Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Steiblys <imbusy@imbusy.org>2009-10-02 02:29:15 +0400
committerLukas Steiblys <imbusy@imbusy.org>2009-10-02 02:29:15 +0400
commit0677398a649b6b8c293df3ce3c6668f0a3be3bc8 (patch)
tree9d510a5bd23559bf4fae670ed04d7e5d6c12578c
parent59248e9f62006ba05e3098e4d213f3dcb23fe711 (diff)
parentbc942eceacb638735dc4f4f68252c4c207147a70 (diff)
merge from 23153 to 23595soc-2009-imbusy
-rw-r--r--CMake/macros.cmake30
-rw-r--r--CMakeLists.txt39
-rw-r--r--SConstruct68
-rw-r--r--config/darwin-config.py1
-rw-r--r--config/irix6-config.py1
-rw-r--r--config/linux2-config.py2
-rw-r--r--config/linuxcross-config.py1
-rw-r--r--config/openbsd3-config.py1
-rw-r--r--config/sunos5-config.py1
-rw-r--r--config/win32-mingw-config.py4
-rw-r--r--config/win32-vc-config.py2
-rw-r--r--config/win64-vc-config.py2
-rw-r--r--extern/CMakeLists.txt9
-rw-r--r--extern/Eigen2/Eigen/Array39
-rw-r--r--extern/Eigen2/Eigen/Cholesky65
-rw-r--r--extern/Eigen2/Eigen/Core154
-rw-r--r--extern/Eigen2/Eigen/Dense8
-rw-r--r--extern/Eigen2/Eigen/Eigen2
-rw-r--r--extern/Eigen2/Eigen/Geometry51
-rw-r--r--extern/Eigen2/Eigen/LU29
-rw-r--r--extern/Eigen2/Eigen/LeastSquares27
-rw-r--r--extern/Eigen2/Eigen/NewStdVector168
-rw-r--r--extern/Eigen2/Eigen/QR73
-rw-r--r--extern/Eigen2/Eigen/QtAlignedMalloc29
-rw-r--r--extern/Eigen2/Eigen/SVD29
-rw-r--r--extern/Eigen2/Eigen/Sparse132
-rw-r--r--extern/Eigen2/Eigen/StdVector147
-rw-r--r--extern/Eigen2/Eigen/src/Array/BooleanRedux.h145
-rw-r--r--extern/Eigen2/Eigen/src/Array/CwiseOperators.h453
-rw-r--r--extern/Eigen2/Eigen/src/Array/Functors.h305
-rw-r--r--extern/Eigen2/Eigen/src/Array/Norms.h80
-rw-r--r--extern/Eigen2/Eigen/src/Array/PartialRedux.h342
-rw-r--r--extern/Eigen2/Eigen/src/Array/Random.h156
-rw-r--r--extern/Eigen2/Eigen/src/Array/Select.h159
-rw-r--r--extern/Eigen2/Eigen/src/Cholesky/CholeskyInstantiations.cpp35
-rw-r--r--extern/Eigen2/Eigen/src/Cholesky/LDLT.h198
-rw-r--r--extern/Eigen2/Eigen/src/Cholesky/LLT.h219
-rw-r--r--extern/Eigen2/Eigen/src/Core/Assign.h445
-rw-r--r--extern/Eigen2/Eigen/src/Core/Block.h752
-rw-r--r--extern/Eigen2/Eigen/src/Core/CacheFriendlyProduct.h753
-rw-r--r--extern/Eigen2/Eigen/src/Core/Coeffs.h384
-rw-r--r--extern/Eigen2/Eigen/src/Core/CommaInitializer.h149
-rw-r--r--extern/Eigen2/Eigen/src/Core/CoreInstantiations.cpp47
-rw-r--r--extern/Eigen2/Eigen/src/Core/Cwise.h211
-rw-r--r--extern/Eigen2/Eigen/src/Core/CwiseBinaryOp.h304
-rw-r--r--extern/Eigen2/Eigen/src/Core/CwiseNullaryOp.h763
-rw-r--r--extern/Eigen2/Eigen/src/Core/CwiseUnaryOp.h229
-rw-r--r--extern/Eigen2/Eigen/src/Core/DiagonalCoeffs.h124
-rw-r--r--extern/Eigen2/Eigen/src/Core/DiagonalMatrix.h144
-rw-r--r--extern/Eigen2/Eigen/src/Core/DiagonalProduct.h130
-rw-r--r--extern/Eigen2/Eigen/src/Core/Dot.h361
-rw-r--r--extern/Eigen2/Eigen/src/Core/Flagged.h146
-rw-r--r--extern/Eigen2/Eigen/src/Core/Functors.h368
-rw-r--r--extern/Eigen2/Eigen/src/Core/Fuzzy.h234
-rw-r--r--extern/Eigen2/Eigen/src/Core/GenericPacketMath.h150
-rw-r--r--extern/Eigen2/Eigen/src/Core/IO.h184
-rw-r--r--extern/Eigen2/Eigen/src/Core/Map.h111
-rw-r--r--extern/Eigen2/Eigen/src/Core/MapBase.h202
-rw-r--r--extern/Eigen2/Eigen/src/Core/MathFunctions.h295
-rw-r--r--extern/Eigen2/Eigen/src/Core/Matrix.h637
-rw-r--r--extern/Eigen2/Eigen/src/Core/MatrixBase.h632
-rw-r--r--extern/Eigen2/Eigen/src/Core/MatrixStorage.h249
-rw-r--r--extern/Eigen2/Eigen/src/Core/Minor.h122
-rw-r--r--extern/Eigen2/Eigen/src/Core/NestByValue.h114
-rw-r--r--extern/Eigen2/Eigen/src/Core/NumTraits.h142
-rw-r--r--extern/Eigen2/Eigen/src/Core/Part.h375
-rw-r--r--extern/Eigen2/Eigen/src/Core/Product.h769
-rw-r--r--extern/Eigen2/Eigen/src/Core/Redux.h117
-rw-r--r--extern/Eigen2/Eigen/src/Core/SolveTriangular.h297
-rw-r--r--extern/Eigen2/Eigen/src/Core/Sum.h271
-rw-r--r--extern/Eigen2/Eigen/src/Core/Swap.h142
-rw-r--r--extern/Eigen2/Eigen/src/Core/Transpose.h228
-rw-r--r--extern/Eigen2/Eigen/src/Core/Visitor.h228
-rw-r--r--extern/Eigen2/Eigen/src/Core/arch/AltiVec/PacketMath.h354
-rw-r--r--extern/Eigen2/Eigen/src/Core/arch/SSE/PacketMath.h321
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/Constants.h254
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/DisableMSVCWarnings.h5
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/EnableMSVCWarnings.h4
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/ForwardDeclarations.h125
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/Macros.h273
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/Memory.h368
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/Meta.h183
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/StaticAssert.h148
-rw-r--r--extern/Eigen2/Eigen/src/Core/util/XprHelper.h219
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/AlignedBox.h173
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/AngleAxis.h228
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/EulerAngles.h96
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/Hyperplane.h268
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/OrthoMethods.h119
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/ParametrizedLine.h155
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/Quaternion.h521
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/Rotation2D.h159
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/RotationBase.h137
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/Scaling.h181
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/Transform.h785
-rw-r--r--extern/Eigen2/Eigen/src/Geometry/Translation.h198
-rw-r--r--extern/Eigen2/Eigen/src/LU/Determinant.h122
-rw-r--r--extern/Eigen2/Eigen/src/LU/Inverse.h258
-rw-r--r--extern/Eigen2/Eigen/src/LU/LU.h541
-rw-r--r--extern/Eigen2/Eigen/src/LeastSquares/LeastSquares.h182
-rw-r--r--extern/Eigen2/Eigen/src/QR/EigenSolver.h722
-rw-r--r--extern/Eigen2/Eigen/src/QR/HessenbergDecomposition.h250
-rw-r--r--extern/Eigen2/Eigen/src/QR/QR.h334
-rw-r--r--extern/Eigen2/Eigen/src/QR/QrInstantiations.cpp43
-rw-r--r--extern/Eigen2/Eigen/src/QR/SelfAdjointEigenSolver.h402
-rw-r--r--extern/Eigen2/Eigen/src/QR/Tridiagonalization.h431
-rw-r--r--extern/Eigen2/Eigen/src/SVD/SVD.h645
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/AmbiVector.h371
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/CholmodSupport.h236
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/CompressedStorage.h230
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/CoreIterators.h68
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h297
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/MappedSparseMatrix.h175
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/RandomSetter.h330
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseAssign.h0
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseBlock.h449
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseCwise.h175
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h442
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h183
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h157
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseDot.h97
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h97
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseFuzzy.h41
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseLDLT.h346
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseLLT.h205
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseLU.h148
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h447
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseMatrixBase.h626
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseProduct.h415
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseRedux.h40
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h85
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseUtil.h148
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SparseVector.h365
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/SuperLUSupport.h565
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/TaucsSupport.h210
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/TriangularSolver.h178
-rw-r--r--extern/Eigen2/Eigen/src/Sparse/UmfPackSupport.h289
-rwxr-xr-xextern/Eigen2/eigen-update.sh28
-rw-r--r--extern/Makefile15
-rw-r--r--extern/SConscript7
-rw-r--r--extern/glew/make/msvc_9_0/glew.vcproj1
-rw-r--r--intern/CMakeLists.txt1
-rw-r--r--intern/Makefile2
-rw-r--r--intern/SConscript1
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp389
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp38
-rw-r--r--intern/audaspace/intern/AUD_C-API.h23
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp194
-rw-r--r--intern/audaspace/make/msvc_9_0/audaspace.vcproj1
-rw-r--r--intern/boolop/make/msvc_9_0/boolop.vcproj1
-rw-r--r--intern/bsp/make/msvc_9_0/bsplib.vcproj1
-rw-r--r--intern/container/make/msvc_9_0/container.vcproj1
-rw-r--r--intern/decimation/make/msvc_9_0/decimation.vcproj1
-rw-r--r--intern/elbeem/make/msvc_9_0/elbeem.vcproj1
-rw-r--r--intern/ghost/CMakeLists.txt17
-rw-r--r--intern/ghost/GHOST_Types.h10
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.h113
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.mm178
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp12
-rw-r--r--intern/ghost/intern/GHOST_System.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp10
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h274
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm1292
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp34
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp13
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h308
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm745
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp10
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp144
-rw-r--r--intern/ghost/make/msvc_9_0/ghost.vcproj1
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h2
-rw-r--r--intern/guardedalloc/intern/mallocn.c24
-rw-r--r--intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj1
-rw-r--r--intern/iksolver/make/msvc_9_0/iksolver.vcproj1
-rw-r--r--intern/itasc/Armature.cpp775
-rw-r--r--intern/itasc/Armature.hpp137
-rw-r--r--intern/itasc/CMakeLists.txt32
-rw-r--r--intern/itasc/Cache.cpp620
-rw-r--r--intern/itasc/Cache.hpp227
-rw-r--r--intern/itasc/ConstraintSet.cpp170
-rw-r--r--intern/itasc/ConstraintSet.hpp115
-rw-r--r--intern/itasc/ControlledObject.cpp61
-rw-r--r--intern/itasc/ControlledObject.hpp70
-rw-r--r--intern/itasc/CopyPose.cpp480
-rw-r--r--intern/itasc/CopyPose.hpp99
-rw-r--r--intern/itasc/Distance.cpp321
-rw-r--r--intern/itasc/Distance.hpp62
-rw-r--r--intern/itasc/FixedObject.cpp70
-rw-r--r--intern/itasc/FixedObject.hpp45
-rw-r--r--intern/itasc/Makefile53
-rw-r--r--intern/itasc/MovingFrame.cpp156
-rw-r--r--intern/itasc/MovingFrame.hpp48
-rw-r--r--intern/itasc/Object.hpp48
-rw-r--r--intern/itasc/SConscript11
-rw-r--r--intern/itasc/Scene.cpp543
-rw-r--r--intern/itasc/Scene.hpp104
-rw-r--r--intern/itasc/Solver.hpp33
-rw-r--r--intern/itasc/UncontrolledObject.cpp43
-rw-r--r--intern/itasc/UncontrolledObject.hpp37
-rw-r--r--intern/itasc/WDLSSolver.cpp101
-rw-r--r--intern/itasc/WDLSSolver.hpp48
-rw-r--r--intern/itasc/WSDLSSolver.cpp138
-rw-r--r--intern/itasc/WSDLSSolver.hpp43
-rw-r--r--intern/itasc/WorldObject.cpp26
-rw-r--r--intern/itasc/WorldObject.hpp30
-rw-r--r--intern/itasc/eigen_types.cpp12
-rw-r--r--intern/itasc/eigen_types.hpp84
-rw-r--r--intern/itasc/kdl/Makefile43
-rw-r--r--intern/itasc/kdl/chain.cpp75
-rw-r--r--intern/itasc/kdl/chain.hpp95
-rw-r--r--intern/itasc/kdl/chainfksolver.hpp107
-rw-r--r--intern/itasc/kdl/chainfksolverpos_recursive.cpp61
-rw-r--r--intern/itasc/kdl/chainfksolverpos_recursive.hpp50
-rw-r--r--intern/itasc/kdl/chainjnttojacsolver.cpp80
-rw-r--r--intern/itasc/kdl/chainjnttojacsolver.hpp65
-rw-r--r--intern/itasc/kdl/frameacc.cpp26
-rw-r--r--intern/itasc/kdl/frameacc.hpp259
-rw-r--r--intern/itasc/kdl/frameacc.inl598
-rw-r--r--intern/itasc/kdl/frames.cpp389
-rw-r--r--intern/itasc/kdl/frames.hpp1097
-rw-r--r--intern/itasc/kdl/frames.inl1390
-rw-r--r--intern/itasc/kdl/frames_io.cpp310
-rw-r--r--intern/itasc/kdl/frames_io.hpp114
-rw-r--r--intern/itasc/kdl/framevel.cpp27
-rw-r--r--intern/itasc/kdl/framevel.hpp382
-rw-r--r--intern/itasc/kdl/framevel.inl534
-rw-r--r--intern/itasc/kdl/inertia.cpp48
-rw-r--r--intern/itasc/kdl/inertia.hpp70
-rw-r--r--intern/itasc/kdl/jacobian.cpp129
-rw-r--r--intern/itasc/kdl/jacobian.hpp68
-rw-r--r--intern/itasc/kdl/jntarray.cpp152
-rw-r--r--intern/itasc/kdl/jntarray.hpp217
-rw-r--r--intern/itasc/kdl/jntarrayacc.cpp170
-rw-r--r--intern/itasc/kdl/jntarrayacc.hpp66
-rw-r--r--intern/itasc/kdl/jntarrayvel.cpp111
-rw-r--r--intern/itasc/kdl/jntarrayvel.hpp59
-rw-r--r--intern/itasc/kdl/joint.cpp153
-rw-r--r--intern/itasc/kdl/joint.hpp138
-rw-r--r--intern/itasc/kdl/kinfam_io.cpp101
-rw-r--r--intern/itasc/kdl/kinfam_io.hpp70
-rw-r--r--intern/itasc/kdl/segment.cpp68
-rw-r--r--intern/itasc/kdl/segment.hpp149
-rw-r--r--intern/itasc/kdl/tree.cpp117
-rw-r--r--intern/itasc/kdl/tree.hpp167
-rw-r--r--intern/itasc/kdl/treefksolver.hpp110
-rw-r--r--intern/itasc/kdl/treefksolverpos_recursive.cpp70
-rw-r--r--intern/itasc/kdl/treefksolverpos_recursive.hpp53
-rw-r--r--intern/itasc/kdl/treejnttojacsolver.cpp78
-rw-r--r--intern/itasc/kdl/treejnttojacsolver.hpp38
-rw-r--r--intern/itasc/kdl/utilities/Makefile40
-rw-r--r--intern/itasc/kdl/utilities/error.h245
-rw-r--r--intern/itasc/kdl/utilities/error_stack.cpp59
-rw-r--r--intern/itasc/kdl/utilities/error_stack.h70
-rw-r--r--intern/itasc/kdl/utilities/kdl-config.h33
-rw-r--r--intern/itasc/kdl/utilities/rall1d.h478
-rw-r--r--intern/itasc/kdl/utilities/rall2d.h538
-rw-r--r--intern/itasc/kdl/utilities/svd_eigen_HH.hpp309
-rw-r--r--intern/itasc/kdl/utilities/traits.h111
-rw-r--r--intern/itasc/kdl/utilities/utility.cpp21
-rw-r--r--intern/itasc/kdl/utilities/utility.h299
-rw-r--r--intern/itasc/kdl/utilities/utility_io.cpp208
-rw-r--r--intern/itasc/kdl/utilities/utility_io.h79
-rw-r--r--intern/itasc/make/msvc_9_0/itasc.vcproj539
-rw-r--r--intern/itasc/ublas_types.hpp82
-rw-r--r--intern/memutil/make/msvc_9_0/memutil.vcproj1
-rw-r--r--intern/moto/make/msvc_9_0/moto.vcproj1
-rw-r--r--intern/smoke/intern/FLUID_3D.cpp3
-rw-r--r--intern/smoke/intern/FLUID_3D.h2
-rw-r--r--intern/smoke/intern/FLUID_3D_STATIC.cpp48
-rw-r--r--intern/smoke/intern/WTURBULENCE.cpp1
-rw-r--r--intern/smoke/intern/smoke_API.cpp3
-rw-r--r--intern/smoke/make/msvc_9_0/smoke.vcproj1
-rw-r--r--intern/string/make/msvc_9_0/string.vcproj1
-rw-r--r--po/Makefile2
-rw-r--r--projectfiles_vc9/blender/BLO_readblenfile/BLO_readblenfile.vcproj2
-rw-r--r--projectfiles_vc9/blender/BPY_python/BPY_python.vcproj1
-rw-r--r--projectfiles_vc9/blender/avi/BL_avi.vcproj1
-rw-r--r--projectfiles_vc9/blender/blender.sln55
-rw-r--r--projectfiles_vc9/blender/blender.vcproj1
-rw-r--r--projectfiles_vc9/blender/blenfont/BLF_blenfont.vcproj1
-rw-r--r--projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj13
-rw-r--r--projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj9
-rw-r--r--projectfiles_vc9/blender/blenpluginapi/blenpluginapi/blenpluginapi.vcproj14
-rw-r--r--projectfiles_vc9/blender/editors/ED_editors.vcproj61
-rw-r--r--projectfiles_vc9/blender/gpu/BL_gpu.vcproj1
-rw-r--r--projectfiles_vc9/blender/ikplugin/BIK_ikplugin.vcproj214
-rw-r--r--projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj1
-rw-r--r--projectfiles_vc9/blender/loader/BLO_loader.vcproj235
-rw-r--r--projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj1
-rw-r--r--projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj55
-rw-r--r--projectfiles_vc9/blender/makesrna/RNA_rna.vcproj4
-rw-r--r--projectfiles_vc9/blender/nodes/nodes.vcproj9
-rw-r--r--projectfiles_vc9/blender/render/BRE_render.vcproj6
-rw-r--r--projectfiles_vc9/blender/windowmanager/windowmanager.vcproj4
-rw-r--r--projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj5
-rw-r--r--projectfiles_vc9/gameengine/converter/KX_converter.vcproj39
-rw-r--r--projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj13
-rw-r--r--projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj9
-rw-r--r--projectfiles_vc9/gameengine/gameplayer/axctl/GP_axctl.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/gameplayer/common/GP_common.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj9
-rw-r--r--projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/network/loopbacknetwork/NG_loopbacknetwork.vcproj2
-rw-r--r--projectfiles_vc9/gameengine/network/network/NG_network.vcproj2
-rw-r--r--projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Dummy/PHY_Dummy.vcproj2
-rw-r--r--projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Ode/PHY_Ode.vcproj2
-rw-r--r--projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj1
-rw-r--r--projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj1
-rw-r--r--projectfiles_vc9/kernel/gen_messaging/gen_messaging.vcproj2
-rw-r--r--projectfiles_vc9/kernel/system/SYS_system.vcproj2
-rw-r--r--release/Makefile3
-rw-r--r--release/datafiles/splash.png (renamed from release/datafiles/splash.jpg)bin197165 -> 197165 bytes
-rw-r--r--release/io/netrender/slave.py169
-rw-r--r--release/scripts/3ds_import.py1007
-rw-r--r--release/scripts/Axiscopy.py125
-rw-r--r--release/scripts/DirectX8Exporter.py1196
-rw-r--r--release/scripts/DirectX8Importer.py238
-rw-r--r--release/scripts/IDPropBrowser.py523
-rw-r--r--release/scripts/ac3d_export.py828
-rw-r--r--release/scripts/ac3d_import.py783
-rw-r--r--release/scripts/add_mesh_empty.py13
-rw-r--r--release/scripts/add_mesh_torus.py69
-rw-r--r--release/scripts/animation_bake_constraints.py792
-rw-r--r--release/scripts/animation_clean.py192
-rw-r--r--release/scripts/animation_trajectory.py575
-rw-r--r--release/scripts/armature_symmetry.py325
-rw-r--r--release/scripts/bevel_center.py474
-rw-r--r--release/scripts/blenderLipSynchro.py729
-rw-r--r--release/scripts/bpydata/KUlang.txt121
-rw-r--r--release/scripts/bpydata/config/readme.txt6
-rw-r--r--release/scripts/bpydata/readme.txt9
-rw-r--r--release/scripts/bpymodules/BPyAddMesh.py159
-rw-r--r--release/scripts/bpymodules/BPyArmature.py152
-rw-r--r--release/scripts/bpymodules/BPyBlender.py36
-rw-r--r--release/scripts/bpymodules/BPyCurve.py79
-rw-r--r--release/scripts/bpymodules/BPyImage.py318
-rw-r--r--release/scripts/bpymodules/BPyMathutils.py228
-rw-r--r--release/scripts/bpymodules/BPyMesh.py1326
-rw-r--r--release/scripts/bpymodules/BPyMesh_redux.py652
-rw-r--r--release/scripts/bpymodules/BPyMessages.py61
-rw-r--r--release/scripts/bpymodules/BPyNMesh.py48
-rw-r--r--release/scripts/bpymodules/BPyObject.py108
-rw-r--r--release/scripts/bpymodules/BPyRegistry.py267
-rw-r--r--release/scripts/bpymodules/BPyRender.py633
-rw-r--r--release/scripts/bpymodules/BPySys.py74
-rw-r--r--release/scripts/bpymodules/BPyTextPlugin.py814
-rw-r--r--release/scripts/bpymodules/BPyWindow.py206
-rw-r--r--release/scripts/bpymodules/blend2renderinfo.py95
-rw-r--r--release/scripts/bpymodules/defaultdoodads.py941
-rw-r--r--release/scripts/bpymodules/dxfColorMap.py282
-rw-r--r--release/scripts/bpymodules/dxfLibrary.py880
-rw-r--r--release/scripts/bpymodules/dxfReader.py381
-rw-r--r--release/scripts/bpymodules/mesh_gradient.py229
-rw-r--r--release/scripts/bpymodules/meshtools.py355
-rw-r--r--release/scripts/bpymodules/paths_ai2obj.py506
-rw-r--r--release/scripts/bpymodules/paths_eps2obj.py452
-rw-r--r--release/scripts/bpymodules/paths_gimp2obj.py363
-rw-r--r--release/scripts/bpymodules/paths_svg2obj.py1651
-rw-r--r--release/scripts/bvh_import.py757
-rw-r--r--release/scripts/c3d_import.py1244
-rw-r--r--release/scripts/camera_changer.py121
-rw-r--r--release/scripts/config.py801
-rw-r--r--release/scripts/console.py861
-rw-r--r--release/scripts/discombobulator.py1526
-rw-r--r--release/scripts/envelope_symmetry.py174
-rw-r--r--release/scripts/export-iv-0.1.py304
-rw-r--r--release/scripts/export_dxf.py3041
-rw-r--r--release/scripts/export_lightwave_motion.py157
-rw-r--r--release/scripts/export_m3g.py3074
-rw-r--r--release/scripts/export_map.py454
-rw-r--r--release/scripts/export_mdd.py168
-rw-r--r--release/scripts/export_obj.py933
-rw-r--r--release/scripts/faceselect_same_weights.py111
-rw-r--r--release/scripts/flt_defaultp.py1
-rw-r--r--release/scripts/flt_dofedit.py835
-rw-r--r--release/scripts/flt_export.py1697
-rw-r--r--release/scripts/flt_filewalker.py286
-rw-r--r--release/scripts/flt_import.py2534
-rw-r--r--release/scripts/flt_lodedit.py502
-rw-r--r--release/scripts/flt_palettemanager.py505
-rw-r--r--release/scripts/flt_properties.py630
-rw-r--r--release/scripts/flt_toolbar.py809
-rw-r--r--release/scripts/help_bpy_api.py47
-rw-r--r--release/scripts/help_browser.py814
-rw-r--r--release/scripts/hotkeys.py944
-rw-r--r--release/scripts/image_2d_cutout.py559
-rw-r--r--release/scripts/image_auto_layout.py455
-rw-r--r--release/scripts/image_billboard.py269
-rw-r--r--release/scripts/image_edit.py158
-rw-r--r--release/scripts/import_dxf.py6225
-rw-r--r--release/scripts/import_edl.py961
-rw-r--r--release/scripts/import_lightwave_motion.py244
-rw-r--r--release/scripts/import_mdd.py158
-rw-r--r--release/scripts/import_web3d.py2594
-rw-r--r--release/scripts/io/engine_render_pov.py (renamed from release/io/engine_render_pov.py)42
-rw-r--r--release/scripts/io/export_3ds.py (renamed from release/scripts/3ds_export.py)323
-rw-r--r--release/scripts/io/export_fbx.py (renamed from release/scripts/export_fbx.py)967
-rw-r--r--release/scripts/io/export_obj.py996
-rw-r--r--release/scripts/io/export_ply.py (renamed from release/io/export_ply.py)15
-rw-r--r--release/scripts/io/export_x3d.py (renamed from release/scripts/x3d_export.py)553
-rw-r--r--release/scripts/io/import_3ds.py1167
-rw-r--r--release/scripts/io/import_obj.py (renamed from release/scripts/import_obj.py)752
-rw-r--r--release/scripts/io/netrender/__init__.py (renamed from release/io/netrender/__init__.py)2
-rw-r--r--release/scripts/io/netrender/balancing.py94
-rw-r--r--release/scripts/io/netrender/client.py (renamed from release/io/netrender/client.py)26
-rw-r--r--release/scripts/io/netrender/master.py (renamed from release/io/netrender/master.py)453
-rw-r--r--release/scripts/io/netrender/master_html.py135
-rw-r--r--release/scripts/io/netrender/model.py (renamed from release/io/netrender/model.py)66
-rw-r--r--release/scripts/io/netrender/operators.py (renamed from release/io/netrender/operators.py)148
-rw-r--r--release/scripts/io/netrender/slave.py224
-rw-r--r--release/scripts/io/netrender/ui.py (renamed from release/io/netrender/ui.py)65
-rw-r--r--release/scripts/io/netrender/utils.py (renamed from release/io/netrender/utils.py)29
-rw-r--r--release/scripts/lightwave_export.py707
-rw-r--r--release/scripts/lightwave_import.py1705
-rw-r--r--release/scripts/md2_export.py1271
-rw-r--r--release/scripts/md2_import.py600
-rw-r--r--release/scripts/mesh_boneweight_copy.py287
-rw-r--r--release/scripts/mesh_cleanup.py456
-rw-r--r--release/scripts/mesh_edges2curves.py166
-rw-r--r--release/scripts/mesh_mirror_tool.py352
-rw-r--r--release/scripts/mesh_poly_reduce.py143
-rw-r--r--release/scripts/mesh_poly_reduce_grid.py351
-rw-r--r--release/scripts/mesh_skin.py639
-rw-r--r--release/scripts/mesh_solidify.py345
-rw-r--r--release/scripts/mesh_unfolder.py1582
-rw-r--r--release/scripts/mesh_wire.py290
-rw-r--r--release/scripts/modules/autocomplete.py211
-rw-r--r--release/scripts/modules/bpy_ops.py (renamed from release/ui/bpy_ops.py)6
-rw-r--r--release/scripts/modules/bpy_sys.py12
-rw-r--r--release/scripts/ms3d_import.py487
-rw-r--r--release/scripts/ms3d_import_ascii.py479
-rw-r--r--release/scripts/obdatacopier.py215
-rw-r--r--release/scripts/object_active_to_other.py58
-rw-r--r--release/scripts/object_apply_def.py178
-rw-r--r--release/scripts/object_batch_name_edit.py274
-rw-r--r--release/scripts/object_cookie_cutter.py667
-rw-r--r--release/scripts/object_drop.py253
-rw-r--r--release/scripts/object_find.py222
-rw-r--r--release/scripts/object_random_loc_sz_rot.py129
-rw-r--r--release/scripts/object_sel2dupgroup.py84
-rw-r--r--release/scripts/object_timeofs_follow_act.py107
-rw-r--r--release/scripts/off_export.py106
-rw-r--r--release/scripts/off_import.py177
-rw-r--r--release/scripts/paths_import.py96
-rw-r--r--release/scripts/ply_import.py354
-rw-r--r--release/scripts/raw_export.py100
-rw-r--r--release/scripts/raw_import.py120
-rw-r--r--release/scripts/renameobjectbyblock.py178
-rw-r--r--release/scripts/render_save_layers.py120
-rw-r--r--release/scripts/rvk1_torvk2.py341
-rw-r--r--release/scripts/save_theme.py143
-rw-r--r--release/scripts/scripttemplate_background_job.py124
-rw-r--r--release/scripts/scripttemplate_camera_object.py104
-rw-r--r--release/scripts/scripttemplate_gamelogic.py97
-rw-r--r--release/scripts/scripttemplate_gamelogic_basic.py33
-rw-r--r--release/scripts/scripttemplate_gamelogic_module.py45
-rw-r--r--release/scripts/scripttemplate_ipo_gen.py92
-rw-r--r--release/scripts/scripttemplate_mesh_edit.py98
-rw-r--r--release/scripts/scripttemplate_metaball_create.py76
-rw-r--r--release/scripts/scripttemplate_object_edit.py81
-rw-r--r--release/scripts/scripttemplate_pyconstraint.py114
-rw-r--r--release/scripts/scripttemplate_text_plugin.py69
-rw-r--r--release/scripts/slp_import.py116
-rw-r--r--release/scripts/sysinfo.py287
-rw-r--r--release/scripts/textplugin_convert_ge.py863
-rw-r--r--release/scripts/textplugin_functiondocs.py64
-rw-r--r--release/scripts/textplugin_imports.py91
-rw-r--r--release/scripts/textplugin_membersuggest.py90
-rw-r--r--release/scripts/textplugin_outliner.py142
-rw-r--r--release/scripts/textplugin_suggest.py94
-rw-r--r--release/scripts/textplugin_templates.py123
-rw-r--r--release/scripts/ui/buttons_data_armature.py (renamed from release/ui/buttons_data_armature.py)35
-rw-r--r--release/scripts/ui/buttons_data_bone.py (renamed from release/ui/buttons_data_bone.py)101
-rw-r--r--release/scripts/ui/buttons_data_camera.py (renamed from release/ui/buttons_data_camera.py)11
-rw-r--r--release/scripts/ui/buttons_data_curve.py (renamed from release/ui/buttons_data_curve.py)19
-rw-r--r--release/scripts/ui/buttons_data_empty.py (renamed from release/ui/buttons_data_empty.py)0
-rw-r--r--release/scripts/ui/buttons_data_lamp.py (renamed from release/ui/buttons_data_lamp.py)35
-rw-r--r--release/scripts/ui/buttons_data_lattice.py (renamed from release/ui/buttons_data_lattice.py)2
-rw-r--r--release/scripts/ui/buttons_data_mesh.py (renamed from release/ui/buttons_data_mesh.py)8
-rw-r--r--release/scripts/ui/buttons_data_metaball.py (renamed from release/ui/buttons_data_metaball.py)8
-rw-r--r--release/scripts/ui/buttons_data_modifier.py (renamed from release/ui/buttons_data_modifier.py)0
-rw-r--r--release/scripts/ui/buttons_data_text.py (renamed from release/ui/buttons_data_text.py)10
-rw-r--r--release/scripts/ui/buttons_game.py (renamed from release/ui/buttons_game.py)17
-rw-r--r--release/scripts/ui/buttons_material.py (renamed from release/ui/buttons_material.py)104
-rw-r--r--release/scripts/ui/buttons_object.py (renamed from release/ui/buttons_object.py)52
-rw-r--r--release/scripts/ui/buttons_object_constraint.py (renamed from release/ui/buttons_object_constraint.py)113
-rw-r--r--release/scripts/ui/buttons_particle.py (renamed from release/ui/buttons_particle.py)162
-rw-r--r--release/scripts/ui/buttons_physics_cloth.py (renamed from release/ui/buttons_physics_cloth.py)44
-rw-r--r--release/scripts/ui/buttons_physics_common.py153
-rw-r--r--release/scripts/ui/buttons_physics_field.py (renamed from release/ui/buttons_physics_field.py)79
-rw-r--r--release/scripts/ui/buttons_physics_fluid.py (renamed from release/ui/buttons_physics_fluid.py)9
-rw-r--r--release/scripts/ui/buttons_physics_smoke.py (renamed from release/ui/buttons_physics_smoke.py)5
-rw-r--r--release/scripts/ui/buttons_physics_softbody.py (renamed from release/ui/buttons_physics_softbody.py)27
-rw-r--r--release/scripts/ui/buttons_scene.py (renamed from release/ui/buttons_scene.py)29
-rw-r--r--release/scripts/ui/buttons_texture.py (renamed from release/ui/buttons_texture.py)32
-rw-r--r--release/scripts/ui/buttons_world.py (renamed from release/ui/buttons_world.py)7
-rw-r--r--release/scripts/ui/space_buttons.py (renamed from release/ui/space_buttons.py)0
-rw-r--r--release/scripts/ui/space_console.py (renamed from release/ui/space_console.py)220
-rw-r--r--release/scripts/ui/space_filebrowser.py (renamed from release/ui/space_filebrowser.py)0
-rw-r--r--release/scripts/ui/space_image.py (renamed from release/ui/space_image.py)140
-rw-r--r--release/scripts/ui/space_info.py (renamed from release/ui/space_info.py)50
-rw-r--r--release/scripts/ui/space_logic.py (renamed from release/ui/space_logic.py)0
-rw-r--r--release/scripts/ui/space_node.py (renamed from release/ui/space_node.py)18
-rw-r--r--release/scripts/ui/space_outliner.py (renamed from release/ui/space_outliner.py)0
-rw-r--r--release/scripts/ui/space_sequencer.py (renamed from release/ui/space_sequencer.py)4
-rw-r--r--release/scripts/ui/space_text.py (renamed from release/ui/space_text.py)0
-rw-r--r--release/scripts/ui/space_time.py (renamed from release/ui/space_time.py)12
-rw-r--r--release/scripts/ui/space_userpref.py (renamed from release/ui/space_userpref.py)153
-rw-r--r--release/scripts/ui/space_view3d.py (renamed from release/ui/space_view3d.py)318
-rw-r--r--release/scripts/ui/space_view3d_toolbar.py (renamed from release/ui/space_view3d_toolbar.py)220
-rw-r--r--release/scripts/unweld.py247
-rw-r--r--release/scripts/uv_export.py498
-rw-r--r--release/scripts/uv_seams_from_islands.py101
-rw-r--r--release/scripts/uvcalc_follow_active_coords.py254
-rw-r--r--release/scripts/uvcalc_lightmap.py599
-rw-r--r--release/scripts/uvcalc_quad_clickproj.py271
-rw-r--r--release/scripts/uvcalc_smart_project.py1132
-rw-r--r--release/scripts/uvcopy.py112
-rw-r--r--release/scripts/vertexpaint_from_material.py99
-rw-r--r--release/scripts/vertexpaint_selfshadow_ao.py186
-rw-r--r--release/scripts/vrml97_export.py1300
-rw-r--r--release/scripts/weightpaint_average.py121
-rw-r--r--release/scripts/weightpaint_clean.py121
-rw-r--r--release/scripts/weightpaint_copy.py101
-rw-r--r--release/scripts/weightpaint_envelope_assign.py240
-rw-r--r--release/scripts/weightpaint_gradient.py59
-rw-r--r--release/scripts/weightpaint_grow_shrink.py131
-rw-r--r--release/scripts/weightpaint_invert.py95
-rw-r--r--release/scripts/weightpaint_normalize.py170
-rw-r--r--release/scripts/widgetwizard.py917
-rw-r--r--release/scripts/wizard_bolt_factory.py2811
-rw-r--r--release/scripts/wizard_curve2tree.py4048
-rw-r--r--release/scripts/wizard_landscape_ant.py2148
-rw-r--r--release/scripts/xsi_export.py1227
-rw-r--r--source/Makefile6
-rw-r--r--source/blender/CMakeLists.txt1
-rw-r--r--source/blender/Makefile2
-rw-r--r--source/blender/SConscript3
-rw-r--r--source/blender/blenfont/CMakeLists.txt1
-rw-r--r--source/blender/blenfont/Makefile4
-rw-r--r--source/blender/blenfont/SConscript8
-rw-r--r--source/blender/blenfont/intern/blf.c2
-rw-r--r--source/blender/blenfont/intern/blf_dir.c2
-rw-r--r--source/blender/blenfont/intern/blf_font.c6
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c2
-rw-r--r--source/blender/blenfont/intern/blf_lang.c55
-rw-r--r--source/blender/blenkernel/BKE_action.h53
-rw-r--r--source/blender/blenkernel/BKE_anim.h9
-rw-r--r--source/blender/blenkernel/BKE_armature.h7
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_boids.h4
-rw-r--r--source/blender/blenkernel/BKE_brush.h4
-rw-r--r--source/blender/blenkernel/BKE_collision.h11
-rw-r--r--source/blender/blenkernel/BKE_constraint.h6
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h16
-rw-r--r--source/blender/blenkernel/BKE_effect.h109
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h7
-rw-r--r--source/blender/blenkernel/BKE_image.h11
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/BKE_node.h7
-rw-r--r--source/blender/blenkernel/BKE_particle.h173
-rw-r--r--source/blender/blenkernel/BKE_screen.h6
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/BKE_text.h12
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h49
-rw-r--r--source/blender/blenkernel/CMakeLists.txt14
-rw-r--r--source/blender/blenkernel/SConscript14
-rw-r--r--source/blender/blenkernel/intern/Makefile19
-rw-r--r--source/blender/blenkernel/intern/action.c413
-rw-r--r--source/blender/blenkernel/intern/anim.c31
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c145
-rw-r--r--source/blender/blenkernel/intern/armature.c547
-rw-r--r--source/blender/blenkernel/intern/boids.c249
-rw-r--r--source/blender/blenkernel/intern/brush.c117
-rw-r--r--source/blender/blenkernel/intern/cloth.c98
-rw-r--r--source/blender/blenkernel/intern/collision.c138
-rw-r--r--source/blender/blenkernel/intern/constraint.c27
-rw-r--r--source/blender/blenkernel/intern/curve.c10
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c147
-rw-r--r--source/blender/blenkernel/intern/displist.c2
-rw-r--r--source/blender/blenkernel/intern/effect.c858
-rw-r--r--source/blender/blenkernel/intern/fcurve.c87
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c1
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/image.c178
-rw-r--r--source/blender/blenkernel/intern/implicit.c48
-rw-r--r--source/blender/blenkernel/intern/ipo.c90
-rw-r--r--source/blender/blenkernel/intern/lattice.c144
-rw-r--r--source/blender/blenkernel/intern/library.c53
-rw-r--r--source/blender/blenkernel/intern/material.c12
-rw-r--r--source/blender/blenkernel/intern/mesh.c3
-rw-r--r--source/blender/blenkernel/intern/modifier.c83
-rw-r--r--source/blender/blenkernel/intern/multires.c4
-rw-r--r--source/blender/blenkernel/intern/nla.c5
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/blenkernel/intern/object.c135
-rw-r--r--source/blender/blenkernel/intern/packedFile.c2
-rw-r--r--source/blender/blenkernel/intern/paint.c27
-rw-r--r--source/blender/blenkernel/intern/particle.c835
-rw-r--r--source/blender/blenkernel/intern/particle_system.c1730
-rw-r--r--source/blender/blenkernel/intern/pointcache.c302
-rw-r--r--source/blender/blenkernel/intern/report.c2
-rw-r--r--source/blender/blenkernel/intern/sca.c18
-rw-r--r--source/blender/blenkernel/intern/scene.c20
-rw-r--r--source/blender/blenkernel/intern/screen.c21
-rw-r--r--source/blender/blenkernel/intern/sequence.c24
-rw-r--r--source/blender/blenkernel/intern/smoke.c215
-rw-r--r--source/blender/blenkernel/intern/softbody.c67
-rw-r--r--source/blender/blenkernel/intern/sound.c8
-rw-r--r--source/blender/blenkernel/intern/text.c95
-rw-r--r--source/blender/blenkernel/intern/texture.c31
-rw-r--r--source/blender/blenkernel/intern/unit.c4
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c15
-rw-r--r--source/blender/blenlib/BLI_arithb.h14
-rw-r--r--source/blender/blenlib/BLI_bfile.h138
-rw-r--r--source/blender/blenlib/BLI_ghash.h8
-rw-r--r--source/blender/blenlib/BLI_listbase.h4
-rw-r--r--source/blender/blenlib/BLI_threads.h53
-rw-r--r--source/blender/blenlib/BLI_util.h9
-rw-r--r--source/blender/blenlib/BLI_winstuff.h21
-rw-r--r--source/blender/blenlib/intern/BLI_bfile.c236
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c4
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c2
-rw-r--r--source/blender/blenlib/intern/arithb.c60
-rw-r--r--source/blender/blenlib/intern/dynlib.c200
-rw-r--r--source/blender/blenlib/intern/freetypefont.c4
-rw-r--r--source/blender/blenlib/intern/graph.c6
-rw-r--r--source/blender/blenlib/intern/listbase.c14
-rw-r--r--source/blender/blenlib/intern/noise.c12
-rw-r--r--source/blender/blenlib/intern/threads.c96
-rw-r--r--source/blender/blenlib/intern/util.c167
-rw-r--r--source/blender/blenloader/BLO_readfile.h19
-rw-r--r--source/blender/blenloader/intern/readblenentry.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c504
-rw-r--r--source/blender/blenloader/intern/writefile.c23
-rw-r--r--source/blender/blenpluginapi/CMakeLists.txt4
-rw-r--r--source/blender/blenpluginapi/SConscript7
-rw-r--r--source/blender/editors/CMakeLists.txt1
-rw-r--r--source/blender/editors/Makefile2
-rw-r--r--source/blender/editors/SConscript2
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c121
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c145
-rw-r--r--source/blender/editors/animation/anim_deps.c14
-rw-r--r--source/blender/editors/animation/anim_draw.c50
-rw-r--r--source/blender/editors/animation/anim_filter.c121
-rw-r--r--source/blender/editors/animation/anim_markers.c5
-rw-r--r--source/blender/editors/animation/anim_ops.c8
-rw-r--r--source/blender/editors/animation/drivers.c237
-rw-r--r--source/blender/editors/animation/keyframes_draw.c32
-rw-r--r--source/blender/editors/animation/keyframes_edit.c19
-rw-r--r--source/blender/editors/animation/keyframing.c89
-rw-r--r--source/blender/editors/animation/keyingsets.c41
-rw-r--r--source/blender/editors/armature/SConscript7
-rw-r--r--source/blender/editors/armature/armature_intern.h8
-rw-r--r--source/blender/editors/armature/armature_ops.c34
-rw-r--r--source/blender/editors/armature/editarmature.c30
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c2
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c12
-rw-r--r--source/blender/editors/armature/meshlaplacian.c6
-rw-r--r--source/blender/editors/armature/poseSlide.c936
-rw-r--r--source/blender/editors/armature/poselib.c76
-rw-r--r--source/blender/editors/armature/poseobject.c239
-rw-r--r--source/blender/editors/curve/curve_ops.c8
-rw-r--r--source/blender/editors/curve/editcurve.c11
-rw-r--r--source/blender/editors/curve/editfont.c12
-rw-r--r--source/blender/editors/datafiles/B.blend.c5657
-rw-r--r--source/blender/editors/datafiles/splash.png.c (renamed from source/blender/editors/datafiles/splash.jpg.c)6
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c2
-rw-r--r--source/blender/editors/include/ED_anim_api.h12
-rw-r--r--source/blender/editors/include/ED_datafiles.h4
-rw-r--r--source/blender/editors/include/ED_fileselect.h32
-rw-r--r--source/blender/editors/include/ED_image.h8
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h4
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h1
-rw-r--r--source/blender/editors/include/ED_keyframing.h18
-rw-r--r--source/blender/editors/include/ED_mesh.h31
-rw-r--r--source/blender/editors/include/ED_node.h5
-rw-r--r--source/blender/editors/include/ED_object.h2
-rw-r--r--source/blender/editors/include/ED_particle.h17
-rw-r--r--source/blender/editors/include/ED_physics.h7
-rw-r--r--source/blender/editors/include/ED_render.h (renamed from source/blender/editors/include/ED_previewrender.h)27
-rw-r--r--source/blender/editors/include/ED_screen.h2
-rw-r--r--source/blender/editors/include/ED_screen_types.h2
-rw-r--r--source/blender/editors/include/ED_sculpt.h2
-rw-r--r--source/blender/editors/include/ED_transform.h10
-rw-r--r--source/blender/editors/include/UI_interface.h38
-rw-r--r--source/blender/editors/include/UI_interface_icons.h6
-rw-r--r--source/blender/editors/interface/SConscript5
-rw-r--r--source/blender/editors/interface/interface.c47
-rw-r--r--source/blender/editors/interface/interface_anim.c19
-rw-r--r--source/blender/editors/interface/interface_handlers.c56
-rw-r--r--source/blender/editors/interface/interface_icons.c467
-rw-r--r--source/blender/editors/interface/interface_intern.h10
-rw-r--r--source/blender/editors/interface/interface_layout.c63
-rw-r--r--source/blender/editors/interface/interface_panel.c14
-rw-r--r--source/blender/editors/interface/interface_regions.c14
-rw-r--r--source/blender/editors/interface/interface_templates.c627
-rw-r--r--source/blender/editors/interface/interface_utils.c1022
-rw-r--r--source/blender/editors/interface/interface_widgets.c115
-rw-r--r--source/blender/editors/interface/resources.c16
-rw-r--r--source/blender/editors/interface/view2d.c55
-rw-r--r--source/blender/editors/interface/view2d_ops.c16
-rw-r--r--source/blender/editors/mesh/SConscript7
-rw-r--r--source/blender/editors/mesh/editmesh_loop.c6
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c23
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c100
-rw-r--r--source/blender/editors/mesh/loopcut.c474
-rw-r--r--source/blender/editors/mesh/mesh_data.c (renamed from source/blender/editors/mesh/mesh_layers.c)388
-rw-r--r--source/blender/editors/mesh/mesh_intern.h9
-rw-r--r--source/blender/editors/mesh/mesh_ops.c35
-rw-r--r--source/blender/editors/mesh/meshtools.c2
-rw-r--r--source/blender/editors/metaball/mball_ops.c8
-rw-r--r--source/blender/editors/object/Makefile1
-rw-r--r--source/blender/editors/object/SConscript2
-rw-r--r--source/blender/editors/object/object_add.c141
-rw-r--r--source/blender/editors/object/object_constraint.c44
-rw-r--r--source/blender/editors/object/object_edit.c42
-rw-r--r--source/blender/editors/object/object_intern.h7
-rw-r--r--source/blender/editors/object/object_modifier.c6
-rw-r--r--source/blender/editors/object/object_ops.c26
-rw-r--r--source/blender/editors/object/object_relations.c18
-rw-r--r--source/blender/editors/object/object_select.c116
-rw-r--r--source/blender/editors/object/object_transform.c74
-rw-r--r--source/blender/editors/physics/SConscript7
-rw-r--r--source/blender/editors/physics/particle_boids.c (renamed from source/blender/editors/physics/physics_boids.c)112
-rw-r--r--source/blender/editors/physics/particle_edit.c (renamed from source/blender/editors/physics/editparticle.c)116
-rw-r--r--source/blender/editors/physics/particle_object.c575
-rw-r--r--source/blender/editors/physics/physics_fluid.c (renamed from source/blender/editors/physics/ed_fluidsim.c)7
-rw-r--r--source/blender/editors/physics/physics_intern.h66
-rw-r--r--source/blender/editors/physics/physics_ops.c173
-rw-r--r--source/blender/editors/physics/physics_pointcache.c (renamed from source/blender/editors/physics/ed_pointcache.c)24
-rw-r--r--source/blender/editors/render/Makefile (renamed from source/blender/editors/preview/Makefile)2
-rw-r--r--source/blender/editors/render/SConscript (renamed from source/blender/editors/preview/SConscript)9
-rw-r--r--source/blender/editors/render/render_intern.h49
-rw-r--r--source/blender/editors/render/render_ops.c54
-rw-r--r--source/blender/editors/render/render_preview.c (renamed from source/blender/editors/preview/previewrender.c)228
-rw-r--r--source/blender/editors/render/render_shading.c645
-rw-r--r--source/blender/editors/screen/SConscript7
-rw-r--r--source/blender/editors/screen/area.c204
-rw-r--r--source/blender/editors/screen/screen_edit.c21
-rw-r--r--source/blender/editors/screen/screen_ops.c160
-rw-r--r--source/blender/editors/screen/screendump.c24
-rw-r--r--source/blender/editors/sculpt_paint/SConscript7
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c111
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h7
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c46
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c44
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c13
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
-rw-r--r--source/blender/editors/sound/sound_ops.c8
-rw-r--r--source/blender/editors/space_action/action_edit.c38
-rw-r--r--source/blender/editors/space_action/action_header.c86
-rw-r--r--source/blender/editors/space_action/action_intern.h2
-rw-r--r--source/blender/editors/space_action/action_ops.c7
-rw-r--r--source/blender/editors/space_action/space_action.c9
-rw-r--r--source/blender/editors/space_api/spacetypes.c11
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c3
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c6
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h27
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c988
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c102
-rw-r--r--source/blender/editors/space_console/console_ops.c99
-rw-r--r--source/blender/editors/space_console/space_console.c17
-rw-r--r--source/blender/editors/space_file/SConscript7
-rw-r--r--source/blender/editors/space_file/file_draw.c84
-rw-r--r--source/blender/editors/space_file/file_ops.c125
-rw-r--r--source/blender/editors/space_file/file_panels.c6
-rw-r--r--source/blender/editors/space_file/filelist.c364
-rw-r--r--source/blender/editors/space_file/filelist.h12
-rw-r--r--source/blender/editors/space_file/filesel.c91
-rw-r--r--source/blender/editors/space_file/space_file.c46
-rw-r--r--source/blender/editors/space_file/writeimage.c14
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c31
-rw-r--r--source/blender/editors/space_graph/graph_draw.c71
-rw-r--r--source/blender/editors/space_graph/graph_edit.c82
-rw-r--r--source/blender/editors/space_graph/graph_header.c24
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c10
-rw-r--r--source/blender/editors/space_graph/graph_select.c9
-rw-r--r--source/blender/editors/space_graph/graph_utils.c29
-rw-r--r--source/blender/editors/space_graph/space_graph.c17
-rw-r--r--source/blender/editors/space_image/image_buttons.c815
-rw-r--r--source/blender/editors/space_image/image_draw.c14
-rw-r--r--source/blender/editors/space_image/image_ops.c135
-rw-r--r--source/blender/editors/space_image/space_image.c139
-rw-r--r--source/blender/editors/space_info/info_ops.c10
-rw-r--r--source/blender/editors/space_logic/logic_buttons.c10
-rw-r--r--source/blender/editors/space_logic/logic_window.c276
-rw-r--r--source/blender/editors/space_logic/space_logic.c10
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c93
-rw-r--r--source/blender/editors/space_nla/nla_channels.c47
-rw-r--r--source/blender/editors/space_nla/nla_header.c26
-rw-r--r--source/blender/editors/space_nla/nla_ops.c12
-rw-r--r--source/blender/editors/space_nla/space_nla.c17
-rw-r--r--source/blender/editors/space_node/SConscript9
-rw-r--r--source/blender/editors/space_node/drawnode.c2393
-rw-r--r--source/blender/editors/space_node/node_draw.c237
-rw-r--r--source/blender/editors/space_node/node_edit.c295
-rw-r--r--source/blender/editors/space_node/node_intern.h10
-rw-r--r--source/blender/editors/space_node/node_ops.c18
-rw-r--r--source/blender/editors/space_node/node_select.c128
-rw-r--r--source/blender/editors/space_node/space_node.c6
-rw-r--r--source/blender/editors/space_outliner/outliner.c18
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c4
-rw-r--r--source/blender/editors/space_script/script_edit.c8
-rw-r--r--source/blender/editors/space_script/script_ops.c4
-rw-r--r--source/blender/editors/space_script/space_script.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c42
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c2
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c4
-rw-r--r--source/blender/editors/space_sound/space_sound.c4
-rw-r--r--source/blender/editors/space_text/space_text.c8
-rw-r--r--source/blender/editors/space_text/text_draw.c54
-rw-r--r--source/blender/editors/space_text/text_header.c11
-rw-r--r--source/blender/editors/space_text/text_ops.c22
-rw-r--r--source/blender/editors/space_time/space_time.c4
-rw-r--r--source/blender/editors/space_time/time_ops.c2
-rw-r--r--source/blender/editors/space_view3d/Makefile5
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c117
-rw-r--r--source/blender/editors/space_view3d/drawobject.c375
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c150
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c168
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c320
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c238
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c57
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h19
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c74
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c144
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c823
-rw-r--r--source/blender/editors/transform/transform.c1393
-rw-r--r--source/blender/editors/transform/transform.h66
-rw-r--r--source/blender/editors/transform/transform_conversions.c292
-rw-r--r--source/blender/editors/transform/transform_generics.c364
-rw-r--r--source/blender/editors/transform/transform_input.c48
-rw-r--r--source/blender/editors/transform/transform_manipulator.c19
-rw-r--r--source/blender/editors/transform/transform_ops.c126
-rw-r--r--source/blender/editors/transform/transform_orientations.c291
-rw-r--r--source/blender/editors/transform/transform_snap.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c28
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c43
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c11
-rw-r--r--source/blender/gpu/intern/gpu_material.c107
-rw-r--r--source/blender/gpu/intern/gpu_shader_material.glsl42
-rw-r--r--source/blender/ikplugin/BIK_api.h93
-rw-r--r--source/blender/ikplugin/CMakeLists.txt (renamed from release/scripts/vertexpaint_gradient.py)45
-rw-r--r--source/blender/ikplugin/Makefile31
-rw-r--r--source/blender/ikplugin/SConscript9
-rw-r--r--source/blender/ikplugin/intern/Makefile51
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c138
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.h60
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c530
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.h47
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp1777
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.h52
-rw-r--r--source/blender/imbuf/intern/anim.c36
-rw-r--r--source/blender/imbuf/intern/divers.c14
-rw-r--r--source/blender/imbuf/intern/jp2.c4
-rw-r--r--source/blender/makesdna/DNA_ID.h65
-rw-r--r--source/blender/makesdna/DNA_action_types.h92
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h21
-rw-r--r--source/blender/makesdna/DNA_anim_types.h7
-rw-r--r--source/blender/makesdna/DNA_armature_types.h6
-rw-r--r--source/blender/makesdna/DNA_brush_types.h4
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h2
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h47
-rw-r--r--source/blender/makesdna/DNA_curve_types.h1
-rw-r--r--source/blender/makesdna/DNA_material_types.h46
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h29
-rw-r--r--source/blender/makesdna/DNA_node_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_fluidsim.h1
-rw-r--r--source/blender/makesdna/DNA_object_force.h125
-rw-r--r--source/blender/makesdna/DNA_object_types.h21
-rw-r--r--source/blender/makesdna/DNA_particle_types.h40
-rw-r--r--source/blender/makesdna/DNA_scene_types.h25
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h17
-rw-r--r--source/blender/makesdna/DNA_space_types.h34
-rw-r--r--source/blender/makesdna/DNA_texture_types.h27
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h6
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h11
-rw-r--r--source/blender/makesrna/RNA_access.h5
-rw-r--r--source/blender/makesrna/RNA_define.h3
-rw-r--r--source/blender/makesrna/RNA_types.h17
-rw-r--r--source/blender/makesrna/SConscript10
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt6
-rw-r--r--source/blender/makesrna/intern/Makefile1
-rw-r--r--source/blender/makesrna/intern/SConscript12
-rw-r--r--source/blender/makesrna/intern/makesrna.c11
-rw-r--r--source/blender/makesrna/intern/rna_ID.c21
-rw-r--r--source/blender/makesrna/intern/rna_access.c53
-rw-r--r--source/blender/makesrna/intern/rna_action.c6
-rw-r--r--source/blender/makesrna/intern/rna_action_api.c80
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c1
-rw-r--r--source/blender/makesrna/intern/rna_animation.c15
-rw-r--r--source/blender/makesrna/intern/rna_armature.c115
-rw-r--r--source/blender/makesrna/intern/rna_boid.c27
-rw-r--r--source/blender/makesrna/intern/rna_brush.c141
-rw-r--r--source/blender/makesrna/intern/rna_camera.c21
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c5
-rw-r--r--source/blender/makesrna/intern/rna_color.c6
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c126
-rw-r--r--source/blender/makesrna/intern/rna_curve.c34
-rw-r--r--source/blender/makesrna/intern/rna_define.c43
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c10
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c9
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c14
-rw-r--r--source/blender/makesrna/intern/rna_group.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c183
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c101
-rw-r--r--source/blender/makesrna/intern/rna_internal.h10
-rw-r--r--source/blender/makesrna/intern/rna_key.c12
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c187
-rw-r--r--source/blender/makesrna/intern/rna_main.c4
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c133
-rw-r--r--source/blender/makesrna/intern/rna_material.c611
-rw-r--r--source/blender/makesrna/intern/rna_material_api.c126
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c16
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c200
-rw-r--r--source/blender/makesrna/intern/rna_meta.c4
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c27
-rw-r--r--source/blender/makesrna/intern/rna_nla.c6
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c453
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_object.c197
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c400
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c430
-rw-r--r--source/blender/makesrna/intern/rna_particle.c258
-rw-r--r--source/blender/makesrna/intern/rna_pose.c471
-rw-r--r--source/blender/makesrna/intern/rna_pose_api.c (renamed from source/blender/editors/preview/previewrender_intern.h)33
-rw-r--r--source/blender/makesrna/intern/rna_rna.c82
-rw-r--r--source/blender/makesrna/intern/rna_scene.c212
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c78
-rw-r--r--source/blender/makesrna/intern/rna_screen.c6
-rw-r--r--source/blender/makesrna/intern/rna_sensor.c68
-rw-r--r--source/blender/makesrna/intern/rna_sequence.c45
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c6
-rw-r--r--source/blender/makesrna/intern/rna_space.c102
-rw-r--r--source/blender/makesrna/intern/rna_text.c8
-rw-r--r--source/blender/makesrna/intern/rna_text_api.c49
-rw-r--r--source/blender/makesrna/intern/rna_texture.c430
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c45
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c381
-rw-r--r--source/blender/makesrna/intern/rna_wm.c10
-rw-r--r--source/blender/makesrna/intern/rna_world.c111
-rw-r--r--source/blender/nodes/CMakeLists.txt4
-rw-r--r--source/blender/nodes/SConscript7
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_composite.c7
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_image.c10
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_levels.c4
-rw-r--r--source/blender/nodes/intern/CMP_util.c9
-rw-r--r--source/blender/nodes/intern/TEX_util.c14
-rw-r--r--source/blender/nodes/intern/TEX_util.h2
-rw-r--r--source/blender/python/epy_doc_gen.py2
-rw-r--r--source/blender/python/generic/Mathutils.c4
-rw-r--r--source/blender/python/intern/bpy_interface.c142
-rw-r--r--source/blender/python/intern/bpy_operator.c81
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c42
-rw-r--r--source/blender/python/intern/bpy_rna.c138
-rw-r--r--source/blender/render/CMakeLists.txt4
-rw-r--r--source/blender/render/SConscript8
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h7
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h2
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h1
-rw-r--r--source/blender/render/intern/include/render_types.h4
-rw-r--r--source/blender/render/intern/include/volume_precache.h2
-rw-r--r--source/blender/render/intern/include/volumetric.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c61
-rw-r--r--source/blender/render/intern/source/pipeline.c172
-rw-r--r--source/blender/render/intern/source/pointdensity.c5
-rw-r--r--source/blender/render/intern/source/rayshade.c6
-rw-r--r--source/blender/render/intern/source/renderdatabase.c10
-rw-r--r--source/blender/render/intern/source/sss.c17
-rw-r--r--source/blender/render/intern/source/texture.c121
-rw-r--r--source/blender/render/intern/source/volume_precache.c53
-rw-r--r--source/blender/render/intern/source/volumetric.c286
-rw-r--r--source/blender/render/intern/source/voxeldata.c14
-rw-r--r--source/blender/windowmanager/SConscript7
-rw-r--r--source/blender/windowmanager/WM_api.h27
-rw-r--r--source/blender/windowmanager/WM_types.h15
-rw-r--r--source/blender/windowmanager/intern/wm.c8
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c187
-rw-r--r--source/blender/windowmanager/intern/wm_files.c5
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c11
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c33
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c39
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c352
-rw-r--r--source/blender/windowmanager/intern/wm_window.c88
-rw-r--r--source/blender/windowmanager/wm_event_system.h2
-rw-r--r--source/blender/windowmanager/wm_event_types.h12
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c18
-rw-r--r--source/creator/CMakeLists.txt79
-rw-r--r--source/creator/SConscript5
-rw-r--r--source/creator/creator.c19
-rw-r--r--source/darwin/Makefile2
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp48
-rw-r--r--source/gameengine/BlenderRoutines/CMakeLists.txt8
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp1
-rw-r--r--source/gameengine/BlenderRoutines/Makefile1
-rw-r--r--source/gameengine/BlenderRoutines/SConscript7
-rw-r--r--source/gameengine/CMakeLists.txt5
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp10
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h5
-rw-r--r--source/gameengine/Converter/BL_ArmatureActuator.cpp267
-rw-r--r--source/gameengine/Converter/BL_ArmatureActuator.h93
-rw-r--r--source/gameengine/Converter/BL_ArmatureChannel.cpp469
-rw-r--r--source/gameengine/Converter/BL_ArmatureChannel.h95
-rw-r--r--source/gameengine/Converter/BL_ArmatureConstraint.cpp454
-rw-r--r--source/gameengine/Converter/BL_ArmatureConstraint.h118
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp496
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.h57
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp17
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.h1
-rw-r--r--source/gameengine/Converter/BL_ShapeActionActuator.cpp4
-rw-r--r--source/gameengine/Converter/BL_ShapeActionActuator.h6
-rw-r--r--source/gameengine/Converter/CMakeLists.txt8
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp9
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h4
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp10
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp16
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.h3
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.cpp3
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp27
-rw-r--r--source/gameengine/Converter/Makefile1
-rw-r--r--source/gameengine/Converter/SConscript13
-rw-r--r--source/gameengine/Expressions/BoolValue.cpp4
-rw-r--r--source/gameengine/Expressions/BoolValue.h2
-rw-r--r--source/gameengine/Expressions/CMakeLists.txt8
-rw-r--r--source/gameengine/Expressions/FloatValue.cpp4
-rw-r--r--source/gameengine/Expressions/FloatValue.h2
-rw-r--r--source/gameengine/Expressions/IntValue.cpp3
-rw-r--r--source/gameengine/Expressions/IntValue.h3
-rw-r--r--source/gameengine/Expressions/KX_Python.h4
-rw-r--r--source/gameengine/Expressions/ListValue.cpp526
-rw-r--r--source/gameengine/Expressions/ListValue.h3
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp475
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h238
-rw-r--r--source/gameengine/Expressions/SConscript12
-rw-r--r--source/gameengine/Expressions/StringValue.h2
-rw-r--r--source/gameengine/Expressions/Value.cpp14
-rw-r--r--source/gameengine/Expressions/Value.h22
-rw-r--r--source/gameengine/GameLogic/CMakeLists.txt7
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.h2
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.h6
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.h2
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_BasicEventManager.cpp61
-rw-r--r--source/gameengine/GameLogic/SCA_BasicEventManager.h57
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h8
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h32
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h4
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h4
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp33
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h17
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.h2
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.h2
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp21
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h12
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.h2
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp29
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp36
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h14
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.h5
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.h2
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.cpp3
-rw-r--r--source/gameengine/GameLogic/SConscript8
-rw-r--r--source/gameengine/GamePlayer/common/SConscript10
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp3
-rw-r--r--source/gameengine/GamePlayer/ghost/SConscript8
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp4
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h2
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt7
-rw-r--r--source/gameengine/Ketsji/KXNetwork/CMakeLists.txt7
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h1
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h4
-rw-r--r--source/gameengine/Ketsji/KXNetwork/SConscript9
-rw-r--r--source/gameengine/Ketsji/KX_ArmatureSensor.cpp208
-rw-r--r--source/gameengine/Ketsji/KX_ArmatureSensor.h89
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp25
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h2
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h4
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.h2
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp71
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp96
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h41
-rw-r--r--source/gameengine/Ketsji/KX_ISceneConverter.h1
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp18
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h11
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_Light.h6
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.h4
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h4
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp38
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h7
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h4
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.h4
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h5
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.h4
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.h5
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp104
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h3
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp67
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.h2
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.cpp39
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.h8
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_RayEventManager.h5
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h3
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp18
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h6
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h1
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h5
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.h3
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h4
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/SConscript8
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp2
-rw-r--r--source/gameengine/Physics/Bullet/SConscript10
-rw-r--r--source/gameengine/PyDoc/GameTypes.py334
-rw-r--r--source/gameengine/PyDoc/SConscript7
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp2
-rw-r--r--source/gameengine/Rasterizer/SConscript10
-rw-r--r--source/gameengine/SConscript6
-rw-r--r--source/gameengine/SceneGraph/SG_DList.h79
-rw-r--r--source/gameengine/VideoTexture/CMakeLists.txt7
-rw-r--r--source/gameengine/VideoTexture/SConscript8
-rw-r--r--source/nan_compile.mk140
-rw-r--r--source/nan_definitions.mk20
-rw-r--r--source/nan_warn.mk51
-rw-r--r--tools/Blender.py7
-rwxr-xr-xtools/btools.py15
1218 files changed, 92945 insertions, 109904 deletions
diff --git a/CMake/macros.cmake b/CMake/macros.cmake
index 6a337505c00..e8f378c0925 100644
--- a/CMake/macros.cmake
+++ b/CMake/macros.cmake
@@ -85,30 +85,24 @@ ENDMACRO(SETUP_LIBDIRS)
MACRO(SETUP_LIBLINKS
target)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ")
- #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIBRARY} ${LLIBS})
- TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS})
+ TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS})
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
- IF(WIN32)
- TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
- TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
- ELSE(WIN32)
- TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
- ENDIF(WIN32)
+ IF(WITH_PYTHON)
+ TARGET_LINK_LIBRARIES(${target} ${PYTHON_LINKFLAGS})
+
+ IF(WIN32)
+ TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
+ TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
+ ELSE(WIN32)
+ TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
+ ENDIF(WIN32)
+ ENDIF(WITH_PYTHON)
- TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${LLIBS})
+ TARGET_LINK_LIBRARIES(${target} ${OPENGL_glu_LIBRARY} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB})
TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIBRARY} ${LIBSAMPLERATE_LIB})
- # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
-
- IF(WIN32)
- TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
- TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
- ELSE(WIN32)
- TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
- ENDIF(WIN32)
-
IF(WITH_INTERNATIONAL)
TARGET_LINK_LIBRARIES(${target} ${GETTEXT_LIB})
ENDIF(WITH_INTERNATIONAL)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7196049f964..d53f4ed9966 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,6 +51,10 @@ PROJECT(Blender)
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
+# Note! - Could create this from the blender version string
+# ...but thats quite involved, make sure this matches the blender version.
+SET(BLENDER_VERSION 2.5)
+
#-----------------------------------------------------------------------------
# Set default config options
OPTION(WITH_PLAYER "Build Player" OFF)
@@ -71,10 +75,16 @@ OPTION(WITH_WEBPLUGIN "Enable Web Plugin (Unix only)" OFF)
OPTION(WITH_FFTW3 "Enable FFTW3 support" OFF)
OPTION(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF)
OPTION(WITH_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
+OPTION(WITH_LZO "Enable fast LZO compression, used for pointcache" ON)
+OPTION(WITH_LZMA "Enable best LZMA compression, used for pointcache" ON)
OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF)
-# OPTION(WITH_BUILDINFO "Include extra build details" ON)
+OPTION(WITH_BUILDINFO "Include extra build details" ON)
OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON)
+IF (APPLE)
+OPTION(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" OFF)
+ENDIF (APPLE)
+
IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
@@ -396,6 +406,7 @@ IF(APPLE)
FIND_PACKAGE(OpenAL)
IF(OPENAL_FOUND)
SET(WITH_OPENAL ON)
+ SET(OPENAL_INCLUDE_DIR "${OPENAL_INCLUDE_DIR};${LIBDIR}/openal/include")
ELSE(OPENAL_FOUND)
SET(WITH_OPENAL OFF)
ENDIF(OPENAL_FOUND)
@@ -409,7 +420,7 @@ IF(APPLE)
ENDIF(WITH_JACK)
IF(WITH_SNDFILE)
- SET(SNDFILE /usr)
+ SET(SNDFILE ${LIBDIR}/sndfile)
SET(SNDFILE_INC ${SNDFILE}/include)
SET(SNDFILE_LIB sndfile)
SET(SNDFILE_LIBPATH ${SNDFILE}/lib)
@@ -479,9 +490,13 @@ IF(APPLE)
SET(LLIBS stdc++ SystemStubs)
+ IF (WITH_COCOA)
+ SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DGHOST_COCOA")
+ SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
+ ELSE (WITH_COCOA)
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
-
+ ENDIF (WITH_COCOA)
IF(WITH_OPENMP)
SET(LLIBS "${LLIBS} -lgomp ")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
@@ -513,15 +528,15 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
-# TODO - buildinfo
-# IF(UNIX)
-# IF(WITH_BUILDINFO)
-# EXEC_PROGRAM("date \"+%Y-%m-%d\"" OUTPUT_VARIABLE BUILD_DATE)
-# EXEC_PROGRAM("date \"+%H:%M:%S\"" OUTPUT_VARIABLE BUILD_TIME)
-# EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV)
-# SET(BUILD_TYPE ${CMAKE_BUILD_TYPE})
-# ENDIF(WITH_BUILDINFO)
-# ENDIF(UNIX)
+# buildinfo
+IF(UNIX)
+ IF(WITH_BUILDINFO)
+ EXEC_PROGRAM("date \"+%Y-%m-%d\"" OUTPUT_VARIABLE BUILD_DATE)
+ EXEC_PROGRAM("date \"+%H:%M:%S\"" OUTPUT_VARIABLE BUILD_TIME)
+ EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV)
+ # BUILD_PLATFORM and BUILD_PLATFORM are taken from CMake
+ ENDIF(WITH_BUILDINFO)
+ENDIF(UNIX)
#-----------------------------------------------------------------------------
# Common.
diff --git a/SConstruct b/SConstruct
index 83ec6c1b718..4d6ef7ccb49 100644
--- a/SConstruct
+++ b/SConstruct
@@ -186,6 +186,15 @@ if not env['BF_FANCY']:
SetOption('num_jobs', int(env['BF_NUMJOBS']))
print "Build with %d parallel jobs" % (GetOption('num_jobs'))
+# BLENDERPATH is a unix only option to enable typical style paths this is
+# spesifically a data-dir, which is used a lot but cant replace BF_INSTALLDIR
+# because the blender binary is installed in $BF_INSTALLDIR/bin/blender
+
+if env['WITH_BF_FHS']:
+ BLENDERPATH = os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION'])
+else:
+ BLENDERPATH = env['BF_INSTALLDIR']
+
# disable elbeem (fluidsim) compilation?
if env['BF_NO_ELBEEM'] == 1:
env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
@@ -198,7 +207,7 @@ if env['WITH_BF_OPENMP'] == 1:
env['CPPFLAGS'].append('/openmp')
env['CXXFLAGS'].append('/openmp')
else:
- if env['CC'][-3:] == 'icc': # to be able to handle CC=/opt/bla/icc case
+ if env['CC'].endswith('icc'): # to be able to handle CC=/opt/bla/icc case
env.Append(LINKFLAGS=['-openmp', '-static-intel'])
env['CCFLAGS'].append('-openmp')
env['CPPFLAGS'].append('-openmp')
@@ -301,7 +310,7 @@ if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-min
# 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']
-B.doc_build_dir = env['BF_DOCDIR']
+B.doc_build_dir = os.path.join(BLENDERPATH, 'doc')
if not B.root_build_dir[-1]==os.sep:
B.root_build_dir += os.sep
if not B.doc_build_dir[-1]==os.sep:
@@ -426,7 +435,10 @@ if env['OURPLATFORM']=='darwin':
source=[dp+os.sep+f for f in df]
blenderinstall.append(env.Install(dir=dir,source=source))
else:
- blenderinstall = env.Install(dir=env['BF_INSTALLDIR'], source=B.program_list)
+ if env['WITH_BF_FHS']: dir= os.path.join(env['BF_INSTALLDIR'], 'bin')
+ else: dir= env['BF_INSTALLDIR']
+
+ blenderinstall = env.Install(dir=dir, source=B.program_list)
#-- .blender
#- dont do .blender and scripts for darwin, it is already in the bundle
@@ -450,7 +462,13 @@ if env['OURPLATFORM']!='darwin':
continue
dotblendlist.append(os.path.join(dp, f))
- dottargetlist.append(env['BF_INSTALLDIR']+dp[3:]+os.sep+f)
+ if env['WITH_BF_FHS']: dir= os.path.join(*([BLENDERPATH] + dp.split(os.sep)[2:])) # skip bin/.blender
+ else: dir= os.path.join(*([BLENDERPATH] + dp.split(os.sep)[1:])) # skip bin
+
+ # print dir+ os.sep + f
+ print dir
+ dottargetlist.append(dir + os.sep + f)
+
dotblenderinstall = []
for targetdir,srcfile in zip(dottargetlist, dotblendlist):
@@ -458,14 +476,18 @@ if env['OURPLATFORM']!='darwin':
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
if env['WITH_BF_PYTHON']:
- #-- .blender/scripts, .blender/ui, .blender/io
- scriptpaths=['release/scripts', 'release/ui', 'release/io']
+ #-- .blender/scripts
+ scriptpaths=['release/scripts']
for scriptpath in scriptpaths:
for dp, dn, df in os.walk(scriptpath):
if '.svn' in dn:
dn.remove('.svn')
- dir=env['BF_INSTALLDIR']+'/.blender/'+os.path.basename(scriptpath)+dp[len(scriptpath):]
- source=[dp+os.sep+f for f in df]
+
+ if env['WITH_BF_FHS']: dir = BLENDERPATH
+ else: dir = os.path.join(env['BF_INSTALLDIR'], '.blender')
+ dir += os.sep + os.path.basename(scriptpath) + dp[len(scriptpath):]
+
+ source=[os.path.join(dp, f) for f in df]
scriptinstall.append(env.Install(dir=dir,source=source))
#-- icons
@@ -477,8 +499,8 @@ if env['OURPLATFORM']=='linux2':
if '.svn' in tn:
tn.remove('.svn')
for f in tf:
- iconlist.append(tp+os.sep+f)
- icontargetlist.append(env['BF_INSTALLDIR']+tp[19:]+os.sep+f)
+ iconlist.append(os.path.join(tp, f))
+ icontargetlist.append( os.path.join(*([BLENDERPATH] + tp.split(os.sep)[2:] + [f])) )
iconinstall = []
for targetdir,srcfile in zip(icontargetlist, iconlist):
@@ -499,24 +521,25 @@ for tp, tn, tf in os.walk('release/plugins'):
if '.svn' in tn:
tn.remove('.svn')
for f in tf:
- pluglist.append(tp+os.sep+f)
- plugtargetlist.append(env['BF_INSTALLDIR']+tp[7:]+os.sep+f)
+ pluglist.append(os.path.join(tp, f))
+ plugtargetlist.append( os.path.join(*([BLENDERPATH] + tp.split(os.sep)[1:] + [f])) )
+
# header files for plugins
pluglist.append('source/blender/blenpluginapi/documentation.h')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'documentation.h')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'documentation.h'))
pluglist.append('source/blender/blenpluginapi/externdef.h')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'externdef.h')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'externdef.h'))
pluglist.append('source/blender/blenpluginapi/floatpatch.h')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'floatpatch.h')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'floatpatch.h'))
pluglist.append('source/blender/blenpluginapi/iff.h')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'iff.h')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'iff.h'))
pluglist.append('source/blender/blenpluginapi/plugin.h')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'plugin.h')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'plugin.h'))
pluglist.append('source/blender/blenpluginapi/util.h')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'util.h')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'util.h'))
pluglist.append('source/blender/blenpluginapi/plugin.DEF')
-plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep + 'plugin.def')
+plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'plugin.def'))
plugininstall = []
for targetdir,srcfile in zip(plugtargetlist, pluglist):
@@ -531,7 +554,7 @@ for tp, tn, tf in os.walk('release/text'):
for f in tf:
textlist.append(tp+os.sep+f)
-textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
+textinstall = env.Install(dir=BLENDERPATH, source=textlist)
if env['OURPLATFORM']=='darwin':
allinstall = [blenderinstall, plugininstall, textinstall]
@@ -560,9 +583,9 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc'):
dllsources.append('${LCGDIR}/release/python' + ver + '.zip')
dllsources.append('${LCGDIR}/release/zlib.pyd')
if env['BF_DEBUG']:
- dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_LIB}_d.dll')
+ dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll')
else:
- dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_LIB}.dll')
+ dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}.dll')
if env['WITH_BF_ICONV']:
if env['OURPLATFORM'] == 'win64-vc':
pass # we link statically to iconv on win64
@@ -620,7 +643,6 @@ if env['WITH_BF_DOCS']:
except: epydoc = None
if epydoc:
- SConscript('source/blender/python/api2_2x/doc/SConscript')
SConscript('source/gameengine/PyDoc/SConscript')
else:
print "No epydoc install detected, Python API and Gameengine API Docs will not be generated "
diff --git a/config/darwin-config.py b/config/darwin-config.py
index 92f70d716fc..981f321e5bc 100644
--- a/config/darwin-config.py
+++ b/config/darwin-config.py
@@ -274,4 +274,3 @@ BF_DEBUG_CCFLAGS = ['-g']
BF_BUILDDIR='../build/darwin'
BF_INSTALLDIR='../install/darwin'
-BF_DOCDIR='../install/doc'
diff --git a/config/irix6-config.py b/config/irix6-config.py
index d38665f282a..085d1dd1e62 100644
--- a/config/irix6-config.py
+++ b/config/irix6-config.py
@@ -189,7 +189,6 @@ BF_DEBUG_FLAGS = '-g'
BF_BUILDDIR = '../build/irix6'
BF_INSTALLDIR='../install/irix6'
-BF_DOCDIR='../install/doc'
#Link against pthread
LDIRS = []
diff --git a/config/linux2-config.py b/config/linux2-config.py
index 757b8210e49..026d0a200a5 100644
--- a/config/linux2-config.py
+++ b/config/linux2-config.py
@@ -189,8 +189,6 @@ BF_DEBUG_CCFLAGS = ['-g']
BF_BUILDDIR = '../build/linux2'
BF_INSTALLDIR='../install/linux2'
-BF_DOCDIR='../install/doc'
-
#Link against pthread
PLATFORM_LINKFLAGS = ['-pthread']
diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py
index a7ce2dc2908..a5c83dc3503 100644
--- a/config/linuxcross-config.py
+++ b/config/linuxcross-config.py
@@ -139,4 +139,3 @@ BF_PROFILE_LINKFLAGS = ['-pg']
BF_BUILDDIR = '../build/linuxcross'
BF_INSTALLDIR='../install/linuxcross'
-BF_DOCDIR='../install/doc'
diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py
index 95649321c07..353d30f50b3 100644
--- a/config/openbsd3-config.py
+++ b/config/openbsd3-config.py
@@ -151,4 +151,3 @@ BF_DEBUG_CCFLAGS = ['-g']
BF_BUILDDIR='../build/openbsd3'
BF_INSTALLDIR='../install/openbsd3'
-BF_DOCDIR='../install/doc'
diff --git a/config/sunos5-config.py b/config/sunos5-config.py
index 8af30e4f4f3..8e4c53b5bc4 100644
--- a/config/sunos5-config.py
+++ b/config/sunos5-config.py
@@ -165,7 +165,6 @@ BF_DEBUG_CCFLAGS = []
BF_BUILDDIR = '../build/sunos5'
BF_INSTALLDIR='../install/sunos5'
-BF_DOCDIR='../install/doc'
PLATFORM_LINKFLAGS = []
diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py
index e3834c41a81..6b10b410715 100644
--- a/config/win32-mingw-config.py
+++ b/config/win32-mingw-config.py
@@ -6,7 +6,8 @@ BF_PYTHON_VERSION = '3.1'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
-BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}'
+BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
+BF_PYTHON_DLL = 'python31'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a'
@@ -152,4 +153,3 @@ BF_PROFILE = False
BF_BUILDDIR = '..\\build\\win32-mingw'
BF_INSTALLDIR='..\\install\\win32-mingw'
-BF_DOCDIR = '..\\install\\doc'
diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py
index 1e993565e98..291aa023ec8 100644
--- a/config/win32-vc-config.py
+++ b/config/win32-vc-config.py
@@ -13,6 +13,7 @@ BF_PYTHON_VERSION = '3.1'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python31'
+BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = True
@@ -173,4 +174,3 @@ PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/INCREMENTAL:NO','/N
BF_BUILDDIR = '..\\build\\win32-vc'
BF_INSTALLDIR='..\\install\\win32-vc'
-BF_DOCDIR='..\\install\\doc'
diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py
index f2fc3190ac9..8087d36008a 100644
--- a/config/win64-vc-config.py
+++ b/config/win64-vc-config.py
@@ -14,6 +14,7 @@ BF_PYTHON_VERSION = '3.1'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python31'
+BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = False
@@ -223,7 +224,6 @@ PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/INCREMENTAL:NO','/NO
BF_BUILDDIR = '..\\build\\blender25-win64-vc'
BF_INSTALLDIR='..\\install\\blender25-win64-vc'
-BF_DOCDIR='..\\install\\blender25-win64-vc\\doc'
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 44e47aaf88d..35271d24a2d 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -38,5 +38,10 @@ IF(WITH_OPENJPEG)
ADD_SUBDIRECTORY(libopenjpeg)
ENDIF(WITH_OPENJPEG)
-ADD_SUBDIRECTORY(lzo)
-ADD_SUBDIRECTORY(lzma)
+IF(WITH_LZO)
+ ADD_SUBDIRECTORY(lzo)
+ENDIF(WITH_LZO)
+
+IF(WITH_LZMA)
+ ADD_SUBDIRECTORY(lzma)
+ENDIF(WITH_LZMA)
diff --git a/extern/Eigen2/Eigen/Array b/extern/Eigen2/Eigen/Array
new file mode 100644
index 00000000000..c847f9521fe
--- /dev/null
+++ b/extern/Eigen2/Eigen/Array
@@ -0,0 +1,39 @@
+#ifndef EIGEN_ARRAY_MODULE_H
+#define EIGEN_ARRAY_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+namespace Eigen {
+
+/** \defgroup Array_Module Array module
+ * This module provides several handy features to manipulate matrices as simple array of values.
+ * In addition to listed classes, it defines various methods of the Cwise interface
+ * (accessible from MatrixBase::cwise()), including:
+ * - matrix-scalar sum,
+ * - coeff-wise comparison operators,
+ * - sin, cos, sqrt, pow, exp, log, square, cube, inverse (reciprocal).
+ *
+ * This module also provides various MatrixBase methods, including:
+ * - \ref MatrixBase::all() "all", \ref MatrixBase::any() "any",
+ * - \ref MatrixBase::Random() "random matrix initialization"
+ *
+ * \code
+ * #include <Eigen/Array>
+ * \endcode
+ */
+
+#include "src/Array/CwiseOperators.h"
+#include "src/Array/Functors.h"
+#include "src/Array/BooleanRedux.h"
+#include "src/Array/Select.h"
+#include "src/Array/PartialRedux.h"
+#include "src/Array/Random.h"
+#include "src/Array/Norms.h"
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_ARRAY_MODULE_H
diff --git a/extern/Eigen2/Eigen/Cholesky b/extern/Eigen2/Eigen/Cholesky
new file mode 100644
index 00000000000..f1806f726c7
--- /dev/null
+++ b/extern/Eigen2/Eigen/Cholesky
@@ -0,0 +1,65 @@
+#ifndef EIGEN_CHOLESKY_MODULE_H
+#define EIGEN_CHOLESKY_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
+#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)
+ #ifndef EIGEN_HIDE_HEAVY_CODE
+ #define EIGEN_HIDE_HEAVY_CODE
+ #endif
+#elif defined EIGEN_HIDE_HEAVY_CODE
+ #undef EIGEN_HIDE_HEAVY_CODE
+#endif
+
+namespace Eigen {
+
+/** \defgroup Cholesky_Module Cholesky module
+ *
+ * \nonstableyet
+ *
+ * This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
+ * Those decompositions are accessible via the following MatrixBase methods:
+ * - MatrixBase::llt(),
+ * - MatrixBase::ldlt()
+ *
+ * \code
+ * #include <Eigen/Cholesky>
+ * \endcode
+ */
+
+#include "src/Array/CwiseOperators.h"
+#include "src/Array/Functors.h"
+#include "src/Cholesky/LLT.h"
+#include "src/Cholesky/LDLT.h"
+
+} // namespace Eigen
+
+#define EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MATRIXTYPE,PREFIX) \
+ PREFIX template class LLT<MATRIXTYPE>; \
+ PREFIX template class LDLT<MATRIXTYPE>
+
+#define EIGEN_CHOLESKY_MODULE_INSTANTIATE(PREFIX) \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix2f,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix2d,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix3f,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix3d,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix4f,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix4d,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXf,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXd,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXcf,PREFIX); \
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXcd,PREFIX)
+
+#ifdef EIGEN_EXTERN_INSTANTIATIONS
+
+namespace Eigen {
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE(extern);
+} // namespace Eigen
+#endif
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_CHOLESKY_MODULE_H
diff --git a/extern/Eigen2/Eigen/Core b/extern/Eigen2/Eigen/Core
new file mode 100644
index 00000000000..f5e315a2c9d
--- /dev/null
+++ b/extern/Eigen2/Eigen/Core
@@ -0,0 +1,154 @@
+#ifndef EIGEN_CORE_H
+#define EIGEN_CORE_H
+
+// first thing Eigen does: prevent MSVC from committing suicide
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+#ifdef _MSC_VER
+ #include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
+ #if (_MSC_VER >= 1500) // 2008 or later
+ // Remember that usage of defined() in a #define is undefined by the standard.
+ // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
+ #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
+ #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
+ #endif
+ #endif
+#endif
+
+#ifdef __GNUC__
+ #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
+#else
+ #define EIGEN_GNUC_AT_LEAST(x,y) 0
+#endif
+
+// Remember that usage of defined() in a #define is undefined by the standard
+#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
+ #define EIGEN_SSE2_BUT_NOT_OLD_GCC
+#endif
+
+#ifndef EIGEN_DONT_VECTORIZE
+ #if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
+ #define EIGEN_VECTORIZE
+ #define EIGEN_VECTORIZE_SSE
+ #include <emmintrin.h>
+ #include <xmmintrin.h>
+ #ifdef __SSE3__
+ #include <pmmintrin.h>
+ #endif
+ #ifdef __SSSE3__
+ #include <tmmintrin.h>
+ #endif
+ #elif defined __ALTIVEC__
+ #define EIGEN_VECTORIZE
+ #define EIGEN_VECTORIZE_ALTIVEC
+ #include <altivec.h>
+ // We need to #undef all these ugly tokens defined in <altivec.h>
+ // => use __vector instead of vector
+ #undef bool
+ #undef vector
+ #undef pixel
+ #endif
+#endif
+
+#include <cstdlib>
+#include <cmath>
+#include <complex>
+#include <cassert>
+#include <functional>
+#include <iostream>
+#include <cstring>
+#include <string>
+#include <limits>
+
+#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_NO_EXCEPTIONS)
+ #define EIGEN_EXCEPTIONS
+#endif
+
+#ifdef EIGEN_EXCEPTIONS
+ #include <new>
+#endif
+
+// this needs to be done after all possible windows C header includes and before any Eigen source includes
+// (system C++ includes are supposed to be able to deal with this already):
+// windows.h defines min and max macros which would make Eigen fail to compile.
+#if defined(min) || defined(max)
+#error The preprocessor symbols 'min' or 'max' are defined. If you are compiling on Windows, do #define NOMINMAX to prevent windows.h from defining these symbols.
+#endif
+
+namespace Eigen {
+
+/** \defgroup Core_Module Core module
+ * This is the main module of Eigen providing dense matrix and vector support
+ * (both fixed and dynamic size) with all the features corresponding to a BLAS library
+ * and much more...
+ *
+ * \code
+ * #include <Eigen/Core>
+ * \endcode
+ */
+
+#include "src/Core/util/Macros.h"
+#include "src/Core/util/Constants.h"
+#include "src/Core/util/ForwardDeclarations.h"
+#include "src/Core/util/Meta.h"
+#include "src/Core/util/XprHelper.h"
+#include "src/Core/util/StaticAssert.h"
+#include "src/Core/util/Memory.h"
+
+#include "src/Core/NumTraits.h"
+#include "src/Core/MathFunctions.h"
+#include "src/Core/GenericPacketMath.h"
+
+#if defined EIGEN_VECTORIZE_SSE
+ #include "src/Core/arch/SSE/PacketMath.h"
+#elif defined EIGEN_VECTORIZE_ALTIVEC
+ #include "src/Core/arch/AltiVec/PacketMath.h"
+#endif
+
+#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
+#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 16
+#endif
+
+#include "src/Core/Functors.h"
+#include "src/Core/MatrixBase.h"
+#include "src/Core/Coeffs.h"
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
+ // at least confirmed with Doxygen 1.5.5 and 1.5.6
+ #include "src/Core/Assign.h"
+#endif
+
+#include "src/Core/MatrixStorage.h"
+#include "src/Core/NestByValue.h"
+#include "src/Core/Flagged.h"
+#include "src/Core/Matrix.h"
+#include "src/Core/Cwise.h"
+#include "src/Core/CwiseBinaryOp.h"
+#include "src/Core/CwiseUnaryOp.h"
+#include "src/Core/CwiseNullaryOp.h"
+#include "src/Core/Dot.h"
+#include "src/Core/Product.h"
+#include "src/Core/DiagonalProduct.h"
+#include "src/Core/SolveTriangular.h"
+#include "src/Core/MapBase.h"
+#include "src/Core/Map.h"
+#include "src/Core/Block.h"
+#include "src/Core/Minor.h"
+#include "src/Core/Transpose.h"
+#include "src/Core/DiagonalMatrix.h"
+#include "src/Core/DiagonalCoeffs.h"
+#include "src/Core/Sum.h"
+#include "src/Core/Redux.h"
+#include "src/Core/Visitor.h"
+#include "src/Core/Fuzzy.h"
+#include "src/Core/IO.h"
+#include "src/Core/Swap.h"
+#include "src/Core/CommaInitializer.h"
+#include "src/Core/Part.h"
+#include "src/Core/CacheFriendlyProduct.h"
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_CORE_H
diff --git a/extern/Eigen2/Eigen/Dense b/extern/Eigen2/Eigen/Dense
new file mode 100644
index 00000000000..9655edcd7aa
--- /dev/null
+++ b/extern/Eigen2/Eigen/Dense
@@ -0,0 +1,8 @@
+#include "Core"
+#include "Array"
+#include "LU"
+#include "Cholesky"
+#include "QR"
+#include "SVD"
+#include "Geometry"
+#include "LeastSquares"
diff --git a/extern/Eigen2/Eigen/Eigen b/extern/Eigen2/Eigen/Eigen
new file mode 100644
index 00000000000..654c8dc6380
--- /dev/null
+++ b/extern/Eigen2/Eigen/Eigen
@@ -0,0 +1,2 @@
+#include "Dense"
+#include "Sparse"
diff --git a/extern/Eigen2/Eigen/Geometry b/extern/Eigen2/Eigen/Geometry
new file mode 100644
index 00000000000..617b25eb6f5
--- /dev/null
+++ b/extern/Eigen2/Eigen/Geometry
@@ -0,0 +1,51 @@
+#ifndef EIGEN_GEOMETRY_MODULE_H
+#define EIGEN_GEOMETRY_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+#include "Array"
+#include <limits>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+namespace Eigen {
+
+/** \defgroup Geometry_Module Geometry module
+ *
+ * \nonstableyet
+ *
+ * This module provides support for:
+ * - fixed-size homogeneous transformations
+ * - translation, scaling, 2D and 3D rotations
+ * - quaternions
+ * - \ref MatrixBase::cross() "cross product"
+ * - \ref MatrixBase::unitOrthogonal() "orthognal vector generation"
+ * - some linear components: parametrized-lines and hyperplanes
+ *
+ * \code
+ * #include <Eigen/Geometry>
+ * \endcode
+ */
+
+#include "src/Geometry/OrthoMethods.h"
+#include "src/Geometry/RotationBase.h"
+#include "src/Geometry/Rotation2D.h"
+#include "src/Geometry/Quaternion.h"
+#include "src/Geometry/AngleAxis.h"
+#include "src/Geometry/EulerAngles.h"
+#include "src/Geometry/Transform.h"
+#include "src/Geometry/Translation.h"
+#include "src/Geometry/Scaling.h"
+#include "src/Geometry/Hyperplane.h"
+#include "src/Geometry/ParametrizedLine.h"
+#include "src/Geometry/AlignedBox.h"
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_GEOMETRY_MODULE_H
diff --git a/extern/Eigen2/Eigen/LU b/extern/Eigen2/Eigen/LU
new file mode 100644
index 00000000000..0ce69456598
--- /dev/null
+++ b/extern/Eigen2/Eigen/LU
@@ -0,0 +1,29 @@
+#ifndef EIGEN_LU_MODULE_H
+#define EIGEN_LU_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+namespace Eigen {
+
+/** \defgroup LU_Module LU module
+ * This module includes %LU decomposition and related notions such as matrix inversion and determinant.
+ * This module defines the following MatrixBase methods:
+ * - MatrixBase::inverse()
+ * - MatrixBase::determinant()
+ *
+ * \code
+ * #include <Eigen/LU>
+ * \endcode
+ */
+
+#include "src/LU/LU.h"
+#include "src/LU/Determinant.h"
+#include "src/LU/Inverse.h"
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_LU_MODULE_H
diff --git a/extern/Eigen2/Eigen/LeastSquares b/extern/Eigen2/Eigen/LeastSquares
new file mode 100644
index 00000000000..573a13cb42f
--- /dev/null
+++ b/extern/Eigen2/Eigen/LeastSquares
@@ -0,0 +1,27 @@
+#ifndef EIGEN_REGRESSION_MODULE_H
+#define EIGEN_REGRESSION_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+#include "QR"
+#include "Geometry"
+
+namespace Eigen {
+
+/** \defgroup LeastSquares_Module LeastSquares module
+ * This module provides linear regression and related features.
+ *
+ * \code
+ * #include <Eigen/LeastSquares>
+ * \endcode
+ */
+
+#include "src/LeastSquares/LeastSquares.h"
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_REGRESSION_MODULE_H
diff --git a/extern/Eigen2/Eigen/NewStdVector b/extern/Eigen2/Eigen/NewStdVector
new file mode 100644
index 00000000000..f37de5ff673
--- /dev/null
+++ b/extern/Eigen2/Eigen/NewStdVector
@@ -0,0 +1,168 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_STDVECTOR_MODULE_H
+#define EIGEN_STDVECTOR_MODULE_H
+
+#include "Core"
+#include <vector>
+
+namespace Eigen {
+
+// This one is needed to prevent reimplementing the whole std::vector.
+template <class T>
+class aligned_allocator_indirection : public aligned_allocator<T>
+{
+public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T value_type;
+
+ template<class U>
+ struct rebind
+ {
+ typedef aligned_allocator_indirection<U> other;
+ };
+
+ aligned_allocator_indirection() throw() {}
+ aligned_allocator_indirection(const aligned_allocator_indirection& ) throw() : aligned_allocator<T>() {}
+ aligned_allocator_indirection(const aligned_allocator<T>& ) throw() {}
+ template<class U>
+ aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) throw() {}
+ template<class U>
+ aligned_allocator_indirection(const aligned_allocator<U>& ) throw() {}
+ ~aligned_allocator_indirection() throw() {}
+};
+
+#ifdef _MSC_VER
+
+ // sometimes, MSVC detects, at compile time, that the argument x
+ // in std::vector::resize(size_t s,T x) won't be aligned and generate an error
+ // even if this function is never called. Whence this little wrapper.
+ #define EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) Eigen::ei_workaround_msvc_std_vector<T>
+ template<typename T> struct ei_workaround_msvc_std_vector : public T
+ {
+ inline ei_workaround_msvc_std_vector() : T() {}
+ inline ei_workaround_msvc_std_vector(const T& other) : T(other) {}
+ inline operator T& () { return *static_cast<T*>(this); }
+ inline operator const T& () const { return *static_cast<const T*>(this); }
+ template<typename OtherT>
+ inline T& operator=(const OtherT& other)
+ { T::operator=(other); return *this; }
+ inline ei_workaround_msvc_std_vector& operator=(const ei_workaround_msvc_std_vector& other)
+ { T::operator=(other); return *this; }
+ };
+
+#else
+
+ #define EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) T
+
+#endif
+
+}
+
+namespace std {
+
+#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
+ public: \
+ typedef T value_type; \
+ typedef typename vector_base::allocator_type allocator_type; \
+ typedef typename vector_base::size_type size_type; \
+ typedef typename vector_base::iterator iterator; \
+ typedef typename vector_base::const_iterator const_iterator; \
+ explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
+ template<typename InputIterator> \
+ vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
+ : vector_base(first, last, a) {} \
+ vector(const vector& c) : vector_base(c) {} \
+ explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
+ vector(iterator start, iterator end) : vector_base(start, end) {} \
+ vector& operator=(const vector& x) { \
+ vector_base::operator=(x); \
+ return *this; \
+ }
+
+template<typename T>
+class vector<T,Eigen::aligned_allocator<T> >
+ : public vector<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
+ Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> >
+{
+ typedef vector<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
+ Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> > vector_base;
+ EIGEN_STD_VECTOR_SPECIALIZATION_BODY
+
+ void resize(size_type new_size)
+ { resize(new_size, T()); }
+
+#if defined(_VECTOR_)
+ // workaround MSVC std::vector implementation
+ void resize(size_type new_size, const value_type& x)
+ {
+ if (vector_base::size() < new_size)
+ vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x);
+ else if (new_size < vector_base::size())
+ vector_base::erase(vector_base::begin() + new_size, vector_base::end());
+ }
+ void push_back(const value_type& x)
+ { vector_base::push_back(x); }
+ using vector_base::insert;
+ iterator insert(const_iterator position, const value_type& x)
+ { return vector_base::insert(position,x); }
+ void insert(const_iterator position, size_type new_size, const value_type& x)
+ { vector_base::insert(position, new_size, x); }
+#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
+ // workaround GCC std::vector implementation
+ void resize(size_type new_size, const value_type& x)
+ {
+ if (new_size < vector_base::size())
+ vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
+ else
+ vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
+ }
+#elif defined(_GLIBCXX_VECTOR) && (!EIGEN_GNUC_AT_LEAST(4,1))
+ // Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&),
+ // no no need to workaround !
+ using vector_base::resize;
+#else
+ // either GCC 4.1 or non-GCC
+ // default implementation which should always work.
+ void resize(size_type new_size, const value_type& x)
+ {
+ if (new_size < vector_base::size())
+ vector_base::erase(vector_base::begin() + new_size, vector_base::end());
+ else if (new_size > vector_base::size())
+ vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
+ }
+#endif
+
+};
+
+}
+
+#endif // EIGEN_STDVECTOR_MODULE_H
diff --git a/extern/Eigen2/Eigen/QR b/extern/Eigen2/Eigen/QR
new file mode 100644
index 00000000000..97907d1e50f
--- /dev/null
+++ b/extern/Eigen2/Eigen/QR
@@ -0,0 +1,73 @@
+#ifndef EIGEN_QR_MODULE_H
+#define EIGEN_QR_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+#include "Cholesky"
+
+// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
+#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)
+ #ifndef EIGEN_HIDE_HEAVY_CODE
+ #define EIGEN_HIDE_HEAVY_CODE
+ #endif
+#elif defined EIGEN_HIDE_HEAVY_CODE
+ #undef EIGEN_HIDE_HEAVY_CODE
+#endif
+
+namespace Eigen {
+
+/** \defgroup QR_Module QR module
+ *
+ * \nonstableyet
+ *
+ * This module mainly provides QR decomposition and an eigen value solver.
+ * This module also provides some MatrixBase methods, including:
+ * - MatrixBase::qr(),
+ * - MatrixBase::eigenvalues(),
+ * - MatrixBase::operatorNorm()
+ *
+ * \code
+ * #include <Eigen/QR>
+ * \endcode
+ */
+
+#include "src/QR/QR.h"
+#include "src/QR/Tridiagonalization.h"
+#include "src/QR/EigenSolver.h"
+#include "src/QR/SelfAdjointEigenSolver.h"
+#include "src/QR/HessenbergDecomposition.h"
+
+// declare all classes for a given matrix type
+#define EIGEN_QR_MODULE_INSTANTIATE_TYPE(MATRIXTYPE,PREFIX) \
+ PREFIX template class QR<MATRIXTYPE>; \
+ PREFIX template class Tridiagonalization<MATRIXTYPE>; \
+ PREFIX template class HessenbergDecomposition<MATRIXTYPE>; \
+ PREFIX template class SelfAdjointEigenSolver<MATRIXTYPE>
+
+// removed because it does not support complex yet
+// PREFIX template class EigenSolver<MATRIXTYPE>
+
+// declare all class for all types
+#define EIGEN_QR_MODULE_INSTANTIATE(PREFIX) \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix2f,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix2d,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix3f,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix3d,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix4f,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix4d,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXf,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXd,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXcf,PREFIX); \
+ EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXcd,PREFIX)
+
+#ifdef EIGEN_EXTERN_INSTANTIATIONS
+ EIGEN_QR_MODULE_INSTANTIATE(extern);
+#endif // EIGEN_EXTERN_INSTANTIATIONS
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_QR_MODULE_H
diff --git a/extern/Eigen2/Eigen/QtAlignedMalloc b/extern/Eigen2/Eigen/QtAlignedMalloc
new file mode 100644
index 00000000000..fde227328fa
--- /dev/null
+++ b/extern/Eigen2/Eigen/QtAlignedMalloc
@@ -0,0 +1,29 @@
+
+#ifndef EIGEN_QTMALLOC_MODULE_H
+#define EIGEN_QTMALLOC_MODULE_H
+
+#include "Core"
+
+#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
+
+inline void *qMalloc(size_t size)
+{
+ return Eigen::ei_aligned_malloc(size);
+}
+
+inline void qFree(void *ptr)
+{
+ Eigen::ei_aligned_free(ptr);
+}
+
+inline void *qRealloc(void *ptr, size_t size)
+{
+ void* newPtr = Eigen::ei_aligned_malloc(size);
+ memcpy(newPtr, ptr, size);
+ Eigen::ei_aligned_free(ptr);
+ return newPtr;
+}
+
+#endif
+
+#endif // EIGEN_QTMALLOC_MODULE_H
diff --git a/extern/Eigen2/Eigen/SVD b/extern/Eigen2/Eigen/SVD
new file mode 100644
index 00000000000..eef05564bde
--- /dev/null
+++ b/extern/Eigen2/Eigen/SVD
@@ -0,0 +1,29 @@
+#ifndef EIGEN_SVD_MODULE_H
+#define EIGEN_SVD_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+namespace Eigen {
+
+/** \defgroup SVD_Module SVD module
+ *
+ * \nonstableyet
+ *
+ * This module provides SVD decomposition for (currently) real matrices.
+ * This decomposition is accessible via the following MatrixBase method:
+ * - MatrixBase::svd()
+ *
+ * \code
+ * #include <Eigen/SVD>
+ * \endcode
+ */
+
+#include "src/SVD/SVD.h"
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_SVD_MODULE_H
diff --git a/extern/Eigen2/Eigen/Sparse b/extern/Eigen2/Eigen/Sparse
new file mode 100644
index 00000000000..536c284549b
--- /dev/null
+++ b/extern/Eigen2/Eigen/Sparse
@@ -0,0 +1,132 @@
+#ifndef EIGEN_SPARSE_MODULE_H
+#define EIGEN_SPARSE_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableMSVCWarnings.h"
+
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include <cstring>
+#include <algorithm>
+
+#ifdef EIGEN_GOOGLEHASH_SUPPORT
+ #include <google/dense_hash_map>
+#endif
+
+#ifdef EIGEN_CHOLMOD_SUPPORT
+ extern "C" {
+ #include "cholmod.h"
+ }
+#endif
+
+#ifdef EIGEN_TAUCS_SUPPORT
+ // taucs.h declares a lot of mess
+ #define isnan
+ #define finite
+ #define isinf
+ extern "C" {
+ #include "taucs.h"
+ }
+ #undef isnan
+ #undef finite
+ #undef isinf
+
+ #ifdef min
+ #undef min
+ #endif
+ #ifdef max
+ #undef max
+ #endif
+ #ifdef complex
+ #undef complex
+ #endif
+#endif
+
+#ifdef EIGEN_SUPERLU_SUPPORT
+ typedef int int_t;
+ #include "superlu/slu_Cnames.h"
+ #include "superlu/supermatrix.h"
+ #include "superlu/slu_util.h"
+
+ namespace SuperLU_S {
+ #include "superlu/slu_sdefs.h"
+ }
+ namespace SuperLU_D {
+ #include "superlu/slu_ddefs.h"
+ }
+ namespace SuperLU_C {
+ #include "superlu/slu_cdefs.h"
+ }
+ namespace SuperLU_Z {
+ #include "superlu/slu_zdefs.h"
+ }
+ namespace Eigen { struct SluMatrix; }
+#endif
+
+#ifdef EIGEN_UMFPACK_SUPPORT
+ #include "umfpack.h"
+#endif
+
+namespace Eigen {
+
+/** \defgroup Sparse_Module Sparse module
+ *
+ * \nonstableyet
+ *
+ * See the \ref TutorialSparse "Sparse tutorial"
+ *
+ * \code
+ * #include <Eigen/QR>
+ * \endcode
+ */
+
+#include "src/Sparse/SparseUtil.h"
+#include "src/Sparse/SparseMatrixBase.h"
+#include "src/Sparse/CompressedStorage.h"
+#include "src/Sparse/AmbiVector.h"
+#include "src/Sparse/RandomSetter.h"
+#include "src/Sparse/SparseBlock.h"
+#include "src/Sparse/SparseMatrix.h"
+#include "src/Sparse/DynamicSparseMatrix.h"
+#include "src/Sparse/MappedSparseMatrix.h"
+#include "src/Sparse/SparseVector.h"
+#include "src/Sparse/CoreIterators.h"
+#include "src/Sparse/SparseTranspose.h"
+#include "src/Sparse/SparseCwise.h"
+#include "src/Sparse/SparseCwiseUnaryOp.h"
+#include "src/Sparse/SparseCwiseBinaryOp.h"
+#include "src/Sparse/SparseDot.h"
+#include "src/Sparse/SparseAssign.h"
+#include "src/Sparse/SparseRedux.h"
+#include "src/Sparse/SparseFuzzy.h"
+#include "src/Sparse/SparseFlagged.h"
+#include "src/Sparse/SparseProduct.h"
+#include "src/Sparse/SparseDiagonalProduct.h"
+#include "src/Sparse/TriangularSolver.h"
+#include "src/Sparse/SparseLLT.h"
+#include "src/Sparse/SparseLDLT.h"
+#include "src/Sparse/SparseLU.h"
+
+#ifdef EIGEN_CHOLMOD_SUPPORT
+# include "src/Sparse/CholmodSupport.h"
+#endif
+
+#ifdef EIGEN_TAUCS_SUPPORT
+# include "src/Sparse/TaucsSupport.h"
+#endif
+
+#ifdef EIGEN_SUPERLU_SUPPORT
+# include "src/Sparse/SuperLUSupport.h"
+#endif
+
+#ifdef EIGEN_UMFPACK_SUPPORT
+# include "src/Sparse/UmfPackSupport.h"
+#endif
+
+} // namespace Eigen
+
+#include "src/Core/util/EnableMSVCWarnings.h"
+
+#endif // EIGEN_SPARSE_MODULE_H
diff --git a/extern/Eigen2/Eigen/StdVector b/extern/Eigen2/Eigen/StdVector
new file mode 100644
index 00000000000..c0744d6a0f3
--- /dev/null
+++ b/extern/Eigen2/Eigen/StdVector
@@ -0,0 +1,147 @@
+#ifdef EIGEN_USE_NEW_STDVECTOR
+#include "NewStdVector"
+#else
+
+#ifndef EIGEN_STDVECTOR_MODULE_H
+#define EIGEN_STDVECTOR_MODULE_H
+
+#if defined(_GLIBCXX_VECTOR) || defined(_VECTOR_)
+#error you must include <Eigen/StdVector> before <vector>. Also note that <Eigen/Sparse> includes <vector>, so it must be included after <Eigen/StdVector> too.
+#endif
+
+#ifndef EIGEN_GNUC_AT_LEAST
+#ifdef __GNUC__
+ #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
+#else
+ #define EIGEN_GNUC_AT_LEAST(x,y) 0
+#endif
+#endif
+
+#define vector std_vector
+#include <vector>
+#undef vector
+
+namespace Eigen {
+
+template<typename T> class aligned_allocator;
+
+// meta programming to determine if a class has a given member
+struct ei_does_not_have_aligned_operator_new_marker_sizeof {int a[1];};
+struct ei_has_aligned_operator_new_marker_sizeof {int a[2];};
+
+template<typename ClassType>
+struct ei_has_aligned_operator_new {
+ template<typename T>
+ static ei_has_aligned_operator_new_marker_sizeof
+ test(T const *, typename T::ei_operator_new_marker_type const * = 0);
+ static ei_does_not_have_aligned_operator_new_marker_sizeof
+ test(...);
+
+ // note that the following indirection is needed for gcc-3.3
+ enum {ret = sizeof(test(static_cast<ClassType*>(0)))
+ == sizeof(ei_has_aligned_operator_new_marker_sizeof) };
+};
+
+#ifdef _MSC_VER
+
+ // sometimes, MSVC detects, at compile time, that the argument x
+ // in std::vector::resize(size_t s,T x) won't be aligned and generate an error
+ // even if this function is never called. Whence this little wrapper.
+ #define _EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) Eigen::ei_workaround_msvc_std_vector<T>
+ template<typename T> struct ei_workaround_msvc_std_vector : public T
+ {
+ inline ei_workaround_msvc_std_vector() : T() {}
+ inline ei_workaround_msvc_std_vector(const T& other) : T(other) {}
+ inline operator T& () { return *static_cast<T*>(this); }
+ inline operator const T& () const { return *static_cast<const T*>(this); }
+ template<typename OtherT>
+ inline T& operator=(const OtherT& other)
+ { T::operator=(other); return *this; }
+ inline ei_workaround_msvc_std_vector& operator=(const ei_workaround_msvc_std_vector& other)
+ { T::operator=(other); return *this; }
+ };
+
+#else
+
+ #define _EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) T
+
+#endif
+
+}
+
+namespace std {
+
+#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
+ public: \
+ typedef T value_type; \
+ typedef typename vector_base::allocator_type allocator_type; \
+ typedef typename vector_base::size_type size_type; \
+ typedef typename vector_base::iterator iterator; \
+ explicit vector(const allocator_type& __a = allocator_type()) : vector_base(__a) {} \
+ vector(const vector& c) : vector_base(c) {} \
+ vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
+ vector(iterator start, iterator end) : vector_base(start, end) {} \
+ vector& operator=(const vector& __x) { \
+ vector_base::operator=(__x); \
+ return *this; \
+ }
+
+template<typename T,
+ typename AllocT = std::allocator<T>,
+ bool HasAlignedNew = Eigen::ei_has_aligned_operator_new<T>::ret>
+class vector : public std::std_vector<T,AllocT>
+{
+ typedef std_vector<T, AllocT> vector_base;
+ EIGEN_STD_VECTOR_SPECIALIZATION_BODY
+};
+
+template<typename T,typename DummyAlloc>
+class vector<T,DummyAlloc,true>
+ : public std::std_vector<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
+ Eigen::aligned_allocator<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> >
+{
+ typedef std_vector<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
+ Eigen::aligned_allocator<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> > vector_base;
+ EIGEN_STD_VECTOR_SPECIALIZATION_BODY
+
+ void resize(size_type __new_size)
+ { resize(__new_size, T()); }
+
+ #if defined(_VECTOR_)
+ // workaround MSVC std::vector implementation
+ void resize(size_type __new_size, const value_type& __x)
+ {
+ if (vector_base::size() < __new_size)
+ vector_base::_Insert_n(vector_base::end(), __new_size - vector_base::size(), __x);
+ else if (__new_size < vector_base::size())
+ vector_base::erase(vector_base::begin() + __new_size, vector_base::end());
+ }
+ #elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
+ // workaround GCC std::vector implementation
+ void resize(size_type __new_size, const value_type& __x)
+ {
+ if (__new_size < vector_base::size())
+ vector_base::_M_erase_at_end(this->_M_impl._M_start + __new_size);
+ else
+ vector_base::insert(vector_base::end(), __new_size - vector_base::size(), __x);
+ }
+ #elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,1)
+ void resize(size_type __new_size, const value_type& __x)
+ {
+ if (__new_size < vector_base::size())
+ vector_base::erase(vector_base::begin() + __new_size, vector_base::end());
+ else
+ vector_base::insert(vector_base::end(), __new_size - vector_base::size(), __x);
+ }
+ #else
+ // Before gcc-4.1 we already have: std::vector::resize(size_type,const T&),
+ // so no need for a workaround !
+ using vector_base::resize;
+ #endif
+};
+
+}
+
+#endif // EIGEN_STDVECTOR_MODULE_H
+
+#endif // EIGEN_USE_NEW_STDVECTOR \ No newline at end of file
diff --git a/extern/Eigen2/Eigen/src/Array/BooleanRedux.h b/extern/Eigen2/Eigen/src/Array/BooleanRedux.h
new file mode 100644
index 00000000000..4e8218327eb
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/BooleanRedux.h
@@ -0,0 +1,145 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ALLANDANY_H
+#define EIGEN_ALLANDANY_H
+
+template<typename Derived, int UnrollCount>
+struct ei_all_unroller
+{
+ enum {
+ col = (UnrollCount-1) / Derived::RowsAtCompileTime,
+ row = (UnrollCount-1) % Derived::RowsAtCompileTime
+ };
+
+ inline static bool run(const Derived &mat)
+ {
+ return ei_all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
+ }
+};
+
+template<typename Derived>
+struct ei_all_unroller<Derived, 1>
+{
+ inline static bool run(const Derived &mat) { return mat.coeff(0, 0); }
+};
+
+template<typename Derived>
+struct ei_all_unroller<Derived, Dynamic>
+{
+ inline static bool run(const Derived &) { return false; }
+};
+
+template<typename Derived, int UnrollCount>
+struct ei_any_unroller
+{
+ enum {
+ col = (UnrollCount-1) / Derived::RowsAtCompileTime,
+ row = (UnrollCount-1) % Derived::RowsAtCompileTime
+ };
+
+ inline static bool run(const Derived &mat)
+ {
+ return ei_any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
+ }
+};
+
+template<typename Derived>
+struct ei_any_unroller<Derived, 1>
+{
+ inline static bool run(const Derived &mat) { return mat.coeff(0, 0); }
+};
+
+template<typename Derived>
+struct ei_any_unroller<Derived, Dynamic>
+{
+ inline static bool run(const Derived &) { return false; }
+};
+
+/** \array_module
+ *
+ * \returns true if all coefficients are true
+ *
+ * \addexample CwiseAll \label How to check whether a point is inside a box (using operator< and all())
+ *
+ * Example: \include MatrixBase_all.cpp
+ * Output: \verbinclude MatrixBase_all.out
+ *
+ * \sa MatrixBase::any(), Cwise::operator<()
+ */
+template<typename Derived>
+inline bool MatrixBase<Derived>::all() const
+{
+ const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost)
+ <= EIGEN_UNROLLING_LIMIT;
+ if(unroll)
+ return ei_all_unroller<Derived,
+ unroll ? int(SizeAtCompileTime) : Dynamic
+ >::run(derived());
+ else
+ {
+ for(int j = 0; j < cols(); ++j)
+ for(int i = 0; i < rows(); ++i)
+ if (!coeff(i, j)) return false;
+ return true;
+ }
+}
+
+/** \array_module
+ *
+ * \returns true if at least one coefficient is true
+ *
+ * \sa MatrixBase::all()
+ */
+template<typename Derived>
+inline bool MatrixBase<Derived>::any() const
+{
+ const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost)
+ <= EIGEN_UNROLLING_LIMIT;
+ if(unroll)
+ return ei_any_unroller<Derived,
+ unroll ? int(SizeAtCompileTime) : Dynamic
+ >::run(derived());
+ else
+ {
+ for(int j = 0; j < cols(); ++j)
+ for(int i = 0; i < rows(); ++i)
+ if (coeff(i, j)) return true;
+ return false;
+ }
+}
+
+/** \array_module
+ *
+ * \returns the number of coefficients which evaluate to true
+ *
+ * \sa MatrixBase::all(), MatrixBase::any()
+ */
+template<typename Derived>
+inline int MatrixBase<Derived>::count() const
+{
+ return this->cast<bool>().cast<int>().sum();
+}
+
+#endif // EIGEN_ALLANDANY_H
diff --git a/extern/Eigen2/Eigen/src/Array/CwiseOperators.h b/extern/Eigen2/Eigen/src/Array/CwiseOperators.h
new file mode 100644
index 00000000000..4b6346daa51
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/CwiseOperators.h
@@ -0,0 +1,453 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ARRAY_CWISE_OPERATORS_H
+#define EIGEN_ARRAY_CWISE_OPERATORS_H
+
+// -- unary operators --
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise square root of *this.
+ *
+ * Example: \include Cwise_sqrt.cpp
+ * Output: \verbinclude Cwise_sqrt.out
+ *
+ * \sa pow(), square()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sqrt_op)
+Cwise<ExpressionType>::sqrt() const
+{
+ return _expression();
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise exponential of *this.
+ *
+ * Example: \include Cwise_exp.cpp
+ * Output: \verbinclude Cwise_exp.out
+ *
+ * \sa pow(), log(), sin(), cos()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op)
+Cwise<ExpressionType>::exp() const
+{
+ return _expression();
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise logarithm of *this.
+ *
+ * Example: \include Cwise_log.cpp
+ * Output: \verbinclude Cwise_log.out
+ *
+ * \sa exp()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op)
+Cwise<ExpressionType>::log() const
+{
+ return _expression();
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise cosine of *this.
+ *
+ * Example: \include Cwise_cos.cpp
+ * Output: \verbinclude Cwise_cos.out
+ *
+ * \sa sin(), exp()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op)
+Cwise<ExpressionType>::cos() const
+{
+ return _expression();
+}
+
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise sine of *this.
+ *
+ * Example: \include Cwise_sin.cpp
+ * Output: \verbinclude Cwise_sin.out
+ *
+ * \sa cos(), exp()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op)
+Cwise<ExpressionType>::sin() const
+{
+ return _expression();
+}
+
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise power of *this to the given exponent.
+ *
+ * Example: \include Cwise_pow.cpp
+ * Output: \verbinclude Cwise_pow.out
+ *
+ * \sa exp(), log()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op)
+Cwise<ExpressionType>::pow(const Scalar& exponent) const
+{
+ return EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op)(_expression(), ei_scalar_pow_op<Scalar>(exponent));
+}
+
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise inverse of *this.
+ *
+ * Example: \include Cwise_inverse.cpp
+ * Output: \verbinclude Cwise_inverse.out
+ *
+ * \sa operator/(), operator*()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_inverse_op)
+Cwise<ExpressionType>::inverse() const
+{
+ return _expression();
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise square of *this.
+ *
+ * Example: \include Cwise_square.cpp
+ * Output: \verbinclude Cwise_square.out
+ *
+ * \sa operator/(), operator*(), abs2()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_square_op)
+Cwise<ExpressionType>::square() const
+{
+ return _expression();
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise cube of *this.
+ *
+ * Example: \include Cwise_cube.cpp
+ * Output: \verbinclude Cwise_cube.out
+ *
+ * \sa square(), pow()
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cube_op)
+Cwise<ExpressionType>::cube() const
+{
+ return _expression();
+}
+
+
+// -- binary operators --
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \< operator of *this and \a other
+ *
+ * Example: \include Cwise_less.cpp
+ * Output: \verbinclude Cwise_less.out
+ *
+ * \sa MatrixBase::all(), MatrixBase::any(), operator>(), operator<=()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)
+Cwise<ExpressionType>::operator<(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)(_expression(), other.derived());
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \<= operator of *this and \a other
+ *
+ * Example: \include Cwise_less_equal.cpp
+ * Output: \verbinclude Cwise_less_equal.out
+ *
+ * \sa MatrixBase::all(), MatrixBase::any(), operator>=(), operator<()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)
+Cwise<ExpressionType>::operator<=(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)(_expression(), other.derived());
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \> operator of *this and \a other
+ *
+ * Example: \include Cwise_greater.cpp
+ * Output: \verbinclude Cwise_greater.out
+ *
+ * \sa MatrixBase::all(), MatrixBase::any(), operator>=(), operator<()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)
+Cwise<ExpressionType>::operator>(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)(_expression(), other.derived());
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \>= operator of *this and \a other
+ *
+ * Example: \include Cwise_greater_equal.cpp
+ * Output: \verbinclude Cwise_greater_equal.out
+ *
+ * \sa MatrixBase::all(), MatrixBase::any(), operator>(), operator<=()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)
+Cwise<ExpressionType>::operator>=(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)(_expression(), other.derived());
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise == operator of *this and \a other
+ *
+ * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
+ * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
+ * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
+ * MatrixBase::isMuchSmallerThan().
+ *
+ * Example: \include Cwise_equal_equal.cpp
+ * Output: \verbinclude Cwise_equal_equal.out
+ *
+ * \sa MatrixBase::all(), MatrixBase::any(), MatrixBase::isApprox(), MatrixBase::isMuchSmallerThan()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)
+Cwise<ExpressionType>::operator==(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)(_expression(), other.derived());
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise != operator of *this and \a other
+ *
+ * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
+ * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
+ * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
+ * MatrixBase::isMuchSmallerThan().
+ *
+ * Example: \include Cwise_not_equal.cpp
+ * Output: \verbinclude Cwise_not_equal.out
+ *
+ * \sa MatrixBase::all(), MatrixBase::any(), MatrixBase::isApprox(), MatrixBase::isMuchSmallerThan()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)
+Cwise<ExpressionType>::operator!=(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)(_expression(), other.derived());
+}
+
+// comparisons to scalar value
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \< operator of *this and a scalar \a s
+ *
+ * \sa operator<(const MatrixBase<OtherDerived> &) const
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
+Cwise<ExpressionType>::operator<(Scalar s) const
+{
+ return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)(_expression(),
+ typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \<= operator of *this and a scalar \a s
+ *
+ * \sa operator<=(const MatrixBase<OtherDerived> &) const
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
+Cwise<ExpressionType>::operator<=(Scalar s) const
+{
+ return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)(_expression(),
+ typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \> operator of *this and a scalar \a s
+ *
+ * \sa operator>(const MatrixBase<OtherDerived> &) const
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
+Cwise<ExpressionType>::operator>(Scalar s) const
+{
+ return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)(_expression(),
+ typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise \>= operator of *this and a scalar \a s
+ *
+ * \sa operator>=(const MatrixBase<OtherDerived> &) const
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
+Cwise<ExpressionType>::operator>=(Scalar s) const
+{
+ return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)(_expression(),
+ typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise == operator of *this and a scalar \a s
+ *
+ * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
+ * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
+ * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
+ * MatrixBase::isMuchSmallerThan().
+ *
+ * \sa operator==(const MatrixBase<OtherDerived> &) const
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
+Cwise<ExpressionType>::operator==(Scalar s) const
+{
+ return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)(_expression(),
+ typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
+}
+
+/** \array_module
+ *
+ * \returns an expression of the coefficient-wise != operator of *this and a scalar \a s
+ *
+ * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
+ * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
+ * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
+ * MatrixBase::isMuchSmallerThan().
+ *
+ * \sa operator!=(const MatrixBase<OtherDerived> &) const
+ */
+template<typename ExpressionType>
+inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
+Cwise<ExpressionType>::operator!=(Scalar s) const
+{
+ return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)(_expression(),
+ typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
+}
+
+// scalar addition
+
+/** \array_module
+ *
+ * \returns an expression of \c *this with each coeff incremented by the constant \a scalar
+ *
+ * Example: \include Cwise_plus.cpp
+ * Output: \verbinclude Cwise_plus.out
+ *
+ * \sa operator+=(), operator-()
+ */
+template<typename ExpressionType>
+inline const typename Cwise<ExpressionType>::ScalarAddReturnType
+Cwise<ExpressionType>::operator+(const Scalar& scalar) const
+{
+ return typename Cwise<ExpressionType>::ScalarAddReturnType(m_matrix, ei_scalar_add_op<Scalar>(scalar));
+}
+
+/** \array_module
+ *
+ * Adds the given \a scalar to each coeff of this expression.
+ *
+ * Example: \include Cwise_plus_equal.cpp
+ * Output: \verbinclude Cwise_plus_equal.out
+ *
+ * \sa operator+(), operator-=()
+ */
+template<typename ExpressionType>
+inline ExpressionType& Cwise<ExpressionType>::operator+=(const Scalar& scalar)
+{
+ return m_matrix.const_cast_derived() = *this + scalar;
+}
+
+/** \array_module
+ *
+ * \returns an expression of \c *this with each coeff decremented by the constant \a scalar
+ *
+ * Example: \include Cwise_minus.cpp
+ * Output: \verbinclude Cwise_minus.out
+ *
+ * \sa operator+(), operator-=()
+ */
+template<typename ExpressionType>
+inline const typename Cwise<ExpressionType>::ScalarAddReturnType
+Cwise<ExpressionType>::operator-(const Scalar& scalar) const
+{
+ return *this + (-scalar);
+}
+
+/** \array_module
+ *
+ * Substracts the given \a scalar from each coeff of this expression.
+ *
+ * Example: \include Cwise_minus_equal.cpp
+ * Output: \verbinclude Cwise_minus_equal.out
+ *
+ * \sa operator+=(), operator-()
+ */
+
+template<typename ExpressionType>
+inline ExpressionType& Cwise<ExpressionType>::operator-=(const Scalar& scalar)
+{
+ return m_matrix.const_cast_derived() = *this - scalar;
+}
+
+#endif // EIGEN_ARRAY_CWISE_OPERATORS_H
diff --git a/extern/Eigen2/Eigen/src/Array/Functors.h b/extern/Eigen2/Eigen/src/Array/Functors.h
new file mode 100644
index 00000000000..0aae7fd2c40
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/Functors.h
@@ -0,0 +1,305 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ARRAY_FUNCTORS_H
+#define EIGEN_ARRAY_FUNCTORS_H
+
+/** \internal
+ * \array_module
+ *
+ * \brief Template functor to add a scalar to a fixed other one
+ *
+ * \sa class CwiseUnaryOp, Array::operator+
+ */
+/* If you wonder why doing the ei_pset1() in packetOp() is an optimization check ei_scalar_multiple_op */
+template<typename Scalar>
+struct ei_scalar_add_op {
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+ // FIXME default copy constructors seems bugged with std::complex<>
+ inline ei_scalar_add_op(const ei_scalar_add_op& other) : m_other(other.m_other) { }
+ inline ei_scalar_add_op(const Scalar& other) : m_other(other) { }
+ inline Scalar operator() (const Scalar& a) const { return a + m_other; }
+ inline const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_padd(a, ei_pset1(m_other)); }
+ const Scalar m_other;
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_add_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the square root of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::sqrt()
+ */
+template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
+ inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the exponential of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::exp()
+ */
+template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
+ inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the logarithm of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::log()
+ */
+template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
+ inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_log_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the cosine of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::cos()
+ */
+template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
+ inline const Scalar operator() (const Scalar& a) const { return ei_cos(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the sine of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::sin()
+ */
+template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
+ inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to raise a scalar to a power
+ *
+ * \sa class CwiseUnaryOp, Cwise::pow
+ */
+template<typename Scalar>
+struct ei_scalar_pow_op {
+ // FIXME default copy constructors seems bugged with std::complex<>
+ inline ei_scalar_pow_op(const ei_scalar_pow_op& other) : m_exponent(other.m_exponent) { }
+ inline ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
+ inline Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); }
+ const Scalar m_exponent;
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_pow_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the inverse of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::inverse()
+ */
+template<typename Scalar>
+struct ei_scalar_inverse_op {
+ inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
+ template<typename PacketScalar>
+ inline const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_pdiv(ei_pset1(Scalar(1)),a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_inverse_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the square of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::square()
+ */
+template<typename Scalar>
+struct ei_scalar_square_op {
+ inline Scalar operator() (const Scalar& a) const { return a*a; }
+ template<typename PacketScalar>
+ inline const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_pmul(a,a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_square_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
+
+/** \internal
+ *
+ * \array_module
+ *
+ * \brief Template functor to compute the cube of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::cube()
+ */
+template<typename Scalar>
+struct ei_scalar_cube_op {
+ inline Scalar operator() (const Scalar& a) const { return a*a*a; }
+ template<typename PacketScalar>
+ inline const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_pmul(a,ei_pmul(a,a)); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_cube_op<Scalar> >
+{ enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
+
+// default ei_functor_traits for STL functors:
+
+template<typename T>
+struct ei_functor_traits<std::multiplies<T> >
+{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::divides<T> >
+{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::plus<T> >
+{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::minus<T> >
+{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::negate<T> >
+{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::logical_or<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::logical_and<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::logical_not<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::greater<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::less<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::greater_equal<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::less_equal<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::equal_to<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::not_equal_to<T> >
+{ enum { Cost = 1, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::binder2nd<T> >
+{ enum { Cost = ei_functor_traits<T>::Cost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::binder1st<T> >
+{ enum { Cost = ei_functor_traits<T>::Cost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::unary_negate<T> >
+{ enum { Cost = 1 + ei_functor_traits<T>::Cost, PacketAccess = false }; };
+
+template<typename T>
+struct ei_functor_traits<std::binary_negate<T> >
+{ enum { Cost = 1 + ei_functor_traits<T>::Cost, PacketAccess = false }; };
+
+#ifdef EIGEN_STDEXT_SUPPORT
+
+template<typename T0,typename T1>
+struct ei_functor_traits<std::project1st<T0,T1> >
+{ enum { Cost = 0, PacketAccess = false }; };
+
+template<typename T0,typename T1>
+struct ei_functor_traits<std::project2nd<T0,T1> >
+{ enum { Cost = 0, PacketAccess = false }; };
+
+template<typename T0,typename T1>
+struct ei_functor_traits<std::select2nd<std::pair<T0,T1> > >
+{ enum { Cost = 0, PacketAccess = false }; };
+
+template<typename T0,typename T1>
+struct ei_functor_traits<std::select1st<std::pair<T0,T1> > >
+{ enum { Cost = 0, PacketAccess = false }; };
+
+template<typename T0,typename T1>
+struct ei_functor_traits<std::unary_compose<T0,T1> >
+{ enum { Cost = ei_functor_traits<T0>::Cost + ei_functor_traits<T1>::Cost, PacketAccess = false }; };
+
+template<typename T0,typename T1,typename T2>
+struct ei_functor_traits<std::binary_compose<T0,T1,T2> >
+{ enum { Cost = ei_functor_traits<T0>::Cost + ei_functor_traits<T1>::Cost + ei_functor_traits<T2>::Cost, PacketAccess = false }; };
+
+#endif // EIGEN_STDEXT_SUPPORT
+
+#endif // EIGEN_ARRAY_FUNCTORS_H
diff --git a/extern/Eigen2/Eigen/src/Array/Norms.h b/extern/Eigen2/Eigen/src/Array/Norms.h
new file mode 100644
index 00000000000..6b92e6a099d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/Norms.h
@@ -0,0 +1,80 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ARRAY_NORMS_H
+#define EIGEN_ARRAY_NORMS_H
+
+template<typename Derived, int p>
+struct ei_lpNorm_selector
+{
+ typedef typename NumTraits<typename ei_traits<Derived>::Scalar>::Real RealScalar;
+ inline static RealScalar run(const MatrixBase<Derived>& m)
+ {
+ return ei_pow(m.cwise().abs().cwise().pow(p).sum(), RealScalar(1)/p);
+ }
+};
+
+template<typename Derived>
+struct ei_lpNorm_selector<Derived, 1>
+{
+ inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
+ {
+ return m.cwise().abs().sum();
+ }
+};
+
+template<typename Derived>
+struct ei_lpNorm_selector<Derived, 2>
+{
+ inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
+ {
+ return m.norm();
+ }
+};
+
+template<typename Derived>
+struct ei_lpNorm_selector<Derived, Infinity>
+{
+ inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
+ {
+ return m.cwise().abs().maxCoeff();
+ }
+};
+
+/** \array_module
+ *
+ * \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values
+ * of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^p\infty \f$
+ * norm, that is the maximum of the absolute values of the coefficients of *this.
+ *
+ * \sa norm()
+ */
+template<typename Derived>
+template<int p>
+inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::lpNorm() const
+{
+ return ei_lpNorm_selector<Derived, p>::run(*this);
+}
+
+#endif // EIGEN_ARRAY_NORMS_H
diff --git a/extern/Eigen2/Eigen/src/Array/PartialRedux.h b/extern/Eigen2/Eigen/src/Array/PartialRedux.h
new file mode 100644
index 00000000000..b1e8fd4babd
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/PartialRedux.h
@@ -0,0 +1,342 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_PARTIAL_REDUX_H
+#define EIGEN_PARTIAL_REDUX_H
+
+/** \array_module \ingroup Array
+ *
+ * \class PartialReduxExpr
+ *
+ * \brief Generic expression of a partially reduxed matrix
+ *
+ * \param MatrixType the type of the matrix we are applying the redux operation
+ * \param MemberOp type of the member functor
+ * \param Direction indicates the direction of the redux (Vertical or Horizontal)
+ *
+ * This class represents an expression of a partial redux operator of a matrix.
+ * It is the return type of PartialRedux functions,
+ * and most of the time this is the only way it is used.
+ *
+ * \sa class PartialRedux
+ */
+
+template< typename MatrixType, typename MemberOp, int Direction>
+class PartialReduxExpr;
+
+template<typename MatrixType, typename MemberOp, int Direction>
+struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
+{
+ typedef typename MemberOp::result_type Scalar;
+ typedef typename MatrixType::Scalar InputScalar;
+ typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
+ typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
+ Flags = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
+ TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime
+ };
+ #if EIGEN_GNUC_AT_LEAST(3,4)
+ typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
+ #else
+ typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType;
+ #endif
+ enum {
+ CoeffReadCost = TraversalSize * ei_traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
+ };
+};
+
+template< typename MatrixType, typename MemberOp, int Direction>
+class PartialReduxExpr : ei_no_assignment_operator,
+ public MatrixBase<PartialReduxExpr<MatrixType, MemberOp, Direction> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(PartialReduxExpr)
+ typedef typename ei_traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested;
+ typedef typename ei_traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested;
+
+ PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
+ : m_matrix(mat), m_functor(func) {}
+
+ int rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
+ int cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
+
+ const Scalar coeff(int i, int j) const
+ {
+ if (Direction==Vertical)
+ return m_functor(m_matrix.col(j));
+ else
+ return m_functor(m_matrix.row(i));
+ }
+
+ protected:
+ const MatrixTypeNested m_matrix;
+ const MemberOp m_functor;
+};
+
+#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
+ template <typename ResultType> \
+ struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \
+ typedef ResultType result_type; \
+ template<typename Scalar, int Size> struct Cost \
+ { enum { value = COST }; }; \
+ template<typename Derived> \
+ inline ResultType operator()(const MatrixBase<Derived>& mat) const \
+ { return mat.MEMBER(); } \
+ }
+
+EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
+
+/** \internal */
+template <typename BinaryOp, typename Scalar>
+struct ei_member_redux {
+ typedef typename ei_result_of<
+ BinaryOp(Scalar)
+ >::type result_type;
+ template<typename _Scalar, int Size> struct Cost
+ { enum { value = (Size-1) * ei_functor_traits<BinaryOp>::Cost }; };
+ ei_member_redux(const BinaryOp func) : m_functor(func) {}
+ template<typename Derived>
+ inline result_type operator()(const MatrixBase<Derived>& mat) const
+ { return mat.redux(m_functor); }
+ const BinaryOp m_functor;
+};
+
+/** \array_module \ingroup Array
+ *
+ * \class PartialRedux
+ *
+ * \brief Pseudo expression providing partial reduction operations
+ *
+ * \param ExpressionType the type of the object on which to do partial reductions
+ * \param Direction indicates the direction of the redux (Vertical or Horizontal)
+ *
+ * This class represents a pseudo expression with partial reduction features.
+ * It is the return type of MatrixBase::colwise() and MatrixBase::rowwise()
+ * and most of the time this is the only way it is used.
+ *
+ * Example: \include MatrixBase_colwise.cpp
+ * Output: \verbinclude MatrixBase_colwise.out
+ *
+ * \sa MatrixBase::colwise(), MatrixBase::rowwise(), class PartialReduxExpr
+ */
+template<typename ExpressionType, int Direction> class PartialRedux
+{
+ public:
+
+ typedef typename ei_traits<ExpressionType>::Scalar Scalar;
+ typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
+ ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
+
+ template<template<typename _Scalar> class Functor> struct ReturnType
+ {
+ typedef PartialReduxExpr<ExpressionType,
+ Functor<typename ei_traits<ExpressionType>::Scalar>,
+ Direction
+ > Type;
+ };
+
+ template<typename BinaryOp> struct ReduxReturnType
+ {
+ typedef PartialReduxExpr<ExpressionType,
+ ei_member_redux<BinaryOp,typename ei_traits<ExpressionType>::Scalar>,
+ Direction
+ > Type;
+ };
+
+ typedef typename ExpressionType::PlainMatrixType CrossReturnType;
+
+ inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {}
+
+ /** \internal */
+ inline const ExpressionType& _expression() const { return m_matrix; }
+
+ template<typename BinaryOp>
+ const typename ReduxReturnType<BinaryOp>::Type
+ redux(const BinaryOp& func = BinaryOp()) const;
+
+ /** \returns a row (or column) vector expression of the smallest coefficient
+ * of each column (or row) of the referenced expression.
+ *
+ * Example: \include PartialRedux_minCoeff.cpp
+ * Output: \verbinclude PartialRedux_minCoeff.out
+ *
+ * \sa MatrixBase::minCoeff() */
+ const typename ReturnType<ei_member_minCoeff>::Type minCoeff() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression of the largest coefficient
+ * of each column (or row) of the referenced expression.
+ *
+ * Example: \include PartialRedux_maxCoeff.cpp
+ * Output: \verbinclude PartialRedux_maxCoeff.out
+ *
+ * \sa MatrixBase::maxCoeff() */
+ const typename ReturnType<ei_member_maxCoeff>::Type maxCoeff() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression of the squared norm
+ * of each column (or row) of the referenced expression.
+ *
+ * Example: \include PartialRedux_squaredNorm.cpp
+ * Output: \verbinclude PartialRedux_squaredNorm.out
+ *
+ * \sa MatrixBase::squaredNorm() */
+ const typename ReturnType<ei_member_squaredNorm>::Type squaredNorm() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression of the norm
+ * of each column (or row) of the referenced expression.
+ *
+ * Example: \include PartialRedux_norm.cpp
+ * Output: \verbinclude PartialRedux_norm.out
+ *
+ * \sa MatrixBase::norm() */
+ const typename ReturnType<ei_member_norm>::Type norm() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression of the sum
+ * of each column (or row) of the referenced expression.
+ *
+ * Example: \include PartialRedux_sum.cpp
+ * Output: \verbinclude PartialRedux_sum.out
+ *
+ * \sa MatrixBase::sum() */
+ const typename ReturnType<ei_member_sum>::Type sum() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression representing
+ * whether \b all coefficients of each respective column (or row) are \c true.
+ *
+ * \sa MatrixBase::all() */
+ const typename ReturnType<ei_member_all>::Type all() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression representing
+ * whether \b at \b least one coefficient of each respective column (or row) is \c true.
+ *
+ * \sa MatrixBase::any() */
+ const typename ReturnType<ei_member_any>::Type any() const
+ { return _expression(); }
+
+ /** \returns a row (or column) vector expression representing
+ * the number of \c true coefficients of each respective column (or row).
+ *
+ * Example: \include PartialRedux_count.cpp
+ * Output: \verbinclude PartialRedux_count.out
+ *
+ * \sa MatrixBase::count() */
+ const PartialReduxExpr<ExpressionType, ei_member_count<int>, Direction> count() const
+ { return _expression(); }
+
+ /** \returns a 3x3 matrix expression of the cross product
+ * of each column or row of the referenced expression with the \a other vector.
+ *
+ * \geometry_module
+ *
+ * \sa MatrixBase::cross() */
+ template<typename OtherDerived>
+ const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const
+ {
+ EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(CrossReturnType,3,3)
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3)
+ EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+
+ if(Direction==Vertical)
+ return (CrossReturnType()
+ << _expression().col(0).cross(other),
+ _expression().col(1).cross(other),
+ _expression().col(2).cross(other)).finished();
+ else
+ return (CrossReturnType()
+ << _expression().row(0).cross(other),
+ _expression().row(1).cross(other),
+ _expression().row(2).cross(other)).finished();
+ }
+
+ protected:
+ ExpressionTypeNested m_matrix;
+};
+
+/** \array_module
+ *
+ * \returns a PartialRedux wrapper of *this providing additional partial reduction operations
+ *
+ * Example: \include MatrixBase_colwise.cpp
+ * Output: \verbinclude MatrixBase_colwise.out
+ *
+ * \sa rowwise(), class PartialRedux
+ */
+template<typename Derived>
+inline const PartialRedux<Derived,Vertical>
+MatrixBase<Derived>::colwise() const
+{
+ return derived();
+}
+
+/** \array_module
+ *
+ * \returns a PartialRedux wrapper of *this providing additional partial reduction operations
+ *
+ * Example: \include MatrixBase_rowwise.cpp
+ * Output: \verbinclude MatrixBase_rowwise.out
+ *
+ * \sa colwise(), class PartialRedux
+ */
+template<typename Derived>
+inline const PartialRedux<Derived,Horizontal>
+MatrixBase<Derived>::rowwise() const
+{
+ return derived();
+}
+
+/** \returns a row or column vector expression of \c *this reduxed by \a func
+ *
+ * The template parameter \a BinaryOp is the type of the functor
+ * of the custom redux operator. Note that func must be an associative operator.
+ *
+ * \sa class PartialRedux, MatrixBase::colwise(), MatrixBase::rowwise()
+ */
+template<typename ExpressionType, int Direction>
+template<typename BinaryOp>
+const typename PartialRedux<ExpressionType,Direction>::template ReduxReturnType<BinaryOp>::Type
+PartialRedux<ExpressionType,Direction>::redux(const BinaryOp& func) const
+{
+ return typename ReduxReturnType<BinaryOp>::Type(_expression(), func);
+}
+
+#endif // EIGEN_PARTIAL_REDUX_H
diff --git a/extern/Eigen2/Eigen/src/Array/Random.h b/extern/Eigen2/Eigen/src/Array/Random.h
new file mode 100644
index 00000000000..9185fe4a7d3
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/Random.h
@@ -0,0 +1,156 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_RANDOM_H
+#define EIGEN_RANDOM_H
+
+template<typename Scalar> struct ei_scalar_random_op EIGEN_EMPTY_STRUCT {
+ inline ei_scalar_random_op(void) {}
+ inline const Scalar operator() (int, int) const { return ei_random<Scalar>(); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_random_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
+
+/** \array_module
+ *
+ * \returns a random matrix (not an expression, the matrix is immediately evaluated).
+ *
+ * The parameters \a rows and \a cols are the number of rows and of columns of
+ * the returned matrix. Must be compatible with this MatrixBase type.
+ *
+ * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
+ * it is redundant to pass \a rows and \a cols as arguments, so ei_random() should be used
+ * instead.
+ *
+ * \addexample RandomExample \label How to create a matrix with random coefficients
+ *
+ * Example: \include MatrixBase_random_int_int.cpp
+ * Output: \verbinclude MatrixBase_random_int_int.out
+ *
+ * \sa MatrixBase::setRandom(), MatrixBase::Random(int), MatrixBase::Random()
+ */
+template<typename Derived>
+inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived>
+MatrixBase<Derived>::Random(int rows, int cols)
+{
+ return NullaryExpr(rows, cols, ei_scalar_random_op<Scalar>());
+}
+
+/** \array_module
+ *
+ * \returns a random vector (not an expression, the vector is immediately evaluated).
+ *
+ * The parameter \a size is the size of the returned vector.
+ * Must be compatible with this MatrixBase type.
+ *
+ * \only_for_vectors
+ *
+ * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
+ * it is redundant to pass \a size as argument, so ei_random() should be used
+ * instead.
+ *
+ * Example: \include MatrixBase_random_int.cpp
+ * Output: \verbinclude MatrixBase_random_int.out
+ *
+ * \sa MatrixBase::setRandom(), MatrixBase::Random(int,int), MatrixBase::Random()
+ */
+template<typename Derived>
+inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived>
+MatrixBase<Derived>::Random(int size)
+{
+ return NullaryExpr(size, ei_scalar_random_op<Scalar>());
+}
+
+/** \array_module
+ *
+ * \returns a fixed-size random matrix or vector
+ * (not an expression, the matrix is immediately evaluated).
+ *
+ * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
+ * need to use the variants taking size arguments.
+ *
+ * Example: \include MatrixBase_random.cpp
+ * Output: \verbinclude MatrixBase_random.out
+ *
+ * \sa MatrixBase::setRandom(), MatrixBase::Random(int,int), MatrixBase::Random(int)
+ */
+template<typename Derived>
+inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived>
+MatrixBase<Derived>::Random()
+{
+ return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_random_op<Scalar>());
+}
+
+/** \array_module
+ *
+ * Sets all coefficients in this expression to random values.
+ *
+ * Example: \include MatrixBase_setRandom.cpp
+ * Output: \verbinclude MatrixBase_setRandom.out
+ *
+ * \sa class CwiseNullaryOp, setRandom(int), setRandom(int,int)
+ */
+template<typename Derived>
+inline Derived& MatrixBase<Derived>::setRandom()
+{
+ return *this = Random(rows(), cols());
+}
+
+/** Resizes to the given \a size, and sets all coefficients in this expression to random values.
+ *
+ * \only_for_vectors
+ *
+ * Example: \include Matrix_setRandom_int.cpp
+ * Output: \verbinclude Matrix_setRandom_int.out
+ *
+ * \sa MatrixBase::setRandom(), setRandom(int,int), class CwiseNullaryOp, MatrixBase::Random()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setRandom(int size)
+{
+ resize(size);
+ return setRandom();
+}
+
+/** Resizes to the given size, and sets all coefficients in this expression to random values.
+ *
+ * \param rows the new number of rows
+ * \param cols the new number of columns
+ *
+ * Example: \include Matrix_setRandom_int_int.cpp
+ * Output: \verbinclude Matrix_setRandom_int_int.out
+ *
+ * \sa MatrixBase::setRandom(), setRandom(int), class CwiseNullaryOp, MatrixBase::Random()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setRandom(int rows, int cols)
+{
+ resize(rows, cols);
+ return setRandom();
+}
+
+#endif // EIGEN_RANDOM_H
diff --git a/extern/Eigen2/Eigen/src/Array/Select.h b/extern/Eigen2/Eigen/src/Array/Select.h
new file mode 100644
index 00000000000..9dc3fb1b27a
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Array/Select.h
@@ -0,0 +1,159 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SELECT_H
+#define EIGEN_SELECT_H
+
+/** \array_module \ingroup Array
+ *
+ * \class Select
+ *
+ * \brief Expression of a coefficient wise version of the C++ ternary operator ?:
+ *
+ * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix
+ * \param ThenMatrixType the type of the \em then expression
+ * \param ElseMatrixType the type of the \em else expression
+ *
+ * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:.
+ * It is the return type of MatrixBase::select() and most of the time this is the only way it is used.
+ *
+ * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const
+ */
+
+template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
+struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
+{
+ typedef typename ei_traits<ThenMatrixType>::Scalar Scalar;
+ typedef typename ConditionMatrixType::Nested ConditionMatrixNested;
+ typedef typename ThenMatrixType::Nested ThenMatrixNested;
+ typedef typename ElseMatrixType::Nested ElseMatrixNested;
+ enum {
+ RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
+ Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
+ CoeffReadCost = ei_traits<typename ei_cleantype<ConditionMatrixNested>::type>::CoeffReadCost
+ + EIGEN_ENUM_MAX(ei_traits<typename ei_cleantype<ThenMatrixNested>::type>::CoeffReadCost,
+ ei_traits<typename ei_cleantype<ElseMatrixNested>::type>::CoeffReadCost)
+ };
+};
+
+template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
+class Select : ei_no_assignment_operator,
+ public MatrixBase<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Select)
+
+ Select(const ConditionMatrixType& conditionMatrix,
+ const ThenMatrixType& thenMatrix,
+ const ElseMatrixType& elseMatrix)
+ : m_condition(conditionMatrix), m_then(thenMatrix), m_else(elseMatrix)
+ {
+ ei_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows());
+ ei_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
+ }
+
+ int rows() const { return m_condition.rows(); }
+ int cols() const { return m_condition.cols(); }
+
+ const Scalar coeff(int i, int j) const
+ {
+ if (m_condition.coeff(i,j))
+ return m_then.coeff(i,j);
+ else
+ return m_else.coeff(i,j);
+ }
+
+ const Scalar coeff(int i) const
+ {
+ if (m_condition.coeff(i))
+ return m_then.coeff(i);
+ else
+ return m_else.coeff(i);
+ }
+
+ protected:
+ const typename ConditionMatrixType::Nested m_condition;
+ const typename ThenMatrixType::Nested m_then;
+ const typename ElseMatrixType::Nested m_else;
+};
+
+
+/** \array_module
+ *
+ * \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j)
+ * if \c *this(i,j), and \a elseMatrix(i,j) otherwise.
+ *
+ * Example: \include MatrixBase_select.cpp
+ * Output: \verbinclude MatrixBase_select.out
+ *
+ * \sa class Select
+ */
+template<typename Derived>
+template<typename ThenDerived,typename ElseDerived>
+inline const Select<Derived,ThenDerived,ElseDerived>
+MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix,
+ const MatrixBase<ElseDerived>& elseMatrix) const
+{
+ return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived());
+}
+
+/** \array_module
+ *
+ * Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with
+ * the \em else expression being a scalar value.
+ *
+ * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select
+ */
+template<typename Derived>
+template<typename ThenDerived>
+inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
+MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix,
+ typename ThenDerived::Scalar elseScalar) const
+{
+ return Select<Derived,ThenDerived,NestByValue<typename ThenDerived::ConstantReturnType> >(
+ derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
+}
+
+/** \array_module
+ *
+ * Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with
+ * the \em then expression being a scalar value.
+ *
+ * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select
+ */
+template<typename Derived>
+template<typename ElseDerived>
+inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
+MatrixBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
+ const MatrixBase<ElseDerived>& elseMatrix) const
+{
+ return Select<Derived,NestByValue<typename ElseDerived::ConstantReturnType>,ElseDerived>(
+ derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
+}
+
+#endif // EIGEN_SELECT_H
diff --git a/extern/Eigen2/Eigen/src/Cholesky/CholeskyInstantiations.cpp b/extern/Eigen2/Eigen/src/Cholesky/CholeskyInstantiations.cpp
new file mode 100644
index 00000000000..e7f40a2ce9c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Cholesky/CholeskyInstantiations.cpp
@@ -0,0 +1,35 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_EXTERN_INSTANTIATIONS
+#define EIGEN_EXTERN_INSTANTIATIONS
+#endif
+#include "../../Core"
+#undef EIGEN_EXTERN_INSTANTIATIONS
+
+#include "../../Cholesky"
+
+namespace Eigen {
+ EIGEN_CHOLESKY_MODULE_INSTANTIATE();
+}
diff --git a/extern/Eigen2/Eigen/src/Cholesky/LDLT.h b/extern/Eigen2/Eigen/src/Cholesky/LDLT.h
new file mode 100644
index 00000000000..205b78a6ded
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Cholesky/LDLT.h
@@ -0,0 +1,198 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_LDLT_H
+#define EIGEN_LDLT_H
+
+/** \ingroup cholesky_Module
+ *
+ * \class LDLT
+ *
+ * \brief Robust Cholesky decomposition of a matrix and associated features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the LDL^T Cholesky decomposition
+ *
+ * This class performs a Cholesky decomposition without square root of a symmetric, positive definite
+ * matrix A such that A = L D L^* = U^* D U, where L is lower triangular with a unit diagonal
+ * and D is a diagonal matrix.
+ *
+ * Compared to a standard Cholesky decomposition, avoiding the square roots allows for faster and more
+ * stable computation.
+ *
+ * Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
+ * the strict lower part does not have to store correct values.
+ *
+ * \sa MatrixBase::ldlt(), class LLT
+ */
+template<typename MatrixType> class LDLT
+{
+ public:
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
+
+ LDLT(const MatrixType& matrix)
+ : m_matrix(matrix.rows(), matrix.cols())
+ {
+ compute(matrix);
+ }
+
+ /** \returns the lower triangular matrix L */
+ inline Part<MatrixType, UnitLowerTriangular> matrixL(void) const { return m_matrix; }
+
+ /** \returns the coefficients of the diagonal matrix D */
+ inline DiagonalCoeffs<MatrixType> vectorD(void) const { return m_matrix.diagonal(); }
+
+ /** \returns true if the matrix is positive definite */
+ inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
+
+ template<typename RhsDerived, typename ResultType>
+ bool solve(const MatrixBase<RhsDerived> &b, ResultType *result) const;
+
+ template<typename Derived>
+ bool solveInPlace(MatrixBase<Derived> &bAndX) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+ /** \internal
+ * Used to compute and store the cholesky decomposition A = L D L^* = U^* D U.
+ * The strict upper part is used during the decomposition, the strict lower
+ * part correspond to the coefficients of L (its diagonal is equal to 1 and
+ * is not stored), and the diagonal entries correspond to D.
+ */
+ MatrixType m_matrix;
+
+ bool m_isPositiveDefinite;
+};
+
+/** Compute / recompute the LLT decomposition A = L D L^* = U^* D U of \a matrix
+ */
+template<typename MatrixType>
+void LDLT<MatrixType>::compute(const MatrixType& a)
+{
+ assert(a.rows()==a.cols());
+ const int size = a.rows();
+ m_matrix.resize(size, size);
+ m_isPositiveDefinite = true;
+ const RealScalar eps = ei_sqrt(precision<Scalar>());
+
+ if (size<=1)
+ {
+ m_matrix = a;
+ return;
+ }
+
+ // Let's preallocate a temporay vector to evaluate the matrix-vector product into it.
+ // Unlike the standard LLT decomposition, here we cannot evaluate it to the destination
+ // matrix because it a sub-row which is not compatible suitable for efficient packet evaluation.
+ // (at least if we assume the matrix is col-major)
+ Matrix<Scalar,MatrixType::RowsAtCompileTime,1> _temporary(size);
+
+ // Note that, in this algorithm the rows of the strict upper part of m_matrix is used to store
+ // column vector, thus the strange .conjugate() and .transpose()...
+
+ m_matrix.row(0) = a.row(0).conjugate();
+ m_matrix.col(0).end(size-1) = m_matrix.row(0).end(size-1) / m_matrix.coeff(0,0);
+ for (int j = 1; j < size; ++j)
+ {
+ RealScalar tmp = ei_real(a.coeff(j,j) - (m_matrix.row(j).start(j) * m_matrix.col(j).start(j).conjugate()).coeff(0,0));
+ m_matrix.coeffRef(j,j) = tmp;
+
+ if (tmp < eps)
+ {
+ m_isPositiveDefinite = false;
+ return;
+ }
+
+ int endSize = size-j-1;
+ if (endSize>0)
+ {
+ _temporary.end(endSize) = ( m_matrix.block(j+1,0, endSize, j)
+ * m_matrix.col(j).start(j).conjugate() ).lazy();
+
+ m_matrix.row(j).end(endSize) = a.row(j).end(endSize).conjugate()
+ - _temporary.end(endSize).transpose();
+
+ m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
+ }
+ }
+}
+
+/** Computes the solution x of \f$ A x = b \f$ using the current decomposition of A.
+ * The result is stored in \a result
+ *
+ * \returns true in case of success, false otherwise.
+ *
+ * In other words, it computes \f$ b = A^{-1} b \f$ with
+ * \f$ {L^{*}}^{-1} D^{-1} L^{-1} b \f$ from right to left.
+ *
+ * \sa LDLT::solveInPlace(), MatrixBase::ldlt()
+ */
+template<typename MatrixType>
+template<typename RhsDerived, typename ResultType>
+bool LDLT<MatrixType>
+::solve(const MatrixBase<RhsDerived> &b, ResultType *result) const
+{
+ const int size = m_matrix.rows();
+ ei_assert(size==b.rows() && "LLT::solve(): invalid number of rows of the right hand side matrix b");
+ *result = b;
+ return solveInPlace(*result);
+}
+
+/** This is the \em in-place version of solve().
+ *
+ * \param bAndX represents both the right-hand side matrix b and result x.
+ *
+ * This version avoids a copy when the right hand side matrix b is not
+ * needed anymore.
+ *
+ * \sa LDLT::solve(), MatrixBase::ldlt()
+ */
+template<typename MatrixType>
+template<typename Derived>
+bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
+{
+ const int size = m_matrix.rows();
+ ei_assert(size==bAndX.rows());
+ if (!m_isPositiveDefinite)
+ return false;
+ matrixL().solveTriangularInPlace(bAndX);
+ bAndX = (m_matrix.cwise().inverse().template part<Diagonal>() * bAndX).lazy();
+ m_matrix.adjoint().template part<UnitUpperTriangular>().solveTriangularInPlace(bAndX);
+ return true;
+}
+
+/** \cholesky_module
+ * \returns the Cholesky decomposition without square root of \c *this
+ */
+template<typename Derived>
+inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
+MatrixBase<Derived>::ldlt() const
+{
+ return derived();
+}
+
+#endif // EIGEN_LDLT_H
diff --git a/extern/Eigen2/Eigen/src/Cholesky/LLT.h b/extern/Eigen2/Eigen/src/Cholesky/LLT.h
new file mode 100644
index 00000000000..42c959f83a2
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Cholesky/LLT.h
@@ -0,0 +1,219 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_LLT_H
+#define EIGEN_LLT_H
+
+/** \ingroup cholesky_Module
+ *
+ * \class LLT
+ *
+ * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition
+ *
+ * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite
+ * matrix A such that A = LL^* = U^*U, where L is lower triangular.
+ *
+ * While the Cholesky decomposition is particularly useful to solve selfadjoint problems like D^*D x = b,
+ * for that purpose, we recommend the Cholesky decomposition without square root which is more stable
+ * and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other
+ * situations like generalised eigen problems with hermitian matrices.
+ *
+ * Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices,
+ * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations
+ * has a solution.
+ *
+ * \sa MatrixBase::llt(), class LDLT
+ */
+ /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH)
+ * Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
+ * the strict lower part does not have to store correct values.
+ */
+template<typename MatrixType> class LLT
+{
+ private:
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
+
+ enum {
+ PacketSize = ei_packet_traits<Scalar>::size,
+ AlignmentMask = int(PacketSize)-1
+ };
+
+ public:
+
+ /**
+ * \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via LLT::compute(const MatrixType&).
+ */
+ LLT() : m_matrix(), m_isInitialized(false) {}
+
+ LLT(const MatrixType& matrix)
+ : m_matrix(matrix.rows(), matrix.cols()),
+ m_isInitialized(false)
+ {
+ compute(matrix);
+ }
+
+ /** \returns the lower triangular matrix L */
+ inline Part<MatrixType, LowerTriangular> matrixL(void) const
+ {
+ ei_assert(m_isInitialized && "LLT is not initialized.");
+ return m_matrix;
+ }
+
+ /** \deprecated */
+ inline bool isPositiveDefinite(void) const { return m_isInitialized && m_isPositiveDefinite; }
+
+ template<typename RhsDerived, typename ResultType>
+ bool solve(const MatrixBase<RhsDerived> &b, ResultType *result) const;
+
+ template<typename Derived>
+ bool solveInPlace(MatrixBase<Derived> &bAndX) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+ /** \internal
+ * Used to compute and store L
+ * The strict upper part is not used and even not initialized.
+ */
+ MatrixType m_matrix;
+ bool m_isInitialized;
+ bool m_isPositiveDefinite;
+};
+
+/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix
+ */
+template<typename MatrixType>
+void LLT<MatrixType>::compute(const MatrixType& a)
+{
+ assert(a.rows()==a.cols());
+ m_isPositiveDefinite = true;
+ const int size = a.rows();
+ m_matrix.resize(size, size);
+ // The biggest overall is the point of reference to which further diagonals
+ // are compared; if any diagonal is negligible compared
+ // to the largest overall, the algorithm bails. This cutoff is suggested
+ // in "Analysis of the Cholesky Decomposition of a Semi-definite Matrix" by
+ // Nicholas J. Higham. Also see "Accuracy and Stability of Numerical
+ // Algorithms" page 217, also by Higham.
+ const RealScalar cutoff = machine_epsilon<Scalar>() * size * a.diagonal().cwise().abs().maxCoeff();
+ RealScalar x;
+ x = ei_real(a.coeff(0,0));
+ m_matrix.coeffRef(0,0) = ei_sqrt(x);
+ if(size==1)
+ {
+ m_isInitialized = true;
+ return;
+ }
+ m_matrix.col(0).end(size-1) = a.row(0).end(size-1).adjoint() / ei_real(m_matrix.coeff(0,0));
+ for (int j = 1; j < size; ++j)
+ {
+ x = ei_real(a.coeff(j,j)) - m_matrix.row(j).start(j).squaredNorm();
+ if (x < cutoff)
+ {
+ m_isPositiveDefinite = false;
+ continue;
+ }
+
+ m_matrix.coeffRef(j,j) = x = ei_sqrt(x);
+
+ int endSize = size-j-1;
+ if (endSize>0) {
+ // Note that when all matrix columns have good alignment, then the following
+ // product is guaranteed to be optimal with respect to alignment.
+ m_matrix.col(j).end(endSize) =
+ (m_matrix.block(j+1, 0, endSize, j) * m_matrix.row(j).start(j).adjoint()).lazy();
+
+ // FIXME could use a.col instead of a.row
+ m_matrix.col(j).end(endSize) = (a.row(j).end(endSize).adjoint()
+ - m_matrix.col(j).end(endSize) ) / x;
+ }
+ }
+
+ m_isInitialized = true;
+}
+
+/** Computes the solution x of \f$ A x = b \f$ using the current decomposition of A.
+ * The result is stored in \a result
+ *
+ * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD.
+ *
+ * In other words, it computes \f$ b = A^{-1} b \f$ with
+ * \f$ {L^{*}}^{-1} L^{-1} b \f$ from right to left.
+ *
+ * Example: \include LLT_solve.cpp
+ * Output: \verbinclude LLT_solve.out
+ *
+ * \sa LLT::solveInPlace(), MatrixBase::llt()
+ */
+template<typename MatrixType>
+template<typename RhsDerived, typename ResultType>
+bool LLT<MatrixType>::solve(const MatrixBase<RhsDerived> &b, ResultType *result) const
+{
+ ei_assert(m_isInitialized && "LLT is not initialized.");
+ const int size = m_matrix.rows();
+ ei_assert(size==b.rows() && "LLT::solve(): invalid number of rows of the right hand side matrix b");
+ return solveInPlace((*result) = b);
+}
+
+/** This is the \em in-place version of solve().
+ *
+ * \param bAndX represents both the right-hand side matrix b and result x.
+ *
+ * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD.
+ *
+ * This version avoids a copy when the right hand side matrix b is not
+ * needed anymore.
+ *
+ * \sa LLT::solve(), MatrixBase::llt()
+ */
+template<typename MatrixType>
+template<typename Derived>
+bool LLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
+{
+ ei_assert(m_isInitialized && "LLT is not initialized.");
+ const int size = m_matrix.rows();
+ ei_assert(size==bAndX.rows());
+ matrixL().solveTriangularInPlace(bAndX);
+ m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
+ return true;
+}
+
+/** \cholesky_module
+ * \returns the LLT decomposition of \c *this
+ */
+template<typename Derived>
+inline const LLT<typename MatrixBase<Derived>::PlainMatrixType>
+MatrixBase<Derived>::llt() const
+{
+ return LLT<PlainMatrixType>(derived());
+}
+
+#endif // EIGEN_LLT_H
diff --git a/extern/Eigen2/Eigen/src/Core/Assign.h b/extern/Eigen2/Eigen/src/Core/Assign.h
new file mode 100644
index 00000000000..57205075596
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Assign.h
@@ -0,0 +1,445 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2007 Michael Olbrich <michael.olbrich@gmx.net>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ASSIGN_H
+#define EIGEN_ASSIGN_H
+
+/***************************************************************************
+* Part 1 : the logic deciding a strategy for vectorization and unrolling
+***************************************************************************/
+
+template <typename Derived, typename OtherDerived>
+struct ei_assign_traits
+{
+public:
+ enum {
+ DstIsAligned = Derived::Flags & AlignedBit,
+ SrcIsAligned = OtherDerived::Flags & AlignedBit,
+ SrcAlignment = DstIsAligned && SrcIsAligned ? Aligned : Unaligned
+ };
+
+private:
+ enum {
+ InnerSize = int(Derived::Flags)&RowMajorBit
+ ? Derived::ColsAtCompileTime
+ : Derived::RowsAtCompileTime,
+ InnerMaxSize = int(Derived::Flags)&RowMajorBit
+ ? Derived::MaxColsAtCompileTime
+ : Derived::MaxRowsAtCompileTime,
+ PacketSize = ei_packet_traits<typename Derived::Scalar>::size
+ };
+
+ enum {
+ MightVectorize = (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit)
+ && ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)),
+ MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
+ && int(DstIsAligned) && int(SrcIsAligned),
+ MayLinearVectorize = MightVectorize && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
+ MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize /* slice vectorization can be slow, so we only
+ want it if the slices are big, which is indicated by InnerMaxSize rather than InnerSize, think of the case
+ of a dynamic block in a fixed-size matrix */
+ };
+
+public:
+ enum {
+ Vectorization = int(MayInnerVectorize) ? int(InnerVectorization)
+ : int(MayLinearVectorize) ? int(LinearVectorization)
+ : int(MaySliceVectorize) ? int(SliceVectorization)
+ : int(NoVectorization)
+ };
+
+private:
+ enum {
+ UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)),
+ MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
+ MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
+ };
+
+public:
+ enum {
+ Unrolling = (int(Vectorization) == int(InnerVectorization) || int(Vectorization) == int(NoVectorization))
+ ? (
+ int(MayUnrollCompletely) ? int(CompleteUnrolling)
+ : int(MayUnrollInner) ? int(InnerUnrolling)
+ : int(NoUnrolling)
+ )
+ : int(Vectorization) == int(LinearVectorization)
+ ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
+ : int(NoUnrolling)
+ };
+};
+
+/***************************************************************************
+* Part 2 : meta-unrollers
+***************************************************************************/
+
+/***********************
+*** No vectorization ***
+***********************/
+
+template<typename Derived1, typename Derived2, int Index, int Stop>
+struct ei_assign_novec_CompleteUnrolling
+{
+ enum {
+ row = int(Derived1::Flags)&RowMajorBit
+ ? Index / int(Derived1::ColsAtCompileTime)
+ : Index % Derived1::RowsAtCompileTime,
+ col = int(Derived1::Flags)&RowMajorBit
+ ? Index % int(Derived1::ColsAtCompileTime)
+ : Index / Derived1::RowsAtCompileTime
+ };
+
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ dst.copyCoeff(row, col, src);
+ ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
+ }
+};
+
+template<typename Derived1, typename Derived2, int Stop>
+struct ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
+};
+
+template<typename Derived1, typename Derived2, int Index, int Stop>
+struct ei_assign_novec_InnerUnrolling
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
+ {
+ const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
+ const int row = rowMajor ? row_or_col : Index;
+ const int col = rowMajor ? Index : row_or_col;
+ dst.copyCoeff(row, col, src);
+ ei_assign_novec_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col);
+ }
+};
+
+template<typename Derived1, typename Derived2, int Stop>
+struct ei_assign_novec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
+};
+
+/**************************
+*** Inner vectorization ***
+**************************/
+
+template<typename Derived1, typename Derived2, int Index, int Stop>
+struct ei_assign_innervec_CompleteUnrolling
+{
+ enum {
+ row = int(Derived1::Flags)&RowMajorBit
+ ? Index / int(Derived1::ColsAtCompileTime)
+ : Index % Derived1::RowsAtCompileTime,
+ col = int(Derived1::Flags)&RowMajorBit
+ ? Index % int(Derived1::ColsAtCompileTime)
+ : Index / Derived1::RowsAtCompileTime,
+ SrcAlignment = ei_assign_traits<Derived1,Derived2>::SrcAlignment
+ };
+
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ dst.template copyPacket<Derived2, Aligned, SrcAlignment>(row, col, src);
+ ei_assign_innervec_CompleteUnrolling<Derived1, Derived2,
+ Index+ei_packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
+ }
+};
+
+template<typename Derived1, typename Derived2, int Stop>
+struct ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
+};
+
+template<typename Derived1, typename Derived2, int Index, int Stop>
+struct ei_assign_innervec_InnerUnrolling
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
+ {
+ const int row = int(Derived1::Flags)&RowMajorBit ? row_or_col : Index;
+ const int col = int(Derived1::Flags)&RowMajorBit ? Index : row_or_col;
+ dst.template copyPacket<Derived2, Aligned, Aligned>(row, col, src);
+ ei_assign_innervec_InnerUnrolling<Derived1, Derived2,
+ Index+ei_packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, row_or_col);
+ }
+};
+
+template<typename Derived1, typename Derived2, int Stop>
+struct ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
+};
+
+/***************************************************************************
+* Part 3 : implementation of all cases
+***************************************************************************/
+
+template<typename Derived1, typename Derived2,
+ int Vectorization = ei_assign_traits<Derived1, Derived2>::Vectorization,
+ int Unrolling = ei_assign_traits<Derived1, Derived2>::Unrolling>
+struct ei_assign_impl;
+
+/***********************
+*** No vectorization ***
+***********************/
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const int innerSize = dst.innerSize();
+ const int outerSize = dst.outerSize();
+ for(int j = 0; j < outerSize; ++j)
+ for(int i = 0; i < innerSize; ++i)
+ {
+ if(int(Derived1::Flags)&RowMajorBit)
+ dst.copyCoeff(j, i, src);
+ else
+ dst.copyCoeff(i, j, src);
+ }
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ ei_assign_novec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
+ ::run(dst, src);
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
+ const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
+ const int outerSize = dst.outerSize();
+ for(int j = 0; j < outerSize; ++j)
+ ei_assign_novec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
+ ::run(dst, src, j);
+ }
+};
+
+/**************************
+*** Inner vectorization ***
+**************************/
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const int innerSize = dst.innerSize();
+ const int outerSize = dst.outerSize();
+ const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
+ for(int j = 0; j < outerSize; ++j)
+ for(int i = 0; i < innerSize; i+=packetSize)
+ {
+ if(int(Derived1::Flags)&RowMajorBit)
+ dst.template copyPacket<Derived2, Aligned, Aligned>(j, i, src);
+ else
+ dst.template copyPacket<Derived2, Aligned, Aligned>(i, j, src);
+ }
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
+ ::run(dst, src);
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
+ const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
+ const int outerSize = dst.outerSize();
+ for(int j = 0; j < outerSize; ++j)
+ ei_assign_innervec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
+ ::run(dst, src, j);
+ }
+};
+
+/***************************
+*** Linear vectorization ***
+***************************/
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const int size = dst.size();
+ const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
+ const int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
+ : ei_alignmentOffset(&dst.coeffRef(0), size);
+ const int alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
+
+ for(int index = 0; index < alignedStart; ++index)
+ dst.copyCoeff(index, src);
+
+ for(int index = alignedStart; index < alignedEnd; index += packetSize)
+ {
+ dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);
+ }
+
+ for(int index = alignedEnd; index < size; ++index)
+ dst.copyCoeff(index, src);
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const int size = Derived1::SizeAtCompileTime;
+ const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
+ const int alignedSize = (size/packetSize)*packetSize;
+
+ ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
+ ei_assign_novec_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
+ }
+};
+
+/**************************
+*** Slice vectorization ***
+***************************/
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
+ const int packetAlignedMask = packetSize - 1;
+ const int innerSize = dst.innerSize();
+ const int outerSize = dst.outerSize();
+ const int alignedStep = (packetSize - dst.stride() % packetSize) & packetAlignedMask;
+ int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
+ : ei_alignmentOffset(&dst.coeffRef(0,0), innerSize);
+
+ for(int i = 0; i < outerSize; ++i)
+ {
+ const int alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
+
+ // do the non-vectorizable part of the assignment
+ for (int index = 0; index<alignedStart ; ++index)
+ {
+ if(Derived1::Flags&RowMajorBit)
+ dst.copyCoeff(i, index, src);
+ else
+ dst.copyCoeff(index, i, src);
+ }
+
+ // do the vectorizable part of the assignment
+ for (int index = alignedStart; index<alignedEnd; index+=packetSize)
+ {
+ if(Derived1::Flags&RowMajorBit)
+ dst.template copyPacket<Derived2, Aligned, Unaligned>(i, index, src);
+ else
+ dst.template copyPacket<Derived2, Aligned, Unaligned>(index, i, src);
+ }
+
+ // do the non-vectorizable part of the assignment
+ for (int index = alignedEnd; index<innerSize ; ++index)
+ {
+ if(Derived1::Flags&RowMajorBit)
+ dst.copyCoeff(i, index, src);
+ else
+ dst.copyCoeff(index, i, src);
+ }
+
+ alignedStart = std::min<int>((alignedStart+alignedStep)%packetSize, innerSize);
+ }
+ }
+};
+
+/***************************************************************************
+* Part 4 : implementation of MatrixBase methods
+***************************************************************************/
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
+ ::lazyAssign(const MatrixBase<OtherDerived>& other)
+{
+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
+ EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+ ei_assert(rows() == other.rows() && cols() == other.cols());
+ ei_assign_impl<Derived, OtherDerived>::run(derived(),other.derived());
+ return derived();
+}
+
+template<typename Derived, typename OtherDerived,
+ bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0,
+ bool NeedToTranspose = Derived::IsVectorAtCompileTime
+ && OtherDerived::IsVectorAtCompileTime
+ && int(Derived::RowsAtCompileTime) == int(OtherDerived::ColsAtCompileTime)
+ && int(Derived::ColsAtCompileTime) == int(OtherDerived::RowsAtCompileTime)
+ && int(Derived::SizeAtCompileTime) != 1>
+struct ei_assign_selector;
+
+template<typename Derived, typename OtherDerived>
+struct ei_assign_selector<Derived,OtherDerived,false,false> {
+ EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
+};
+template<typename Derived, typename OtherDerived>
+struct ei_assign_selector<Derived,OtherDerived,true,false> {
+ EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
+};
+template<typename Derived, typename OtherDerived>
+struct ei_assign_selector<Derived,OtherDerived,false,true> {
+ EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
+};
+template<typename Derived, typename OtherDerived>
+struct ei_assign_selector<Derived,OtherDerived,true,true> {
+ EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
+};
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
+ ::operator=(const MatrixBase<OtherDerived>& other)
+{
+ return ei_assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
+}
+
+#endif // EIGEN_ASSIGN_H
diff --git a/extern/Eigen2/Eigen/src/Core/Block.h b/extern/Eigen2/Eigen/src/Core/Block.h
new file mode 100644
index 00000000000..7f422aa5c07
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Block.h
@@ -0,0 +1,752 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_BLOCK_H
+#define EIGEN_BLOCK_H
+
+/** \class Block
+ *
+ * \brief Expression of a fixed-size or dynamic-size block
+ *
+ * \param MatrixType the type of the object in which we are taking a block
+ * \param BlockRows the number of rows of the block we are taking at compile time (optional)
+ * \param BlockCols the number of columns of the block we are taking at compile time (optional)
+ * \param _PacketAccess allows to enforce aligned loads and stores if set to ForceAligned.
+ * The default is AsRequested. This parameter is internaly used by Eigen
+ * in expressions such as \code mat.block() += other; \endcode and most of
+ * the time this is the only way it is used.
+ * \param _DirectAccessStatus \internal used for partial specialization
+ *
+ * This class represents an expression of either a fixed-size or dynamic-size block. It is the return
+ * type of MatrixBase::block(int,int,int,int) and MatrixBase::block<int,int>(int,int) and
+ * most of the time this is the only way it is used.
+ *
+ * However, if you want to directly maniputate block expressions,
+ * for instance if you want to write a function returning such an expression, you
+ * will need to use this class.
+ *
+ * Here is an example illustrating the dynamic case:
+ * \include class_Block.cpp
+ * Output: \verbinclude class_Block.out
+ *
+ * \note Even though this expression has dynamic size, in the case where \a MatrixType
+ * has fixed size, this expression inherits a fixed maximal size which means that evaluating
+ * it does not cause a dynamic memory allocation.
+ *
+ * Here is an example illustrating the fixed-size case:
+ * \include class_FixedBlock.cpp
+ * Output: \verbinclude class_FixedBlock.out
+ *
+ * \sa MatrixBase::block(int,int,int,int), MatrixBase::block(int,int), class VectorBlock
+ */
+
+template<typename MatrixType, int BlockRows, int BlockCols, int _PacketAccess, int _DirectAccessStatus>
+struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus> >
+{
+ typedef typename ei_traits<MatrixType>::Scalar Scalar;
+ typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum{
+ RowsAtCompileTime = ei_traits<MatrixType>::RowsAtCompileTime == 1 ? 1 : BlockRows,
+ ColsAtCompileTime = ei_traits<MatrixType>::ColsAtCompileTime == 1 ? 1 : BlockCols,
+ MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
+ : (BlockRows==Dynamic ? int(ei_traits<MatrixType>::MaxRowsAtCompileTime) : BlockRows),
+ MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1
+ : (BlockCols==Dynamic ? int(ei_traits<MatrixType>::MaxColsAtCompileTime) : BlockCols),
+ RowMajor = int(ei_traits<MatrixType>::Flags)&RowMajorBit,
+ InnerSize = RowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
+ InnerMaxSize = RowMajor ? int(MaxColsAtCompileTime) : int(MaxRowsAtCompileTime),
+ MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits<Scalar>::size))
+ ? PacketAccessBit : 0,
+ FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
+ Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
+ CoeffReadCost = ei_traits<MatrixType>::CoeffReadCost,
+ PacketAccess = _PacketAccess
+ };
+ typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,
+ Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus>&,
+ Block<MatrixType, BlockRows, BlockCols, ForceAligned, _DirectAccessStatus> >::ret AlignedDerivedType;
+};
+
+template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, int _DirectAccessStatus> class Block
+ : public MatrixBase<Block<MatrixType, BlockRows, BlockCols, PacketAccess, _DirectAccessStatus> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
+
+ class InnerIterator;
+
+ /** Column or Row constructor
+ */
+ inline Block(const MatrixType& matrix, int i)
+ : m_matrix(matrix),
+ // It is a row if and only if BlockRows==1 and BlockCols==MatrixType::ColsAtCompileTime,
+ // and it is a column if and only if BlockRows==MatrixType::RowsAtCompileTime and BlockCols==1,
+ // all other cases are invalid.
+ // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
+ m_startRow( (BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0),
+ m_startCol( (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
+ m_blockRows(matrix.rows()), // if it is a row, then m_blockRows has a fixed-size of 1, so no pb to try to overwrite it
+ m_blockCols(matrix.cols()) // same for m_blockCols
+ {
+ ei_assert( (i>=0) && (
+ ((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
+ ||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
+ }
+
+ /** Fixed-size constructor
+ */
+ inline Block(const MatrixType& matrix, int startRow, int startCol)
+ : m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
+ m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
+ {
+ EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
+ ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
+ && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
+ }
+
+ /** Dynamic-size constructor
+ */
+ inline Block(const MatrixType& matrix,
+ int startRow, int startCol,
+ int blockRows, int blockCols)
+ : m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
+ m_blockRows(blockRows), m_blockCols(blockCols)
+ {
+ ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
+ && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
+ ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
+ && startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
+ }
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
+
+ inline int rows() const { return m_blockRows.value(); }
+ inline int cols() const { return m_blockCols.value(); }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived()
+ .coeffRef(row + m_startRow.value(), col + m_startCol.value());
+ }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived()
+ .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ return m_matrix
+ .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+
+ template<int LoadMode>
+ inline PacketScalar packet(int row, int col) const
+ {
+ return m_matrix.template packet<Unaligned>
+ (row + m_startRow.value(), col + m_startCol.value());
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int row, int col, const PacketScalar& x)
+ {
+ m_matrix.const_cast_derived().template writePacket<Unaligned>
+ (row + m_startRow.value(), col + m_startCol.value(), x);
+ }
+
+ template<int LoadMode>
+ inline PacketScalar packet(int index) const
+ {
+ return m_matrix.template packet<Unaligned>
+ (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int index, const PacketScalar& x)
+ {
+ m_matrix.const_cast_derived().template writePacket<Unaligned>
+ (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x);
+ }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+ const ei_int_if_dynamic<MatrixType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
+ const ei_int_if_dynamic<MatrixType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
+ const ei_int_if_dynamic<RowsAtCompileTime> m_blockRows;
+ const ei_int_if_dynamic<ColsAtCompileTime> m_blockCols;
+};
+
+/** \internal */
+template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess>
+class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess>
+ : public MapBase<Block<MatrixType, BlockRows, BlockCols,PacketAccess,HasDirectAccess> >
+{
+ public:
+
+ _EIGEN_GENERIC_PUBLIC_INTERFACE(Block, MapBase<Block>)
+
+ class InnerIterator;
+ typedef typename ei_traits<Block>::AlignedDerivedType AlignedDerivedType;
+ friend class Block<MatrixType,BlockRows,BlockCols,PacketAccess==AsRequested?ForceAligned:AsRequested,HasDirectAccess>;
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
+
+ AlignedDerivedType _convertToForceAligned()
+ {
+ return Block<MatrixType,BlockRows,BlockCols,ForceAligned,HasDirectAccess>
+ (m_matrix, Base::m_data, Base::m_rows.value(), Base::m_cols.value());
+ }
+
+ /** Column or Row constructor
+ */
+ inline Block(const MatrixType& matrix, int i)
+ : Base(&matrix.const_cast_derived().coeffRef(
+ (BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0,
+ (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
+ BlockRows==1 ? 1 : matrix.rows(),
+ BlockCols==1 ? 1 : matrix.cols()),
+ m_matrix(matrix)
+ {
+ ei_assert( (i>=0) && (
+ ((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
+ ||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
+ }
+
+ /** Fixed-size constructor
+ */
+ inline Block(const MatrixType& matrix, int startRow, int startCol)
+ : Base(&matrix.const_cast_derived().coeffRef(startRow,startCol)), m_matrix(matrix)
+ {
+ ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
+ && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
+ }
+
+ /** Dynamic-size constructor
+ */
+ inline Block(const MatrixType& matrix,
+ int startRow, int startCol,
+ int blockRows, int blockCols)
+ : Base(&matrix.const_cast_derived().coeffRef(startRow,startCol), blockRows, blockCols),
+ m_matrix(matrix)
+ {
+ ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
+ && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
+ ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
+ && startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
+ }
+
+ inline int stride(void) const { return m_matrix.stride(); }
+
+ protected:
+
+ /** \internal used by allowAligned() */
+ inline Block(const MatrixType& matrix, const Scalar* data, int blockRows, int blockCols)
+ : Base(data, blockRows, blockCols), m_matrix(matrix)
+ {}
+
+ const typename MatrixType::Nested m_matrix;
+};
+
+/** \returns a dynamic-size expression of a block in *this.
+ *
+ * \param startRow the first row in the block
+ * \param startCol the first column in the block
+ * \param blockRows the number of rows in the block
+ * \param blockCols the number of columns in the block
+ *
+ * \addexample BlockIntIntIntInt \label How to reference a sub-matrix (dynamic-size)
+ *
+ * Example: \include MatrixBase_block_int_int_int_int.cpp
+ * Output: \verbinclude MatrixBase_block_int_int_int_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, block(int,int)
+ */
+template<typename Derived>
+inline typename BlockReturnType<Derived>::Type MatrixBase<Derived>
+ ::block(int startRow, int startCol, int blockRows, int blockCols)
+{
+ return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
+}
+
+/** This is the const version of block(int,int,int,int). */
+template<typename Derived>
+inline const typename BlockReturnType<Derived>::Type MatrixBase<Derived>
+ ::block(int startRow, int startCol, int blockRows, int blockCols) const
+{
+ return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
+}
+
+/** \returns a dynamic-size expression of a segment (i.e. a vector block) in *this.
+ *
+ * \only_for_vectors
+ *
+ * \addexample SegmentIntInt \label How to reference a sub-vector (dynamic size)
+ *
+ * \param start the first coefficient in the segment
+ * \param size the number of coefficients in the segment
+ *
+ * Example: \include MatrixBase_segment_int_int.cpp
+ * Output: \verbinclude MatrixBase_segment_int_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, segment(int)
+ */
+template<typename Derived>
+inline typename BlockReturnType<Derived>::SubVectorType MatrixBase<Derived>
+ ::segment(int start, int size)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename BlockReturnType<Derived>::SubVectorType(derived(), RowsAtCompileTime == 1 ? 0 : start,
+ ColsAtCompileTime == 1 ? 0 : start,
+ RowsAtCompileTime == 1 ? 1 : size,
+ ColsAtCompileTime == 1 ? 1 : size);
+}
+
+/** This is the const version of segment(int,int).*/
+template<typename Derived>
+inline const typename BlockReturnType<Derived>::SubVectorType
+MatrixBase<Derived>::segment(int start, int size) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename BlockReturnType<Derived>::SubVectorType(derived(), RowsAtCompileTime == 1 ? 0 : start,
+ ColsAtCompileTime == 1 ? 0 : start,
+ RowsAtCompileTime == 1 ? 1 : size,
+ ColsAtCompileTime == 1 ? 1 : size);
+}
+
+/** \returns a dynamic-size expression of the first coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * \param size the number of coefficients in the block
+ *
+ * \addexample BlockInt \label How to reference a sub-vector (fixed-size)
+ *
+ * Example: \include MatrixBase_start_int.cpp
+ * Output: \verbinclude MatrixBase_start_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, block(int,int)
+ */
+template<typename Derived>
+inline typename BlockReturnType<Derived,Dynamic>::SubVectorType
+MatrixBase<Derived>::start(int size)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived,
+ RowsAtCompileTime == 1 ? 1 : Dynamic,
+ ColsAtCompileTime == 1 ? 1 : Dynamic>
+ (derived(), 0, 0,
+ RowsAtCompileTime == 1 ? 1 : size,
+ ColsAtCompileTime == 1 ? 1 : size);
+}
+
+/** This is the const version of start(int).*/
+template<typename Derived>
+inline const typename BlockReturnType<Derived,Dynamic>::SubVectorType
+MatrixBase<Derived>::start(int size) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived,
+ RowsAtCompileTime == 1 ? 1 : Dynamic,
+ ColsAtCompileTime == 1 ? 1 : Dynamic>
+ (derived(), 0, 0,
+ RowsAtCompileTime == 1 ? 1 : size,
+ ColsAtCompileTime == 1 ? 1 : size);
+}
+
+/** \returns a dynamic-size expression of the last coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * \param size the number of coefficients in the block
+ *
+ * \addexample BlockEnd \label How to reference the end of a vector (fixed-size)
+ *
+ * Example: \include MatrixBase_end_int.cpp
+ * Output: \verbinclude MatrixBase_end_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, block(int,int)
+ */
+template<typename Derived>
+inline typename BlockReturnType<Derived,Dynamic>::SubVectorType
+MatrixBase<Derived>::end(int size)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived,
+ RowsAtCompileTime == 1 ? 1 : Dynamic,
+ ColsAtCompileTime == 1 ? 1 : Dynamic>
+ (derived(),
+ RowsAtCompileTime == 1 ? 0 : rows() - size,
+ ColsAtCompileTime == 1 ? 0 : cols() - size,
+ RowsAtCompileTime == 1 ? 1 : size,
+ ColsAtCompileTime == 1 ? 1 : size);
+}
+
+/** This is the const version of end(int).*/
+template<typename Derived>
+inline const typename BlockReturnType<Derived,Dynamic>::SubVectorType
+MatrixBase<Derived>::end(int size) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived,
+ RowsAtCompileTime == 1 ? 1 : Dynamic,
+ ColsAtCompileTime == 1 ? 1 : Dynamic>
+ (derived(),
+ RowsAtCompileTime == 1 ? 0 : rows() - size,
+ ColsAtCompileTime == 1 ? 0 : cols() - size,
+ RowsAtCompileTime == 1 ? 1 : size,
+ ColsAtCompileTime == 1 ? 1 : size);
+}
+
+/** \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this
+ *
+ * \only_for_vectors
+ *
+ * The template parameter \a Size is the number of coefficients in the block
+ *
+ * \param start the index of the first element of the sub-vector
+ *
+ * Example: \include MatrixBase_template_int_segment.cpp
+ * Output: \verbinclude MatrixBase_template_int_segment.out
+ *
+ * \sa class Block
+ */
+template<typename Derived>
+template<int Size>
+inline typename BlockReturnType<Derived,Size>::SubVectorType
+MatrixBase<Derived>::segment(int start)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
+ (ColsAtCompileTime == 1 ? 1 : Size)>
+ (derived(), RowsAtCompileTime == 1 ? 0 : start,
+ ColsAtCompileTime == 1 ? 0 : start);
+}
+
+/** This is the const version of segment<int>(int).*/
+template<typename Derived>
+template<int Size>
+inline const typename BlockReturnType<Derived,Size>::SubVectorType
+MatrixBase<Derived>::segment(int start) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
+ (ColsAtCompileTime == 1 ? 1 : Size)>
+ (derived(), RowsAtCompileTime == 1 ? 0 : start,
+ ColsAtCompileTime == 1 ? 0 : start);
+}
+
+/** \returns a fixed-size expression of the first coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * The template parameter \a Size is the number of coefficients in the block
+ *
+ * \addexample BlockStart \label How to reference the start of a vector (fixed-size)
+ *
+ * Example: \include MatrixBase_template_int_start.cpp
+ * Output: \verbinclude MatrixBase_template_int_start.out
+ *
+ * \sa class Block
+ */
+template<typename Derived>
+template<int Size>
+inline typename BlockReturnType<Derived,Size>::SubVectorType
+MatrixBase<Derived>::start()
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
+ (ColsAtCompileTime == 1 ? 1 : Size)>(derived(), 0, 0);
+}
+
+/** This is the const version of start<int>().*/
+template<typename Derived>
+template<int Size>
+inline const typename BlockReturnType<Derived,Size>::SubVectorType
+MatrixBase<Derived>::start() const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
+ (ColsAtCompileTime == 1 ? 1 : Size)>(derived(), 0, 0);
+}
+
+/** \returns a fixed-size expression of the last coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * The template parameter \a Size is the number of coefficients in the block
+ *
+ * Example: \include MatrixBase_template_int_end.cpp
+ * Output: \verbinclude MatrixBase_template_int_end.out
+ *
+ * \sa class Block
+ */
+template<typename Derived>
+template<int Size>
+inline typename BlockReturnType<Derived,Size>::SubVectorType
+MatrixBase<Derived>::end()
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived, RowsAtCompileTime == 1 ? 1 : Size,
+ ColsAtCompileTime == 1 ? 1 : Size>
+ (derived(),
+ RowsAtCompileTime == 1 ? 0 : rows() - Size,
+ ColsAtCompileTime == 1 ? 0 : cols() - Size);
+}
+
+/** This is the const version of end<int>.*/
+template<typename Derived>
+template<int Size>
+inline const typename BlockReturnType<Derived,Size>::SubVectorType
+MatrixBase<Derived>::end() const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return Block<Derived, RowsAtCompileTime == 1 ? 1 : Size,
+ ColsAtCompileTime == 1 ? 1 : Size>
+ (derived(),
+ RowsAtCompileTime == 1 ? 0 : rows() - Size,
+ ColsAtCompileTime == 1 ? 0 : cols() - Size);
+}
+
+/** \returns a dynamic-size expression of a corner of *this.
+ *
+ * \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
+ * \a Eigen::BottomLeft, \a Eigen::BottomRight.
+ * \param cRows the number of rows in the corner
+ * \param cCols the number of columns in the corner
+ *
+ * \addexample BlockCornerDynamicSize \label How to reference a sub-corner of a matrix
+ *
+ * Example: \include MatrixBase_corner_enum_int_int.cpp
+ * Output: \verbinclude MatrixBase_corner_enum_int_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, block(int,int,int,int)
+ */
+template<typename Derived>
+inline typename BlockReturnType<Derived>::Type MatrixBase<Derived>
+ ::corner(CornerType type, int cRows, int cCols)
+{
+ switch(type)
+ {
+ default:
+ ei_assert(false && "Bad corner type.");
+ case TopLeft:
+ return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
+ case TopRight:
+ return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
+ case BottomLeft:
+ return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
+ case BottomRight:
+ return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
+ }
+}
+
+/** This is the const version of corner(CornerType, int, int).*/
+template<typename Derived>
+inline const typename BlockReturnType<Derived>::Type
+MatrixBase<Derived>::corner(CornerType type, int cRows, int cCols) const
+{
+ switch(type)
+ {
+ default:
+ ei_assert(false && "Bad corner type.");
+ case TopLeft:
+ return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
+ case TopRight:
+ return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
+ case BottomLeft:
+ return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
+ case BottomRight:
+ return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
+ }
+}
+
+/** \returns a fixed-size expression of a corner of *this.
+ *
+ * \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
+ * \a Eigen::BottomLeft, \a Eigen::BottomRight.
+ *
+ * The template parameters CRows and CCols arethe number of rows and columns in the corner.
+ *
+ * Example: \include MatrixBase_template_int_int_corner_enum.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_corner_enum.out
+ *
+ * \sa class Block, block(int,int,int,int)
+ */
+template<typename Derived>
+template<int CRows, int CCols>
+inline typename BlockReturnType<Derived, CRows, CCols>::Type
+MatrixBase<Derived>::corner(CornerType type)
+{
+ switch(type)
+ {
+ default:
+ ei_assert(false && "Bad corner type.");
+ case TopLeft:
+ return Block<Derived, CRows, CCols>(derived(), 0, 0);
+ case TopRight:
+ return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
+ case BottomLeft:
+ return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
+ case BottomRight:
+ return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
+ }
+}
+
+/** This is the const version of corner<int, int>(CornerType).*/
+template<typename Derived>
+template<int CRows, int CCols>
+inline const typename BlockReturnType<Derived, CRows, CCols>::Type
+MatrixBase<Derived>::corner(CornerType type) const
+{
+ switch(type)
+ {
+ default:
+ ei_assert(false && "Bad corner type.");
+ case TopLeft:
+ return Block<Derived, CRows, CCols>(derived(), 0, 0);
+ case TopRight:
+ return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
+ case BottomLeft:
+ return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
+ case BottomRight:
+ return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
+ }
+}
+
+/** \returns a fixed-size expression of a block in *this.
+ *
+ * The template parameters \a BlockRows and \a BlockCols are the number of
+ * rows and columns in the block.
+ *
+ * \param startRow the first row in the block
+ * \param startCol the first column in the block
+ *
+ * \addexample BlockSubMatrixFixedSize \label How to reference a sub-matrix (fixed-size)
+ *
+ * Example: \include MatrixBase_block_int_int.cpp
+ * Output: \verbinclude MatrixBase_block_int_int.out
+ *
+ * \note since block is a templated member, the keyword template has to be used
+ * if the matrix type is also a template parameter: \code m.template block<3,3>(1,1); \endcode
+ *
+ * \sa class Block, block(int,int,int,int)
+ */
+template<typename Derived>
+template<int BlockRows, int BlockCols>
+inline typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
+MatrixBase<Derived>::block(int startRow, int startCol)
+{
+ return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
+}
+
+/** This is the const version of block<>(int, int). */
+template<typename Derived>
+template<int BlockRows, int BlockCols>
+inline const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
+MatrixBase<Derived>::block(int startRow, int startCol) const
+{
+ return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
+}
+
+/** \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0.
+ *
+ * \addexample BlockColumn \label How to reference a single column of a matrix
+ *
+ * Example: \include MatrixBase_col.cpp
+ * Output: \verbinclude MatrixBase_col.out
+ *
+ * \sa row(), class Block */
+template<typename Derived>
+inline typename MatrixBase<Derived>::ColXpr
+MatrixBase<Derived>::col(int i)
+{
+ return ColXpr(derived(), i);
+}
+
+/** This is the const version of col(). */
+template<typename Derived>
+inline const typename MatrixBase<Derived>::ColXpr
+MatrixBase<Derived>::col(int i) const
+{
+ return ColXpr(derived(), i);
+}
+
+/** \returns an expression of the \a i-th row of *this. Note that the numbering starts at 0.
+ *
+ * \addexample BlockRow \label How to reference a single row of a matrix
+ *
+ * Example: \include MatrixBase_row.cpp
+ * Output: \verbinclude MatrixBase_row.out
+ *
+ * \sa col(), class Block */
+template<typename Derived>
+inline typename MatrixBase<Derived>::RowXpr
+MatrixBase<Derived>::row(int i)
+{
+ return RowXpr(derived(), i);
+}
+
+/** This is the const version of row(). */
+template<typename Derived>
+inline const typename MatrixBase<Derived>::RowXpr
+MatrixBase<Derived>::row(int i) const
+{
+ return RowXpr(derived(), i);
+}
+
+#endif // EIGEN_BLOCK_H
diff --git a/extern/Eigen2/Eigen/src/Core/CacheFriendlyProduct.h b/extern/Eigen2/Eigen/src/Core/CacheFriendlyProduct.h
new file mode 100644
index 00000000000..b1362b0a80c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/CacheFriendlyProduct.h
@@ -0,0 +1,753 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CACHE_FRIENDLY_PRODUCT_H
+#define EIGEN_CACHE_FRIENDLY_PRODUCT_H
+
+template <int L2MemorySize,typename Scalar>
+struct ei_L2_block_traits {
+ enum {width = 8 * ei_meta_sqrt<L2MemorySize/(64*sizeof(Scalar))>::ret };
+};
+
+#ifndef EIGEN_EXTERN_INSTANTIATIONS
+
+template<typename Scalar>
+static void ei_cache_friendly_product(
+ int _rows, int _cols, int depth,
+ bool _lhsRowMajor, const Scalar* _lhs, int _lhsStride,
+ bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride,
+ bool resRowMajor, Scalar* res, int resStride)
+{
+ const Scalar* EIGEN_RESTRICT lhs;
+ const Scalar* EIGEN_RESTRICT rhs;
+ int lhsStride, rhsStride, rows, cols;
+ bool lhsRowMajor;
+
+ if (resRowMajor)
+ {
+ lhs = _rhs;
+ rhs = _lhs;
+ lhsStride = _rhsStride;
+ rhsStride = _lhsStride;
+ cols = _rows;
+ rows = _cols;
+ lhsRowMajor = !_rhsRowMajor;
+ ei_assert(_lhsRowMajor);
+ }
+ else
+ {
+ lhs = _lhs;
+ rhs = _rhs;
+ lhsStride = _lhsStride;
+ rhsStride = _rhsStride;
+ rows = _rows;
+ cols = _cols;
+ lhsRowMajor = _lhsRowMajor;
+ ei_assert(!_rhsRowMajor);
+ }
+
+ typedef typename ei_packet_traits<Scalar>::type PacketType;
+
+ enum {
+ PacketSize = sizeof(PacketType)/sizeof(Scalar),
+ #if (defined __i386__)
+ // i386 architecture provides only 8 xmm registers,
+ // so let's reduce the max number of rows processed at once.
+ MaxBlockRows = 4,
+ MaxBlockRows_ClampingMask = 0xFFFFFC,
+ #else
+ MaxBlockRows = 8,
+ MaxBlockRows_ClampingMask = 0xFFFFF8,
+ #endif
+ // maximal size of the blocks fitted in L2 cache
+ MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_CPU_CACHE_SIZE,Scalar>::width
+ };
+
+ const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (size_t(res)%16==0));
+
+ const int remainingSize = depth % PacketSize;
+ const int size = depth - remainingSize; // third dimension of the product clamped to packet boundaries
+ const int l2BlockRows = MaxL2BlockSize > rows ? rows : MaxL2BlockSize;
+ const int l2BlockCols = MaxL2BlockSize > cols ? cols : MaxL2BlockSize;
+ const int l2BlockSize = MaxL2BlockSize > size ? size : MaxL2BlockSize;
+ const int l2BlockSizeAligned = (1 + std::max(l2BlockSize,l2BlockCols)/PacketSize)*PacketSize;
+ const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (size_t(rhs)%16!=0));
+ Scalar* EIGEN_RESTRICT block = 0;
+ const int allocBlockSize = l2BlockRows*size;
+ block = ei_aligned_stack_new(Scalar, allocBlockSize);
+ Scalar* EIGEN_RESTRICT rhsCopy
+ = ei_aligned_stack_new(Scalar, l2BlockSizeAligned*l2BlockSizeAligned);
+
+ // loops on each L2 cache friendly blocks of the result
+ for(int l2i=0; l2i<rows; l2i+=l2BlockRows)
+ {
+ const int l2blockRowEnd = std::min(l2i+l2BlockRows, rows);
+ const int l2blockRowEndBW = l2blockRowEnd & MaxBlockRows_ClampingMask; // end of the rows aligned to bw
+ const int l2blockRemainingRows = l2blockRowEnd - l2blockRowEndBW; // number of remaining rows
+ //const int l2blockRowEndBWPlusOne = l2blockRowEndBW + (l2blockRemainingRows?0:MaxBlockRows);
+
+ // build a cache friendly blocky matrix
+ int count = 0;
+
+ // copy l2blocksize rows of m_lhs to blocks of ps x bw
+ for(int l2k=0; l2k<size; l2k+=l2BlockSize)
+ {
+ const int l2blockSizeEnd = std::min(l2k+l2BlockSize, size);
+
+ for (int i = l2i; i<l2blockRowEndBW/*PlusOne*/; i+=MaxBlockRows)
+ {
+ // TODO merge the "if l2blockRemainingRows" using something like:
+ // const int blockRows = std::min(i+MaxBlockRows, rows) - i;
+
+ for (int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
+ {
+ // TODO write these loops using meta unrolling
+ // negligible for large matrices but useful for small ones
+ if (lhsRowMajor)
+ {
+ for (int w=0; w<MaxBlockRows; ++w)
+ for (int s=0; s<PacketSize; ++s)
+ block[count++] = lhs[(i+w)*lhsStride + (k+s)];
+ }
+ else
+ {
+ for (int w=0; w<MaxBlockRows; ++w)
+ for (int s=0; s<PacketSize; ++s)
+ block[count++] = lhs[(i+w) + (k+s)*lhsStride];
+ }
+ }
+ }
+ if (l2blockRemainingRows>0)
+ {
+ for (int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
+ {
+ if (lhsRowMajor)
+ {
+ for (int w=0; w<l2blockRemainingRows; ++w)
+ for (int s=0; s<PacketSize; ++s)
+ block[count++] = lhs[(l2blockRowEndBW+w)*lhsStride + (k+s)];
+ }
+ else
+ {
+ for (int w=0; w<l2blockRemainingRows; ++w)
+ for (int s=0; s<PacketSize; ++s)
+ block[count++] = lhs[(l2blockRowEndBW+w) + (k+s)*lhsStride];
+ }
+ }
+ }
+ }
+
+ for(int l2j=0; l2j<cols; l2j+=l2BlockCols)
+ {
+ int l2blockColEnd = std::min(l2j+l2BlockCols, cols);
+
+ for(int l2k=0; l2k<size; l2k+=l2BlockSize)
+ {
+ // acumulate bw rows of lhs time a single column of rhs to a bw x 1 block of res
+ int l2blockSizeEnd = std::min(l2k+l2BlockSize, size);
+
+ // if not aligned, copy the rhs block
+ if (needRhsCopy)
+ for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
+ {
+ ei_internal_assert(l2BlockSizeAligned*(l1j-l2j)+(l2blockSizeEnd-l2k) < l2BlockSizeAligned*l2BlockSizeAligned);
+ memcpy(rhsCopy+l2BlockSizeAligned*(l1j-l2j),&(rhs[l1j*rhsStride+l2k]),(l2blockSizeEnd-l2k)*sizeof(Scalar));
+ }
+
+ // for each bw x 1 result's block
+ for(int l1i=l2i; l1i<l2blockRowEndBW; l1i+=MaxBlockRows)
+ {
+ int offsetblock = l2k * (l2blockRowEnd-l2i) + (l1i-l2i)*(l2blockSizeEnd-l2k) - l2k*MaxBlockRows;
+ const Scalar* EIGEN_RESTRICT localB = &block[offsetblock];
+
+ for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
+ {
+ const Scalar* EIGEN_RESTRICT rhsColumn;
+ if (needRhsCopy)
+ rhsColumn = &(rhsCopy[l2BlockSizeAligned*(l1j-l2j)-l2k]);
+ else
+ rhsColumn = &(rhs[l1j*rhsStride]);
+
+ PacketType dst[MaxBlockRows];
+ dst[3] = dst[2] = dst[1] = dst[0] = ei_pset1(Scalar(0.));
+ if (MaxBlockRows==8)
+ dst[7] = dst[6] = dst[5] = dst[4] = dst[0];
+
+ PacketType tmp;
+
+ for(int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
+ {
+ tmp = ei_ploadu(&rhsColumn[k]);
+ PacketType A0, A1, A2, A3, A4, A5;
+ A0 = ei_pload(localB + k*MaxBlockRows);
+ A1 = ei_pload(localB + k*MaxBlockRows+1*PacketSize);
+ A2 = ei_pload(localB + k*MaxBlockRows+2*PacketSize);
+ A3 = ei_pload(localB + k*MaxBlockRows+3*PacketSize);
+ if (MaxBlockRows==8) A4 = ei_pload(localB + k*MaxBlockRows+4*PacketSize);
+ if (MaxBlockRows==8) A5 = ei_pload(localB + k*MaxBlockRows+5*PacketSize);
+ dst[0] = ei_pmadd(tmp, A0, dst[0]);
+ if (MaxBlockRows==8) A0 = ei_pload(localB + k*MaxBlockRows+6*PacketSize);
+ dst[1] = ei_pmadd(tmp, A1, dst[1]);
+ if (MaxBlockRows==8) A1 = ei_pload(localB + k*MaxBlockRows+7*PacketSize);
+ dst[2] = ei_pmadd(tmp, A2, dst[2]);
+ dst[3] = ei_pmadd(tmp, A3, dst[3]);
+ if (MaxBlockRows==8)
+ {
+ dst[4] = ei_pmadd(tmp, A4, dst[4]);
+ dst[5] = ei_pmadd(tmp, A5, dst[5]);
+ dst[6] = ei_pmadd(tmp, A0, dst[6]);
+ dst[7] = ei_pmadd(tmp, A1, dst[7]);
+ }
+ }
+
+ Scalar* EIGEN_RESTRICT localRes = &(res[l1i + l1j*resStride]);
+
+ if (PacketSize>1 && resIsAligned)
+ {
+ // the result is aligned: let's do packet reduction
+ ei_pstore(&(localRes[0]), ei_padd(ei_pload(&(localRes[0])), ei_preduxp(&dst[0])));
+ if (PacketSize==2)
+ ei_pstore(&(localRes[2]), ei_padd(ei_pload(&(localRes[2])), ei_preduxp(&(dst[2]))));
+ if (MaxBlockRows==8)
+ {
+ ei_pstore(&(localRes[4]), ei_padd(ei_pload(&(localRes[4])), ei_preduxp(&(dst[4]))));
+ if (PacketSize==2)
+ ei_pstore(&(localRes[6]), ei_padd(ei_pload(&(localRes[6])), ei_preduxp(&(dst[6]))));
+ }
+ }
+ else
+ {
+ // not aligned => per coeff packet reduction
+ localRes[0] += ei_predux(dst[0]);
+ localRes[1] += ei_predux(dst[1]);
+ localRes[2] += ei_predux(dst[2]);
+ localRes[3] += ei_predux(dst[3]);
+ if (MaxBlockRows==8)
+ {
+ localRes[4] += ei_predux(dst[4]);
+ localRes[5] += ei_predux(dst[5]);
+ localRes[6] += ei_predux(dst[6]);
+ localRes[7] += ei_predux(dst[7]);
+ }
+ }
+ }
+ }
+ if (l2blockRemainingRows>0)
+ {
+ int offsetblock = l2k * (l2blockRowEnd-l2i) + (l2blockRowEndBW-l2i)*(l2blockSizeEnd-l2k) - l2k*l2blockRemainingRows;
+ const Scalar* localB = &block[offsetblock];
+
+ for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
+ {
+ const Scalar* EIGEN_RESTRICT rhsColumn;
+ if (needRhsCopy)
+ rhsColumn = &(rhsCopy[l2BlockSizeAligned*(l1j-l2j)-l2k]);
+ else
+ rhsColumn = &(rhs[l1j*rhsStride]);
+
+ PacketType dst[MaxBlockRows];
+ dst[3] = dst[2] = dst[1] = dst[0] = ei_pset1(Scalar(0.));
+ if (MaxBlockRows==8)
+ dst[7] = dst[6] = dst[5] = dst[4] = dst[0];
+
+ // let's declare a few other temporary registers
+ PacketType tmp;
+
+ for(int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
+ {
+ tmp = ei_pload(&rhsColumn[k]);
+
+ dst[0] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows ])), dst[0]);
+ if (l2blockRemainingRows>=2) dst[1] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+ PacketSize])), dst[1]);
+ if (l2blockRemainingRows>=3) dst[2] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+2*PacketSize])), dst[2]);
+ if (l2blockRemainingRows>=4) dst[3] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+3*PacketSize])), dst[3]);
+ if (MaxBlockRows==8)
+ {
+ if (l2blockRemainingRows>=5) dst[4] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+4*PacketSize])), dst[4]);
+ if (l2blockRemainingRows>=6) dst[5] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+5*PacketSize])), dst[5]);
+ if (l2blockRemainingRows>=7) dst[6] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+6*PacketSize])), dst[6]);
+ if (l2blockRemainingRows>=8) dst[7] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+7*PacketSize])), dst[7]);
+ }
+ }
+
+ Scalar* EIGEN_RESTRICT localRes = &(res[l2blockRowEndBW + l1j*resStride]);
+
+ // process the remaining rows once at a time
+ localRes[0] += ei_predux(dst[0]);
+ if (l2blockRemainingRows>=2) localRes[1] += ei_predux(dst[1]);
+ if (l2blockRemainingRows>=3) localRes[2] += ei_predux(dst[2]);
+ if (l2blockRemainingRows>=4) localRes[3] += ei_predux(dst[3]);
+ if (MaxBlockRows==8)
+ {
+ if (l2blockRemainingRows>=5) localRes[4] += ei_predux(dst[4]);
+ if (l2blockRemainingRows>=6) localRes[5] += ei_predux(dst[5]);
+ if (l2blockRemainingRows>=7) localRes[6] += ei_predux(dst[6]);
+ if (l2blockRemainingRows>=8) localRes[7] += ei_predux(dst[7]);
+ }
+
+ }
+ }
+ }
+ }
+ }
+ if (PacketSize>1 && remainingSize)
+ {
+ if (lhsRowMajor)
+ {
+ for (int j=0; j<cols; ++j)
+ for (int i=0; i<rows; ++i)
+ {
+ Scalar tmp = lhs[i*lhsStride+size] * rhs[j*rhsStride+size];
+ // FIXME this loop get vectorized by the compiler !
+ for (int k=1; k<remainingSize; ++k)
+ tmp += lhs[i*lhsStride+size+k] * rhs[j*rhsStride+size+k];
+ res[i+j*resStride] += tmp;
+ }
+ }
+ else
+ {
+ for (int j=0; j<cols; ++j)
+ for (int i=0; i<rows; ++i)
+ {
+ Scalar tmp = lhs[i+size*lhsStride] * rhs[j*rhsStride+size];
+ for (int k=1; k<remainingSize; ++k)
+ tmp += lhs[i+(size+k)*lhsStride] * rhs[j*rhsStride+size+k];
+ res[i+j*resStride] += tmp;
+ }
+ }
+ }
+
+ ei_aligned_stack_delete(Scalar, block, allocBlockSize);
+ ei_aligned_stack_delete(Scalar, rhsCopy, l2BlockSizeAligned*l2BlockSizeAligned);
+}
+
+#endif // EIGEN_EXTERN_INSTANTIATIONS
+
+/* Optimized col-major matrix * vector product:
+ * This algorithm processes 4 columns at onces that allows to both reduce
+ * the number of load/stores of the result by a factor 4 and to reduce
+ * the instruction dependency. Moreover, we know that all bands have the
+ * same alignment pattern.
+ * TODO: since rhs gets evaluated only once, no need to evaluate it
+ */
+template<typename Scalar, typename RhsType>
+static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
+ int size,
+ const Scalar* lhs, int lhsStride,
+ const RhsType& rhs,
+ Scalar* res)
+{
+ #ifdef _EIGEN_ACCUMULATE_PACKETS
+ #error _EIGEN_ACCUMULATE_PACKETS has already been defined
+ #endif
+ #define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2) \
+ ei_pstore(&res[j], \
+ ei_padd(ei_pload(&res[j]), \
+ ei_padd( \
+ ei_padd(ei_pmul(ptmp0,EIGEN_CAT(ei_ploa , A0)(&lhs0[j])), \
+ ei_pmul(ptmp1,EIGEN_CAT(ei_ploa , A13)(&lhs1[j]))), \
+ ei_padd(ei_pmul(ptmp2,EIGEN_CAT(ei_ploa , A2)(&lhs2[j])), \
+ ei_pmul(ptmp3,EIGEN_CAT(ei_ploa , A13)(&lhs3[j]))) )))
+
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+ const int PacketSize = sizeof(Packet)/sizeof(Scalar);
+
+ enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned };
+ const int columnsAtOnce = 4;
+ const int peels = 2;
+ const int PacketAlignedMask = PacketSize-1;
+ const int PeelAlignedMask = PacketSize*peels-1;
+
+ // How many coeffs of the result do we have to skip to be aligned.
+ // Here we assume data are at least aligned on the base scalar type that is mandatory anyway.
+ const int alignedStart = ei_alignmentOffset(res,size);
+ const int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
+ const int peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
+
+ const int alignmentStep = PacketSize>1 ? (PacketSize - lhsStride % PacketSize) & PacketAlignedMask : 0;
+ int alignmentPattern = alignmentStep==0 ? AllAligned
+ : alignmentStep==(PacketSize/2) ? EvenAligned
+ : FirstAligned;
+
+ // we cannot assume the first element is aligned because of sub-matrices
+ const int lhsAlignmentOffset = ei_alignmentOffset(lhs,size);
+
+ // find how many columns do we have to skip to be aligned with the result (if possible)
+ int skipColumns = 0;
+ if (PacketSize>1)
+ {
+ ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
+
+ while (skipColumns<PacketSize &&
+ alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
+ ++skipColumns;
+ if (skipColumns==PacketSize)
+ {
+ // nothing can be aligned, no need to skip any column
+ alignmentPattern = NoneAligned;
+ skipColumns = 0;
+ }
+ else
+ {
+ skipColumns = std::min(skipColumns,rhs.size());
+ // note that the skiped columns are processed later.
+ }
+
+ ei_internal_assert((alignmentPattern==NoneAligned) || (size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(Packet))==0);
+ }
+
+ int offset1 = (FirstAligned && alignmentStep==1?3:1);
+ int offset3 = (FirstAligned && alignmentStep==1?1:3);
+
+ int columnBound = ((rhs.size()-skipColumns)/columnsAtOnce)*columnsAtOnce + skipColumns;
+ for (int i=skipColumns; i<columnBound; i+=columnsAtOnce)
+ {
+ Packet ptmp0 = ei_pset1(rhs[i]), ptmp1 = ei_pset1(rhs[i+offset1]),
+ ptmp2 = ei_pset1(rhs[i+2]), ptmp3 = ei_pset1(rhs[i+offset3]);
+
+ // this helps a lot generating better binary code
+ const Scalar *lhs0 = lhs + i*lhsStride, *lhs1 = lhs + (i+offset1)*lhsStride,
+ *lhs2 = lhs + (i+2)*lhsStride, *lhs3 = lhs + (i+offset3)*lhsStride;
+
+ if (PacketSize>1)
+ {
+ /* explicit vectorization */
+ // process initial unaligned coeffs
+ for (int j=0; j<alignedStart; ++j)
+ res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
+
+ if (alignedSize>alignedStart)
+ {
+ switch(alignmentPattern)
+ {
+ case AllAligned:
+ for (int j = alignedStart; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(d,d,d);
+ break;
+ case EvenAligned:
+ for (int j = alignedStart; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(d,du,d);
+ break;
+ case FirstAligned:
+ if(peels>1)
+ {
+ Packet A00, A01, A02, A03, A10, A11, A12, A13;
+
+ A01 = ei_pload(&lhs1[alignedStart-1]);
+ A02 = ei_pload(&lhs2[alignedStart-2]);
+ A03 = ei_pload(&lhs3[alignedStart-3]);
+
+ for (int j = alignedStart; j<peeledSize; j+=peels*PacketSize)
+ {
+ A11 = ei_pload(&lhs1[j-1+PacketSize]); ei_palign<1>(A01,A11);
+ A12 = ei_pload(&lhs2[j-2+PacketSize]); ei_palign<2>(A02,A12);
+ A13 = ei_pload(&lhs3[j-3+PacketSize]); ei_palign<3>(A03,A13);
+
+ A00 = ei_pload (&lhs0[j]);
+ A10 = ei_pload (&lhs0[j+PacketSize]);
+ A00 = ei_pmadd(ptmp0, A00, ei_pload(&res[j]));
+ A10 = ei_pmadd(ptmp0, A10, ei_pload(&res[j+PacketSize]));
+
+ A00 = ei_pmadd(ptmp1, A01, A00);
+ A01 = ei_pload(&lhs1[j-1+2*PacketSize]); ei_palign<1>(A11,A01);
+ A00 = ei_pmadd(ptmp2, A02, A00);
+ A02 = ei_pload(&lhs2[j-2+2*PacketSize]); ei_palign<2>(A12,A02);
+ A00 = ei_pmadd(ptmp3, A03, A00);
+ ei_pstore(&res[j],A00);
+ A03 = ei_pload(&lhs3[j-3+2*PacketSize]); ei_palign<3>(A13,A03);
+ A10 = ei_pmadd(ptmp1, A11, A10);
+ A10 = ei_pmadd(ptmp2, A12, A10);
+ A10 = ei_pmadd(ptmp3, A13, A10);
+ ei_pstore(&res[j+PacketSize],A10);
+ }
+ }
+ for (int j = peeledSize; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(d,du,du);
+ break;
+ default:
+ for (int j = alignedStart; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(du,du,du);
+ break;
+ }
+ }
+ } // end explicit vectorization
+
+ /* process remaining coeffs (or all if there is no explicit vectorization) */
+ for (int j=alignedSize; j<size; ++j)
+ res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
+ }
+
+ // process remaining first and last columns (at most columnsAtOnce-1)
+ int end = rhs.size();
+ int start = columnBound;
+ do
+ {
+ for (int i=start; i<end; ++i)
+ {
+ Packet ptmp0 = ei_pset1(rhs[i]);
+ const Scalar* lhs0 = lhs + i*lhsStride;
+
+ if (PacketSize>1)
+ {
+ /* explicit vectorization */
+ // process first unaligned result's coeffs
+ for (int j=0; j<alignedStart; ++j)
+ res[j] += ei_pfirst(ptmp0) * lhs0[j];
+
+ // process aligned result's coeffs
+ if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
+ for (int j = alignedStart;j<alignedSize;j+=PacketSize)
+ ei_pstore(&res[j], ei_pmadd(ptmp0,ei_pload(&lhs0[j]),ei_pload(&res[j])));
+ else
+ for (int j = alignedStart;j<alignedSize;j+=PacketSize)
+ ei_pstore(&res[j], ei_pmadd(ptmp0,ei_ploadu(&lhs0[j]),ei_pload(&res[j])));
+ }
+
+ // process remaining scalars (or all if no explicit vectorization)
+ for (int j=alignedSize; j<size; ++j)
+ res[j] += ei_pfirst(ptmp0) * lhs0[j];
+ }
+ if (skipColumns)
+ {
+ start = 0;
+ end = skipColumns;
+ skipColumns = 0;
+ }
+ else
+ break;
+ } while(PacketSize>1);
+ #undef _EIGEN_ACCUMULATE_PACKETS
+}
+
+// TODO add peeling to mask unaligned load/stores
+template<typename Scalar, typename ResType>
+static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
+ const Scalar* lhs, int lhsStride,
+ const Scalar* rhs, int rhsSize,
+ ResType& res)
+{
+ #ifdef _EIGEN_ACCUMULATE_PACKETS
+ #error _EIGEN_ACCUMULATE_PACKETS has already been defined
+ #endif
+
+ #define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2) {\
+ Packet b = ei_pload(&rhs[j]); \
+ ptmp0 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A0) (&lhs0[j]), ptmp0); \
+ ptmp1 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A13)(&lhs1[j]), ptmp1); \
+ ptmp2 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A2) (&lhs2[j]), ptmp2); \
+ ptmp3 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A13)(&lhs3[j]), ptmp3); }
+
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+ const int PacketSize = sizeof(Packet)/sizeof(Scalar);
+
+ enum { AllAligned=0, EvenAligned=1, FirstAligned=2, NoneAligned=3 };
+ const int rowsAtOnce = 4;
+ const int peels = 2;
+ const int PacketAlignedMask = PacketSize-1;
+ const int PeelAlignedMask = PacketSize*peels-1;
+ const int size = rhsSize;
+
+ // How many coeffs of the result do we have to skip to be aligned.
+ // Here we assume data are at least aligned on the base scalar type that is mandatory anyway.
+ const int alignedStart = ei_alignmentOffset(rhs, size);
+ const int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
+ const int peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
+
+ const int alignmentStep = PacketSize>1 ? (PacketSize - lhsStride % PacketSize) & PacketAlignedMask : 0;
+ int alignmentPattern = alignmentStep==0 ? AllAligned
+ : alignmentStep==(PacketSize/2) ? EvenAligned
+ : FirstAligned;
+
+ // we cannot assume the first element is aligned because of sub-matrices
+ const int lhsAlignmentOffset = ei_alignmentOffset(lhs,size);
+
+ // find how many rows do we have to skip to be aligned with rhs (if possible)
+ int skipRows = 0;
+ if (PacketSize>1)
+ {
+ ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
+
+ while (skipRows<PacketSize &&
+ alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%PacketSize))
+ ++skipRows;
+ if (skipRows==PacketSize)
+ {
+ // nothing can be aligned, no need to skip any column
+ alignmentPattern = NoneAligned;
+ skipRows = 0;
+ }
+ else
+ {
+ skipRows = std::min(skipRows,res.size());
+ // note that the skiped columns are processed later.
+ }
+ ei_internal_assert((alignmentPattern==NoneAligned) || PacketSize==1
+ || (size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(Packet))==0);
+ }
+
+ int offset1 = (FirstAligned && alignmentStep==1?3:1);
+ int offset3 = (FirstAligned && alignmentStep==1?1:3);
+
+ int rowBound = ((res.size()-skipRows)/rowsAtOnce)*rowsAtOnce + skipRows;
+ for (int i=skipRows; i<rowBound; i+=rowsAtOnce)
+ {
+ Scalar tmp0 = Scalar(0), tmp1 = Scalar(0), tmp2 = Scalar(0), tmp3 = Scalar(0);
+
+ // this helps the compiler generating good binary code
+ const Scalar *lhs0 = lhs + i*lhsStride, *lhs1 = lhs + (i+offset1)*lhsStride,
+ *lhs2 = lhs + (i+2)*lhsStride, *lhs3 = lhs + (i+offset3)*lhsStride;
+
+ if (PacketSize>1)
+ {
+ /* explicit vectorization */
+ Packet ptmp0 = ei_pset1(Scalar(0)), ptmp1 = ei_pset1(Scalar(0)), ptmp2 = ei_pset1(Scalar(0)), ptmp3 = ei_pset1(Scalar(0));
+
+ // process initial unaligned coeffs
+ // FIXME this loop get vectorized by the compiler !
+ for (int j=0; j<alignedStart; ++j)
+ {
+ Scalar b = rhs[j];
+ tmp0 += b*lhs0[j]; tmp1 += b*lhs1[j]; tmp2 += b*lhs2[j]; tmp3 += b*lhs3[j];
+ }
+
+ if (alignedSize>alignedStart)
+ {
+ switch(alignmentPattern)
+ {
+ case AllAligned:
+ for (int j = alignedStart; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(d,d,d);
+ break;
+ case EvenAligned:
+ for (int j = alignedStart; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(d,du,d);
+ break;
+ case FirstAligned:
+ if (peels>1)
+ {
+ /* Here we proccess 4 rows with with two peeled iterations to hide
+ * tghe overhead of unaligned loads. Moreover unaligned loads are handled
+ * using special shift/move operations between the two aligned packets
+ * overlaping the desired unaligned packet. This is *much* more efficient
+ * than basic unaligned loads.
+ */
+ Packet A01, A02, A03, b, A11, A12, A13;
+ A01 = ei_pload(&lhs1[alignedStart-1]);
+ A02 = ei_pload(&lhs2[alignedStart-2]);
+ A03 = ei_pload(&lhs3[alignedStart-3]);
+
+ for (int j = alignedStart; j<peeledSize; j+=peels*PacketSize)
+ {
+ b = ei_pload(&rhs[j]);
+ A11 = ei_pload(&lhs1[j-1+PacketSize]); ei_palign<1>(A01,A11);
+ A12 = ei_pload(&lhs2[j-2+PacketSize]); ei_palign<2>(A02,A12);
+ A13 = ei_pload(&lhs3[j-3+PacketSize]); ei_palign<3>(A03,A13);
+
+ ptmp0 = ei_pmadd(b, ei_pload (&lhs0[j]), ptmp0);
+ ptmp1 = ei_pmadd(b, A01, ptmp1);
+ A01 = ei_pload(&lhs1[j-1+2*PacketSize]); ei_palign<1>(A11,A01);
+ ptmp2 = ei_pmadd(b, A02, ptmp2);
+ A02 = ei_pload(&lhs2[j-2+2*PacketSize]); ei_palign<2>(A12,A02);
+ ptmp3 = ei_pmadd(b, A03, ptmp3);
+ A03 = ei_pload(&lhs3[j-3+2*PacketSize]); ei_palign<3>(A13,A03);
+
+ b = ei_pload(&rhs[j+PacketSize]);
+ ptmp0 = ei_pmadd(b, ei_pload (&lhs0[j+PacketSize]), ptmp0);
+ ptmp1 = ei_pmadd(b, A11, ptmp1);
+ ptmp2 = ei_pmadd(b, A12, ptmp2);
+ ptmp3 = ei_pmadd(b, A13, ptmp3);
+ }
+ }
+ for (int j = peeledSize; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(d,du,du);
+ break;
+ default:
+ for (int j = alignedStart; j<alignedSize; j+=PacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(du,du,du);
+ break;
+ }
+ tmp0 += ei_predux(ptmp0);
+ tmp1 += ei_predux(ptmp1);
+ tmp2 += ei_predux(ptmp2);
+ tmp3 += ei_predux(ptmp3);
+ }
+ } // end explicit vectorization
+
+ // process remaining coeffs (or all if no explicit vectorization)
+ // FIXME this loop get vectorized by the compiler !
+ for (int j=alignedSize; j<size; ++j)
+ {
+ Scalar b = rhs[j];
+ tmp0 += b*lhs0[j]; tmp1 += b*lhs1[j]; tmp2 += b*lhs2[j]; tmp3 += b*lhs3[j];
+ }
+ res[i] += tmp0; res[i+offset1] += tmp1; res[i+2] += tmp2; res[i+offset3] += tmp3;
+ }
+
+ // process remaining first and last rows (at most columnsAtOnce-1)
+ int end = res.size();
+ int start = rowBound;
+ do
+ {
+ for (int i=start; i<end; ++i)
+ {
+ Scalar tmp0 = Scalar(0);
+ Packet ptmp0 = ei_pset1(tmp0);
+ const Scalar* lhs0 = lhs + i*lhsStride;
+ // process first unaligned result's coeffs
+ // FIXME this loop get vectorized by the compiler !
+ for (int j=0; j<alignedStart; ++j)
+ tmp0 += rhs[j] * lhs0[j];
+
+ if (alignedSize>alignedStart)
+ {
+ // process aligned rhs coeffs
+ if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
+ for (int j = alignedStart;j<alignedSize;j+=PacketSize)
+ ptmp0 = ei_pmadd(ei_pload(&rhs[j]), ei_pload(&lhs0[j]), ptmp0);
+ else
+ for (int j = alignedStart;j<alignedSize;j+=PacketSize)
+ ptmp0 = ei_pmadd(ei_pload(&rhs[j]), ei_ploadu(&lhs0[j]), ptmp0);
+ tmp0 += ei_predux(ptmp0);
+ }
+
+ // process remaining scalars
+ // FIXME this loop get vectorized by the compiler !
+ for (int j=alignedSize; j<size; ++j)
+ tmp0 += rhs[j] * lhs0[j];
+ res[i] += tmp0;
+ }
+ if (skipRows)
+ {
+ start = 0;
+ end = skipRows;
+ skipRows = 0;
+ }
+ else
+ break;
+ } while(PacketSize>1);
+
+ #undef _EIGEN_ACCUMULATE_PACKETS
+}
+
+#endif // EIGEN_CACHE_FRIENDLY_PRODUCT_H
diff --git a/extern/Eigen2/Eigen/src/Core/Coeffs.h b/extern/Eigen2/Eigen/src/Core/Coeffs.h
new file mode 100644
index 00000000000..23a84228b24
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Coeffs.h
@@ -0,0 +1,384 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_COEFFS_H
+#define EIGEN_COEFFS_H
+
+/** Short version: don't use this function, use
+ * \link operator()(int,int) const \endlink instead.
+ *
+ * Long version: this function is similar to
+ * \link operator()(int,int) const \endlink, but without the assertion.
+ * Use this for limiting the performance cost of debugging code when doing
+ * repeated coefficient access. Only use this when it is guaranteed that the
+ * parameters \a row and \a col are in range.
+ *
+ * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
+ * function equivalent to \link operator()(int,int) const \endlink.
+ *
+ * \sa operator()(int,int) const, coeffRef(int,int), coeff(int) const
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::coeff(int row, int col) const
+{
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ return derived().coeff(row, col);
+}
+
+/** \returns the coefficient at given the given row and column.
+ *
+ * \sa operator()(int,int), operator[](int) const
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::operator()(int row, int col) const
+{
+ ei_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ return derived().coeff(row, col);
+}
+
+/** Short version: don't use this function, use
+ * \link operator()(int,int) \endlink instead.
+ *
+ * Long version: this function is similar to
+ * \link operator()(int,int) \endlink, but without the assertion.
+ * Use this for limiting the performance cost of debugging code when doing
+ * repeated coefficient access. Only use this when it is guaranteed that the
+ * parameters \a row and \a col are in range.
+ *
+ * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
+ * function equivalent to \link operator()(int,int) \endlink.
+ *
+ * \sa operator()(int,int), coeff(int, int) const, coeffRef(int)
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::coeffRef(int row, int col)
+{
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ return derived().coeffRef(row, col);
+}
+
+/** \returns a reference to the coefficient at given the given row and column.
+ *
+ * \sa operator()(int,int) const, operator[](int)
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::operator()(int row, int col)
+{
+ ei_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ return derived().coeffRef(row, col);
+}
+
+/** Short version: don't use this function, use
+ * \link operator[](int) const \endlink instead.
+ *
+ * Long version: this function is similar to
+ * \link operator[](int) const \endlink, but without the assertion.
+ * Use this for limiting the performance cost of debugging code when doing
+ * repeated coefficient access. Only use this when it is guaranteed that the
+ * parameter \a index is in range.
+ *
+ * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
+ * function equivalent to \link operator[](int) const \endlink.
+ *
+ * \sa operator[](int) const, coeffRef(int), coeff(int,int) const
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::coeff(int index) const
+{
+ ei_internal_assert(index >= 0 && index < size());
+ return derived().coeff(index);
+}
+
+/** \returns the coefficient at given index.
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int), operator()(int,int) const, x() const, y() const,
+ * z() const, w() const
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::operator[](int index) const
+{
+ ei_assert(index >= 0 && index < size());
+ return derived().coeff(index);
+}
+
+/** \returns the coefficient at given index.
+ *
+ * This is synonymous to operator[](int) const.
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int), operator()(int,int) const, x() const, y() const,
+ * z() const, w() const
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::operator()(int index) const
+{
+ ei_assert(index >= 0 && index < size());
+ return derived().coeff(index);
+}
+
+/** Short version: don't use this function, use
+ * \link operator[](int) \endlink instead.
+ *
+ * Long version: this function is similar to
+ * \link operator[](int) \endlink, but without the assertion.
+ * Use this for limiting the performance cost of debugging code when doing
+ * repeated coefficient access. Only use this when it is guaranteed that the
+ * parameters \a row and \a col are in range.
+ *
+ * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
+ * function equivalent to \link operator[](int) \endlink.
+ *
+ * \sa operator[](int), coeff(int) const, coeffRef(int,int)
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::coeffRef(int index)
+{
+ ei_internal_assert(index >= 0 && index < size());
+ return derived().coeffRef(index);
+}
+
+/** \returns a reference to the coefficient at given index.
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::operator[](int index)
+{
+ ei_assert(index >= 0 && index < size());
+ return derived().coeffRef(index);
+}
+
+/** \returns a reference to the coefficient at given index.
+ *
+ * This is synonymous to operator[](int).
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::operator()(int index)
+{
+ ei_assert(index >= 0 && index < size());
+ return derived().coeffRef(index);
+}
+
+/** equivalent to operator[](0). */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::x() const { return (*this)[0]; }
+
+/** equivalent to operator[](1). */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::y() const { return (*this)[1]; }
+
+/** equivalent to operator[](2). */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::z() const { return (*this)[2]; }
+
+/** equivalent to operator[](3). */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
+ ::w() const { return (*this)[3]; }
+
+/** equivalent to operator[](0). */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::x() { return (*this)[0]; }
+
+/** equivalent to operator[](1). */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::y() { return (*this)[1]; }
+
+/** equivalent to operator[](2). */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::z() { return (*this)[2]; }
+
+/** equivalent to operator[](3). */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
+ ::w() { return (*this)[3]; }
+
+/** \returns the packet of coefficients starting at the given row and column. It is your responsibility
+ * to ensure that a packet really starts there. This method is only available on expressions having the
+ * PacketAccessBit.
+ *
+ * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
+ * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
+ * starting at an address which is a multiple of the packet size.
+ */
+template<typename Derived>
+template<int LoadMode>
+EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
+MatrixBase<Derived>::packet(int row, int col) const
+{
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ return derived().template packet<LoadMode>(row,col);
+}
+
+/** Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
+ * to ensure that a packet really starts there. This method is only available on expressions having the
+ * PacketAccessBit.
+ *
+ * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
+ * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
+ * starting at an address which is a multiple of the packet size.
+ */
+template<typename Derived>
+template<int StoreMode>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket
+(int row, int col, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
+{
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ derived().template writePacket<StoreMode>(row,col,x);
+}
+
+/** \returns the packet of coefficients starting at the given index. It is your responsibility
+ * to ensure that a packet really starts there. This method is only available on expressions having the
+ * PacketAccessBit and the LinearAccessBit.
+ *
+ * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
+ * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
+ * starting at an address which is a multiple of the packet size.
+ */
+template<typename Derived>
+template<int LoadMode>
+EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
+MatrixBase<Derived>::packet(int index) const
+{
+ ei_internal_assert(index >= 0 && index < size());
+ return derived().template packet<LoadMode>(index);
+}
+
+/** Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
+ * to ensure that a packet really starts there. This method is only available on expressions having the
+ * PacketAccessBit and the LinearAccessBit.
+ *
+ * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
+ * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
+ * starting at an address which is a multiple of the packet size.
+ */
+template<typename Derived>
+template<int StoreMode>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket
+(int index, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
+{
+ ei_internal_assert(index >= 0 && index < size());
+ derived().template writePacket<StoreMode>(index,x);
+}
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+
+/** \internal Copies the coefficient at position (row,col) of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
+{
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ derived().coeffRef(row, col) = other.derived().coeff(row, col);
+}
+
+/** \internal Copies the coefficient at the given index of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int index, const MatrixBase<OtherDerived>& other)
+{
+ ei_internal_assert(index >= 0 && index < size());
+ derived().coeffRef(index) = other.derived().coeff(index);
+}
+
+/** \internal Copies the packet at position (row,col) of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+template<typename Derived>
+template<typename OtherDerived, int StoreMode, int LoadMode>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
+{
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ derived().template writePacket<StoreMode>(row, col,
+ other.derived().template packet<LoadMode>(row, col));
+}
+
+/** \internal Copies the packet at the given index of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+template<typename Derived>
+template<typename OtherDerived, int StoreMode, int LoadMode>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int index, const MatrixBase<OtherDerived>& other)
+{
+ ei_internal_assert(index >= 0 && index < size());
+ derived().template writePacket<StoreMode>(index,
+ other.derived().template packet<LoadMode>(index));
+}
+
+#endif
+
+#endif // EIGEN_COEFFS_H
diff --git a/extern/Eigen2/Eigen/src/Core/CommaInitializer.h b/extern/Eigen2/Eigen/src/Core/CommaInitializer.h
new file mode 100644
index 00000000000..ed28e0ca371
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/CommaInitializer.h
@@ -0,0 +1,149 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_COMMAINITIALIZER_H
+#define EIGEN_COMMAINITIALIZER_H
+
+/** \class CommaInitializer
+ *
+ * \brief Helper class used by the comma initializer operator
+ *
+ * This class is internally used to implement the comma initializer feature. It is
+ * the return type of MatrixBase::operator<<, and most of the time this is the only
+ * way it is used.
+ *
+ * \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
+ */
+template<typename MatrixType>
+struct CommaInitializer
+{
+ typedef typename ei_traits<MatrixType>::Scalar Scalar;
+ inline CommaInitializer(MatrixType& mat, const Scalar& s)
+ : m_matrix(mat), m_row(0), m_col(1), m_currentBlockRows(1)
+ {
+ m_matrix.coeffRef(0,0) = s;
+ }
+
+ template<typename OtherDerived>
+ inline CommaInitializer(MatrixType& mat, const MatrixBase<OtherDerived>& other)
+ : m_matrix(mat), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
+ {
+ m_matrix.block(0, 0, other.rows(), other.cols()) = other;
+ }
+
+ /* inserts a scalar value in the target matrix */
+ CommaInitializer& operator,(const Scalar& s)
+ {
+ if (m_col==m_matrix.cols())
+ {
+ m_row+=m_currentBlockRows;
+ m_col = 0;
+ m_currentBlockRows = 1;
+ ei_assert(m_row<m_matrix.rows()
+ && "Too many rows passed to comma initializer (operator<<)");
+ }
+ ei_assert(m_col<m_matrix.cols()
+ && "Too many coefficients passed to comma initializer (operator<<)");
+ ei_assert(m_currentBlockRows==1);
+ m_matrix.coeffRef(m_row, m_col++) = s;
+ return *this;
+ }
+
+ /* inserts a matrix expression in the target matrix */
+ template<typename OtherDerived>
+ CommaInitializer& operator,(const MatrixBase<OtherDerived>& other)
+ {
+ if (m_col==m_matrix.cols())
+ {
+ m_row+=m_currentBlockRows;
+ m_col = 0;
+ m_currentBlockRows = other.rows();
+ ei_assert(m_row+m_currentBlockRows<=m_matrix.rows()
+ && "Too many rows passed to comma initializer (operator<<)");
+ }
+ ei_assert(m_col<m_matrix.cols()
+ && "Too many coefficients passed to comma initializer (operator<<)");
+ ei_assert(m_currentBlockRows==other.rows());
+ if (OtherDerived::SizeAtCompileTime != Dynamic)
+ m_matrix.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1,
+ OtherDerived::ColsAtCompileTime != Dynamic ? OtherDerived::ColsAtCompileTime : 1>
+ (m_row, m_col) = other;
+ else
+ m_matrix.block(m_row, m_col, other.rows(), other.cols()) = other;
+ m_col += other.cols();
+ return *this;
+ }
+
+ inline ~CommaInitializer()
+ {
+ ei_assert((m_row+m_currentBlockRows) == m_matrix.rows()
+ && m_col == m_matrix.cols()
+ && "Too few coefficients passed to comma initializer (operator<<)");
+ }
+
+ /** \returns the built matrix once all its coefficients have been set.
+ * Calling finished is 100% optional. Its purpose is to write expressions
+ * like this:
+ * \code
+ * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
+ * \endcode
+ */
+ inline MatrixType& finished() { return m_matrix; }
+
+ MatrixType& m_matrix; // target matrix
+ int m_row; // current row id
+ int m_col; // current col id
+ int m_currentBlockRows; // current block height
+};
+
+/** \anchor MatrixBaseCommaInitRef
+ * Convenient operator to set the coefficients of a matrix.
+ *
+ * The coefficients must be provided in a row major order and exactly match
+ * the size of the matrix. Otherwise an assertion is raised.
+ *
+ * \addexample CommaInit \label How to easily set all the coefficients of a matrix
+ *
+ * Example: \include MatrixBase_set.cpp
+ * Output: \verbinclude MatrixBase_set.out
+ *
+ * \sa CommaInitializer::finished(), class CommaInitializer
+ */
+template<typename Derived>
+inline CommaInitializer<Derived> MatrixBase<Derived>::operator<< (const Scalar& s)
+{
+ return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
+}
+
+/** \sa operator<<(const Scalar&) */
+template<typename Derived>
+template<typename OtherDerived>
+inline CommaInitializer<Derived>
+MatrixBase<Derived>::operator<<(const MatrixBase<OtherDerived>& other)
+{
+ return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
+}
+
+#endif // EIGEN_COMMAINITIALIZER_H
diff --git a/extern/Eigen2/Eigen/src/Core/CoreInstantiations.cpp b/extern/Eigen2/Eigen/src/Core/CoreInstantiations.cpp
new file mode 100644
index 00000000000..56a9448917a
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/CoreInstantiations.cpp
@@ -0,0 +1,47 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifdef EIGEN_EXTERN_INSTANTIATIONS
+#undef EIGEN_EXTERN_INSTANTIATIONS
+#endif
+
+#include "../../Core"
+
+namespace Eigen
+{
+
+#define EIGEN_INSTANTIATE_PRODUCT(TYPE) \
+template static void ei_cache_friendly_product<TYPE>( \
+ int _rows, int _cols, int depth, \
+ bool _lhsRowMajor, const TYPE* _lhs, int _lhsStride, \
+ bool _rhsRowMajor, const TYPE* _rhs, int _rhsStride, \
+ bool resRowMajor, TYPE* res, int resStride)
+
+EIGEN_INSTANTIATE_PRODUCT(float);
+EIGEN_INSTANTIATE_PRODUCT(double);
+EIGEN_INSTANTIATE_PRODUCT(int);
+EIGEN_INSTANTIATE_PRODUCT(std::complex<float>);
+EIGEN_INSTANTIATE_PRODUCT(std::complex<double>);
+
+}
diff --git a/extern/Eigen2/Eigen/src/Core/Cwise.h b/extern/Eigen2/Eigen/src/Core/Cwise.h
new file mode 100644
index 00000000000..0e92dce4e12
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Cwise.h
@@ -0,0 +1,211 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CWISE_H
+#define EIGEN_CWISE_H
+
+/** \internal
+ * convenient macro to defined the return type of a cwise binary operation */
+#define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \
+ CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived>
+
+#define EIGEN_CWISE_PRODUCT_RETURN_TYPE \
+ CwiseBinaryOp< \
+ ei_scalar_product_op< \
+ typename ei_scalar_product_traits< \
+ typename ei_traits<ExpressionType>::Scalar, \
+ typename ei_traits<OtherDerived>::Scalar \
+ >::ReturnType \
+ >, \
+ ExpressionType, \
+ OtherDerived \
+ >
+
+/** \internal
+ * convenient macro to defined the return type of a cwise unary operation */
+#define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \
+ CwiseUnaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType>
+
+/** \internal
+ * convenient macro to defined the return type of a cwise comparison to a scalar */
+#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
+ CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \
+ NestByValue<typename ExpressionType::ConstantReturnType> >
+
+/** \class Cwise
+ *
+ * \brief Pseudo expression providing additional coefficient-wise operations
+ *
+ * \param ExpressionType the type of the object on which to do coefficient-wise operations
+ *
+ * This class represents an expression with additional coefficient-wise features.
+ * It is the return type of MatrixBase::cwise()
+ * and most of the time this is the only way it is used.
+ *
+ * Note that some methods are defined in the \ref Array module.
+ *
+ * Example: \include MatrixBase_cwise_const.cpp
+ * Output: \verbinclude MatrixBase_cwise_const.out
+ *
+ * \sa MatrixBase::cwise() const, MatrixBase::cwise()
+ */
+template<typename ExpressionType> class Cwise
+{
+ public:
+
+ typedef typename ei_traits<ExpressionType>::Scalar Scalar;
+ typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
+ ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
+ typedef CwiseUnaryOp<ei_scalar_add_op<Scalar>, ExpressionType> ScalarAddReturnType;
+
+ inline Cwise(const ExpressionType& matrix) : m_matrix(matrix) {}
+
+ /** \internal */
+ inline const ExpressionType& _expression() const { return m_matrix; }
+
+ template<typename OtherDerived>
+ const EIGEN_CWISE_PRODUCT_RETURN_TYPE
+ operator*(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
+ operator/(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
+ min(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
+ max(const MatrixBase<OtherDerived> &other) const;
+
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op) abs() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op) abs2() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_square_op) square() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cube_op) cube() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_inverse_op) inverse() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sqrt_op) sqrt() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op) exp() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op) log() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op) cos() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op) sin() const;
+ const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op) pow(const Scalar& exponent) const;
+
+ const ScalarAddReturnType
+ operator+(const Scalar& scalar) const;
+
+ /** \relates Cwise */
+ friend const ScalarAddReturnType
+ operator+(const Scalar& scalar, const Cwise& mat)
+ { return mat + scalar; }
+
+ ExpressionType& operator+=(const Scalar& scalar);
+
+ const ScalarAddReturnType
+ operator-(const Scalar& scalar) const;
+
+ ExpressionType& operator-=(const Scalar& scalar);
+
+ template<typename OtherDerived>
+ inline ExpressionType& operator*=(const MatrixBase<OtherDerived> &other);
+
+ template<typename OtherDerived>
+ inline ExpressionType& operator/=(const MatrixBase<OtherDerived> &other);
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)
+ operator<(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)
+ operator<=(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)
+ operator>(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)
+ operator>=(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)
+ operator==(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)
+ operator!=(const MatrixBase<OtherDerived>& other) const;
+
+ // comparisons to a scalar value
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
+ operator<(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
+ operator<=(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
+ operator>(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
+ operator>=(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
+ operator==(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
+ operator!=(Scalar s) const;
+
+ // allow to extend Cwise outside Eigen
+ #ifdef EIGEN_CWISE_PLUGIN
+ #include EIGEN_CWISE_PLUGIN
+ #endif
+
+ protected:
+ ExpressionTypeNested m_matrix;
+};
+
+/** \returns a Cwise wrapper of *this providing additional coefficient-wise operations
+ *
+ * Example: \include MatrixBase_cwise_const.cpp
+ * Output: \verbinclude MatrixBase_cwise_const.out
+ *
+ * \sa class Cwise, cwise()
+ */
+template<typename Derived>
+inline const Cwise<Derived>
+MatrixBase<Derived>::cwise() const
+{
+ return derived();
+}
+
+/** \returns a Cwise wrapper of *this providing additional coefficient-wise operations
+ *
+ * Example: \include MatrixBase_cwise.cpp
+ * Output: \verbinclude MatrixBase_cwise.out
+ *
+ * \sa class Cwise, cwise() const
+ */
+template<typename Derived>
+inline Cwise<Derived>
+MatrixBase<Derived>::cwise()
+{
+ return derived();
+}
+
+#endif // EIGEN_CWISE_H
diff --git a/extern/Eigen2/Eigen/src/Core/CwiseBinaryOp.h b/extern/Eigen2/Eigen/src/Core/CwiseBinaryOp.h
new file mode 100644
index 00000000000..c4223e2204e
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/CwiseBinaryOp.h
@@ -0,0 +1,304 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CWISE_BINARY_OP_H
+#define EIGEN_CWISE_BINARY_OP_H
+
+/** \class CwiseBinaryOp
+ *
+ * \brief Generic expression of a coefficient-wise operator between two matrices or vectors
+ *
+ * \param BinaryOp template functor implementing the operator
+ * \param Lhs the type of the left-hand side
+ * \param Rhs the type of the right-hand side
+ *
+ * This class represents an expression of a generic binary operator of two matrices or vectors.
+ * It is the return type of the operator+, operator-, and the Cwise methods, and most
+ * of the time this is the only way it is used.
+ *
+ * However, if you want to write a function returning such an expression, you
+ * will need to use this class.
+ *
+ * \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp
+ */
+template<typename BinaryOp, typename Lhs, typename Rhs>
+struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
+{
+ // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor),
+ // we still want to handle the case when the result type is different.
+ typedef typename ei_result_of<
+ BinaryOp(
+ typename Lhs::Scalar,
+ typename Rhs::Scalar
+ )
+ >::type Scalar;
+ typedef typename Lhs::Nested LhsNested;
+ typedef typename Rhs::Nested RhsNested;
+ typedef typename ei_unref<LhsNested>::type _LhsNested;
+ typedef typename ei_unref<RhsNested>::type _RhsNested;
+ enum {
+ LhsCoeffReadCost = _LhsNested::CoeffReadCost,
+ RhsCoeffReadCost = _RhsNested::CoeffReadCost,
+ LhsFlags = _LhsNested::Flags,
+ RhsFlags = _RhsNested::Flags,
+ RowsAtCompileTime = Lhs::RowsAtCompileTime,
+ ColsAtCompileTime = Lhs::ColsAtCompileTime,
+ MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime,
+ Flags = (int(LhsFlags) | int(RhsFlags)) & (
+ HereditaryBits
+ | (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit))
+ | (ei_functor_traits<BinaryOp>::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit))
+ ? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)),
+ CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
+ };
+};
+
+template<typename BinaryOp, typename Lhs, typename Rhs>
+class CwiseBinaryOp : ei_no_assignment_operator,
+ public MatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
+ typedef typename ei_traits<CwiseBinaryOp>::LhsNested LhsNested;
+ typedef typename ei_traits<CwiseBinaryOp>::RhsNested RhsNested;
+
+ EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
+ : m_lhs(lhs), m_rhs(rhs), m_functor(func)
+ {
+ // we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
+ // that would take two operands of different types. If there were such an example, then this check should be
+ // moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as
+ // currently they take only one typename Scalar template parameter.
+ // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
+ // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
+ // add together a float matrix and a double matrix.
+ EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret
+ ? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret)
+ : int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+ // require the sizes to match
+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
+ ei_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
+ }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
+ {
+ return m_functor(m_lhs.coeff(row, col), m_rhs.coeff(row, col));
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
+ {
+ return m_functor.packetOp(m_lhs.template packet<LoadMode>(row, col), m_rhs.template packet<LoadMode>(row, col));
+ }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int index) const
+ {
+ return m_functor(m_lhs.coeff(index), m_rhs.coeff(index));
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int index) const
+ {
+ return m_functor.packetOp(m_lhs.template packet<LoadMode>(index), m_rhs.template packet<LoadMode>(index));
+ }
+
+ protected:
+ const LhsNested m_lhs;
+ const RhsNested m_rhs;
+ const BinaryOp m_functor;
+};
+
+/**\returns an expression of the difference of \c *this and \a other
+ *
+ * \note If you want to substract a given scalar from all coefficients, see Cwise::operator-().
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator-=(), Cwise::operator-()
+ */
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>,
+ Derived, OtherDerived>
+MatrixBase<Derived>::operator-(const MatrixBase<OtherDerived> &other) const
+{
+ return CwiseBinaryOp<ei_scalar_difference_op<Scalar>,
+ Derived, OtherDerived>(derived(), other.derived());
+}
+
+/** replaces \c *this by \c *this - \a other.
+ *
+ * \returns a reference to \c *this
+ */
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
+{
+ return *this = *this - other;
+}
+
+/** \relates MatrixBase
+ *
+ * \returns an expression of the sum of \c *this and \a other
+ *
+ * \note If you want to add a given scalar to all coefficients, see Cwise::operator+().
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+=(), Cwise::operator+()
+ */
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
+MatrixBase<Derived>::operator+(const MatrixBase<OtherDerived> &other) const
+{
+ return CwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived());
+}
+
+/** replaces \c *this by \c *this + \a other.
+ *
+ * \returns a reference to \c *this
+ */
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
+{
+ return *this = *this + other;
+}
+
+/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other
+ *
+ * Example: \include Cwise_product.cpp
+ * Output: \verbinclude Cwise_product.out
+ *
+ * \sa class CwiseBinaryOp, operator/(), square()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE
+Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
+}
+
+/** \returns an expression of the coefficient-wise quotient of *this and \a other
+ *
+ * Example: \include Cwise_quotient.cpp
+ * Output: \verbinclude Cwise_quotient.out
+ *
+ * \sa class CwiseBinaryOp, operator*(), inverse()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
+Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived());
+}
+
+/** Replaces this expression by its coefficient-wise product with \a other.
+ *
+ * Example: \include Cwise_times_equal.cpp
+ * Output: \verbinclude Cwise_times_equal.out
+ *
+ * \sa operator*(), operator/=()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline ExpressionType& Cwise<ExpressionType>::operator*=(const MatrixBase<OtherDerived> &other)
+{
+ return m_matrix.const_cast_derived() = *this * other;
+}
+
+/** Replaces this expression by its coefficient-wise quotient by \a other.
+ *
+ * Example: \include Cwise_slash_equal.cpp
+ * Output: \verbinclude Cwise_slash_equal.out
+ *
+ * \sa operator/(), operator*=()
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline ExpressionType& Cwise<ExpressionType>::operator/=(const MatrixBase<OtherDerived> &other)
+{
+ return m_matrix.const_cast_derived() = *this / other;
+}
+
+/** \returns an expression of the coefficient-wise min of *this and \a other
+ *
+ * Example: \include Cwise_min.cpp
+ * Output: \verbinclude Cwise_min.out
+ *
+ * \sa class CwiseBinaryOp
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
+Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived());
+}
+
+/** \returns an expression of the coefficient-wise max of *this and \a other
+ *
+ * Example: \include Cwise_max.cpp
+ * Output: \verbinclude Cwise_max.out
+ *
+ * \sa class CwiseBinaryOp
+ */
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
+Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived());
+}
+
+/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
+ *
+ * The template parameter \a CustomBinaryOp is the type of the functor
+ * of the custom operator (see class CwiseBinaryOp for an example)
+ *
+ * \addexample CustomCwiseBinaryFunctors \label How to use custom coeff wise binary functors
+ *
+ * Here is an example illustrating the use of custom functors:
+ * \include class_CwiseBinaryOp.cpp
+ * Output: \verbinclude class_CwiseBinaryOp.out
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, Cwise::operator*, Cwise::operator/
+ */
+template<typename Derived>
+template<typename CustomBinaryOp, typename OtherDerived>
+EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
+MatrixBase<Derived>::binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const
+{
+ return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func);
+}
+
+#endif // EIGEN_CWISE_BINARY_OP_H
diff --git a/extern/Eigen2/Eigen/src/Core/CwiseNullaryOp.h b/extern/Eigen2/Eigen/src/Core/CwiseNullaryOp.h
new file mode 100644
index 00000000000..4ee5b58afec
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/CwiseNullaryOp.h
@@ -0,0 +1,763 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CWISE_NULLARY_OP_H
+#define EIGEN_CWISE_NULLARY_OP_H
+
+/** \class CwiseNullaryOp
+ *
+ * \brief Generic expression of a matrix where all coefficients are defined by a functor
+ *
+ * \param NullaryOp template functor implementing the operator
+ *
+ * This class represents an expression of a generic nullary operator.
+ * It is the return type of the Ones(), Zero(), Constant(), Identity() and Random() functions,
+ * and most of the time this is the only way it is used.
+ *
+ * However, if you want to write a function returning such an expression, you
+ * will need to use this class.
+ *
+ * \sa class CwiseUnaryOp, class CwiseBinaryOp, MatrixBase::NullaryExpr()
+ */
+template<typename NullaryOp, typename MatrixType>
+struct ei_traits<CwiseNullaryOp<NullaryOp, MatrixType> > : ei_traits<MatrixType>
+{
+ enum {
+ Flags = (ei_traits<MatrixType>::Flags
+ & ( HereditaryBits
+ | (ei_functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
+ | (ei_functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
+ | (ei_functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
+ CoeffReadCost = ei_functor_traits<NullaryOp>::Cost
+ };
+};
+
+template<typename NullaryOp, typename MatrixType>
+class CwiseNullaryOp : ei_no_assignment_operator,
+ public MatrixBase<CwiseNullaryOp<NullaryOp, MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseNullaryOp)
+
+ CwiseNullaryOp(int rows, int cols, const NullaryOp& func = NullaryOp())
+ : m_rows(rows), m_cols(cols), m_functor(func)
+ {
+ ei_assert(rows > 0
+ && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
+ && cols > 0
+ && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
+ }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_rows.value(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_cols.value(); }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int rows, int cols) const
+ {
+ return m_functor(rows, cols);
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int, int) const
+ {
+ return m_functor.packetOp();
+ }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int index) const
+ {
+ if(RowsAtCompileTime == 1)
+ return m_functor(0, index);
+ else
+ return m_functor(index, 0);
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int) const
+ {
+ return m_functor.packetOp();
+ }
+
+ protected:
+ const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
+ const ei_int_if_dynamic<ColsAtCompileTime> m_cols;
+ const NullaryOp m_functor;
+};
+
+
+/** \returns an expression of a matrix defined by a custom functor \a func
+ *
+ * The parameters \a rows and \a cols are the number of rows and of columns of
+ * the returned matrix. Must be compatible with this MatrixBase type.
+ *
+ * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
+ * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
+ * instead.
+ *
+ * The template parameter \a CustomNullaryOp is the type of the functor.
+ *
+ * \sa class CwiseNullaryOp
+ */
+template<typename Derived>
+template<typename CustomNullaryOp>
+EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
+MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func)
+{
+ return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
+}
+
+/** \returns an expression of a matrix defined by a custom functor \a func
+ *
+ * The parameter \a size is the size of the returned vector.
+ * Must be compatible with this MatrixBase type.
+ *
+ * \only_for_vectors
+ *
+ * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
+ * it is redundant to pass \a size as argument, so Zero() should be used
+ * instead.
+ *
+ * The template parameter \a CustomNullaryOp is the type of the functor.
+ *
+ * \sa class CwiseNullaryOp
+ */
+template<typename Derived>
+template<typename CustomNullaryOp>
+EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
+MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ ei_assert(IsVectorAtCompileTime);
+ if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func);
+ else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func);
+}
+
+/** \returns an expression of a matrix defined by a custom functor \a func
+ *
+ * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
+ * need to use the variants taking size arguments.
+ *
+ * The template parameter \a CustomNullaryOp is the type of the functor.
+ *
+ * \sa class CwiseNullaryOp
+ */
+template<typename Derived>
+template<typename CustomNullaryOp>
+EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
+MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
+{
+ return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
+}
+
+/** \returns an expression of a constant matrix of value \a value
+ *
+ * The parameters \a rows and \a cols are the number of rows and of columns of
+ * the returned matrix. Must be compatible with this MatrixBase type.
+ *
+ * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
+ * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
+ * instead.
+ *
+ * The template parameter \a CustomNullaryOp is the type of the functor.
+ *
+ * \sa class CwiseNullaryOp
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value)
+{
+ return NullaryExpr(rows, cols, ei_scalar_constant_op<Scalar>(value));
+}
+
+/** \returns an expression of a constant matrix of value \a value
+ *
+ * The parameter \a size is the size of the returned vector.
+ * Must be compatible with this MatrixBase type.
+ *
+ * \only_for_vectors
+ *
+ * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
+ * it is redundant to pass \a size as argument, so Zero() should be used
+ * instead.
+ *
+ * The template parameter \a CustomNullaryOp is the type of the functor.
+ *
+ * \sa class CwiseNullaryOp
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Constant(int size, const Scalar& value)
+{
+ return NullaryExpr(size, ei_scalar_constant_op<Scalar>(value));
+}
+
+/** \returns an expression of a constant matrix of value \a value
+ *
+ * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
+ * need to use the variants taking size arguments.
+ *
+ * The template parameter \a CustomNullaryOp is the type of the functor.
+ *
+ * \sa class CwiseNullaryOp
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Constant(const Scalar& value)
+{
+ EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
+ return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_constant_op<Scalar>(value));
+}
+
+/** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
+template<typename Derived>
+bool MatrixBase<Derived>::isApproxToConstant
+(const Scalar& value, RealScalar prec) const
+{
+ for(int j = 0; j < cols(); ++j)
+ for(int i = 0; i < rows(); ++i)
+ if(!ei_isApprox(coeff(i, j), value, prec))
+ return false;
+ return true;
+}
+
+/** This is just an alias for isApproxToConstant().
+ *
+ * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
+template<typename Derived>
+bool MatrixBase<Derived>::isConstant
+(const Scalar& value, RealScalar prec) const
+{
+ return isApproxToConstant(value, prec);
+}
+
+/** Alias for setConstant(): sets all coefficients in this expression to \a value.
+ *
+ * \sa setConstant(), Constant(), class CwiseNullaryOp
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::fill(const Scalar& value)
+{
+ setConstant(value);
+}
+
+/** Sets all coefficients in this expression to \a value.
+ *
+ * \sa fill(), setConstant(int,const Scalar&), setConstant(int,int,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setConstant(const Scalar& value)
+{
+ return derived() = Constant(rows(), cols(), value);
+}
+
+/** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value.
+ *
+ * \only_for_vectors
+ *
+ * Example: \include Matrix_set_int.cpp
+ * Output: \verbinclude Matrix_setConstant_int.out
+ *
+ * \sa MatrixBase::setConstant(const Scalar&), setConstant(int,int,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setConstant(int size, const Scalar& value)
+{
+ resize(size);
+ return setConstant(value);
+}
+
+/** Resizes to the given size, and sets all coefficients in this expression to the given \a value.
+ *
+ * \param rows the new number of rows
+ * \param cols the new number of columns
+ *
+ * Example: \include Matrix_setConstant_int_int.cpp
+ * Output: \verbinclude Matrix_setConstant_int_int.out
+ *
+ * \sa MatrixBase::setConstant(const Scalar&), setConstant(int,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setConstant(int rows, int cols, const Scalar& value)
+{
+ resize(rows, cols);
+ return setConstant(value);
+}
+
+
+// zero:
+
+/** \returns an expression of a zero matrix.
+ *
+ * The parameters \a rows and \a cols are the number of rows and of columns of
+ * the returned matrix. Must be compatible with this MatrixBase type.
+ *
+ * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
+ * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
+ * instead.
+ *
+ * \addexample Zero \label How to take get a zero matrix
+ *
+ * Example: \include MatrixBase_zero_int_int.cpp
+ * Output: \verbinclude MatrixBase_zero_int_int.out
+ *
+ * \sa Zero(), Zero(int)
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Zero(int rows, int cols)
+{
+ return Constant(rows, cols, Scalar(0));
+}
+
+/** \returns an expression of a zero vector.
+ *
+ * The parameter \a size is the size of the returned vector.
+ * Must be compatible with this MatrixBase type.
+ *
+ * \only_for_vectors
+ *
+ * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
+ * it is redundant to pass \a size as argument, so Zero() should be used
+ * instead.
+ *
+ * Example: \include MatrixBase_zero_int.cpp
+ * Output: \verbinclude MatrixBase_zero_int.out
+ *
+ * \sa Zero(), Zero(int,int)
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Zero(int size)
+{
+ return Constant(size, Scalar(0));
+}
+
+/** \returns an expression of a fixed-size zero matrix or vector.
+ *
+ * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
+ * need to use the variants taking size arguments.
+ *
+ * Example: \include MatrixBase_zero.cpp
+ * Output: \verbinclude MatrixBase_zero.out
+ *
+ * \sa Zero(int), Zero(int,int)
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Zero()
+{
+ return Constant(Scalar(0));
+}
+
+/** \returns true if *this is approximately equal to the zero matrix,
+ * within the precision given by \a prec.
+ *
+ * Example: \include MatrixBase_isZero.cpp
+ * Output: \verbinclude MatrixBase_isZero.out
+ *
+ * \sa class CwiseNullaryOp, Zero()
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isZero(RealScalar prec) const
+{
+ for(int j = 0; j < cols(); ++j)
+ for(int i = 0; i < rows(); ++i)
+ if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<Scalar>(1), prec))
+ return false;
+ return true;
+}
+
+/** Sets all coefficients in this expression to zero.
+ *
+ * Example: \include MatrixBase_setZero.cpp
+ * Output: \verbinclude MatrixBase_setZero.out
+ *
+ * \sa class CwiseNullaryOp, Zero()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setZero()
+{
+ return setConstant(Scalar(0));
+}
+
+/** Resizes to the given \a size, and sets all coefficients in this expression to zero.
+ *
+ * \only_for_vectors
+ *
+ * Example: \include Matrix_setZero_int.cpp
+ * Output: \verbinclude Matrix_setZero_int.out
+ *
+ * \sa MatrixBase::setZero(), setZero(int,int), class CwiseNullaryOp, MatrixBase::Zero()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int size)
+{
+ resize(size);
+ return setConstant(Scalar(0));
+}
+
+/** Resizes to the given size, and sets all coefficients in this expression to zero.
+ *
+ * \param rows the new number of rows
+ * \param cols the new number of columns
+ *
+ * Example: \include Matrix_setZero_int_int.cpp
+ * Output: \verbinclude Matrix_setZero_int_int.out
+ *
+ * \sa MatrixBase::setZero(), setZero(int), class CwiseNullaryOp, MatrixBase::Zero()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int rows, int cols)
+{
+ resize(rows, cols);
+ return setConstant(Scalar(0));
+}
+
+// ones:
+
+/** \returns an expression of a matrix where all coefficients equal one.
+ *
+ * The parameters \a rows and \a cols are the number of rows and of columns of
+ * the returned matrix. Must be compatible with this MatrixBase type.
+ *
+ * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
+ * it is redundant to pass \a rows and \a cols as arguments, so Ones() should be used
+ * instead.
+ *
+ * \addexample One \label How to get a matrix with all coefficients equal one
+ *
+ * Example: \include MatrixBase_ones_int_int.cpp
+ * Output: \verbinclude MatrixBase_ones_int_int.out
+ *
+ * \sa Ones(), Ones(int), isOnes(), class Ones
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Ones(int rows, int cols)
+{
+ return Constant(rows, cols, Scalar(1));
+}
+
+/** \returns an expression of a vector where all coefficients equal one.
+ *
+ * The parameter \a size is the size of the returned vector.
+ * Must be compatible with this MatrixBase type.
+ *
+ * \only_for_vectors
+ *
+ * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
+ * it is redundant to pass \a size as argument, so Ones() should be used
+ * instead.
+ *
+ * Example: \include MatrixBase_ones_int.cpp
+ * Output: \verbinclude MatrixBase_ones_int.out
+ *
+ * \sa Ones(), Ones(int,int), isOnes(), class Ones
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Ones(int size)
+{
+ return Constant(size, Scalar(1));
+}
+
+/** \returns an expression of a fixed-size matrix or vector where all coefficients equal one.
+ *
+ * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
+ * need to use the variants taking size arguments.
+ *
+ * Example: \include MatrixBase_ones.cpp
+ * Output: \verbinclude MatrixBase_ones.out
+ *
+ * \sa Ones(int), Ones(int,int), isOnes(), class Ones
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
+MatrixBase<Derived>::Ones()
+{
+ return Constant(Scalar(1));
+}
+
+/** \returns true if *this is approximately equal to the matrix where all coefficients
+ * are equal to 1, within the precision given by \a prec.
+ *
+ * Example: \include MatrixBase_isOnes.cpp
+ * Output: \verbinclude MatrixBase_isOnes.out
+ *
+ * \sa class CwiseNullaryOp, Ones()
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isOnes
+(RealScalar prec) const
+{
+ return isApproxToConstant(Scalar(1), prec);
+}
+
+/** Sets all coefficients in this expression to one.
+ *
+ * Example: \include MatrixBase_setOnes.cpp
+ * Output: \verbinclude MatrixBase_setOnes.out
+ *
+ * \sa class CwiseNullaryOp, Ones()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes()
+{
+ return setConstant(Scalar(1));
+}
+
+/** Resizes to the given \a size, and sets all coefficients in this expression to one.
+ *
+ * \only_for_vectors
+ *
+ * Example: \include Matrix_setOnes_int.cpp
+ * Output: \verbinclude Matrix_setOnes_int.out
+ *
+ * \sa MatrixBase::setOnes(), setOnes(int,int), class CwiseNullaryOp, MatrixBase::Ones()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setOnes(int size)
+{
+ resize(size);
+ return setConstant(Scalar(1));
+}
+
+/** Resizes to the given size, and sets all coefficients in this expression to one.
+ *
+ * \param rows the new number of rows
+ * \param cols the new number of columns
+ *
+ * Example: \include Matrix_setOnes_int_int.cpp
+ * Output: \verbinclude Matrix_setOnes_int_int.out
+ *
+ * \sa MatrixBase::setOnes(), setOnes(int), class CwiseNullaryOp, MatrixBase::Ones()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setOnes(int rows, int cols)
+{
+ resize(rows, cols);
+ return setConstant(Scalar(1));
+}
+
+// Identity:
+
+/** \returns an expression of the identity matrix (not necessarily square).
+ *
+ * The parameters \a rows and \a cols are the number of rows and of columns of
+ * the returned matrix. Must be compatible with this MatrixBase type.
+ *
+ * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
+ * it is redundant to pass \a rows and \a cols as arguments, so Identity() should be used
+ * instead.
+ *
+ * \addexample Identity \label How to get an identity matrix
+ *
+ * Example: \include MatrixBase_identity_int_int.cpp
+ * Output: \verbinclude MatrixBase_identity_int_int.out
+ *
+ * \sa Identity(), setIdentity(), isIdentity()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
+MatrixBase<Derived>::Identity(int rows, int cols)
+{
+ return NullaryExpr(rows, cols, ei_scalar_identity_op<Scalar>());
+}
+
+/** \returns an expression of the identity matrix (not necessarily square).
+ *
+ * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
+ * need to use the variant taking size arguments.
+ *
+ * Example: \include MatrixBase_identity.cpp
+ * Output: \verbinclude MatrixBase_identity.out
+ *
+ * \sa Identity(int,int), setIdentity(), isIdentity()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
+MatrixBase<Derived>::Identity()
+{
+ EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
+ return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_identity_op<Scalar>());
+}
+
+/** \returns true if *this is approximately equal to the identity matrix
+ * (not necessarily square),
+ * within the precision given by \a prec.
+ *
+ * Example: \include MatrixBase_isIdentity.cpp
+ * Output: \verbinclude MatrixBase_isIdentity.out
+ *
+ * \sa class CwiseNullaryOp, Identity(), Identity(int,int), setIdentity()
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isIdentity
+(RealScalar prec) const
+{
+ for(int j = 0; j < cols(); ++j)
+ {
+ for(int i = 0; i < rows(); ++i)
+ {
+ if(i == j)
+ {
+ if(!ei_isApprox(coeff(i, j), static_cast<Scalar>(1), prec))
+ return false;
+ }
+ else
+ {
+ if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<RealScalar>(1), prec))
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
+struct ei_setIdentity_impl
+{
+ static EIGEN_STRONG_INLINE Derived& run(Derived& m)
+ {
+ return m = Derived::Identity(m.rows(), m.cols());
+ }
+};
+
+template<typename Derived>
+struct ei_setIdentity_impl<Derived, true>
+{
+ static EIGEN_STRONG_INLINE Derived& run(Derived& m)
+ {
+ m.setZero();
+ const int size = std::min(m.rows(), m.cols());
+ for(int i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
+ return m;
+ }
+};
+
+/** Writes the identity expression (not necessarily square) into *this.
+ *
+ * Example: \include MatrixBase_setIdentity.cpp
+ * Output: \verbinclude MatrixBase_setIdentity.out
+ *
+ * \sa class CwiseNullaryOp, Identity(), Identity(int,int), isIdentity()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
+{
+ return ei_setIdentity_impl<Derived>::run(derived());
+}
+
+/** Resizes to the given size, and writes the identity expression (not necessarily square) into *this.
+ *
+ * \param rows the new number of rows
+ * \param cols the new number of columns
+ *
+ * Example: \include Matrix_setIdentity_int_int.cpp
+ * Output: \verbinclude Matrix_setIdentity_int_int.out
+ *
+ * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity()
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setIdentity(int rows, int cols)
+{
+ resize(rows, cols);
+ return setIdentity();
+}
+
+/** \returns an expression of the i-th unit (basis) vector.
+ *
+ * \only_for_vectors
+ *
+ * \sa MatrixBase::Unit(int), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(int size, int i)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return BasisReturnType(SquareMatrixType::Identity(size,size), i);
+}
+
+/** \returns an expression of the i-th unit (basis) vector.
+ *
+ * \only_for_vectors
+ *
+ * This variant is for fixed-size vector only.
+ *
+ * \sa MatrixBase::Unit(int,int), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(int i)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return BasisReturnType(SquareMatrixType::Identity(),i);
+}
+
+/** \returns an expression of the X axis unit vector (1{,0}^*)
+ *
+ * \only_for_vectors
+ *
+ * \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
+{ return Derived::Unit(0); }
+
+/** \returns an expression of the Y axis unit vector (0,1{,0}^*)
+ *
+ * \only_for_vectors
+ *
+ * \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
+{ return Derived::Unit(1); }
+
+/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*)
+ *
+ * \only_for_vectors
+ *
+ * \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
+{ return Derived::Unit(2); }
+
+/** \returns an expression of the W axis unit vector (0,0,0,1)
+ *
+ * \only_for_vectors
+ *
+ * \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
+{ return Derived::Unit(3); }
+
+#endif // EIGEN_CWISE_NULLARY_OP_H
diff --git a/extern/Eigen2/Eigen/src/Core/CwiseUnaryOp.h b/extern/Eigen2/Eigen/src/Core/CwiseUnaryOp.h
new file mode 100644
index 00000000000..076d568e023
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/CwiseUnaryOp.h
@@ -0,0 +1,229 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CWISE_UNARY_OP_H
+#define EIGEN_CWISE_UNARY_OP_H
+
+/** \class CwiseUnaryOp
+ *
+ * \brief Generic expression of a coefficient-wise unary operator of a matrix or a vector
+ *
+ * \param UnaryOp template functor implementing the operator
+ * \param MatrixType the type of the matrix we are applying the unary operator
+ *
+ * This class represents an expression of a generic unary operator of a matrix or a vector.
+ * It is the return type of the unary operator-, of a matrix or a vector, and most
+ * of the time this is the only way it is used.
+ *
+ * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp
+ */
+template<typename UnaryOp, typename MatrixType>
+struct ei_traits<CwiseUnaryOp<UnaryOp, MatrixType> >
+ : ei_traits<MatrixType>
+{
+ typedef typename ei_result_of<
+ UnaryOp(typename MatrixType::Scalar)
+ >::type Scalar;
+ typedef typename MatrixType::Nested MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ Flags = (_MatrixTypeNested::Flags & (
+ HereditaryBits | LinearAccessBit | AlignedBit
+ | (ei_functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0))),
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost
+ };
+};
+
+template<typename UnaryOp, typename MatrixType>
+class CwiseUnaryOp : ei_no_assignment_operator,
+ public MatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
+
+ inline CwiseUnaryOp(const MatrixType& mat, const UnaryOp& func = UnaryOp())
+ : m_matrix(mat), m_functor(func) {}
+
+ EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
+ {
+ return m_functor(m_matrix.coeff(row, col));
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
+ {
+ return m_functor.packetOp(m_matrix.template packet<LoadMode>(row, col));
+ }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int index) const
+ {
+ return m_functor(m_matrix.coeff(index));
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int index) const
+ {
+ return m_functor.packetOp(m_matrix.template packet<LoadMode>(index));
+ }
+
+ protected:
+ const typename MatrixType::Nested m_matrix;
+ const UnaryOp m_functor;
+};
+
+/** \returns an expression of a custom coefficient-wise unary operator \a func of *this
+ *
+ * The template parameter \a CustomUnaryOp is the type of the functor
+ * of the custom unary operator.
+ *
+ * \addexample CustomCwiseUnaryFunctors \label How to use custom coeff wise unary functors
+ *
+ * Example:
+ * \include class_CwiseUnaryOp.cpp
+ * Output: \verbinclude class_CwiseUnaryOp.out
+ *
+ * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs
+ */
+template<typename Derived>
+template<typename CustomUnaryOp>
+EIGEN_STRONG_INLINE const CwiseUnaryOp<CustomUnaryOp, Derived>
+MatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const
+{
+ return CwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func);
+}
+
+/** \returns an expression of the opposite of \c *this
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived>
+MatrixBase<Derived>::operator-() const
+{
+ return derived();
+}
+
+/** \returns an expression of the coefficient-wise absolute value of \c *this
+ *
+ * Example: \include Cwise_abs.cpp
+ * Output: \verbinclude Cwise_abs.out
+ *
+ * \sa abs2()
+ */
+template<typename ExpressionType>
+EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op)
+Cwise<ExpressionType>::abs() const
+{
+ return _expression();
+}
+
+/** \returns an expression of the coefficient-wise squared absolute value of \c *this
+ *
+ * Example: \include Cwise_abs2.cpp
+ * Output: \verbinclude Cwise_abs2.out
+ *
+ * \sa abs(), square()
+ */
+template<typename ExpressionType>
+EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op)
+Cwise<ExpressionType>::abs2() const
+{
+ return _expression();
+}
+
+/** \returns an expression of the complex conjugate of \c *this.
+ *
+ * \sa adjoint() */
+template<typename Derived>
+EIGEN_STRONG_INLINE typename MatrixBase<Derived>::ConjugateReturnType
+MatrixBase<Derived>::conjugate() const
+{
+ return ConjugateReturnType(derived());
+}
+
+/** \returns an expression of the real part of \c *this.
+ *
+ * \sa imag() */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::RealReturnType
+MatrixBase<Derived>::real() const { return derived(); }
+
+/** \returns an expression of the imaginary part of \c *this.
+ *
+ * \sa real() */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ImagReturnType
+MatrixBase<Derived>::imag() const { return derived(); }
+
+/** \returns an expression of *this with the \a Scalar type casted to
+ * \a NewScalar.
+ *
+ * The template parameter \a NewScalar is the type we are casting the scalars to.
+ *
+ * \sa class CwiseUnaryOp
+ */
+template<typename Derived>
+template<typename NewType>
+EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived>
+MatrixBase<Derived>::cast() const
+{
+ return derived();
+}
+
+/** \relates MatrixBase */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ScalarMultipleReturnType
+MatrixBase<Derived>::operator*(const Scalar& scalar) const
+{
+ return CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived>
+ (derived(), ei_scalar_multiple_op<Scalar>(scalar));
+}
+
+/** \relates MatrixBase */
+template<typename Derived>
+EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
+MatrixBase<Derived>::operator/(const Scalar& scalar) const
+{
+ return CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived>
+ (derived(), ei_scalar_quotient1_op<Scalar>(scalar));
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived&
+MatrixBase<Derived>::operator*=(const Scalar& other)
+{
+ return *this = *this * other;
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived&
+MatrixBase<Derived>::operator/=(const Scalar& other)
+{
+ return *this = *this / other;
+}
+
+#endif // EIGEN_CWISE_UNARY_OP_H
diff --git a/extern/Eigen2/Eigen/src/Core/DiagonalCoeffs.h b/extern/Eigen2/Eigen/src/Core/DiagonalCoeffs.h
new file mode 100644
index 00000000000..767fe5fb7c0
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/DiagonalCoeffs.h
@@ -0,0 +1,124 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_DIAGONALCOEFFS_H
+#define EIGEN_DIAGONALCOEFFS_H
+
+/** \class DiagonalCoeffs
+ *
+ * \brief Expression of the main diagonal of a matrix
+ *
+ * \param MatrixType the type of the object in which we are taking the main diagonal
+ *
+ * The matrix is not required to be square.
+ *
+ * This class represents an expression of the main diagonal of a square matrix.
+ * It is the return type of MatrixBase::diagonal() and most of the time this is
+ * the only way it is used.
+ *
+ * \sa MatrixBase::diagonal()
+ */
+template<typename MatrixType>
+struct ei_traits<DiagonalCoeffs<MatrixType> >
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic
+ : EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,
+ MatrixType::ColsAtCompileTime),
+ ColsAtCompileTime = 1,
+ MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
+ : EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime,
+ MatrixType::MaxColsAtCompileTime),
+ MaxColsAtCompileTime = 1,
+ Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit),
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost
+ };
+};
+
+template<typename MatrixType> class DiagonalCoeffs
+ : public MatrixBase<DiagonalCoeffs<MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalCoeffs)
+
+ inline DiagonalCoeffs(const MatrixType& matrix) : m_matrix(matrix) {}
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(DiagonalCoeffs)
+
+ inline int rows() const { return std::min(m_matrix.rows(), m_matrix.cols()); }
+ inline int cols() const { return 1; }
+
+ inline Scalar& coeffRef(int row, int)
+ {
+ return m_matrix.const_cast_derived().coeffRef(row, row);
+ }
+
+ inline const Scalar coeff(int row, int) const
+ {
+ return m_matrix.coeff(row, row);
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived().coeffRef(index, index);
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ return m_matrix.coeff(index, index);
+ }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+};
+
+/** \returns an expression of the main diagonal of the matrix \c *this
+ *
+ * \c *this is not required to be square.
+ *
+ * Example: \include MatrixBase_diagonal.cpp
+ * Output: \verbinclude MatrixBase_diagonal.out
+ *
+ * \sa class DiagonalCoeffs */
+template<typename Derived>
+inline DiagonalCoeffs<Derived>
+MatrixBase<Derived>::diagonal()
+{
+ return DiagonalCoeffs<Derived>(derived());
+}
+
+/** This is the const version of diagonal(). */
+template<typename Derived>
+inline const DiagonalCoeffs<Derived>
+MatrixBase<Derived>::diagonal() const
+{
+ return DiagonalCoeffs<Derived>(derived());
+}
+
+#endif // EIGEN_DIAGONALCOEFFS_H
diff --git a/extern/Eigen2/Eigen/src/Core/DiagonalMatrix.h b/extern/Eigen2/Eigen/src/Core/DiagonalMatrix.h
new file mode 100644
index 00000000000..01f01fdf259
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/DiagonalMatrix.h
@@ -0,0 +1,144 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_DIAGONALMATRIX_H
+#define EIGEN_DIAGONALMATRIX_H
+
+/** \class DiagonalMatrix
+ * \nonstableyet
+ *
+ * \brief Expression of a diagonal matrix
+ *
+ * \param CoeffsVectorType the type of the vector of diagonal coefficients
+ *
+ * This class is an expression of a diagonal matrix with given vector of diagonal
+ * coefficients. It is the return
+ * type of MatrixBase::diagonal(const OtherDerived&) and most of the time this is
+ * the only way it is used.
+ *
+ * \sa MatrixBase::diagonal(const OtherDerived&)
+ */
+template<typename CoeffsVectorType>
+struct ei_traits<DiagonalMatrix<CoeffsVectorType> >
+{
+ typedef typename CoeffsVectorType::Scalar Scalar;
+ typedef typename ei_nested<CoeffsVectorType>::type CoeffsVectorTypeNested;
+ typedef typename ei_unref<CoeffsVectorTypeNested>::type _CoeffsVectorTypeNested;
+ enum {
+ RowsAtCompileTime = CoeffsVectorType::SizeAtCompileTime,
+ ColsAtCompileTime = CoeffsVectorType::SizeAtCompileTime,
+ MaxRowsAtCompileTime = CoeffsVectorType::MaxSizeAtCompileTime,
+ MaxColsAtCompileTime = CoeffsVectorType::MaxSizeAtCompileTime,
+ Flags = (_CoeffsVectorTypeNested::Flags & HereditaryBits) | Diagonal,
+ CoeffReadCost = _CoeffsVectorTypeNested::CoeffReadCost
+ };
+};
+
+template<typename CoeffsVectorType>
+class DiagonalMatrix : ei_no_assignment_operator,
+ public MatrixBase<DiagonalMatrix<CoeffsVectorType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix)
+ typedef CoeffsVectorType _CoeffsVectorType;
+
+ // needed to evaluate a DiagonalMatrix<Xpr> to a DiagonalMatrix<NestByValue<Vector> >
+ template<typename OtherCoeffsVectorType>
+ inline DiagonalMatrix(const DiagonalMatrix<OtherCoeffsVectorType>& other) : m_coeffs(other.diagonal())
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherCoeffsVectorType);
+ ei_assert(m_coeffs.size() > 0);
+ }
+
+ inline DiagonalMatrix(const CoeffsVectorType& coeffs) : m_coeffs(coeffs)
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
+ ei_assert(coeffs.size() > 0);
+ }
+
+ inline int rows() const { return m_coeffs.size(); }
+ inline int cols() const { return m_coeffs.size(); }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0);
+ }
+
+ inline const CoeffsVectorType& diagonal() const { return m_coeffs; }
+
+ protected:
+ const typename CoeffsVectorType::Nested m_coeffs;
+};
+
+/** \nonstableyet
+ * \returns an expression of a diagonal matrix with *this as vector of diagonal coefficients
+ *
+ * \only_for_vectors
+ *
+ * \addexample AsDiagonalExample \label How to build a diagonal matrix from a vector
+ *
+ * Example: \include MatrixBase_asDiagonal.cpp
+ * Output: \verbinclude MatrixBase_asDiagonal.out
+ *
+ * \sa class DiagonalMatrix, isDiagonal()
+ **/
+template<typename Derived>
+inline const DiagonalMatrix<Derived>
+MatrixBase<Derived>::asDiagonal() const
+{
+ return derived();
+}
+
+/** \nonstableyet
+ * \returns true if *this is approximately equal to a diagonal matrix,
+ * within the precision given by \a prec.
+ *
+ * Example: \include MatrixBase_isDiagonal.cpp
+ * Output: \verbinclude MatrixBase_isDiagonal.out
+ *
+ * \sa asDiagonal()
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isDiagonal
+(RealScalar prec) const
+{
+ if(cols() != rows()) return false;
+ RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
+ for(int j = 0; j < cols(); ++j)
+ {
+ RealScalar absOnDiagonal = ei_abs(coeff(j,j));
+ if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
+ }
+ for(int j = 0; j < cols(); ++j)
+ for(int i = 0; i < j; ++i)
+ {
+ if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
+ if(!ei_isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
+ }
+ return true;
+}
+
+#endif // EIGEN_DIAGONALMATRIX_H
diff --git a/extern/Eigen2/Eigen/src/Core/DiagonalProduct.h b/extern/Eigen2/Eigen/src/Core/DiagonalProduct.h
new file mode 100644
index 00000000000..f33a26f98b0
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/DiagonalProduct.h
@@ -0,0 +1,130 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_DIAGONALPRODUCT_H
+#define EIGEN_DIAGONALPRODUCT_H
+
+/** \internal Specialization of ei_nested for DiagonalMatrix.
+ * Unlike ei_nested, if the argument is a DiagonalMatrix and if it must be evaluated,
+ * then it evaluated to a DiagonalMatrix having its own argument evaluated.
+ */
+template<typename T, int N> struct ei_nested_diagonal : ei_nested<T,N> {};
+template<typename T, int N> struct ei_nested_diagonal<DiagonalMatrix<T>,N >
+ : ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_plain_matrix_type<T>::type> > >
+{};
+
+// specialization of ProductReturnType
+template<typename Lhs, typename Rhs>
+struct ProductReturnType<Lhs,Rhs,DiagonalProduct>
+{
+ typedef typename ei_nested_diagonal<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
+ typedef typename ei_nested_diagonal<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
+
+ typedef Product<LhsNested, RhsNested, DiagonalProduct> Type;
+};
+
+template<typename LhsNested, typename RhsNested>
+struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> >
+{
+ // clean the nested types:
+ typedef typename ei_cleantype<LhsNested>::type _LhsNested;
+ typedef typename ei_cleantype<RhsNested>::type _RhsNested;
+ typedef typename _LhsNested::Scalar Scalar;
+
+ enum {
+ LhsFlags = _LhsNested::Flags,
+ RhsFlags = _RhsNested::Flags,
+ RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
+ ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
+ MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
+
+ LhsIsDiagonal = (_LhsNested::Flags&Diagonal)==Diagonal,
+ RhsIsDiagonal = (_RhsNested::Flags&Diagonal)==Diagonal,
+
+ CanVectorizeRhs = (!RhsIsDiagonal) && (RhsFlags & RowMajorBit) && (RhsFlags & PacketAccessBit)
+ && (ColsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
+
+ CanVectorizeLhs = (!LhsIsDiagonal) && (!(LhsFlags & RowMajorBit)) && (LhsFlags & PacketAccessBit)
+ && (RowsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
+
+ RemovedBits = ~((RhsFlags & RowMajorBit) && (!CanVectorizeLhs) ? 0 : RowMajorBit),
+
+ Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
+ | (((CanVectorizeLhs&&RhsIsDiagonal) || (CanVectorizeRhs&&LhsIsDiagonal)) ? PacketAccessBit : 0),
+
+ CoeffReadCost = NumTraits<Scalar>::MulCost + _LhsNested::CoeffReadCost + _RhsNested::CoeffReadCost
+ };
+};
+
+template<typename LhsNested, typename RhsNested> class Product<LhsNested, RhsNested, DiagonalProduct> : ei_no_assignment_operator,
+ public MatrixBase<Product<LhsNested, RhsNested, DiagonalProduct> >
+{
+ typedef typename ei_traits<Product>::_LhsNested _LhsNested;
+ typedef typename ei_traits<Product>::_RhsNested _RhsNested;
+
+ enum {
+ RhsIsDiagonal = (_RhsNested::Flags&Diagonal)==Diagonal
+ };
+
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
+
+ template<typename Lhs, typename Rhs>
+ inline Product(const Lhs& lhs, const Rhs& rhs)
+ : m_lhs(lhs), m_rhs(rhs)
+ {
+ ei_assert(lhs.cols() == rhs.rows());
+ }
+
+ inline int rows() const { return m_lhs.rows(); }
+ inline int cols() const { return m_rhs.cols(); }
+
+ const Scalar coeff(int row, int col) const
+ {
+ const int unique = RhsIsDiagonal ? col : row;
+ return m_lhs.coeff(row, unique) * m_rhs.coeff(unique, col);
+ }
+
+ template<int LoadMode>
+ const PacketScalar packet(int row, int col) const
+ {
+ if (RhsIsDiagonal)
+ {
+ return ei_pmul(m_lhs.template packet<LoadMode>(row, col), ei_pset1(m_rhs.coeff(col, col)));
+ }
+ else
+ {
+ return ei_pmul(ei_pset1(m_lhs.coeff(row, row)), m_rhs.template packet<LoadMode>(row, col));
+ }
+ }
+
+ protected:
+ const LhsNested m_lhs;
+ const RhsNested m_rhs;
+};
+
+#endif // EIGEN_DIAGONALPRODUCT_H
diff --git a/extern/Eigen2/Eigen/src/Core/Dot.h b/extern/Eigen2/Eigen/src/Core/Dot.h
new file mode 100644
index 00000000000..5838af70d4a
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Dot.h
@@ -0,0 +1,361 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_DOT_H
+#define EIGEN_DOT_H
+
+/***************************************************************************
+* Part 1 : the logic deciding a strategy for vectorization and unrolling
+***************************************************************************/
+
+template<typename Derived1, typename Derived2>
+struct ei_dot_traits
+{
+public:
+ enum {
+ Vectorization = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit)
+ && (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit)
+ ? LinearVectorization
+ : NoVectorization
+ };
+
+private:
+ typedef typename Derived1::Scalar Scalar;
+ enum {
+ PacketSize = ei_packet_traits<Scalar>::size,
+ Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits<Scalar>::MulCost)
+ + (Derived1::SizeAtCompileTime-1) * NumTraits<Scalar>::AddCost,
+ UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
+ };
+
+public:
+ enum {
+ Unrolling = Cost <= UnrollingLimit
+ ? CompleteUnrolling
+ : NoUnrolling
+ };
+};
+
+/***************************************************************************
+* Part 2 : unrollers
+***************************************************************************/
+
+/*** no vectorization ***/
+
+template<typename Derived1, typename Derived2, int Start, int Length>
+struct ei_dot_novec_unroller
+{
+ enum {
+ HalfLength = Length/2
+ };
+
+ typedef typename Derived1::Scalar Scalar;
+
+ inline static Scalar run(const Derived1& v1, const Derived2& v2)
+ {
+ return ei_dot_novec_unroller<Derived1, Derived2, Start, HalfLength>::run(v1, v2)
+ + ei_dot_novec_unroller<Derived1, Derived2, Start+HalfLength, Length-HalfLength>::run(v1, v2);
+ }
+};
+
+template<typename Derived1, typename Derived2, int Start>
+struct ei_dot_novec_unroller<Derived1, Derived2, Start, 1>
+{
+ typedef typename Derived1::Scalar Scalar;
+
+ inline static Scalar run(const Derived1& v1, const Derived2& v2)
+ {
+ return v1.coeff(Start) * ei_conj(v2.coeff(Start));
+ }
+};
+
+/*** vectorization ***/
+
+template<typename Derived1, typename Derived2, int Index, int Stop,
+ bool LastPacket = (Stop-Index == ei_packet_traits<typename Derived1::Scalar>::size)>
+struct ei_dot_vec_unroller
+{
+ typedef typename Derived1::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+
+ enum {
+ row1 = Derived1::RowsAtCompileTime == 1 ? 0 : Index,
+ col1 = Derived1::RowsAtCompileTime == 1 ? Index : 0,
+ row2 = Derived2::RowsAtCompileTime == 1 ? 0 : Index,
+ col2 = Derived2::RowsAtCompileTime == 1 ? Index : 0
+ };
+
+ inline static PacketScalar run(const Derived1& v1, const Derived2& v2)
+ {
+ return ei_pmadd(
+ v1.template packet<Aligned>(row1, col1),
+ v2.template packet<Aligned>(row2, col2),
+ ei_dot_vec_unroller<Derived1, Derived2, Index+ei_packet_traits<Scalar>::size, Stop>::run(v1, v2)
+ );
+ }
+};
+
+template<typename Derived1, typename Derived2, int Index, int Stop>
+struct ei_dot_vec_unroller<Derived1, Derived2, Index, Stop, true>
+{
+ enum {
+ row1 = Derived1::RowsAtCompileTime == 1 ? 0 : Index,
+ col1 = Derived1::RowsAtCompileTime == 1 ? Index : 0,
+ row2 = Derived2::RowsAtCompileTime == 1 ? 0 : Index,
+ col2 = Derived2::RowsAtCompileTime == 1 ? Index : 0,
+ alignment1 = (Derived1::Flags & AlignedBit) ? Aligned : Unaligned,
+ alignment2 = (Derived2::Flags & AlignedBit) ? Aligned : Unaligned
+ };
+
+ typedef typename Derived1::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+
+ inline static PacketScalar run(const Derived1& v1, const Derived2& v2)
+ {
+ return ei_pmul(v1.template packet<alignment1>(row1, col1), v2.template packet<alignment2>(row2, col2));
+ }
+};
+
+/***************************************************************************
+* Part 3 : implementation of all cases
+***************************************************************************/
+
+template<typename Derived1, typename Derived2,
+ int Vectorization = ei_dot_traits<Derived1, Derived2>::Vectorization,
+ int Unrolling = ei_dot_traits<Derived1, Derived2>::Unrolling
+>
+struct ei_dot_impl;
+
+template<typename Derived1, typename Derived2>
+struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
+{
+ typedef typename Derived1::Scalar Scalar;
+ static Scalar run(const Derived1& v1, const Derived2& v2)
+ {
+ ei_assert(v1.size()>0 && "you are using a non initialized vector");
+ Scalar res;
+ res = v1.coeff(0) * ei_conj(v2.coeff(0));
+ for(int i = 1; i < v1.size(); ++i)
+ res += v1.coeff(i) * ei_conj(v2.coeff(i));
+ return res;
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_dot_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
+ : public ei_dot_novec_unroller<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
+{};
+
+template<typename Derived1, typename Derived2>
+struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
+{
+ typedef typename Derived1::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+
+ static Scalar run(const Derived1& v1, const Derived2& v2)
+ {
+ const int size = v1.size();
+ const int packetSize = ei_packet_traits<Scalar>::size;
+ const int alignedSize = (size/packetSize)*packetSize;
+ enum {
+ alignment1 = (Derived1::Flags & AlignedBit) ? Aligned : Unaligned,
+ alignment2 = (Derived2::Flags & AlignedBit) ? Aligned : Unaligned
+ };
+ Scalar res;
+
+ // do the vectorizable part of the sum
+ if(size >= packetSize)
+ {
+ PacketScalar packet_res = ei_pmul(
+ v1.template packet<alignment1>(0),
+ v2.template packet<alignment2>(0)
+ );
+ for(int index = packetSize; index<alignedSize; index += packetSize)
+ {
+ packet_res = ei_pmadd(
+ v1.template packet<alignment1>(index),
+ v2.template packet<alignment2>(index),
+ packet_res
+ );
+ }
+ res = ei_predux(packet_res);
+
+ // now we must do the rest without vectorization.
+ if(alignedSize == size) return res;
+ }
+ else // too small to vectorize anything.
+ // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
+ {
+ res = Scalar(0);
+ }
+
+ // do the remainder of the vector
+ for(int index = alignedSize; index < size; ++index)
+ {
+ res += v1.coeff(index) * v2.coeff(index);
+ }
+
+ return res;
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_dot_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
+{
+ typedef typename Derived1::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+ enum {
+ PacketSize = ei_packet_traits<Scalar>::size,
+ Size = Derived1::SizeAtCompileTime,
+ VectorizationSize = (Size / PacketSize) * PacketSize
+ };
+ static Scalar run(const Derived1& v1, const Derived2& v2)
+ {
+ Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizationSize>::run(v1, v2));
+ if (VectorizationSize != Size)
+ res += ei_dot_novec_unroller<Derived1, Derived2, VectorizationSize, Size-VectorizationSize>::run(v1, v2);
+ return res;
+ }
+};
+
+/***************************************************************************
+* Part 4 : implementation of MatrixBase methods
+***************************************************************************/
+
+/** \returns the dot product of *this with other.
+ *
+ * \only_for_vectors
+ *
+ * \note If the scalar type is complex numbers, then this function returns the hermitian
+ * (sesquilinear) dot product, linear in the first variable and conjugate-linear in the
+ * second variable.
+ *
+ * \sa squaredNorm(), norm()
+ */
+template<typename Derived>
+template<typename OtherDerived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
+ EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+
+ ei_assert(size() == other.size());
+
+ return ei_dot_impl<Derived, OtherDerived>::run(derived(), other.derived());
+}
+
+/** \returns the squared \em l2 norm of *this, i.e., for vectors, the dot product of *this with itself.
+ *
+ * \sa dot(), norm()
+ */
+template<typename Derived>
+inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
+{
+ return ei_real((*this).cwise().abs2().sum());
+}
+
+/** \returns the \em l2 norm of *this, i.e., for vectors, the square root of the dot product of *this with itself.
+ *
+ * \sa dot(), squaredNorm()
+ */
+template<typename Derived>
+inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
+{
+ return ei_sqrt(squaredNorm());
+}
+
+/** \returns an expression of the quotient of *this by its own norm.
+ *
+ * \only_for_vectors
+ *
+ * \sa norm(), normalize()
+ */
+template<typename Derived>
+inline const typename MatrixBase<Derived>::PlainMatrixType
+MatrixBase<Derived>::normalized() const
+{
+ typedef typename ei_nested<Derived>::type Nested;
+ typedef typename ei_unref<Nested>::type _Nested;
+ _Nested n(derived());
+ return n / n.norm();
+}
+
+/** Normalizes the vector, i.e. divides it by its own norm.
+ *
+ * \only_for_vectors
+ *
+ * \sa norm(), normalized()
+ */
+template<typename Derived>
+inline void MatrixBase<Derived>::normalize()
+{
+ *this /= norm();
+}
+
+/** \returns true if *this is approximately orthogonal to \a other,
+ * within the precision given by \a prec.
+ *
+ * Example: \include MatrixBase_isOrthogonal.cpp
+ * Output: \verbinclude MatrixBase_isOrthogonal.out
+ */
+template<typename Derived>
+template<typename OtherDerived>
+bool MatrixBase<Derived>::isOrthogonal
+(const MatrixBase<OtherDerived>& other, RealScalar prec) const
+{
+ typename ei_nested<Derived,2>::type nested(derived());
+ typename ei_nested<OtherDerived,2>::type otherNested(other.derived());
+ return ei_abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
+}
+
+/** \returns true if *this is approximately an unitary matrix,
+ * within the precision given by \a prec. In the case where the \a Scalar
+ * type is real numbers, a unitary matrix is an orthogonal matrix, whence the name.
+ *
+ * \note This can be used to check whether a family of vectors forms an orthonormal basis.
+ * Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an
+ * orthonormal basis.
+ *
+ * Example: \include MatrixBase_isUnitary.cpp
+ * Output: \verbinclude MatrixBase_isUnitary.out
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isUnitary(RealScalar prec) const
+{
+ typename Derived::Nested nested(derived());
+ for(int i = 0; i < cols(); ++i)
+ {
+ if(!ei_isApprox(nested.col(i).squaredNorm(), static_cast<Scalar>(1), prec))
+ return false;
+ for(int j = 0; j < i; ++j)
+ if(!ei_isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
+ return false;
+ }
+ return true;
+}
+#endif // EIGEN_DOT_H
diff --git a/extern/Eigen2/Eigen/src/Core/Flagged.h b/extern/Eigen2/Eigen/src/Core/Flagged.h
new file mode 100644
index 00000000000..ce50246cb67
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Flagged.h
@@ -0,0 +1,146 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_FLAGGED_H
+#define EIGEN_FLAGGED_H
+
+/** \class Flagged
+ *
+ * \brief Expression with modified flags
+ *
+ * \param ExpressionType the type of the object of which we are modifying the flags
+ * \param Added the flags added to the expression
+ * \param Removed the flags removed from the expression (has priority over Added).
+ *
+ * This class represents an expression whose flags have been modified.
+ * It is the return type of MatrixBase::flagged()
+ * and most of the time this is the only way it is used.
+ *
+ * \sa MatrixBase::flagged()
+ */
+template<typename ExpressionType, unsigned int Added, unsigned int Removed>
+struct ei_traits<Flagged<ExpressionType, Added, Removed> > : ei_traits<ExpressionType>
+{
+ enum { Flags = (ExpressionType::Flags | Added) & ~Removed };
+};
+
+template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged
+ : public MatrixBase<Flagged<ExpressionType, Added, Removed> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Flagged)
+ typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
+ ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
+ typedef typename ExpressionType::InnerIterator InnerIterator;
+
+ inline Flagged(const ExpressionType& matrix) : m_matrix(matrix) {}
+
+ inline int rows() const { return m_matrix.rows(); }
+ inline int cols() const { return m_matrix.cols(); }
+ inline int stride() const { return m_matrix.stride(); }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_matrix.coeff(row, col);
+ }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived().coeffRef(row, col);
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ return m_matrix.coeff(index);
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived().coeffRef(index);
+ }
+
+ template<int LoadMode>
+ inline const PacketScalar packet(int row, int col) const
+ {
+ return m_matrix.template packet<LoadMode>(row, col);
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int row, int col, const PacketScalar& x)
+ {
+ m_matrix.const_cast_derived().template writePacket<LoadMode>(row, col, x);
+ }
+
+ template<int LoadMode>
+ inline const PacketScalar packet(int index) const
+ {
+ return m_matrix.template packet<LoadMode>(index);
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int index, const PacketScalar& x)
+ {
+ m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x);
+ }
+
+ const ExpressionType& _expression() const { return m_matrix; }
+
+ protected:
+ ExpressionTypeNested m_matrix;
+};
+
+/** \returns an expression of *this with added flags
+ *
+ * \addexample MarkExample \label How to mark a triangular matrix as triangular
+ *
+ * Example: \include MatrixBase_marked.cpp
+ * Output: \verbinclude MatrixBase_marked.out
+ *
+ * \sa class Flagged, extract(), part()
+ */
+template<typename Derived>
+template<unsigned int Added>
+inline const Flagged<Derived, Added, 0>
+MatrixBase<Derived>::marked() const
+{
+ return derived();
+}
+
+/** \returns an expression of *this with the following flags removed:
+ * EvalBeforeNestingBit and EvalBeforeAssigningBit.
+ *
+ * Example: \include MatrixBase_lazy.cpp
+ * Output: \verbinclude MatrixBase_lazy.out
+ *
+ * \sa class Flagged, marked()
+ */
+template<typename Derived>
+inline const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>
+MatrixBase<Derived>::lazy() const
+{
+ return derived();
+}
+
+#endif // EIGEN_FLAGGED_H
diff --git a/extern/Eigen2/Eigen/src/Core/Functors.h b/extern/Eigen2/Eigen/src/Core/Functors.h
new file mode 100644
index 00000000000..c8ca3dac1cf
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Functors.h
@@ -0,0 +1,368 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_FUNCTORS_H
+#define EIGEN_FUNCTORS_H
+
+// associative functors:
+
+/** \internal
+ * \brief Template functor to compute the sum of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+, class PartialRedux, MatrixBase::sum()
+ */
+template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_padd(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the product of two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator*(), class PartialRedux, MatrixBase::redux()
+ */
+template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pmul(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_product_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the min of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class PartialRedux, MatrixBase::minCoeff()
+ */
+template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pmin(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_min_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the max of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class PartialRedux, MatrixBase::maxCoeff()
+ */
+template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pmax(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_max_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+
+// other binary functors:
+
+/** \internal
+ * \brief Template functor to compute the difference of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator-
+ */
+template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_psub(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the quotient of two scalars
+ *
+ * \sa class CwiseBinaryOp, Cwise::operator/()
+ */
+template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
+ { return ei_pdiv(a,b); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_quotient_op<Scalar> > {
+ enum {
+ Cost = 2 * NumTraits<Scalar>::MulCost,
+ PacketAccess = ei_packet_traits<Scalar>::size>1
+ #if (defined EIGEN_VECTORIZE_SSE)
+ && NumTraits<Scalar>::HasFloatingPoint
+ #endif
+ };
+};
+
+// unary functors:
+
+/** \internal
+ * \brief Template functor to compute the opposite of a scalar
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::operator-
+ */
+template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false }; };
+
+/** \internal
+ * \brief Template functor to compute the absolute value of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::abs
+ */
+template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
+ typedef typename NumTraits<Scalar>::Real result_type;
+ EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
+{
+ enum {
+ Cost = NumTraits<Scalar>::AddCost,
+ PacketAccess = false // this could actually be vectorized with SSSE3.
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the squared absolute value of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::abs2
+ */
+template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
+ typedef typename NumTraits<Scalar>::Real result_type;
+ EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_pmul(a,a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
+
+/** \internal
+ * \brief Template functor to compute the conjugate of a complex value
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::conjugate()
+ */
+template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
+ template<typename PacketScalar>
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
+{
+ enum {
+ Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
+ PacketAccess = int(ei_packet_traits<Scalar>::size)>1
+ };
+};
+
+/** \internal
+ * \brief Template functor to cast a scalar to another type
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::cast()
+ */
+template<typename Scalar, typename NewType>
+struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
+ typedef NewType result_type;
+ EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
+};
+template<typename Scalar, typename NewType>
+struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
+{ enum { Cost = ei_is_same_type<Scalar, NewType>::ret ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
+
+/** \internal
+ * \brief Template functor to extract the real part of a complex
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::real()
+ */
+template<typename Scalar>
+struct ei_scalar_real_op EIGEN_EMPTY_STRUCT {
+ typedef typename NumTraits<Scalar>::Real result_type;
+ EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_real_op<Scalar> >
+{ enum { Cost = 0, PacketAccess = false }; };
+
+/** \internal
+ * \brief Template functor to extract the imaginary part of a complex
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::imag()
+ */
+template<typename Scalar>
+struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT {
+ typedef typename NumTraits<Scalar>::Real result_type;
+ EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_imag_op<Scalar> >
+{ enum { Cost = 0, PacketAccess = false }; };
+
+/** \internal
+ * \brief Template functor to multiply a scalar by a fixed other one
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/
+ */
+/* NOTE why doing the ei_pset1() in packetOp *is* an optimization ?
+ * indeed it seems better to declare m_other as a PacketScalar and do the ei_pset1() once
+ * in the constructor. However, in practice:
+ * - GCC does not like m_other as a PacketScalar and generate a load every time it needs it
+ * - one the other hand GCC is able to moves the ei_pset1() away the loop :)
+ * - simpler code ;)
+ * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y)
+ */
+template<typename Scalar>
+struct ei_scalar_multiple_op {
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+ // FIXME default copy constructors seems bugged with std::complex<>
+ EIGEN_STRONG_INLINE ei_scalar_multiple_op(const ei_scalar_multiple_op& other) : m_other(other.m_other) { }
+ EIGEN_STRONG_INLINE ei_scalar_multiple_op(const Scalar& other) : m_other(other) { }
+ EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_pmul(a, ei_pset1(m_other)); }
+ const Scalar m_other;
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
+
+template<typename Scalar, bool HasFloatingPoint>
+struct ei_scalar_quotient1_impl {
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+ // FIXME default copy constructors seems bugged with std::complex<>
+ EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
+ EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
+ EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
+ EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
+ { return ei_pmul(a, ei_pset1(m_other)); }
+ const Scalar m_other;
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
+{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
+
+template<typename Scalar>
+struct ei_scalar_quotient1_impl<Scalar,false> {
+ // FIXME default copy constructors seems bugged with std::complex<>
+ EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
+ EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
+ EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
+ const Scalar m_other;
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,false> >
+{ enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
+
+/** \internal
+ * \brief Template functor to divide a scalar by a fixed other one
+ *
+ * This functor is used to implement the quotient of a matrix by
+ * a scalar where the scalar type is not necessarily a floating point type.
+ *
+ * \sa class CwiseUnaryOp, MatrixBase::operator/
+ */
+template<typename Scalar>
+struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > {
+ EIGEN_STRONG_INLINE ei_scalar_quotient1_op(const Scalar& other)
+ : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {}
+};
+
+// nullary functors
+
+template<typename Scalar>
+struct ei_scalar_constant_op {
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+ EIGEN_STRONG_INLINE ei_scalar_constant_op(const ei_scalar_constant_op& other) : m_other(other.m_other) { }
+ EIGEN_STRONG_INLINE ei_scalar_constant_op(const Scalar& other) : m_other(other) { }
+ EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
+ EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
+ const Scalar m_other;
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_constant_op<Scalar> >
+{ enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
+
+template<typename Scalar> struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT {
+ EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {}
+ EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
+};
+template<typename Scalar>
+struct ei_functor_traits<ei_scalar_identity_op<Scalar> >
+{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
+
+// allow to add new functors and specializations of ei_functor_traits from outside Eigen.
+// this macro is really needed because ei_functor_traits must be specialized after it is declared but before it is used...
+#ifdef EIGEN_FUNCTORS_PLUGIN
+#include EIGEN_FUNCTORS_PLUGIN
+#endif
+
+// all functors allow linear access, except ei_scalar_identity_op. So we fix here a quick meta
+// to indicate whether a functor allows linear access, just always answering 'yes' except for
+// ei_scalar_identity_op.
+template<typename Functor> struct ei_functor_has_linear_access { enum { ret = 1 }; };
+template<typename Scalar> struct ei_functor_has_linear_access<ei_scalar_identity_op<Scalar> > { enum { ret = 0 }; };
+
+// in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication
+// where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex<float>.
+template<typename Functor> struct ei_functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
+template<typename Scalar> struct ei_functor_allows_mixing_real_and_complex<ei_scalar_product_op<Scalar> > { enum { ret = 1 }; };
+
+#endif // EIGEN_FUNCTORS_H
diff --git a/extern/Eigen2/Eigen/src/Core/Fuzzy.h b/extern/Eigen2/Eigen/src/Core/Fuzzy.h
new file mode 100644
index 00000000000..1285542966c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Fuzzy.h
@@ -0,0 +1,234 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_FUZZY_H
+#define EIGEN_FUZZY_H
+
+#ifndef EIGEN_LEGACY_COMPARES
+
+/** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$
+ * are considered to be approximately equal within precision \f$ p \f$ if
+ * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f]
+ * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm
+ * L2 norm).
+ *
+ * \note Because of the multiplicativeness of this comparison, one can't use this function
+ * to check whether \c *this is approximately equal to the zero matrix or vector.
+ * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix
+ * or vector. If you want to test whether \c *this is zero, use ei_isMuchSmallerThan(const
+ * RealScalar&, RealScalar) instead.
+ *
+ * \sa ei_isMuchSmallerThan(const RealScalar&, RealScalar) const
+ */
+template<typename Derived>
+template<typename OtherDerived>
+bool MatrixBase<Derived>::isApprox(
+ const MatrixBase<OtherDerived>& other,
+ typename NumTraits<Scalar>::Real prec
+) const
+{
+ const typename ei_nested<Derived,2>::type nested(derived());
+ const typename ei_nested<OtherDerived,2>::type otherNested(other.derived());
+ return (nested - otherNested).cwise().abs2().sum() <= prec * prec * std::min(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum());
+}
+
+/** \returns \c true if the norm of \c *this is much smaller than \a other,
+ * within the precision determined by \a prec.
+ *
+ * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
+ * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if
+ * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f]
+ *
+ * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason,
+ * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm
+ * of a reference matrix of same dimensions.
+ *
+ * \sa isApprox(), isMuchSmallerThan(const MatrixBase<OtherDerived>&, RealScalar) const
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isMuchSmallerThan(
+ const typename NumTraits<Scalar>::Real& other,
+ typename NumTraits<Scalar>::Real prec
+) const
+{
+ return cwise().abs2().sum() <= prec * prec * other * other;
+}
+
+/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other,
+ * within the precision determined by \a prec.
+ *
+ * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
+ * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if
+ * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f]
+ * For matrices, the comparison is done using the Hilbert-Schmidt norm.
+ *
+ * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const
+ */
+template<typename Derived>
+template<typename OtherDerived>
+bool MatrixBase<Derived>::isMuchSmallerThan(
+ const MatrixBase<OtherDerived>& other,
+ typename NumTraits<Scalar>::Real prec
+) const
+{
+ return this->cwise().abs2().sum() <= prec * prec * other.cwise().abs2().sum();
+}
+
+#else
+
+template<typename Derived, typename OtherDerived=Derived, bool IsVector=Derived::IsVectorAtCompileTime>
+struct ei_fuzzy_selector;
+
+/** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$
+ * are considered to be approximately equal within precision \f$ p \f$ if
+ * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f]
+ * For matrices, the comparison is done on all columns.
+ *
+ * \note Because of the multiplicativeness of this comparison, one can't use this function
+ * to check whether \c *this is approximately equal to the zero matrix or vector.
+ * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix
+ * or vector. If you want to test whether \c *this is zero, use ei_isMuchSmallerThan(const
+ * RealScalar&, RealScalar) instead.
+ *
+ * \sa ei_isMuchSmallerThan(const RealScalar&, RealScalar) const
+ */
+template<typename Derived>
+template<typename OtherDerived>
+bool MatrixBase<Derived>::isApprox(
+ const MatrixBase<OtherDerived>& other,
+ typename NumTraits<Scalar>::Real prec
+) const
+{
+ return ei_fuzzy_selector<Derived,OtherDerived>::isApprox(derived(), other.derived(), prec);
+}
+
+/** \returns \c true if the norm of \c *this is much smaller than \a other,
+ * within the precision determined by \a prec.
+ *
+ * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
+ * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if
+ * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f]
+ * For matrices, the comparison is done on all columns.
+ *
+ * \sa isApprox(), isMuchSmallerThan(const MatrixBase<OtherDerived>&, RealScalar) const
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isMuchSmallerThan(
+ const typename NumTraits<Scalar>::Real& other,
+ typename NumTraits<Scalar>::Real prec
+) const
+{
+ return ei_fuzzy_selector<Derived>::isMuchSmallerThan(derived(), other, prec);
+}
+
+/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other,
+ * within the precision determined by \a prec.
+ *
+ * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
+ * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if
+ * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f]
+ * For matrices, the comparison is done on all columns.
+ *
+ * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const
+ */
+template<typename Derived>
+template<typename OtherDerived>
+bool MatrixBase<Derived>::isMuchSmallerThan(
+ const MatrixBase<OtherDerived>& other,
+ typename NumTraits<Scalar>::Real prec
+) const
+{
+ return ei_fuzzy_selector<Derived,OtherDerived>::isMuchSmallerThan(derived(), other.derived(), prec);
+}
+
+
+template<typename Derived, typename OtherDerived>
+struct ei_fuzzy_selector<Derived,OtherDerived,true>
+{
+ typedef typename Derived::RealScalar RealScalar;
+ static bool isApprox(const Derived& self, const OtherDerived& other, RealScalar prec)
+ {
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
+ ei_assert(self.size() == other.size());
+ return((self - other).squaredNorm() <= std::min(self.squaredNorm(), other.squaredNorm()) * prec * prec);
+ }
+ static bool isMuchSmallerThan(const Derived& self, const RealScalar& other, RealScalar prec)
+ {
+ return(self.squaredNorm() <= ei_abs2(other * prec));
+ }
+ static bool isMuchSmallerThan(const Derived& self, const OtherDerived& other, RealScalar prec)
+ {
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
+ ei_assert(self.size() == other.size());
+ return(self.squaredNorm() <= other.squaredNorm() * prec * prec);
+ }
+};
+
+template<typename Derived, typename OtherDerived>
+struct ei_fuzzy_selector<Derived,OtherDerived,false>
+{
+ typedef typename Derived::RealScalar RealScalar;
+ static bool isApprox(const Derived& self, const OtherDerived& other, RealScalar prec)
+ {
+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
+ ei_assert(self.rows() == other.rows() && self.cols() == other.cols());
+ typename Derived::Nested nested(self);
+ typename OtherDerived::Nested otherNested(other);
+ for(int i = 0; i < self.cols(); ++i)
+ if((nested.col(i) - otherNested.col(i)).squaredNorm()
+ > std::min(nested.col(i).squaredNorm(), otherNested.col(i).squaredNorm()) * prec * prec)
+ return false;
+ return true;
+ }
+ static bool isMuchSmallerThan(const Derived& self, const RealScalar& other, RealScalar prec)
+ {
+ typename Derived::Nested nested(self);
+ for(int i = 0; i < self.cols(); ++i)
+ if(nested.col(i).squaredNorm() > ei_abs2(other * prec))
+ return false;
+ return true;
+ }
+ static bool isMuchSmallerThan(const Derived& self, const OtherDerived& other, RealScalar prec)
+ {
+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
+ ei_assert(self.rows() == other.rows() && self.cols() == other.cols());
+ typename Derived::Nested nested(self);
+ typename OtherDerived::Nested otherNested(other);
+ for(int i = 0; i < self.cols(); ++i)
+ if(nested.col(i).squaredNorm() > otherNested.col(i).squaredNorm() * prec * prec)
+ return false;
+ return true;
+ }
+};
+
+#endif
+
+#endif // EIGEN_FUZZY_H
diff --git a/extern/Eigen2/Eigen/src/Core/GenericPacketMath.h b/extern/Eigen2/Eigen/src/Core/GenericPacketMath.h
new file mode 100644
index 00000000000..b0eee29f70f
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/GenericPacketMath.h
@@ -0,0 +1,150 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_GENERIC_PACKET_MATH_H
+#define EIGEN_GENERIC_PACKET_MATH_H
+
+/** \internal
+ * \file GenericPacketMath.h
+ *
+ * Default implementation for types not supported by the vectorization.
+ * In practice these functions are provided to make easier the writing
+ * of generic vectorized code.
+ */
+
+/** \internal \returns a + b (coeff-wise) */
+template<typename Packet> inline Packet
+ei_padd(const Packet& a,
+ const Packet& b) { return a+b; }
+
+/** \internal \returns a - b (coeff-wise) */
+template<typename Packet> inline Packet
+ei_psub(const Packet& a,
+ const Packet& b) { return a-b; }
+
+/** \internal \returns a * b (coeff-wise) */
+template<typename Packet> inline Packet
+ei_pmul(const Packet& a,
+ const Packet& b) { return a*b; }
+
+/** \internal \returns a / b (coeff-wise) */
+template<typename Packet> inline Packet
+ei_pdiv(const Packet& a,
+ const Packet& b) { return a/b; }
+
+/** \internal \returns the min of \a a and \a b (coeff-wise) */
+template<typename Packet> inline Packet
+ei_pmin(const Packet& a,
+ const Packet& b) { return std::min(a, b); }
+
+/** \internal \returns the max of \a a and \a b (coeff-wise) */
+template<typename Packet> inline Packet
+ei_pmax(const Packet& a,
+ const Packet& b) { return std::max(a, b); }
+
+/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
+template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
+ei_pload(const Scalar* from) { return *from; }
+
+/** \internal \returns a packet version of \a *from, (un-aligned load) */
+template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
+ei_ploadu(const Scalar* from) { return *from; }
+
+/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
+template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
+ei_pset1(const Scalar& a) { return a; }
+
+/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
+template<typename Scalar, typename Packet> inline void ei_pstore(Scalar* to, const Packet& from)
+{ (*to) = from; }
+
+/** \internal copy the packet \a from to \a *to, (un-aligned store) */
+template<typename Scalar, typename Packet> inline void ei_pstoreu(Scalar* to, const Packet& from)
+{ (*to) = from; }
+
+/** \internal \returns the first element of a packet */
+template<typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_pfirst(const Packet& a)
+{ return a; }
+
+/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
+template<typename Packet> inline Packet
+ei_preduxp(const Packet* vecs) { return vecs[0]; }
+
+/** \internal \returns the sum of the elements of \a a*/
+template<typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_predux(const Packet& a)
+{ return a; }
+
+
+/***************************************************************************
+* The following functions might not have to be overwritten for vectorized types
+***************************************************************************/
+
+/** \internal \returns a * b + c (coeff-wise) */
+template<typename Packet> inline Packet
+ei_pmadd(const Packet& a,
+ const Packet& b,
+ const Packet& c)
+{ return ei_padd(ei_pmul(a, b),c); }
+
+/** \internal \returns a packet version of \a *from.
+ * \If LoadMode equals Aligned, \a from must be 16 bytes aligned */
+template<typename Scalar, int LoadMode>
+inline typename ei_packet_traits<Scalar>::type ei_ploadt(const Scalar* from)
+{
+ if(LoadMode == Aligned)
+ return ei_pload(from);
+ else
+ return ei_ploadu(from);
+}
+
+/** \internal copy the packet \a from to \a *to.
+ * If StoreMode equals Aligned, \a to must be 16 bytes aligned */
+template<typename Scalar, typename Packet, int LoadMode>
+inline void ei_pstoret(Scalar* to, const Packet& from)
+{
+ if(LoadMode == Aligned)
+ ei_pstore(to, from);
+ else
+ ei_pstoreu(to, from);
+}
+
+/** \internal default implementation of ei_palign() allowing partial specialization */
+template<int Offset,typename PacketType>
+struct ei_palign_impl
+{
+ // by default data are aligned, so there is nothing to be done :)
+ inline static void run(PacketType&, const PacketType&) {}
+};
+
+/** \internal update \a first using the concatenation of the \a Offset last elements
+ * of \a first and packet_size minus \a Offset first elements of \a second */
+template<int Offset,typename PacketType>
+inline void ei_palign(PacketType& first, const PacketType& second)
+{
+ ei_palign_impl<Offset,PacketType>::run(first,second);
+}
+
+#endif // EIGEN_GENERIC_PACKET_MATH_H
+
diff --git a/extern/Eigen2/Eigen/src/Core/IO.h b/extern/Eigen2/Eigen/src/Core/IO.h
new file mode 100644
index 00000000000..2b00d5bc509
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/IO.h
@@ -0,0 +1,184 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_IO_H
+#define EIGEN_IO_H
+
+enum { Raw, AlignCols };
+
+/** \class IOFormat
+ *
+ * \brief Stores a set of parameters controlling the way matrices are printed
+ *
+ * List of available parameters:
+ * - \b precision number of digits for floating point values
+ * - \b flags can be either Raw (default) or AlignCols which aligns all the columns
+ * - \b coeffSeparator string printed between two coefficients of the same row
+ * - \b rowSeparator string printed between two rows
+ * - \b rowPrefix string printed at the beginning of each row
+ * - \b rowSuffix string printed at the end of each row
+ * - \b matPrefix string printed at the beginning of the matrix
+ * - \b matSuffix string printed at the end of the matrix
+ *
+ * Example: \include IOFormat.cpp
+ * Output: \verbinclude IOFormat.out
+ *
+ * \sa MatrixBase::format(), class WithFormat
+ */
+struct IOFormat
+{
+ /** Default contructor, see class IOFormat for the meaning of the parameters */
+ IOFormat(int _precision=4, int _flags=Raw,
+ const std::string& _coeffSeparator = " ",
+ const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
+ const std::string& _matPrefix="", const std::string& _matSuffix="")
+ : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
+ coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
+ {
+ rowSpacer = "";
+ int i = int(matSuffix.length())-1;
+ while (i>=0 && matSuffix[i]!='\n')
+ {
+ rowSpacer += ' ';
+ i--;
+ }
+ }
+ std::string matPrefix, matSuffix;
+ std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
+ std::string coeffSeparator;
+ int precision;
+ int flags;
+};
+
+/** \class WithFormat
+ *
+ * \brief Pseudo expression providing matrix output with given format
+ *
+ * \param ExpressionType the type of the object on which IO stream operations are performed
+ *
+ * This class represents an expression with stream operators controlled by a given IOFormat.
+ * It is the return type of MatrixBase::format()
+ * and most of the time this is the only way it is used.
+ *
+ * See class IOFormat for some examples.
+ *
+ * \sa MatrixBase::format(), class IOFormat
+ */
+template<typename ExpressionType>
+class WithFormat
+{
+ public:
+
+ WithFormat(const ExpressionType& matrix, const IOFormat& format)
+ : m_matrix(matrix), m_format(format)
+ {}
+
+ friend std::ostream & operator << (std::ostream & s, const WithFormat& wf)
+ {
+ return ei_print_matrix(s, wf.m_matrix.eval(), wf.m_format);
+ }
+
+ protected:
+ const typename ExpressionType::Nested m_matrix;
+ IOFormat m_format;
+};
+
+/** \returns a WithFormat proxy object allowing to print a matrix the with given
+ * format \a fmt.
+ *
+ * See class IOFormat for some examples.
+ *
+ * \sa class IOFormat, class WithFormat
+ */
+template<typename Derived>
+inline const WithFormat<Derived>
+MatrixBase<Derived>::format(const IOFormat& fmt) const
+{
+ return WithFormat<Derived>(derived(), fmt);
+}
+
+/** \internal
+ * print the matrix \a _m to the output stream \a s using the output format \a fmt */
+template<typename Derived>
+std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
+{
+ const typename Derived::Nested m = _m;
+
+ int width = 0;
+ if (fmt.flags & AlignCols)
+ {
+ // compute the largest width
+ for(int j = 1; j < m.cols(); ++j)
+ for(int i = 0; i < m.rows(); ++i)
+ {
+ std::stringstream sstr;
+ sstr.precision(fmt.precision);
+ sstr << m.coeff(i,j);
+ width = std::max<int>(width, int(sstr.str().length()));
+ }
+ }
+ s.precision(fmt.precision);
+ s << fmt.matPrefix;
+ for(int i = 0; i < m.rows(); ++i)
+ {
+ if (i)
+ s << fmt.rowSpacer;
+ s << fmt.rowPrefix;
+ if(width) s.width(width);
+ s << m.coeff(i, 0);
+ for(int j = 1; j < m.cols(); ++j)
+ {
+ s << fmt.coeffSeparator;
+ if (width) s.width(width);
+ s << m.coeff(i, j);
+ }
+ s << fmt.rowSuffix;
+ if( i < m.rows() - 1)
+ s << fmt.rowSeparator;
+ }
+ s << fmt.matSuffix;
+ return s;
+}
+
+/** \relates MatrixBase
+ *
+ * Outputs the matrix, to the given stream.
+ *
+ * If you wish to print the matrix with a format different than the default, use MatrixBase::format().
+ *
+ * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers.
+ * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters.
+ *
+ * \sa MatrixBase::format()
+ */
+template<typename Derived>
+std::ostream & operator <<
+(std::ostream & s,
+ const MatrixBase<Derived> & m)
+{
+ return ei_print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT);
+}
+
+#endif // EIGEN_IO_H
diff --git a/extern/Eigen2/Eigen/src/Core/Map.h b/extern/Eigen2/Eigen/src/Core/Map.h
new file mode 100644
index 00000000000..5f44a87e685
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Map.h
@@ -0,0 +1,111 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MAP_H
+#define EIGEN_MAP_H
+
+/** \class Map
+ *
+ * \brief A matrix or vector expression mapping an existing array of data.
+ *
+ * \param MatrixType the equivalent matrix type of the mapped data
+ * \param _PacketAccess allows to enforce aligned loads and stores if set to ForceAligned.
+ * The default is AsRequested. This parameter is internaly used by Eigen
+ * in expressions such as \code Map<...>(...) += other; \endcode and most
+ * of the time this is the only way it is used.
+ *
+ * This class represents a matrix or vector expression mapping an existing array of data.
+ * It can be used to let Eigen interface without any overhead with non-Eigen data structures,
+ * such as plain C arrays or structures from other libraries.
+ *
+ * This class is the return type of Matrix::Map() but can also be used directly.
+ *
+ * \sa Matrix::Map()
+ */
+template<typename MatrixType, int _PacketAccess>
+struct ei_traits<Map<MatrixType, _PacketAccess> > : public ei_traits<MatrixType>
+{
+ enum {
+ PacketAccess = _PacketAccess,
+ Flags = ei_traits<MatrixType>::Flags & ~AlignedBit
+ };
+ typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,
+ Map<MatrixType, _PacketAccess>&,
+ Map<MatrixType, ForceAligned> >::ret AlignedDerivedType;
+};
+
+template<typename MatrixType, int PacketAccess> class Map
+ : public MapBase<Map<MatrixType, PacketAccess> >
+{
+ public:
+
+ _EIGEN_GENERIC_PUBLIC_INTERFACE(Map, MapBase<Map>)
+ typedef typename ei_traits<Map>::AlignedDerivedType AlignedDerivedType;
+
+ inline int stride() const { return this->innerSize(); }
+
+ AlignedDerivedType _convertToForceAligned()
+ {
+ return Map<MatrixType,ForceAligned>(Base::m_data, Base::m_rows.value(), Base::m_cols.value());
+ }
+
+ inline Map(const Scalar* data) : Base(data) {}
+
+ inline Map(const Scalar* data, int size) : Base(data, size) {}
+
+ inline Map(const Scalar* data, int rows, int cols) : Base(data, rows, cols) {}
+
+ inline void resize(int rows, int cols)
+ {
+ EIGEN_ONLY_USED_FOR_DEBUG(rows);
+ EIGEN_ONLY_USED_FOR_DEBUG(cols);
+ ei_assert(rows == this->rows());
+ ei_assert(cols == this->cols());
+ }
+
+ inline void resize(int size)
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(MatrixType)
+ EIGEN_ONLY_USED_FOR_DEBUG(size);
+ ei_assert(size == this->size());
+ }
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
+};
+
+/** Constructor copying an existing array of data.
+ * Only for fixed-size matrices and vectors.
+ * \param data The array of data to copy
+ *
+ * \sa Matrix::Map(const Scalar *)
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
+inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>
+ ::Matrix(const Scalar *data)
+{
+ _set_noalias(Eigen::Map<Matrix>(data));
+}
+
+#endif // EIGEN_MAP_H
diff --git a/extern/Eigen2/Eigen/src/Core/MapBase.h b/extern/Eigen2/Eigen/src/Core/MapBase.h
new file mode 100644
index 00000000000..c923bc34034
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/MapBase.h
@@ -0,0 +1,202 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MAPBASE_H
+#define EIGEN_MAPBASE_H
+
+/** \class MapBase
+ *
+ * \brief Base class for Map and Block expression with direct access
+ *
+ * Expression classes inheriting MapBase must define the constant \c PacketAccess,
+ * and type \c AlignedDerivedType in their respective ei_traits<> specialization structure.
+ * The value of \c PacketAccess can be either:
+ * - \b ForceAligned which enforces both aligned loads and stores
+ * - \b AsRequested which is the default behavior
+ * The type \c AlignedDerivedType should correspond to the equivalent expression type
+ * with \c PacketAccess being \c ForceAligned.
+ *
+ * \sa class Map, class Block
+ */
+template<typename Derived> class MapBase
+ : public MatrixBase<Derived>
+{
+ public:
+
+ typedef MatrixBase<Derived> Base;
+ enum {
+ IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0,
+ PacketAccess = ei_traits<Derived>::PacketAccess,
+ RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
+ ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
+ SizeAtCompileTime = Base::SizeAtCompileTime
+ };
+
+ typedef typename ei_traits<Derived>::AlignedDerivedType AlignedDerivedType;
+ typedef typename ei_traits<Derived>::Scalar Scalar;
+ typedef typename Base::PacketScalar PacketScalar;
+ using Base::derived;
+
+ inline int rows() const { return m_rows.value(); }
+ inline int cols() const { return m_cols.value(); }
+
+ inline int stride() const { return derived().stride(); }
+ inline const Scalar* data() const { return m_data; }
+
+ template<bool IsForceAligned,typename Dummy> struct force_aligned_impl {
+ AlignedDerivedType static run(MapBase& a) { return a.derived(); }
+ };
+
+ template<typename Dummy> struct force_aligned_impl<false,Dummy> {
+ AlignedDerivedType static run(MapBase& a) { return a.derived()._convertToForceAligned(); }
+ };
+
+ /** \returns an expression equivalent to \c *this but having the \c PacketAccess constant
+ * set to \c ForceAligned. Must be reimplemented by the derived class. */
+ AlignedDerivedType forceAligned()
+ {
+ return force_aligned_impl<int(PacketAccess)==int(ForceAligned),Derived>::run(*this);
+ }
+
+ inline const Scalar& coeff(int row, int col) const
+ {
+ if(IsRowMajor)
+ return m_data[col + row * stride()];
+ else // column-major
+ return m_data[row + col * stride()];
+ }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ if(IsRowMajor)
+ return const_cast<Scalar*>(m_data)[col + row * stride()];
+ else // column-major
+ return const_cast<Scalar*>(m_data)[row + col * stride()];
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
+ if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
+ return m_data[index];
+ else
+ return m_data[index*stride()];
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
+ if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
+ return const_cast<Scalar*>(m_data)[index];
+ else
+ return const_cast<Scalar*>(m_data)[index*stride()];
+ }
+
+ template<int LoadMode>
+ inline PacketScalar packet(int row, int col) const
+ {
+ return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>
+ (m_data + (IsRowMajor ? col + row * stride()
+ : row + col * stride()));
+ }
+
+ template<int LoadMode>
+ inline PacketScalar packet(int index) const
+ {
+ return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>(m_data + index);
+ }
+
+ template<int StoreMode>
+ inline void writePacket(int row, int col, const PacketScalar& x)
+ {
+ ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
+ (const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride()
+ : row + col * stride()), x);
+ }
+
+ template<int StoreMode>
+ inline void writePacket(int index, const PacketScalar& x)
+ {
+ ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
+ (const_cast<Scalar*>(m_data) + index, x);
+ }
+
+ inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
+ {
+ EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
+ }
+
+ inline MapBase(const Scalar* data, int size)
+ : m_data(data),
+ m_rows(RowsAtCompileTime == Dynamic ? size : RowsAtCompileTime),
+ m_cols(ColsAtCompileTime == Dynamic ? size : ColsAtCompileTime)
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ ei_assert(size > 0 || data == 0);
+ ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
+ }
+
+ inline MapBase(const Scalar* data, int rows, int cols)
+ : m_data(data), m_rows(rows), m_cols(cols)
+ {
+ ei_assert( (data == 0)
+ || ( rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
+ && cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
+ }
+
+ Derived& operator=(const MapBase& other)
+ {
+ return Base::operator=(other);
+ }
+
+ template<typename OtherDerived>
+ Derived& operator=(const MatrixBase<OtherDerived>& other)
+ {
+ return Base::operator=(other);
+ }
+
+ using Base::operator*=;
+
+ template<typename OtherDerived>
+ Derived& operator+=(const MatrixBase<OtherDerived>& other)
+ { return derived() = forceAligned() + other; }
+
+ template<typename OtherDerived>
+ Derived& operator-=(const MatrixBase<OtherDerived>& other)
+ { return derived() = forceAligned() - other; }
+
+ Derived& operator*=(const Scalar& other)
+ { return derived() = forceAligned() * other; }
+
+ Derived& operator/=(const Scalar& other)
+ { return derived() = forceAligned() / other; }
+
+ protected:
+ const Scalar* EIGEN_RESTRICT m_data;
+ const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
+ const ei_int_if_dynamic<ColsAtCompileTime> m_cols;
+};
+
+#endif // EIGEN_MAPBASE_H
diff --git a/extern/Eigen2/Eigen/src/Core/MathFunctions.h b/extern/Eigen2/Eigen/src/Core/MathFunctions.h
new file mode 100644
index 00000000000..1ee64af02c6
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/MathFunctions.h
@@ -0,0 +1,295 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MATHFUNCTIONS_H
+#define EIGEN_MATHFUNCTIONS_H
+
+template<typename T> inline typename NumTraits<T>::Real precision();
+template<typename T> inline typename NumTraits<T>::Real machine_epsilon();
+template<typename T> inline T ei_random(T a, T b);
+template<typename T> inline T ei_random();
+template<typename T> inline T ei_random_amplitude()
+{
+ if(NumTraits<T>::HasFloatingPoint) return static_cast<T>(1);
+ else return static_cast<T>(10);
+}
+
+template<typename T> inline T ei_hypot(T x, T y)
+{
+ T _x = ei_abs(x);
+ T _y = ei_abs(y);
+ T p = std::max(_x, _y);
+ T q = std::min(_x, _y);
+ T qp = q/p;
+ return p * ei_sqrt(T(1) + qp*qp);
+}
+
+/**************
+*** int ***
+**************/
+
+template<> inline int precision<int>() { return 0; }
+template<> inline int machine_epsilon<int>() { return 0; }
+inline int ei_real(int x) { return x; }
+inline int ei_imag(int) { return 0; }
+inline int ei_conj(int x) { return x; }
+inline int ei_abs(int x) { return abs(x); }
+inline int ei_abs2(int x) { return x*x; }
+inline int ei_sqrt(int) { ei_assert(false); return 0; }
+inline int ei_exp(int) { ei_assert(false); return 0; }
+inline int ei_log(int) { ei_assert(false); return 0; }
+inline int ei_sin(int) { ei_assert(false); return 0; }
+inline int ei_cos(int) { ei_assert(false); return 0; }
+inline int ei_atan2(int, int) { ei_assert(false); return 0; }
+inline int ei_pow(int x, int y) { return int(std::pow(double(x), y)); }
+
+template<> inline int ei_random(int a, int b)
+{
+ // We can't just do rand()%n as only the high-order bits are really random
+ return a + static_cast<int>((b-a+1) * (rand() / (RAND_MAX + 1.0)));
+}
+template<> inline int ei_random()
+{
+ return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>());
+}
+inline bool ei_isMuchSmallerThan(int a, int, int = precision<int>())
+{
+ return a == 0;
+}
+inline bool ei_isApprox(int a, int b, int = precision<int>())
+{
+ return a == b;
+}
+inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>())
+{
+ return a <= b;
+}
+
+/**************
+*** float ***
+**************/
+
+template<> inline float precision<float>() { return 1e-5f; }
+template<> inline float machine_epsilon<float>() { return 1.192e-07f; }
+inline float ei_real(float x) { return x; }
+inline float ei_imag(float) { return 0.f; }
+inline float ei_conj(float x) { return x; }
+inline float ei_abs(float x) { return std::abs(x); }
+inline float ei_abs2(float x) { return x*x; }
+inline float ei_sqrt(float x) { return std::sqrt(x); }
+inline float ei_exp(float x) { return std::exp(x); }
+inline float ei_log(float x) { return std::log(x); }
+inline float ei_sin(float x) { return std::sin(x); }
+inline float ei_cos(float x) { return std::cos(x); }
+inline float ei_atan2(float y, float x) { return std::atan2(y,x); }
+inline float ei_pow(float x, float y) { return std::pow(x, y); }
+
+template<> inline float ei_random(float a, float b)
+{
+#ifdef EIGEN_NICE_RANDOM
+ int i;
+ do { i = ei_random<int>(256*int(a),256*int(b));
+ } while(i==0);
+ return float(i)/256.f;
+#else
+ return a + (b-a) * float(std::rand()) / float(RAND_MAX);
+#endif
+}
+template<> inline float ei_random()
+{
+ return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>());
+}
+inline bool ei_isMuchSmallerThan(float a, float b, float prec = precision<float>())
+{
+ return ei_abs(a) <= ei_abs(b) * prec;
+}
+inline bool ei_isApprox(float a, float b, float prec = precision<float>())
+{
+ return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
+}
+inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float>())
+{
+ return a <= b || ei_isApprox(a, b, prec);
+}
+
+/**************
+*** double ***
+**************/
+
+template<> inline double precision<double>() { return 1e-11; }
+template<> inline double machine_epsilon<double>() { return 2.220e-16; }
+
+inline double ei_real(double x) { return x; }
+inline double ei_imag(double) { return 0.; }
+inline double ei_conj(double x) { return x; }
+inline double ei_abs(double x) { return std::abs(x); }
+inline double ei_abs2(double x) { return x*x; }
+inline double ei_sqrt(double x) { return std::sqrt(x); }
+inline double ei_exp(double x) { return std::exp(x); }
+inline double ei_log(double x) { return std::log(x); }
+inline double ei_sin(double x) { return std::sin(x); }
+inline double ei_cos(double x) { return std::cos(x); }
+inline double ei_atan2(double y, double x) { return std::atan2(y,x); }
+inline double ei_pow(double x, double y) { return std::pow(x, y); }
+
+template<> inline double ei_random(double a, double b)
+{
+#ifdef EIGEN_NICE_RANDOM
+ int i;
+ do { i= ei_random<int>(256*int(a),256*int(b));
+ } while(i==0);
+ return i/256.;
+#else
+ return a + (b-a) * std::rand() / RAND_MAX;
+#endif
+}
+template<> inline double ei_random()
+{
+ return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
+}
+inline bool ei_isMuchSmallerThan(double a, double b, double prec = precision<double>())
+{
+ return ei_abs(a) <= ei_abs(b) * prec;
+}
+inline bool ei_isApprox(double a, double b, double prec = precision<double>())
+{
+ return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
+}
+inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<double>())
+{
+ return a <= b || ei_isApprox(a, b, prec);
+}
+
+/*********************
+*** complex<float> ***
+*********************/
+
+template<> inline float precision<std::complex<float> >() { return precision<float>(); }
+template<> inline float machine_epsilon<std::complex<float> >() { return machine_epsilon<float>(); }
+inline float ei_real(const std::complex<float>& x) { return std::real(x); }
+inline float ei_imag(const std::complex<float>& x) { return std::imag(x); }
+inline std::complex<float> ei_conj(const std::complex<float>& x) { return std::conj(x); }
+inline float ei_abs(const std::complex<float>& x) { return std::abs(x); }
+inline float ei_abs2(const std::complex<float>& x) { return std::norm(x); }
+inline std::complex<float> ei_exp(std::complex<float> x) { return std::exp(x); }
+inline std::complex<float> ei_sin(std::complex<float> x) { return std::sin(x); }
+inline std::complex<float> ei_cos(std::complex<float> x) { return std::cos(x); }
+inline std::complex<float> ei_atan2(std::complex<float>, std::complex<float> ) { ei_assert(false); return 0; }
+
+template<> inline std::complex<float> ei_random()
+{
+ return std::complex<float>(ei_random<float>(), ei_random<float>());
+}
+inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>())
+{
+ return ei_abs2(a) <= ei_abs2(b) * prec * prec;
+}
+inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = precision<float>())
+{
+ return ei_abs2(a) <= ei_abs2(b) * prec * prec;
+}
+inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>())
+{
+ return ei_isApprox(ei_real(a), ei_real(b), prec)
+ && ei_isApprox(ei_imag(a), ei_imag(b), prec);
+}
+// ei_isApproxOrLessThan wouldn't make sense for complex numbers
+
+/**********************
+*** complex<double> ***
+**********************/
+
+template<> inline double precision<std::complex<double> >() { return precision<double>(); }
+template<> inline double machine_epsilon<std::complex<double> >() { return machine_epsilon<double>(); }
+inline double ei_real(const std::complex<double>& x) { return std::real(x); }
+inline double ei_imag(const std::complex<double>& x) { return std::imag(x); }
+inline std::complex<double> ei_conj(const std::complex<double>& x) { return std::conj(x); }
+inline double ei_abs(const std::complex<double>& x) { return std::abs(x); }
+inline double ei_abs2(const std::complex<double>& x) { return std::norm(x); }
+inline std::complex<double> ei_exp(std::complex<double> x) { return std::exp(x); }
+inline std::complex<double> ei_sin(std::complex<double> x) { return std::sin(x); }
+inline std::complex<double> ei_cos(std::complex<double> x) { return std::cos(x); }
+inline std::complex<double> ei_atan2(std::complex<double>, std::complex<double>) { ei_assert(false); return 0; }
+
+template<> inline std::complex<double> ei_random()
+{
+ return std::complex<double>(ei_random<double>(), ei_random<double>());
+}
+inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>())
+{
+ return ei_abs2(a) <= ei_abs2(b) * prec * prec;
+}
+inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = precision<double>())
+{
+ return ei_abs2(a) <= ei_abs2(b) * prec * prec;
+}
+inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>())
+{
+ return ei_isApprox(ei_real(a), ei_real(b), prec)
+ && ei_isApprox(ei_imag(a), ei_imag(b), prec);
+}
+// ei_isApproxOrLessThan wouldn't make sense for complex numbers
+
+
+/******************
+*** long double ***
+******************/
+
+template<> inline long double precision<long double>() { return precision<double>(); }
+template<> inline long double machine_epsilon<long double>() { return 1.084e-19l; }
+inline long double ei_real(long double x) { return x; }
+inline long double ei_imag(long double) { return 0.; }
+inline long double ei_conj(long double x) { return x; }
+inline long double ei_abs(long double x) { return std::abs(x); }
+inline long double ei_abs2(long double x) { return x*x; }
+inline long double ei_sqrt(long double x) { return std::sqrt(x); }
+inline long double ei_exp(long double x) { return std::exp(x); }
+inline long double ei_log(long double x) { return std::log(x); }
+inline long double ei_sin(long double x) { return std::sin(x); }
+inline long double ei_cos(long double x) { return std::cos(x); }
+inline long double ei_atan2(long double y, long double x) { return std::atan2(y,x); }
+inline long double ei_pow(long double x, long double y) { return std::pow(x, y); }
+
+template<> inline long double ei_random(long double a, long double b)
+{
+ return ei_random<double>(static_cast<double>(a),static_cast<double>(b));
+}
+template<> inline long double ei_random()
+{
+ return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
+}
+inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = precision<long double>())
+{
+ return ei_abs(a) <= ei_abs(b) * prec;
+}
+inline bool ei_isApprox(long double a, long double b, long double prec = precision<long double>())
+{
+ return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
+}
+inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = precision<long double>())
+{
+ return a <= b || ei_isApprox(a, b, prec);
+}
+
+#endif // EIGEN_MATHFUNCTIONS_H
diff --git a/extern/Eigen2/Eigen/src/Core/Matrix.h b/extern/Eigen2/Eigen/src/Core/Matrix.h
new file mode 100644
index 00000000000..ffd16d37606
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Matrix.h
@@ -0,0 +1,637 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MATRIX_H
+#define EIGEN_MATRIX_H
+
+
+/** \class Matrix
+ *
+ * \brief The matrix class, also used for vectors and row-vectors
+ *
+ * The %Matrix class is the work-horse for all \em dense (\ref dense "note") matrices and vectors within Eigen.
+ * Vectors are matrices with one column, and row-vectors are matrices with one row.
+ *
+ * The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note").
+ *
+ * The first three template parameters are required:
+ * \param _Scalar Numeric type, i.e. float, double, int
+ * \param _Rows Number of rows, or \b Dynamic
+ * \param _Cols Number of columns, or \b Dynamic
+ *
+ * The remaining template parameters are optional -- in most cases you don't have to worry about them.
+ * \param _Options A combination of either \b RowMajor or \b ColMajor, and of either
+ * \b AutoAlign or \b DontAlign.
+ * The former controls storage order, and defaults to column-major. The latter controls alignment, which is required
+ * for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
+ * \param _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
+ * \param _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note").
+ *
+ * Eigen provides a number of typedefs covering the usual cases. Here are some examples:
+ *
+ * \li \c Matrix2d is a 2x2 square matrix of doubles (\c Matrix<double, 2, 2>)
+ * \li \c Vector4f is a vector of 4 floats (\c Matrix<float, 4, 1>)
+ * \li \c RowVector3i is a row-vector of 3 ints (\c Matrix<int, 1, 3>)
+ *
+ * \li \c MatrixXf is a dynamic-size matrix of floats (\c Matrix<float, Dynamic, Dynamic>)
+ * \li \c VectorXf is a dynamic-size vector of floats (\c Matrix<float, Dynamic, 1>)
+ *
+ * See \link matrixtypedefs this page \endlink for a complete list of predefined \em %Matrix and \em Vector typedefs.
+ *
+ * You can access elements of vectors and matrices using normal subscripting:
+ *
+ * \code
+ * Eigen::VectorXd v(10);
+ * v[0] = 0.1;
+ * v[1] = 0.2;
+ * v(0) = 0.3;
+ * v(1) = 0.4;
+ *
+ * Eigen::MatrixXi m(10, 10);
+ * m(0, 1) = 1;
+ * m(0, 2) = 2;
+ * m(0, 3) = 3;
+ * \endcode
+ *
+ * <i><b>Some notes:</b></i>
+ *
+ * <dl>
+ * <dt><b>\anchor dense Dense versus sparse:</b></dt>
+ * <dd>This %Matrix class handles dense, not sparse matrices and vectors. For sparse matrices and vectors, see the Sparse module.
+ *
+ * Dense matrices and vectors are plain usual arrays of coefficients. All the coefficients are stored, in an ordinary contiguous array.
+ * This is unlike Sparse matrices and vectors where the coefficients are stored as a list of nonzero coefficients.</dd>
+ *
+ * <dt><b>\anchor fixedsize Fixed-size versus dynamic-size:</b></dt>
+ * <dd>Fixed-size means that the numbers of rows and columns are known are compile-time. In this case, Eigen allocates the array
+ * of coefficients as a fixed-size array, as a class member. This makes sense for very small matrices, typically up to 4x4, sometimes up
+ * to 16x16. Larger matrices should be declared as dynamic-size even if one happens to know their size at compile-time.
+ *
+ * Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime
+ * variables, and the array of coefficients is allocated dynamically on the heap.
+ *
+ * Note that \em dense matrices, be they Fixed-size or Dynamic-size, <em>do not</em> expand dynamically in the sense of a std::map.
+ * If you want this behavior, see the Sparse module.</dd>
+ *
+ * <dt><b>\anchor maxrows _MaxRows and _MaxCols:</b></dt>
+ * <dd>In most cases, one just leaves these parameters to the default values.
+ * These parameters mean the maximum size of rows and columns that the matrix may have. They are useful in cases
+ * when the exact numbers of rows and columns are not known are compile-time, but it is known at compile-time that they cannot
+ * exceed a certain value. This happens when taking dynamic-size blocks inside fixed-size matrices: in this case _MaxRows and _MaxCols
+ * are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.</dd>
+ * </dl>
+ *
+ * \see MatrixBase for the majority of the API methods for matrices
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
+{
+ typedef _Scalar Scalar;
+ enum {
+ RowsAtCompileTime = _Rows,
+ ColsAtCompileTime = _Cols,
+ MaxRowsAtCompileTime = _MaxRows,
+ MaxColsAtCompileTime = _MaxCols,
+ Flags = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
+ CoeffReadCost = NumTraits<Scalar>::ReadCost
+ };
+};
+
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+class Matrix
+ : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
+{
+ public:
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
+ enum { Options = _Options };
+ friend class Eigen::Map<Matrix, Unaligned>;
+ typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType;
+ friend class Eigen::Map<Matrix, Aligned>;
+ typedef class Eigen::Map<Matrix, Aligned> AlignedMapType;
+
+ protected:
+ ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage;
+
+ public:
+ enum { NeedsToAlign = (Options&AutoAlign) == AutoAlign
+ && SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 };
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
+
+ Base& base() { return *static_cast<Base*>(this); }
+ const Base& base() const { return *static_cast<const Base*>(this); }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); }
+
+ EIGEN_STRONG_INLINE int stride(void) const
+ {
+ if(Flags & RowMajorBit)
+ return m_storage.cols();
+ else
+ return m_storage.rows();
+ }
+
+ EIGEN_STRONG_INLINE const Scalar& coeff(int row, int col) const
+ {
+ if(Flags & RowMajorBit)
+ return m_storage.data()[col + row * m_storage.cols()];
+ else // column-major
+ return m_storage.data()[row + col * m_storage.rows()];
+ }
+
+ EIGEN_STRONG_INLINE const Scalar& coeff(int index) const
+ {
+ return m_storage.data()[index];
+ }
+
+ EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col)
+ {
+ if(Flags & RowMajorBit)
+ return m_storage.data()[col + row * m_storage.cols()];
+ else // column-major
+ return m_storage.data()[row + col * m_storage.rows()];
+ }
+
+ EIGEN_STRONG_INLINE Scalar& coeffRef(int index)
+ {
+ return m_storage.data()[index];
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
+ {
+ return ei_ploadt<Scalar, LoadMode>
+ (m_storage.data() + (Flags & RowMajorBit
+ ? col + row * m_storage.cols()
+ : row + col * m_storage.rows()));
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(int index) const
+ {
+ return ei_ploadt<Scalar, LoadMode>(m_storage.data() + index);
+ }
+
+ template<int StoreMode>
+ EIGEN_STRONG_INLINE void writePacket(int row, int col, const PacketScalar& x)
+ {
+ ei_pstoret<Scalar, PacketScalar, StoreMode>
+ (m_storage.data() + (Flags & RowMajorBit
+ ? col + row * m_storage.cols()
+ : row + col * m_storage.rows()), x);
+ }
+
+ template<int StoreMode>
+ EIGEN_STRONG_INLINE void writePacket(int index, const PacketScalar& x)
+ {
+ ei_pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
+ }
+
+ /** \returns a const pointer to the data array of this matrix */
+ EIGEN_STRONG_INLINE const Scalar *data() const
+ { return m_storage.data(); }
+
+ /** \returns a pointer to the data array of this matrix */
+ EIGEN_STRONG_INLINE Scalar *data()
+ { return m_storage.data(); }
+
+ /** Resizes \c *this to a \a rows x \a cols matrix.
+ *
+ * Makes sense for dynamic-size matrices only.
+ *
+ * If the current number of coefficients of \c *this exactly matches the
+ * product \a rows * \a cols, then no memory allocation is performed and
+ * the current values are left unchanged. In all other cases, including
+ * shrinking, the data is reallocated and all previous values are lost.
+ *
+ * \sa resize(int) for vectors.
+ */
+ inline void resize(int rows, int cols)
+ {
+ ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows)
+ && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
+ && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
+ && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
+ m_storage.resize(rows * cols, rows, cols);
+ }
+
+ /** Resizes \c *this to a vector of length \a size
+ *
+ * \sa resize(int,int) for the details.
+ */
+ inline void resize(int size)
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
+ if(RowsAtCompileTime == 1)
+ m_storage.resize(size, 1, size);
+ else
+ m_storage.resize(size, size, 1);
+ }
+
+ /** Copies the value of the expression \a other into \c *this with automatic resizing.
+ *
+ * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
+ * it will be initialized.
+ *
+ * Note that copying a row-vector into a vector (and conversely) is allowed.
+ * The resizing, if any, is then done in the appropriate way so that row-vectors
+ * remain row-vectors and vectors remain vectors.
+ */
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
+ {
+ return _set(other);
+ }
+
+ /** This is a special case of the templated operator=. Its purpose is to
+ * prevent a default operator= from hiding the templated operator=.
+ */
+ EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
+ {
+ return _set(other);
+ }
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, +=)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, -=)
+ EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Matrix, *=)
+ EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Matrix, /=)
+
+ /** Default constructor.
+ *
+ * For fixed-size matrices, does nothing.
+ *
+ * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
+ * is called a null matrix. This constructor is the unique way to create null matrices: resizing
+ * a matrix to 0 is not supported.
+ *
+ * \sa resize(int,int)
+ */
+ EIGEN_STRONG_INLINE explicit Matrix() : m_storage()
+ {
+ _check_template_params();
+ }
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** \internal */
+ Matrix(ei_constructor_without_unaligned_array_assert)
+ : m_storage(ei_constructor_without_unaligned_array_assert())
+ {}
+#endif
+
+ /** Constructs a vector or row-vector with given dimension. \only_for_vectors
+ *
+ * Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
+ * it is redundant to pass the dimension here, so it makes more sense to use the default
+ * constructor Matrix() instead.
+ */
+ EIGEN_STRONG_INLINE explicit Matrix(int dim)
+ : m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
+ {
+ _check_template_params();
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
+ ei_assert(dim > 0);
+ ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
+ }
+
+ /** This constructor has two very different behaviors, depending on the type of *this.
+ *
+ * \li When Matrix is a fixed-size vector type of size 2, this constructor constructs
+ * an initialized vector. The parameters \a x, \a y are copied into the first and second
+ * coords of the vector respectively.
+ * \li Otherwise, this constructor constructs an uninitialized matrix with \a x rows and
+ * \a y columns. This is useful for dynamic-size matrices. For fixed-size matrices,
+ * it is redundant to pass these parameters, so one should use the default constructor
+ * Matrix() instead.
+ */
+ EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y)
+ {
+ _check_template_params();
+ if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2)
+ || (RowsAtCompileTime == 2 && ColsAtCompileTime == 1))
+ {
+ m_storage.data()[0] = Scalar(x);
+ m_storage.data()[1] = Scalar(y);
+ }
+ else
+ {
+ ei_assert(x > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == x)
+ && y > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == y));
+ }
+ }
+ /** constructs an initialized 2D vector with given coefficients */
+ EIGEN_STRONG_INLINE Matrix(const float& x, const float& y)
+ {
+ _check_template_params();
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
+ m_storage.data()[0] = x;
+ m_storage.data()[1] = y;
+ }
+ /** constructs an initialized 2D vector with given coefficients */
+ EIGEN_STRONG_INLINE Matrix(const double& x, const double& y)
+ {
+ _check_template_params();
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
+ m_storage.data()[0] = x;
+ m_storage.data()[1] = y;
+ }
+ /** constructs an initialized 3D vector with given coefficients */
+ EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
+ {
+ _check_template_params();
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
+ m_storage.data()[0] = x;
+ m_storage.data()[1] = y;
+ m_storage.data()[2] = z;
+ }
+ /** constructs an initialized 4D vector with given coefficients */
+ EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
+ {
+ _check_template_params();
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
+ m_storage.data()[0] = x;
+ m_storage.data()[1] = y;
+ m_storage.data()[2] = z;
+ m_storage.data()[3] = w;
+ }
+
+ explicit Matrix(const Scalar *data);
+
+ /** Constructor copying the value of the expression \a other */
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
+ : m_storage(other.rows() * other.cols(), other.rows(), other.cols())
+ {
+ _check_template_params();
+ _set_noalias(other);
+ }
+ /** Copy constructor */
+ EIGEN_STRONG_INLINE Matrix(const Matrix& other)
+ : Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols())
+ {
+ _check_template_params();
+ _set_noalias(other);
+ }
+ /** Destructor */
+ inline ~Matrix() {}
+
+ /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
+ * data pointers.
+ */
+ template<typename OtherDerived>
+ void swap(const MatrixBase<OtherDerived>& other);
+
+ /** \name Map
+ * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
+ * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
+ * \a data pointers.
+ *
+ * \see class Map
+ */
+ //@{
+ inline static const UnalignedMapType Map(const Scalar* data)
+ { return UnalignedMapType(data); }
+ inline static UnalignedMapType Map(Scalar* data)
+ { return UnalignedMapType(data); }
+ inline static const UnalignedMapType Map(const Scalar* data, int size)
+ { return UnalignedMapType(data, size); }
+ inline static UnalignedMapType Map(Scalar* data, int size)
+ { return UnalignedMapType(data, size); }
+ inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols)
+ { return UnalignedMapType(data, rows, cols); }
+ inline static UnalignedMapType Map(Scalar* data, int rows, int cols)
+ { return UnalignedMapType(data, rows, cols); }
+
+ inline static const AlignedMapType MapAligned(const Scalar* data)
+ { return AlignedMapType(data); }
+ inline static AlignedMapType MapAligned(Scalar* data)
+ { return AlignedMapType(data); }
+ inline static const AlignedMapType MapAligned(const Scalar* data, int size)
+ { return AlignedMapType(data, size); }
+ inline static AlignedMapType MapAligned(Scalar* data, int size)
+ { return AlignedMapType(data, size); }
+ inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols)
+ { return AlignedMapType(data, rows, cols); }
+ inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols)
+ { return AlignedMapType(data, rows, cols); }
+ //@}
+
+ using Base::setConstant;
+ Matrix& setConstant(int size, const Scalar& value);
+ Matrix& setConstant(int rows, int cols, const Scalar& value);
+
+ using Base::setZero;
+ Matrix& setZero(int size);
+ Matrix& setZero(int rows, int cols);
+
+ using Base::setOnes;
+ Matrix& setOnes(int size);
+ Matrix& setOnes(int rows, int cols);
+
+ using Base::setRandom;
+ Matrix& setRandom(int size);
+ Matrix& setRandom(int rows, int cols);
+
+ using Base::setIdentity;
+ Matrix& setIdentity(int rows, int cols);
+
+/////////// Geometry module ///////////
+
+ template<typename OtherDerived>
+ explicit Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
+ template<typename OtherDerived>
+ Matrix& operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
+
+ // allow to extend Matrix outside Eigen
+ #ifdef EIGEN_MATRIX_PLUGIN
+ #include EIGEN_MATRIX_PLUGIN
+ #endif
+
+ private:
+ /** \internal Resizes *this in preparation for assigning \a other to it.
+ * Takes care of doing all the checking that's needed.
+ *
+ * Note that copying a row-vector into a vector (and conversely) is allowed.
+ * The resizing, if any, is then done in the appropriate way so that row-vectors
+ * remain row-vectors and vectors remain vectors.
+ */
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE void _resize_to_match(const MatrixBase<OtherDerived>& other)
+ {
+ if(RowsAtCompileTime == 1)
+ {
+ ei_assert(other.isVector());
+ resize(1, other.size());
+ }
+ else if(ColsAtCompileTime == 1)
+ {
+ ei_assert(other.isVector());
+ resize(other.size(), 1);
+ }
+ else resize(other.rows(), other.cols());
+ }
+
+ /** \internal Copies the value of the expression \a other into \c *this with automatic resizing.
+ *
+ * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
+ * it will be initialized.
+ *
+ * Note that copying a row-vector into a vector (and conversely) is allowed.
+ * The resizing, if any, is then done in the appropriate way so that row-vectors
+ * remain row-vectors and vectors remain vectors.
+ *
+ * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
+ */
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other)
+ {
+ _set_selector(other.derived(), typename ei_meta_if<bool(int(OtherDerived::Flags) & EvalBeforeAssigningBit), ei_meta_true, ei_meta_false>::ret());
+ return *this;
+ }
+
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_true&) { _set_noalias(other.eval()); }
+
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_false&) { _set_noalias(other); }
+
+ /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
+ * is the case when creating a new matrix) so one can enforce lazy evaluation.
+ *
+ * \sa operator=(const MatrixBase<OtherDerived>&), _set()
+ */
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE Matrix& _set_noalias(const MatrixBase<OtherDerived>& other)
+ {
+ _resize_to_match(other);
+ // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
+ // it wouldn't allow to copy a row-vector into a column-vector.
+ return ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived());
+ }
+
+ static EIGEN_STRONG_INLINE void _check_template_params()
+ {
+ EIGEN_STATIC_ASSERT((_Rows > 0
+ && _Cols > 0
+ && _MaxRows <= _Rows
+ && _MaxCols <= _Cols
+ && (_Options & (AutoAlign|RowMajor)) == _Options),
+ INVALID_MATRIX_TEMPLATE_PARAMETERS)
+ }
+
+ template<typename MatrixType, typename OtherDerived, bool IsSameType, bool IsDynamicSize>
+ friend struct ei_matrix_swap_impl;
+};
+
+template<typename MatrixType, typename OtherDerived,
+ bool IsSameType = ei_is_same_type<MatrixType, OtherDerived>::ret,
+ bool IsDynamicSize = MatrixType::SizeAtCompileTime==Dynamic>
+struct ei_matrix_swap_impl
+{
+ static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
+ {
+ matrix.base().swap(other);
+ }
+};
+
+template<typename MatrixType, typename OtherDerived>
+struct ei_matrix_swap_impl<MatrixType, OtherDerived, true, true>
+{
+ static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
+ {
+ matrix.m_storage.swap(other.derived().m_storage);
+ }
+};
+
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+template<typename OtherDerived>
+inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other)
+{
+ ei_matrix_swap_impl<Matrix, OtherDerived>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));
+}
+
+
+/** \defgroup matrixtypedefs Global matrix typedefs
+ *
+ * \ingroup Core_Module
+ *
+ * Eigen defines several typedef shortcuts for most common matrix and vector types.
+ *
+ * The general patterns are the following:
+ *
+ * \c MatrixSizeType where \c Size can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,
+ * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd
+ * for complex double.
+ *
+ * For example, \c Matrix3d is a fixed-size 3x3 matrix type of doubles, and \c MatrixXf is a dynamic-size matrix of floats.
+ *
+ * There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is
+ * a fixed-size vector of 4 complex floats.
+ *
+ * \sa class Matrix
+ */
+
+#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \
+/** \ingroup matrixtypedefs */ \
+typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix; \
+/** \ingroup matrixtypedefs */ \
+typedef Matrix<Type, Size, 1> Vector##SizeSuffix##TypeSuffix; \
+/** \ingroup matrixtypedefs */ \
+typedef Matrix<Type, 1, Size> RowVector##SizeSuffix##TypeSuffix;
+
+#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
+EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \
+EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \
+EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \
+EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X)
+
+EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i)
+EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f)
+EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d)
+EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<float>, cf)
+EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
+
+#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES
+#undef EIGEN_MAKE_TYPEDEFS
+
+#undef EIGEN_MAKE_TYPEDEFS_LARGE
+
+#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
+using Eigen::Matrix##SizeSuffix##TypeSuffix; \
+using Eigen::Vector##SizeSuffix##TypeSuffix; \
+using Eigen::RowVector##SizeSuffix##TypeSuffix;
+
+#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
+
+#define EIGEN_USING_MATRIX_TYPEDEFS \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd)
+
+#endif // EIGEN_MATRIX_H
diff --git a/extern/Eigen2/Eigen/src/Core/MatrixBase.h b/extern/Eigen2/Eigen/src/Core/MatrixBase.h
new file mode 100644
index 00000000000..7935a7554ea
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/MatrixBase.h
@@ -0,0 +1,632 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MATRIXBASE_H
+#define EIGEN_MATRIXBASE_H
+
+/** \class MatrixBase
+ *
+ * \brief Base class for all matrices, vectors, and expressions
+ *
+ * This class is the base that is inherited by all matrix, vector, and expression
+ * types. Most of the Eigen API is contained in this class. Other important classes for
+ * the Eigen API are Matrix, Cwise, and PartialRedux.
+ *
+ * Note that some methods are defined in the \ref Array module.
+ *
+ * \param Derived is the derived type, e.g. a matrix type, or an expression, etc.
+ *
+ * When writing a function taking Eigen objects as argument, if you want your function
+ * to take as argument any matrix, vector, or expression, just let it take a
+ * MatrixBase argument. As an example, here is a function printFirstRow which, given
+ * a matrix, vector, or expression \a x, prints the first row of \a x.
+ *
+ * \code
+ template<typename Derived>
+ void printFirstRow(const Eigen::MatrixBase<Derived>& x)
+ {
+ cout << x.row(0) << endl;
+ }
+ * \endcode
+ *
+ */
+template<typename Derived> class MatrixBase
+{
+ public:
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ class InnerIterator;
+
+ typedef typename ei_traits<Derived>::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+ enum {
+
+ RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
+ /**< The number of rows at compile-time. This is just a copy of the value provided
+ * by the \a Derived type. If a value is not known at compile-time,
+ * it is set to the \a Dynamic constant.
+ * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
+
+ ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
+ /**< The number of columns at compile-time. This is just a copy of the value provided
+ * by the \a Derived type. If a value is not known at compile-time,
+ * it is set to the \a Dynamic constant.
+ * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
+
+
+ SizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime,
+ ei_traits<Derived>::ColsAtCompileTime>::ret),
+ /**< This is equal to the number of coefficients, i.e. the number of
+ * rows times the number of columns, or to \a Dynamic if this is not
+ * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
+
+ MaxRowsAtCompileTime = ei_traits<Derived>::MaxRowsAtCompileTime,
+ /**< This value is equal to the maximum possible number of rows that this expression
+ * might have. If this expression might have an arbitrarily high number of rows,
+ * this value is set to \a Dynamic.
+ *
+ * This value is useful to know when evaluating an expression, in order to determine
+ * whether it is possible to avoid doing a dynamic memory allocation.
+ *
+ * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime
+ */
+
+ MaxColsAtCompileTime = ei_traits<Derived>::MaxColsAtCompileTime,
+ /**< This value is equal to the maximum possible number of columns that this expression
+ * might have. If this expression might have an arbitrarily high number of columns,
+ * this value is set to \a Dynamic.
+ *
+ * This value is useful to know when evaluating an expression, in order to determine
+ * whether it is possible to avoid doing a dynamic memory allocation.
+ *
+ * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime
+ */
+
+ MaxSizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::MaxRowsAtCompileTime,
+ ei_traits<Derived>::MaxColsAtCompileTime>::ret),
+ /**< This value is equal to the maximum possible number of coefficients that this expression
+ * might have. If this expression might have an arbitrarily high number of coefficients,
+ * this value is set to \a Dynamic.
+ *
+ * This value is useful to know when evaluating an expression, in order to determine
+ * whether it is possible to avoid doing a dynamic memory allocation.
+ *
+ * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
+ */
+
+ IsVectorAtCompileTime = ei_traits<Derived>::RowsAtCompileTime == 1
+ || ei_traits<Derived>::ColsAtCompileTime == 1,
+ /**< This is set to true if either the number of rows or the number of
+ * columns is known at compile-time to be equal to 1. Indeed, in that case,
+ * we are dealing with a column-vector (if there is only one column) or with
+ * a row-vector (if there is only one row). */
+
+ Flags = ei_traits<Derived>::Flags,
+ /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
+ * constructed from this one. See the \ref flags "list of flags".
+ */
+
+ CoeffReadCost = ei_traits<Derived>::CoeffReadCost
+ /**< This is a rough measure of how expensive it is to read one coefficient from
+ * this expression.
+ */
+ };
+
+ /** Default constructor. Just checks at compile-time for self-consistency of the flags. */
+ MatrixBase()
+ {
+ ei_assert(ei_are_flags_consistent<Flags>::ret);
+ }
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** This is the "real scalar" type; if the \a Scalar type is already real numbers
+ * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
+ * \a Scalar is \a std::complex<T> then RealScalar is \a T.
+ *
+ * \sa class NumTraits
+ */
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ /** type of the equivalent square matrix */
+ typedef Matrix<Scalar,EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime),
+ EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+ /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
+ inline int rows() const { return derived().rows(); }
+ /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
+ inline int cols() const { return derived().cols(); }
+ /** \returns the number of coefficients, which is \a rows()*cols().
+ * \sa rows(), cols(), SizeAtCompileTime. */
+ inline int size() const { return rows() * cols(); }
+ /** \returns the number of nonzero coefficients which is in practice the number
+ * of stored coefficients. */
+ inline int nonZeros() const { return derived.nonZeros(); }
+ /** \returns true if either the number of rows or the number of columns is equal to 1.
+ * In other words, this function returns
+ * \code rows()==1 || cols()==1 \endcode
+ * \sa rows(), cols(), IsVectorAtCompileTime. */
+ inline bool isVector() const { return rows()==1 || cols()==1; }
+ /** \returns the size of the storage major dimension,
+ * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
+ int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
+ /** \returns the size of the inner dimension according to the storage order,
+ * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
+ int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
+ * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
+ * reference to a matrix, not a matrix! It guaranteed however, that the return type of eval() is either
+ * PlainMatrixType or const PlainMatrixType&.
+ */
+ typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
+ /** \internal the column-major plain matrix type corresponding to this expression. Note that is not necessarily
+ * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
+ * reference to a matrix, not a matrix!
+ * The only difference from PlainMatrixType is that PlainMatrixType_ColMajor is guaranteed to be column-major.
+ */
+ typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType_ColMajor;
+
+ /** \internal Represents a matrix with all coefficients equal to one another*/
+ typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
+ /** \internal Represents a scalar multiple of a matrix */
+ typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType;
+ /** \internal Represents a quotient of a matrix by a scalar*/
+ typedef CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> ScalarQuotient1ReturnType;
+ /** \internal the return type of MatrixBase::conjugate() */
+ typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
+ const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
+ const Derived&
+ >::ret ConjugateReturnType;
+ /** \internal the return type of MatrixBase::real() */
+ typedef CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType;
+ /** \internal the return type of MatrixBase::imag() */
+ typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
+ /** \internal the return type of MatrixBase::adjoint() */
+ typedef Eigen::Transpose<NestByValue<typename ei_cleantype<ConjugateReturnType>::type> >
+ AdjointReturnType;
+ /** \internal the return type of MatrixBase::eigenvalues() */
+ typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
+ /** \internal expression tyepe of a column */
+ typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr;
+ /** \internal expression tyepe of a column */
+ typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr;
+ /** \internal the return type of identity */
+ typedef CwiseNullaryOp<ei_scalar_identity_op<Scalar>,Derived> IdentityReturnType;
+ /** \internal the return type of unit vectors */
+ typedef Block<CwiseNullaryOp<ei_scalar_identity_op<Scalar>, SquareMatrixType>,
+ ei_traits<Derived>::RowsAtCompileTime,
+ ei_traits<Derived>::ColsAtCompileTime> BasisReturnType;
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+
+ /** Copies \a other into *this. \returns a reference to *this. */
+ template<typename OtherDerived>
+ Derived& operator=(const MatrixBase<OtherDerived>& other);
+
+ /** Special case of the template operator=, in order to prevent the compiler
+ * from generating a default operator= (issue hit with g++ 4.1)
+ */
+ inline Derived& operator=(const MatrixBase& other)
+ {
+ return this->operator=<Derived>(other);
+ }
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** Copies \a other into *this without evaluating other. \returns a reference to *this. */
+ template<typename OtherDerived>
+ Derived& lazyAssign(const MatrixBase<OtherDerived>& other);
+
+ /** Overloaded for cache friendly product evaluation */
+ template<typename Lhs, typename Rhs>
+ Derived& lazyAssign(const Product<Lhs,Rhs,CacheFriendlyProduct>& product);
+
+ /** Overloaded for cache friendly product evaluation */
+ template<typename OtherDerived>
+ Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other)
+ { return lazyAssign(other._expression()); }
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+ CommaInitializer<Derived> operator<< (const Scalar& s);
+
+ template<typename OtherDerived>
+ CommaInitializer<Derived> operator<< (const MatrixBase<OtherDerived>& other);
+
+ const Scalar coeff(int row, int col) const;
+ const Scalar operator()(int row, int col) const;
+
+ Scalar& coeffRef(int row, int col);
+ Scalar& operator()(int row, int col);
+
+ const Scalar coeff(int index) const;
+ const Scalar operator[](int index) const;
+ const Scalar operator()(int index) const;
+
+ Scalar& coeffRef(int index);
+ Scalar& operator[](int index);
+ Scalar& operator()(int index);
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ template<typename OtherDerived>
+ void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other);
+ template<typename OtherDerived>
+ void copyCoeff(int index, const MatrixBase<OtherDerived>& other);
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other);
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ void copyPacket(int index, const MatrixBase<OtherDerived>& other);
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+ template<int LoadMode>
+ PacketScalar packet(int row, int col) const;
+ template<int StoreMode>
+ void writePacket(int row, int col, const PacketScalar& x);
+
+ template<int LoadMode>
+ PacketScalar packet(int index) const;
+ template<int StoreMode>
+ void writePacket(int index, const PacketScalar& x);
+
+ const Scalar x() const;
+ const Scalar y() const;
+ const Scalar z() const;
+ const Scalar w() const;
+ Scalar& x();
+ Scalar& y();
+ Scalar& z();
+ Scalar& w();
+
+
+ const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const;
+
+ template<typename OtherDerived>
+ const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
+ operator+(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
+ operator-(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ Derived& operator+=(const MatrixBase<OtherDerived>& other);
+ template<typename OtherDerived>
+ Derived& operator-=(const MatrixBase<OtherDerived>& other);
+
+ template<typename Lhs,typename Rhs>
+ Derived& operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProduct>, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other);
+
+ Derived& operator*=(const Scalar& other);
+ Derived& operator/=(const Scalar& other);
+
+ const ScalarMultipleReturnType operator*(const Scalar& scalar) const;
+ const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
+ operator/(const Scalar& scalar) const;
+
+ inline friend const CwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
+ operator*(const Scalar& scalar, const MatrixBase& matrix)
+ { return matrix*scalar; }
+
+
+ template<typename OtherDerived>
+ const typename ProductReturnType<Derived,OtherDerived>::Type
+ operator*(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ Derived& operator*=(const MatrixBase<OtherDerived>& other);
+
+ template<typename OtherDerived>
+ typename ei_plain_matrix_type_column_major<OtherDerived>::type
+ solveTriangular(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived>
+ void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const;
+
+
+ template<typename OtherDerived>
+ Scalar dot(const MatrixBase<OtherDerived>& other) const;
+ RealScalar squaredNorm() const;
+ RealScalar norm() const;
+ const PlainMatrixType normalized() const;
+ void normalize();
+
+ Eigen::Transpose<Derived> transpose();
+ const Eigen::Transpose<Derived> transpose() const;
+ void transposeInPlace();
+ const AdjointReturnType adjoint() const;
+
+
+ RowXpr row(int i);
+ const RowXpr row(int i) const;
+
+ ColXpr col(int i);
+ const ColXpr col(int i) const;
+
+ Minor<Derived> minor(int row, int col);
+ const Minor<Derived> minor(int row, int col) const;
+
+ typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols);
+ const typename BlockReturnType<Derived>::Type
+ block(int startRow, int startCol, int blockRows, int blockCols) const;
+
+ typename BlockReturnType<Derived>::SubVectorType segment(int start, int size);
+ const typename BlockReturnType<Derived>::SubVectorType segment(int start, int size) const;
+
+ typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size);
+ const typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size) const;
+
+ typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size);
+ const typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size) const;
+
+ typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols);
+ const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const;
+
+ template<int BlockRows, int BlockCols>
+ typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol);
+ template<int BlockRows, int BlockCols>
+ const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const;
+
+ template<int CRows, int CCols>
+ typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type);
+ template<int CRows, int CCols>
+ const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const;
+
+ template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType start(void);
+ template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType start() const;
+
+ template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType end();
+ template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType end() const;
+
+ template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType segment(int start);
+ template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType segment(int start) const;
+
+ DiagonalCoeffs<Derived> diagonal();
+ const DiagonalCoeffs<Derived> diagonal() const;
+
+ template<unsigned int Mode> Part<Derived, Mode> part();
+ template<unsigned int Mode> const Part<Derived, Mode> part() const;
+
+
+ static const ConstantReturnType
+ Constant(int rows, int cols, const Scalar& value);
+ static const ConstantReturnType
+ Constant(int size, const Scalar& value);
+ static const ConstantReturnType
+ Constant(const Scalar& value);
+
+ template<typename CustomNullaryOp>
+ static const CwiseNullaryOp<CustomNullaryOp, Derived>
+ NullaryExpr(int rows, int cols, const CustomNullaryOp& func);
+ template<typename CustomNullaryOp>
+ static const CwiseNullaryOp<CustomNullaryOp, Derived>
+ NullaryExpr(int size, const CustomNullaryOp& func);
+ template<typename CustomNullaryOp>
+ static const CwiseNullaryOp<CustomNullaryOp, Derived>
+ NullaryExpr(const CustomNullaryOp& func);
+
+ static const ConstantReturnType Zero(int rows, int cols);
+ static const ConstantReturnType Zero(int size);
+ static const ConstantReturnType Zero();
+ static const ConstantReturnType Ones(int rows, int cols);
+ static const ConstantReturnType Ones(int size);
+ static const ConstantReturnType Ones();
+ static const IdentityReturnType Identity();
+ static const IdentityReturnType Identity(int rows, int cols);
+ static const BasisReturnType Unit(int size, int i);
+ static const BasisReturnType Unit(int i);
+ static const BasisReturnType UnitX();
+ static const BasisReturnType UnitY();
+ static const BasisReturnType UnitZ();
+ static const BasisReturnType UnitW();
+
+ const DiagonalMatrix<Derived> asDiagonal() const;
+
+ void fill(const Scalar& value);
+ Derived& setConstant(const Scalar& value);
+ Derived& setZero();
+ Derived& setOnes();
+ Derived& setRandom();
+ Derived& setIdentity();
+
+
+ template<typename OtherDerived>
+ bool isApprox(const MatrixBase<OtherDerived>& other,
+ RealScalar prec = precision<Scalar>()) const;
+ bool isMuchSmallerThan(const RealScalar& other,
+ RealScalar prec = precision<Scalar>()) const;
+ template<typename OtherDerived>
+ bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
+ RealScalar prec = precision<Scalar>()) const;
+
+ bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
+ bool isConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
+ bool isZero(RealScalar prec = precision<Scalar>()) const;
+ bool isOnes(RealScalar prec = precision<Scalar>()) const;
+ bool isIdentity(RealScalar prec = precision<Scalar>()) const;
+ bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
+
+ bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
+ bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
+
+ template<typename OtherDerived>
+ bool isOrthogonal(const MatrixBase<OtherDerived>& other,
+ RealScalar prec = precision<Scalar>()) const;
+ bool isUnitary(RealScalar prec = precision<Scalar>()) const;
+
+ template<typename OtherDerived>
+ inline bool operator==(const MatrixBase<OtherDerived>& other) const
+ { return (cwise() == other).all(); }
+
+ template<typename OtherDerived>
+ inline bool operator!=(const MatrixBase<OtherDerived>& other) const
+ { return (cwise() != other).any(); }
+
+
+ template<typename NewType>
+ const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const;
+
+ /** \returns the matrix or vector obtained by evaluating this expression.
+ *
+ * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
+ * a const reference, in order to avoid a useless copy.
+ */
+ EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const
+ { return typename ei_eval<Derived>::type(derived()); }
+
+ template<typename OtherDerived>
+ void swap(const MatrixBase<OtherDerived>& other);
+
+ template<unsigned int Added>
+ const Flagged<Derived, Added, 0> marked() const;
+ const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit> lazy() const;
+
+ /** \returns number of elements to skip to pass from one row (resp. column) to another
+ * for a row-major (resp. column-major) matrix.
+ * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data
+ * of the underlying matrix.
+ */
+ inline int stride(void) const { return derived().stride(); }
+
+ inline const NestByValue<Derived> nestByValue() const;
+
+
+ ConjugateReturnType conjugate() const;
+ const RealReturnType real() const;
+ const ImagReturnType imag() const;
+
+ template<typename CustomUnaryOp>
+ const CwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const;
+
+ template<typename CustomBinaryOp, typename OtherDerived>
+ const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
+ binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const;
+
+
+ Scalar sum() const;
+ Scalar trace() const;
+
+ typename ei_traits<Derived>::Scalar minCoeff() const;
+ typename ei_traits<Derived>::Scalar maxCoeff() const;
+
+ typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col) const;
+ typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col) const;
+
+ typename ei_traits<Derived>::Scalar minCoeff(int* index) const;
+ typename ei_traits<Derived>::Scalar maxCoeff(int* index) const;
+
+ template<typename BinaryOp>
+ typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
+ redux(const BinaryOp& func) const;
+
+ template<typename Visitor>
+ void visit(Visitor& func) const;
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
+ inline Derived& derived() { return *static_cast<Derived*>(this); }
+ inline Derived& const_cast_derived() const
+ { return *static_cast<Derived*>(const_cast<MatrixBase*>(this)); }
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+ const Cwise<Derived> cwise() const;
+ Cwise<Derived> cwise();
+
+ inline const WithFormat<Derived> format(const IOFormat& fmt) const;
+
+/////////// Array module ///////////
+
+ bool all(void) const;
+ bool any(void) const;
+ int count() const;
+
+ const PartialRedux<Derived,Horizontal> rowwise() const;
+ const PartialRedux<Derived,Vertical> colwise() const;
+
+ static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int rows, int cols);
+ static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int size);
+ static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random();
+
+ template<typename ThenDerived,typename ElseDerived>
+ const Select<Derived,ThenDerived,ElseDerived>
+ select(const MatrixBase<ThenDerived>& thenMatrix,
+ const MatrixBase<ElseDerived>& elseMatrix) const;
+
+ template<typename ThenDerived>
+ inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
+ select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
+
+ template<typename ElseDerived>
+ inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
+ select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
+
+ template<int p> RealScalar lpNorm() const;
+
+/////////// LU module ///////////
+
+ const LU<PlainMatrixType> lu() const;
+ const PlainMatrixType inverse() const;
+ void computeInverse(PlainMatrixType *result) const;
+ Scalar determinant() const;
+
+/////////// Cholesky module ///////////
+
+ const LLT<PlainMatrixType> llt() const;
+ const LDLT<PlainMatrixType> ldlt() const;
+
+/////////// QR module ///////////
+
+ const QR<PlainMatrixType> qr() const;
+
+ EigenvaluesReturnType eigenvalues() const;
+ RealScalar operatorNorm() const;
+
+/////////// SVD module ///////////
+
+ SVD<PlainMatrixType> svd() const;
+
+/////////// Geometry module ///////////
+
+ template<typename OtherDerived>
+ PlainMatrixType cross(const MatrixBase<OtherDerived>& other) const;
+ PlainMatrixType unitOrthogonal(void) const;
+ Matrix<Scalar,3,1> eulerAngles(int a0, int a1, int a2) const;
+
+/////////// Sparse module ///////////
+
+ // dense = spasre * dense
+ template<typename Derived1, typename Derived2>
+ Derived& lazyAssign(const SparseProduct<Derived1,Derived2,SparseTimeDenseProduct>& product);
+ // dense = dense * spasre
+ template<typename Derived1, typename Derived2>
+ Derived& lazyAssign(const SparseProduct<Derived1,Derived2,DenseTimeSparseProduct>& product);
+
+ #ifdef EIGEN_MATRIXBASE_PLUGIN
+ #include EIGEN_MATRIXBASE_PLUGIN
+ #endif
+};
+
+#endif // EIGEN_MATRIXBASE_H
diff --git a/extern/Eigen2/Eigen/src/Core/MatrixStorage.h b/extern/Eigen2/Eigen/src/Core/MatrixStorage.h
new file mode 100644
index 00000000000..ba2355b8e60
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/MatrixStorage.h
@@ -0,0 +1,249 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MATRIXSTORAGE_H
+#define EIGEN_MATRIXSTORAGE_H
+
+struct ei_constructor_without_unaligned_array_assert {};
+
+/** \internal
+ * Static array automatically aligned if the total byte size is a multiple of 16 and the matrix options require auto alignment
+ */
+template <typename T, int Size, int MatrixOptions,
+ bool Align = (MatrixOptions&AutoAlign) && (((Size*sizeof(T))&0xf)==0)
+> struct ei_matrix_array
+{
+ EIGEN_ALIGN_128 T array[Size];
+
+ ei_matrix_array()
+ {
+ #ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
+ ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0
+ && "this assertion is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
+ #endif
+ }
+
+ ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
+};
+
+template <typename T, int Size, int MatrixOptions> struct ei_matrix_array<T,Size,MatrixOptions,false>
+{
+ T array[Size];
+ ei_matrix_array() {}
+ ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
+};
+
+/** \internal
+ *
+ * \class ei_matrix_storage
+ *
+ * \brief Stores the data of a matrix
+ *
+ * This class stores the data of fixed-size, dynamic-size or mixed matrices
+ * in a way as compact as possible.
+ *
+ * \sa Matrix
+ */
+template<typename T, int Size, int _Rows, int _Cols, int _Options> class ei_matrix_storage;
+
+// purely fixed-size matrix
+template<typename T, int Size, int _Rows, int _Cols, int _Options> class ei_matrix_storage
+{
+ ei_matrix_array<T,Size,_Options> m_data;
+ public:
+ inline explicit ei_matrix_storage() {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
+ : m_data(ei_constructor_without_unaligned_array_assert()) {}
+ inline ei_matrix_storage(int,int,int) {}
+ inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); }
+ inline static int rows(void) {return _Rows;}
+ inline static int cols(void) {return _Cols;}
+ inline void resize(int,int,int) {}
+ inline const T *data() const { return m_data.array; }
+ inline T *data() { return m_data.array; }
+};
+
+// dynamic-size matrix with fixed-size storage
+template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dynamic, Dynamic, _Options>
+{
+ ei_matrix_array<T,Size,_Options> m_data;
+ int m_rows;
+ int m_cols;
+ public:
+ inline explicit ei_matrix_storage() : m_rows(0), m_cols(0) {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
+ : m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
+ inline ei_matrix_storage(int, int rows, int cols) : m_rows(rows), m_cols(cols) {}
+ inline ~ei_matrix_storage() {}
+ inline void swap(ei_matrix_storage& other)
+ { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
+ inline int rows(void) const {return m_rows;}
+ inline int cols(void) const {return m_cols;}
+ inline void resize(int, int rows, int cols)
+ {
+ m_rows = rows;
+ m_cols = cols;
+ }
+ inline const T *data() const { return m_data.array; }
+ inline T *data() { return m_data.array; }
+};
+
+// dynamic-size matrix with fixed-size storage and fixed width
+template<typename T, int Size, int _Cols, int _Options> class ei_matrix_storage<T, Size, Dynamic, _Cols, _Options>
+{
+ ei_matrix_array<T,Size,_Options> m_data;
+ int m_rows;
+ public:
+ inline explicit ei_matrix_storage() : m_rows(0) {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
+ : m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {}
+ inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {}
+ inline ~ei_matrix_storage() {}
+ inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
+ inline int rows(void) const {return m_rows;}
+ inline int cols(void) const {return _Cols;}
+ inline void resize(int /*size*/, int rows, int)
+ {
+ m_rows = rows;
+ }
+ inline const T *data() const { return m_data.array; }
+ inline T *data() { return m_data.array; }
+};
+
+// dynamic-size matrix with fixed-size storage and fixed height
+template<typename T, int Size, int _Rows, int _Options> class ei_matrix_storage<T, Size, _Rows, Dynamic, _Options>
+{
+ ei_matrix_array<T,Size,_Options> m_data;
+ int m_cols;
+ public:
+ inline explicit ei_matrix_storage() : m_cols(0) {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
+ : m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {}
+ inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {}
+ inline ~ei_matrix_storage() {}
+ inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
+ inline int rows(void) const {return _Rows;}
+ inline int cols(void) const {return m_cols;}
+ inline void resize(int, int, int cols)
+ {
+ m_cols = cols;
+ }
+ inline const T *data() const { return m_data.array; }
+ inline T *data() { return m_data.array; }
+};
+
+// purely dynamic matrix.
+template<typename T, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic, Dynamic, _Options>
+{
+ T *m_data;
+ int m_rows;
+ int m_cols;
+ public:
+ inline explicit ei_matrix_storage() : m_data(0), m_rows(0), m_cols(0) {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
+ : m_data(0), m_rows(0), m_cols(0) {}
+ inline ei_matrix_storage(int size, int rows, int cols)
+ : m_data(ei_aligned_new<T>(size)), m_rows(rows), m_cols(cols) {}
+ inline ~ei_matrix_storage() { ei_aligned_delete(m_data, m_rows*m_cols); }
+ inline void swap(ei_matrix_storage& other)
+ { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
+ inline int rows(void) const {return m_rows;}
+ inline int cols(void) const {return m_cols;}
+ void resize(int size, int rows, int cols)
+ {
+ if(size != m_rows*m_cols)
+ {
+ ei_aligned_delete(m_data, m_rows*m_cols);
+ if (size)
+ m_data = ei_aligned_new<T>(size);
+ else
+ m_data = 0;
+ }
+ m_rows = rows;
+ m_cols = cols;
+ }
+ inline const T *data() const { return m_data; }
+ inline T *data() { return m_data; }
+};
+
+// matrix with dynamic width and fixed height (so that matrix has dynamic size).
+template<typename T, int _Rows, int _Options> class ei_matrix_storage<T, Dynamic, _Rows, Dynamic, _Options>
+{
+ T *m_data;
+ int m_cols;
+ public:
+ inline explicit ei_matrix_storage() : m_data(0), m_cols(0) {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
+ inline ei_matrix_storage(int size, int, int cols) : m_data(ei_aligned_new<T>(size)), m_cols(cols) {}
+ inline ~ei_matrix_storage() { ei_aligned_delete(m_data, _Rows*m_cols); }
+ inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
+ inline static int rows(void) {return _Rows;}
+ inline int cols(void) const {return m_cols;}
+ void resize(int size, int, int cols)
+ {
+ if(size != _Rows*m_cols)
+ {
+ ei_aligned_delete(m_data, _Rows*m_cols);
+ if (size)
+ m_data = ei_aligned_new<T>(size);
+ else
+ m_data = 0;
+ }
+ m_cols = cols;
+ }
+ inline const T *data() const { return m_data; }
+ inline T *data() { return m_data; }
+};
+
+// matrix with dynamic height and fixed width (so that matrix has dynamic size).
+template<typename T, int _Cols, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic, _Cols, _Options>
+{
+ T *m_data;
+ int m_rows;
+ public:
+ inline explicit ei_matrix_storage() : m_data(0), m_rows(0) {}
+ inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
+ inline ei_matrix_storage(int size, int rows, int) : m_data(ei_aligned_new<T>(size)), m_rows(rows) {}
+ inline ~ei_matrix_storage() { ei_aligned_delete(m_data, _Cols*m_rows); }
+ inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
+ inline int rows(void) const {return m_rows;}
+ inline static int cols(void) {return _Cols;}
+ void resize(int size, int rows, int)
+ {
+ if(size != m_rows*_Cols)
+ {
+ ei_aligned_delete(m_data, _Cols*m_rows);
+ if (size)
+ m_data = ei_aligned_new<T>(size);
+ else
+ m_data = 0;
+ }
+ m_rows = rows;
+ }
+ inline const T *data() const { return m_data; }
+ inline T *data() { return m_data; }
+};
+
+#endif // EIGEN_MATRIX_H
diff --git a/extern/Eigen2/Eigen/src/Core/Minor.h b/extern/Eigen2/Eigen/src/Core/Minor.h
new file mode 100644
index 00000000000..e2d47da79c2
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Minor.h
@@ -0,0 +1,122 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MINOR_H
+#define EIGEN_MINOR_H
+
+/** \nonstableyet
+ * \class Minor
+ *
+ * \brief Expression of a minor
+ *
+ * \param MatrixType the type of the object in which we are taking a minor
+ *
+ * This class represents an expression of a minor. It is the return
+ * type of MatrixBase::minor() and most of the time this is the only way it
+ * is used.
+ *
+ * \sa MatrixBase::minor()
+ */
+template<typename MatrixType>
+struct ei_traits<Minor<MatrixType> >
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ RowsAtCompileTime = (MatrixType::RowsAtCompileTime != Dynamic) ?
+ int(MatrixType::RowsAtCompileTime) - 1 : Dynamic,
+ ColsAtCompileTime = (MatrixType::ColsAtCompileTime != Dynamic) ?
+ int(MatrixType::ColsAtCompileTime) - 1 : Dynamic,
+ MaxRowsAtCompileTime = (MatrixType::MaxRowsAtCompileTime != Dynamic) ?
+ int(MatrixType::MaxRowsAtCompileTime) - 1 : Dynamic,
+ MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ?
+ int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic,
+ Flags = _MatrixTypeNested::Flags & HereditaryBits,
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost
+ };
+};
+
+template<typename MatrixType> class Minor
+ : public MatrixBase<Minor<MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Minor)
+
+ inline Minor(const MatrixType& matrix,
+ int row, int col)
+ : m_matrix(matrix), m_row(row), m_col(col)
+ {
+ ei_assert(row >= 0 && row < matrix.rows()
+ && col >= 0 && col < matrix.cols());
+ }
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Minor)
+
+ inline int rows() const { return m_matrix.rows() - 1; }
+ inline int cols() const { return m_matrix.cols() - 1; }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived().coeffRef(row + (row >= m_row), col + (col >= m_col));
+ }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_matrix.coeff(row + (row >= m_row), col + (col >= m_col));
+ }
+
+ protected:
+ const typename MatrixType::Nested m_matrix;
+ const int m_row, m_col;
+};
+
+/** \nonstableyet
+ * \return an expression of the (\a row, \a col)-minor of *this,
+ * i.e. an expression constructed from *this by removing the specified
+ * row and column.
+ *
+ * Example: \include MatrixBase_minor.cpp
+ * Output: \verbinclude MatrixBase_minor.out
+ *
+ * \sa class Minor
+ */
+template<typename Derived>
+inline Minor<Derived>
+MatrixBase<Derived>::minor(int row, int col)
+{
+ return Minor<Derived>(derived(), row, col);
+}
+
+/** \nonstableyet
+ * This is the const version of minor(). */
+template<typename Derived>
+inline const Minor<Derived>
+MatrixBase<Derived>::minor(int row, int col) const
+{
+ return Minor<Derived>(derived(), row, col);
+}
+
+#endif // EIGEN_MINOR_H
diff --git a/extern/Eigen2/Eigen/src/Core/NestByValue.h b/extern/Eigen2/Eigen/src/Core/NestByValue.h
new file mode 100644
index 00000000000..da79315bffe
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/NestByValue.h
@@ -0,0 +1,114 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_NESTBYVALUE_H
+#define EIGEN_NESTBYVALUE_H
+
+/** \class NestByValue
+ *
+ * \brief Expression which must be nested by value
+ *
+ * \param ExpressionType the type of the object of which we are requiring nesting-by-value
+ *
+ * This class is the return type of MatrixBase::nestByValue()
+ * and most of the time this is the only way it is used.
+ *
+ * \sa MatrixBase::nestByValue()
+ */
+template<typename ExpressionType>
+struct ei_traits<NestByValue<ExpressionType> > : public ei_traits<ExpressionType>
+{};
+
+template<typename ExpressionType> class NestByValue
+ : public MatrixBase<NestByValue<ExpressionType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(NestByValue)
+
+ inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
+
+ inline int rows() const { return m_expression.rows(); }
+ inline int cols() const { return m_expression.cols(); }
+ inline int stride() const { return m_expression.stride(); }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_expression.coeff(row, col);
+ }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_expression.const_cast_derived().coeffRef(row, col);
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ return m_expression.coeff(index);
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_expression.const_cast_derived().coeffRef(index);
+ }
+
+ template<int LoadMode>
+ inline const PacketScalar packet(int row, int col) const
+ {
+ return m_expression.template packet<LoadMode>(row, col);
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int row, int col, const PacketScalar& x)
+ {
+ m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
+ }
+
+ template<int LoadMode>
+ inline const PacketScalar packet(int index) const
+ {
+ return m_expression.template packet<LoadMode>(index);
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int index, const PacketScalar& x)
+ {
+ m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
+ }
+
+ protected:
+ const ExpressionType m_expression;
+};
+
+/** \returns an expression of the temporary version of *this.
+ */
+template<typename Derived>
+inline const NestByValue<Derived>
+MatrixBase<Derived>::nestByValue() const
+{
+ return NestByValue<Derived>(derived());
+}
+
+#endif // EIGEN_NESTBYVALUE_H
diff --git a/extern/Eigen2/Eigen/src/Core/NumTraits.h b/extern/Eigen2/Eigen/src/Core/NumTraits.h
new file mode 100644
index 00000000000..b27284a78bc
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/NumTraits.h
@@ -0,0 +1,142 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_NUMTRAITS_H
+#define EIGEN_NUMTRAITS_H
+
+/** \class NumTraits
+ *
+ * \brief Holds some data about the various numeric (i.e. scalar) types allowed by Eigen.
+ *
+ * \param T the numeric type about which this class provides data. Recall that Eigen allows
+ * only the following types for \a T: \c int, \c float, \c double,
+ * \c std::complex<float>, \c std::complex<double>, and \c long \c double (especially
+ * useful to enforce x87 arithmetics when SSE is the default).
+ *
+ * The provided data consists of:
+ * \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real,
+ * then \a Real is just a typedef to \a T. If \a T is \c std::complex<U> then \a Real
+ * is a typedef to \a U.
+ * \li A typedef \a FloatingPoint, giving the "floating-point type" of \a T. If \a T is
+ * \c int, then \a FloatingPoint is a typedef to \c double. Otherwise, \a FloatingPoint
+ * is a typedef to \a T.
+ * \li An enum value \a IsComplex. It is equal to 1 if \a T is a \c std::complex
+ * type, and to 0 otherwise.
+ * \li An enum \a HasFloatingPoint. It is equal to \c 0 if \a T is \c int,
+ * and to \c 1 otherwise.
+ */
+template<typename T> struct NumTraits;
+
+template<> struct NumTraits<int>
+{
+ typedef int Real;
+ typedef double FloatingPoint;
+ enum {
+ IsComplex = 0,
+ HasFloatingPoint = 0,
+ ReadCost = 1,
+ AddCost = 1,
+ MulCost = 1
+ };
+};
+
+template<> struct NumTraits<float>
+{
+ typedef float Real;
+ typedef float FloatingPoint;
+ enum {
+ IsComplex = 0,
+ HasFloatingPoint = 1,
+ ReadCost = 1,
+ AddCost = 1,
+ MulCost = 1
+ };
+};
+
+template<> struct NumTraits<double>
+{
+ typedef double Real;
+ typedef double FloatingPoint;
+ enum {
+ IsComplex = 0,
+ HasFloatingPoint = 1,
+ ReadCost = 1,
+ AddCost = 1,
+ MulCost = 1
+ };
+};
+
+template<typename _Real> struct NumTraits<std::complex<_Real> >
+{
+ typedef _Real Real;
+ typedef std::complex<_Real> FloatingPoint;
+ enum {
+ IsComplex = 1,
+ HasFloatingPoint = NumTraits<Real>::HasFloatingPoint,
+ ReadCost = 2,
+ AddCost = 2 * NumTraits<Real>::AddCost,
+ MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
+ };
+};
+
+template<> struct NumTraits<long long int>
+{
+ typedef long long int Real;
+ typedef long double FloatingPoint;
+ enum {
+ IsComplex = 0,
+ HasFloatingPoint = 0,
+ ReadCost = 1,
+ AddCost = 1,
+ MulCost = 1
+ };
+};
+
+template<> struct NumTraits<long double>
+{
+ typedef long double Real;
+ typedef long double FloatingPoint;
+ enum {
+ IsComplex = 0,
+ HasFloatingPoint = 1,
+ ReadCost = 1,
+ AddCost = 1,
+ MulCost = 1
+ };
+};
+
+template<> struct NumTraits<bool>
+{
+ typedef bool Real;
+ typedef float FloatingPoint;
+ enum {
+ IsComplex = 0,
+ HasFloatingPoint = 0,
+ ReadCost = 1,
+ AddCost = 1,
+ MulCost = 1
+ };
+};
+
+#endif // EIGEN_NUMTRAITS_H
diff --git a/extern/Eigen2/Eigen/src/Core/Part.h b/extern/Eigen2/Eigen/src/Core/Part.h
new file mode 100644
index 00000000000..9c273f249ec
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Part.h
@@ -0,0 +1,375 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_PART_H
+#define EIGEN_PART_H
+
+/** \nonstableyet
+ * \class Part
+ *
+ * \brief Expression of a triangular matrix extracted from a given matrix
+ *
+ * \param MatrixType the type of the object in which we are taking the triangular part
+ * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular, StrictlyUpperTriangular,
+ * UnitUpperTriangular, LowerTriangular, StrictlyLowerTriangular, UnitLowerTriangular. This is in fact a bit field; it must have either
+ * UpperTriangularBit or LowerTriangularBit, and additionnaly it may have either ZeroDiagBit or
+ * UnitDiagBit.
+ *
+ * This class represents an expression of the upper or lower triangular part of
+ * a square matrix, possibly with a further assumption on the diagonal. It is the return type
+ * of MatrixBase::part() and most of the time this is the only way it is used.
+ *
+ * \sa MatrixBase::part()
+ */
+template<typename MatrixType, unsigned int Mode>
+struct ei_traits<Part<MatrixType, Mode> > : ei_traits<MatrixType>
+{
+ typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ Flags = (_MatrixTypeNested::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode,
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost
+ };
+};
+
+template<typename MatrixType, unsigned int Mode> class Part
+ : public MatrixBase<Part<MatrixType, Mode> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Part)
+
+ inline Part(const MatrixType& matrix) : m_matrix(matrix)
+ { ei_assert(ei_are_flags_consistent<Mode>::ret); }
+
+ /** \sa MatrixBase::operator+=() */
+ template<typename Other> Part& operator+=(const Other& other);
+ /** \sa MatrixBase::operator-=() */
+ template<typename Other> Part& operator-=(const Other& other);
+ /** \sa MatrixBase::operator*=() */
+ Part& operator*=(const typename ei_traits<MatrixType>::Scalar& other);
+ /** \sa MatrixBase::operator/=() */
+ Part& operator/=(const typename ei_traits<MatrixType>::Scalar& other);
+
+ /** \sa operator=(), MatrixBase::lazyAssign() */
+ template<typename Other> void lazyAssign(const Other& other);
+ /** \sa MatrixBase::operator=() */
+ template<typename Other> Part& operator=(const Other& other);
+
+ inline int rows() const { return m_matrix.rows(); }
+ inline int cols() const { return m_matrix.cols(); }
+ inline int stride() const { return m_matrix.stride(); }
+
+ inline Scalar coeff(int row, int col) const
+ {
+ // SelfAdjointBit doesn't play any role here: just because a matrix is selfadjoint doesn't say anything about
+ // each individual coefficient, except for the not-very-useful-here fact that diagonal coefficients are real.
+ if( ((Flags & LowerTriangularBit) && (col>row)) || ((Flags & UpperTriangularBit) && (row>col)) )
+ return (Scalar)0;
+ if(Flags & UnitDiagBit)
+ return col==row ? (Scalar)1 : m_matrix.coeff(row, col);
+ else if(Flags & ZeroDiagBit)
+ return col==row ? (Scalar)0 : m_matrix.coeff(row, col);
+ else
+ return m_matrix.coeff(row, col);
+ }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ EIGEN_STATIC_ASSERT(!(Flags & UnitDiagBit), WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED)
+ EIGEN_STATIC_ASSERT(!(Flags & SelfAdjointBit), COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED)
+ ei_assert( (Mode==UpperTriangular && col>=row)
+ || (Mode==LowerTriangular && col<=row)
+ || (Mode==StrictlyUpperTriangular && col>row)
+ || (Mode==StrictlyLowerTriangular && col<row));
+ return m_matrix.const_cast_derived().coeffRef(row, col);
+ }
+
+ /** \internal */
+ const MatrixType& _expression() const { return m_matrix; }
+
+ /** discard any writes to a row */
+ const Block<Part, 1, ColsAtCompileTime> row(int i) { return Base::row(i); }
+ const Block<Part, 1, ColsAtCompileTime> row(int i) const { return Base::row(i); }
+ /** discard any writes to a column */
+ const Block<Part, RowsAtCompileTime, 1> col(int i) { return Base::col(i); }
+ const Block<Part, RowsAtCompileTime, 1> col(int i) const { return Base::col(i); }
+
+ template<typename OtherDerived>
+ void swap(const MatrixBase<OtherDerived>& other)
+ {
+ Part<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived());
+ }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+};
+
+/** \nonstableyet
+ * \returns an expression of a triangular matrix extracted from the current matrix
+ *
+ * The parameter \a Mode can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c UnitUpperTriangular,
+ * \c LowerTriangular, \c StrictlyLowerTriangular, \c UnitLowerTriangular.
+ *
+ * \addexample PartExample \label How to extract a triangular part of an arbitrary matrix
+ *
+ * Example: \include MatrixBase_extract.cpp
+ * Output: \verbinclude MatrixBase_extract.out
+ *
+ * \sa class Part, part(), marked()
+ */
+template<typename Derived>
+template<unsigned int Mode>
+const Part<Derived, Mode> MatrixBase<Derived>::part() const
+{
+ return derived();
+}
+
+template<typename MatrixType, unsigned int Mode>
+template<typename Other>
+inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator=(const Other& other)
+{
+ if(Other::Flags & EvalBeforeAssigningBit)
+ {
+ typename MatrixBase<Other>::PlainMatrixType other_evaluated(other.rows(), other.cols());
+ other_evaluated.template part<Mode>().lazyAssign(other);
+ lazyAssign(other_evaluated);
+ }
+ else
+ lazyAssign(other.derived());
+ return *this;
+}
+
+template<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount>
+struct ei_part_assignment_impl
+{
+ enum {
+ col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
+ row = (UnrollCount-1) % Derived1::RowsAtCompileTime
+ };
+
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ ei_part_assignment_impl<Derived1, Derived2, Mode, UnrollCount-1>::run(dst, src);
+
+ if(Mode == SelfAdjoint)
+ {
+ if(row == col)
+ dst.coeffRef(row, col) = ei_real(src.coeff(row, col));
+ else if(row < col)
+ dst.coeffRef(col, row) = ei_conj(dst.coeffRef(row, col) = src.coeff(row, col));
+ }
+ else
+ {
+ ei_assert(Mode == UpperTriangular || Mode == LowerTriangular || Mode == StrictlyUpperTriangular || Mode == StrictlyLowerTriangular);
+ if((Mode == UpperTriangular && row <= col)
+ || (Mode == LowerTriangular && row >= col)
+ || (Mode == StrictlyUpperTriangular && row < col)
+ || (Mode == StrictlyLowerTriangular && row > col))
+ dst.copyCoeff(row, col, src);
+ }
+ }
+};
+
+template<typename Derived1, typename Derived2, unsigned int Mode>
+struct ei_part_assignment_impl<Derived1, Derived2, Mode, 1>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ if(!(Mode & ZeroDiagBit))
+ dst.copyCoeff(0, 0, src);
+ }
+};
+
+// prevent buggy user code from causing an infinite recursion
+template<typename Derived1, typename Derived2, unsigned int Mode>
+struct ei_part_assignment_impl<Derived1, Derived2, Mode, 0>
+{
+ inline static void run(Derived1 &, const Derived2 &) {}
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_part_assignment_impl<Derived1, Derived2, UpperTriangular, Dynamic>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ for(int j = 0; j < dst.cols(); ++j)
+ for(int i = 0; i <= j; ++i)
+ dst.copyCoeff(i, j, src);
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_part_assignment_impl<Derived1, Derived2, LowerTriangular, Dynamic>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ for(int j = 0; j < dst.cols(); ++j)
+ for(int i = j; i < dst.rows(); ++i)
+ dst.copyCoeff(i, j, src);
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpperTriangular, Dynamic>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ for(int j = 0; j < dst.cols(); ++j)
+ for(int i = 0; i < j; ++i)
+ dst.copyCoeff(i, j, src);
+ }
+};
+template<typename Derived1, typename Derived2>
+struct ei_part_assignment_impl<Derived1, Derived2, StrictlyLowerTriangular, Dynamic>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ for(int j = 0; j < dst.cols(); ++j)
+ for(int i = j+1; i < dst.rows(); ++i)
+ dst.copyCoeff(i, j, src);
+ }
+};
+template<typename Derived1, typename Derived2>
+struct ei_part_assignment_impl<Derived1, Derived2, SelfAdjoint, Dynamic>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ for(int j = 0; j < dst.cols(); ++j)
+ {
+ for(int i = 0; i < j; ++i)
+ dst.coeffRef(j, i) = ei_conj(dst.coeffRef(i, j) = src.coeff(i, j));
+ dst.coeffRef(j, j) = ei_real(src.coeff(j, j));
+ }
+ }
+};
+
+template<typename MatrixType, unsigned int Mode>
+template<typename Other>
+void Part<MatrixType, Mode>::lazyAssign(const Other& other)
+{
+ const bool unroll = MatrixType::SizeAtCompileTime * Other::CoeffReadCost / 2 <= EIGEN_UNROLLING_LIMIT;
+ ei_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
+
+ ei_part_assignment_impl
+ <MatrixType, Other, Mode,
+ unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic
+ >::run(m_matrix.const_cast_derived(), other.derived());
+}
+
+/** \nonstableyet
+ * \returns a lvalue pseudo-expression allowing to perform special operations on \c *this.
+ *
+ * The \a Mode parameter can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c LowerTriangular,
+ * \c StrictlyLowerTriangular, \c SelfAdjoint.
+ *
+ * \addexample PartExample \label How to write to a triangular part of a matrix
+ *
+ * Example: \include MatrixBase_part.cpp
+ * Output: \verbinclude MatrixBase_part.out
+ *
+ * \sa class Part, MatrixBase::extract(), MatrixBase::marked()
+ */
+template<typename Derived>
+template<unsigned int Mode>
+inline Part<Derived, Mode> MatrixBase<Derived>::part()
+{
+ return Part<Derived, Mode>(derived());
+}
+
+/** \returns true if *this is approximately equal to an upper triangular matrix,
+ * within the precision given by \a prec.
+ *
+ * \sa isLowerTriangular(), extract(), part(), marked()
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
+{
+ if(cols() != rows()) return false;
+ RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
+ for(int j = 0; j < cols(); ++j)
+ for(int i = 0; i <= j; ++i)
+ {
+ RealScalar absValue = ei_abs(coeff(i,j));
+ if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
+ }
+ for(int j = 0; j < cols()-1; ++j)
+ for(int i = j+1; i < rows(); ++i)
+ if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false;
+ return true;
+}
+
+/** \returns true if *this is approximately equal to a lower triangular matrix,
+ * within the precision given by \a prec.
+ *
+ * \sa isUpperTriangular(), extract(), part(), marked()
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
+{
+ if(cols() != rows()) return false;
+ RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
+ for(int j = 0; j < cols(); ++j)
+ for(int i = j; i < rows(); ++i)
+ {
+ RealScalar absValue = ei_abs(coeff(i,j));
+ if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
+ }
+ for(int j = 1; j < cols(); ++j)
+ for(int i = 0; i < j; ++i)
+ if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
+ return true;
+}
+
+template<typename MatrixType, unsigned int Mode>
+template<typename Other>
+inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator+=(const Other& other)
+{
+ return *this = m_matrix + other;
+}
+
+template<typename MatrixType, unsigned int Mode>
+template<typename Other>
+inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator-=(const Other& other)
+{
+ return *this = m_matrix - other;
+}
+
+template<typename MatrixType, unsigned int Mode>
+inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator*=
+(const typename ei_traits<MatrixType>::Scalar& other)
+{
+ return *this = m_matrix * other;
+}
+
+template<typename MatrixType, unsigned int Mode>
+inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator/=
+(const typename ei_traits<MatrixType>::Scalar& other)
+{
+ return *this = m_matrix / other;
+}
+
+#endif // EIGEN_PART_H
diff --git a/extern/Eigen2/Eigen/src/Core/Product.h b/extern/Eigen2/Eigen/src/Core/Product.h
new file mode 100644
index 00000000000..1151b21641c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Product.h
@@ -0,0 +1,769 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_PRODUCT_H
+#define EIGEN_PRODUCT_H
+
+/***************************
+*** Forward declarations ***
+***************************/
+
+template<int VectorizationMode, int Index, typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl;
+
+template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl;
+
+/** \class ProductReturnType
+ *
+ * \brief Helper class to get the correct and optimized returned type of operator*
+ *
+ * \param Lhs the type of the left-hand side
+ * \param Rhs the type of the right-hand side
+ * \param ProductMode the type of the product (determined automatically by ei_product_mode)
+ *
+ * This class defines the typename Type representing the optimized product expression
+ * between two matrix expressions. In practice, using ProductReturnType<Lhs,Rhs>::Type
+ * is the recommended way to define the result type of a function returning an expression
+ * which involve a matrix product. The class Product or DiagonalProduct should never be
+ * used directly.
+ *
+ * \sa class Product, class DiagonalProduct, MatrixBase::operator*(const MatrixBase<OtherDerived>&)
+ */
+template<typename Lhs, typename Rhs, int ProductMode>
+struct ProductReturnType
+{
+ typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
+ typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
+
+ typedef Product<LhsNested, RhsNested, ProductMode> Type;
+};
+
+// cache friendly specialization
+// note that there is a DiagonalProduct specialization in DiagonalProduct.h
+template<typename Lhs, typename Rhs>
+struct ProductReturnType<Lhs,Rhs,CacheFriendlyProduct>
+{
+ typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
+
+ typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime,
+ typename ei_plain_matrix_type_column_major<Rhs>::type
+ >::type RhsNested;
+
+ typedef Product<LhsNested, RhsNested, CacheFriendlyProduct> Type;
+};
+
+/* Helper class to determine the type of the product, can be either:
+ * - NormalProduct
+ * - CacheFriendlyProduct
+ * - DiagonalProduct
+ */
+template<typename Lhs, typename Rhs> struct ei_product_mode
+{
+ enum{
+
+ value = ((Rhs::Flags&Diagonal)==Diagonal) || ((Lhs::Flags&Diagonal)==Diagonal)
+ ? DiagonalProduct
+ : Lhs::MaxColsAtCompileTime == Dynamic
+ && ( Lhs::MaxRowsAtCompileTime == Dynamic
+ || Rhs::MaxColsAtCompileTime == Dynamic )
+ && (!(Rhs::IsVectorAtCompileTime && (Lhs::Flags&RowMajorBit) && (!(Lhs::Flags&DirectAccessBit))))
+ && (!(Lhs::IsVectorAtCompileTime && (!(Rhs::Flags&RowMajorBit)) && (!(Rhs::Flags&DirectAccessBit))))
+ && (ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)
+ ? CacheFriendlyProduct
+ : NormalProduct };
+};
+
+/** \class Product
+ *
+ * \brief Expression of the product of two matrices
+ *
+ * \param LhsNested the type used to store the left-hand side
+ * \param RhsNested the type used to store the right-hand side
+ * \param ProductMode the type of the product
+ *
+ * This class represents an expression of the product of two matrices.
+ * It is the return type of the operator* between matrices. Its template
+ * arguments are determined automatically by ProductReturnType. Therefore,
+ * Product should never be used direclty. To determine the result type of a
+ * function which involves a matrix product, use ProductReturnType::Type.
+ *
+ * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase<OtherDerived>&)
+ */
+template<typename LhsNested, typename RhsNested, int ProductMode>
+struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
+{
+ // clean the nested types:
+ typedef typename ei_cleantype<LhsNested>::type _LhsNested;
+ typedef typename ei_cleantype<RhsNested>::type _RhsNested;
+ typedef typename ei_scalar_product_traits<typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType Scalar;
+
+ enum {
+ LhsCoeffReadCost = _LhsNested::CoeffReadCost,
+ RhsCoeffReadCost = _RhsNested::CoeffReadCost,
+ LhsFlags = _LhsNested::Flags,
+ RhsFlags = _RhsNested::Flags,
+
+ RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
+ ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
+ InnerSize = EIGEN_ENUM_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
+
+ MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
+
+ LhsRowMajor = LhsFlags & RowMajorBit,
+ RhsRowMajor = RhsFlags & RowMajorBit,
+
+ CanVectorizeRhs = RhsRowMajor && (RhsFlags & PacketAccessBit)
+ && (ColsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
+
+ CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit)
+ && (RowsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
+
+ EvalToRowMajor = RhsRowMajor && (ProductMode==(int)CacheFriendlyProduct ? LhsRowMajor : (!CanVectorizeLhs)),
+
+ RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit),
+
+ Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
+ | EvalBeforeAssigningBit
+ | EvalBeforeNestingBit
+ | (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0)
+ | (LhsFlags & RhsFlags & AlignedBit),
+
+ CoeffReadCost = InnerSize == Dynamic ? Dynamic
+ : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
+ + (InnerSize - 1) * NumTraits<Scalar>::AddCost,
+
+ /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside
+ * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner
+ * loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect
+ * the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI.
+ */
+ CanVectorizeInner = LhsRowMajor && (!RhsRowMajor) && (LhsFlags & RhsFlags & ActualPacketAccessBit)
+ && (InnerSize % ei_packet_traits<Scalar>::size == 0)
+ };
+};
+
+template<typename LhsNested, typename RhsNested, int ProductMode> class Product : ei_no_assignment_operator,
+ public MatrixBase<Product<LhsNested, RhsNested, ProductMode> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
+
+ private:
+
+ typedef typename ei_traits<Product>::_LhsNested _LhsNested;
+ typedef typename ei_traits<Product>::_RhsNested _RhsNested;
+
+ enum {
+ PacketSize = ei_packet_traits<Scalar>::size,
+ InnerSize = ei_traits<Product>::InnerSize,
+ Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
+ CanVectorizeInner = ei_traits<Product>::CanVectorizeInner
+ };
+
+ typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorization : NoVectorization,
+ Unroll ? InnerSize-1 : Dynamic,
+ _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
+
+ public:
+
+ template<typename Lhs, typename Rhs>
+ inline Product(const Lhs& lhs, const Rhs& rhs)
+ : m_lhs(lhs), m_rhs(rhs)
+ {
+ // we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable.
+ // We still allow to mix T and complex<T>.
+ EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+ ei_assert(lhs.cols() == rhs.rows()
+ && "invalid matrix product"
+ && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
+ }
+
+ /** \internal
+ * compute \a res += \c *this using the cache friendly product.
+ */
+ template<typename DestDerived>
+ void _cacheFriendlyEvalAndAdd(DestDerived& res) const;
+
+ /** \internal
+ * \returns whether it is worth it to use the cache friendly product.
+ */
+ EIGEN_STRONG_INLINE bool _useCacheFriendlyProduct() const
+ {
+ return m_lhs.cols()>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
+ && ( rows()>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
+ || cols()>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD);
+ }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_rhs.cols(); }
+
+ EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
+ {
+ Scalar res;
+ ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res);
+ return res;
+ }
+
+ /* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
+ * which is why we don't set the LinearAccessBit.
+ */
+ EIGEN_STRONG_INLINE const Scalar coeff(int index) const
+ {
+ Scalar res;
+ const int row = RowsAtCompileTime == 1 ? 0 : index;
+ const int col = RowsAtCompileTime == 1 ? index : 0;
+ ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res);
+ return res;
+ }
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE const PacketScalar packet(int row, int col) const
+ {
+ PacketScalar res;
+ ei_product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor,
+ Unroll ? InnerSize-1 : Dynamic,
+ _LhsNested, _RhsNested, PacketScalar, LoadMode>
+ ::run(row, col, m_lhs, m_rhs, res);
+ return res;
+ }
+
+ EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
+ EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
+
+ protected:
+ const LhsNested m_lhs;
+ const RhsNested m_rhs;
+};
+
+/** \returns the matrix product of \c *this and \a other.
+ *
+ * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*().
+ *
+ * \sa lazy(), operator*=(const MatrixBase&), Cwise::operator*()
+ */
+template<typename Derived>
+template<typename OtherDerived>
+inline const typename ProductReturnType<Derived,OtherDerived>::Type
+MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
+{
+ enum {
+ ProductIsValid = Derived::ColsAtCompileTime==Dynamic
+ || OtherDerived::RowsAtCompileTime==Dynamic
+ || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
+ AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
+ SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
+ };
+ // note to the lost user:
+ // * for a dot product use: v1.dot(v2)
+ // * for a coeff-wise product use: v1.cwise()*v2
+ EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
+ INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
+ EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
+ INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
+ EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
+ return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
+}
+
+/** replaces \c *this by \c *this * \a other.
+ *
+ * \returns a reference to \c *this
+ */
+template<typename Derived>
+template<typename OtherDerived>
+inline Derived &
+MatrixBase<Derived>::operator*=(const MatrixBase<OtherDerived> &other)
+{
+ return derived() = derived() * other.derived();
+}
+
+/***************************************************************************
+* Normal product .coeff() implementation (with meta-unrolling)
+***************************************************************************/
+
+/**************************************
+*** Scalar path - no vectorization ***
+**************************************/
+
+template<int Index, typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl<NoVectorization, Index, Lhs, Rhs, RetScalar>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
+ {
+ ei_product_coeff_impl<NoVectorization, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
+ res += lhs.coeff(row, Index) * rhs.coeff(Index, col);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
+ {
+ res = lhs.coeff(row, 0) * rhs.coeff(0, col);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
+ {
+ ei_assert(lhs.cols()>0 && "you are using a non initialized matrix");
+ res = lhs.coeff(row, 0) * rhs.coeff(0, col);
+ for(int i = 1; i < lhs.cols(); ++i)
+ res += lhs.coeff(row, i) * rhs.coeff(i, col);
+ }
+};
+
+// prevent buggy user code from causing an infinite recursion
+template<typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl<NoVectorization, -1, Lhs, Rhs, RetScalar>
+{
+ EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {}
+};
+
+/*******************************************
+*** Scalar path with inner vectorization ***
+*******************************************/
+
+template<int Index, typename Lhs, typename Rhs, typename PacketScalar>
+struct ei_product_coeff_vectorized_unroller
+{
+ enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
+ {
+ ei_product_coeff_vectorized_unroller<Index-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
+ pres = ei_padd(pres, ei_pmul( lhs.template packet<Aligned>(row, Index) , rhs.template packet<Aligned>(Index, col) ));
+ }
+};
+
+template<typename Lhs, typename Rhs, typename PacketScalar>
+struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
+ {
+ pres = ei_pmul(lhs.template packet<Aligned>(row, 0) , rhs.template packet<Aligned>(0, col));
+ }
+};
+
+template<int Index, typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar>
+{
+ typedef typename Lhs::PacketScalar PacketScalar;
+ enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
+ {
+ PacketScalar pres;
+ ei_product_coeff_vectorized_unroller<Index+1-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
+ ei_product_coeff_impl<NoVectorization,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
+ res = ei_predux(pres);
+ }
+};
+
+template<typename Lhs, typename Rhs, int LhsRows = Lhs::RowsAtCompileTime, int RhsCols = Rhs::ColsAtCompileTime>
+struct ei_product_coeff_vectorized_dyn_selector
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
+ {
+ res = ei_dot_impl<
+ Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
+ Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
+ LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs.col(col));
+ }
+};
+
+// NOTE the 3 following specializations are because taking .col(0) on a vector is a bit slower
+// NOTE maybe they are now useless since we have a specialization for Block<Matrix>
+template<typename Lhs, typename Rhs, int RhsCols>
+struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
+{
+ EIGEN_STRONG_INLINE static void run(int /*row*/, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
+ {
+ res = ei_dot_impl<
+ Lhs,
+ Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
+ LinearVectorization, NoUnrolling>::run(lhs, rhs.col(col));
+ }
+};
+
+template<typename Lhs, typename Rhs, int LhsRows>
+struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
+ {
+ res = ei_dot_impl<
+ Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
+ Rhs,
+ LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs);
+ }
+};
+
+template<typename Lhs, typename Rhs>
+struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
+{
+ EIGEN_STRONG_INLINE static void run(int /*row*/, int /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
+ {
+ res = ei_dot_impl<
+ Lhs,
+ Rhs,
+ LinearVectorization, NoUnrolling>::run(lhs, rhs);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename RetScalar>
+struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs, RetScalar>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
+ {
+ ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs>::run(row, col, lhs, rhs, res);
+ }
+};
+
+/*******************
+*** Packet path ***
+*******************/
+
+template<int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl<RowMajor, Index, Lhs, Rhs, PacketScalar, LoadMode>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
+ {
+ ei_product_packet_impl<RowMajor, Index-1, Lhs, Rhs, PacketScalar, LoadMode>::run(row, col, lhs, rhs, res);
+ res = ei_pmadd(ei_pset1(lhs.coeff(row, Index)), rhs.template packet<LoadMode>(Index, col), res);
+ }
+};
+
+template<int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl<ColMajor, Index, Lhs, Rhs, PacketScalar, LoadMode>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
+ {
+ ei_product_packet_impl<ColMajor, Index-1, Lhs, Rhs, PacketScalar, LoadMode>::run(row, col, lhs, rhs, res);
+ res = ei_pmadd(lhs.template packet<LoadMode>(row, Index), ei_pset1(rhs.coeff(Index, col)), res);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl<RowMajor, 0, Lhs, Rhs, PacketScalar, LoadMode>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
+ {
+ res = ei_pmul(ei_pset1(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
+ }
+};
+
+template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl<ColMajor, 0, Lhs, Rhs, PacketScalar, LoadMode>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
+ {
+ res = ei_pmul(lhs.template packet<LoadMode>(row, 0), ei_pset1(rhs.coeff(0, col)));
+ }
+};
+
+template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMode>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar& res)
+ {
+ ei_assert(lhs.cols()>0 && "you are using a non initialized matrix");
+ res = ei_pmul(ei_pset1(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
+ for(int i = 1; i < lhs.cols(); ++i)
+ res = ei_pmadd(ei_pset1(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
+struct ei_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMode>
+{
+ EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar& res)
+ {
+ ei_assert(lhs.cols()>0 && "you are using a non initialized matrix");
+ res = ei_pmul(lhs.template packet<LoadMode>(row, 0), ei_pset1(rhs.coeff(0, col)));
+ for(int i = 1; i < lhs.cols(); ++i)
+ res = ei_pmadd(lhs.template packet<LoadMode>(row, i), ei_pset1(rhs.coeff(i, col)), res);
+ }
+};
+
+/***************************************************************************
+* Cache friendly product callers and specific nested evaluation strategies
+***************************************************************************/
+
+template<typename Scalar, typename RhsType>
+static void ei_cache_friendly_product_colmajor_times_vector(
+ int size, const Scalar* lhs, int lhsStride, const RhsType& rhs, Scalar* res);
+
+template<typename Scalar, typename ResType>
+static void ei_cache_friendly_product_rowmajor_times_vector(
+ const Scalar* lhs, int lhsStride, const Scalar* rhs, int rhsSize, ResType& res);
+
+template<typename ProductType,
+ int LhsRows = ei_traits<ProductType>::RowsAtCompileTime,
+ int LhsOrder = int(ei_traits<ProductType>::LhsFlags)&RowMajorBit ? RowMajor : ColMajor,
+ int LhsHasDirectAccess = int(ei_traits<ProductType>::LhsFlags)&DirectAccessBit? HasDirectAccess : NoDirectAccess,
+ int RhsCols = ei_traits<ProductType>::ColsAtCompileTime,
+ int RhsOrder = int(ei_traits<ProductType>::RhsFlags)&RowMajorBit ? RowMajor : ColMajor,
+ int RhsHasDirectAccess = int(ei_traits<ProductType>::RhsFlags)&DirectAccessBit? HasDirectAccess : NoDirectAccess>
+struct ei_cache_friendly_product_selector
+{
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ product._cacheFriendlyEvalAndAdd(res);
+ }
+};
+
+// optimized colmajor * vector path
+template<typename ProductType, int LhsRows, int RhsOrder, int RhsAccess>
+struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,NoDirectAccess,1,RhsOrder,RhsAccess>
+{
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ const int size = product.rhs().rows();
+ for (int k=0; k<size; ++k)
+ res += product.rhs().coeff(k) * product.lhs().col(k);
+ }
+};
+
+// optimized cache friendly colmajor * vector path for matrix with direct access flag
+// NOTE this path could also be enabled for expressions if we add runtime align queries
+template<typename ProductType, int LhsRows, int RhsOrder, int RhsAccess>
+struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirectAccess,1,RhsOrder,RhsAccess>
+{
+ typedef typename ProductType::Scalar Scalar;
+
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ enum {
+ EvalToRes = (ei_packet_traits<Scalar>::size==1)
+ ||((DestDerived::Flags&ActualPacketAccessBit) && (!(DestDerived::Flags & RowMajorBit))) };
+ Scalar* EIGEN_RESTRICT _res;
+ if (EvalToRes)
+ _res = &res.coeffRef(0);
+ else
+ {
+ _res = ei_aligned_stack_new(Scalar,res.size());
+ Map<Matrix<Scalar,DestDerived::RowsAtCompileTime,1> >(_res, res.size()) = res;
+ }
+ ei_cache_friendly_product_colmajor_times_vector(res.size(),
+ &product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
+ product.rhs(), _res);
+
+ if (!EvalToRes)
+ {
+ res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size());
+ ei_aligned_stack_delete(Scalar, _res, res.size());
+ }
+ }
+};
+
+// optimized vector * rowmajor path
+template<typename ProductType, int LhsOrder, int LhsAccess, int RhsCols>
+struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCols,RowMajor,NoDirectAccess>
+{
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ const int cols = product.lhs().cols();
+ for (int j=0; j<cols; ++j)
+ res += product.lhs().coeff(j) * product.rhs().row(j);
+ }
+};
+
+// optimized cache friendly vector * rowmajor path for matrix with direct access flag
+// NOTE this path coul also be enabled for expressions if we add runtime align queries
+template<typename ProductType, int LhsOrder, int LhsAccess, int RhsCols>
+struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCols,RowMajor,HasDirectAccess>
+{
+ typedef typename ProductType::Scalar Scalar;
+
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ enum {
+ EvalToRes = (ei_packet_traits<Scalar>::size==1)
+ ||((DestDerived::Flags & ActualPacketAccessBit) && (DestDerived::Flags & RowMajorBit)) };
+ Scalar* EIGEN_RESTRICT _res;
+ if (EvalToRes)
+ _res = &res.coeffRef(0);
+ else
+ {
+ _res = ei_aligned_stack_new(Scalar, res.size());
+ Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size()) = res;
+ }
+ ei_cache_friendly_product_colmajor_times_vector(res.size(),
+ &product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
+ product.lhs().transpose(), _res);
+
+ if (!EvalToRes)
+ {
+ res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size());
+ ei_aligned_stack_delete(Scalar, _res, res.size());
+ }
+ }
+};
+
+// optimized rowmajor - vector product
+template<typename ProductType, int LhsRows, int RhsOrder, int RhsAccess>
+struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,HasDirectAccess,1,RhsOrder,RhsAccess>
+{
+ typedef typename ProductType::Scalar Scalar;
+ typedef typename ei_traits<ProductType>::_RhsNested Rhs;
+ enum {
+ UseRhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Rhs::Flags&ActualPacketAccessBit))
+ && (!(Rhs::Flags & RowMajorBit)) };
+
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ Scalar* EIGEN_RESTRICT _rhs;
+ if (UseRhsDirectly)
+ _rhs = &product.rhs().const_cast_derived().coeffRef(0);
+ else
+ {
+ _rhs = ei_aligned_stack_new(Scalar, product.rhs().size());
+ Map<Matrix<Scalar,Rhs::SizeAtCompileTime,1> >(_rhs, product.rhs().size()) = product.rhs();
+ }
+ ei_cache_friendly_product_rowmajor_times_vector(&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
+ _rhs, product.rhs().size(), res);
+
+ if (!UseRhsDirectly) ei_aligned_stack_delete(Scalar, _rhs, product.rhs().size());
+ }
+};
+
+// optimized vector - colmajor product
+template<typename ProductType, int LhsOrder, int LhsAccess, int RhsCols>
+struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCols,ColMajor,HasDirectAccess>
+{
+ typedef typename ProductType::Scalar Scalar;
+ typedef typename ei_traits<ProductType>::_LhsNested Lhs;
+ enum {
+ UseLhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Lhs::Flags&ActualPacketAccessBit))
+ && (Lhs::Flags & RowMajorBit) };
+
+ template<typename DestDerived>
+ inline static void run(DestDerived& res, const ProductType& product)
+ {
+ Scalar* EIGEN_RESTRICT _lhs;
+ if (UseLhsDirectly)
+ _lhs = &product.lhs().const_cast_derived().coeffRef(0);
+ else
+ {
+ _lhs = ei_aligned_stack_new(Scalar, product.lhs().size());
+ Map<Matrix<Scalar,Lhs::SizeAtCompileTime,1> >(_lhs, product.lhs().size()) = product.lhs();
+ }
+ ei_cache_friendly_product_rowmajor_times_vector(&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
+ _lhs, product.lhs().size(), res);
+
+ if(!UseLhsDirectly) ei_aligned_stack_delete(Scalar, _lhs, product.lhs().size());
+ }
+};
+
+// discard this case which has to be handled by the default path
+// (we keep it to be sure to hit a compilation error if this is not the case)
+template<typename ProductType, int LhsRows, int RhsOrder, int RhsAccess>
+struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,NoDirectAccess,1,RhsOrder,RhsAccess>
+{};
+
+// discard this case which has to be handled by the default path
+// (we keep it to be sure to hit a compilation error if this is not the case)
+template<typename ProductType, int LhsOrder, int LhsAccess, int RhsCols>
+struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCols,ColMajor,NoDirectAccess>
+{};
+
+
+/** \internal */
+template<typename Derived>
+template<typename Lhs,typename Rhs>
+inline Derived&
+MatrixBase<Derived>::operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProduct>, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other)
+{
+ if (other._expression()._useCacheFriendlyProduct())
+ ei_cache_friendly_product_selector<Product<Lhs,Rhs,CacheFriendlyProduct> >::run(const_cast_derived(), other._expression());
+ else
+ lazyAssign(derived() + other._expression());
+ return derived();
+}
+
+template<typename Derived>
+template<typename Lhs, typename Rhs>
+inline Derived& MatrixBase<Derived>::lazyAssign(const Product<Lhs,Rhs,CacheFriendlyProduct>& product)
+{
+ if (product._useCacheFriendlyProduct())
+ {
+ setZero();
+ ei_cache_friendly_product_selector<Product<Lhs,Rhs,CacheFriendlyProduct> >::run(const_cast_derived(), product);
+ }
+ else
+ {
+ lazyAssign<Product<Lhs,Rhs,CacheFriendlyProduct> >(product);
+ }
+ return derived();
+}
+
+template<typename T> struct ei_product_copy_rhs
+{
+ typedef typename ei_meta_if<
+ (ei_traits<T>::Flags & RowMajorBit)
+ || (!(ei_traits<T>::Flags & DirectAccessBit)),
+ typename ei_plain_matrix_type_column_major<T>::type,
+ const T&
+ >::ret type;
+};
+
+template<typename T> struct ei_product_copy_lhs
+{
+ typedef typename ei_meta_if<
+ (!(int(ei_traits<T>::Flags) & DirectAccessBit)),
+ typename ei_plain_matrix_type<T>::type,
+ const T&
+ >::ret type;
+};
+
+template<typename Lhs, typename Rhs, int ProductMode>
+template<typename DestDerived>
+inline void Product<Lhs,Rhs,ProductMode>::_cacheFriendlyEvalAndAdd(DestDerived& res) const
+{
+ typedef typename ei_product_copy_lhs<_LhsNested>::type LhsCopy;
+ typedef typename ei_unref<LhsCopy>::type _LhsCopy;
+ typedef typename ei_product_copy_rhs<_RhsNested>::type RhsCopy;
+ typedef typename ei_unref<RhsCopy>::type _RhsCopy;
+ LhsCopy lhs(m_lhs);
+ RhsCopy rhs(m_rhs);
+ ei_cache_friendly_product<Scalar>(
+ rows(), cols(), lhs.cols(),
+ _LhsCopy::Flags&RowMajorBit, (const Scalar*)&(lhs.const_cast_derived().coeffRef(0,0)), lhs.stride(),
+ _RhsCopy::Flags&RowMajorBit, (const Scalar*)&(rhs.const_cast_derived().coeffRef(0,0)), rhs.stride(),
+ DestDerived::Flags&RowMajorBit, (Scalar*)&(res.coeffRef(0,0)), res.stride()
+ );
+}
+
+#endif // EIGEN_PRODUCT_H
diff --git a/extern/Eigen2/Eigen/src/Core/Redux.h b/extern/Eigen2/Eigen/src/Core/Redux.h
new file mode 100644
index 00000000000..734ef1929a4
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Redux.h
@@ -0,0 +1,117 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_REDUX_H
+#define EIGEN_REDUX_H
+
+template<typename BinaryOp, typename Derived, int Start, int Length>
+struct ei_redux_impl
+{
+ enum {
+ HalfLength = Length/2
+ };
+
+ typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
+
+ static Scalar run(const Derived &mat, const BinaryOp& func)
+ {
+ return func(
+ ei_redux_impl<BinaryOp, Derived, Start, HalfLength>::run(mat, func),
+ ei_redux_impl<BinaryOp, Derived, Start+HalfLength, Length - HalfLength>::run(mat, func));
+ }
+};
+
+template<typename BinaryOp, typename Derived, int Start>
+struct ei_redux_impl<BinaryOp, Derived, Start, 1>
+{
+ enum {
+ col = Start / Derived::RowsAtCompileTime,
+ row = Start % Derived::RowsAtCompileTime
+ };
+
+ typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
+
+ static Scalar run(const Derived &mat, const BinaryOp &)
+ {
+ return mat.coeff(row, col);
+ }
+};
+
+template<typename BinaryOp, typename Derived, int Start>
+struct ei_redux_impl<BinaryOp, Derived, Start, Dynamic>
+{
+ typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
+ static Scalar run(const Derived& mat, const BinaryOp& func)
+ {
+ ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
+ Scalar res;
+ res = mat.coeff(0,0);
+ for(int i = 1; i < mat.rows(); ++i)
+ res = func(res, mat.coeff(i, 0));
+ for(int j = 1; j < mat.cols(); ++j)
+ for(int i = 0; i < mat.rows(); ++i)
+ res = func(res, mat.coeff(i, j));
+ return res;
+ }
+};
+
+/** \returns the result of a full redux operation on the whole matrix or vector using \a func
+ *
+ * The template parameter \a BinaryOp is the type of the functor \a func which must be
+ * an assiociative operator. Both current STL and TR1 functor styles are handled.
+ *
+ * \sa MatrixBase::sum(), MatrixBase::minCoeff(), MatrixBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
+ */
+template<typename Derived>
+template<typename BinaryOp>
+typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
+MatrixBase<Derived>::redux(const BinaryOp& func) const
+{
+ const bool unroll = SizeAtCompileTime * CoeffReadCost
+ + (SizeAtCompileTime-1) * ei_functor_traits<BinaryOp>::Cost
+ <= EIGEN_UNROLLING_LIMIT;
+ return ei_redux_impl<BinaryOp, Derived, 0, unroll ? int(SizeAtCompileTime) : Dynamic>
+ ::run(derived(), func);
+}
+
+/** \returns the minimum of all coefficients of *this
+ */
+template<typename Derived>
+inline typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::minCoeff() const
+{
+ return this->redux(Eigen::ei_scalar_min_op<Scalar>());
+}
+
+/** \returns the maximum of all coefficients of *this
+ */
+template<typename Derived>
+inline typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::maxCoeff() const
+{
+ return this->redux(Eigen::ei_scalar_max_op<Scalar>());
+}
+
+#endif // EIGEN_REDUX_H
diff --git a/extern/Eigen2/Eigen/src/Core/SolveTriangular.h b/extern/Eigen2/Eigen/src/Core/SolveTriangular.h
new file mode 100644
index 00000000000..12fb0e1d159
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/SolveTriangular.h
@@ -0,0 +1,297 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SOLVETRIANGULAR_H
+#define EIGEN_SOLVETRIANGULAR_H
+
+template<typename XprType> struct ei_is_part { enum {value=false}; };
+template<typename XprType, unsigned int Mode> struct ei_is_part<Part<XprType,Mode> > { enum {value=true}; };
+
+template<typename Lhs, typename Rhs,
+ int TriangularPart = (int(Lhs::Flags) & LowerTriangularBit)
+ ? LowerTriangular
+ : (int(Lhs::Flags) & UpperTriangularBit)
+ ? UpperTriangular
+ : -1,
+ int StorageOrder = ei_is_part<Lhs>::value ? -1 // this is to solve ambiguous specializations
+ : int(Lhs::Flags) & (RowMajorBit|SparseBit)
+ >
+struct ei_solve_triangular_selector;
+
+// transform a Part xpr to a Flagged xpr
+template<typename Lhs, unsigned int LhsMode, typename Rhs, int UpLo, int StorageOrder>
+struct ei_solve_triangular_selector<Part<Lhs,LhsMode>,Rhs,UpLo,StorageOrder>
+{
+ static void run(const Part<Lhs,LhsMode>& lhs, Rhs& other)
+ {
+ ei_solve_triangular_selector<Flagged<Lhs,LhsMode,0>,Rhs>::run(lhs._expression(), other);
+ }
+};
+
+// forward substitution, row-major
+template<typename Lhs, typename Rhs, int UpLo>
+struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
+{
+ typedef typename Rhs::Scalar Scalar;
+ static void run(const Lhs& lhs, Rhs& other)
+ {
+ const bool IsLowerTriangular = (UpLo==LowerTriangular);
+ const int size = lhs.cols();
+ /* We perform the inverse product per block of 4 rows such that we perfectly match
+ * our optimized matrix * vector product. blockyStart represents the number of rows
+ * we have process first using the non-block version.
+ */
+ int blockyStart = (std::max(size-5,0)/4)*4;
+ if (IsLowerTriangular)
+ blockyStart = size - blockyStart;
+ else
+ blockyStart -= 1;
+ for(int c=0 ; c<other.cols() ; ++c)
+ {
+ // process first rows using the non block version
+ if(!(Lhs::Flags & UnitDiagBit))
+ {
+ if (IsLowerTriangular)
+ other.coeffRef(0,c) = other.coeff(0,c)/lhs.coeff(0, 0);
+ else
+ other.coeffRef(size-1,c) = other.coeff(size-1, c)/lhs.coeff(size-1, size-1);
+ }
+ for(int i=(IsLowerTriangular ? 1 : size-2); IsLowerTriangular ? i<blockyStart : i>blockyStart; i += (IsLowerTriangular ? 1 : -1) )
+ {
+ Scalar tmp = other.coeff(i,c)
+ - (IsLowerTriangular ? ((lhs.row(i).start(i)) * other.col(c).start(i)).coeff(0,0)
+ : ((lhs.row(i).end(size-i-1)) * other.col(c).end(size-i-1)).coeff(0,0));
+ if (Lhs::Flags & UnitDiagBit)
+ other.coeffRef(i,c) = tmp;
+ else
+ other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
+ }
+
+ // now let's process the remaining rows 4 at once
+ for(int i=blockyStart; IsLowerTriangular ? i<size : i>0; )
+ {
+ int startBlock = i;
+ int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
+
+ /* Process the i cols times 4 rows block, and keep the result in a temporary vector */
+ // FIXME use fixed size block but take care to small fixed size matrices...
+ Matrix<Scalar,Dynamic,1> btmp(4);
+ if (IsLowerTriangular)
+ btmp = lhs.block(startBlock,0,4,i) * other.col(c).start(i);
+ else
+ btmp = lhs.block(i-3,i+1,4,size-1-i) * other.col(c).end(size-1-i);
+
+ /* Let's process the 4x4 sub-matrix as usual.
+ * btmp stores the diagonal coefficients used to update the remaining part of the result.
+ */
+ {
+ Scalar tmp = other.coeff(startBlock,c)-btmp.coeff(IsLowerTriangular?0:3);
+ if (Lhs::Flags & UnitDiagBit)
+ other.coeffRef(i,c) = tmp;
+ else
+ other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
+ }
+
+ i += IsLowerTriangular ? 1 : -1;
+ for (;IsLowerTriangular ? i<endBlock : i>endBlock; i += IsLowerTriangular ? 1 : -1)
+ {
+ int remainingSize = IsLowerTriangular ? i-startBlock : startBlock-i;
+ Scalar tmp = other.coeff(i,c)
+ - btmp.coeff(IsLowerTriangular ? remainingSize : 3-remainingSize)
+ - ( lhs.row(i).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)
+ * other.col(c).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)).coeff(0,0);
+
+ if (Lhs::Flags & UnitDiagBit)
+ other.coeffRef(i,c) = tmp;
+ else
+ other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
+ }
+ }
+ }
+ }
+};
+
+// Implements the following configurations:
+// - inv(LowerTriangular, ColMajor) * Column vector
+// - inv(LowerTriangular,UnitDiag,ColMajor) * Column vector
+// - inv(UpperTriangular, ColMajor) * Column vector
+// - inv(UpperTriangular,UnitDiag,ColMajor) * Column vector
+template<typename Lhs, typename Rhs, int UpLo>
+struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
+{
+ typedef typename Rhs::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+ enum { PacketSize = ei_packet_traits<Scalar>::size };
+
+ static void run(const Lhs& lhs, Rhs& other)
+ {
+ static const bool IsLowerTriangular = (UpLo==LowerTriangular);
+ const int size = lhs.cols();
+ for(int c=0 ; c<other.cols() ; ++c)
+ {
+ /* let's perform the inverse product per block of 4 columns such that we perfectly match
+ * our optimized matrix * vector product. blockyEnd represents the number of rows
+ * we can process using the block version.
+ */
+ int blockyEnd = (std::max(size-5,0)/4)*4;
+ if (!IsLowerTriangular)
+ blockyEnd = size-1 - blockyEnd;
+ for(int i=IsLowerTriangular ? 0 : size-1; IsLowerTriangular ? i<blockyEnd : i>blockyEnd;)
+ {
+ /* Let's process the 4x4 sub-matrix as usual.
+ * btmp stores the diagonal coefficients used to update the remaining part of the result.
+ */
+ int startBlock = i;
+ int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
+ Matrix<Scalar,4,1> btmp;
+ for (;IsLowerTriangular ? i<endBlock : i>endBlock;
+ i += IsLowerTriangular ? 1 : -1)
+ {
+ if(!(Lhs::Flags & UnitDiagBit))
+ other.coeffRef(i,c) /= lhs.coeff(i,i);
+ int remainingSize = IsLowerTriangular ? endBlock-i-1 : i-endBlock-1;
+ if (remainingSize>0)
+ other.col(c).segment((IsLowerTriangular ? i : endBlock) + 1, remainingSize) -=
+ other.coeffRef(i,c)
+ * Block<Lhs,Dynamic,1>(lhs, (IsLowerTriangular ? i : endBlock) + 1, i, remainingSize, 1);
+ btmp.coeffRef(IsLowerTriangular ? i-startBlock : remainingSize) = -other.coeffRef(i,c);
+ }
+
+ /* Now we can efficiently update the remaining part of the result as a matrix * vector product.
+ * NOTE in order to reduce both compilation time and binary size, let's directly call
+ * the fast product implementation. It is equivalent to the following code:
+ * other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
+ * * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
+ */
+ // FIXME this is cool but what about conjugate/adjoint expressions ? do we want to evaluate them ?
+ // this is a more general problem though.
+ ei_cache_friendly_product_colmajor_times_vector(
+ IsLowerTriangular ? size-endBlock : endBlock+1,
+ &(lhs.const_cast_derived().coeffRef(IsLowerTriangular ? endBlock : 0, IsLowerTriangular ? startBlock : endBlock+1)),
+ lhs.stride(),
+ btmp, &(other.coeffRef(IsLowerTriangular ? endBlock : 0, c)));
+// if (IsLowerTriangular)
+// other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
+// * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
+// else
+// other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
+// * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
+ }
+
+ /* Now we have to process the remaining part as usual */
+ int i;
+ for(i=blockyEnd; IsLowerTriangular ? i<size-1 : i>0; i += (IsLowerTriangular ? 1 : -1) )
+ {
+ if(!(Lhs::Flags & UnitDiagBit))
+ other.coeffRef(i,c) /= lhs.coeff(i,i);
+
+ /* NOTE we cannot use lhs.col(i).end(size-i-1) because Part::coeffRef gets called by .col() to
+ * get the address of the start of the row
+ */
+ if(IsLowerTriangular)
+ other.col(c).end(size-i-1) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, i+1,i, size-i-1,1);
+ else
+ other.col(c).start(i) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, 0,i, i, 1);
+ }
+ if(!(Lhs::Flags & UnitDiagBit))
+ other.coeffRef(i,c) /= lhs.coeff(i,i);
+ }
+ }
+};
+
+/** "in-place" version of MatrixBase::solveTriangular() where the result is written in \a other
+ *
+ * \nonstableyet
+ *
+ * The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
+ * This function will const_cast it, so constness isn't honored here.
+ *
+ * See MatrixBase:solveTriangular() for the details.
+ */
+template<typename Derived>
+template<typename OtherDerived>
+void MatrixBase<Derived>::solveTriangularInPlace(const MatrixBase<OtherDerived>& _other) const
+{
+ MatrixBase<OtherDerived>& other = _other.const_cast_derived();
+ ei_assert(derived().cols() == derived().rows());
+ ei_assert(derived().cols() == other.rows());
+ ei_assert(!(Flags & ZeroDiagBit));
+ ei_assert(Flags & (UpperTriangularBit|LowerTriangularBit));
+
+ enum { copy = ei_traits<OtherDerived>::Flags & RowMajorBit };
+
+ typedef typename ei_meta_if<copy,
+ typename ei_plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy;
+ OtherCopy otherCopy(other.derived());
+
+ ei_solve_triangular_selector<Derived, typename ei_unref<OtherCopy>::type>::run(derived(), otherCopy);
+
+ if (copy)
+ other = otherCopy;
+}
+
+/** \returns the product of the inverse of \c *this with \a other, \a *this being triangular.
+ *
+ * \nonstableyet
+ *
+ * This function computes the inverse-matrix matrix product inverse(\c *this) * \a other.
+ * The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
+ * diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
+ * is an upper (resp. lower) triangular matrix.
+ *
+ * It is required that \c *this be marked as either an upper or a lower triangular matrix, which
+ * can be done by marked(), and that is automatically the case with expressions such as those returned
+ * by extract().
+ *
+ * \addexample SolveTriangular \label How to solve a triangular system (aka. how to multiply the inverse of a triangular matrix by another one)
+ *
+ * Example: \include MatrixBase_marked.cpp
+ * Output: \verbinclude MatrixBase_marked.out
+ *
+ * This function is essentially a wrapper to the faster solveTriangularInPlace() function creating
+ * a temporary copy of \a other, calling solveTriangularInPlace() on the copy and returning it.
+ * Therefore, if \a other is not needed anymore, it is quite faster to call solveTriangularInPlace()
+ * instead of solveTriangular().
+ *
+ * For users coming from BLAS, this function (and more specifically solveTriangularInPlace()) offer
+ * all the operations supported by the \c *TRSV and \c *TRSM BLAS routines.
+ *
+ * \b Tips: to perform a \em "right-inverse-multiply" you can simply transpose the operation, e.g.:
+ * \code
+ * M * T^1 <=> T.transpose().solveTriangularInPlace(M.transpose());
+ * \endcode
+ *
+ * \sa solveTriangularInPlace(), marked(), extract()
+ */
+template<typename Derived>
+template<typename OtherDerived>
+typename ei_plain_matrix_type_column_major<OtherDerived>::type
+MatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other) const
+{
+ typename ei_plain_matrix_type_column_major<OtherDerived>::type res(other);
+ solveTriangularInPlace(res);
+ return res;
+}
+
+#endif // EIGEN_SOLVETRIANGULAR_H
diff --git a/extern/Eigen2/Eigen/src/Core/Sum.h b/extern/Eigen2/Eigen/src/Core/Sum.h
new file mode 100644
index 00000000000..6d7e9959fa5
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Sum.h
@@ -0,0 +1,271 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SUM_H
+#define EIGEN_SUM_H
+
+/***************************************************************************
+* Part 1 : the logic deciding a strategy for vectorization and unrolling
+***************************************************************************/
+
+template<typename Derived>
+struct ei_sum_traits
+{
+private:
+ enum {
+ PacketSize = ei_packet_traits<typename Derived::Scalar>::size
+ };
+
+public:
+ enum {
+ Vectorization = (int(Derived::Flags)&ActualPacketAccessBit)
+ && (int(Derived::Flags)&LinearAccessBit)
+ ? LinearVectorization
+ : NoVectorization
+ };
+
+private:
+ enum {
+ Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost
+ + (Derived::SizeAtCompileTime-1) * NumTraits<typename Derived::Scalar>::AddCost,
+ UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
+ };
+
+public:
+ enum {
+ Unrolling = Cost <= UnrollingLimit
+ ? CompleteUnrolling
+ : NoUnrolling
+ };
+};
+
+/***************************************************************************
+* Part 2 : unrollers
+***************************************************************************/
+
+/*** no vectorization ***/
+
+template<typename Derived, int Start, int Length>
+struct ei_sum_novec_unroller
+{
+ enum {
+ HalfLength = Length/2
+ };
+
+ typedef typename Derived::Scalar Scalar;
+
+ inline static Scalar run(const Derived &mat)
+ {
+ return ei_sum_novec_unroller<Derived, Start, HalfLength>::run(mat)
+ + ei_sum_novec_unroller<Derived, Start+HalfLength, Length-HalfLength>::run(mat);
+ }
+};
+
+template<typename Derived, int Start>
+struct ei_sum_novec_unroller<Derived, Start, 1>
+{
+ enum {
+ col = Start / Derived::RowsAtCompileTime,
+ row = Start % Derived::RowsAtCompileTime
+ };
+
+ typedef typename Derived::Scalar Scalar;
+
+ inline static Scalar run(const Derived &mat)
+ {
+ return mat.coeff(row, col);
+ }
+};
+
+/*** vectorization ***/
+
+template<typename Derived, int Start, int Length>
+struct ei_sum_vec_unroller
+{
+ enum {
+ PacketSize = ei_packet_traits<typename Derived::Scalar>::size,
+ HalfLength = Length/2
+ };
+
+ typedef typename Derived::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+
+ inline static PacketScalar run(const Derived &mat)
+ {
+ return ei_padd(
+ ei_sum_vec_unroller<Derived, Start, HalfLength>::run(mat),
+ ei_sum_vec_unroller<Derived, Start+HalfLength, Length-HalfLength>::run(mat) );
+ }
+};
+
+template<typename Derived, int Start>
+struct ei_sum_vec_unroller<Derived, Start, 1>
+{
+ enum {
+ index = Start * ei_packet_traits<typename Derived::Scalar>::size,
+ row = int(Derived::Flags)&RowMajorBit
+ ? index / int(Derived::ColsAtCompileTime)
+ : index % Derived::RowsAtCompileTime,
+ col = int(Derived::Flags)&RowMajorBit
+ ? index % int(Derived::ColsAtCompileTime)
+ : index / Derived::RowsAtCompileTime,
+ alignment = (Derived::Flags & AlignedBit) ? Aligned : Unaligned
+ };
+
+ typedef typename Derived::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+
+ inline static PacketScalar run(const Derived &mat)
+ {
+ return mat.template packet<alignment>(row, col);
+ }
+};
+
+/***************************************************************************
+* Part 3 : implementation of all cases
+***************************************************************************/
+
+template<typename Derived,
+ int Vectorization = ei_sum_traits<Derived>::Vectorization,
+ int Unrolling = ei_sum_traits<Derived>::Unrolling
+>
+struct ei_sum_impl;
+
+template<typename Derived>
+struct ei_sum_impl<Derived, NoVectorization, NoUnrolling>
+{
+ typedef typename Derived::Scalar Scalar;
+ static Scalar run(const Derived& mat)
+ {
+ ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
+ Scalar res;
+ res = mat.coeff(0, 0);
+ for(int i = 1; i < mat.rows(); ++i)
+ res += mat.coeff(i, 0);
+ for(int j = 1; j < mat.cols(); ++j)
+ for(int i = 0; i < mat.rows(); ++i)
+ res += mat.coeff(i, j);
+ return res;
+ }
+};
+
+template<typename Derived>
+struct ei_sum_impl<Derived, NoVectorization, CompleteUnrolling>
+ : public ei_sum_novec_unroller<Derived, 0, Derived::SizeAtCompileTime>
+{};
+
+template<typename Derived>
+struct ei_sum_impl<Derived, LinearVectorization, NoUnrolling>
+{
+ typedef typename Derived::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+
+ static Scalar run(const Derived& mat)
+ {
+ const int size = mat.size();
+ const int packetSize = ei_packet_traits<Scalar>::size;
+ const int alignedStart = (Derived::Flags & AlignedBit)
+ || !(Derived::Flags & DirectAccessBit)
+ ? 0
+ : ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size);
+ enum {
+ alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit)
+ ? Aligned : Unaligned
+ };
+ const int alignedSize = ((size-alignedStart)/packetSize)*packetSize;
+ const int alignedEnd = alignedStart + alignedSize;
+ Scalar res;
+
+ if(alignedSize)
+ {
+ PacketScalar packet_res = mat.template packet<alignment>(alignedStart);
+ for(int index = alignedStart + packetSize; index < alignedEnd; index += packetSize)
+ packet_res = ei_padd(packet_res, mat.template packet<alignment>(index));
+ res = ei_predux(packet_res);
+ }
+ else // too small to vectorize anything.
+ // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
+ {
+ res = Scalar(0);
+ }
+
+ for(int index = 0; index < alignedStart; ++index)
+ res += mat.coeff(index);
+
+ for(int index = alignedEnd; index < size; ++index)
+ res += mat.coeff(index);
+
+ return res;
+ }
+};
+
+template<typename Derived>
+struct ei_sum_impl<Derived, LinearVectorization, CompleteUnrolling>
+{
+ typedef typename Derived::Scalar Scalar;
+ typedef typename ei_packet_traits<Scalar>::type PacketScalar;
+ enum {
+ PacketSize = ei_packet_traits<Scalar>::size,
+ Size = Derived::SizeAtCompileTime,
+ VectorizationSize = (Size / PacketSize) * PacketSize
+ };
+ static Scalar run(const Derived& mat)
+ {
+ Scalar res = ei_predux(ei_sum_vec_unroller<Derived, 0, Size / PacketSize>::run(mat));
+ if (VectorizationSize != Size)
+ res += ei_sum_novec_unroller<Derived, VectorizationSize, Size-VectorizationSize>::run(mat);
+ return res;
+ }
+};
+
+/***************************************************************************
+* Part 4 : implementation of MatrixBase methods
+***************************************************************************/
+
+/** \returns the sum of all coefficients of *this
+ *
+ * \sa trace()
+ */
+template<typename Derived>
+inline typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::sum() const
+{
+ return ei_sum_impl<Derived>::run(derived());
+}
+
+/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal.
+ *
+ * \c *this can be any matrix, not necessarily square.
+ *
+ * \sa diagonal(), sum()
+ */
+template<typename Derived>
+inline typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::trace() const
+{
+ return diagonal().sum();
+}
+
+#endif // EIGEN_SUM_H
diff --git a/extern/Eigen2/Eigen/src/Core/Swap.h b/extern/Eigen2/Eigen/src/Core/Swap.h
new file mode 100644
index 00000000000..77d562cd3ac
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Swap.h
@@ -0,0 +1,142 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SWAP_H
+#define EIGEN_SWAP_H
+
+/** \class SwapWrapper
+ *
+ * \internal
+ *
+ * \brief Internal helper class for swapping two expressions
+ */
+template<typename ExpressionType>
+struct ei_traits<SwapWrapper<ExpressionType> >
+{
+ typedef typename ExpressionType::Scalar Scalar;
+ enum {
+ RowsAtCompileTime = ExpressionType::RowsAtCompileTime,
+ ColsAtCompileTime = ExpressionType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime,
+ Flags = ExpressionType::Flags,
+ CoeffReadCost = ExpressionType::CoeffReadCost
+ };
+};
+
+template<typename ExpressionType> class SwapWrapper
+ : public MatrixBase<SwapWrapper<ExpressionType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(SwapWrapper)
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+
+ inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {}
+
+ inline int rows() const { return m_expression.rows(); }
+ inline int cols() const { return m_expression.cols(); }
+ inline int stride() const { return m_expression.stride(); }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_expression.const_cast_derived().coeffRef(row, col);
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_expression.const_cast_derived().coeffRef(index);
+ }
+
+ template<typename OtherDerived>
+ void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ Scalar tmp = m_expression.coeff(row, col);
+ m_expression.coeffRef(row, col) = _other.coeff(row, col);
+ _other.coeffRef(row, col) = tmp;
+ }
+
+ template<typename OtherDerived>
+ void copyCoeff(int index, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(index >= 0 && index < m_expression.size());
+ Scalar tmp = m_expression.coeff(index);
+ m_expression.coeffRef(index) = _other.coeff(index);
+ _other.coeffRef(index) = tmp;
+ }
+
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ Packet tmp = m_expression.template packet<StoreMode>(row, col);
+ m_expression.template writePacket<StoreMode>(row, col,
+ _other.template packet<LoadMode>(row, col)
+ );
+ _other.template writePacket<LoadMode>(row, col, tmp);
+ }
+
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ void copyPacket(int index, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(index >= 0 && index < m_expression.size());
+ Packet tmp = m_expression.template packet<StoreMode>(index);
+ m_expression.template writePacket<StoreMode>(index,
+ _other.template packet<LoadMode>(index)
+ );
+ _other.template writePacket<LoadMode>(index, tmp);
+ }
+
+ protected:
+ ExpressionType& m_expression;
+};
+
+/** swaps *this with the expression \a other.
+ *
+ * \note \a other is only marked for internal reasons, but of course
+ * it gets const-casted. One reason is that one will often call swap
+ * on temporary objects (hence non-const references are forbidden).
+ * Another reason is that lazyAssign takes a const argument anyway.
+ */
+template<typename Derived>
+template<typename OtherDerived>
+void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
+{
+ (SwapWrapper<Derived>(derived())).lazyAssign(other);
+}
+
+#endif // EIGEN_SWAP_H
+
+
+
+
+
+
diff --git a/extern/Eigen2/Eigen/src/Core/Transpose.h b/extern/Eigen2/Eigen/src/Core/Transpose.h
new file mode 100644
index 00000000000..870edfe320b
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Transpose.h
@@ -0,0 +1,228 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_TRANSPOSE_H
+#define EIGEN_TRANSPOSE_H
+
+/** \class Transpose
+ *
+ * \brief Expression of the transpose of a matrix
+ *
+ * \param MatrixType the type of the object of which we are taking the transpose
+ *
+ * This class represents an expression of the transpose of a matrix.
+ * It is the return type of MatrixBase::transpose() and MatrixBase::adjoint()
+ * and most of the time this is the only way it is used.
+ *
+ * \sa MatrixBase::transpose(), MatrixBase::adjoint()
+ */
+template<typename MatrixType>
+struct ei_traits<Transpose<MatrixType> >
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ RowsAtCompileTime = MatrixType::ColsAtCompileTime,
+ ColsAtCompileTime = MatrixType::RowsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ Flags = ((int(_MatrixTypeNested::Flags) ^ RowMajorBit)
+ & ~(LowerTriangularBit | UpperTriangularBit))
+ | (int(_MatrixTypeNested::Flags)&UpperTriangularBit ? LowerTriangularBit : 0)
+ | (int(_MatrixTypeNested::Flags)&LowerTriangularBit ? UpperTriangularBit : 0),
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost
+ };
+};
+
+template<typename MatrixType> class Transpose
+ : public MatrixBase<Transpose<MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
+
+ inline Transpose(const MatrixType& matrix) : m_matrix(matrix) {}
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
+
+ inline int rows() const { return m_matrix.cols(); }
+ inline int cols() const { return m_matrix.rows(); }
+ inline int nonZeros() const { return m_matrix.nonZeros(); }
+ inline int stride(void) const { return m_matrix.stride(); }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived().coeffRef(col, row);
+ }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_matrix.coeff(col, row);
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ return m_matrix.coeff(index);
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived().coeffRef(index);
+ }
+
+ template<int LoadMode>
+ inline const PacketScalar packet(int row, int col) const
+ {
+ return m_matrix.template packet<LoadMode>(col, row);
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int row, int col, const PacketScalar& x)
+ {
+ m_matrix.const_cast_derived().template writePacket<LoadMode>(col, row, x);
+ }
+
+ template<int LoadMode>
+ inline const PacketScalar packet(int index) const
+ {
+ return m_matrix.template packet<LoadMode>(index);
+ }
+
+ template<int LoadMode>
+ inline void writePacket(int index, const PacketScalar& x)
+ {
+ m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x);
+ }
+
+ protected:
+ const typename MatrixType::Nested m_matrix;
+};
+
+/** \returns an expression of the transpose of *this.
+ *
+ * Example: \include MatrixBase_transpose.cpp
+ * Output: \verbinclude MatrixBase_transpose.out
+ *
+ * \warning If you want to replace a matrix by its own transpose, do \b NOT do this:
+ * \code
+ * m = m.transpose(); // bug!!! caused by aliasing effect
+ * \endcode
+ * Instead, use the transposeInPlace() method:
+ * \code
+ * m.transposeInPlace();
+ * \endcode
+ * which gives Eigen good opportunities for optimization, or alternatively you can also do:
+ * \code
+ * m = m.transpose().eval();
+ * \endcode
+ *
+ * \sa transposeInPlace(), adjoint() */
+template<typename Derived>
+inline Transpose<Derived>
+MatrixBase<Derived>::transpose()
+{
+ return derived();
+}
+
+/** This is the const version of transpose().
+ *
+ * Make sure you read the warning for transpose() !
+ *
+ * \sa transposeInPlace(), adjoint() */
+template<typename Derived>
+inline const Transpose<Derived>
+MatrixBase<Derived>::transpose() const
+{
+ return derived();
+}
+
+/** \returns an expression of the adjoint (i.e. conjugate transpose) of *this.
+ *
+ * Example: \include MatrixBase_adjoint.cpp
+ * Output: \verbinclude MatrixBase_adjoint.out
+ *
+ * \warning If you want to replace a matrix by its own adjoint, do \b NOT do this:
+ * \code
+ * m = m.adjoint(); // bug!!! caused by aliasing effect
+ * \endcode
+ * Instead, do:
+ * \code
+ * m = m.adjoint().eval();
+ * \endcode
+ *
+ * \sa transpose(), conjugate(), class Transpose, class ei_scalar_conjugate_op */
+template<typename Derived>
+inline const typename MatrixBase<Derived>::AdjointReturnType
+MatrixBase<Derived>::adjoint() const
+{
+ return conjugate().nestByValue();
+}
+
+/***************************************************************************
+* "in place" transpose implementation
+***************************************************************************/
+
+template<typename MatrixType,
+ bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic>
+struct ei_inplace_transpose_selector;
+
+template<typename MatrixType>
+struct ei_inplace_transpose_selector<MatrixType,true> { // square matrix
+ static void run(MatrixType& m) {
+ m.template part<StrictlyUpperTriangular>().swap(m.transpose());
+ }
+};
+
+template<typename MatrixType>
+struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
+ static void run(MatrixType& m) {
+ if (m.rows()==m.cols())
+ m.template part<StrictlyUpperTriangular>().swap(m.transpose());
+ else
+ m = m.transpose().eval();
+ }
+};
+
+/** This is the "in place" version of transpose: it transposes \c *this.
+ *
+ * In most cases it is probably better to simply use the transposed expression
+ * of a matrix. However, when transposing the matrix data itself is really needed,
+ * then this "in-place" version is probably the right choice because it provides
+ * the following additional features:
+ * - less error prone: doing the same operation with .transpose() requires special care:
+ * \code m = m.transpose().eval(); \endcode
+ * - no temporary object is created (currently only for squared matrices)
+ * - it allows future optimizations (cache friendliness, etc.)
+ *
+ * \note if the matrix is not square, then \c *this must be a resizable matrix.
+ *
+ * \sa transpose(), adjoint() */
+template<typename Derived>
+inline void MatrixBase<Derived>::transposeInPlace()
+{
+ ei_inplace_transpose_selector<Derived>::run(derived());
+}
+
+#endif // EIGEN_TRANSPOSE_H
diff --git a/extern/Eigen2/Eigen/src/Core/Visitor.h b/extern/Eigen2/Eigen/src/Core/Visitor.h
new file mode 100644
index 00000000000..7569114e90d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/Visitor.h
@@ -0,0 +1,228 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_VISITOR_H
+#define EIGEN_VISITOR_H
+
+template<typename Visitor, typename Derived, int UnrollCount>
+struct ei_visitor_impl
+{
+ enum {
+ col = (UnrollCount-1) / Derived::RowsAtCompileTime,
+ row = (UnrollCount-1) % Derived::RowsAtCompileTime
+ };
+
+ inline static void run(const Derived &mat, Visitor& visitor)
+ {
+ ei_visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
+ visitor(mat.coeff(row, col), row, col);
+ }
+};
+
+template<typename Visitor, typename Derived>
+struct ei_visitor_impl<Visitor, Derived, 1>
+{
+ inline static void run(const Derived &mat, Visitor& visitor)
+ {
+ return visitor.init(mat.coeff(0, 0), 0, 0);
+ }
+};
+
+template<typename Visitor, typename Derived>
+struct ei_visitor_impl<Visitor, Derived, Dynamic>
+{
+ inline static void run(const Derived& mat, Visitor& visitor)
+ {
+ visitor.init(mat.coeff(0,0), 0, 0);
+ for(int i = 1; i < mat.rows(); ++i)
+ visitor(mat.coeff(i, 0), i, 0);
+ for(int j = 1; j < mat.cols(); ++j)
+ for(int i = 0; i < mat.rows(); ++i)
+ visitor(mat.coeff(i, j), i, j);
+ }
+};
+
+
+/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
+ *
+ * The template parameter \a Visitor is the type of the visitor and provides the following interface:
+ * \code
+ * struct MyVisitor {
+ * // called for the first coefficient
+ * void init(const Scalar& value, int i, int j);
+ * // called for all other coefficients
+ * void operator() (const Scalar& value, int i, int j);
+ * };
+ * \endcode
+ *
+ * \note compared to one or two \em for \em loops, visitors offer automatic
+ * unrolling for small fixed size matrix.
+ *
+ * \sa minCoeff(int*,int*), maxCoeff(int*,int*), MatrixBase::redux()
+ */
+template<typename Derived>
+template<typename Visitor>
+void MatrixBase<Derived>::visit(Visitor& visitor) const
+{
+ const bool unroll = SizeAtCompileTime * CoeffReadCost
+ + (SizeAtCompileTime-1) * ei_functor_traits<Visitor>::Cost
+ <= EIGEN_UNROLLING_LIMIT;
+ return ei_visitor_impl<Visitor, Derived,
+ unroll ? int(SizeAtCompileTime) : Dynamic
+ >::run(derived(), visitor);
+}
+
+/** \internal
+ * \brief Base class to implement min and max visitors
+ */
+template <typename Scalar>
+struct ei_coeff_visitor
+{
+ int row, col;
+ Scalar res;
+ inline void init(const Scalar& value, int i, int j)
+ {
+ res = value;
+ row = i;
+ col = j;
+ }
+};
+
+/** \internal
+ * \brief Visitor computing the min coefficient with its value and coordinates
+ *
+ * \sa MatrixBase::minCoeff(int*, int*)
+ */
+template <typename Scalar>
+struct ei_min_coeff_visitor : ei_coeff_visitor<Scalar>
+{
+ void operator() (const Scalar& value, int i, int j)
+ {
+ if(value < this->res)
+ {
+ this->res = value;
+ this->row = i;
+ this->col = j;
+ }
+ }
+};
+
+template<typename Scalar>
+struct ei_functor_traits<ei_min_coeff_visitor<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost
+ };
+};
+
+/** \internal
+ * \brief Visitor computing the max coefficient with its value and coordinates
+ *
+ * \sa MatrixBase::maxCoeff(int*, int*)
+ */
+template <typename Scalar>
+struct ei_max_coeff_visitor : ei_coeff_visitor<Scalar>
+{
+ void operator() (const Scalar& value, int i, int j)
+ {
+ if(value > this->res)
+ {
+ this->res = value;
+ this->row = i;
+ this->col = j;
+ }
+ }
+};
+
+template<typename Scalar>
+struct ei_functor_traits<ei_max_coeff_visitor<Scalar> > {
+ enum {
+ Cost = NumTraits<Scalar>::AddCost
+ };
+};
+
+/** \returns the minimum of all coefficients of *this
+ * and puts in *row and *col its location.
+ *
+ * \sa MatrixBase::minCoeff(int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::minCoeff(int* row, int* col) const
+{
+ ei_min_coeff_visitor<Scalar> minVisitor;
+ this->visit(minVisitor);
+ *row = minVisitor.row;
+ if (col) *col = minVisitor.col;
+ return minVisitor.res;
+}
+
+/** \returns the minimum of all coefficients of *this
+ * and puts in *index its location.
+ *
+ * \sa MatrixBase::minCoeff(int*,int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::minCoeff(int* index) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ ei_min_coeff_visitor<Scalar> minVisitor;
+ this->visit(minVisitor);
+ *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
+ return minVisitor.res;
+}
+
+/** \returns the maximum of all coefficients of *this
+ * and puts in *row and *col its location.
+ *
+ * \sa MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::maxCoeff(int* row, int* col) const
+{
+ ei_max_coeff_visitor<Scalar> maxVisitor;
+ this->visit(maxVisitor);
+ *row = maxVisitor.row;
+ if (col) *col = maxVisitor.col;
+ return maxVisitor.res;
+}
+
+/** \returns the maximum of all coefficients of *this
+ * and puts in *index its location.
+ *
+ * \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::maxCoeff(int* index) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ ei_max_coeff_visitor<Scalar> maxVisitor;
+ this->visit(maxVisitor);
+ *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
+ return maxVisitor.res;
+}
+
+#endif // EIGEN_VISITOR_H
diff --git a/extern/Eigen2/Eigen/src/Core/arch/AltiVec/PacketMath.h b/extern/Eigen2/Eigen/src/Core/arch/AltiVec/PacketMath.h
new file mode 100644
index 00000000000..4de3b5e2e0b
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -0,0 +1,354 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Konstantinos Margaritis <markos@codex.gr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_PACKET_MATH_ALTIVEC_H
+#define EIGEN_PACKET_MATH_ALTIVEC_H
+
+#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
+#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 4
+#endif
+
+typedef __vector float v4f;
+typedef __vector int v4i;
+typedef __vector unsigned int v4ui;
+typedef __vector __bool int v4bi;
+
+// We don't want to write the same code all the time, but we need to reuse the constants
+// and it doesn't really work to declare them global, so we define macros instead
+
+#define USE_CONST_v0i const v4i v0i = vec_splat_s32(0)
+#define USE_CONST_v1i const v4i v1i = vec_splat_s32(1)
+#define USE_CONST_v16i_ const v4i v16i_ = vec_splat_s32(-16)
+#define USE_CONST_v0f USE_CONST_v0i; const v4f v0f = (v4f) v0i
+#define USE_CONST_v1f USE_CONST_v1i; const v4f v1f = vec_ctf(v1i, 0)
+#define USE_CONST_v1i_ const v4ui v1i_ = vec_splat_u32(-1)
+#define USE_CONST_v0f_ USE_CONST_v1i_; const v4f v0f_ = (v4f) vec_sl(v1i_, v1i_)
+
+template<> struct ei_packet_traits<float> { typedef v4f type; enum {size=4}; };
+template<> struct ei_packet_traits<int> { typedef v4i type; enum {size=4}; };
+
+template<> struct ei_unpacket_traits<v4f> { typedef float type; enum {size=4}; };
+template<> struct ei_unpacket_traits<v4i> { typedef int type; enum {size=4}; };
+
+inline std::ostream & operator <<(std::ostream & s, const v4f & v)
+{
+ union {
+ v4f v;
+ float n[4];
+ } vt;
+ vt.v = v;
+ s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3];
+ return s;
+}
+
+inline std::ostream & operator <<(std::ostream & s, const v4i & v)
+{
+ union {
+ v4i v;
+ int n[4];
+ } vt;
+ vt.v = v;
+ s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3];
+ return s;
+}
+
+inline std::ostream & operator <<(std::ostream & s, const v4ui & v)
+{
+ union {
+ v4ui v;
+ unsigned int n[4];
+ } vt;
+ vt.v = v;
+ s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3];
+ return s;
+}
+
+inline std::ostream & operator <<(std::ostream & s, const v4bi & v)
+{
+ union {
+ __vector __bool int v;
+ unsigned int n[4];
+ } vt;
+ vt.v = v;
+ s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3];
+ return s;
+}
+
+template<> inline v4f ei_padd(const v4f& a, const v4f& b) { return vec_add(a,b); }
+template<> inline v4i ei_padd(const v4i& a, const v4i& b) { return vec_add(a,b); }
+
+template<> inline v4f ei_psub(const v4f& a, const v4f& b) { return vec_sub(a,b); }
+template<> inline v4i ei_psub(const v4i& a, const v4i& b) { return vec_sub(a,b); }
+
+template<> inline v4f ei_pmul(const v4f& a, const v4f& b) { USE_CONST_v0f; return vec_madd(a,b, v0f); }
+template<> inline v4i ei_pmul(const v4i& a, const v4i& b)
+{
+ // Detailed in: http://freevec.org/content/32bit_signed_integer_multiplication_altivec
+ //Set up constants, variables
+ v4i a1, b1, bswap, low_prod, high_prod, prod, prod_, v1sel;
+ USE_CONST_v0i;
+ USE_CONST_v1i;
+ USE_CONST_v16i_;
+
+ // Get the absolute values
+ a1 = vec_abs(a);
+ b1 = vec_abs(b);
+
+ // Get the signs using xor
+ v4bi sgn = (v4bi) vec_cmplt(vec_xor(a, b), v0i);
+
+ // Do the multiplication for the asbolute values.
+ bswap = (v4i) vec_rl((v4ui) b1, (v4ui) v16i_ );
+ low_prod = vec_mulo((__vector short)a1, (__vector short)b1);
+ high_prod = vec_msum((__vector short)a1, (__vector short)bswap, v0i);
+ high_prod = (v4i) vec_sl((v4ui) high_prod, (v4ui) v16i_);
+ prod = vec_add( low_prod, high_prod );
+
+ // NOR the product and select only the negative elements according to the sign mask
+ prod_ = vec_nor(prod, prod);
+ prod_ = vec_sel(v0i, prod_, sgn);
+
+ // Add 1 to the result to get the negative numbers
+ v1sel = vec_sel(v0i, v1i, sgn);
+ prod_ = vec_add(prod_, v1sel);
+
+ // Merge the results back to the final vector.
+ prod = vec_sel(prod, prod_, sgn);
+
+ return prod;
+}
+
+template<> inline v4f ei_pdiv(const v4f& a, const v4f& b) {
+ v4f t, y_0, y_1, res;
+ USE_CONST_v0f;
+ USE_CONST_v1f;
+
+ // Altivec does not offer a divide instruction, we have to do a reciprocal approximation
+ y_0 = vec_re(b);
+
+ // Do one Newton-Raphson iteration to get the needed accuracy
+ t = vec_nmsub(y_0, b, v1f);
+ y_1 = vec_madd(y_0, t, y_0);
+
+ res = vec_madd(a, y_1, v0f);
+ return res;
+}
+
+template<> inline v4f ei_pmadd(const v4f& a, const v4f& b, const v4f& c) { return vec_madd(a, b, c); }
+
+template<> inline v4f ei_pmin(const v4f& a, const v4f& b) { return vec_min(a,b); }
+template<> inline v4i ei_pmin(const v4i& a, const v4i& b) { return vec_min(a,b); }
+
+template<> inline v4f ei_pmax(const v4f& a, const v4f& b) { return vec_max(a,b); }
+template<> inline v4i ei_pmax(const v4i& a, const v4i& b) { return vec_max(a,b); }
+
+template<> inline v4f ei_pload(const float* from) { return vec_ld(0, from); }
+template<> inline v4i ei_pload(const int* from) { return vec_ld(0, from); }
+
+template<> inline v4f ei_ploadu(const float* from)
+{
+ // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html
+ __vector unsigned char MSQ, LSQ;
+ __vector unsigned char mask;
+ MSQ = vec_ld(0, (unsigned char *)from); // most significant quadword
+ LSQ = vec_ld(15, (unsigned char *)from); // least significant quadword
+ mask = vec_lvsl(0, from); // create the permute mask
+ return (v4f) vec_perm(MSQ, LSQ, mask); // align the data
+}
+
+template<> inline v4i ei_ploadu(const int* from)
+{
+ // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html
+ __vector unsigned char MSQ, LSQ;
+ __vector unsigned char mask;
+ MSQ = vec_ld(0, (unsigned char *)from); // most significant quadword
+ LSQ = vec_ld(15, (unsigned char *)from); // least significant quadword
+ mask = vec_lvsl(0, from); // create the permute mask
+ return (v4i) vec_perm(MSQ, LSQ, mask); // align the data
+}
+
+template<> inline v4f ei_pset1(const float& from)
+{
+ // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html
+ float __attribute__(aligned(16)) af[4];
+ af[0] = from;
+ v4f vc = vec_ld(0, af);
+ vc = vec_splat(vc, 0);
+ return vc;
+}
+
+template<> inline v4i ei_pset1(const int& from)
+{
+ int __attribute__(aligned(16)) ai[4];
+ ai[0] = from;
+ v4i vc = vec_ld(0, ai);
+ vc = vec_splat(vc, 0);
+ return vc;
+}
+
+template<> inline void ei_pstore(float* to, const v4f& from) { vec_st(from, 0, to); }
+template<> inline void ei_pstore(int* to, const v4i& from) { vec_st(from, 0, to); }
+
+template<> inline void ei_pstoreu(float* to, const v4f& from)
+{
+ // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html
+ // Warning: not thread safe!
+ __vector unsigned char MSQ, LSQ, edges;
+ __vector unsigned char edgeAlign, align;
+
+ MSQ = vec_ld(0, (unsigned char *)to); // most significant quadword
+ LSQ = vec_ld(15, (unsigned char *)to); // least significant quadword
+ edgeAlign = vec_lvsl(0, to); // permute map to extract edges
+ edges=vec_perm(LSQ,MSQ,edgeAlign); // extract the edges
+ align = vec_lvsr( 0, to ); // permute map to misalign data
+ MSQ = vec_perm(edges,(__vector unsigned char)from,align); // misalign the data (MSQ)
+ LSQ = vec_perm((__vector unsigned char)from,edges,align); // misalign the data (LSQ)
+ vec_st( LSQ, 15, (unsigned char *)to ); // Store the LSQ part first
+ vec_st( MSQ, 0, (unsigned char *)to ); // Store the MSQ part
+}
+
+template<> inline void ei_pstoreu(int* to , const v4i& from )
+{
+ // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html
+ // Warning: not thread safe!
+ __vector unsigned char MSQ, LSQ, edges;
+ __vector unsigned char edgeAlign, align;
+
+ MSQ = vec_ld(0, (unsigned char *)to); // most significant quadword
+ LSQ = vec_ld(15, (unsigned char *)to); // least significant quadword
+ edgeAlign = vec_lvsl(0, to); // permute map to extract edges
+ edges=vec_perm(LSQ,MSQ,edgeAlign); // extract the edges
+ align = vec_lvsr( 0, to ); // permute map to misalign data
+ MSQ = vec_perm(edges,(__vector unsigned char)from,align); // misalign the data (MSQ)
+ LSQ = vec_perm((__vector unsigned char)from,edges,align); // misalign the data (LSQ)
+ vec_st( LSQ, 15, (unsigned char *)to ); // Store the LSQ part first
+ vec_st( MSQ, 0, (unsigned char *)to ); // Store the MSQ part
+}
+
+template<> inline float ei_pfirst(const v4f& a)
+{
+ float __attribute__(aligned(16)) af[4];
+ vec_st(a, 0, af);
+ return af[0];
+}
+
+template<> inline int ei_pfirst(const v4i& a)
+{
+ int __attribute__(aligned(16)) ai[4];
+ vec_st(a, 0, ai);
+ return ai[0];
+}
+
+inline v4f ei_preduxp(const v4f* vecs)
+{
+ v4f v[4], sum[4];
+
+ // It's easier and faster to transpose then add as columns
+ // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation
+ // Do the transpose, first set of moves
+ v[0] = vec_mergeh(vecs[0], vecs[2]);
+ v[1] = vec_mergel(vecs[0], vecs[2]);
+ v[2] = vec_mergeh(vecs[1], vecs[3]);
+ v[3] = vec_mergel(vecs[1], vecs[3]);
+ // Get the resulting vectors
+ sum[0] = vec_mergeh(v[0], v[2]);
+ sum[1] = vec_mergel(v[0], v[2]);
+ sum[2] = vec_mergeh(v[1], v[3]);
+ sum[3] = vec_mergel(v[1], v[3]);
+
+ // Now do the summation:
+ // Lines 0+1
+ sum[0] = vec_add(sum[0], sum[1]);
+ // Lines 2+3
+ sum[1] = vec_add(sum[2], sum[3]);
+ // Add the results
+ sum[0] = vec_add(sum[0], sum[1]);
+ return sum[0];
+}
+
+inline float ei_predux(const v4f& a)
+{
+ v4f b, sum;
+ b = (v4f)vec_sld(a, a, 8);
+ sum = vec_add(a, b);
+ b = (v4f)vec_sld(sum, sum, 4);
+ sum = vec_add(sum, b);
+ return ei_pfirst(sum);
+}
+
+inline v4i ei_preduxp(const v4i* vecs)
+{
+ v4i v[4], sum[4];
+
+ // It's easier and faster to transpose then add as columns
+ // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation
+ // Do the transpose, first set of moves
+ v[0] = vec_mergeh(vecs[0], vecs[2]);
+ v[1] = vec_mergel(vecs[0], vecs[2]);
+ v[2] = vec_mergeh(vecs[1], vecs[3]);
+ v[3] = vec_mergel(vecs[1], vecs[3]);
+ // Get the resulting vectors
+ sum[0] = vec_mergeh(v[0], v[2]);
+ sum[1] = vec_mergel(v[0], v[2]);
+ sum[2] = vec_mergeh(v[1], v[3]);
+ sum[3] = vec_mergel(v[1], v[3]);
+
+ // Now do the summation:
+ // Lines 0+1
+ sum[0] = vec_add(sum[0], sum[1]);
+ // Lines 2+3
+ sum[1] = vec_add(sum[2], sum[3]);
+ // Add the results
+ sum[0] = vec_add(sum[0], sum[1]);
+ return sum[0];
+}
+
+inline int ei_predux(const v4i& a)
+{
+ USE_CONST_v0i;
+ v4i sum;
+ sum = vec_sums(a, v0i);
+ sum = vec_sld(sum, v0i, 12);
+ return ei_pfirst(sum);
+}
+
+template<int Offset>
+struct ei_palign_impl<Offset, v4f>
+{
+ inline static void run(v4f& first, const v4f& second)
+ {
+ first = vec_sld(first, second, Offset*4);
+ }
+};
+
+template<int Offset>
+struct ei_palign_impl<Offset, v4i>
+{
+ inline static void run(v4i& first, const v4i& second)
+ {
+ first = vec_sld(first, second, Offset*4);
+ }
+};
+
+#endif // EIGEN_PACKET_MATH_ALTIVEC_H
diff --git a/extern/Eigen2/Eigen/src/Core/arch/SSE/PacketMath.h b/extern/Eigen2/Eigen/src/Core/arch/SSE/PacketMath.h
new file mode 100644
index 00000000000..9ca65b9be5b
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -0,0 +1,321 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_PACKET_MATH_SSE_H
+#define EIGEN_PACKET_MATH_SSE_H
+
+#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
+#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 16
+#endif
+
+template<> struct ei_packet_traits<float> { typedef __m128 type; enum {size=4}; };
+template<> struct ei_packet_traits<double> { typedef __m128d type; enum {size=2}; };
+template<> struct ei_packet_traits<int> { typedef __m128i type; enum {size=4}; };
+
+template<> struct ei_unpacket_traits<__m128> { typedef float type; enum {size=4}; };
+template<> struct ei_unpacket_traits<__m128d> { typedef double type; enum {size=2}; };
+template<> struct ei_unpacket_traits<__m128i> { typedef int type; enum {size=4}; };
+
+template<> EIGEN_STRONG_INLINE __m128 ei_pset1<float>(const float& from) { return _mm_set1_ps(from); }
+template<> EIGEN_STRONG_INLINE __m128d ei_pset1<double>(const double& from) { return _mm_set1_pd(from); }
+template<> EIGEN_STRONG_INLINE __m128i ei_pset1<int>(const int& from) { return _mm_set1_epi32(from); }
+
+template<> EIGEN_STRONG_INLINE __m128 ei_padd<__m128>(const __m128& a, const __m128& b) { return _mm_add_ps(a,b); }
+template<> EIGEN_STRONG_INLINE __m128d ei_padd<__m128d>(const __m128d& a, const __m128d& b) { return _mm_add_pd(a,b); }
+template<> EIGEN_STRONG_INLINE __m128i ei_padd<__m128i>(const __m128i& a, const __m128i& b) { return _mm_add_epi32(a,b); }
+
+template<> EIGEN_STRONG_INLINE __m128 ei_psub<__m128>(const __m128& a, const __m128& b) { return _mm_sub_ps(a,b); }
+template<> EIGEN_STRONG_INLINE __m128d ei_psub<__m128d>(const __m128d& a, const __m128d& b) { return _mm_sub_pd(a,b); }
+template<> EIGEN_STRONG_INLINE __m128i ei_psub<__m128i>(const __m128i& a, const __m128i& b) { return _mm_sub_epi32(a,b); }
+
+template<> EIGEN_STRONG_INLINE __m128 ei_pmul<__m128>(const __m128& a, const __m128& b) { return _mm_mul_ps(a,b); }
+template<> EIGEN_STRONG_INLINE __m128d ei_pmul<__m128d>(const __m128d& a, const __m128d& b) { return _mm_mul_pd(a,b); }
+template<> EIGEN_STRONG_INLINE __m128i ei_pmul<__m128i>(const __m128i& a, const __m128i& b)
+{
+ return _mm_or_si128(
+ _mm_and_si128(
+ _mm_mul_epu32(a,b),
+ _mm_setr_epi32(0xffffffff,0,0xffffffff,0)),
+ _mm_slli_si128(
+ _mm_and_si128(
+ _mm_mul_epu32(_mm_srli_si128(a,4),_mm_srli_si128(b,4)),
+ _mm_setr_epi32(0xffffffff,0,0xffffffff,0)), 4));
+}
+
+template<> EIGEN_STRONG_INLINE __m128 ei_pdiv<__m128>(const __m128& a, const __m128& b) { return _mm_div_ps(a,b); }
+template<> EIGEN_STRONG_INLINE __m128d ei_pdiv<__m128d>(const __m128d& a, const __m128d& b) { return _mm_div_pd(a,b); }
+template<> EIGEN_STRONG_INLINE __m128i ei_pdiv<__m128i>(const __m128i& /*a*/, const __m128i& /*b*/)
+{ ei_assert(false && "packet integer division are not supported by SSE");
+ __m128i dummy = ei_pset1<int>(0);
+ return dummy;
+}
+
+// for some weird raisons, it has to be overloaded for packet integer
+template<> EIGEN_STRONG_INLINE __m128i ei_pmadd(const __m128i& a, const __m128i& b, const __m128i& c) { return ei_padd(ei_pmul(a,b), c); }
+
+template<> EIGEN_STRONG_INLINE __m128 ei_pmin<__m128>(const __m128& a, const __m128& b) { return _mm_min_ps(a,b); }
+template<> EIGEN_STRONG_INLINE __m128d ei_pmin<__m128d>(const __m128d& a, const __m128d& b) { return _mm_min_pd(a,b); }
+// FIXME this vectorized min operator is likely to be slower than the standard one
+template<> EIGEN_STRONG_INLINE __m128i ei_pmin<__m128i>(const __m128i& a, const __m128i& b)
+{
+ __m128i mask = _mm_cmplt_epi32(a,b);
+ return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
+}
+
+template<> EIGEN_STRONG_INLINE __m128 ei_pmax<__m128>(const __m128& a, const __m128& b) { return _mm_max_ps(a,b); }
+template<> EIGEN_STRONG_INLINE __m128d ei_pmax<__m128d>(const __m128d& a, const __m128d& b) { return _mm_max_pd(a,b); }
+// FIXME this vectorized max operator is likely to be slower than the standard one
+template<> EIGEN_STRONG_INLINE __m128i ei_pmax<__m128i>(const __m128i& a, const __m128i& b)
+{
+ __m128i mask = _mm_cmpgt_epi32(a,b);
+ return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
+}
+
+template<> EIGEN_STRONG_INLINE __m128 ei_pload<float>(const float* from) { return _mm_load_ps(from); }
+template<> EIGEN_STRONG_INLINE __m128d ei_pload<double>(const double* from) { return _mm_load_pd(from); }
+template<> EIGEN_STRONG_INLINE __m128i ei_pload<int>(const int* from) { return _mm_load_si128(reinterpret_cast<const __m128i*>(from)); }
+
+template<> EIGEN_STRONG_INLINE __m128 ei_ploadu<float>(const float* from) { return _mm_loadu_ps(from); }
+// template<> EIGEN_STRONG_INLINE __m128 ei_ploadu(const float* from) {
+// if (size_t(from)&0xF)
+// return _mm_loadu_ps(from);
+// else
+// return _mm_loadu_ps(from);
+// }
+template<> EIGEN_STRONG_INLINE __m128d ei_ploadu<double>(const double* from) { return _mm_loadu_pd(from); }
+template<> EIGEN_STRONG_INLINE __m128i ei_ploadu<int>(const int* from) { return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from)); }
+
+template<> EIGEN_STRONG_INLINE void ei_pstore<float>(float* to, const __m128& from) { _mm_store_ps(to, from); }
+template<> EIGEN_STRONG_INLINE void ei_pstore<double>(double* to, const __m128d& from) { _mm_store_pd(to, from); }
+template<> EIGEN_STRONG_INLINE void ei_pstore<int>(int* to, const __m128i& from) { _mm_store_si128(reinterpret_cast<__m128i*>(to), from); }
+
+template<> EIGEN_STRONG_INLINE void ei_pstoreu<float>(float* to, const __m128& from) { _mm_storeu_ps(to, from); }
+template<> EIGEN_STRONG_INLINE void ei_pstoreu<double>(double* to, const __m128d& from) { _mm_storeu_pd(to, from); }
+template<> EIGEN_STRONG_INLINE void ei_pstoreu<int>(int* to, const __m128i& from) { _mm_storeu_si128(reinterpret_cast<__m128i*>(to), from); }
+
+#ifdef _MSC_VER
+// this fix internal compilation error
+template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { float x = _mm_cvtss_f32(a); return x; }
+template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { double x = _mm_cvtsd_f64(a); return x; }
+template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { int x = _mm_cvtsi128_si32(a); return x; }
+#else
+template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { return _mm_cvtss_f32(a); }
+template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { return _mm_cvtsd_f64(a); }
+template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { return _mm_cvtsi128_si32(a); }
+#endif
+
+#ifdef __SSE3__
+// TODO implement SSE2 versions as well as integer versions
+template<> EIGEN_STRONG_INLINE __m128 ei_preduxp<__m128>(const __m128* vecs)
+{
+ return _mm_hadd_ps(_mm_hadd_ps(vecs[0], vecs[1]),_mm_hadd_ps(vecs[2], vecs[3]));
+}
+template<> EIGEN_STRONG_INLINE __m128d ei_preduxp<__m128d>(const __m128d* vecs)
+{
+ return _mm_hadd_pd(vecs[0], vecs[1]);
+}
+// SSSE3 version:
+// EIGEN_STRONG_INLINE __m128i ei_preduxp(const __m128i* vecs)
+// {
+// return _mm_hadd_epi32(_mm_hadd_epi32(vecs[0], vecs[1]),_mm_hadd_epi32(vecs[2], vecs[3]));
+// }
+
+template<> EIGEN_STRONG_INLINE float ei_predux<__m128>(const __m128& a)
+{
+ __m128 tmp0 = _mm_hadd_ps(a,a);
+ return ei_pfirst(_mm_hadd_ps(tmp0, tmp0));
+}
+
+template<> EIGEN_STRONG_INLINE double ei_predux<__m128d>(const __m128d& a) { return ei_pfirst(_mm_hadd_pd(a, a)); }
+
+// SSSE3 version:
+// EIGEN_STRONG_INLINE float ei_predux(const __m128i& a)
+// {
+// __m128i tmp0 = _mm_hadd_epi32(a,a);
+// return ei_pfirst(_mm_hadd_epi32(tmp0, tmp0));
+// }
+#else
+// SSE2 versions
+template<> EIGEN_STRONG_INLINE float ei_predux<__m128>(const __m128& a)
+{
+ __m128 tmp = _mm_add_ps(a, _mm_movehl_ps(a,a));
+ return ei_pfirst(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
+}
+template<> EIGEN_STRONG_INLINE double ei_predux<__m128d>(const __m128d& a)
+{
+ return ei_pfirst(_mm_add_sd(a, _mm_unpackhi_pd(a,a)));
+}
+
+template<> EIGEN_STRONG_INLINE __m128 ei_preduxp<__m128>(const __m128* vecs)
+{
+ __m128 tmp0, tmp1, tmp2;
+ tmp0 = _mm_unpacklo_ps(vecs[0], vecs[1]);
+ tmp1 = _mm_unpackhi_ps(vecs[0], vecs[1]);
+ tmp2 = _mm_unpackhi_ps(vecs[2], vecs[3]);
+ tmp0 = _mm_add_ps(tmp0, tmp1);
+ tmp1 = _mm_unpacklo_ps(vecs[2], vecs[3]);
+ tmp1 = _mm_add_ps(tmp1, tmp2);
+ tmp2 = _mm_movehl_ps(tmp1, tmp0);
+ tmp0 = _mm_movelh_ps(tmp0, tmp1);
+ return _mm_add_ps(tmp0, tmp2);
+}
+
+template<> EIGEN_STRONG_INLINE __m128d ei_preduxp<__m128d>(const __m128d* vecs)
+{
+ return _mm_add_pd(_mm_unpacklo_pd(vecs[0], vecs[1]), _mm_unpackhi_pd(vecs[0], vecs[1]));
+}
+#endif // SSE3
+
+template<> EIGEN_STRONG_INLINE int ei_predux<__m128i>(const __m128i& a)
+{
+ __m128i tmp = _mm_add_epi32(a, _mm_unpackhi_epi64(a,a));
+ return ei_pfirst(tmp) + ei_pfirst(_mm_shuffle_epi32(tmp, 1));
+}
+
+template<> EIGEN_STRONG_INLINE __m128i ei_preduxp<__m128i>(const __m128i* vecs)
+{
+ __m128i tmp0, tmp1, tmp2;
+ tmp0 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
+ tmp1 = _mm_unpackhi_epi32(vecs[0], vecs[1]);
+ tmp2 = _mm_unpackhi_epi32(vecs[2], vecs[3]);
+ tmp0 = _mm_add_epi32(tmp0, tmp1);
+ tmp1 = _mm_unpacklo_epi32(vecs[2], vecs[3]);
+ tmp1 = _mm_add_epi32(tmp1, tmp2);
+ tmp2 = _mm_unpacklo_epi64(tmp0, tmp1);
+ tmp0 = _mm_unpackhi_epi64(tmp0, tmp1);
+ return _mm_add_epi32(tmp0, tmp2);
+}
+
+#if (defined __GNUC__)
+// template <> EIGEN_STRONG_INLINE __m128 ei_pmadd(const __m128& a, const __m128& b, const __m128& c)
+// {
+// __m128 res = b;
+// asm("mulps %[a], %[b] \n\taddps %[c], %[b]" : [b] "+x" (res) : [a] "x" (a), [c] "x" (c));
+// return res;
+// }
+// EIGEN_STRONG_INLINE __m128i _mm_alignr_epi8(const __m128i& a, const __m128i& b, const int i)
+// {
+// __m128i res = a;
+// asm("palignr %[i], %[a], %[b] " : [b] "+x" (res) : [a] "x" (a), [i] "i" (i));
+// return res;
+// }
+#endif
+
+#ifdef __SSSE3__
+// SSSE3 versions
+template<int Offset>
+struct ei_palign_impl<Offset,__m128>
+{
+ EIGEN_STRONG_INLINE static void run(__m128& first, const __m128& second)
+ {
+ if (Offset!=0)
+ first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4));
+ }
+};
+
+template<int Offset>
+struct ei_palign_impl<Offset,__m128i>
+{
+ EIGEN_STRONG_INLINE static void run(__m128i& first, const __m128i& second)
+ {
+ if (Offset!=0)
+ first = _mm_alignr_epi8(second,first, Offset*4);
+ }
+};
+
+template<int Offset>
+struct ei_palign_impl<Offset,__m128d>
+{
+ EIGEN_STRONG_INLINE static void run(__m128d& first, const __m128d& second)
+ {
+ if (Offset==1)
+ first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8));
+ }
+};
+#else
+// SSE2 versions
+template<int Offset>
+struct ei_palign_impl<Offset,__m128>
+{
+ EIGEN_STRONG_INLINE static void run(__m128& first, const __m128& second)
+ {
+ if (Offset==1)
+ {
+ first = _mm_move_ss(first,second);
+ first = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(first),0x39));
+ }
+ else if (Offset==2)
+ {
+ first = _mm_movehl_ps(first,first);
+ first = _mm_movelh_ps(first,second);
+ }
+ else if (Offset==3)
+ {
+ first = _mm_move_ss(first,second);
+ first = _mm_shuffle_ps(first,second,0x93);
+ }
+ }
+};
+
+template<int Offset>
+struct ei_palign_impl<Offset,__m128i>
+{
+ EIGEN_STRONG_INLINE static void run(__m128i& first, const __m128i& second)
+ {
+ if (Offset==1)
+ {
+ first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second)));
+ first = _mm_shuffle_epi32(first,0x39);
+ }
+ else if (Offset==2)
+ {
+ first = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(first)));
+ first = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second)));
+ }
+ else if (Offset==3)
+ {
+ first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second)));
+ first = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second),0x93));
+ }
+ }
+};
+
+template<int Offset>
+struct ei_palign_impl<Offset,__m128d>
+{
+ EIGEN_STRONG_INLINE static void run(__m128d& first, const __m128d& second)
+ {
+ if (Offset==1)
+ {
+ first = _mm_castps_pd(_mm_movehl_ps(_mm_castpd_ps(first),_mm_castpd_ps(first)));
+ first = _mm_castps_pd(_mm_movelh_ps(_mm_castpd_ps(first),_mm_castpd_ps(second)));
+ }
+ }
+};
+#endif
+
+#define ei_vec4f_swizzle1(v,p,q,r,s) \
+ (_mm_castsi128_ps(_mm_shuffle_epi32( _mm_castps_si128(v), ((s)<<6|(r)<<4|(q)<<2|(p)))))
+
+#endif // EIGEN_PACKET_MATH_SSE_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/Constants.h b/extern/Eigen2/Eigen/src/Core/util/Constants.h
new file mode 100644
index 00000000000..296c3caa5f6
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/Constants.h
@@ -0,0 +1,254 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CONSTANTS_H
+#define EIGEN_CONSTANTS_H
+
+/** This value means that a quantity is not known at compile-time, and that instead the value is
+ * stored in some runtime variable.
+ *
+ * Explanation for the choice of this value:
+ * - It should be positive and larger than any reasonable compile-time-fixed number of rows or columns.
+ * This allows to simplify many compile-time conditions throughout Eigen.
+ * - It should be smaller than the sqrt of INT_MAX. Indeed, we often multiply a number of rows with a number
+ * of columns in order to compute a number of coefficients. Even if we guard that with an "if" checking whether
+ * the values are Dynamic, we still get a compiler warning "integer overflow". So the only way to get around
+ * it would be a meta-selector. Doing this everywhere would reduce code readability and lenghten compilation times.
+ * Also, disabling compiler warnings for integer overflow, sounds like a bad idea.
+ *
+ * If you wish to port Eigen to a platform where sizeof(int)==2, it is perfectly possible to set Dynamic to, say, 100.
+ */
+const int Dynamic = 10000;
+
+/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>().
+ * The value Infinity there means the L-infinity norm.
+ */
+const int Infinity = -1;
+
+/** \defgroup flags flags
+ * \ingroup Core_Module
+ *
+ * These are the possible bits which can be OR'ed to constitute the flags of a matrix or
+ * expression.
+ *
+ * It is important to note that these flags are a purely compile-time notion. They are a compile-time property of
+ * an expression type, implemented as enum's. They are not stored in memory at runtime, and they do not incur any
+ * runtime overhead.
+ *
+ * \sa MatrixBase::Flags
+ */
+
+/** \ingroup flags
+ *
+ * for a matrix, this means that the storage order is row-major.
+ * If this bit is not set, the storage order is column-major.
+ * For an expression, this determines the storage order of
+ * the matrix created by evaluation of that expression. */
+const unsigned int RowMajorBit = 0x1;
+
+/** \ingroup flags
+ *
+ * means the expression should be evaluated by the calling expression */
+const unsigned int EvalBeforeNestingBit = 0x2;
+
+/** \ingroup flags
+ *
+ * means the expression should be evaluated before any assignement */
+const unsigned int EvalBeforeAssigningBit = 0x4;
+
+/** \ingroup flags
+ *
+ * Short version: means the expression might be vectorized
+ *
+ * Long version: means that the coefficients can be handled by packets
+ * and start at a memory location whose alignment meets the requirements
+ * of the present CPU architecture for optimized packet access. In the fixed-size
+ * case, there is the additional condition that the total size of the coefficients
+ * array is a multiple of the packet size, so that it is possible to access all the
+ * coefficients by packets. In the dynamic-size case, there is no such condition
+ * on the total size, so it might not be possible to access the few last coeffs
+ * by packets.
+ *
+ * \note This bit can be set regardless of whether vectorization is actually enabled.
+ * To check for actual vectorizability, see \a ActualPacketAccessBit.
+ */
+const unsigned int PacketAccessBit = 0x8;
+
+#ifdef EIGEN_VECTORIZE
+/** \ingroup flags
+ *
+ * If vectorization is enabled (EIGEN_VECTORIZE is defined) this constant
+ * is set to the value \a PacketAccessBit.
+ *
+ * If vectorization is not enabled (EIGEN_VECTORIZE is not defined) this constant
+ * is set to the value 0.
+ */
+const unsigned int ActualPacketAccessBit = PacketAccessBit;
+#else
+const unsigned int ActualPacketAccessBit = 0x0;
+#endif
+
+/** \ingroup flags
+ *
+ * Short version: means the expression can be seen as 1D vector.
+ *
+ * Long version: means that one can access the coefficients
+ * of this expression by coeff(int), and coeffRef(int) in the case of a lvalue expression. These
+ * index-based access methods are guaranteed
+ * to not have to do any runtime computation of a (row, col)-pair from the index, so that it
+ * is guaranteed that whenever it is available, index-based access is at least as fast as
+ * (row,col)-based access. Expressions for which that isn't possible don't have the LinearAccessBit.
+ *
+ * If both PacketAccessBit and LinearAccessBit are set, then the
+ * packets of this expression can be accessed by packet(int), and writePacket(int) in the case of a
+ * lvalue expression.
+ *
+ * Typically, all vector expressions have the LinearAccessBit, but there is one exception:
+ * Product expressions don't have it, because it would be troublesome for vectorization, even when the
+ * Product is a vector expression. Thus, vector Product expressions allow index-based coefficient access but
+ * not index-based packet access, so they don't have the LinearAccessBit.
+ */
+const unsigned int LinearAccessBit = 0x10;
+
+/** \ingroup flags
+ *
+ * Means that the underlying array of coefficients can be directly accessed. This means two things.
+ * First, references to the coefficients must be available through coeffRef(int, int). This rules out read-only
+ * expressions whose coefficients are computed on demand by coeff(int, int). Second, the memory layout of the
+ * array of coefficients must be exactly the natural one suggested by rows(), cols(), stride(), and the RowMajorBit.
+ * This rules out expressions such as DiagonalCoeffs, whose coefficients, though referencable, do not have
+ * such a regular memory layout.
+ */
+const unsigned int DirectAccessBit = 0x20;
+
+/** \ingroup flags
+ *
+ * means the first coefficient packet is guaranteed to be aligned */
+const unsigned int AlignedBit = 0x40;
+
+/** \ingroup flags
+ *
+ * means all diagonal coefficients are equal to 0 */
+const unsigned int ZeroDiagBit = 0x80;
+
+/** \ingroup flags
+ *
+ * means all diagonal coefficients are equal to 1 */
+const unsigned int UnitDiagBit = 0x100;
+
+/** \ingroup flags
+ *
+ * means the matrix is selfadjoint (M=M*). */
+const unsigned int SelfAdjointBit = 0x200;
+
+/** \ingroup flags
+ *
+ * means the strictly lower triangular part is 0 */
+const unsigned int UpperTriangularBit = 0x400;
+
+/** \ingroup flags
+ *
+ * means the strictly upper triangular part is 0 */
+const unsigned int LowerTriangularBit = 0x800;
+
+/** \ingroup flags
+ *
+ * means the expression includes sparse matrices and the sparse path has to be taken. */
+const unsigned int SparseBit = 0x1000;
+
+// list of flags that are inherited by default
+const unsigned int HereditaryBits = RowMajorBit
+ | EvalBeforeNestingBit
+ | EvalBeforeAssigningBit
+ | SparseBit;
+
+// Possible values for the Mode parameter of part() and of extract()
+const unsigned int UpperTriangular = UpperTriangularBit;
+const unsigned int StrictlyUpperTriangular = UpperTriangularBit | ZeroDiagBit;
+const unsigned int LowerTriangular = LowerTriangularBit;
+const unsigned int StrictlyLowerTriangular = LowerTriangularBit | ZeroDiagBit;
+const unsigned int SelfAdjoint = SelfAdjointBit;
+
+// additional possible values for the Mode parameter of extract()
+const unsigned int UnitUpperTriangular = UpperTriangularBit | UnitDiagBit;
+const unsigned int UnitLowerTriangular = LowerTriangularBit | UnitDiagBit;
+const unsigned int Diagonal = UpperTriangular | LowerTriangular;
+
+enum { Aligned, Unaligned };
+enum { ForceAligned, AsRequested };
+enum { ConditionalJumpCost = 5 };
+enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
+enum DirectionType { Vertical, Horizontal };
+enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct, DiagonalProduct, SparseTimeSparseProduct, SparseTimeDenseProduct, DenseTimeSparseProduct };
+
+enum {
+ /** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment
+ * and good size */
+ InnerVectorization,
+ /** \internal Vectorization path using a single loop plus scalar loops for the
+ * unaligned boundaries */
+ LinearVectorization,
+ /** \internal Generic vectorization path using one vectorized loop per row/column with some
+ * scalar loops to handle the unaligned boundaries */
+ SliceVectorization,
+ NoVectorization
+};
+
+enum {
+ NoUnrolling,
+ InnerUnrolling,
+ CompleteUnrolling
+};
+
+enum {
+ ColMajor = 0,
+ RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
+ /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be
+ requested to be aligned) */
+ DontAlign = 0,
+ /** \internal Align the matrix itself if it is vectorizable fixed-size */
+ AutoAlign = 0x2
+};
+
+enum {
+ IsDense = 0,
+ IsSparse = SparseBit,
+ NoDirectAccess = 0,
+ HasDirectAccess = DirectAccessBit
+};
+
+const int EiArch_Generic = 0x0;
+const int EiArch_SSE = 0x1;
+const int EiArch_AltiVec = 0x2;
+
+#if defined EIGEN_VECTORIZE_SSE
+ const int EiArch = EiArch_SSE;
+#elif defined EIGEN_VECTORIZE_ALTIVEC
+ const int EiArch = EiArch_AltiVec;
+#else
+ const int EiArch = EiArch_Generic;
+#endif
+
+#endif // EIGEN_CONSTANTS_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/DisableMSVCWarnings.h b/extern/Eigen2/Eigen/src/Core/util/DisableMSVCWarnings.h
new file mode 100644
index 00000000000..765ddecc53c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/DisableMSVCWarnings.h
@@ -0,0 +1,5 @@
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning( disable : 4181 4244 4127 4211 4717 )
+#endif
diff --git a/extern/Eigen2/Eigen/src/Core/util/EnableMSVCWarnings.h b/extern/Eigen2/Eigen/src/Core/util/EnableMSVCWarnings.h
new file mode 100644
index 00000000000..8bd61601ebb
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/EnableMSVCWarnings.h
@@ -0,0 +1,4 @@
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
diff --git a/extern/Eigen2/Eigen/src/Core/util/ForwardDeclarations.h b/extern/Eigen2/Eigen/src/Core/util/ForwardDeclarations.h
new file mode 100644
index 00000000000..a72a40b1bfc
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/ForwardDeclarations.h
@@ -0,0 +1,125 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_FORWARDDECLARATIONS_H
+#define EIGEN_FORWARDDECLARATIONS_H
+
+template<typename T> struct ei_traits;
+template<typename T> struct NumTraits;
+
+template<typename _Scalar, int _Rows, int _Cols,
+ int _Options = EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION | AutoAlign,
+ int _MaxRows = _Rows, int _MaxCols = _Cols> class Matrix;
+
+template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged;
+template<typename ExpressionType> class NestByValue;
+template<typename ExpressionType> class SwapWrapper;
+template<typename MatrixType> class Minor;
+template<typename MatrixType, int BlockRows=Dynamic, int BlockCols=Dynamic, int PacketAccess=AsRequested,
+ int _DirectAccessStatus = ei_traits<MatrixType>::Flags&DirectAccessBit ? DirectAccessBit
+ : ei_traits<MatrixType>::Flags&SparseBit> class Block;
+template<typename MatrixType> class Transpose;
+template<typename MatrixType> class Conjugate;
+template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp;
+template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp;
+template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp;
+template<typename Lhs, typename Rhs, int ProductMode> class Product;
+template<typename CoeffsVectorType> class DiagonalMatrix;
+template<typename MatrixType> class DiagonalCoeffs;
+template<typename MatrixType, int PacketAccess = AsRequested> class Map;
+template<typename MatrixType, unsigned int Mode> class Part;
+template<typename MatrixType, unsigned int Mode> class Extract;
+template<typename ExpressionType> class Cwise;
+template<typename ExpressionType> class WithFormat;
+template<typename MatrixType> struct CommaInitializer;
+
+
+template<typename Lhs, typename Rhs> struct ei_product_mode;
+template<typename Lhs, typename Rhs, int ProductMode = ei_product_mode<Lhs,Rhs>::value> struct ProductReturnType;
+
+template<typename Scalar> struct ei_scalar_sum_op;
+template<typename Scalar> struct ei_scalar_difference_op;
+template<typename Scalar> struct ei_scalar_product_op;
+template<typename Scalar> struct ei_scalar_quotient_op;
+template<typename Scalar> struct ei_scalar_opposite_op;
+template<typename Scalar> struct ei_scalar_conjugate_op;
+template<typename Scalar> struct ei_scalar_real_op;
+template<typename Scalar> struct ei_scalar_imag_op;
+template<typename Scalar> struct ei_scalar_abs_op;
+template<typename Scalar> struct ei_scalar_abs2_op;
+template<typename Scalar> struct ei_scalar_sqrt_op;
+template<typename Scalar> struct ei_scalar_exp_op;
+template<typename Scalar> struct ei_scalar_log_op;
+template<typename Scalar> struct ei_scalar_cos_op;
+template<typename Scalar> struct ei_scalar_sin_op;
+template<typename Scalar> struct ei_scalar_pow_op;
+template<typename Scalar> struct ei_scalar_inverse_op;
+template<typename Scalar> struct ei_scalar_square_op;
+template<typename Scalar> struct ei_scalar_cube_op;
+template<typename Scalar, typename NewType> struct ei_scalar_cast_op;
+template<typename Scalar> struct ei_scalar_multiple_op;
+template<typename Scalar> struct ei_scalar_quotient1_op;
+template<typename Scalar> struct ei_scalar_min_op;
+template<typename Scalar> struct ei_scalar_max_op;
+template<typename Scalar> struct ei_scalar_random_op;
+template<typename Scalar> struct ei_scalar_add_op;
+template<typename Scalar> struct ei_scalar_constant_op;
+template<typename Scalar> struct ei_scalar_identity_op;
+
+struct IOFormat;
+
+template<typename Scalar>
+void ei_cache_friendly_product(
+ int _rows, int _cols, int depth,
+ bool _lhsRowMajor, const Scalar* _lhs, int _lhsStride,
+ bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride,
+ bool resRowMajor, Scalar* res, int resStride);
+
+// Array module
+template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> class Select;
+template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr;
+template<typename ExpressionType, int Direction> class PartialRedux;
+
+template<typename MatrixType> class LU;
+template<typename MatrixType> class QR;
+template<typename MatrixType> class SVD;
+template<typename MatrixType> class LLT;
+template<typename MatrixType> class LDLT;
+
+// Geometry module:
+template<typename Derived, int _Dim> class RotationBase;
+template<typename Lhs, typename Rhs> class Cross;
+template<typename Scalar> class Quaternion;
+template<typename Scalar> class Rotation2D;
+template<typename Scalar> class AngleAxis;
+template<typename Scalar,int Dim> class Transform;
+template <typename _Scalar, int _AmbientDim> class ParametrizedLine;
+template <typename _Scalar, int _AmbientDim> class Hyperplane;
+template<typename Scalar,int Dim> class Translation;
+template<typename Scalar,int Dim> class Scaling;
+
+// Sparse module:
+template<typename Lhs, typename Rhs, int ProductMode> class SparseProduct;
+
+#endif // EIGEN_FORWARDDECLARATIONS_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/Macros.h b/extern/Eigen2/Eigen/src/Core/util/Macros.h
new file mode 100644
index 00000000000..6be6f096055
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/Macros.h
@@ -0,0 +1,273 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MACROS_H
+#define EIGEN_MACROS_H
+
+#undef minor
+
+#define EIGEN_WORLD_VERSION 2
+#define EIGEN_MAJOR_VERSION 0
+#define EIGEN_MINOR_VERSION 6
+
+#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
+ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
+ EIGEN_MINOR_VERSION>=z))))
+
+// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable 16 byte alignment on all
+// platforms where vectorization might be enabled. In theory we could always enable alignment, but it can be a cause of problems
+// on some platforms, so we just disable it in certain common platform (compiler+architecture combinations) to avoid these problems.
+#if defined(__GNUC__) && !(defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__ia64__))
+#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT 1
+#else
+#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT 0
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ <= 3)
+#define EIGEN_GCC3_OR_OLDER 1
+#else
+#define EIGEN_GCC3_OR_OLDER 0
+#endif
+
+// FIXME vectorization + alignment is completely disabled with sun studio
+#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC)
+ #define EIGEN_ARCH_WANTS_ALIGNMENT 1
+#else
+ #define EIGEN_ARCH_WANTS_ALIGNMENT 0
+#endif
+
+// EIGEN_ALIGN is the true test whether we want to align or not. It takes into account both the user choice to explicitly disable
+// alignment (EIGEN_DONT_ALIGN) and the architecture config (EIGEN_ARCH_WANTS_ALIGNMENT). Henceforth, only EIGEN_ALIGN should be used.
+#if EIGEN_ARCH_WANTS_ALIGNMENT && !defined(EIGEN_DONT_ALIGN)
+ #define EIGEN_ALIGN 1
+#else
+ #define EIGEN_ALIGN 0
+ #ifdef EIGEN_VECTORIZE
+ #error "Vectorization enabled, but our platform checks say that we don't do 16 byte alignment on this platform. If you added vectorization for another architecture, you also need to edit this platform check."
+ #endif
+ #ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
+ #define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
+ #endif
+#endif
+
+#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
+#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION RowMajor
+#else
+#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ColMajor
+#endif
+
+/** \internal Defines the maximal loop size to enable meta unrolling of loops.
+ * Note that the value here is expressed in Eigen's own notion of "number of FLOPS",
+ * it does not correspond to the number of iterations or the number of instructions
+ */
+#ifndef EIGEN_UNROLLING_LIMIT
+#define EIGEN_UNROLLING_LIMIT 100
+#endif
+
+/** \internal Define the maximal size in Bytes of blocks fitting in CPU cache.
+ * The current value is set to generate blocks of 256x256 for float
+ *
+ * Typically for a single-threaded application you would set that to 25% of the size of your CPU caches in bytes
+ */
+#ifndef EIGEN_TUNE_FOR_CPU_CACHE_SIZE
+#define EIGEN_TUNE_FOR_CPU_CACHE_SIZE (sizeof(float)*256*256)
+#endif
+
+// FIXME this should go away quickly
+#ifdef EIGEN_TUNE_FOR_L2_CACHE_SIZE
+#error EIGEN_TUNE_FOR_L2_CACHE_SIZE is now called EIGEN_TUNE_FOR_CPU_CACHE_SIZE.
+#endif
+
+#define USING_PART_OF_NAMESPACE_EIGEN \
+EIGEN_USING_MATRIX_TYPEDEFS \
+using Eigen::Matrix; \
+using Eigen::MatrixBase; \
+using Eigen::ei_random; \
+using Eigen::ei_real; \
+using Eigen::ei_imag; \
+using Eigen::ei_conj; \
+using Eigen::ei_abs; \
+using Eigen::ei_abs2; \
+using Eigen::ei_sqrt; \
+using Eigen::ei_exp; \
+using Eigen::ei_log; \
+using Eigen::ei_sin; \
+using Eigen::ei_cos;
+
+#ifdef NDEBUG
+# ifndef EIGEN_NO_DEBUG
+# define EIGEN_NO_DEBUG
+# endif
+#endif
+
+#ifndef ei_assert
+#ifdef EIGEN_NO_DEBUG
+#define ei_assert(x)
+#else
+#define ei_assert(x) assert(x)
+#endif
+#endif
+
+#ifdef EIGEN_INTERNAL_DEBUGGING
+#define ei_internal_assert(x) ei_assert(x)
+#else
+#define ei_internal_assert(x)
+#endif
+
+#ifdef EIGEN_NO_DEBUG
+#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x
+#else
+#define EIGEN_ONLY_USED_FOR_DEBUG(x)
+#endif
+
+// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
+// which should be inlined even in debug mode.
+// FIXME with the always_inline attribute,
+// gcc 3.4.x reports the following compilation error:
+// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const'
+// : function body not available
+#if EIGEN_GNUC_AT_LEAST(4,0)
+#define EIGEN_ALWAYS_INLINE_ATTRIB __attribute__((always_inline))
+#else
+#define EIGEN_ALWAYS_INLINE_ATTRIB
+#endif
+
+// EIGEN_FORCE_INLINE means "inline as much as possible"
+#if (defined _MSC_VER)
+#define EIGEN_STRONG_INLINE __forceinline
+#else
+#define EIGEN_STRONG_INLINE inline
+#endif
+
+#if (defined __GNUC__)
+#define EIGEN_DONT_INLINE __attribute__((noinline))
+#elif (defined _MSC_VER)
+#define EIGEN_DONT_INLINE __declspec(noinline)
+#else
+#define EIGEN_DONT_INLINE
+#endif
+
+#if (defined __GNUC__)
+#define EIGEN_DEPRECATED __attribute__((deprecated))
+#elif (defined _MSC_VER)
+#define EIGEN_DEPRECATED __declspec(deprecated)
+#else
+#define EIGEN_DEPRECATED
+#endif
+
+/* EIGEN_ALIGN_128 forces data to be 16-byte aligned, EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
+ * so that vectorization doesn't affect binary compatibility.
+ *
+ * If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
+ * vectorized and non-vectorized code.
+ */
+#if !EIGEN_ALIGN
+#define EIGEN_ALIGN_128
+#elif (defined __GNUC__)
+#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
+#elif (defined _MSC_VER)
+#define EIGEN_ALIGN_128 __declspec(align(16))
+#else
+#error Please tell me what is the equivalent of __attribute__((aligned(16))) for your compiler
+#endif
+
+#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
+ #define EIGEN_RESTRICT
+#endif
+#ifndef EIGEN_RESTRICT
+ #define EIGEN_RESTRICT __restrict
+#endif
+
+#ifndef EIGEN_STACK_ALLOCATION_LIMIT
+#define EIGEN_STACK_ALLOCATION_LIMIT 1000000
+#endif
+
+#ifndef EIGEN_DEFAULT_IO_FORMAT
+#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat()
+#endif
+
+// format used in Eigen's documentation
+// needed to define it here as escaping characters in CMake add_definition's argument seems very problematic.
+#define EIGEN_DOCS_IO_FORMAT IOFormat(3, AlignCols, " ", "\n", "", "")
+
+#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \
+template<typename OtherDerived> \
+EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::MatrixBase<OtherDerived>& other) \
+{ \
+ return Base::operator Op(other.derived()); \
+} \
+EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \
+{ \
+ return Base::operator Op(other); \
+}
+
+#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \
+template<typename Other> \
+EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \
+{ \
+ return Base::operator Op(scalar); \
+}
+
+#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
+EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \
+EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \
+EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \
+EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \
+EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)
+
+#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \
+typedef BaseClass Base; \
+typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \
+typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \
+typedef typename Base::PacketScalar PacketScalar; \
+typedef typename Eigen::ei_nested<Derived>::type Nested; \
+enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
+ ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
+ MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \
+ MaxColsAtCompileTime = Eigen::ei_traits<Derived>::MaxColsAtCompileTime, \
+ Flags = Eigen::ei_traits<Derived>::Flags, \
+ CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \
+ SizeAtCompileTime = Base::SizeAtCompileTime, \
+ MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
+ IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
+
+#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
+_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>)
+
+#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
+#define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
+
+// just an empty macro !
+#define EIGEN_EMPTY
+
+// concatenate two tokens
+#define EIGEN_CAT2(a,b) a ## b
+#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
+
+// convert a token to a string
+#define EIGEN_MAKESTRING2(a) #a
+#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
+
+#endif // EIGEN_MACROS_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/Memory.h b/extern/Eigen2/Eigen/src/Core/util/Memory.h
new file mode 100644
index 00000000000..09ad39d5be9
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/Memory.h
@@ -0,0 +1,368 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2009 Kenneth Riddile <kfriddile@yahoo.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MEMORY_H
+#define EIGEN_MEMORY_H
+
+#if defined(__APPLE__) || defined(_WIN64)
+ #define EIGEN_MALLOC_ALREADY_ALIGNED 1
+#else
+ #define EIGEN_MALLOC_ALREADY_ALIGNED 0
+#endif
+
+#if ((defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
+ #define EIGEN_HAS_POSIX_MEMALIGN 1
+#else
+ #define EIGEN_HAS_POSIX_MEMALIGN 0
+#endif
+
+#ifdef EIGEN_VECTORIZE_SSE
+ #define EIGEN_HAS_MM_MALLOC 1
+#else
+ #define EIGEN_HAS_MM_MALLOC 0
+#endif
+
+/** \internal like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
+ * Fast, but wastes 16 additional bytes of memory.
+ * Does not throw any exception.
+ */
+inline void* ei_handmade_aligned_malloc(size_t size)
+{
+ void *original = malloc(size+16);
+ void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
+ *(reinterpret_cast<void**>(aligned) - 1) = original;
+ return aligned;
+}
+
+/** \internal frees memory allocated with ei_handmade_aligned_malloc */
+inline void ei_handmade_aligned_free(void *ptr)
+{
+ if(ptr)
+ free(*(reinterpret_cast<void**>(ptr) - 1));
+}
+
+/** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
+ * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
+ */
+inline void* ei_aligned_malloc(size_t size)
+{
+ #ifdef EIGEN_NO_MALLOC
+ ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
+ #endif
+
+ void *result;
+ #if !EIGEN_ALIGN
+ result = malloc(size);
+ #elif EIGEN_MALLOC_ALREADY_ALIGNED
+ result = malloc(size);
+ #elif EIGEN_HAS_POSIX_MEMALIGN
+ if(posix_memalign(&result, 16, size)) result = 0;
+ #elif EIGEN_HAS_MM_MALLOC
+ result = _mm_malloc(size, 16);
+ #elif (defined _MSC_VER)
+ result = _aligned_malloc(size, 16);
+ #else
+ result = ei_handmade_aligned_malloc(size);
+ #endif
+
+ #ifdef EIGEN_EXCEPTIONS
+ if(result == 0)
+ throw std::bad_alloc();
+ #endif
+ return result;
+}
+
+/** allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
+ * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
+ */
+template<bool Align> inline void* ei_conditional_aligned_malloc(size_t size)
+{
+ return ei_aligned_malloc(size);
+}
+
+template<> inline void* ei_conditional_aligned_malloc<false>(size_t size)
+{
+ #ifdef EIGEN_NO_MALLOC
+ ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
+ #endif
+
+ void *result = malloc(size);
+ #ifdef EIGEN_EXCEPTIONS
+ if(!result) throw std::bad_alloc();
+ #endif
+ return result;
+}
+
+/** allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
+ * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
+ * The default constructor of T is called.
+ */
+template<typename T> inline T* ei_aligned_new(size_t size)
+{
+ void *void_result = ei_aligned_malloc(sizeof(T)*size);
+ return ::new(void_result) T[size];
+}
+
+template<typename T, bool Align> inline T* ei_conditional_aligned_new(size_t size)
+{
+ void *void_result = ei_conditional_aligned_malloc<Align>(sizeof(T)*size);
+ return ::new(void_result) T[size];
+}
+
+/** \internal free memory allocated with ei_aligned_malloc
+ */
+inline void ei_aligned_free(void *ptr)
+{
+ #if !EIGEN_ALIGN
+ free(ptr);
+ #elif EIGEN_MALLOC_ALREADY_ALIGNED
+ free(ptr);
+ #elif EIGEN_HAS_POSIX_MEMALIGN
+ free(ptr);
+ #elif EIGEN_HAS_MM_MALLOC
+ _mm_free(ptr);
+ #elif defined(_MSC_VER)
+ _aligned_free(ptr);
+ #else
+ ei_handmade_aligned_free(ptr);
+ #endif
+}
+
+/** \internal free memory allocated with ei_conditional_aligned_malloc
+ */
+template<bool Align> inline void ei_conditional_aligned_free(void *ptr)
+{
+ ei_aligned_free(ptr);
+}
+
+template<> inline void ei_conditional_aligned_free<false>(void *ptr)
+{
+ free(ptr);
+}
+
+/** \internal delete the elements of an array.
+ * The \a size parameters tells on how many objects to call the destructor of T.
+ */
+template<typename T> inline void ei_delete_elements_of_array(T *ptr, size_t size)
+{
+ // always destruct an array starting from the end.
+ while(size) ptr[--size].~T();
+}
+
+/** \internal delete objects constructed with ei_aligned_new
+ * The \a size parameters tells on how many objects to call the destructor of T.
+ */
+template<typename T> inline void ei_aligned_delete(T *ptr, size_t size)
+{
+ ei_delete_elements_of_array<T>(ptr, size);
+ ei_aligned_free(ptr);
+}
+
+/** \internal delete objects constructed with ei_conditional_aligned_new
+ * The \a size parameters tells on how many objects to call the destructor of T.
+ */
+template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *ptr, size_t size)
+{
+ ei_delete_elements_of_array<T>(ptr, size);
+ ei_conditional_aligned_free<Align>(ptr);
+}
+
+/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */
+template<typename Scalar>
+inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
+{
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+ const int PacketSize = ei_packet_traits<Scalar>::size;
+ const int PacketAlignedMask = PacketSize-1;
+ const bool Vectorized = PacketSize>1;
+ return Vectorized
+ ? std::min<int>( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
+ & PacketAlignedMask, maxOffset)
+ : 0;
+}
+
+/** \internal
+ * ei_aligned_stack_alloc(SIZE) allocates an aligned buffer of SIZE bytes
+ * on the stack if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT.
+ * Otherwise the memory is allocated on the heap.
+ * Data allocated with ei_aligned_stack_alloc \b must be freed by calling ei_aligned_stack_free(PTR,SIZE).
+ * \code
+ * float * data = ei_aligned_stack_alloc(float,array.size());
+ * // ...
+ * ei_aligned_stack_free(data,float,array.size());
+ * \endcode
+ */
+#ifdef __linux__
+ #define ei_aligned_stack_alloc(SIZE) (SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) \
+ ? alloca(SIZE) \
+ : ei_aligned_malloc(SIZE)
+ #define ei_aligned_stack_free(PTR,SIZE) if(SIZE>EIGEN_STACK_ALLOCATION_LIMIT) ei_aligned_free(PTR)
+#else
+ #define ei_aligned_stack_alloc(SIZE) ei_aligned_malloc(SIZE)
+ #define ei_aligned_stack_free(PTR,SIZE) ei_aligned_free(PTR)
+#endif
+
+#define ei_aligned_stack_new(TYPE,SIZE) ::new(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)) TYPE[SIZE]
+#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_delete_elements_of_array<TYPE>(PTR, SIZE); \
+ ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0)
+
+
+#if EIGEN_ALIGN
+ #ifdef EIGEN_EXCEPTIONS
+ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
+ void* operator new(size_t size, const std::nothrow_t&) throw() { \
+ try { return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); } \
+ catch (...) { return 0; } \
+ return 0; \
+ }
+ #else
+ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
+ void* operator new(size_t size, const std::nothrow_t&) throw() { \
+ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
+ }
+ #endif
+
+ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
+ void *operator new(size_t size) { \
+ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
+ } \
+ void *operator new[](size_t size) { \
+ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
+ } \
+ void operator delete(void * ptr) throw() { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
+ void operator delete[](void * ptr) throw() { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
+ /* in-place new and delete. since (at least afaik) there is no actual */ \
+ /* memory allocated we can safely let the default implementation handle */ \
+ /* this particular case. */ \
+ static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \
+ void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \
+ /* nothrow-new (returns zero instead of std::bad_alloc) */ \
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
+ void operator delete(void *ptr, const std::nothrow_t&) throw() { \
+ Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); \
+ } \
+ typedef void ei_operator_new_marker_type;
+#else
+ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
+#endif
+
+#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true)
+#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0))
+
+
+/** \class aligned_allocator
+*
+* \brief stl compatible allocator to use with with 16 byte aligned types
+*
+* Example:
+* \code
+* // Matrix4f requires 16 bytes alignment:
+* std::map< int, Matrix4f, std::less<int>, aligned_allocator<Matrix4f> > my_map_mat4;
+* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator:
+* std::map< int, Vector3f > my_map_vec3;
+* \endcode
+*
+*/
+template<class T>
+class aligned_allocator
+{
+public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T value_type;
+
+ template<class U>
+ struct rebind
+ {
+ typedef aligned_allocator<U> other;
+ };
+
+ pointer address( reference value ) const
+ {
+ return &value;
+ }
+
+ const_pointer address( const_reference value ) const
+ {
+ return &value;
+ }
+
+ aligned_allocator() throw()
+ {
+ }
+
+ aligned_allocator( const aligned_allocator& ) throw()
+ {
+ }
+
+ template<class U>
+ aligned_allocator( const aligned_allocator<U>& ) throw()
+ {
+ }
+
+ ~aligned_allocator() throw()
+ {
+ }
+
+ size_type max_size() const throw()
+ {
+ return std::numeric_limits<size_type>::max();
+ }
+
+ pointer allocate( size_type num, const_pointer* hint = 0 )
+ {
+ static_cast<void>( hint ); // suppress unused variable warning
+ return static_cast<pointer>( ei_aligned_malloc( num * sizeof(T) ) );
+ }
+
+ void construct( pointer p, const T& value )
+ {
+ ::new( p ) T( value );
+ }
+
+ void destroy( pointer p )
+ {
+ p->~T();
+ }
+
+ void deallocate( pointer p, size_type /*num*/ )
+ {
+ ei_aligned_free( p );
+ }
+
+ bool operator!=(const aligned_allocator<T>& other) const
+ { return false; }
+
+ bool operator==(const aligned_allocator<T>& other) const
+ { return true; }
+};
+
+#endif // EIGEN_MEMORY_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/Meta.h b/extern/Eigen2/Eigen/src/Core/util/Meta.h
new file mode 100644
index 00000000000..c65c52ef42f
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/Meta.h
@@ -0,0 +1,183 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_META_H
+#define EIGEN_META_H
+
+/** \internal
+ * \file Meta.h
+ * This file contains generic metaprogramming classes which are not specifically related to Eigen.
+ * \note In case you wonder, yes we're aware that Boost already provides all these features,
+ * we however don't want to add a dependency to Boost.
+ */
+
+struct ei_meta_true { enum { ret = 1 }; };
+struct ei_meta_false { enum { ret = 0 }; };
+
+template<bool Condition, typename Then, typename Else>
+struct ei_meta_if { typedef Then ret; };
+
+template<typename Then, typename Else>
+struct ei_meta_if <false, Then, Else> { typedef Else ret; };
+
+template<typename T, typename U> struct ei_is_same_type { enum { ret = 0 }; };
+template<typename T> struct ei_is_same_type<T,T> { enum { ret = 1 }; };
+
+template<typename T> struct ei_unref { typedef T type; };
+template<typename T> struct ei_unref<T&> { typedef T type; };
+
+template<typename T> struct ei_unpointer { typedef T type; };
+template<typename T> struct ei_unpointer<T*> { typedef T type; };
+template<typename T> struct ei_unpointer<T*const> { typedef T type; };
+
+template<typename T> struct ei_unconst { typedef T type; };
+template<typename T> struct ei_unconst<const T> { typedef T type; };
+template<typename T> struct ei_unconst<T const &> { typedef T & type; };
+template<typename T> struct ei_unconst<T const *> { typedef T * type; };
+
+template<typename T> struct ei_cleantype { typedef T type; };
+template<typename T> struct ei_cleantype<const T> { typedef typename ei_cleantype<T>::type type; };
+template<typename T> struct ei_cleantype<const T&> { typedef typename ei_cleantype<T>::type type; };
+template<typename T> struct ei_cleantype<T&> { typedef typename ei_cleantype<T>::type type; };
+template<typename T> struct ei_cleantype<const T*> { typedef typename ei_cleantype<T>::type type; };
+template<typename T> struct ei_cleantype<T*> { typedef typename ei_cleantype<T>::type type; };
+
+/** \internal
+ * Convenient struct to get the result type of a unary or binary functor.
+ *
+ * It supports both the current STL mechanism (using the result_type member) as well as
+ * upcoming next STL generation (using a templated result member).
+ * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
+ */
+template<typename T> struct ei_result_of {};
+
+struct ei_has_none {int a[1];};
+struct ei_has_std_result_type {int a[2];};
+struct ei_has_tr1_result {int a[3];};
+
+template<typename Func, typename ArgType, int SizeOf=sizeof(ei_has_none)>
+struct ei_unary_result_of_select {typedef ArgType type;};
+
+template<typename Func, typename ArgType>
+struct ei_unary_result_of_select<Func, ArgType, sizeof(ei_has_std_result_type)> {typedef typename Func::result_type type;};
+
+template<typename Func, typename ArgType>
+struct ei_unary_result_of_select<Func, ArgType, sizeof(ei_has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
+
+template<typename Func, typename ArgType>
+struct ei_result_of<Func(ArgType)> {
+ template<typename T>
+ static ei_has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
+ template<typename T>
+ static ei_has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
+ static ei_has_none testFunctor(...);
+
+ // note that the following indirection is needed for gcc-3.3
+ enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
+ typedef typename ei_unary_result_of_select<Func, ArgType, FunctorType>::type type;
+};
+
+template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(ei_has_none)>
+struct ei_binary_result_of_select {typedef ArgType0 type;};
+
+template<typename Func, typename ArgType0, typename ArgType1>
+struct ei_binary_result_of_select<Func, ArgType0, ArgType1, sizeof(ei_has_std_result_type)>
+{typedef typename Func::result_type type;};
+
+template<typename Func, typename ArgType0, typename ArgType1>
+struct ei_binary_result_of_select<Func, ArgType0, ArgType1, sizeof(ei_has_tr1_result)>
+{typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
+
+template<typename Func, typename ArgType0, typename ArgType1>
+struct ei_result_of<Func(ArgType0,ArgType1)> {
+ template<typename T>
+ static ei_has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
+ template<typename T>
+ static ei_has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
+ static ei_has_none testFunctor(...);
+
+ // note that the following indirection is needed for gcc-3.3
+ enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
+ typedef typename ei_binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
+};
+
+/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
+ * Usage example: \code ei_meta_sqrt<1023>::ret \endcode
+ */
+template<int Y,
+ int InfX = 0,
+ int SupX = ((Y==1) ? 1 : Y/2),
+ bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
+ // use ?: instead of || just to shut up a stupid gcc 4.3 warning
+class ei_meta_sqrt
+{
+ enum {
+ MidX = (InfX+SupX)/2,
+ TakeInf = MidX*MidX > Y ? 1 : 0,
+ NewInf = int(TakeInf) ? InfX : int(MidX),
+ NewSup = int(TakeInf) ? int(MidX) : SupX
+ };
+ public:
+ enum { ret = ei_meta_sqrt<Y,NewInf,NewSup>::ret };
+};
+
+template<int Y, int InfX, int SupX>
+class ei_meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
+
+/** \internal determines whether the product of two numeric types is allowed and what the return type is */
+template<typename T, typename U> struct ei_scalar_product_traits
+{
+ // dummy general case where T and U aren't compatible -- not allowed anyway but we catch it elsewhere
+ //enum { Cost = NumTraits<T>::MulCost };
+ typedef T ReturnType;
+};
+
+template<typename T> struct ei_scalar_product_traits<T,T>
+{
+ //enum { Cost = NumTraits<T>::MulCost };
+ typedef T ReturnType;
+};
+
+template<typename T> struct ei_scalar_product_traits<T,std::complex<T> >
+{
+ //enum { Cost = 2*NumTraits<T>::MulCost };
+ typedef std::complex<T> ReturnType;
+};
+
+template<typename T> struct ei_scalar_product_traits<std::complex<T>, T>
+{
+ //enum { Cost = 2*NumTraits<T>::MulCost };
+ typedef std::complex<T> ReturnType;
+};
+
+// FIXME quick workaround around current limitation of ei_result_of
+template<typename Scalar, typename ArgType0, typename ArgType1>
+struct ei_result_of<ei_scalar_product_op<Scalar>(ArgType0,ArgType1)> {
+typedef typename ei_scalar_product_traits<typename ei_cleantype<ArgType0>::type, typename ei_cleantype<ArgType1>::type>::ReturnType type;
+};
+
+
+
+#endif // EIGEN_META_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/StaticAssert.h b/extern/Eigen2/Eigen/src/Core/util/StaticAssert.h
new file mode 100644
index 00000000000..2c13098a20f
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/StaticAssert.h
@@ -0,0 +1,148 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_STATIC_ASSERT_H
+#define EIGEN_STATIC_ASSERT_H
+
+/* Some notes on Eigen's static assertion mechanism:
+ *
+ * - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean
+ * expression, and MSG an enum listed in struct ei_static_assert<true>
+ *
+ * - define EIGEN_NO_STATIC_ASSERT to disable them (and save compilation time)
+ * in that case, the static assertion is converted to the following runtime assert:
+ * ei_assert(CONDITION && "MSG")
+ *
+ * - currently EIGEN_STATIC_ASSERT can only be used in function scope
+ *
+ */
+
+#ifndef EIGEN_NO_STATIC_ASSERT
+
+ #ifdef __GXX_EXPERIMENTAL_CXX0X__
+
+ // if native static_assert is enabled, let's use it
+ #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
+
+ #else // CXX0X
+
+ template<bool condition>
+ struct ei_static_assert {};
+
+ template<>
+ struct ei_static_assert<true>
+ {
+ enum {
+ YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
+ YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
+ YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES,
+ THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
+ THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
+ YOU_MADE_A_PROGRAMMING_MISTAKE,
+ YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
+ UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC,
+ NUMERIC_TYPE_MUST_BE_FLOATING_POINT,
+ COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED,
+ WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED,
+ THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE,
+ INVALID_MATRIX_PRODUCT,
+ INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS,
+ INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION,
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY,
+ THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
+ THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
+ INVALID_MATRIX_TEMPLATE_PARAMETERS,
+ BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
+ THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX
+ };
+ };
+
+ // Specialized implementation for MSVC to avoid "conditional
+ // expression is constant" warnings. This implementation doesn't
+ // appear to work under GCC, hence the multiple implementations.
+ #ifdef _MSC_VER
+
+ #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
+ {Eigen::ei_static_assert<CONDITION ? true : false>::MSG;}
+
+ #else
+
+ #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
+ if (Eigen::ei_static_assert<CONDITION ? true : false>::MSG) {}
+
+ #endif
+
+ #endif // not CXX0X
+
+#else // EIGEN_NO_STATIC_ASSERT
+
+ #define EIGEN_STATIC_ASSERT(CONDITION,MSG) ei_assert((CONDITION) && #MSG);
+
+#endif // EIGEN_NO_STATIC_ASSERT
+
+
+// static assertion failing if the type \a TYPE is not a vector type
+#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \
+ EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime, \
+ YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX)
+
+// static assertion failing if the type \a TYPE is not fixed-size
+#define EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) \
+ EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime!=Eigen::Dynamic, \
+ YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR)
+
+// static assertion failing if the type \a TYPE is not a vector type of the given size
+#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) \
+ EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime && TYPE::SizeAtCompileTime==SIZE, \
+ THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE)
+
+// static assertion failing if the type \a TYPE is not a vector type of the given size
+#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) \
+ EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime==ROWS && TYPE::ColsAtCompileTime==COLS, \
+ THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
+
+// static assertion failing if the two vector expression types are not compatible (same fixed-size or dynamic size)
+#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) \
+ EIGEN_STATIC_ASSERT( \
+ (int(TYPE0::SizeAtCompileTime)==Eigen::Dynamic \
+ || int(TYPE1::SizeAtCompileTime)==Eigen::Dynamic \
+ || int(TYPE0::SizeAtCompileTime)==int(TYPE1::SizeAtCompileTime)),\
+ YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES)
+
+#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
+ ((int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \
+ || int(TYPE1::RowsAtCompileTime)==Eigen::Dynamic \
+ || int(TYPE0::RowsAtCompileTime)==int(TYPE1::RowsAtCompileTime)) \
+ && (int(TYPE0::ColsAtCompileTime)==Eigen::Dynamic \
+ || int(TYPE1::ColsAtCompileTime)==Eigen::Dynamic \
+ || int(TYPE0::ColsAtCompileTime)==int(TYPE1::ColsAtCompileTime)))
+
+// static assertion failing if it is guaranteed at compile-time that the two matrix expression types have different sizes
+#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
+ EIGEN_STATIC_ASSERT( \
+ EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1),\
+ YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES)
+
+#endif // EIGEN_STATIC_ASSERT_H
diff --git a/extern/Eigen2/Eigen/src/Core/util/XprHelper.h b/extern/Eigen2/Eigen/src/Core/util/XprHelper.h
new file mode 100644
index 00000000000..12d6f9a3a3e
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Core/util/XprHelper.h
@@ -0,0 +1,219 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_XPRHELPER_H
+#define EIGEN_XPRHELPER_H
+
+// just a workaround because GCC seems to not really like empty structs
+#ifdef __GNUG__
+ struct ei_empty_struct{char _ei_dummy_;};
+ #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct
+#else
+ #define EIGEN_EMPTY_STRUCT
+#endif
+
+//classes inheriting ei_no_assignment_operator don't generate a default operator=.
+class ei_no_assignment_operator
+{
+ private:
+ ei_no_assignment_operator& operator=(const ei_no_assignment_operator&);
+};
+
+/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around an int variable that
+ * can be accessed using value() and setValue().
+ * Otherwise, this class is an empty structure and value() just returns the template parameter Value.
+ */
+template<int Value> class ei_int_if_dynamic EIGEN_EMPTY_STRUCT
+{
+ public:
+ ei_int_if_dynamic() {}
+ explicit ei_int_if_dynamic(int) {}
+ static int value() { return Value; }
+ void setValue(int) {}
+};
+
+template<> class ei_int_if_dynamic<Dynamic>
+{
+ int m_value;
+ ei_int_if_dynamic() {}
+ public:
+ explicit ei_int_if_dynamic(int value) : m_value(value) {}
+ int value() const { return m_value; }
+ void setValue(int value) { m_value = value; }
+};
+
+template<typename T> struct ei_functor_traits
+{
+ enum
+ {
+ Cost = 10,
+ PacketAccess = false
+ };
+};
+
+template<typename T> struct ei_packet_traits
+{
+ typedef T type;
+ enum {size=1};
+};
+
+template<typename T> struct ei_unpacket_traits
+{
+ typedef T type;
+ enum {size=1};
+};
+
+template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+class ei_compute_matrix_flags
+{
+ enum {
+ row_major_bit = Options&RowMajor ? RowMajorBit : 0,
+ inner_max_size = row_major_bit ? MaxCols : MaxRows,
+ is_big = inner_max_size == Dynamic,
+ is_packet_size_multiple = (Cols*Rows) % ei_packet_traits<Scalar>::size == 0,
+ aligned_bit = ((Options&AutoAlign) && (is_big || is_packet_size_multiple)) ? AlignedBit : 0,
+ packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
+ };
+
+ public:
+ enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit };
+};
+
+template<int _Rows, int _Cols> struct ei_size_at_compile_time
+{
+ enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
+};
+
+/* ei_eval : the return type of eval(). For matrices, this is just a const reference
+ * in order to avoid a useless copy
+ */
+
+template<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> class ei_eval;
+
+template<typename T> struct ei_eval<T,IsDense>
+{
+ typedef Matrix<typename ei_traits<T>::Scalar,
+ ei_traits<T>::RowsAtCompileTime,
+ ei_traits<T>::ColsAtCompileTime,
+ AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
+ ei_traits<T>::MaxRowsAtCompileTime,
+ ei_traits<T>::MaxColsAtCompileTime
+ > type;
+};
+
+// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
+template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
+struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, IsDense>
+{
+ typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type;
+};
+
+/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type,
+ * whereas ei_eval is a const reference in the case of a matrix
+ */
+template<typename T> struct ei_plain_matrix_type
+{
+ typedef Matrix<typename ei_traits<T>::Scalar,
+ ei_traits<T>::RowsAtCompileTime,
+ ei_traits<T>::ColsAtCompileTime,
+ AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
+ ei_traits<T>::MaxRowsAtCompileTime,
+ ei_traits<T>::MaxColsAtCompileTime
+ > type;
+};
+
+/* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major
+ */
+template<typename T> struct ei_plain_matrix_type_column_major
+{
+ typedef Matrix<typename ei_traits<T>::Scalar,
+ ei_traits<T>::RowsAtCompileTime,
+ ei_traits<T>::ColsAtCompileTime,
+ AutoAlign | ColMajor,
+ ei_traits<T>::MaxRowsAtCompileTime,
+ ei_traits<T>::MaxColsAtCompileTime
+ > type;
+};
+
+template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
+template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; };
+
+/** \internal Determines how a given expression should be nested into another one.
+ * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
+ * nested into the bigger product expression. The choice is between nesting the expression b+c as-is, or
+ * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
+ * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
+ * many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
+ *
+ * \param T the type of the expression being nested
+ * \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
+ *
+ * Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c).
+ * b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it,
+ * the Product expression uses: ei_nested<S, 3>::ret, which turns out to be Matrix3d because the internal logic of
+ * ei_nested determined that in this case it was better to evaluate the expression b+c into a temporary. On the other hand,
+ * since a is of type Matrix3d, the Product expression nests it as ei_nested<Matrix3d, 3>::ret, which turns out to be
+ * const Matrix3d&, because the internal logic of ei_nested determined that since a was already a matrix, there was no point
+ * in copying it into another matrix.
+ */
+template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::type> struct ei_nested
+{
+ enum {
+ CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
+ CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost)
+ };
+ typedef typename ei_meta_if<
+ ei_must_nest_by_value<T>::ret,
+ T,
+ typename ei_meta_if<
+ (int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
+ || ( int(CostEval) <= int(CostNoEval) ),
+ PlainMatrixType,
+ const T&
+ >::ret
+ >::ret type;
+};
+
+template<unsigned int Flags> struct ei_are_flags_consistent
+{
+ enum { ret = !( (Flags&UnitDiagBit && Flags&ZeroDiagBit) )
+ };
+};
+
+/** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size
+ * TODO: could be a good idea to define a big ReturnType struct ??
+ */
+template<typename ExpressionType, int RowsOrSize=Dynamic, int Cols=Dynamic> struct BlockReturnType {
+ typedef Block<ExpressionType, (ei_traits<ExpressionType>::RowsAtCompileTime == 1 ? 1 : RowsOrSize),
+ (ei_traits<ExpressionType>::ColsAtCompileTime == 1 ? 1 : RowsOrSize)> SubVectorType;
+ typedef Block<ExpressionType, RowsOrSize, Cols> Type;
+};
+
+template<typename CurrentType, typename NewType> struct ei_cast_return_type
+{
+ typedef typename ei_meta_if<ei_is_same_type<CurrentType,NewType>::ret,const CurrentType&,NewType>::ret type;
+};
+
+#endif // EIGEN_XPRHELPER_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/AlignedBox.h b/extern/Eigen2/Eigen/src/Geometry/AlignedBox.h
new file mode 100644
index 00000000000..14ec9261e3a
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/AlignedBox.h
@@ -0,0 +1,173 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ALIGNEDBOX_H
+#define EIGEN_ALIGNEDBOX_H
+
+/** \geometry_module \ingroup Geometry_Module
+ * \nonstableyet
+ *
+ * \class AlignedBox
+ *
+ * \brief An axis aligned box
+ *
+ * \param _Scalar the type of the scalar coefficients
+ * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
+ *
+ * This class represents an axis aligned box as a pair of the minimal and maximal corners.
+ */
+template <typename _Scalar, int _AmbientDim>
+class AlignedBox
+{
+public:
+EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1)
+ enum { AmbientDimAtCompileTime = _AmbientDim };
+ typedef _Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
+
+ /** Default constructor initializing a null box. */
+ inline explicit AlignedBox()
+ { if (AmbientDimAtCompileTime!=Dynamic) setNull(); }
+
+ /** Constructs a null box with \a _dim the dimension of the ambient space. */
+ inline explicit AlignedBox(int _dim) : m_min(_dim), m_max(_dim)
+ { setNull(); }
+
+ /** Constructs a box with extremities \a _min and \a _max. */
+ inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_min(_min), m_max(_max) {}
+
+ /** Constructs a box containing a single point \a p. */
+ inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {}
+
+ ~AlignedBox() {}
+
+ /** \returns the dimension in which the box holds */
+ inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; }
+
+ /** \returns true if the box is null, i.e, empty. */
+ inline bool isNull() const { return (m_min.cwise() > m_max).any(); }
+
+ /** Makes \c *this a null/empty box. */
+ inline void setNull()
+ {
+ m_min.setConstant( std::numeric_limits<Scalar>::max());
+ m_max.setConstant(-std::numeric_limits<Scalar>::max());
+ }
+
+ /** \returns the minimal corner */
+ inline const VectorType& min() const { return m_min; }
+ /** \returns a non const reference to the minimal corner */
+ inline VectorType& min() { return m_min; }
+ /** \returns the maximal corner */
+ inline const VectorType& max() const { return m_max; }
+ /** \returns a non const reference to the maximal corner */
+ inline VectorType& max() { return m_max; }
+
+ /** \returns true if the point \a p is inside the box \c *this. */
+ inline bool contains(const VectorType& p) const
+ { return (m_min.cwise()<=p).all() && (p.cwise()<=m_max).all(); }
+
+ /** \returns true if the box \a b is entirely inside the box \c *this. */
+ inline bool contains(const AlignedBox& b) const
+ { return (m_min.cwise()<=b.min()).all() && (b.max().cwise()<=m_max).all(); }
+
+ /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
+ inline AlignedBox& extend(const VectorType& p)
+ { m_min = m_min.cwise().min(p); m_max = m_max.cwise().max(p); return *this; }
+
+ /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */
+ inline AlignedBox& extend(const AlignedBox& b)
+ { m_min = m_min.cwise().min(b.m_min); m_max = m_max.cwise().max(b.m_max); return *this; }
+
+ /** Clamps \c *this by the box \a b and returns a reference to \c *this. */
+ inline AlignedBox& clamp(const AlignedBox& b)
+ { m_min = m_min.cwise().max(b.m_min); m_max = m_max.cwise().min(b.m_max); return *this; }
+
+ /** Translate \c *this by the vector \a t and returns a reference to \c *this. */
+ inline AlignedBox& translate(const VectorType& t)
+ { m_min += t; m_max += t; return *this; }
+
+ /** \returns the squared distance between the point \a p and the box \c *this,
+ * and zero if \a p is inside the box.
+ * \sa exteriorDistance()
+ */
+ inline Scalar squaredExteriorDistance(const VectorType& p) const;
+
+ /** \returns the distance between the point \a p and the box \c *this,
+ * and zero if \a p is inside the box.
+ * \sa squaredExteriorDistance()
+ */
+ inline Scalar exteriorDistance(const VectorType& p) const
+ { return ei_sqrt(squaredExteriorDistance(p)); }
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<AlignedBox,
+ AlignedBox<NewScalarType,AmbientDimAtCompileTime> >::type cast() const
+ {
+ return typename ei_cast_return_type<AlignedBox,
+ AlignedBox<NewScalarType,AmbientDimAtCompileTime> >::type(*this);
+ }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
+ {
+ m_min = other.min().template cast<Scalar>();
+ m_max = other.max().template cast<Scalar>();
+ }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
+
+protected:
+
+ VectorType m_min, m_max;
+};
+
+template<typename Scalar,int AmbiantDim>
+inline Scalar AlignedBox<Scalar,AmbiantDim>::squaredExteriorDistance(const VectorType& p) const
+{
+ Scalar dist2 = 0.;
+ Scalar aux;
+ for (int k=0; k<dim(); ++k)
+ {
+ if ((aux = (p[k]-m_min[k]))<0.)
+ dist2 += aux*aux;
+ else if ( (aux = (m_max[k]-p[k]))<0. )
+ dist2 += aux*aux;
+ }
+ return dist2;
+}
+
+#endif // EIGEN_ALIGNEDBOX_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/AngleAxis.h b/extern/Eigen2/Eigen/src/Geometry/AngleAxis.h
new file mode 100644
index 00000000000..91e3d0d61ec
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/AngleAxis.h
@@ -0,0 +1,228 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ANGLEAXIS_H
+#define EIGEN_ANGLEAXIS_H
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class AngleAxis
+ *
+ * \brief Represents a 3D rotation as a rotation angle around an arbitrary 3D axis
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients.
+ *
+ * The following two typedefs are provided for convenience:
+ * \li \c AngleAxisf for \c float
+ * \li \c AngleAxisd for \c double
+ *
+ * \addexample AngleAxisForEuler \label How to define a rotation from Euler-angles
+ *
+ * Combined with MatrixBase::Unit{X,Y,Z}, AngleAxis can be used to easily
+ * mimic Euler-angles. Here is an example:
+ * \include AngleAxis_mimic_euler.cpp
+ * Output: \verbinclude AngleAxis_mimic_euler.out
+ *
+ * \note This class is not aimed to be used to store a rotation transformation,
+ * but rather to make easier the creation of other rotation (Quaternion, rotation Matrix)
+ * and transformation objects.
+ *
+ * \sa class Quaternion, class Transform, MatrixBase::UnitX()
+ */
+
+template<typename _Scalar> struct ei_traits<AngleAxis<_Scalar> >
+{
+ typedef _Scalar Scalar;
+};
+
+template<typename _Scalar>
+class AngleAxis : public RotationBase<AngleAxis<_Scalar>,3>
+{
+ typedef RotationBase<AngleAxis<_Scalar>,3> Base;
+
+public:
+
+ using Base::operator*;
+
+ enum { Dim = 3 };
+ /** the scalar type of the coefficients */
+ typedef _Scalar Scalar;
+ typedef Matrix<Scalar,3,3> Matrix3;
+ typedef Matrix<Scalar,3,1> Vector3;
+ typedef Quaternion<Scalar> QuaternionType;
+
+protected:
+
+ Vector3 m_axis;
+ Scalar m_angle;
+
+public:
+
+ /** Default constructor without initialization. */
+ AngleAxis() {}
+ /** Constructs and initialize the angle-axis rotation from an \a angle in radian
+ * and an \a axis which must be normalized. */
+ template<typename Derived>
+ inline AngleAxis(Scalar angle, const MatrixBase<Derived>& axis) : m_axis(axis), m_angle(angle) {}
+ /** Constructs and initialize the angle-axis rotation from a quaternion \a q. */
+ inline AngleAxis(const QuaternionType& q) { *this = q; }
+ /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */
+ template<typename Derived>
+ inline explicit AngleAxis(const MatrixBase<Derived>& m) { *this = m; }
+
+ Scalar angle() const { return m_angle; }
+ Scalar& angle() { return m_angle; }
+
+ const Vector3& axis() const { return m_axis; }
+ Vector3& axis() { return m_axis; }
+
+ /** Concatenates two rotations */
+ inline QuaternionType operator* (const AngleAxis& other) const
+ { return QuaternionType(*this) * QuaternionType(other); }
+
+ /** Concatenates two rotations */
+ inline QuaternionType operator* (const QuaternionType& other) const
+ { return QuaternionType(*this) * other; }
+
+ /** Concatenates two rotations */
+ friend inline QuaternionType operator* (const QuaternionType& a, const AngleAxis& b)
+ { return a * QuaternionType(b); }
+
+ /** Concatenates two rotations */
+ inline Matrix3 operator* (const Matrix3& other) const
+ { return toRotationMatrix() * other; }
+
+ /** Concatenates two rotations */
+ inline friend Matrix3 operator* (const Matrix3& a, const AngleAxis& b)
+ { return a * b.toRotationMatrix(); }
+
+ /** Applies rotation to vector */
+ inline Vector3 operator* (const Vector3& other) const
+ { return toRotationMatrix() * other; }
+
+ /** \returns the inverse rotation, i.e., an angle-axis with opposite rotation angle */
+ AngleAxis inverse() const
+ { return AngleAxis(-m_angle, m_axis); }
+
+ AngleAxis& operator=(const QuaternionType& q);
+ template<typename Derived>
+ AngleAxis& operator=(const MatrixBase<Derived>& m);
+
+ template<typename Derived>
+ AngleAxis& fromRotationMatrix(const MatrixBase<Derived>& m);
+ Matrix3 toRotationMatrix(void) const;
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<AngleAxis,AngleAxis<NewScalarType> >::type cast() const
+ { return typename ei_cast_return_type<AngleAxis,AngleAxis<NewScalarType> >::type(*this); }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit AngleAxis(const AngleAxis<OtherScalarType>& other)
+ {
+ m_axis = other.axis().template cast<Scalar>();
+ m_angle = Scalar(other.angle());
+ }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
+};
+
+/** \ingroup Geometry_Module
+ * single precision angle-axis type */
+typedef AngleAxis<float> AngleAxisf;
+/** \ingroup Geometry_Module
+ * double precision angle-axis type */
+typedef AngleAxis<double> AngleAxisd;
+
+/** Set \c *this from a quaternion.
+ * The axis is normalized.
+ */
+template<typename Scalar>
+AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionType& q)
+{
+ Scalar n2 = q.vec().squaredNorm();
+ if (n2 < precision<Scalar>()*precision<Scalar>())
+ {
+ m_angle = 0;
+ m_axis << 1, 0, 0;
+ }
+ else
+ {
+ m_angle = 2*std::acos(q.w());
+ m_axis = q.vec() / ei_sqrt(n2);
+ }
+ return *this;
+}
+
+/** Set \c *this from a 3x3 rotation matrix \a mat.
+ */
+template<typename Scalar>
+template<typename Derived>
+AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const MatrixBase<Derived>& mat)
+{
+ // Since a direct conversion would not be really faster,
+ // let's use the robust Quaternion implementation:
+ return *this = QuaternionType(mat);
+}
+
+/** Constructs and \returns an equivalent 3x3 rotation matrix.
+ */
+template<typename Scalar>
+typename AngleAxis<Scalar>::Matrix3
+AngleAxis<Scalar>::toRotationMatrix(void) const
+{
+ Matrix3 res;
+ Vector3 sin_axis = ei_sin(m_angle) * m_axis;
+ Scalar c = ei_cos(m_angle);
+ Vector3 cos1_axis = (Scalar(1)-c) * m_axis;
+
+ Scalar tmp;
+ tmp = cos1_axis.x() * m_axis.y();
+ res.coeffRef(0,1) = tmp - sin_axis.z();
+ res.coeffRef(1,0) = tmp + sin_axis.z();
+
+ tmp = cos1_axis.x() * m_axis.z();
+ res.coeffRef(0,2) = tmp + sin_axis.y();
+ res.coeffRef(2,0) = tmp - sin_axis.y();
+
+ tmp = cos1_axis.y() * m_axis.z();
+ res.coeffRef(1,2) = tmp - sin_axis.x();
+ res.coeffRef(2,1) = tmp + sin_axis.x();
+
+ res.diagonal() = (cos1_axis.cwise() * m_axis).cwise() + c;
+
+ return res;
+}
+
+#endif // EIGEN_ANGLEAXIS_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/EulerAngles.h b/extern/Eigen2/Eigen/src/Geometry/EulerAngles.h
new file mode 100644
index 00000000000..204118ac94d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/EulerAngles.h
@@ -0,0 +1,96 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_EULERANGLES_H
+#define EIGEN_EULERANGLES_H
+
+/** \geometry_module \ingroup Geometry_Module
+ * \nonstableyet
+ *
+ * \returns the Euler-angles of the rotation matrix \c *this using the convention defined by the triplet (\a a0,\a a1,\a a2)
+ *
+ * Each of the three parameters \a a0,\a a1,\a a2 represents the respective rotation axis as an integer in {0,1,2}.
+ * For instance, in:
+ * \code Vector3f ea = mat.eulerAngles(2, 0, 2); \endcode
+ * "2" represents the z axis and "0" the x axis, etc. The returned angles are such that
+ * we have the following equality:
+ * \code
+ * mat == AngleAxisf(ea[0], Vector3f::UnitZ())
+ * * AngleAxisf(ea[1], Vector3f::UnitX())
+ * * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode
+ * This corresponds to the right-multiply conventions (with right hand side frames).
+ */
+template<typename Derived>
+inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
+MatrixBase<Derived>::eulerAngles(int a0, int a1, int a2) const
+{
+ /* Implemented from Graphics Gems IV */
+ EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)
+
+ Matrix<Scalar,3,1> res;
+ typedef Matrix<typename Derived::Scalar,2,1> Vector2;
+ const Scalar epsilon = precision<Scalar>();
+
+ const int odd = ((a0+1)%3 == a1) ? 0 : 1;
+ const int i = a0;
+ const int j = (a0 + 1 + odd)%3;
+ const int k = (a0 + 2 - odd)%3;
+
+ if (a0==a2)
+ {
+ Scalar s = Vector2(coeff(j,i) , coeff(k,i)).norm();
+ res[1] = ei_atan2(s, coeff(i,i));
+ if (s > epsilon)
+ {
+ res[0] = ei_atan2(coeff(j,i), coeff(k,i));
+ res[2] = ei_atan2(coeff(i,j),-coeff(i,k));
+ }
+ else
+ {
+ res[0] = Scalar(0);
+ res[2] = (coeff(i,i)>0?1:-1)*ei_atan2(-coeff(k,j), coeff(j,j));
+ }
+ }
+ else
+ {
+ Scalar c = Vector2(coeff(i,i) , coeff(i,j)).norm();
+ res[1] = ei_atan2(-coeff(i,k), c);
+ if (c > epsilon)
+ {
+ res[0] = ei_atan2(coeff(j,k), coeff(k,k));
+ res[2] = ei_atan2(coeff(i,j), coeff(i,i));
+ }
+ else
+ {
+ res[0] = Scalar(0);
+ res[2] = (coeff(i,k)>0?1:-1)*ei_atan2(-coeff(k,j), coeff(j,j));
+ }
+ }
+ if (!odd)
+ res = -res;
+ return res;
+}
+
+
+#endif // EIGEN_EULERANGLES_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/Hyperplane.h b/extern/Eigen2/Eigen/src/Geometry/Hyperplane.h
new file mode 100644
index 00000000000..22c530d4be0
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/Hyperplane.h
@@ -0,0 +1,268 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_HYPERPLANE_H
+#define EIGEN_HYPERPLANE_H
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class Hyperplane
+ *
+ * \brief A hyperplane
+ *
+ * A hyperplane is an affine subspace of dimension n-1 in a space of dimension n.
+ * For example, a hyperplane in a plane is a line; a hyperplane in 3-space is a plane.
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients
+ * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
+ * Notice that the dimension of the hyperplane is _AmbientDim-1.
+ *
+ * This class represents an hyperplane as the zero set of the implicit equation
+ * \f$ n \cdot x + d = 0 \f$ where \f$ n \f$ is a unit normal vector of the plane (linear part)
+ * and \f$ d \f$ is the distance (offset) to the origin.
+ */
+template <typename _Scalar, int _AmbientDim>
+class Hyperplane
+{
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1)
+ enum { AmbientDimAtCompileTime = _AmbientDim };
+ typedef _Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
+ typedef Matrix<Scalar,AmbientDimAtCompileTime==Dynamic
+ ? Dynamic
+ : AmbientDimAtCompileTime+1,1> Coefficients;
+ typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
+
+ /** Default constructor without initialization */
+ inline explicit Hyperplane() {}
+
+ /** Constructs a dynamic-size hyperplane with \a _dim the dimension
+ * of the ambient space */
+ inline explicit Hyperplane(int _dim) : m_coeffs(_dim+1) {}
+
+ /** Construct a plane from its normal \a n and a point \a e onto the plane.
+ * \warning the vector normal is assumed to be normalized.
+ */
+ inline Hyperplane(const VectorType& n, const VectorType& e)
+ : m_coeffs(n.size()+1)
+ {
+ normal() = n;
+ offset() = -e.dot(n);
+ }
+
+ /** Constructs a plane from its normal \a n and distance to the origin \a d
+ * such that the algebraic equation of the plane is \f$ n \cdot x + d = 0 \f$.
+ * \warning the vector normal is assumed to be normalized.
+ */
+ inline Hyperplane(const VectorType& n, Scalar d)
+ : m_coeffs(n.size()+1)
+ {
+ normal() = n;
+ offset() = d;
+ }
+
+ /** Constructs a hyperplane passing through the two points. If the dimension of the ambient space
+ * is greater than 2, then there isn't uniqueness, so an arbitrary choice is made.
+ */
+ static inline Hyperplane Through(const VectorType& p0, const VectorType& p1)
+ {
+ Hyperplane result(p0.size());
+ result.normal() = (p1 - p0).unitOrthogonal();
+ result.offset() = -result.normal().dot(p0);
+ return result;
+ }
+
+ /** Constructs a hyperplane passing through the three points. The dimension of the ambient space
+ * is required to be exactly 3.
+ */
+ static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2)
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3)
+ Hyperplane result(p0.size());
+ result.normal() = (p2 - p0).cross(p1 - p0).normalized();
+ result.offset() = -result.normal().dot(p0);
+ return result;
+ }
+
+ /** Constructs a hyperplane passing through the parametrized line \a parametrized.
+ * If the dimension of the ambient space is greater than 2, then there isn't uniqueness,
+ * so an arbitrary choice is made.
+ */
+ // FIXME to be consitent with the rest this could be implemented as a static Through function ??
+ explicit Hyperplane(const ParametrizedLine<Scalar, AmbientDimAtCompileTime>& parametrized)
+ {
+ normal() = parametrized.direction().unitOrthogonal();
+ offset() = -normal().dot(parametrized.origin());
+ }
+
+ ~Hyperplane() {}
+
+ /** \returns the dimension in which the plane holds */
+ inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_coeffs.size()-1 : AmbientDimAtCompileTime; }
+
+ /** normalizes \c *this */
+ void normalize(void)
+ {
+ m_coeffs /= normal().norm();
+ }
+
+ /** \returns the signed distance between the plane \c *this and a point \a p.
+ * \sa absDistance()
+ */
+ inline Scalar signedDistance(const VectorType& p) const { return p.dot(normal()) + offset(); }
+
+ /** \returns the absolute distance between the plane \c *this and a point \a p.
+ * \sa signedDistance()
+ */
+ inline Scalar absDistance(const VectorType& p) const { return ei_abs(signedDistance(p)); }
+
+ /** \returns the projection of a point \a p onto the plane \c *this.
+ */
+ inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); }
+
+ /** \returns a constant reference to the unit normal vector of the plane, which corresponds
+ * to the linear part of the implicit equation.
+ */
+ inline const NormalReturnType normal() const { return NormalReturnType(m_coeffs,0,0,dim(),1); }
+
+ /** \returns a non-constant reference to the unit normal vector of the plane, which corresponds
+ * to the linear part of the implicit equation.
+ */
+ inline NormalReturnType normal() { return NormalReturnType(m_coeffs,0,0,dim(),1); }
+
+ /** \returns the distance to the origin, which is also the "constant term" of the implicit equation
+ * \warning the vector normal is assumed to be normalized.
+ */
+ inline const Scalar& offset() const { return m_coeffs.coeff(dim()); }
+
+ /** \returns a non-constant reference to the distance to the origin, which is also the constant part
+ * of the implicit equation */
+ inline Scalar& offset() { return m_coeffs(dim()); }
+
+ /** \returns a constant reference to the coefficients c_i of the plane equation:
+ * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$
+ */
+ inline const Coefficients& coeffs() const { return m_coeffs; }
+
+ /** \returns a non-constant reference to the coefficients c_i of the plane equation:
+ * \f$ c_0*x_0 + ... + c_{d-1}*x_{d-1} + c_d = 0 \f$
+ */
+ inline Coefficients& coeffs() { return m_coeffs; }
+
+ /** \returns the intersection of *this with \a other.
+ *
+ * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines.
+ *
+ * \note If \a other is approximately parallel to *this, this method will return any point on *this.
+ */
+ VectorType intersection(const Hyperplane& other)
+ {
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
+ Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
+ // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests
+ // whether the two lines are approximately parallel.
+ if(ei_isMuchSmallerThan(det, Scalar(1)))
+ { // special case where the two lines are approximately parallel. Pick any point on the first line.
+ if(ei_abs(coeffs().coeff(1))>ei_abs(coeffs().coeff(0)))
+ return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0));
+ else
+ return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0));
+ }
+ else
+ { // general case
+ Scalar invdet = Scalar(1) / det;
+ return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)),
+ invdet*(other.coeffs().coeff(0)*coeffs().coeff(2)-coeffs().coeff(0)*other.coeffs().coeff(2)));
+ }
+ }
+
+ /** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this.
+ *
+ * \param mat the Dim x Dim transformation matrix
+ * \param traits specifies whether the matrix \a mat represents an Isometry
+ * or a more generic Affine transformation. The default is Affine.
+ */
+ template<typename XprType>
+ inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
+ {
+ if (traits==Affine)
+ normal() = mat.inverse().transpose() * normal();
+ else if (traits==Isometry)
+ normal() = mat * normal();
+ else
+ {
+ ei_assert("invalid traits value in Hyperplane::transform()");
+ }
+ return *this;
+ }
+
+ /** Applies the transformation \a t to \c *this and returns a reference to \c *this.
+ *
+ * \param t the transformation of dimension Dim
+ * \param traits specifies whether the transformation \a t represents an Isometry
+ * or a more generic Affine transformation. The default is Affine.
+ * Other kind of transformations are not supported.
+ */
+ inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime>& t,
+ TransformTraits traits = Affine)
+ {
+ transform(t.linear(), traits);
+ offset() -= t.translation().dot(normal());
+ return *this;
+ }
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<Hyperplane,
+ Hyperplane<NewScalarType,AmbientDimAtCompileTime> >::type cast() const
+ {
+ return typename ei_cast_return_type<Hyperplane,
+ Hyperplane<NewScalarType,AmbientDimAtCompileTime> >::type(*this);
+ }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit Hyperplane(const Hyperplane<OtherScalarType,AmbientDimAtCompileTime>& other)
+ { m_coeffs = other.coeffs().template cast<Scalar>(); }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_coeffs.isApprox(other.m_coeffs, prec); }
+
+protected:
+
+ Coefficients m_coeffs;
+};
+
+#endif // EIGEN_HYPERPLANE_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/OrthoMethods.h b/extern/Eigen2/Eigen/src/Geometry/OrthoMethods.h
new file mode 100644
index 00000000000..047152d0b99
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/OrthoMethods.h
@@ -0,0 +1,119 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ORTHOMETHODS_H
+#define EIGEN_ORTHOMETHODS_H
+
+/** \geometry_module
+ *
+ * \returns the cross product of \c *this and \a other
+ *
+ * Here is a very good explanation of cross-product: http://xkcd.com/199/
+ */
+template<typename Derived>
+template<typename OtherDerived>
+inline typename MatrixBase<Derived>::PlainMatrixType
+MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3)
+
+ // Note that there is no need for an expression here since the compiler
+ // optimize such a small temporary very well (even within a complex expression)
+ const typename ei_nested<Derived,2>::type lhs(derived());
+ const typename ei_nested<OtherDerived,2>::type rhs(other.derived());
+ return typename ei_plain_matrix_type<Derived>::type(
+ lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1),
+ lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2),
+ lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)
+ );
+}
+
+template<typename Derived, int Size = Derived::SizeAtCompileTime>
+struct ei_unitOrthogonal_selector
+{
+ typedef typename ei_plain_matrix_type<Derived>::type VectorType;
+ typedef typename ei_traits<Derived>::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ inline static VectorType run(const Derived& src)
+ {
+ VectorType perp(src.size());
+ /* Let us compute the crossed product of *this with a vector
+ * that is not too close to being colinear to *this.
+ */
+
+ /* unless the x and y coords are both close to zero, we can
+ * simply take ( -y, x, 0 ) and normalize it.
+ */
+ if((!ei_isMuchSmallerThan(src.x(), src.z()))
+ || (!ei_isMuchSmallerThan(src.y(), src.z())))
+ {
+ RealScalar invnm = RealScalar(1)/src.template start<2>().norm();
+ perp.coeffRef(0) = -ei_conj(src.y())*invnm;
+ perp.coeffRef(1) = ei_conj(src.x())*invnm;
+ perp.coeffRef(2) = 0;
+ }
+ /* if both x and y are close to zero, then the vector is close
+ * to the z-axis, so it's far from colinear to the x-axis for instance.
+ * So we take the crossed product with (1,0,0) and normalize it.
+ */
+ else
+ {
+ RealScalar invnm = RealScalar(1)/src.template end<2>().norm();
+ perp.coeffRef(0) = 0;
+ perp.coeffRef(1) = -ei_conj(src.z())*invnm;
+ perp.coeffRef(2) = ei_conj(src.y())*invnm;
+ }
+ if( (Derived::SizeAtCompileTime!=Dynamic && Derived::SizeAtCompileTime>3)
+ || (Derived::SizeAtCompileTime==Dynamic && src.size()>3) )
+ perp.end(src.size()-3).setZero();
+
+ return perp;
+ }
+};
+
+template<typename Derived>
+struct ei_unitOrthogonal_selector<Derived,2>
+{
+ typedef typename ei_plain_matrix_type<Derived>::type VectorType;
+ inline static VectorType run(const Derived& src)
+ { return VectorType(-ei_conj(src.y()), ei_conj(src.x())).normalized(); }
+};
+
+/** \returns a unit vector which is orthogonal to \c *this
+ *
+ * The size of \c *this must be at least 2. If the size is exactly 2,
+ * then the returned vector is a counter clock wise rotation of \c *this, i.e., (-y,x).normalized().
+ *
+ * \sa cross()
+ */
+template<typename Derived>
+typename MatrixBase<Derived>::PlainMatrixType
+MatrixBase<Derived>::unitOrthogonal() const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return ei_unitOrthogonal_selector<Derived>::run(derived());
+}
+
+#endif // EIGEN_ORTHOMETHODS_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/ParametrizedLine.h b/extern/Eigen2/Eigen/src/Geometry/ParametrizedLine.h
new file mode 100644
index 00000000000..2b990d084f0
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/ParametrizedLine.h
@@ -0,0 +1,155 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_PARAMETRIZEDLINE_H
+#define EIGEN_PARAMETRIZEDLINE_H
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class ParametrizedLine
+ *
+ * \brief A parametrized line
+ *
+ * A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit
+ * direction vector \f$ \mathbf{d} \f$ such that the line corresponds to
+ * the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ l \in \mathbf{R} \f$.
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients
+ * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
+ */
+template <typename _Scalar, int _AmbientDim>
+class ParametrizedLine
+{
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
+ enum { AmbientDimAtCompileTime = _AmbientDim };
+ typedef _Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
+
+ /** Default constructor without initialization */
+ inline explicit ParametrizedLine() {}
+
+ /** Constructs a dynamic-size line with \a _dim the dimension
+ * of the ambient space */
+ inline explicit ParametrizedLine(int _dim) : m_origin(_dim), m_direction(_dim) {}
+
+ /** Initializes a parametrized line of direction \a direction and origin \a origin.
+ * \warning the vector direction is assumed to be normalized.
+ */
+ ParametrizedLine(const VectorType& origin, const VectorType& direction)
+ : m_origin(origin), m_direction(direction) {}
+
+ explicit ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim>& hyperplane);
+
+ /** Constructs a parametrized line going from \a p0 to \a p1. */
+ static inline ParametrizedLine Through(const VectorType& p0, const VectorType& p1)
+ { return ParametrizedLine(p0, (p1-p0).normalized()); }
+
+ ~ParametrizedLine() {}
+
+ /** \returns the dimension in which the line holds */
+ inline int dim() const { return m_direction.size(); }
+
+ const VectorType& origin() const { return m_origin; }
+ VectorType& origin() { return m_origin; }
+
+ const VectorType& direction() const { return m_direction; }
+ VectorType& direction() { return m_direction; }
+
+ /** \returns the squared distance of a point \a p to its projection onto the line \c *this.
+ * \sa distance()
+ */
+ RealScalar squaredDistance(const VectorType& p) const
+ {
+ VectorType diff = p-origin();
+ return (diff - diff.dot(direction())* direction()).squaredNorm();
+ }
+ /** \returns the distance of a point \a p to its projection onto the line \c *this.
+ * \sa squaredDistance()
+ */
+ RealScalar distance(const VectorType& p) const { return ei_sqrt(squaredDistance(p)); }
+
+ /** \returns the projection of a point \a p onto the line \c *this. */
+ VectorType projection(const VectorType& p) const
+ { return origin() + (p-origin()).dot(direction()) * direction(); }
+
+ Scalar intersection(const Hyperplane<_Scalar, _AmbientDim>& hyperplane);
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<ParametrizedLine,
+ ParametrizedLine<NewScalarType,AmbientDimAtCompileTime> >::type cast() const
+ {
+ return typename ei_cast_return_type<ParametrizedLine,
+ ParametrizedLine<NewScalarType,AmbientDimAtCompileTime> >::type(*this);
+ }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit ParametrizedLine(const ParametrizedLine<OtherScalarType,AmbientDimAtCompileTime>& other)
+ {
+ m_origin = other.origin().template cast<Scalar>();
+ m_direction = other.direction().template cast<Scalar>();
+ }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
+
+protected:
+
+ VectorType m_origin, m_direction;
+};
+
+/** Constructs a parametrized line from a 2D hyperplane
+ *
+ * \warning the ambient space must have dimension 2 such that the hyperplane actually describes a line
+ */
+template <typename _Scalar, int _AmbientDim>
+inline ParametrizedLine<_Scalar, _AmbientDim>::ParametrizedLine(const Hyperplane<_Scalar, _AmbientDim>& hyperplane)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
+ direction() = hyperplane.normal().unitOrthogonal();
+ origin() = -hyperplane.normal()*hyperplane.offset();
+}
+
+/** \returns the parameter value of the intersection between \c *this and the given hyperplane
+ */
+template <typename _Scalar, int _AmbientDim>
+inline _Scalar ParametrizedLine<_Scalar, _AmbientDim>::intersection(const Hyperplane<_Scalar, _AmbientDim>& hyperplane)
+{
+ return -(hyperplane.offset()+origin().dot(hyperplane.normal()))
+ /(direction().dot(hyperplane.normal()));
+}
+
+#endif // EIGEN_PARAMETRIZEDLINE_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/Quaternion.h b/extern/Eigen2/Eigen/src/Geometry/Quaternion.h
new file mode 100644
index 00000000000..3fcbff4e71d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/Quaternion.h
@@ -0,0 +1,521 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_QUATERNION_H
+#define EIGEN_QUATERNION_H
+
+template<typename Other,
+ int OtherRows=Other::RowsAtCompileTime,
+ int OtherCols=Other::ColsAtCompileTime>
+struct ei_quaternion_assign_impl;
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class Quaternion
+ *
+ * \brief The quaternion class used to represent 3D orientations and rotations
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients
+ *
+ * This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of
+ * orientations and rotations of objects in three dimensions. Compared to other representations
+ * like Euler angles or 3x3 matrices, quatertions offer the following advantages:
+ * \li \b compact storage (4 scalars)
+ * \li \b efficient to compose (28 flops),
+ * \li \b stable spherical interpolation
+ *
+ * The following two typedefs are provided for convenience:
+ * \li \c Quaternionf for \c float
+ * \li \c Quaterniond for \c double
+ *
+ * \sa class AngleAxis, class Transform
+ */
+
+template<typename _Scalar> struct ei_traits<Quaternion<_Scalar> >
+{
+ typedef _Scalar Scalar;
+};
+
+template<typename _Scalar>
+class Quaternion : public RotationBase<Quaternion<_Scalar>,3>
+{
+ typedef RotationBase<Quaternion<_Scalar>,3> Base;
+
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,4)
+
+ using Base::operator*;
+
+ /** the scalar type of the coefficients */
+ typedef _Scalar Scalar;
+
+ /** the type of the Coefficients 4-vector */
+ typedef Matrix<Scalar, 4, 1> Coefficients;
+ /** the type of a 3D vector */
+ typedef Matrix<Scalar,3,1> Vector3;
+ /** the equivalent rotation matrix type */
+ typedef Matrix<Scalar,3,3> Matrix3;
+ /** the equivalent angle-axis type */
+ typedef AngleAxis<Scalar> AngleAxisType;
+
+ /** \returns the \c x coefficient */
+ inline Scalar x() const { return m_coeffs.coeff(0); }
+ /** \returns the \c y coefficient */
+ inline Scalar y() const { return m_coeffs.coeff(1); }
+ /** \returns the \c z coefficient */
+ inline Scalar z() const { return m_coeffs.coeff(2); }
+ /** \returns the \c w coefficient */
+ inline Scalar w() const { return m_coeffs.coeff(3); }
+
+ /** \returns a reference to the \c x coefficient */
+ inline Scalar& x() { return m_coeffs.coeffRef(0); }
+ /** \returns a reference to the \c y coefficient */
+ inline Scalar& y() { return m_coeffs.coeffRef(1); }
+ /** \returns a reference to the \c z coefficient */
+ inline Scalar& z() { return m_coeffs.coeffRef(2); }
+ /** \returns a reference to the \c w coefficient */
+ inline Scalar& w() { return m_coeffs.coeffRef(3); }
+
+ /** \returns a read-only vector expression of the imaginary part (x,y,z) */
+ inline const Block<Coefficients,3,1> vec() const { return m_coeffs.template start<3>(); }
+
+ /** \returns a vector expression of the imaginary part (x,y,z) */
+ inline Block<Coefficients,3,1> vec() { return m_coeffs.template start<3>(); }
+
+ /** \returns a read-only vector expression of the coefficients (x,y,z,w) */
+ inline const Coefficients& coeffs() const { return m_coeffs; }
+
+ /** \returns a vector expression of the coefficients (x,y,z,w) */
+ inline Coefficients& coeffs() { return m_coeffs; }
+
+ /** Default constructor leaving the quaternion uninitialized. */
+ inline Quaternion() {}
+
+ /** Constructs and initializes the quaternion \f$ w+xi+yj+zk \f$ from
+ * its four coefficients \a w, \a x, \a y and \a z.
+ *
+ * \warning Note the order of the arguments: the real \a w coefficient first,
+ * while internally the coefficients are stored in the following order:
+ * [\c x, \c y, \c z, \c w]
+ */
+ inline Quaternion(Scalar w, Scalar x, Scalar y, Scalar z)
+ { m_coeffs << x, y, z, w; }
+
+ /** Copy constructor */
+ inline Quaternion(const Quaternion& other) { m_coeffs = other.m_coeffs; }
+
+ /** Constructs and initializes a quaternion from the angle-axis \a aa */
+ explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; }
+
+ /** Constructs and initializes a quaternion from either:
+ * - a rotation matrix expression,
+ * - a 4D vector expression representing quaternion coefficients.
+ * \sa operator=(MatrixBase<Derived>)
+ */
+ template<typename Derived>
+ explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
+
+ Quaternion& operator=(const Quaternion& other);
+ Quaternion& operator=(const AngleAxisType& aa);
+ template<typename Derived>
+ Quaternion& operator=(const MatrixBase<Derived>& m);
+
+ /** \returns a quaternion representing an identity rotation
+ * \sa MatrixBase::Identity()
+ */
+ inline static Quaternion Identity() { return Quaternion(1, 0, 0, 0); }
+
+ /** \sa Quaternion::Identity(), MatrixBase::setIdentity()
+ */
+ inline Quaternion& setIdentity() { m_coeffs << 0, 0, 0, 1; return *this; }
+
+ /** \returns the squared norm of the quaternion's coefficients
+ * \sa Quaternion::norm(), MatrixBase::squaredNorm()
+ */
+ inline Scalar squaredNorm() const { return m_coeffs.squaredNorm(); }
+
+ /** \returns the norm of the quaternion's coefficients
+ * \sa Quaternion::squaredNorm(), MatrixBase::norm()
+ */
+ inline Scalar norm() const { return m_coeffs.norm(); }
+
+ /** Normalizes the quaternion \c *this
+ * \sa normalized(), MatrixBase::normalize() */
+ inline void normalize() { m_coeffs.normalize(); }
+ /** \returns a normalized version of \c *this
+ * \sa normalize(), MatrixBase::normalized() */
+ inline Quaternion normalized() const { return Quaternion(m_coeffs.normalized()); }
+
+ /** \returns the dot product of \c *this and \a other
+ * Geometrically speaking, the dot product of two unit quaternions
+ * corresponds to the cosine of half the angle between the two rotations.
+ * \sa angularDistance()
+ */
+ inline Scalar dot(const Quaternion& other) const { return m_coeffs.dot(other.m_coeffs); }
+
+ inline Scalar angularDistance(const Quaternion& other) const;
+
+ Matrix3 toRotationMatrix(void) const;
+
+ template<typename Derived1, typename Derived2>
+ Quaternion& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
+
+ inline Quaternion operator* (const Quaternion& q) const;
+ inline Quaternion& operator*= (const Quaternion& q);
+
+ Quaternion inverse(void) const;
+ Quaternion conjugate(void) const;
+
+ Quaternion slerp(Scalar t, const Quaternion& other) const;
+
+ template<typename Derived>
+ Vector3 operator* (const MatrixBase<Derived>& vec) const;
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<Quaternion,Quaternion<NewScalarType> >::type cast() const
+ { return typename ei_cast_return_type<Quaternion,Quaternion<NewScalarType> >::type(*this); }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit Quaternion(const Quaternion<OtherScalarType>& other)
+ { m_coeffs = other.coeffs().template cast<Scalar>(); }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const Quaternion& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_coeffs.isApprox(other.m_coeffs, prec); }
+
+protected:
+ Coefficients m_coeffs;
+};
+
+/** \ingroup Geometry_Module
+ * single precision quaternion type */
+typedef Quaternion<float> Quaternionf;
+/** \ingroup Geometry_Module
+ * double precision quaternion type */
+typedef Quaternion<double> Quaterniond;
+
+// Generic Quaternion * Quaternion product
+template<int Arch,typename Scalar> inline Quaternion<Scalar>
+ei_quaternion_product(const Quaternion<Scalar>& a, const Quaternion<Scalar>& b)
+{
+ return Quaternion<Scalar>
+ (
+ a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(),
+ a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(),
+ a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(),
+ a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x()
+ );
+}
+
+#ifdef EIGEN_VECTORIZE_SSE
+template<> inline Quaternion<float>
+ei_quaternion_product<EiArch_SSE,float>(const Quaternion<float>& _a, const Quaternion<float>& _b)
+{
+ const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0,0,0,0x80000000));
+ Quaternion<float> res;
+ __m128 a = _a.coeffs().packet<Aligned>(0);
+ __m128 b = _b.coeffs().packet<Aligned>(0);
+ __m128 flip1 = _mm_xor_ps(_mm_mul_ps(ei_vec4f_swizzle1(a,1,2,0,2),
+ ei_vec4f_swizzle1(b,2,0,1,2)),mask);
+ __m128 flip2 = _mm_xor_ps(_mm_mul_ps(ei_vec4f_swizzle1(a,3,3,3,1),
+ ei_vec4f_swizzle1(b,0,1,2,1)),mask);
+ ei_pstore(&res.x(),
+ _mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,ei_vec4f_swizzle1(b,3,3,3,3)),
+ _mm_mul_ps(ei_vec4f_swizzle1(a,2,0,1,0),
+ ei_vec4f_swizzle1(b,1,2,0,0))),
+ _mm_add_ps(flip1,flip2)));
+ return res;
+}
+#endif
+
+/** \returns the concatenation of two rotations as a quaternion-quaternion product */
+template <typename Scalar>
+inline Quaternion<Scalar> Quaternion<Scalar>::operator* (const Quaternion& other) const
+{
+ return ei_quaternion_product<EiArch>(*this,other);
+}
+
+/** \sa operator*(Quaternion) */
+template <typename Scalar>
+inline Quaternion<Scalar>& Quaternion<Scalar>::operator*= (const Quaternion& other)
+{
+ return (*this = *this * other);
+}
+
+/** Rotation of a vector by a quaternion.
+ * \remarks If the quaternion is used to rotate several points (>1)
+ * then it is much more efficient to first convert it to a 3x3 Matrix.
+ * Comparison of the operation cost for n transformations:
+ * - Quaternion: 30n
+ * - Via a Matrix3: 24 + 15n
+ */
+template <typename Scalar>
+template<typename Derived>
+inline typename Quaternion<Scalar>::Vector3
+Quaternion<Scalar>::operator* (const MatrixBase<Derived>& v) const
+{
+ // Note that this algorithm comes from the optimization by hand
+ // of the conversion to a Matrix followed by a Matrix/Vector product.
+ // It appears to be much faster than the common algorithm found
+ // in the litterature (30 versus 39 flops). It also requires two
+ // Vector3 as temporaries.
+ Vector3 uv;
+ uv = 2 * this->vec().cross(v);
+ return v + this->w() * uv + this->vec().cross(uv);
+}
+
+template<typename Scalar>
+inline Quaternion<Scalar>& Quaternion<Scalar>::operator=(const Quaternion& other)
+{
+ m_coeffs = other.m_coeffs;
+ return *this;
+}
+
+/** Set \c *this from an angle-axis \a aa and returns a reference to \c *this
+ */
+template<typename Scalar>
+inline Quaternion<Scalar>& Quaternion<Scalar>::operator=(const AngleAxisType& aa)
+{
+ Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
+ this->w() = ei_cos(ha);
+ this->vec() = ei_sin(ha) * aa.axis();
+ return *this;
+}
+
+/** Set \c *this from the expression \a xpr:
+ * - if \a xpr is a 4x1 vector, then \a xpr is assumed to be a quaternion
+ * - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix
+ * and \a xpr is converted to a quaternion
+ */
+template<typename Scalar>
+template<typename Derived>
+inline Quaternion<Scalar>& Quaternion<Scalar>::operator=(const MatrixBase<Derived>& xpr)
+{
+ ei_quaternion_assign_impl<Derived>::run(*this, xpr.derived());
+ return *this;
+}
+
+/** Convert the quaternion to a 3x3 rotation matrix */
+template<typename Scalar>
+inline typename Quaternion<Scalar>::Matrix3
+Quaternion<Scalar>::toRotationMatrix(void) const
+{
+ // NOTE if inlined, then gcc 4.2 and 4.4 get rid of the temporary (not gcc 4.3 !!)
+ // if not inlined then the cost of the return by value is huge ~ +35%,
+ // however, not inlining this function is an order of magnitude slower, so
+ // it has to be inlined, and so the return by value is not an issue
+ Matrix3 res;
+
+ const Scalar tx = 2*this->x();
+ const Scalar ty = 2*this->y();
+ const Scalar tz = 2*this->z();
+ const Scalar twx = tx*this->w();
+ const Scalar twy = ty*this->w();
+ const Scalar twz = tz*this->w();
+ const Scalar txx = tx*this->x();
+ const Scalar txy = ty*this->x();
+ const Scalar txz = tz*this->x();
+ const Scalar tyy = ty*this->y();
+ const Scalar tyz = tz*this->y();
+ const Scalar tzz = tz*this->z();
+
+ res.coeffRef(0,0) = 1-(tyy+tzz);
+ res.coeffRef(0,1) = txy-twz;
+ res.coeffRef(0,2) = txz+twy;
+ res.coeffRef(1,0) = txy+twz;
+ res.coeffRef(1,1) = 1-(txx+tzz);
+ res.coeffRef(1,2) = tyz-twx;
+ res.coeffRef(2,0) = txz-twy;
+ res.coeffRef(2,1) = tyz+twx;
+ res.coeffRef(2,2) = 1-(txx+tyy);
+
+ return res;
+}
+
+/** Sets *this to be a quaternion representing a rotation sending the vector \a a to the vector \a b.
+ *
+ * \returns a reference to *this.
+ *
+ * Note that the two input vectors do \b not have to be normalized.
+ */
+template<typename Scalar>
+template<typename Derived1, typename Derived2>
+inline Quaternion<Scalar>& Quaternion<Scalar>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
+{
+ Vector3 v0 = a.normalized();
+ Vector3 v1 = b.normalized();
+ Scalar c = v0.dot(v1);
+
+ // if dot == 1, vectors are the same
+ if (ei_isApprox(c,Scalar(1)))
+ {
+ // set to identity
+ this->w() = 1; this->vec().setZero();
+ return *this;
+ }
+ // if dot == -1, vectors are opposites
+ if (ei_isApprox(c,Scalar(-1)))
+ {
+ this->vec() = v0.unitOrthogonal();
+ this->w() = 0;
+ return *this;
+ }
+
+ Vector3 axis = v0.cross(v1);
+ Scalar s = ei_sqrt((Scalar(1)+c)*Scalar(2));
+ Scalar invs = Scalar(1)/s;
+ this->vec() = axis * invs;
+ this->w() = s * Scalar(0.5);
+
+ return *this;
+}
+
+/** \returns the multiplicative inverse of \c *this
+ * Note that in most cases, i.e., if you simply want the opposite rotation,
+ * and/or the quaternion is normalized, then it is enough to use the conjugate.
+ *
+ * \sa Quaternion::conjugate()
+ */
+template <typename Scalar>
+inline Quaternion<Scalar> Quaternion<Scalar>::inverse() const
+{
+ // FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite() ??
+ Scalar n2 = this->squaredNorm();
+ if (n2 > 0)
+ return Quaternion(conjugate().coeffs() / n2);
+ else
+ {
+ // return an invalid result to flag the error
+ return Quaternion(Coefficients::Zero());
+ }
+}
+
+/** \returns the conjugate of the \c *this which is equal to the multiplicative inverse
+ * if the quaternion is normalized.
+ * The conjugate of a quaternion represents the opposite rotation.
+ *
+ * \sa Quaternion::inverse()
+ */
+template <typename Scalar>
+inline Quaternion<Scalar> Quaternion<Scalar>::conjugate() const
+{
+ return Quaternion(this->w(),-this->x(),-this->y(),-this->z());
+}
+
+/** \returns the angle (in radian) between two rotations
+ * \sa dot()
+ */
+template <typename Scalar>
+inline Scalar Quaternion<Scalar>::angularDistance(const Quaternion& other) const
+{
+ double d = ei_abs(this->dot(other));
+ if (d>=1.0)
+ return 0;
+ return Scalar(2) * std::acos(d);
+}
+
+/** \returns the spherical linear interpolation between the two quaternions
+ * \c *this and \a other at the parameter \a t
+ */
+template <typename Scalar>
+Quaternion<Scalar> Quaternion<Scalar>::slerp(Scalar t, const Quaternion& other) const
+{
+ static const Scalar one = Scalar(1) - precision<Scalar>();
+ Scalar d = this->dot(other);
+ Scalar absD = ei_abs(d);
+ if (absD>=one)
+ return *this;
+
+ // theta is the angle between the 2 quaternions
+ Scalar theta = std::acos(absD);
+ Scalar sinTheta = ei_sin(theta);
+
+ Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+
+ return Quaternion(scale0 * m_coeffs + scale1 * other.m_coeffs);
+}
+
+// set from a rotation matrix
+template<typename Other>
+struct ei_quaternion_assign_impl<Other,3,3>
+{
+ typedef typename Other::Scalar Scalar;
+ inline static void run(Quaternion<Scalar>& q, const Other& mat)
+ {
+ // This algorithm comes from "Quaternion Calculus and Fast Animation",
+ // Ken Shoemake, 1987 SIGGRAPH course notes
+ Scalar t = mat.trace();
+ if (t > 0)
+ {
+ t = ei_sqrt(t + Scalar(1.0));
+ q.w() = Scalar(0.5)*t;
+ t = Scalar(0.5)/t;
+ q.x() = (mat.coeff(2,1) - mat.coeff(1,2)) * t;
+ q.y() = (mat.coeff(0,2) - mat.coeff(2,0)) * t;
+ q.z() = (mat.coeff(1,0) - mat.coeff(0,1)) * t;
+ }
+ else
+ {
+ int i = 0;
+ if (mat.coeff(1,1) > mat.coeff(0,0))
+ i = 1;
+ if (mat.coeff(2,2) > mat.coeff(i,i))
+ i = 2;
+ int j = (i+1)%3;
+ int k = (j+1)%3;
+
+ t = ei_sqrt(mat.coeff(i,i)-mat.coeff(j,j)-mat.coeff(k,k) + Scalar(1.0));
+ q.coeffs().coeffRef(i) = Scalar(0.5) * t;
+ t = Scalar(0.5)/t;
+ q.w() = (mat.coeff(k,j)-mat.coeff(j,k))*t;
+ q.coeffs().coeffRef(j) = (mat.coeff(j,i)+mat.coeff(i,j))*t;
+ q.coeffs().coeffRef(k) = (mat.coeff(k,i)+mat.coeff(i,k))*t;
+ }
+ }
+};
+
+// set from a vector of coefficients assumed to be a quaternion
+template<typename Other>
+struct ei_quaternion_assign_impl<Other,4,1>
+{
+ typedef typename Other::Scalar Scalar;
+ inline static void run(Quaternion<Scalar>& q, const Other& vec)
+ {
+ q.coeffs() = vec;
+ }
+};
+
+#endif // EIGEN_QUATERNION_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/Rotation2D.h b/extern/Eigen2/Eigen/src/Geometry/Rotation2D.h
new file mode 100644
index 00000000000..dca7f06bf5d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/Rotation2D.h
@@ -0,0 +1,159 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ROTATION2D_H
+#define EIGEN_ROTATION2D_H
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class Rotation2D
+ *
+ * \brief Represents a rotation/orientation in a 2 dimensional space.
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients
+ *
+ * This class is equivalent to a single scalar representing a counter clock wise rotation
+ * as a single angle in radian. It provides some additional features such as the automatic
+ * conversion from/to a 2x2 rotation matrix. Moreover this class aims to provide a similar
+ * interface to Quaternion in order to facilitate the writing of generic algorithms
+ * dealing with rotations.
+ *
+ * \sa class Quaternion, class Transform
+ */
+template<typename _Scalar> struct ei_traits<Rotation2D<_Scalar> >
+{
+ typedef _Scalar Scalar;
+};
+
+template<typename _Scalar>
+class Rotation2D : public RotationBase<Rotation2D<_Scalar>,2>
+{
+ typedef RotationBase<Rotation2D<_Scalar>,2> Base;
+
+public:
+
+ using Base::operator*;
+
+ enum { Dim = 2 };
+ /** the scalar type of the coefficients */
+ typedef _Scalar Scalar;
+ typedef Matrix<Scalar,2,1> Vector2;
+ typedef Matrix<Scalar,2,2> Matrix2;
+
+protected:
+
+ Scalar m_angle;
+
+public:
+
+ /** Construct a 2D counter clock wise rotation from the angle \a a in radian. */
+ inline Rotation2D(Scalar a) : m_angle(a) {}
+
+ /** \returns the rotation angle */
+ inline Scalar angle() const { return m_angle; }
+
+ /** \returns a read-write reference to the rotation angle */
+ inline Scalar& angle() { return m_angle; }
+
+ /** \returns the inverse rotation */
+ inline Rotation2D inverse() const { return -m_angle; }
+
+ /** Concatenates two rotations */
+ inline Rotation2D operator*(const Rotation2D& other) const
+ { return m_angle + other.m_angle; }
+
+ /** Concatenates two rotations */
+ inline Rotation2D& operator*=(const Rotation2D& other)
+ { return m_angle += other.m_angle; return *this; }
+
+ /** Applies the rotation to a 2D vector */
+ Vector2 operator* (const Vector2& vec) const
+ { return toRotationMatrix() * vec; }
+
+ template<typename Derived>
+ Rotation2D& fromRotationMatrix(const MatrixBase<Derived>& m);
+ Matrix2 toRotationMatrix(void) const;
+
+ /** \returns the spherical interpolation between \c *this and \a other using
+ * parameter \a t. It is in fact equivalent to a linear interpolation.
+ */
+ inline Rotation2D slerp(Scalar t, const Rotation2D& other) const
+ { return m_angle * (1-t) + other.angle() * t; }
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<Rotation2D,Rotation2D<NewScalarType> >::type cast() const
+ { return typename ei_cast_return_type<Rotation2D,Rotation2D<NewScalarType> >::type(*this); }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit Rotation2D(const Rotation2D<OtherScalarType>& other)
+ {
+ m_angle = Scalar(other.angle());
+ }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return ei_isApprox(m_angle,other.m_angle, prec); }
+};
+
+/** \ingroup Geometry_Module
+ * single precision 2D rotation type */
+typedef Rotation2D<float> Rotation2Df;
+/** \ingroup Geometry_Module
+ * double precision 2D rotation type */
+typedef Rotation2D<double> Rotation2Dd;
+
+/** Set \c *this from a 2x2 rotation matrix \a mat.
+ * In other words, this function extract the rotation angle
+ * from the rotation matrix.
+ */
+template<typename Scalar>
+template<typename Derived>
+Rotation2D<Scalar>& Rotation2D<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
+{
+ EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
+ m_angle = ei_atan2(mat.coeff(1,0), mat.coeff(0,0));
+ return *this;
+}
+
+/** Constructs and \returns an equivalent 2x2 rotation matrix.
+ */
+template<typename Scalar>
+typename Rotation2D<Scalar>::Matrix2
+Rotation2D<Scalar>::toRotationMatrix(void) const
+{
+ Scalar sinA = ei_sin(m_angle);
+ Scalar cosA = ei_cos(m_angle);
+ return (Matrix2() << cosA, -sinA, sinA, cosA).finished();
+}
+
+#endif // EIGEN_ROTATION2D_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/RotationBase.h b/extern/Eigen2/Eigen/src/Geometry/RotationBase.h
new file mode 100644
index 00000000000..5fec0f18d72
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/RotationBase.h
@@ -0,0 +1,137 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ROTATIONBASE_H
+#define EIGEN_ROTATIONBASE_H
+
+// this file aims to contains the various representations of rotation/orientation
+// in 2D and 3D space excepted Matrix and Quaternion.
+
+/** \class RotationBase
+ *
+ * \brief Common base class for compact rotation representations
+ *
+ * \param Derived is the derived type, i.e., a rotation type
+ * \param _Dim the dimension of the space
+ */
+template<typename Derived, int _Dim>
+class RotationBase
+{
+ public:
+ enum { Dim = _Dim };
+ /** the scalar type of the coefficients */
+ typedef typename ei_traits<Derived>::Scalar Scalar;
+
+ /** corresponding linear transformation matrix type */
+ typedef Matrix<Scalar,Dim,Dim> RotationMatrixType;
+
+ inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
+ inline Derived& derived() { return *static_cast<Derived*>(this); }
+
+ /** \returns an equivalent rotation matrix */
+ inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); }
+
+ /** \returns the inverse rotation */
+ inline Derived inverse() const { return derived().inverse(); }
+
+ /** \returns the concatenation of the rotation \c *this with a translation \a t */
+ inline Transform<Scalar,Dim> operator*(const Translation<Scalar,Dim>& t) const
+ { return toRotationMatrix() * t; }
+
+ /** \returns the concatenation of the rotation \c *this with a scaling \a s */
+ inline RotationMatrixType operator*(const Scaling<Scalar,Dim>& s) const
+ { return toRotationMatrix() * s; }
+
+ /** \returns the concatenation of the rotation \c *this with an affine transformation \a t */
+ inline Transform<Scalar,Dim> operator*(const Transform<Scalar,Dim>& t) const
+ { return toRotationMatrix() * t; }
+};
+
+/** \geometry_module
+ *
+ * Constructs a Dim x Dim rotation matrix from the rotation \a r
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols>
+template<typename OtherDerived>
+Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
+::Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
+{
+ EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim))
+ *this = r.toRotationMatrix();
+}
+
+/** \geometry_module
+ *
+ * Set a Dim x Dim rotation matrix from the rotation \a r
+ */
+template<typename _Scalar, int _Rows, int _Cols, int _Storage, int _MaxRows, int _MaxCols>
+template<typename OtherDerived>
+Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>&
+Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
+::operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
+{
+ EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix,int(OtherDerived::Dim),int(OtherDerived::Dim))
+ return *this = r.toRotationMatrix();
+}
+
+/** \internal
+ *
+ * Helper function to return an arbitrary rotation object to a rotation matrix.
+ *
+ * \param Scalar the numeric type of the matrix coefficients
+ * \param Dim the dimension of the current space
+ *
+ * It returns a Dim x Dim fixed size matrix.
+ *
+ * Default specializations are provided for:
+ * - any scalar type (2D),
+ * - any matrix expression,
+ * - any type based on RotationBase (e.g., Quaternion, AngleAxis, Rotation2D)
+ *
+ * Currently ei_toRotationMatrix is only used by Transform.
+ *
+ * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis
+ */
+template<typename Scalar, int Dim>
+inline static Matrix<Scalar,2,2> ei_toRotationMatrix(const Scalar& s)
+{
+ EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
+ return Rotation2D<Scalar>(s).toRotationMatrix();
+}
+
+template<typename Scalar, int Dim, typename OtherDerived>
+inline static Matrix<Scalar,Dim,Dim> ei_toRotationMatrix(const RotationBase<OtherDerived,Dim>& r)
+{
+ return r.toRotationMatrix();
+}
+
+template<typename Scalar, int Dim, typename OtherDerived>
+inline static const MatrixBase<OtherDerived>& ei_toRotationMatrix(const MatrixBase<OtherDerived>& mat)
+{
+ EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim,
+ YOU_MADE_A_PROGRAMMING_MISTAKE)
+ return mat;
+}
+
+#endif // EIGEN_ROTATIONBASE_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/Scaling.h b/extern/Eigen2/Eigen/src/Geometry/Scaling.h
new file mode 100644
index 00000000000..5daf0a49961
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/Scaling.h
@@ -0,0 +1,181 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SCALING_H
+#define EIGEN_SCALING_H
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class Scaling
+ *
+ * \brief Represents a possibly non uniform scaling transformation
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients.
+ * \param _Dim the dimension of the space, can be a compile time value or Dynamic
+ *
+ * \note This class is not aimed to be used to store a scaling transformation,
+ * but rather to make easier the constructions and updates of Transform objects.
+ *
+ * \sa class Translation, class Transform
+ */
+template<typename _Scalar, int _Dim>
+class Scaling
+{
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim)
+ /** dimension of the space */
+ enum { Dim = _Dim };
+ /** the scalar type of the coefficients */
+ typedef _Scalar Scalar;
+ /** corresponding vector type */
+ typedef Matrix<Scalar,Dim,1> VectorType;
+ /** corresponding linear transformation matrix type */
+ typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
+ /** corresponding translation type */
+ typedef Translation<Scalar,Dim> TranslationType;
+ /** corresponding affine transformation type */
+ typedef Transform<Scalar,Dim> TransformType;
+
+protected:
+
+ VectorType m_coeffs;
+
+public:
+
+ /** Default constructor without initialization. */
+ Scaling() {}
+ /** Constructs and initialize a uniform scaling transformation */
+ explicit inline Scaling(const Scalar& s) { m_coeffs.setConstant(s); }
+ /** 2D only */
+ inline Scaling(const Scalar& sx, const Scalar& sy)
+ {
+ ei_assert(Dim==2);
+ m_coeffs.x() = sx;
+ m_coeffs.y() = sy;
+ }
+ /** 3D only */
+ inline Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz)
+ {
+ ei_assert(Dim==3);
+ m_coeffs.x() = sx;
+ m_coeffs.y() = sy;
+ m_coeffs.z() = sz;
+ }
+ /** Constructs and initialize the scaling transformation from a vector of scaling coefficients */
+ explicit inline Scaling(const VectorType& coeffs) : m_coeffs(coeffs) {}
+
+ const VectorType& coeffs() const { return m_coeffs; }
+ VectorType& coeffs() { return m_coeffs; }
+
+ /** Concatenates two scaling */
+ inline Scaling operator* (const Scaling& other) const
+ { return Scaling(coeffs().cwise() * other.coeffs()); }
+
+ /** Concatenates a scaling and a translation */
+ inline TransformType operator* (const TranslationType& t) const;
+
+ /** Concatenates a scaling and an affine transformation */
+ inline TransformType operator* (const TransformType& t) const;
+
+ /** Concatenates a scaling and a linear transformation matrix */
+ // TODO returns an expression
+ inline LinearMatrixType operator* (const LinearMatrixType& other) const
+ { return coeffs().asDiagonal() * other; }
+
+ /** Concatenates a linear transformation matrix and a scaling */
+ // TODO returns an expression
+ friend inline LinearMatrixType operator* (const LinearMatrixType& other, const Scaling& s)
+ { return other * s.coeffs().asDiagonal(); }
+
+ template<typename Derived>
+ inline LinearMatrixType operator*(const RotationBase<Derived,Dim>& r) const
+ { return *this * r.toRotationMatrix(); }
+
+ /** Applies scaling to vector */
+ inline VectorType operator* (const VectorType& other) const
+ { return coeffs().asDiagonal() * other; }
+
+ /** \returns the inverse scaling */
+ inline Scaling inverse() const
+ { return Scaling(coeffs().cwise().inverse()); }
+
+ inline Scaling& operator=(const Scaling& other)
+ {
+ m_coeffs = other.m_coeffs;
+ return *this;
+ }
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type cast() const
+ { return typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type(*this); }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit Scaling(const Scaling<OtherScalarType,Dim>& other)
+ { m_coeffs = other.coeffs().template cast<Scalar>(); }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const Scaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_coeffs.isApprox(other.m_coeffs, prec); }
+
+};
+
+/** \addtogroup Geometry_Module */
+//@{
+typedef Scaling<float, 2> Scaling2f;
+typedef Scaling<double,2> Scaling2d;
+typedef Scaling<float, 3> Scaling3f;
+typedef Scaling<double,3> Scaling3d;
+//@}
+
+template<typename Scalar, int Dim>
+inline typename Scaling<Scalar,Dim>::TransformType
+Scaling<Scalar,Dim>::operator* (const TranslationType& t) const
+{
+ TransformType res;
+ res.matrix().setZero();
+ res.linear().diagonal() = coeffs();
+ res.translation() = m_coeffs.cwise() * t.vector();
+ res(Dim,Dim) = Scalar(1);
+ return res;
+}
+
+template<typename Scalar, int Dim>
+inline typename Scaling<Scalar,Dim>::TransformType
+Scaling<Scalar,Dim>::operator* (const TransformType& t) const
+{
+ TransformType res = t;
+ res.prescale(m_coeffs);
+ return res;
+}
+
+#endif // EIGEN_SCALING_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/Transform.h b/extern/Eigen2/Eigen/src/Geometry/Transform.h
new file mode 100644
index 00000000000..8425a1cd963
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/Transform.h
@@ -0,0 +1,785 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_TRANSFORM_H
+#define EIGEN_TRANSFORM_H
+
+/** Represents some traits of a transformation */
+enum TransformTraits {
+ Isometry, ///< the transformation is a concatenation of translations and rotations
+ Affine, ///< the transformation is affine (linear transformation + translation)
+ Projective ///< the transformation might not be affine
+};
+
+// Note that we have to pass Dim and HDim because it is not allowed to use a template
+// parameter to define a template specialization. To be more precise, in the following
+// specializations, it is not allowed to use Dim+1 instead of HDim.
+template< typename Other,
+ int Dim,
+ int HDim,
+ int OtherRows=Other::RowsAtCompileTime,
+ int OtherCols=Other::ColsAtCompileTime>
+struct ei_transform_product_impl;
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class Transform
+ *
+ * \brief Represents an homogeneous transformation in a N dimensional space
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients
+ * \param _Dim the dimension of the space
+ *
+ * The homography is internally represented and stored as a (Dim+1)^2 matrix which
+ * is available through the matrix() method.
+ *
+ * Conversion methods from/to Qt's QMatrix and QTransform are available if the
+ * preprocessor token EIGEN_QT_SUPPORT is defined.
+ *
+ * \sa class Matrix, class Quaternion
+ */
+template<typename _Scalar, int _Dim>
+class Transform
+{
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1))
+ enum {
+ Dim = _Dim, ///< space dimension in which the transformation holds
+ HDim = _Dim+1 ///< size of a respective homogeneous vector
+ };
+ /** the scalar type of the coefficients */
+ typedef _Scalar Scalar;
+ /** type of the matrix used to represent the transformation */
+ typedef Matrix<Scalar,HDim,HDim> MatrixType;
+ /** type of the matrix used to represent the linear part of the transformation */
+ typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
+ /** type of read/write reference to the linear part of the transformation */
+ typedef Block<MatrixType,Dim,Dim> LinearPart;
+ /** type of a vector */
+ typedef Matrix<Scalar,Dim,1> VectorType;
+ /** type of a read/write reference to the translation part of the rotation */
+ typedef Block<MatrixType,Dim,1> TranslationPart;
+ /** corresponding translation type */
+ typedef Translation<Scalar,Dim> TranslationType;
+ /** corresponding scaling transformation type */
+ typedef Scaling<Scalar,Dim> ScalingType;
+
+protected:
+
+ MatrixType m_matrix;
+
+public:
+
+ /** Default constructor without initialization of the coefficients. */
+ inline Transform() { }
+
+ inline Transform(const Transform& other)
+ {
+ m_matrix = other.m_matrix;
+ }
+
+ inline explicit Transform(const TranslationType& t) { *this = t; }
+ inline explicit Transform(const ScalingType& s) { *this = s; }
+ template<typename Derived>
+ inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; }
+
+ inline Transform& operator=(const Transform& other)
+ { m_matrix = other.m_matrix; return *this; }
+
+ template<typename OtherDerived, bool BigMatrix> // MSVC 2005 will commit suicide if BigMatrix has a default value
+ struct construct_from_matrix
+ {
+ static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other)
+ {
+ transform->matrix() = other;
+ }
+ };
+
+ template<typename OtherDerived> struct construct_from_matrix<OtherDerived, true>
+ {
+ static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other)
+ {
+ transform->linear() = other;
+ transform->translation().setZero();
+ transform->matrix()(Dim,Dim) = Scalar(1);
+ transform->matrix().template block<1,Dim>(Dim,0).setZero();
+ }
+ };
+
+ /** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */
+ template<typename OtherDerived>
+ inline explicit Transform(const MatrixBase<OtherDerived>& other)
+ {
+ construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other);
+ }
+
+ /** Set \c *this from a (Dim+1)^2 matrix. */
+ template<typename OtherDerived>
+ inline Transform& operator=(const MatrixBase<OtherDerived>& other)
+ { m_matrix = other; return *this; }
+
+ #ifdef EIGEN_QT_SUPPORT
+ inline Transform(const QMatrix& other);
+ inline Transform& operator=(const QMatrix& other);
+ inline QMatrix toQMatrix(void) const;
+ inline Transform(const QTransform& other);
+ inline Transform& operator=(const QTransform& other);
+ inline QTransform toQTransform(void) const;
+ #endif
+
+ /** shortcut for m_matrix(row,col);
+ * \sa MatrixBase::operaror(int,int) const */
+ inline Scalar operator() (int row, int col) const { return m_matrix(row,col); }
+ /** shortcut for m_matrix(row,col);
+ * \sa MatrixBase::operaror(int,int) */
+ inline Scalar& operator() (int row, int col) { return m_matrix(row,col); }
+
+ /** \returns a read-only expression of the transformation matrix */
+ inline const MatrixType& matrix() const { return m_matrix; }
+ /** \returns a writable expression of the transformation matrix */
+ inline MatrixType& matrix() { return m_matrix; }
+
+ /** \returns a read-only expression of the linear (linear) part of the transformation */
+ inline const LinearPart linear() const { return m_matrix.template block<Dim,Dim>(0,0); }
+ /** \returns a writable expression of the linear (linear) part of the transformation */
+ inline LinearPart linear() { return m_matrix.template block<Dim,Dim>(0,0); }
+
+ /** \returns a read-only expression of the translation vector of the transformation */
+ inline const TranslationPart translation() const { return m_matrix.template block<Dim,1>(0,Dim); }
+ /** \returns a writable expression of the translation vector of the transformation */
+ inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
+
+ /** \returns an expression of the product between the transform \c *this and a matrix expression \a other
+ *
+ * The right hand side \a other might be either:
+ * \li a vector of size Dim,
+ * \li an homogeneous vector of size Dim+1,
+ * \li a transformation matrix of size Dim+1 x Dim+1.
+ */
+ // note: this function is defined here because some compilers cannot find the respective declaration
+ template<typename OtherDerived>
+ inline const typename ei_transform_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType
+ operator * (const MatrixBase<OtherDerived> &other) const
+ { return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); }
+
+ /** \returns the product expression of a transformation matrix \a a times a transform \a b
+ * The transformation matrix \a a must have a Dim+1 x Dim+1 sizes. */
+ template<typename OtherDerived>
+ friend inline const typename ProductReturnType<OtherDerived,MatrixType>::Type
+ operator * (const MatrixBase<OtherDerived> &a, const Transform &b)
+ { return a.derived() * b.matrix(); }
+
+ /** Contatenates two transformations */
+ inline const Transform
+ operator * (const Transform& other) const
+ { return Transform(m_matrix * other.matrix()); }
+
+ /** \sa MatrixBase::setIdentity() */
+ void setIdentity() { m_matrix.setIdentity(); }
+ static const typename MatrixType::IdentityReturnType Identity()
+ {
+ return MatrixType::Identity();
+ }
+
+ template<typename OtherDerived>
+ inline Transform& scale(const MatrixBase<OtherDerived> &other);
+
+ template<typename OtherDerived>
+ inline Transform& prescale(const MatrixBase<OtherDerived> &other);
+
+ inline Transform& scale(Scalar s);
+ inline Transform& prescale(Scalar s);
+
+ template<typename OtherDerived>
+ inline Transform& translate(const MatrixBase<OtherDerived> &other);
+
+ template<typename OtherDerived>
+ inline Transform& pretranslate(const MatrixBase<OtherDerived> &other);
+
+ template<typename RotationType>
+ inline Transform& rotate(const RotationType& rotation);
+
+ template<typename RotationType>
+ inline Transform& prerotate(const RotationType& rotation);
+
+ Transform& shear(Scalar sx, Scalar sy);
+ Transform& preshear(Scalar sx, Scalar sy);
+
+ inline Transform& operator=(const TranslationType& t);
+ inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
+ inline Transform operator*(const TranslationType& t) const;
+
+ inline Transform& operator=(const ScalingType& t);
+ inline Transform& operator*=(const ScalingType& s) { return scale(s.coeffs()); }
+ inline Transform operator*(const ScalingType& s) const;
+ friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t)
+ {
+ Transform res = t;
+ res.matrix().row(Dim) = t.matrix().row(Dim);
+ res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy();
+ return res;
+ }
+
+ template<typename Derived>
+ inline Transform& operator=(const RotationBase<Derived,Dim>& r);
+ template<typename Derived>
+ inline Transform& operator*=(const RotationBase<Derived,Dim>& r) { return rotate(r.toRotationMatrix()); }
+ template<typename Derived>
+ inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
+
+ LinearMatrixType rotation() const;
+ template<typename RotationMatrixType, typename ScalingMatrixType>
+ void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
+ template<typename ScalingMatrixType, typename RotationMatrixType>
+ void computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const;
+
+ template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
+ Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
+ const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
+
+ inline const MatrixType inverse(TransformTraits traits = Affine) const;
+
+ /** \returns a const pointer to the column major internal matrix */
+ const Scalar* data() const { return m_matrix.data(); }
+ /** \returns a non-const pointer to the column major internal matrix */
+ Scalar* data() { return m_matrix.data(); }
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<Transform,Transform<NewScalarType,Dim> >::type cast() const
+ { return typename ei_cast_return_type<Transform,Transform<NewScalarType,Dim> >::type(*this); }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit Transform(const Transform<OtherScalarType,Dim>& other)
+ { m_matrix = other.matrix().template cast<Scalar>(); }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_matrix.isApprox(other.m_matrix, prec); }
+
+ #ifdef EIGEN_TRANSFORM_PLUGIN
+ #include EIGEN_TRANSFORM_PLUGIN
+ #endif
+
+protected:
+
+};
+
+/** \ingroup Geometry_Module */
+typedef Transform<float,2> Transform2f;
+/** \ingroup Geometry_Module */
+typedef Transform<float,3> Transform3f;
+/** \ingroup Geometry_Module */
+typedef Transform<double,2> Transform2d;
+/** \ingroup Geometry_Module */
+typedef Transform<double,3> Transform3d;
+
+/**************************
+*** Optional QT support ***
+**************************/
+
+#ifdef EIGEN_QT_SUPPORT
+/** Initialises \c *this from a QMatrix assuming the dimension is 2.
+ *
+ * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ */
+template<typename Scalar, int Dim>
+Transform<Scalar,Dim>::Transform(const QMatrix& other)
+{
+ *this = other;
+}
+
+/** Set \c *this from a QMatrix assuming the dimension is 2.
+ *
+ * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ */
+template<typename Scalar, int Dim>
+Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QMatrix& other)
+{
+ EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
+ m_matrix << other.m11(), other.m21(), other.dx(),
+ other.m12(), other.m22(), other.dy(),
+ 0, 0, 1;
+ return *this;
+}
+
+/** \returns a QMatrix from \c *this assuming the dimension is 2.
+ *
+ * \warning this convertion might loss data if \c *this is not affine
+ *
+ * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ */
+template<typename Scalar, int Dim>
+QMatrix Transform<Scalar,Dim>::toQMatrix(void) const
+{
+ EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
+ return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
+ m_matrix.coeff(0,1), m_matrix.coeff(1,1),
+ m_matrix.coeff(0,2), m_matrix.coeff(1,2));
+}
+
+/** Initialises \c *this from a QTransform assuming the dimension is 2.
+ *
+ * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ */
+template<typename Scalar, int Dim>
+Transform<Scalar,Dim>::Transform(const QTransform& other)
+{
+ *this = other;
+}
+
+/** Set \c *this from a QTransform assuming the dimension is 2.
+ *
+ * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ */
+template<typename Scalar, int Dim>
+Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QTransform& other)
+{
+ EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
+ m_matrix << other.m11(), other.m21(), other.dx(),
+ other.m12(), other.m22(), other.dy(),
+ other.m13(), other.m23(), other.m33();
+ return *this;
+}
+
+/** \returns a QTransform from \c *this assuming the dimension is 2.
+ *
+ * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ */
+template<typename Scalar, int Dim>
+QTransform Transform<Scalar,Dim>::toQTransform(void) const
+{
+ EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
+ return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
+ m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
+ m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
+}
+#endif
+
+/*********************
+*** Procedural API ***
+*********************/
+
+/** Applies on the right the non uniform scale transformation represented
+ * by the vector \a other to \c *this and returns a reference to \c *this.
+ * \sa prescale()
+ */
+template<typename Scalar, int Dim>
+template<typename OtherDerived>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::scale(const MatrixBase<OtherDerived> &other)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
+ linear() = (linear() * other.asDiagonal()).lazy();
+ return *this;
+}
+
+/** Applies on the right a uniform scale of a factor \a c to \c *this
+ * and returns a reference to \c *this.
+ * \sa prescale(Scalar)
+ */
+template<typename Scalar, int Dim>
+inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::scale(Scalar s)
+{
+ linear() *= s;
+ return *this;
+}
+
+/** Applies on the left the non uniform scale transformation represented
+ * by the vector \a other to \c *this and returns a reference to \c *this.
+ * \sa scale()
+ */
+template<typename Scalar, int Dim>
+template<typename OtherDerived>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::prescale(const MatrixBase<OtherDerived> &other)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
+ m_matrix.template block<Dim,HDim>(0,0) = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0)).lazy();
+ return *this;
+}
+
+/** Applies on the left a uniform scale of a factor \a c to \c *this
+ * and returns a reference to \c *this.
+ * \sa scale(Scalar)
+ */
+template<typename Scalar, int Dim>
+inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::prescale(Scalar s)
+{
+ m_matrix.template corner<Dim,HDim>(TopLeft) *= s;
+ return *this;
+}
+
+/** Applies on the right the translation matrix represented by the vector \a other
+ * to \c *this and returns a reference to \c *this.
+ * \sa pretranslate()
+ */
+template<typename Scalar, int Dim>
+template<typename OtherDerived>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::translate(const MatrixBase<OtherDerived> &other)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
+ translation() += linear() * other;
+ return *this;
+}
+
+/** Applies on the left the translation matrix represented by the vector \a other
+ * to \c *this and returns a reference to \c *this.
+ * \sa translate()
+ */
+template<typename Scalar, int Dim>
+template<typename OtherDerived>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::pretranslate(const MatrixBase<OtherDerived> &other)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
+ translation() += other;
+ return *this;
+}
+
+/** Applies on the right the rotation represented by the rotation \a rotation
+ * to \c *this and returns a reference to \c *this.
+ *
+ * The template parameter \a RotationType is the type of the rotation which
+ * must be known by ei_toRotationMatrix<>.
+ *
+ * Natively supported types includes:
+ * - any scalar (2D),
+ * - a Dim x Dim matrix expression,
+ * - a Quaternion (3D),
+ * - a AngleAxis (3D)
+ *
+ * This mechanism is easily extendable to support user types such as Euler angles,
+ * or a pair of Quaternion for 4D rotations.
+ *
+ * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType)
+ */
+template<typename Scalar, int Dim>
+template<typename RotationType>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::rotate(const RotationType& rotation)
+{
+ linear() *= ei_toRotationMatrix<Scalar,Dim>(rotation);
+ return *this;
+}
+
+/** Applies on the left the rotation represented by the rotation \a rotation
+ * to \c *this and returns a reference to \c *this.
+ *
+ * See rotate() for further details.
+ *
+ * \sa rotate()
+ */
+template<typename Scalar, int Dim>
+template<typename RotationType>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::prerotate(const RotationType& rotation)
+{
+ m_matrix.template block<Dim,HDim>(0,0) = ei_toRotationMatrix<Scalar,Dim>(rotation)
+ * m_matrix.template block<Dim,HDim>(0,0);
+ return *this;
+}
+
+/** Applies on the right the shear transformation represented
+ * by the vector \a other to \c *this and returns a reference to \c *this.
+ * \warning 2D only.
+ * \sa preshear()
+ */
+template<typename Scalar, int Dim>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::shear(Scalar sx, Scalar sy)
+{
+ EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
+ VectorType tmp = linear().col(0)*sy + linear().col(1);
+ linear() << linear().col(0) + linear().col(1)*sx, tmp;
+ return *this;
+}
+
+/** Applies on the left the shear transformation represented
+ * by the vector \a other to \c *this and returns a reference to \c *this.
+ * \warning 2D only.
+ * \sa shear()
+ */
+template<typename Scalar, int Dim>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::preshear(Scalar sx, Scalar sy)
+{
+ EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
+ m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
+ return *this;
+}
+
+/******************************************************
+*** Scaling, Translation and Rotation compatibility ***
+******************************************************/
+
+template<typename Scalar, int Dim>
+inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const TranslationType& t)
+{
+ linear().setIdentity();
+ translation() = t.vector();
+ m_matrix.template block<1,Dim>(Dim,0).setZero();
+ m_matrix(Dim,Dim) = Scalar(1);
+ return *this;
+}
+
+template<typename Scalar, int Dim>
+inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const TranslationType& t) const
+{
+ Transform res = *this;
+ res.translate(t.vector());
+ return res;
+}
+
+template<typename Scalar, int Dim>
+inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const ScalingType& s)
+{
+ m_matrix.setZero();
+ linear().diagonal() = s.coeffs();
+ m_matrix.coeffRef(Dim,Dim) = Scalar(1);
+ return *this;
+}
+
+template<typename Scalar, int Dim>
+inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const ScalingType& s) const
+{
+ Transform res = *this;
+ res.scale(s.coeffs());
+ return res;
+}
+
+template<typename Scalar, int Dim>
+template<typename Derived>
+inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const RotationBase<Derived,Dim>& r)
+{
+ linear() = ei_toRotationMatrix<Scalar,Dim>(r);
+ translation().setZero();
+ m_matrix.template block<1,Dim>(Dim,0).setZero();
+ m_matrix.coeffRef(Dim,Dim) = Scalar(1);
+ return *this;
+}
+
+template<typename Scalar, int Dim>
+template<typename Derived>
+inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const RotationBase<Derived,Dim>& r) const
+{
+ Transform res = *this;
+ res.rotate(r.derived());
+ return res;
+}
+
+/************************
+*** Special functions ***
+************************/
+
+/** \returns the rotation part of the transformation
+ * \nonstableyet
+ *
+ * \svd_module
+ *
+ * \sa computeRotationScaling(), computeScalingRotation(), class SVD
+ */
+template<typename Scalar, int Dim>
+typename Transform<Scalar,Dim>::LinearMatrixType
+Transform<Scalar,Dim>::rotation() const
+{
+ LinearMatrixType result;
+ computeRotationScaling(&result, (LinearMatrixType*)0);
+ return result;
+}
+
+
+/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being
+ * not necessarily positive.
+ *
+ * If either pointer is zero, the corresponding computation is skipped.
+ *
+ * \nonstableyet
+ *
+ * \svd_module
+ *
+ * \sa computeScalingRotation(), rotation(), class SVD
+ */
+template<typename Scalar, int Dim>
+template<typename RotationMatrixType, typename ScalingMatrixType>
+void Transform<Scalar,Dim>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
+{
+ linear().svd().computeRotationScaling(rotation, scaling);
+}
+
+/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being
+ * not necessarily positive.
+ *
+ * If either pointer is zero, the corresponding computation is skipped.
+ *
+ * \nonstableyet
+ *
+ * \svd_module
+ *
+ * \sa computeRotationScaling(), rotation(), class SVD
+ */
+template<typename Scalar, int Dim>
+template<typename ScalingMatrixType, typename RotationMatrixType>
+void Transform<Scalar,Dim>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
+{
+ linear().svd().computeScalingRotation(scaling, rotation);
+}
+
+/** Convenient method to set \c *this from a position, orientation and scale
+ * of a 3D object.
+ */
+template<typename Scalar, int Dim>
+template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
+Transform<Scalar,Dim>&
+Transform<Scalar,Dim>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
+ const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale)
+{
+ linear() = ei_toRotationMatrix<Scalar,Dim>(orientation);
+ linear() *= scale.asDiagonal();
+ translation() = position;
+ m_matrix.template block<1,Dim>(Dim,0).setZero();
+ m_matrix(Dim,Dim) = Scalar(1);
+ return *this;
+}
+
+/** \nonstableyet
+ *
+ * \returns the inverse transformation matrix according to some given knowledge
+ * on \c *this.
+ *
+ * \param traits allows to optimize the inversion process when the transformion
+ * is known to be not a general transformation. The possible values are:
+ * - Projective if the transformation is not necessarily affine, i.e., if the
+ * last row is not guaranteed to be [0 ... 0 1]
+ * - Affine is the default, the last row is assumed to be [0 ... 0 1]
+ * - Isometry if the transformation is only a concatenations of translations
+ * and rotations.
+ *
+ * \warning unless \a traits is always set to NoShear or NoScaling, this function
+ * requires the generic inverse method of MatrixBase defined in the LU module. If
+ * you forget to include this module, then you will get hard to debug linking errors.
+ *
+ * \sa MatrixBase::inverse()
+ */
+template<typename Scalar, int Dim>
+inline const typename Transform<Scalar,Dim>::MatrixType
+Transform<Scalar,Dim>::inverse(TransformTraits traits) const
+{
+ if (traits == Projective)
+ {
+ return m_matrix.inverse();
+ }
+ else
+ {
+ MatrixType res;
+ if (traits == Affine)
+ {
+ res.template corner<Dim,Dim>(TopLeft) = linear().inverse();
+ }
+ else if (traits == Isometry)
+ {
+ res.template corner<Dim,Dim>(TopLeft) = linear().transpose();
+ }
+ else
+ {
+ ei_assert("invalid traits value in Transform::inverse()");
+ }
+ // translation and remaining parts
+ res.template corner<Dim,1>(TopRight) = - res.template corner<Dim,Dim>(TopLeft) * translation();
+ res.template corner<1,Dim>(BottomLeft).setZero();
+ res.coeffRef(Dim,Dim) = Scalar(1);
+ return res;
+ }
+}
+
+/*****************************************************
+*** Specializations of operator* with a MatrixBase ***
+*****************************************************/
+
+template<typename Other, int Dim, int HDim>
+struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim>
+{
+ typedef Transform<typename Other::Scalar,Dim> TransformType;
+ typedef typename TransformType::MatrixType MatrixType;
+ typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
+ static ResultType run(const TransformType& tr, const Other& other)
+ { return tr.matrix() * other; }
+};
+
+template<typename Other, int Dim, int HDim>
+struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim>
+{
+ typedef Transform<typename Other::Scalar,Dim> TransformType;
+ typedef typename TransformType::MatrixType MatrixType;
+ typedef TransformType ResultType;
+ static ResultType run(const TransformType& tr, const Other& other)
+ {
+ TransformType res;
+ res.translation() = tr.translation();
+ res.matrix().row(Dim) = tr.matrix().row(Dim);
+ res.linear() = (tr.linear() * other).lazy();
+ return res;
+ }
+};
+
+template<typename Other, int Dim, int HDim>
+struct ei_transform_product_impl<Other,Dim,HDim, HDim,1>
+{
+ typedef Transform<typename Other::Scalar,Dim> TransformType;
+ typedef typename TransformType::MatrixType MatrixType;
+ typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
+ static ResultType run(const TransformType& tr, const Other& other)
+ { return tr.matrix() * other; }
+};
+
+template<typename Other, int Dim, int HDim>
+struct ei_transform_product_impl<Other,Dim,HDim, Dim,1>
+{
+ typedef typename Other::Scalar Scalar;
+ typedef Transform<Scalar,Dim> TransformType;
+ typedef typename TransformType::LinearPart MatrixType;
+ typedef const CwiseUnaryOp<
+ ei_scalar_multiple_op<Scalar>,
+ NestByValue<CwiseBinaryOp<
+ ei_scalar_sum_op<Scalar>,
+ NestByValue<typename ProductReturnType<NestByValue<MatrixType>,Other>::Type >,
+ NestByValue<typename TransformType::TranslationPart> > >
+ > ResultType;
+ // FIXME should we offer an optimized version when the last row is known to be 0,0...,0,1 ?
+ static ResultType run(const TransformType& tr, const Other& other)
+ { return ((tr.linear().nestByValue() * other).nestByValue() + tr.translation().nestByValue()).nestByValue()
+ * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); }
+};
+
+#endif // EIGEN_TRANSFORM_H
diff --git a/extern/Eigen2/Eigen/src/Geometry/Translation.h b/extern/Eigen2/Eigen/src/Geometry/Translation.h
new file mode 100644
index 00000000000..4b2fc7a56fc
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Geometry/Translation.h
@@ -0,0 +1,198 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_TRANSLATION_H
+#define EIGEN_TRANSLATION_H
+
+/** \geometry_module \ingroup Geometry_Module
+ *
+ * \class Translation
+ *
+ * \brief Represents a translation transformation
+ *
+ * \param _Scalar the scalar type, i.e., the type of the coefficients.
+ * \param _Dim the dimension of the space, can be a compile time value or Dynamic
+ *
+ * \note This class is not aimed to be used to store a translation transformation,
+ * but rather to make easier the constructions and updates of Transform objects.
+ *
+ * \sa class Scaling, class Transform
+ */
+template<typename _Scalar, int _Dim>
+class Translation
+{
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim)
+ /** dimension of the space */
+ enum { Dim = _Dim };
+ /** the scalar type of the coefficients */
+ typedef _Scalar Scalar;
+ /** corresponding vector type */
+ typedef Matrix<Scalar,Dim,1> VectorType;
+ /** corresponding linear transformation matrix type */
+ typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
+ /** corresponding scaling transformation type */
+ typedef Scaling<Scalar,Dim> ScalingType;
+ /** corresponding affine transformation type */
+ typedef Transform<Scalar,Dim> TransformType;
+
+protected:
+
+ VectorType m_coeffs;
+
+public:
+
+ /** Default constructor without initialization. */
+ Translation() {}
+ /** */
+ inline Translation(const Scalar& sx, const Scalar& sy)
+ {
+ ei_assert(Dim==2);
+ m_coeffs.x() = sx;
+ m_coeffs.y() = sy;
+ }
+ /** */
+ inline Translation(const Scalar& sx, const Scalar& sy, const Scalar& sz)
+ {
+ ei_assert(Dim==3);
+ m_coeffs.x() = sx;
+ m_coeffs.y() = sy;
+ m_coeffs.z() = sz;
+ }
+ /** Constructs and initialize the scaling transformation from a vector of scaling coefficients */
+ explicit inline Translation(const VectorType& vector) : m_coeffs(vector) {}
+
+ const VectorType& vector() const { return m_coeffs; }
+ VectorType& vector() { return m_coeffs; }
+
+ /** Concatenates two translation */
+ inline Translation operator* (const Translation& other) const
+ { return Translation(m_coeffs + other.m_coeffs); }
+
+ /** Concatenates a translation and a scaling */
+ inline TransformType operator* (const ScalingType& other) const;
+
+ /** Concatenates a translation and a linear transformation */
+ inline TransformType operator* (const LinearMatrixType& linear) const;
+
+ template<typename Derived>
+ inline TransformType operator*(const RotationBase<Derived,Dim>& r) const
+ { return *this * r.toRotationMatrix(); }
+
+ /** Concatenates a linear transformation and a translation */
+ // its a nightmare to define a templated friend function outside its declaration
+ friend inline TransformType operator* (const LinearMatrixType& linear, const Translation& t)
+ {
+ TransformType res;
+ res.matrix().setZero();
+ res.linear() = linear;
+ res.translation() = linear * t.m_coeffs;
+ res.matrix().row(Dim).setZero();
+ res(Dim,Dim) = Scalar(1);
+ return res;
+ }
+
+ /** Concatenates a translation and an affine transformation */
+ inline TransformType operator* (const TransformType& t) const;
+
+ /** Applies translation to vector */
+ inline VectorType operator* (const VectorType& other) const
+ { return m_coeffs + other; }
+
+ /** \returns the inverse translation (opposite) */
+ Translation inverse() const { return Translation(-m_coeffs); }
+
+ Translation& operator=(const Translation& other)
+ {
+ m_coeffs = other.m_coeffs;
+ return *this;
+ }
+
+ /** \returns \c *this with scalar type casted to \a NewScalarType
+ *
+ * Note that if \a NewScalarType is equal to the current scalar type of \c *this
+ * then this function smartly returns a const reference to \c *this.
+ */
+ template<typename NewScalarType>
+ inline typename ei_cast_return_type<Translation,Translation<NewScalarType,Dim> >::type cast() const
+ { return typename ei_cast_return_type<Translation,Translation<NewScalarType,Dim> >::type(*this); }
+
+ /** Copy constructor with scalar type conversion */
+ template<typename OtherScalarType>
+ inline explicit Translation(const Translation<OtherScalarType,Dim>& other)
+ { m_coeffs = other.vector().template cast<Scalar>(); }
+
+ /** \returns \c true if \c *this is approximately equal to \a other, within the precision
+ * determined by \a prec.
+ *
+ * \sa MatrixBase::isApprox() */
+ bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ { return m_coeffs.isApprox(other.m_coeffs, prec); }
+
+};
+
+/** \addtogroup Geometry_Module */
+//@{
+typedef Translation<float, 2> Translation2f;
+typedef Translation<double,2> Translation2d;
+typedef Translation<float, 3> Translation3f;
+typedef Translation<double,3> Translation3d;
+//@}
+
+
+template<typename Scalar, int Dim>
+inline typename Translation<Scalar,Dim>::TransformType
+Translation<Scalar,Dim>::operator* (const ScalingType& other) const
+{
+ TransformType res;
+ res.matrix().setZero();
+ res.linear().diagonal() = other.coeffs();
+ res.translation() = m_coeffs;
+ res(Dim,Dim) = Scalar(1);
+ return res;
+}
+
+template<typename Scalar, int Dim>
+inline typename Translation<Scalar,Dim>::TransformType
+Translation<Scalar,Dim>::operator* (const LinearMatrixType& linear) const
+{
+ TransformType res;
+ res.matrix().setZero();
+ res.linear() = linear;
+ res.translation() = m_coeffs;
+ res.matrix().row(Dim).setZero();
+ res(Dim,Dim) = Scalar(1);
+ return res;
+}
+
+template<typename Scalar, int Dim>
+inline typename Translation<Scalar,Dim>::TransformType
+Translation<Scalar,Dim>::operator* (const TransformType& t) const
+{
+ TransformType res = t;
+ res.pretranslate(m_coeffs);
+ return res;
+}
+
+#endif // EIGEN_TRANSLATION_H
diff --git a/extern/Eigen2/Eigen/src/LU/Determinant.h b/extern/Eigen2/Eigen/src/LU/Determinant.h
new file mode 100644
index 00000000000..4f435054ac6
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/LU/Determinant.h
@@ -0,0 +1,122 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_DETERMINANT_H
+#define EIGEN_DETERMINANT_H
+
+template<typename Derived>
+inline const typename Derived::Scalar ei_bruteforce_det3_helper
+(const MatrixBase<Derived>& matrix, int a, int b, int c)
+{
+ return matrix.coeff(0,a)
+ * (matrix.coeff(1,b) * matrix.coeff(2,c) - matrix.coeff(1,c) * matrix.coeff(2,b));
+}
+
+template<typename Derived>
+const typename Derived::Scalar ei_bruteforce_det4_helper
+(const MatrixBase<Derived>& matrix, int j, int k, int m, int n)
+{
+ return (matrix.coeff(j,0) * matrix.coeff(k,1) - matrix.coeff(k,0) * matrix.coeff(j,1))
+ * (matrix.coeff(m,2) * matrix.coeff(n,3) - matrix.coeff(n,2) * matrix.coeff(m,3));
+}
+
+const int TriangularDeterminant = 0;
+
+template<typename Derived,
+ int DeterminantType =
+ (Derived::Flags & (UpperTriangularBit | LowerTriangularBit))
+ ? TriangularDeterminant : Derived::RowsAtCompileTime
+> struct ei_determinant_impl
+{
+ static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
+ {
+ return m.lu().determinant();
+ }
+};
+
+template<typename Derived> struct ei_determinant_impl<Derived, TriangularDeterminant>
+{
+ static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
+ {
+ if (Derived::Flags & UnitDiagBit)
+ return 1;
+ else if (Derived::Flags & ZeroDiagBit)
+ return 0;
+ else
+ return m.diagonal().redux(ei_scalar_product_op<typename ei_traits<Derived>::Scalar>());
+ }
+};
+
+template<typename Derived> struct ei_determinant_impl<Derived, 1>
+{
+ static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
+ {
+ return m.coeff(0,0);
+ }
+};
+
+template<typename Derived> struct ei_determinant_impl<Derived, 2>
+{
+ static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
+ {
+ return m.coeff(0,0) * m.coeff(1,1) - m.coeff(1,0) * m.coeff(0,1);
+ }
+};
+
+template<typename Derived> struct ei_determinant_impl<Derived, 3>
+{
+ static typename ei_traits<Derived>::Scalar run(const Derived& m)
+ {
+ return ei_bruteforce_det3_helper(m,0,1,2)
+ - ei_bruteforce_det3_helper(m,1,0,2)
+ + ei_bruteforce_det3_helper(m,2,0,1);
+ }
+};
+
+template<typename Derived> struct ei_determinant_impl<Derived, 4>
+{
+ static typename ei_traits<Derived>::Scalar run(const Derived& m)
+ {
+ // trick by Martin Costabel to compute 4x4 det with only 30 muls
+ return ei_bruteforce_det4_helper(m,0,1,2,3)
+ - ei_bruteforce_det4_helper(m,0,2,1,3)
+ + ei_bruteforce_det4_helper(m,0,3,1,2)
+ + ei_bruteforce_det4_helper(m,1,2,0,3)
+ - ei_bruteforce_det4_helper(m,1,3,0,2)
+ + ei_bruteforce_det4_helper(m,2,3,0,1);
+ }
+};
+
+/** \lu_module
+ *
+ * \returns the determinant of this matrix
+ */
+template<typename Derived>
+inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
+{
+ assert(rows() == cols());
+ return ei_determinant_impl<Derived>::run(derived());
+}
+
+#endif // EIGEN_DETERMINANT_H
diff --git a/extern/Eigen2/Eigen/src/LU/Inverse.h b/extern/Eigen2/Eigen/src/LU/Inverse.h
new file mode 100644
index 00000000000..3d4d6348949
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/LU/Inverse.h
@@ -0,0 +1,258 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_INVERSE_H
+#define EIGEN_INVERSE_H
+
+/********************************************************************
+*** Part 1 : optimized implementations for fixed-size 2,3,4 cases ***
+********************************************************************/
+
+template<typename MatrixType>
+void ei_compute_inverse_in_size2_case(const MatrixType& matrix, MatrixType* result)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ const Scalar invdet = Scalar(1) / matrix.determinant();
+ result->coeffRef(0,0) = matrix.coeff(1,1) * invdet;
+ result->coeffRef(1,0) = -matrix.coeff(1,0) * invdet;
+ result->coeffRef(0,1) = -matrix.coeff(0,1) * invdet;
+ result->coeffRef(1,1) = matrix.coeff(0,0) * invdet;
+}
+
+template<typename XprType, typename MatrixType>
+bool ei_compute_inverse_in_size2_case_with_check(const XprType& matrix, MatrixType* result)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ const Scalar det = matrix.determinant();
+ if(ei_isMuchSmallerThan(det, matrix.cwise().abs().maxCoeff())) return false;
+ const Scalar invdet = Scalar(1) / det;
+ result->coeffRef(0,0) = matrix.coeff(1,1) * invdet;
+ result->coeffRef(1,0) = -matrix.coeff(1,0) * invdet;
+ result->coeffRef(0,1) = -matrix.coeff(0,1) * invdet;
+ result->coeffRef(1,1) = matrix.coeff(0,0) * invdet;
+ return true;
+}
+
+template<typename MatrixType>
+void ei_compute_inverse_in_size3_case(const MatrixType& matrix, MatrixType* result)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ const Scalar det_minor00 = matrix.minor(0,0).determinant();
+ const Scalar det_minor10 = matrix.minor(1,0).determinant();
+ const Scalar det_minor20 = matrix.minor(2,0).determinant();
+ const Scalar invdet = Scalar(1) / ( det_minor00 * matrix.coeff(0,0)
+ - det_minor10 * matrix.coeff(1,0)
+ + det_minor20 * matrix.coeff(2,0) );
+ result->coeffRef(0, 0) = det_minor00 * invdet;
+ result->coeffRef(0, 1) = -det_minor10 * invdet;
+ result->coeffRef(0, 2) = det_minor20 * invdet;
+ result->coeffRef(1, 0) = -matrix.minor(0,1).determinant() * invdet;
+ result->coeffRef(1, 1) = matrix.minor(1,1).determinant() * invdet;
+ result->coeffRef(1, 2) = -matrix.minor(2,1).determinant() * invdet;
+ result->coeffRef(2, 0) = matrix.minor(0,2).determinant() * invdet;
+ result->coeffRef(2, 1) = -matrix.minor(1,2).determinant() * invdet;
+ result->coeffRef(2, 2) = matrix.minor(2,2).determinant() * invdet;
+}
+
+template<typename MatrixType>
+bool ei_compute_inverse_in_size4_case_helper(const MatrixType& matrix, MatrixType* result)
+{
+ /* Let's split M into four 2x2 blocks:
+ * (P Q)
+ * (R S)
+ * If P is invertible, with inverse denoted by P_inverse, and if
+ * (S - R*P_inverse*Q) is also invertible, then the inverse of M is
+ * (P' Q')
+ * (R' S')
+ * where
+ * S' = (S - R*P_inverse*Q)^(-1)
+ * P' = P1 + (P1*Q) * S' *(R*P_inverse)
+ * Q' = -(P_inverse*Q) * S'
+ * R' = -S' * (R*P_inverse)
+ */
+ typedef Block<MatrixType,2,2> XprBlock22;
+ typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22;
+ Block22 P_inverse;
+ if(ei_compute_inverse_in_size2_case_with_check(matrix.template block<2,2>(0,0), &P_inverse))
+ {
+ const Block22 Q = matrix.template block<2,2>(0,2);
+ const Block22 P_inverse_times_Q = P_inverse * Q;
+ const XprBlock22 R = matrix.template block<2,2>(2,0);
+ const Block22 R_times_P_inverse = R * P_inverse;
+ const Block22 R_times_P_inverse_times_Q = R_times_P_inverse * Q;
+ const XprBlock22 S = matrix.template block<2,2>(2,2);
+ const Block22 X = S - R_times_P_inverse_times_Q;
+ Block22 Y;
+ ei_compute_inverse_in_size2_case(X, &Y);
+ result->template block<2,2>(2,2) = Y;
+ result->template block<2,2>(2,0) = - Y * R_times_P_inverse;
+ const Block22 Z = P_inverse_times_Q * Y;
+ result->template block<2,2>(0,2) = - Z;
+ result->template block<2,2>(0,0) = P_inverse + Z * R_times_P_inverse;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+template<typename MatrixType>
+void ei_compute_inverse_in_size4_case(const MatrixType& matrix, MatrixType* result)
+{
+ if(ei_compute_inverse_in_size4_case_helper(matrix, result))
+ {
+ // good ! The topleft 2x2 block was invertible, so the 2x2 blocks approach is successful.
+ return;
+ }
+ else
+ {
+ // rare case: the topleft 2x2 block is not invertible (but the matrix itself is assumed to be).
+ // since this is a rare case, we don't need to optimize it. We just want to handle it with little
+ // additional code.
+ MatrixType m(matrix);
+ m.row(0).swap(m.row(2));
+ m.row(1).swap(m.row(3));
+ if(ei_compute_inverse_in_size4_case_helper(m, result))
+ {
+ // good, the topleft 2x2 block of m is invertible. Since m is different from matrix in that some
+ // rows were permuted, the actual inverse of matrix is derived from the inverse of m by permuting
+ // the corresponding columns.
+ result->col(0).swap(result->col(2));
+ result->col(1).swap(result->col(3));
+ }
+ else
+ {
+ // last possible case. Since matrix is assumed to be invertible, this last case has to work.
+ // first, undo the swaps previously made
+ m.row(0).swap(m.row(2));
+ m.row(1).swap(m.row(3));
+ // swap row 0 with the the row among 0 and 1 that has the biggest 2 first coeffs
+ int swap0with = ei_abs(m.coeff(0,0))+ei_abs(m.coeff(0,1))>ei_abs(m.coeff(1,0))+ei_abs(m.coeff(1,1)) ? 0 : 1;
+ m.row(0).swap(m.row(swap0with));
+ // swap row 1 with the the row among 2 and 3 that has the biggest 2 first coeffs
+ int swap1with = ei_abs(m.coeff(2,0))+ei_abs(m.coeff(2,1))>ei_abs(m.coeff(3,0))+ei_abs(m.coeff(3,1)) ? 2 : 3;
+ m.row(1).swap(m.row(swap1with));
+ ei_compute_inverse_in_size4_case_helper(m, result);
+ result->col(1).swap(result->col(swap1with));
+ result->col(0).swap(result->col(swap0with));
+ }
+ }
+}
+
+/***********************************************
+*** Part 2 : selector and MatrixBase methods ***
+***********************************************/
+
+template<typename MatrixType, int Size = MatrixType::RowsAtCompileTime>
+struct ei_compute_inverse
+{
+ static inline void run(const MatrixType& matrix, MatrixType* result)
+ {
+ LU<MatrixType> lu(matrix);
+ lu.computeInverse(result);
+ }
+};
+
+template<typename MatrixType>
+struct ei_compute_inverse<MatrixType, 1>
+{
+ static inline void run(const MatrixType& matrix, MatrixType* result)
+ {
+ typedef typename MatrixType::Scalar Scalar;
+ result->coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
+ }
+};
+
+template<typename MatrixType>
+struct ei_compute_inverse<MatrixType, 2>
+{
+ static inline void run(const MatrixType& matrix, MatrixType* result)
+ {
+ ei_compute_inverse_in_size2_case(matrix, result);
+ }
+};
+
+template<typename MatrixType>
+struct ei_compute_inverse<MatrixType, 3>
+{
+ static inline void run(const MatrixType& matrix, MatrixType* result)
+ {
+ ei_compute_inverse_in_size3_case(matrix, result);
+ }
+};
+
+template<typename MatrixType>
+struct ei_compute_inverse<MatrixType, 4>
+{
+ static inline void run(const MatrixType& matrix, MatrixType* result)
+ {
+ ei_compute_inverse_in_size4_case(matrix, result);
+ }
+};
+
+/** \lu_module
+ *
+ * Computes the matrix inverse of this matrix.
+ *
+ * \note This matrix must be invertible, otherwise the result is undefined.
+ *
+ * \param result Pointer to the matrix in which to store the result.
+ *
+ * Example: \include MatrixBase_computeInverse.cpp
+ * Output: \verbinclude MatrixBase_computeInverse.out
+ *
+ * \sa inverse()
+ */
+template<typename Derived>
+inline void MatrixBase<Derived>::computeInverse(PlainMatrixType *result) const
+{
+ ei_assert(rows() == cols());
+ EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)
+ ei_compute_inverse<PlainMatrixType>::run(eval(), result);
+}
+
+/** \lu_module
+ *
+ * \returns the matrix inverse of this matrix.
+ *
+ * \note This matrix must be invertible, otherwise the result is undefined.
+ *
+ * \note This method returns a matrix by value, which can be inefficient. To avoid that overhead,
+ * use computeInverse() instead.
+ *
+ * Example: \include MatrixBase_inverse.cpp
+ * Output: \verbinclude MatrixBase_inverse.out
+ *
+ * \sa computeInverse()
+ */
+template<typename Derived>
+inline const typename MatrixBase<Derived>::PlainMatrixType MatrixBase<Derived>::inverse() const
+{
+ PlainMatrixType result(rows(), cols());
+ computeInverse(&result);
+ return result;
+}
+
+#endif // EIGEN_INVERSE_H
diff --git a/extern/Eigen2/Eigen/src/LU/LU.h b/extern/Eigen2/Eigen/src/LU/LU.h
new file mode 100644
index 00000000000..176e76a91a3
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/LU/LU.h
@@ -0,0 +1,541 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_LU_H
+#define EIGEN_LU_H
+
+/** \ingroup LU_Module
+ *
+ * \class LU
+ *
+ * \brief LU decomposition of a matrix with complete pivoting, and related features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the LU decomposition
+ *
+ * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A
+ * is decomposed as A = PLUQ where L is unit-lower-triangular, U is upper-triangular, and P and Q
+ * are permutation matrices. This is a rank-revealing LU decomposition. The eigenvalues (diagonal
+ * coefficients) of U are sorted in such a way that any zeros are at the end, so that the rank
+ * of A is the index of the first zero on the diagonal of U (with indices starting at 0) if any.
+ *
+ * This decomposition provides the generic approach to solving systems of linear equations, computing
+ * the rank, invertibility, inverse, kernel, and determinant.
+ *
+ * This LU decomposition is very stable and well tested with large matrices. Even exact rank computation
+ * works at sizes larger than 1000x1000. However there are use cases where the SVD decomposition is inherently
+ * more stable when dealing with numerically damaged input. For example, computing the kernel is more stable with
+ * SVD because the SVD can determine which singular values are negligible while LU has to work at the level of matrix
+ * coefficients that are less meaningful in this respect.
+ *
+ * The data of the LU decomposition can be directly accessed through the methods matrixLU(),
+ * permutationP(), permutationQ().
+ *
+ * As an exemple, here is how the original matrix can be retrieved:
+ * \include class_LU.cpp
+ * Output: \verbinclude class_LU.out
+ *
+ * \sa MatrixBase::lu(), MatrixBase::determinant(), MatrixBase::inverse(), MatrixBase::computeInverse()
+ */
+template<typename MatrixType> class LU
+{
+ public:
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
+ typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
+ typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
+
+ enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN(
+ MatrixType::MaxColsAtCompileTime,
+ MatrixType::MaxRowsAtCompileTime)
+ };
+
+ typedef Matrix<typename MatrixType::Scalar,
+ MatrixType::ColsAtCompileTime, // the number of rows in the "kernel matrix" is the number of cols of the original matrix
+ // so that the product "matrix * kernel = zero" makes sense
+ Dynamic, // we don't know at compile-time the dimension of the kernel
+ MatrixType::Options,
+ MatrixType::MaxColsAtCompileTime, // see explanation for 2nd template parameter
+ MatrixType::MaxColsAtCompileTime // the kernel is a subspace of the domain space, whose dimension is the number
+ // of columns of the original matrix
+ > KernelResultType;
+
+ typedef Matrix<typename MatrixType::Scalar,
+ MatrixType::RowsAtCompileTime, // the image is a subspace of the destination space, whose dimension is the number
+ // of rows of the original matrix
+ Dynamic, // we don't know at compile time the dimension of the image (the rank)
+ MatrixType::Options,
+ MatrixType::MaxRowsAtCompileTime, // the image matrix will consist of columns from the original matrix,
+ MatrixType::MaxColsAtCompileTime // so it has the same number of rows and at most as many columns.
+ > ImageResultType;
+
+ /** Constructor.
+ *
+ * \param matrix the matrix of which to compute the LU decomposition.
+ */
+ LU(const MatrixType& matrix);
+
+ /** \returns the LU decomposition matrix: the upper-triangular part is U, the
+ * unit-lower-triangular part is L (at least for square matrices; in the non-square
+ * case, special care is needed, see the documentation of class LU).
+ *
+ * \sa matrixL(), matrixU()
+ */
+ inline const MatrixType& matrixLU() const
+ {
+ return m_lu;
+ }
+
+ /** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed,
+ * representing the P permutation i.e. the permutation of the rows. For its precise meaning,
+ * see the examples given in the documentation of class LU.
+ *
+ * \sa permutationQ()
+ */
+ inline const IntColVectorType& permutationP() const
+ {
+ return m_p;
+ }
+
+ /** \returns a vector of integers, whose size is the number of columns of the matrix being
+ * decomposed, representing the Q permutation i.e. the permutation of the columns.
+ * For its precise meaning, see the examples given in the documentation of class LU.
+ *
+ * \sa permutationP()
+ */
+ inline const IntRowVectorType& permutationQ() const
+ {
+ return m_q;
+ }
+
+ /** Computes a basis of the kernel of the matrix, also called the null-space of the matrix.
+ *
+ * \note This method is only allowed on non-invertible matrices, as determined by
+ * isInvertible(). Calling it on an invertible matrix will make an assertion fail.
+ *
+ * \param result a pointer to the matrix in which to store the kernel. The columns of this
+ * matrix will be set to form a basis of the kernel (it will be resized
+ * if necessary).
+ *
+ * Example: \include LU_computeKernel.cpp
+ * Output: \verbinclude LU_computeKernel.out
+ *
+ * \sa kernel(), computeImage(), image()
+ */
+ template<typename KernelMatrixType>
+ void computeKernel(KernelMatrixType *result) const;
+
+ /** Computes a basis of the image of the matrix, also called the column-space or range of he matrix.
+ *
+ * \note Calling this method on the zero matrix will make an assertion fail.
+ *
+ * \param result a pointer to the matrix in which to store the image. The columns of this
+ * matrix will be set to form a basis of the image (it will be resized
+ * if necessary).
+ *
+ * Example: \include LU_computeImage.cpp
+ * Output: \verbinclude LU_computeImage.out
+ *
+ * \sa image(), computeKernel(), kernel()
+ */
+ template<typename ImageMatrixType>
+ void computeImage(ImageMatrixType *result) const;
+
+ /** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix
+ * will form a basis of the kernel.
+ *
+ * \note: this method is only allowed on non-invertible matrices, as determined by
+ * isInvertible(). Calling it on an invertible matrix will make an assertion fail.
+ *
+ * \note: this method returns a matrix by value, which induces some inefficiency.
+ * If you prefer to avoid this overhead, use computeKernel() instead.
+ *
+ * Example: \include LU_kernel.cpp
+ * Output: \verbinclude LU_kernel.out
+ *
+ * \sa computeKernel(), image()
+ */
+ const KernelResultType kernel() const;
+
+ /** \returns the image of the matrix, also called its column-space. The columns of the returned matrix
+ * will form a basis of the kernel.
+ *
+ * \note: Calling this method on the zero matrix will make an assertion fail.
+ *
+ * \note: this method returns a matrix by value, which induces some inefficiency.
+ * If you prefer to avoid this overhead, use computeImage() instead.
+ *
+ * Example: \include LU_image.cpp
+ * Output: \verbinclude LU_image.out
+ *
+ * \sa computeImage(), kernel()
+ */
+ const ImageResultType image() const;
+
+ /** This method finds a solution x to the equation Ax=b, where A is the matrix of which
+ * *this is the LU decomposition, if any exists.
+ *
+ * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix,
+ * the only requirement in order for the equation to make sense is that
+ * b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition.
+ * \param result a pointer to the vector or matrix in which to store the solution, if any exists.
+ * Resized if necessary, so that result->rows()==A.cols() and result->cols()==b.cols().
+ * If no solution exists, *result is left with undefined coefficients.
+ *
+ * \returns true if any solution exists, false if no solution exists.
+ *
+ * \note If there exist more than one solution, this method will arbitrarily choose one.
+ * If you need a complete analysis of the space of solutions, take the one solution obtained
+ * by this method and add to it elements of the kernel, as determined by kernel().
+ *
+ * Example: \include LU_solve.cpp
+ * Output: \verbinclude LU_solve.out
+ *
+ * \sa MatrixBase::solveTriangular(), kernel(), computeKernel(), inverse(), computeInverse()
+ */
+ template<typename OtherDerived, typename ResultType>
+ bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const;
+
+ /** \returns the determinant of the matrix of which
+ * *this is the LU decomposition. It has only linear complexity
+ * (that is, O(n) where n is the dimension of the square matrix)
+ * as the LU decomposition has already been computed.
+ *
+ * \note This is only for square matrices.
+ *
+ * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers
+ * optimized paths.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ *
+ * \sa MatrixBase::determinant()
+ */
+ typename ei_traits<MatrixType>::Scalar determinant() const;
+
+ /** \returns the rank of the matrix of which *this is the LU decomposition.
+ *
+ * \note This is computed at the time of the construction of the LU decomposition. This
+ * method does not perform any further computation.
+ */
+ inline int rank() const
+ {
+ return m_rank;
+ }
+
+ /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition.
+ *
+ * \note Since the rank is computed at the time of the construction of the LU decomposition, this
+ * method almost does not perform any further computation.
+ */
+ inline int dimensionOfKernel() const
+ {
+ return m_lu.cols() - m_rank;
+ }
+
+ /** \returns true if the matrix of which *this is the LU decomposition represents an injective
+ * linear map, i.e. has trivial kernel; false otherwise.
+ *
+ * \note Since the rank is computed at the time of the construction of the LU decomposition, this
+ * method almost does not perform any further computation.
+ */
+ inline bool isInjective() const
+ {
+ return m_rank == m_lu.cols();
+ }
+
+ /** \returns true if the matrix of which *this is the LU decomposition represents a surjective
+ * linear map; false otherwise.
+ *
+ * \note Since the rank is computed at the time of the construction of the LU decomposition, this
+ * method almost does not perform any further computation.
+ */
+ inline bool isSurjective() const
+ {
+ return m_rank == m_lu.rows();
+ }
+
+ /** \returns true if the matrix of which *this is the LU decomposition is invertible.
+ *
+ * \note Since the rank is computed at the time of the construction of the LU decomposition, this
+ * method almost does not perform any further computation.
+ */
+ inline bool isInvertible() const
+ {
+ return isInjective() && isSurjective();
+ }
+
+ /** Computes the inverse of the matrix of which *this is the LU decomposition.
+ *
+ * \param result a pointer to the matrix into which to store the inverse. Resized if needed.
+ *
+ * \note If this matrix is not invertible, *result is left with undefined coefficients.
+ * Use isInvertible() to first determine whether this matrix is invertible.
+ *
+ * \sa MatrixBase::computeInverse(), inverse()
+ */
+ inline void computeInverse(MatrixType *result) const
+ {
+ solve(MatrixType::Identity(m_lu.rows(), m_lu.cols()), result);
+ }
+
+ /** \returns the inverse of the matrix of which *this is the LU decomposition.
+ *
+ * \note If this matrix is not invertible, the returned matrix has undefined coefficients.
+ * Use isInvertible() to first determine whether this matrix is invertible.
+ *
+ * \sa computeInverse(), MatrixBase::inverse()
+ */
+ inline MatrixType inverse() const
+ {
+ MatrixType result;
+ computeInverse(&result);
+ return result;
+ }
+
+ protected:
+ const MatrixType& m_originalMatrix;
+ MatrixType m_lu;
+ IntColVectorType m_p;
+ IntRowVectorType m_q;
+ int m_det_pq;
+ int m_rank;
+ RealScalar m_precision;
+};
+
+template<typename MatrixType>
+LU<MatrixType>::LU(const MatrixType& matrix)
+ : m_originalMatrix(matrix),
+ m_lu(matrix),
+ m_p(matrix.rows()),
+ m_q(matrix.cols())
+{
+ const int size = matrix.diagonal().size();
+ const int rows = matrix.rows();
+ const int cols = matrix.cols();
+
+ // this formula comes from experimenting (see "LU precision tuning" thread on the list)
+ // and turns out to be identical to Higham's formula used already in LDLt.
+ m_precision = machine_epsilon<Scalar>() * size;
+
+ IntColVectorType rows_transpositions(matrix.rows());
+ IntRowVectorType cols_transpositions(matrix.cols());
+ int number_of_transpositions = 0;
+
+ RealScalar biggest = RealScalar(0);
+ m_rank = size;
+ for(int k = 0; k < size; ++k)
+ {
+ int row_of_biggest_in_corner, col_of_biggest_in_corner;
+ RealScalar biggest_in_corner;
+
+ biggest_in_corner = m_lu.corner(Eigen::BottomRight, rows-k, cols-k)
+ .cwise().abs()
+ .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
+ row_of_biggest_in_corner += k;
+ col_of_biggest_in_corner += k;
+ if(k==0) biggest = biggest_in_corner;
+
+ // if the corner is negligible, then we have less than full rank, and we can finish early
+ if(ei_isMuchSmallerThan(biggest_in_corner, biggest, m_precision))
+ {
+ m_rank = k;
+ for(int i = k; i < size; i++)
+ {
+ rows_transpositions.coeffRef(i) = i;
+ cols_transpositions.coeffRef(i) = i;
+ }
+ break;
+ }
+
+ rows_transpositions.coeffRef(k) = row_of_biggest_in_corner;
+ cols_transpositions.coeffRef(k) = col_of_biggest_in_corner;
+ if(k != row_of_biggest_in_corner) {
+ m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
+ ++number_of_transpositions;
+ }
+ if(k != col_of_biggest_in_corner) {
+ m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
+ ++number_of_transpositions;
+ }
+ if(k<rows-1)
+ m_lu.col(k).end(rows-k-1) /= m_lu.coeff(k,k);
+ if(k<size-1)
+ for(int col = k + 1; col < cols; ++col)
+ m_lu.col(col).end(rows-k-1) -= m_lu.col(k).end(rows-k-1) * m_lu.coeff(k,col);
+ }
+
+ for(int k = 0; k < matrix.rows(); ++k) m_p.coeffRef(k) = k;
+ for(int k = size-1; k >= 0; --k)
+ std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k)));
+
+ for(int k = 0; k < matrix.cols(); ++k) m_q.coeffRef(k) = k;
+ for(int k = 0; k < size; ++k)
+ std::swap(m_q.coeffRef(k), m_q.coeffRef(cols_transpositions.coeff(k)));
+
+ m_det_pq = (number_of_transpositions%2) ? -1 : 1;
+}
+
+template<typename MatrixType>
+typename ei_traits<MatrixType>::Scalar LU<MatrixType>::determinant() const
+{
+ return Scalar(m_det_pq) * m_lu.diagonal().redux(ei_scalar_product_op<Scalar>());
+}
+
+template<typename MatrixType>
+template<typename KernelMatrixType>
+void LU<MatrixType>::computeKernel(KernelMatrixType *result) const
+{
+ ei_assert(!isInvertible());
+ const int dimker = dimensionOfKernel(), cols = m_lu.cols();
+ result->resize(cols, dimker);
+
+ /* Let us use the following lemma:
+ *
+ * Lemma: If the matrix A has the LU decomposition PAQ = LU,
+ * then Ker A = Q(Ker U).
+ *
+ * Proof: trivial: just keep in mind that P, Q, L are invertible.
+ */
+
+ /* Thus, all we need to do is to compute Ker U, and then apply Q.
+ *
+ * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end.
+ * Thus, the diagonal of U ends with exactly
+ * m_dimKer zero's. Let us use that to construct m_dimKer linearly
+ * independent vectors in Ker U.
+ */
+
+ Matrix<Scalar, Dynamic, Dynamic, MatrixType::Options,
+ MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime>
+ y(-m_lu.corner(TopRight, m_rank, dimker));
+
+ m_lu.corner(TopLeft, m_rank, m_rank)
+ .template marked<UpperTriangular>()
+ .solveTriangularInPlace(y);
+
+ for(int i = 0; i < m_rank; ++i) result->row(m_q.coeff(i)) = y.row(i);
+ for(int i = m_rank; i < cols; ++i) result->row(m_q.coeff(i)).setZero();
+ for(int k = 0; k < dimker; ++k) result->coeffRef(m_q.coeff(m_rank+k), k) = Scalar(1);
+}
+
+template<typename MatrixType>
+const typename LU<MatrixType>::KernelResultType
+LU<MatrixType>::kernel() const
+{
+ KernelResultType result(m_lu.cols(), dimensionOfKernel());
+ computeKernel(&result);
+ return result;
+}
+
+template<typename MatrixType>
+template<typename ImageMatrixType>
+void LU<MatrixType>::computeImage(ImageMatrixType *result) const
+{
+ ei_assert(m_rank > 0);
+ result->resize(m_originalMatrix.rows(), m_rank);
+ for(int i = 0; i < m_rank; ++i)
+ result->col(i) = m_originalMatrix.col(m_q.coeff(i));
+}
+
+template<typename MatrixType>
+const typename LU<MatrixType>::ImageResultType
+LU<MatrixType>::image() const
+{
+ ImageResultType result(m_originalMatrix.rows(), m_rank);
+ computeImage(&result);
+ return result;
+}
+
+template<typename MatrixType>
+template<typename OtherDerived, typename ResultType>
+bool LU<MatrixType>::solve(
+ const MatrixBase<OtherDerived>& b,
+ ResultType *result
+) const
+{
+ /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}.
+ * So we proceed as follows:
+ * Step 1: compute c = Pb.
+ * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible.
+ * Step 3: replace c by the solution x to Ux = c. Check if a solution really exists.
+ * Step 4: result = Qc;
+ */
+
+ const int rows = m_lu.rows(), cols = m_lu.cols();
+ ei_assert(b.rows() == rows);
+ const int smalldim = std::min(rows, cols);
+
+ typename OtherDerived::PlainMatrixType c(b.rows(), b.cols());
+
+ // Step 1
+ for(int i = 0; i < rows; ++i) c.row(m_p.coeff(i)) = b.row(i);
+
+ // Step 2
+ m_lu.corner(Eigen::TopLeft,smalldim,smalldim).template marked<UnitLowerTriangular>()
+ .solveTriangularInPlace(
+ c.corner(Eigen::TopLeft, smalldim, c.cols()));
+ if(rows>cols)
+ {
+ c.corner(Eigen::BottomLeft, rows-cols, c.cols())
+ -= m_lu.corner(Eigen::BottomLeft, rows-cols, cols) * c.corner(Eigen::TopLeft, cols, c.cols());
+ }
+
+ // Step 3
+ if(!isSurjective())
+ {
+ // is c is in the image of U ?
+ RealScalar biggest_in_c = m_rank>0 ? c.corner(TopLeft, m_rank, c.cols()).cwise().abs().maxCoeff() : 0;
+ for(int col = 0; col < c.cols(); ++col)
+ for(int row = m_rank; row < c.rows(); ++row)
+ if(!ei_isMuchSmallerThan(c.coeff(row,col), biggest_in_c, m_precision))
+ return false;
+ }
+ m_lu.corner(TopLeft, m_rank, m_rank)
+ .template marked<UpperTriangular>()
+ .solveTriangularInPlace(c.corner(TopLeft, m_rank, c.cols()));
+
+ // Step 4
+ result->resize(m_lu.cols(), b.cols());
+ for(int i = 0; i < m_rank; ++i) result->row(m_q.coeff(i)) = c.row(i);
+ for(int i = m_rank; i < m_lu.cols(); ++i) result->row(m_q.coeff(i)).setZero();
+ return true;
+}
+
+/** \lu_module
+ *
+ * \return the LU decomposition of \c *this.
+ *
+ * \sa class LU
+ */
+template<typename Derived>
+inline const LU<typename MatrixBase<Derived>::PlainMatrixType>
+MatrixBase<Derived>::lu() const
+{
+ return LU<PlainMatrixType>(eval());
+}
+
+#endif // EIGEN_LU_H
diff --git a/extern/Eigen2/Eigen/src/LeastSquares/LeastSquares.h b/extern/Eigen2/Eigen/src/LeastSquares/LeastSquares.h
new file mode 100644
index 00000000000..b2595ede1fe
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/LeastSquares/LeastSquares.h
@@ -0,0 +1,182 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_LEASTSQUARES_H
+#define EIGEN_LEASTSQUARES_H
+
+/** \ingroup LeastSquares_Module
+ *
+ * \leastsquares_module
+ *
+ * For a set of points, this function tries to express
+ * one of the coords as a linear (affine) function of the other coords.
+ *
+ * This is best explained by an example. This function works in full
+ * generality, for points in a space of arbitrary dimension, and also over
+ * the complex numbers, but for this example we will work in dimension 3
+ * over the real numbers (doubles).
+ *
+ * So let us work with the following set of 5 points given by their
+ * \f$(x,y,z)\f$ coordinates:
+ * @code
+ Vector3d points[5];
+ points[0] = Vector3d( 3.02, 6.89, -4.32 );
+ points[1] = Vector3d( 2.01, 5.39, -3.79 );
+ points[2] = Vector3d( 2.41, 6.01, -4.01 );
+ points[3] = Vector3d( 2.09, 5.55, -3.86 );
+ points[4] = Vector3d( 2.58, 6.32, -4.10 );
+ * @endcode
+ * Suppose that we want to express the second coordinate (\f$y\f$) as a linear
+ * expression in \f$x\f$ and \f$z\f$, that is,
+ * \f[ y=ax+bz+c \f]
+ * for some constants \f$a,b,c\f$. Thus, we want to find the best possible
+ * constants \f$a,b,c\f$ so that the plane of equation \f$y=ax+bz+c\f$ fits
+ * best the five above points. To do that, call this function as follows:
+ * @code
+ Vector3d coeffs; // will store the coefficients a, b, c
+ linearRegression(
+ 5,
+ &points,
+ &coeffs,
+ 1 // the coord to express as a function of
+ // the other ones. 0 means x, 1 means y, 2 means z.
+ );
+ * @endcode
+ * Now the vector \a coeffs is approximately
+ * \f$( 0.495 , -1.927 , -2.906 )\f$.
+ * Thus, we get \f$a=0.495, b = -1.927, c = -2.906\f$. Let us check for
+ * instance how near points[0] is from the plane of equation \f$y=ax+bz+c\f$.
+ * Looking at the coords of points[0], we see that:
+ * \f[ax+bz+c = 0.495 * 3.02 + (-1.927) * (-4.32) + (-2.906) = 6.91.\f]
+ * On the other hand, we have \f$y=6.89\f$. We see that the values
+ * \f$6.91\f$ and \f$6.89\f$
+ * are near, so points[0] is very near the plane of equation \f$y=ax+bz+c\f$.
+ *
+ * Let's now describe precisely the parameters:
+ * @param numPoints the number of points
+ * @param points the array of pointers to the points on which to perform the linear regression
+ * @param result pointer to the vector in which to store the result.
+ This vector must be of the same type and size as the
+ data points. The meaning of its coords is as follows.
+ For brevity, let \f$n=Size\f$,
+ \f$r_i=result[i]\f$,
+ and \f$f=funcOfOthers\f$. Denote by
+ \f$x_0,\ldots,x_{n-1}\f$
+ the n coordinates in the n-dimensional space.
+ Then the resulting equation is:
+ \f[ x_f = r_0 x_0 + \cdots + r_{f-1}x_{f-1}
+ + r_{f+1}x_{f+1} + \cdots + r_{n-1}x_{n-1} + r_n. \f]
+ * @param funcOfOthers Determines which coord to express as a function of the
+ others. Coords are numbered starting from 0, so that a
+ value of 0 means \f$x\f$, 1 means \f$y\f$,
+ 2 means \f$z\f$, ...
+ *
+ * \sa fitHyperplane()
+ */
+template<typename VectorType>
+void linearRegression(int numPoints,
+ VectorType **points,
+ VectorType *result,
+ int funcOfOthers )
+{
+ typedef typename VectorType::Scalar Scalar;
+ typedef Hyperplane<Scalar, VectorType::SizeAtCompileTime> HyperplaneType;
+ const int size = points[0]->size();
+ result->resize(size);
+ HyperplaneType h(size);
+ fitHyperplane(numPoints, points, &h);
+ for(int i = 0; i < funcOfOthers; i++)
+ result->coeffRef(i) = - h.coeffs()[i] / h.coeffs()[funcOfOthers];
+ for(int i = funcOfOthers; i < size; i++)
+ result->coeffRef(i) = - h.coeffs()[i+1] / h.coeffs()[funcOfOthers];
+}
+
+/** \ingroup LeastSquares_Module
+ *
+ * \leastsquares_module
+ *
+ * This function is quite similar to linearRegression(), so we refer to the
+ * documentation of this function and only list here the differences.
+ *
+ * The main difference from linearRegression() is that this function doesn't
+ * take a \a funcOfOthers argument. Instead, it finds a general equation
+ * of the form
+ * \f[ r_0 x_0 + \cdots + r_{n-1}x_{n-1} + r_n = 0, \f]
+ * where \f$n=Size\f$, \f$r_i=retCoefficients[i]\f$, and we denote by
+ * \f$x_0,\ldots,x_{n-1}\f$ the n coordinates in the n-dimensional space.
+ *
+ * Thus, the vector \a retCoefficients has size \f$n+1\f$, which is another
+ * difference from linearRegression().
+ *
+ * In practice, this function performs an hyper-plane fit in a total least square sense
+ * via the following steps:
+ * 1 - center the data to the mean
+ * 2 - compute the covariance matrix
+ * 3 - pick the eigenvector corresponding to the smallest eigenvalue of the covariance matrix
+ * The ratio of the smallest eigenvalue and the second one gives us a hint about the relevance
+ * of the solution. This value is optionally returned in \a soundness.
+ *
+ * \sa linearRegression()
+ */
+template<typename VectorType, typename HyperplaneType>
+void fitHyperplane(int numPoints,
+ VectorType **points,
+ HyperplaneType *result,
+ typename NumTraits<typename VectorType::Scalar>::Real* soundness = 0)
+{
+ typedef typename VectorType::Scalar Scalar;
+ typedef Matrix<Scalar,VectorType::SizeAtCompileTime,VectorType::SizeAtCompileTime> CovMatrixType;
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType)
+ ei_assert(numPoints >= 1);
+ int size = points[0]->size();
+ ei_assert(size+1 == result->coeffs().size());
+
+ // compute the mean of the data
+ VectorType mean = VectorType::Zero(size);
+ for(int i = 0; i < numPoints; ++i)
+ mean += *(points[i]);
+ mean /= numPoints;
+
+ // compute the covariance matrix
+ CovMatrixType covMat = CovMatrixType::Zero(size, size);
+ VectorType remean = VectorType::Zero(size);
+ for(int i = 0; i < numPoints; ++i)
+ {
+ VectorType diff = (*(points[i]) - mean).conjugate();
+ covMat += diff * diff.adjoint();
+ }
+
+ // now we just have to pick the eigen vector with smallest eigen value
+ SelfAdjointEigenSolver<CovMatrixType> eig(covMat);
+ result->normal() = eig.eigenvectors().col(0);
+ if (soundness)
+ *soundness = eig.eigenvalues().coeff(0)/eig.eigenvalues().coeff(1);
+
+ // let's compute the constant coefficient such that the
+ // plane pass trough the mean point:
+ result->offset() = - (result->normal().cwise()* mean).sum();
+}
+
+
+#endif // EIGEN_LEASTSQUARES_H
diff --git a/extern/Eigen2/Eigen/src/QR/EigenSolver.h b/extern/Eigen2/Eigen/src/QR/EigenSolver.h
new file mode 100644
index 00000000000..70f21cebcdb
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/QR/EigenSolver.h
@@ -0,0 +1,722 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_EIGENSOLVER_H
+#define EIGEN_EIGENSOLVER_H
+
+/** \ingroup QR_Module
+ * \nonstableyet
+ *
+ * \class EigenSolver
+ *
+ * \brief Eigen values/vectors solver for non selfadjoint matrices
+ *
+ * \param MatrixType the type of the matrix of which we are computing the eigen decomposition
+ *
+ * Currently it only support real matrices.
+ *
+ * \note this code was adapted from JAMA (public domain)
+ *
+ * \sa MatrixBase::eigenvalues(), SelfAdjointEigenSolver
+ */
+template<typename _MatrixType> class EigenSolver
+{
+ public:
+
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef std::complex<RealScalar> Complex;
+ typedef Matrix<Complex, MatrixType::ColsAtCompileTime, 1> EigenvalueType;
+ typedef Matrix<Complex, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> EigenvectorType;
+ typedef Matrix<RealScalar, MatrixType::ColsAtCompileTime, 1> RealVectorType;
+ typedef Matrix<RealScalar, Dynamic, 1> RealVectorTypeX;
+
+ /**
+ * \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via EigenSolver::compute(const MatrixType&).
+ */
+ EigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false) {}
+
+ EigenSolver(const MatrixType& matrix)
+ : m_eivec(matrix.rows(), matrix.cols()),
+ m_eivalues(matrix.cols()),
+ m_isInitialized(false)
+ {
+ compute(matrix);
+ }
+
+
+ EigenvectorType eigenvectors(void) const;
+
+ /** \returns a real matrix V of pseudo eigenvectors.
+ *
+ * Let D be the block diagonal matrix with the real eigenvalues in 1x1 blocks,
+ * and any complex values u+iv in 2x2 blocks [u v ; -v u]. Then, the matrices D
+ * and V satisfy A*V = V*D.
+ *
+ * More precisely, if the diagonal matrix of the eigen values is:\n
+ * \f$
+ * \left[ \begin{array}{cccccc}
+ * u+iv & & & & & \\
+ * & u-iv & & & & \\
+ * & & a+ib & & & \\
+ * & & & a-ib & & \\
+ * & & & & x & \\
+ * & & & & & y \\
+ * \end{array} \right]
+ * \f$ \n
+ * then, we have:\n
+ * \f$
+ * D =\left[ \begin{array}{cccccc}
+ * u & v & & & & \\
+ * -v & u & & & & \\
+ * & & a & b & & \\
+ * & & -b & a & & \\
+ * & & & & x & \\
+ * & & & & & y \\
+ * \end{array} \right]
+ * \f$
+ *
+ * \sa pseudoEigenvalueMatrix()
+ */
+ const MatrixType& pseudoEigenvectors() const
+ {
+ ei_assert(m_isInitialized && "EigenSolver is not initialized.");
+ return m_eivec;
+ }
+
+ MatrixType pseudoEigenvalueMatrix() const;
+
+ /** \returns the eigenvalues as a column vector */
+ EigenvalueType eigenvalues() const
+ {
+ ei_assert(m_isInitialized && "EigenSolver is not initialized.");
+ return m_eivalues;
+ }
+
+ void compute(const MatrixType& matrix);
+
+ private:
+
+ void orthes(MatrixType& matH, RealVectorType& ort);
+ void hqr2(MatrixType& matH);
+
+ protected:
+ MatrixType m_eivec;
+ EigenvalueType m_eivalues;
+ bool m_isInitialized;
+};
+
+/** \returns the real block diagonal matrix D of the eigenvalues.
+ *
+ * See pseudoEigenvectors() for the details.
+ */
+template<typename MatrixType>
+MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
+{
+ ei_assert(m_isInitialized && "EigenSolver is not initialized.");
+ int n = m_eivec.cols();
+ MatrixType matD = MatrixType::Zero(n,n);
+ for (int i=0; i<n; ++i)
+ {
+ if (ei_isMuchSmallerThan(ei_imag(m_eivalues.coeff(i)), ei_real(m_eivalues.coeff(i))))
+ matD.coeffRef(i,i) = ei_real(m_eivalues.coeff(i));
+ else
+ {
+ matD.template block<2,2>(i,i) << ei_real(m_eivalues.coeff(i)), ei_imag(m_eivalues.coeff(i)),
+ -ei_imag(m_eivalues.coeff(i)), ei_real(m_eivalues.coeff(i));
+ ++i;
+ }
+ }
+ return matD;
+}
+
+/** \returns the normalized complex eigenvectors as a matrix of column vectors.
+ *
+ * \sa eigenvalues(), pseudoEigenvectors()
+ */
+template<typename MatrixType>
+typename EigenSolver<MatrixType>::EigenvectorType EigenSolver<MatrixType>::eigenvectors(void) const
+{
+ ei_assert(m_isInitialized && "EigenSolver is not initialized.");
+ int n = m_eivec.cols();
+ EigenvectorType matV(n,n);
+ for (int j=0; j<n; ++j)
+ {
+ if (ei_isMuchSmallerThan(ei_abs(ei_imag(m_eivalues.coeff(j))), ei_abs(ei_real(m_eivalues.coeff(j)))))
+ {
+ // we have a real eigen value
+ matV.col(j) = m_eivec.col(j).template cast<Complex>();
+ }
+ else
+ {
+ // we have a pair of complex eigen values
+ for (int i=0; i<n; ++i)
+ {
+ matV.coeffRef(i,j) = Complex(m_eivec.coeff(i,j), m_eivec.coeff(i,j+1));
+ matV.coeffRef(i,j+1) = Complex(m_eivec.coeff(i,j), -m_eivec.coeff(i,j+1));
+ }
+ matV.col(j).normalize();
+ matV.col(j+1).normalize();
+ ++j;
+ }
+ }
+ return matV;
+}
+
+template<typename MatrixType>
+void EigenSolver<MatrixType>::compute(const MatrixType& matrix)
+{
+ assert(matrix.cols() == matrix.rows());
+ int n = matrix.cols();
+ m_eivalues.resize(n,1);
+
+ MatrixType matH = matrix;
+ RealVectorType ort(n);
+
+ // Reduce to Hessenberg form.
+ orthes(matH, ort);
+
+ // Reduce Hessenberg to real Schur form.
+ hqr2(matH);
+
+ m_isInitialized = true;
+}
+
+// Nonsymmetric reduction to Hessenberg form.
+template<typename MatrixType>
+void EigenSolver<MatrixType>::orthes(MatrixType& matH, RealVectorType& ort)
+{
+ // This is derived from the Algol procedures orthes and ortran,
+ // by Martin and Wilkinson, Handbook for Auto. Comp.,
+ // Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutines in EISPACK.
+
+ int n = m_eivec.cols();
+ int low = 0;
+ int high = n-1;
+
+ for (int m = low+1; m <= high-1; ++m)
+ {
+ // Scale column.
+ RealScalar scale = matH.block(m, m-1, high-m+1, 1).cwise().abs().sum();
+ if (scale != 0.0)
+ {
+ // Compute Householder transformation.
+ RealScalar h = 0.0;
+ // FIXME could be rewritten, but this one looks better wrt cache
+ for (int i = high; i >= m; i--)
+ {
+ ort.coeffRef(i) = matH.coeff(i,m-1)/scale;
+ h += ort.coeff(i) * ort.coeff(i);
+ }
+ RealScalar g = ei_sqrt(h);
+ if (ort.coeff(m) > 0)
+ g = -g;
+ h = h - ort.coeff(m) * g;
+ ort.coeffRef(m) = ort.coeff(m) - g;
+
+ // Apply Householder similarity transformation
+ // H = (I-u*u'/h)*H*(I-u*u')/h)
+ int bSize = high-m+1;
+ matH.block(m, m, bSize, n-m) -= ((ort.segment(m, bSize)/h)
+ * (ort.segment(m, bSize).transpose() * matH.block(m, m, bSize, n-m)).lazy()).lazy();
+
+ matH.block(0, m, high+1, bSize) -= ((matH.block(0, m, high+1, bSize) * ort.segment(m, bSize)).lazy()
+ * (ort.segment(m, bSize)/h).transpose()).lazy();
+
+ ort.coeffRef(m) = scale*ort.coeff(m);
+ matH.coeffRef(m,m-1) = scale*g;
+ }
+ }
+
+ // Accumulate transformations (Algol's ortran).
+ m_eivec.setIdentity();
+
+ for (int m = high-1; m >= low+1; m--)
+ {
+ if (matH.coeff(m,m-1) != 0.0)
+ {
+ ort.segment(m+1, high-m) = matH.col(m-1).segment(m+1, high-m);
+
+ int bSize = high-m+1;
+ m_eivec.block(m, m, bSize, bSize) += ( (ort.segment(m, bSize) / (matH.coeff(m,m-1) * ort.coeff(m) ) )
+ * (ort.segment(m, bSize).transpose() * m_eivec.block(m, m, bSize, bSize)).lazy());
+ }
+ }
+}
+
+// Complex scalar division.
+template<typename Scalar>
+std::complex<Scalar> cdiv(Scalar xr, Scalar xi, Scalar yr, Scalar yi)
+{
+ Scalar r,d;
+ if (ei_abs(yr) > ei_abs(yi))
+ {
+ r = yi/yr;
+ d = yr + r*yi;
+ return std::complex<Scalar>((xr + r*xi)/d, (xi - r*xr)/d);
+ }
+ else
+ {
+ r = yr/yi;
+ d = yi + r*yr;
+ return std::complex<Scalar>((r*xr + xi)/d, (r*xi - xr)/d);
+ }
+}
+
+
+// Nonsymmetric reduction from Hessenberg to real Schur form.
+template<typename MatrixType>
+void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
+{
+ // This is derived from the Algol procedure hqr2,
+ // by Martin and Wilkinson, Handbook for Auto. Comp.,
+ // Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ // Initialize
+ int nn = m_eivec.cols();
+ int n = nn-1;
+ int low = 0;
+ int high = nn-1;
+ Scalar eps = ei_pow(Scalar(2),ei_is_same_type<Scalar,float>::ret ? Scalar(-23) : Scalar(-52));
+ Scalar exshift = 0.0;
+ Scalar p=0,q=0,r=0,s=0,z=0,t,w,x,y;
+
+ // Store roots isolated by balanc and compute matrix norm
+ // FIXME to be efficient the following would requires a triangular reduxion code
+ // Scalar norm = matH.upper().cwise().abs().sum() + matH.corner(BottomLeft,n,n).diagonal().cwise().abs().sum();
+ Scalar norm = 0.0;
+ for (int j = 0; j < nn; ++j)
+ {
+ // FIXME what's the purpose of the following since the condition is always false
+ if ((j < low) || (j > high))
+ {
+ m_eivalues.coeffRef(j) = Complex(matH.coeff(j,j), 0.0);
+ }
+ norm += matH.row(j).segment(std::max(j-1,0), nn-std::max(j-1,0)).cwise().abs().sum();
+ }
+
+ // Outer loop over eigenvalue index
+ int iter = 0;
+ while (n >= low)
+ {
+ // Look for single small sub-diagonal element
+ int l = n;
+ while (l > low)
+ {
+ s = ei_abs(matH.coeff(l-1,l-1)) + ei_abs(matH.coeff(l,l));
+ if (s == 0.0)
+ s = norm;
+ if (ei_abs(matH.coeff(l,l-1)) < eps * s)
+ break;
+ l--;
+ }
+
+ // Check for convergence
+ // One root found
+ if (l == n)
+ {
+ matH.coeffRef(n,n) = matH.coeff(n,n) + exshift;
+ m_eivalues.coeffRef(n) = Complex(matH.coeff(n,n), 0.0);
+ n--;
+ iter = 0;
+ }
+ else if (l == n-1) // Two roots found
+ {
+ w = matH.coeff(n,n-1) * matH.coeff(n-1,n);
+ p = (matH.coeff(n-1,n-1) - matH.coeff(n,n)) * Scalar(0.5);
+ q = p * p + w;
+ z = ei_sqrt(ei_abs(q));
+ matH.coeffRef(n,n) = matH.coeff(n,n) + exshift;
+ matH.coeffRef(n-1,n-1) = matH.coeff(n-1,n-1) + exshift;
+ x = matH.coeff(n,n);
+
+ // Scalar pair
+ if (q >= 0)
+ {
+ if (p >= 0)
+ z = p + z;
+ else
+ z = p - z;
+
+ m_eivalues.coeffRef(n-1) = Complex(x + z, 0.0);
+ m_eivalues.coeffRef(n) = Complex(z!=0.0 ? x - w / z : m_eivalues.coeff(n-1).real(), 0.0);
+
+ x = matH.coeff(n,n-1);
+ s = ei_abs(x) + ei_abs(z);
+ p = x / s;
+ q = z / s;
+ r = ei_sqrt(p * p+q * q);
+ p = p / r;
+ q = q / r;
+
+ // Row modification
+ for (int j = n-1; j < nn; ++j)
+ {
+ z = matH.coeff(n-1,j);
+ matH.coeffRef(n-1,j) = q * z + p * matH.coeff(n,j);
+ matH.coeffRef(n,j) = q * matH.coeff(n,j) - p * z;
+ }
+
+ // Column modification
+ for (int i = 0; i <= n; ++i)
+ {
+ z = matH.coeff(i,n-1);
+ matH.coeffRef(i,n-1) = q * z + p * matH.coeff(i,n);
+ matH.coeffRef(i,n) = q * matH.coeff(i,n) - p * z;
+ }
+
+ // Accumulate transformations
+ for (int i = low; i <= high; ++i)
+ {
+ z = m_eivec.coeff(i,n-1);
+ m_eivec.coeffRef(i,n-1) = q * z + p * m_eivec.coeff(i,n);
+ m_eivec.coeffRef(i,n) = q * m_eivec.coeff(i,n) - p * z;
+ }
+ }
+ else // Complex pair
+ {
+ m_eivalues.coeffRef(n-1) = Complex(x + p, z);
+ m_eivalues.coeffRef(n) = Complex(x + p, -z);
+ }
+ n = n - 2;
+ iter = 0;
+ }
+ else // No convergence yet
+ {
+ // Form shift
+ x = matH.coeff(n,n);
+ y = 0.0;
+ w = 0.0;
+ if (l < n)
+ {
+ y = matH.coeff(n-1,n-1);
+ w = matH.coeff(n,n-1) * matH.coeff(n-1,n);
+ }
+
+ // Wilkinson's original ad hoc shift
+ if (iter == 10)
+ {
+ exshift += x;
+ for (int i = low; i <= n; ++i)
+ matH.coeffRef(i,i) -= x;
+ s = ei_abs(matH.coeff(n,n-1)) + ei_abs(matH.coeff(n-1,n-2));
+ x = y = Scalar(0.75) * s;
+ w = Scalar(-0.4375) * s * s;
+ }
+
+ // MATLAB's new ad hoc shift
+ if (iter == 30)
+ {
+ s = Scalar((y - x) / 2.0);
+ s = s * s + w;
+ if (s > 0)
+ {
+ s = ei_sqrt(s);
+ if (y < x)
+ s = -s;
+ s = Scalar(x - w / ((y - x) / 2.0 + s));
+ for (int i = low; i <= n; ++i)
+ matH.coeffRef(i,i) -= s;
+ exshift += s;
+ x = y = w = Scalar(0.964);
+ }
+ }
+
+ iter = iter + 1; // (Could check iteration count here.)
+
+ // Look for two consecutive small sub-diagonal elements
+ int m = n-2;
+ while (m >= l)
+ {
+ z = matH.coeff(m,m);
+ r = x - z;
+ s = y - z;
+ p = (r * s - w) / matH.coeff(m+1,m) + matH.coeff(m,m+1);
+ q = matH.coeff(m+1,m+1) - z - r - s;
+ r = matH.coeff(m+2,m+1);
+ s = ei_abs(p) + ei_abs(q) + ei_abs(r);
+ p = p / s;
+ q = q / s;
+ r = r / s;
+ if (m == l) {
+ break;
+ }
+ if (ei_abs(matH.coeff(m,m-1)) * (ei_abs(q) + ei_abs(r)) <
+ eps * (ei_abs(p) * (ei_abs(matH.coeff(m-1,m-1)) + ei_abs(z) +
+ ei_abs(matH.coeff(m+1,m+1)))))
+ {
+ break;
+ }
+ m--;
+ }
+
+ for (int i = m+2; i <= n; ++i)
+ {
+ matH.coeffRef(i,i-2) = 0.0;
+ if (i > m+2)
+ matH.coeffRef(i,i-3) = 0.0;
+ }
+
+ // Double QR step involving rows l:n and columns m:n
+ for (int k = m; k <= n-1; ++k)
+ {
+ int notlast = (k != n-1);
+ if (k != m) {
+ p = matH.coeff(k,k-1);
+ q = matH.coeff(k+1,k-1);
+ r = notlast ? matH.coeff(k+2,k-1) : Scalar(0);
+ x = ei_abs(p) + ei_abs(q) + ei_abs(r);
+ if (x != 0.0)
+ {
+ p = p / x;
+ q = q / x;
+ r = r / x;
+ }
+ }
+
+ if (x == 0.0)
+ break;
+
+ s = ei_sqrt(p * p + q * q + r * r);
+
+ if (p < 0)
+ s = -s;
+
+ if (s != 0)
+ {
+ if (k != m)
+ matH.coeffRef(k,k-1) = -s * x;
+ else if (l != m)
+ matH.coeffRef(k,k-1) = -matH.coeff(k,k-1);
+
+ p = p + s;
+ x = p / s;
+ y = q / s;
+ z = r / s;
+ q = q / p;
+ r = r / p;
+
+ // Row modification
+ for (int j = k; j < nn; ++j)
+ {
+ p = matH.coeff(k,j) + q * matH.coeff(k+1,j);
+ if (notlast)
+ {
+ p = p + r * matH.coeff(k+2,j);
+ matH.coeffRef(k+2,j) = matH.coeff(k+2,j) - p * z;
+ }
+ matH.coeffRef(k,j) = matH.coeff(k,j) - p * x;
+ matH.coeffRef(k+1,j) = matH.coeff(k+1,j) - p * y;
+ }
+
+ // Column modification
+ for (int i = 0; i <= std::min(n,k+3); ++i)
+ {
+ p = x * matH.coeff(i,k) + y * matH.coeff(i,k+1);
+ if (notlast)
+ {
+ p = p + z * matH.coeff(i,k+2);
+ matH.coeffRef(i,k+2) = matH.coeff(i,k+2) - p * r;
+ }
+ matH.coeffRef(i,k) = matH.coeff(i,k) - p;
+ matH.coeffRef(i,k+1) = matH.coeff(i,k+1) - p * q;
+ }
+
+ // Accumulate transformations
+ for (int i = low; i <= high; ++i)
+ {
+ p = x * m_eivec.coeff(i,k) + y * m_eivec.coeff(i,k+1);
+ if (notlast)
+ {
+ p = p + z * m_eivec.coeff(i,k+2);
+ m_eivec.coeffRef(i,k+2) = m_eivec.coeff(i,k+2) - p * r;
+ }
+ m_eivec.coeffRef(i,k) = m_eivec.coeff(i,k) - p;
+ m_eivec.coeffRef(i,k+1) = m_eivec.coeff(i,k+1) - p * q;
+ }
+ } // (s != 0)
+ } // k loop
+ } // check convergence
+ } // while (n >= low)
+
+ // Backsubstitute to find vectors of upper triangular form
+ if (norm == 0.0)
+ {
+ return;
+ }
+
+ for (n = nn-1; n >= 0; n--)
+ {
+ p = m_eivalues.coeff(n).real();
+ q = m_eivalues.coeff(n).imag();
+
+ // Scalar vector
+ if (q == 0)
+ {
+ int l = n;
+ matH.coeffRef(n,n) = 1.0;
+ for (int i = n-1; i >= 0; i--)
+ {
+ w = matH.coeff(i,i) - p;
+ r = (matH.row(i).segment(l,n-l+1) * matH.col(n).segment(l, n-l+1))(0,0);
+
+ if (m_eivalues.coeff(i).imag() < 0.0)
+ {
+ z = w;
+ s = r;
+ }
+ else
+ {
+ l = i;
+ if (m_eivalues.coeff(i).imag() == 0.0)
+ {
+ if (w != 0.0)
+ matH.coeffRef(i,n) = -r / w;
+ else
+ matH.coeffRef(i,n) = -r / (eps * norm);
+ }
+ else // Solve real equations
+ {
+ x = matH.coeff(i,i+1);
+ y = matH.coeff(i+1,i);
+ q = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
+ t = (x * s - z * r) / q;
+ matH.coeffRef(i,n) = t;
+ if (ei_abs(x) > ei_abs(z))
+ matH.coeffRef(i+1,n) = (-r - w * t) / x;
+ else
+ matH.coeffRef(i+1,n) = (-s - y * t) / z;
+ }
+
+ // Overflow control
+ t = ei_abs(matH.coeff(i,n));
+ if ((eps * t) * t > 1)
+ matH.col(n).end(nn-i) /= t;
+ }
+ }
+ }
+ else if (q < 0) // Complex vector
+ {
+ std::complex<Scalar> cc;
+ int l = n-1;
+
+ // Last vector component imaginary so matrix is triangular
+ if (ei_abs(matH.coeff(n,n-1)) > ei_abs(matH.coeff(n-1,n)))
+ {
+ matH.coeffRef(n-1,n-1) = q / matH.coeff(n,n-1);
+ matH.coeffRef(n-1,n) = -(matH.coeff(n,n) - p) / matH.coeff(n,n-1);
+ }
+ else
+ {
+ cc = cdiv<Scalar>(0.0,-matH.coeff(n-1,n),matH.coeff(n-1,n-1)-p,q);
+ matH.coeffRef(n-1,n-1) = ei_real(cc);
+ matH.coeffRef(n-1,n) = ei_imag(cc);
+ }
+ matH.coeffRef(n,n-1) = 0.0;
+ matH.coeffRef(n,n) = 1.0;
+ for (int i = n-2; i >= 0; i--)
+ {
+ Scalar ra,sa,vr,vi;
+ ra = (matH.block(i,l, 1, n-l+1) * matH.block(l,n-1, n-l+1, 1)).lazy()(0,0);
+ sa = (matH.block(i,l, 1, n-l+1) * matH.block(l,n, n-l+1, 1)).lazy()(0,0);
+ w = matH.coeff(i,i) - p;
+
+ if (m_eivalues.coeff(i).imag() < 0.0)
+ {
+ z = w;
+ r = ra;
+ s = sa;
+ }
+ else
+ {
+ l = i;
+ if (m_eivalues.coeff(i).imag() == 0)
+ {
+ cc = cdiv(-ra,-sa,w,q);
+ matH.coeffRef(i,n-1) = ei_real(cc);
+ matH.coeffRef(i,n) = ei_imag(cc);
+ }
+ else
+ {
+ // Solve complex equations
+ x = matH.coeff(i,i+1);
+ y = matH.coeff(i+1,i);
+ vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
+ vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
+ if ((vr == 0.0) && (vi == 0.0))
+ vr = eps * norm * (ei_abs(w) + ei_abs(q) + ei_abs(x) + ei_abs(y) + ei_abs(z));
+
+ cc= cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
+ matH.coeffRef(i,n-1) = ei_real(cc);
+ matH.coeffRef(i,n) = ei_imag(cc);
+ if (ei_abs(x) > (ei_abs(z) + ei_abs(q)))
+ {
+ matH.coeffRef(i+1,n-1) = (-ra - w * matH.coeff(i,n-1) + q * matH.coeff(i,n)) / x;
+ matH.coeffRef(i+1,n) = (-sa - w * matH.coeff(i,n) - q * matH.coeff(i,n-1)) / x;
+ }
+ else
+ {
+ cc = cdiv(-r-y*matH.coeff(i,n-1),-s-y*matH.coeff(i,n),z,q);
+ matH.coeffRef(i+1,n-1) = ei_real(cc);
+ matH.coeffRef(i+1,n) = ei_imag(cc);
+ }
+ }
+
+ // Overflow control
+ t = std::max(ei_abs(matH.coeff(i,n-1)),ei_abs(matH.coeff(i,n)));
+ if ((eps * t) * t > 1)
+ matH.block(i, n-1, nn-i, 2) /= t;
+
+ }
+ }
+ }
+ }
+
+ // Vectors of isolated roots
+ for (int i = 0; i < nn; ++i)
+ {
+ // FIXME again what's the purpose of this test ?
+ // in this algo low==0 and high==nn-1 !!
+ if (i < low || i > high)
+ {
+ m_eivec.row(i).end(nn-i) = matH.row(i).end(nn-i);
+ }
+ }
+
+ // Back transformation to get eigenvectors of original matrix
+ int bRows = high-low+1;
+ for (int j = nn-1; j >= low; j--)
+ {
+ int bSize = std::min(j,high)-low+1;
+ m_eivec.col(j).segment(low, bRows) = (m_eivec.block(low, low, bRows, bSize) * matH.col(j).segment(low, bSize));
+ }
+}
+
+#endif // EIGEN_EIGENSOLVER_H
diff --git a/extern/Eigen2/Eigen/src/QR/HessenbergDecomposition.h b/extern/Eigen2/Eigen/src/QR/HessenbergDecomposition.h
new file mode 100644
index 00000000000..6d0ff794ec2
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/QR/HessenbergDecomposition.h
@@ -0,0 +1,250 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_HESSENBERGDECOMPOSITION_H
+#define EIGEN_HESSENBERGDECOMPOSITION_H
+
+/** \ingroup QR_Module
+ * \nonstableyet
+ *
+ * \class HessenbergDecomposition
+ *
+ * \brief Reduces a squared matrix to an Hessemberg form
+ *
+ * \param MatrixType the type of the matrix of which we are computing the Hessenberg decomposition
+ *
+ * This class performs an Hessenberg decomposition of a matrix \f$ A \f$ such that:
+ * \f$ A = Q H Q^* \f$ where \f$ Q \f$ is unitary and \f$ H \f$ a Hessenberg matrix.
+ *
+ * \sa class Tridiagonalization, class Qr
+ */
+template<typename _MatrixType> class HessenbergDecomposition
+{
+ public:
+
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ enum {
+ Size = MatrixType::RowsAtCompileTime,
+ SizeMinusOne = MatrixType::RowsAtCompileTime==Dynamic
+ ? Dynamic
+ : MatrixType::RowsAtCompileTime-1
+ };
+
+ typedef Matrix<Scalar, SizeMinusOne, 1> CoeffVectorType;
+ typedef Matrix<RealScalar, Size, 1> DiagonalType;
+ typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
+
+ typedef typename NestByValue<DiagonalCoeffs<MatrixType> >::RealReturnType DiagonalReturnType;
+
+ typedef typename NestByValue<DiagonalCoeffs<
+ NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> > > >::RealReturnType SubDiagonalReturnType;
+
+ /** This constructor initializes a HessenbergDecomposition object for
+ * further use with HessenbergDecomposition::compute()
+ */
+ HessenbergDecomposition(int size = Size==Dynamic ? 2 : Size)
+ : m_matrix(size,size), m_hCoeffs(size-1)
+ {}
+
+ HessenbergDecomposition(const MatrixType& matrix)
+ : m_matrix(matrix),
+ m_hCoeffs(matrix.cols()-1)
+ {
+ _compute(m_matrix, m_hCoeffs);
+ }
+
+ /** Computes or re-compute the Hessenberg decomposition for the matrix \a matrix.
+ *
+ * This method allows to re-use the allocated data.
+ */
+ void compute(const MatrixType& matrix)
+ {
+ m_matrix = matrix;
+ m_hCoeffs.resize(matrix.rows()-1,1);
+ _compute(m_matrix, m_hCoeffs);
+ }
+
+ /** \returns the householder coefficients allowing to
+ * reconstruct the matrix Q from the packed data.
+ *
+ * \sa packedMatrix()
+ */
+ CoeffVectorType householderCoefficients(void) const { return m_hCoeffs; }
+
+ /** \returns the internal result of the decomposition.
+ *
+ * The returned matrix contains the following information:
+ * - the upper part and lower sub-diagonal represent the Hessenberg matrix H
+ * - the rest of the lower part contains the Householder vectors that, combined with
+ * Householder coefficients returned by householderCoefficients(),
+ * allows to reconstruct the matrix Q as follow:
+ * Q = H_{N-1} ... H_1 H_0
+ * where the matrices H are the Householder transformation:
+ * H_i = (I - h_i * v_i * v_i')
+ * where h_i == householderCoefficients()[i] and v_i is a Householder vector:
+ * v_i = [ 0, ..., 0, 1, M(i+2,i), ..., M(N-1,i) ]
+ *
+ * See LAPACK for further details on this packed storage.
+ */
+ const MatrixType& packedMatrix(void) const { return m_matrix; }
+
+ MatrixType matrixQ(void) const;
+ MatrixType matrixH(void) const;
+
+ private:
+
+ static void _compute(MatrixType& matA, CoeffVectorType& hCoeffs);
+
+ protected:
+ MatrixType m_matrix;
+ CoeffVectorType m_hCoeffs;
+};
+
+#ifndef EIGEN_HIDE_HEAVY_CODE
+
+/** \internal
+ * Performs a tridiagonal decomposition of \a matA in place.
+ *
+ * \param matA the input selfadjoint matrix
+ * \param hCoeffs returned Householder coefficients
+ *
+ * The result is written in the lower triangular part of \a matA.
+ *
+ * Implemented from Golub's "Matrix Computations", algorithm 8.3.1.
+ *
+ * \sa packedMatrix()
+ */
+template<typename MatrixType>
+void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs)
+{
+ assert(matA.rows()==matA.cols());
+ int n = matA.rows();
+ for (int i = 0; i<n-2; ++i)
+ {
+ // let's consider the vector v = i-th column starting at position i+1
+
+ // start of the householder transformation
+ // squared norm of the vector v skipping the first element
+ RealScalar v1norm2 = matA.col(i).end(n-(i+2)).squaredNorm();
+
+ if (ei_isMuchSmallerThan(v1norm2,static_cast<Scalar>(1)))
+ {
+ hCoeffs.coeffRef(i) = 0.;
+ }
+ else
+ {
+ Scalar v0 = matA.col(i).coeff(i+1);
+ RealScalar beta = ei_sqrt(ei_abs2(v0)+v1norm2);
+ if (ei_real(v0)>=0.)
+ beta = -beta;
+ matA.col(i).end(n-(i+2)) *= (Scalar(1)/(v0-beta));
+ matA.col(i).coeffRef(i+1) = beta;
+ Scalar h = (beta - v0) / beta;
+ // end of the householder transformation
+
+ // Apply similarity transformation to remaining columns,
+ // i.e., A = H' A H where H = I - h v v' and v = matA.col(i).end(n-i-1)
+ matA.col(i).coeffRef(i+1) = 1;
+
+ // first let's do A = H A
+ matA.corner(BottomRight,n-i-1,n-i-1) -= ((ei_conj(h) * matA.col(i).end(n-i-1)) *
+ (matA.col(i).end(n-i-1).adjoint() * matA.corner(BottomRight,n-i-1,n-i-1))).lazy();
+
+ // now let's do A = A H
+ matA.corner(BottomRight,n,n-i-1) -= ((matA.corner(BottomRight,n,n-i-1) * matA.col(i).end(n-i-1))
+ * (h * matA.col(i).end(n-i-1).adjoint())).lazy();
+
+ matA.col(i).coeffRef(i+1) = beta;
+ hCoeffs.coeffRef(i) = h;
+ }
+ }
+ if (NumTraits<Scalar>::IsComplex)
+ {
+ // Householder transformation on the remaining single scalar
+ int i = n-2;
+ Scalar v0 = matA.coeff(i+1,i);
+
+ RealScalar beta = ei_sqrt(ei_abs2(v0));
+ if (ei_real(v0)>=0.)
+ beta = -beta;
+ Scalar h = (beta - v0) / beta;
+ hCoeffs.coeffRef(i) = h;
+
+ // A = H* A
+ matA.corner(BottomRight,n-i-1,n-i) -= ei_conj(h) * matA.corner(BottomRight,n-i-1,n-i);
+
+ // A = A H
+ matA.col(n-1) -= h * matA.col(n-1);
+ }
+ else
+ {
+ hCoeffs.coeffRef(n-2) = 0;
+ }
+}
+
+/** reconstructs and returns the matrix Q */
+template<typename MatrixType>
+typename HessenbergDecomposition<MatrixType>::MatrixType
+HessenbergDecomposition<MatrixType>::matrixQ(void) const
+{
+ int n = m_matrix.rows();
+ MatrixType matQ = MatrixType::Identity(n,n);
+ for (int i = n-2; i>=0; i--)
+ {
+ Scalar tmp = m_matrix.coeff(i+1,i);
+ m_matrix.const_cast_derived().coeffRef(i+1,i) = 1;
+
+ matQ.corner(BottomRight,n-i-1,n-i-1) -=
+ ((m_hCoeffs.coeff(i) * m_matrix.col(i).end(n-i-1)) *
+ (m_matrix.col(i).end(n-i-1).adjoint() * matQ.corner(BottomRight,n-i-1,n-i-1)).lazy()).lazy();
+
+ m_matrix.const_cast_derived().coeffRef(i+1,i) = tmp;
+ }
+ return matQ;
+}
+
+#endif // EIGEN_HIDE_HEAVY_CODE
+
+/** constructs and returns the matrix H.
+ * Note that the matrix H is equivalent to the upper part of the packed matrix
+ * (including the lower sub-diagonal). Therefore, it might be often sufficient
+ * to directly use the packed matrix instead of creating a new one.
+ */
+template<typename MatrixType>
+typename HessenbergDecomposition<MatrixType>::MatrixType
+HessenbergDecomposition<MatrixType>::matrixH(void) const
+{
+ // FIXME should this function (and other similar) rather take a matrix as argument
+ // and fill it (to avoid temporaries)
+ int n = m_matrix.rows();
+ MatrixType matH = m_matrix;
+ if (n>2)
+ matH.corner(BottomLeft,n-2, n-2).template part<LowerTriangular>().setZero();
+ return matH;
+}
+
+#endif // EIGEN_HESSENBERGDECOMPOSITION_H
diff --git a/extern/Eigen2/Eigen/src/QR/QR.h b/extern/Eigen2/Eigen/src/QR/QR.h
new file mode 100644
index 00000000000..90751dd428d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/QR/QR.h
@@ -0,0 +1,334 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_QR_H
+#define EIGEN_QR_H
+
+/** \ingroup QR_Module
+ * \nonstableyet
+ *
+ * \class QR
+ *
+ * \brief QR decomposition of a matrix
+ *
+ * \param MatrixType the type of the matrix of which we are computing the QR decomposition
+ *
+ * This class performs a QR decomposition using Householder transformations. The result is
+ * stored in a compact way compatible with LAPACK.
+ *
+ * \sa MatrixBase::qr()
+ */
+template<typename MatrixType> class QR
+{
+ public:
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef Block<MatrixType, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> MatrixRBlockType;
+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> MatrixTypeR;
+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
+
+ /**
+ * \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via QR::compute(const MatrixType&).
+ */
+ QR() : m_qr(), m_hCoeffs(), m_isInitialized(false) {}
+
+ QR(const MatrixType& matrix)
+ : m_qr(matrix.rows(), matrix.cols()),
+ m_hCoeffs(matrix.cols()),
+ m_isInitialized(false)
+ {
+ compute(matrix);
+ }
+
+ /** \deprecated use isInjective()
+ * \returns whether or not the matrix is of full rank
+ *
+ * \note Since the rank is computed only once, i.e. the first time it is needed, this
+ * method almost does not perform any further computation.
+ */
+ EIGEN_DEPRECATED bool isFullRank() const
+ {
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ return rank() == m_qr.cols();
+ }
+
+ /** \returns the rank of the matrix of which *this is the QR decomposition.
+ *
+ * \note Since the rank is computed only once, i.e. the first time it is needed, this
+ * method almost does not perform any further computation.
+ */
+ int rank() const;
+
+ /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
+ *
+ * \note Since the rank is computed only once, i.e. the first time it is needed, this
+ * method almost does not perform any further computation.
+ */
+ inline int dimensionOfKernel() const
+ {
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ return m_qr.cols() - rank();
+ }
+
+ /** \returns true if the matrix of which *this is the QR decomposition represents an injective
+ * linear map, i.e. has trivial kernel; false otherwise.
+ *
+ * \note Since the rank is computed only once, i.e. the first time it is needed, this
+ * method almost does not perform any further computation.
+ */
+ inline bool isInjective() const
+ {
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ return rank() == m_qr.cols();
+ }
+
+ /** \returns true if the matrix of which *this is the QR decomposition represents a surjective
+ * linear map; false otherwise.
+ *
+ * \note Since the rank is computed only once, i.e. the first time it is needed, this
+ * method almost does not perform any further computation.
+ */
+ inline bool isSurjective() const
+ {
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ return rank() == m_qr.rows();
+ }
+
+ /** \returns true if the matrix of which *this is the QR decomposition is invertible.
+ *
+ * \note Since the rank is computed only once, i.e. the first time it is needed, this
+ * method almost does not perform any further computation.
+ */
+ inline bool isInvertible() const
+ {
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ return isInjective() && isSurjective();
+ }
+
+ /** \returns a read-only expression of the matrix R of the actual the QR decomposition */
+ const Part<NestByValue<MatrixRBlockType>, UpperTriangular>
+ matrixR(void) const
+ {
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ int cols = m_qr.cols();
+ return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<UpperTriangular>();
+ }
+
+ /** This method finds a solution x to the equation Ax=b, where A is the matrix of which
+ * *this is the QR decomposition, if any exists.
+ *
+ * \param b the right-hand-side of the equation to solve.
+ *
+ * \param result a pointer to the vector/matrix in which to store the solution, if any exists.
+ * Resized if necessary, so that result->rows()==A.cols() and result->cols()==b.cols().
+ * If no solution exists, *result is left with undefined coefficients.
+ *
+ * \returns true if any solution exists, false if no solution exists.
+ *
+ * \note If there exist more than one solution, this method will arbitrarily choose one.
+ * If you need a complete analysis of the space of solutions, take the one solution obtained
+ * by this method and add to it elements of the kernel, as determined by kernel().
+ *
+ * \note The case where b is a matrix is not yet implemented. Also, this
+ * code is space inefficient.
+ *
+ * Example: \include QR_solve.cpp
+ * Output: \verbinclude QR_solve.out
+ *
+ * \sa MatrixBase::solveTriangular(), kernel(), computeKernel(), inverse(), computeInverse()
+ */
+ template<typename OtherDerived, typename ResultType>
+ bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const;
+
+ MatrixType matrixQ(void) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+ MatrixType m_qr;
+ VectorType m_hCoeffs;
+ mutable int m_rank;
+ mutable bool m_rankIsUptodate;
+ bool m_isInitialized;
+};
+
+/** \returns the rank of the matrix of which *this is the QR decomposition. */
+template<typename MatrixType>
+int QR<MatrixType>::rank() const
+{
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ if (!m_rankIsUptodate)
+ {
+ RealScalar maxCoeff = m_qr.diagonal().cwise().abs().maxCoeff();
+ int n = m_qr.cols();
+ m_rank = 0;
+ while(m_rank<n && !ei_isMuchSmallerThan(m_qr.diagonal().coeff(m_rank), maxCoeff))
+ ++m_rank;
+ m_rankIsUptodate = true;
+ }
+ return m_rank;
+}
+
+#ifndef EIGEN_HIDE_HEAVY_CODE
+
+template<typename MatrixType>
+void QR<MatrixType>::compute(const MatrixType& matrix)
+{
+ m_rankIsUptodate = false;
+ m_qr = matrix;
+ m_hCoeffs.resize(matrix.cols());
+
+ int rows = matrix.rows();
+ int cols = matrix.cols();
+ RealScalar eps2 = precision<RealScalar>()*precision<RealScalar>();
+
+ for (int k = 0; k < cols; ++k)
+ {
+ int remainingSize = rows-k;
+
+ RealScalar beta;
+ Scalar v0 = m_qr.col(k).coeff(k);
+
+ if (remainingSize==1)
+ {
+ if (NumTraits<Scalar>::IsComplex)
+ {
+ // Householder transformation on the remaining single scalar
+ beta = ei_abs(v0);
+ if (ei_real(v0)>0)
+ beta = -beta;
+ m_qr.coeffRef(k,k) = beta;
+ m_hCoeffs.coeffRef(k) = (beta - v0) / beta;
+ }
+ else
+ {
+ m_hCoeffs.coeffRef(k) = 0;
+ }
+ }
+ else if ((beta=m_qr.col(k).end(remainingSize-1).squaredNorm())>eps2)
+ // FIXME what about ei_imag(v0) ??
+ {
+ // form k-th Householder vector
+ beta = ei_sqrt(ei_abs2(v0)+beta);
+ if (ei_real(v0)>=0.)
+ beta = -beta;
+ m_qr.col(k).end(remainingSize-1) /= v0-beta;
+ m_qr.coeffRef(k,k) = beta;
+ Scalar h = m_hCoeffs.coeffRef(k) = (beta - v0) / beta;
+
+ // apply the Householder transformation (I - h v v') to remaining columns, i.e.,
+ // R <- (I - h v v') * R where v = [1,m_qr(k+1,k), m_qr(k+2,k), ...]
+ int remainingCols = cols - k -1;
+ if (remainingCols>0)
+ {
+ m_qr.coeffRef(k,k) = Scalar(1);
+ m_qr.corner(BottomRight, remainingSize, remainingCols) -= ei_conj(h) * m_qr.col(k).end(remainingSize)
+ * (m_qr.col(k).end(remainingSize).adjoint() * m_qr.corner(BottomRight, remainingSize, remainingCols));
+ m_qr.coeffRef(k,k) = beta;
+ }
+ }
+ else
+ {
+ m_hCoeffs.coeffRef(k) = 0;
+ }
+ }
+ m_isInitialized = true;
+}
+
+template<typename MatrixType>
+template<typename OtherDerived, typename ResultType>
+bool QR<MatrixType>::solve(
+ const MatrixBase<OtherDerived>& b,
+ ResultType *result
+) const
+{
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ const int rows = m_qr.rows();
+ ei_assert(b.rows() == rows);
+ result->resize(rows, b.cols());
+
+ // TODO(keir): There is almost certainly a faster way to multiply by
+ // Q^T without explicitly forming matrixQ(). Investigate.
+ *result = matrixQ().transpose()*b;
+
+ if(!isSurjective())
+ {
+ // is result is in the image of R ?
+ RealScalar biggest_in_res = result->corner(TopLeft, m_rank, result->cols()).cwise().abs().maxCoeff();
+ for(int col = 0; col < result->cols(); ++col)
+ for(int row = m_rank; row < result->rows(); ++row)
+ if(!ei_isMuchSmallerThan(result->coeff(row,col), biggest_in_res))
+ return false;
+ }
+ m_qr.corner(TopLeft, m_rank, m_rank)
+ .template marked<UpperTriangular>()
+ .solveTriangularInPlace(result->corner(TopLeft, m_rank, result->cols()));
+
+ return true;
+}
+
+/** \returns the matrix Q */
+template<typename MatrixType>
+MatrixType QR<MatrixType>::matrixQ() const
+{
+ ei_assert(m_isInitialized && "QR is not initialized.");
+ // compute the product Q_0 Q_1 ... Q_n-1,
+ // where Q_k is the k-th Householder transformation I - h_k v_k v_k'
+ // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...]
+ int rows = m_qr.rows();
+ int cols = m_qr.cols();
+ MatrixType res = MatrixType::Identity(rows, cols);
+ for (int k = cols-1; k >= 0; k--)
+ {
+ // to make easier the computation of the transformation, let's temporarily
+ // overwrite m_qr(k,k) such that the end of m_qr.col(k) is exactly our Householder vector.
+ Scalar beta = m_qr.coeff(k,k);
+ m_qr.const_cast_derived().coeffRef(k,k) = 1;
+ int endLength = rows-k;
+ res.corner(BottomRight,endLength, cols-k) -= ((m_hCoeffs.coeff(k) * m_qr.col(k).end(endLength))
+ * (m_qr.col(k).end(endLength).adjoint() * res.corner(BottomRight,endLength, cols-k)).lazy()).lazy();
+ m_qr.const_cast_derived().coeffRef(k,k) = beta;
+ }
+ return res;
+}
+
+#endif // EIGEN_HIDE_HEAVY_CODE
+
+/** \return the QR decomposition of \c *this.
+ *
+ * \sa class QR
+ */
+template<typename Derived>
+const QR<typename MatrixBase<Derived>::PlainMatrixType>
+MatrixBase<Derived>::qr() const
+{
+ return QR<PlainMatrixType>(eval());
+}
+
+
+#endif // EIGEN_QR_H
diff --git a/extern/Eigen2/Eigen/src/QR/QrInstantiations.cpp b/extern/Eigen2/Eigen/src/QR/QrInstantiations.cpp
new file mode 100644
index 00000000000..dacb05d3d1f
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/QR/QrInstantiations.cpp
@@ -0,0 +1,43 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_EXTERN_INSTANTIATIONS
+#define EIGEN_EXTERN_INSTANTIATIONS
+#endif
+#include "../../Core"
+#undef EIGEN_EXTERN_INSTANTIATIONS
+
+#include "../../QR"
+
+namespace Eigen
+{
+
+template static void ei_tridiagonal_qr_step(float* , float* , int, int, float* , int);
+template static void ei_tridiagonal_qr_step(double* , double* , int, int, double* , int);
+template static void ei_tridiagonal_qr_step(float* , float* , int, int, std::complex<float>* , int);
+template static void ei_tridiagonal_qr_step(double* , double* , int, int, std::complex<double>* , int);
+
+EIGEN_QR_MODULE_INSTANTIATE();
+
+}
diff --git a/extern/Eigen2/Eigen/src/QR/SelfAdjointEigenSolver.h b/extern/Eigen2/Eigen/src/QR/SelfAdjointEigenSolver.h
new file mode 100644
index 00000000000..70984efab9d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/QR/SelfAdjointEigenSolver.h
@@ -0,0 +1,402 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SELFADJOINTEIGENSOLVER_H
+#define EIGEN_SELFADJOINTEIGENSOLVER_H
+
+/** \qr_module \ingroup QR_Module
+ * \nonstableyet
+ *
+ * \class SelfAdjointEigenSolver
+ *
+ * \brief Eigen values/vectors solver for selfadjoint matrix
+ *
+ * \param MatrixType the type of the matrix of which we are computing the eigen decomposition
+ *
+ * \note MatrixType must be an actual Matrix type, it can't be an expression type.
+ *
+ * \sa MatrixBase::eigenvalues(), class EigenSolver
+ */
+template<typename _MatrixType> class SelfAdjointEigenSolver
+{
+ public:
+
+ enum {Size = _MatrixType::RowsAtCompileTime };
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef std::complex<RealScalar> Complex;
+ typedef Matrix<RealScalar, MatrixType::ColsAtCompileTime, 1> RealVectorType;
+ typedef Matrix<RealScalar, Dynamic, 1> RealVectorTypeX;
+ typedef Tridiagonalization<MatrixType> TridiagonalizationType;
+
+ SelfAdjointEigenSolver()
+ : m_eivec(int(Size), int(Size)),
+ m_eivalues(int(Size))
+ {
+ ei_assert(Size!=Dynamic);
+ }
+
+ SelfAdjointEigenSolver(int size)
+ : m_eivec(size, size),
+ m_eivalues(size)
+ {}
+
+ /** Constructors computing the eigenvalues of the selfadjoint matrix \a matrix,
+ * as well as the eigenvectors if \a computeEigenvectors is true.
+ *
+ * \sa compute(MatrixType,bool), SelfAdjointEigenSolver(MatrixType,MatrixType,bool)
+ */
+ SelfAdjointEigenSolver(const MatrixType& matrix, bool computeEigenvectors = true)
+ : m_eivec(matrix.rows(), matrix.cols()),
+ m_eivalues(matrix.cols())
+ {
+ compute(matrix, computeEigenvectors);
+ }
+
+ /** Constructors computing the eigenvalues of the generalized eigen problem
+ * \f$ Ax = lambda B x \f$ with \a matA the selfadjoint matrix \f$ A \f$
+ * and \a matB the positive definite matrix \f$ B \f$ . The eigenvectors
+ * are computed if \a computeEigenvectors is true.
+ *
+ * \sa compute(MatrixType,MatrixType,bool), SelfAdjointEigenSolver(MatrixType,bool)
+ */
+ SelfAdjointEigenSolver(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors = true)
+ : m_eivec(matA.rows(), matA.cols()),
+ m_eivalues(matA.cols())
+ {
+ compute(matA, matB, computeEigenvectors);
+ }
+
+ void compute(const MatrixType& matrix, bool computeEigenvectors = true);
+
+ void compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors = true);
+
+ /** \returns the computed eigen vectors as a matrix of column vectors */
+ MatrixType eigenvectors(void) const
+ {
+ #ifndef NDEBUG
+ ei_assert(m_eigenvectorsOk);
+ #endif
+ return m_eivec;
+ }
+
+ /** \returns the computed eigen values */
+ RealVectorType eigenvalues(void) const { return m_eivalues; }
+
+ /** \returns the positive square root of the matrix
+ *
+ * \note the matrix itself must be positive in order for this to make sense.
+ */
+ MatrixType operatorSqrt() const
+ {
+ return m_eivec * m_eivalues.cwise().sqrt().asDiagonal() * m_eivec.adjoint();
+ }
+
+ /** \returns the positive inverse square root of the matrix
+ *
+ * \note the matrix itself must be positive definite in order for this to make sense.
+ */
+ MatrixType operatorInverseSqrt() const
+ {
+ return m_eivec * m_eivalues.cwise().inverse().cwise().sqrt().asDiagonal() * m_eivec.adjoint();
+ }
+
+
+ protected:
+ MatrixType m_eivec;
+ RealVectorType m_eivalues;
+ #ifndef NDEBUG
+ bool m_eigenvectorsOk;
+ #endif
+};
+
+#ifndef EIGEN_HIDE_HEAVY_CODE
+
+// from Golub's "Matrix Computations", algorithm 5.1.3
+template<typename Scalar>
+static void ei_givens_rotation(Scalar a, Scalar b, Scalar& c, Scalar& s)
+{
+ if (b==0)
+ {
+ c = 1; s = 0;
+ }
+ else if (ei_abs(b)>ei_abs(a))
+ {
+ Scalar t = -a/b;
+ s = Scalar(1)/ei_sqrt(1+t*t);
+ c = s * t;
+ }
+ else
+ {
+ Scalar t = -b/a;
+ c = Scalar(1)/ei_sqrt(1+t*t);
+ s = c * t;
+ }
+}
+
+/** \internal
+ *
+ * \qr_module
+ *
+ * Performs a QR step on a tridiagonal symmetric matrix represented as a
+ * pair of two vectors \a diag and \a subdiag.
+ *
+ * \param matA the input selfadjoint matrix
+ * \param hCoeffs returned Householder coefficients
+ *
+ * For compilation efficiency reasons, this procedure does not use eigen expression
+ * for its arguments.
+ *
+ * Implemented from Golub's "Matrix Computations", algorithm 8.3.2:
+ * "implicit symmetric QR step with Wilkinson shift"
+ */
+template<typename RealScalar, typename Scalar>
+static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, int start, int end, Scalar* matrixQ, int n);
+
+/** Computes the eigenvalues of the selfadjoint matrix \a matrix,
+ * as well as the eigenvectors if \a computeEigenvectors is true.
+ *
+ * \sa SelfAdjointEigenSolver(MatrixType,bool), compute(MatrixType,MatrixType,bool)
+ */
+template<typename MatrixType>
+void SelfAdjointEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
+{
+ #ifndef NDEBUG
+ m_eigenvectorsOk = computeEigenvectors;
+ #endif
+ assert(matrix.cols() == matrix.rows());
+ int n = matrix.cols();
+ m_eivalues.resize(n,1);
+
+ if(n==1)
+ {
+ m_eivalues.coeffRef(0,0) = ei_real(matrix.coeff(0,0));
+ m_eivec.setOnes();
+ return;
+ }
+
+ m_eivec = matrix;
+
+ // FIXME, should tridiag be a local variable of this function or an attribute of SelfAdjointEigenSolver ?
+ // the latter avoids multiple memory allocation when the same SelfAdjointEigenSolver is used multiple times...
+ // (same for diag and subdiag)
+ RealVectorType& diag = m_eivalues;
+ typename TridiagonalizationType::SubDiagonalType subdiag(n-1);
+ TridiagonalizationType::decomposeInPlace(m_eivec, diag, subdiag, computeEigenvectors);
+
+ int end = n-1;
+ int start = 0;
+ while (end>0)
+ {
+ for (int i = start; i<end; ++i)
+ if (ei_isMuchSmallerThan(ei_abs(subdiag[i]),(ei_abs(diag[i])+ei_abs(diag[i+1]))))
+ subdiag[i] = 0;
+
+ // find the largest unreduced block
+ while (end>0 && subdiag[end-1]==0)
+ end--;
+ if (end<=0)
+ break;
+ start = end - 1;
+ while (start>0 && subdiag[start-1]!=0)
+ start--;
+
+ ei_tridiagonal_qr_step(diag.data(), subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
+ }
+
+ // Sort eigenvalues and corresponding vectors.
+ // TODO make the sort optional ?
+ // TODO use a better sort algorithm !!
+ for (int i = 0; i < n-1; ++i)
+ {
+ int k;
+ m_eivalues.segment(i,n-i).minCoeff(&k);
+ if (k > 0)
+ {
+ std::swap(m_eivalues[i], m_eivalues[k+i]);
+ m_eivec.col(i).swap(m_eivec.col(k+i));
+ }
+ }
+}
+
+/** Computes the eigenvalues of the generalized eigen problem
+ * \f$ Ax = lambda B x \f$ with \a matA the selfadjoint matrix \f$ A \f$
+ * and \a matB the positive definite matrix \f$ B \f$ . The eigenvectors
+ * are computed if \a computeEigenvectors is true.
+ *
+ * \sa SelfAdjointEigenSolver(MatrixType,MatrixType,bool), compute(MatrixType,bool)
+ */
+template<typename MatrixType>
+void SelfAdjointEigenSolver<MatrixType>::
+compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors)
+{
+ ei_assert(matA.cols()==matA.rows() && matB.rows()==matA.rows() && matB.cols()==matB.rows());
+
+ // Compute the cholesky decomposition of matB = L L'
+ LLT<MatrixType> cholB(matB);
+
+ // compute C = inv(L) A inv(L')
+ MatrixType matC = matA;
+ cholB.matrixL().solveTriangularInPlace(matC);
+ // FIXME since we currently do not support A * inv(L'), let's do (inv(L) A')' :
+ matC = matC.adjoint().eval();
+ cholB.matrixL().template marked<LowerTriangular>().solveTriangularInPlace(matC);
+ matC = matC.adjoint().eval();
+ // this version works too:
+// matC = matC.transpose();
+// cholB.matrixL().conjugate().template marked<LowerTriangular>().solveTriangularInPlace(matC);
+// matC = matC.transpose();
+ // FIXME: this should work: (currently it only does for small matrices)
+// Transpose<MatrixType> trMatC(matC);
+// cholB.matrixL().conjugate().eval().template marked<LowerTriangular>().solveTriangularInPlace(trMatC);
+
+ compute(matC, computeEigenvectors);
+
+ if (computeEigenvectors)
+ {
+ // transform back the eigen vectors: evecs = inv(U) * evecs
+ cholB.matrixL().adjoint().template marked<UpperTriangular>().solveTriangularInPlace(m_eivec);
+ for (int i=0; i<m_eivec.cols(); ++i)
+ m_eivec.col(i) = m_eivec.col(i).normalized();
+ }
+}
+
+#endif // EIGEN_HIDE_HEAVY_CODE
+
+/** \qr_module
+ *
+ * \returns a vector listing the eigenvalues of this matrix.
+ */
+template<typename Derived>
+inline Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1>
+MatrixBase<Derived>::eigenvalues() const
+{
+ ei_assert(Flags&SelfAdjointBit);
+ return SelfAdjointEigenSolver<typename Derived::PlainMatrixType>(eval(),false).eigenvalues();
+}
+
+template<typename Derived, bool IsSelfAdjoint>
+struct ei_operatorNorm_selector
+{
+ static inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
+ operatorNorm(const MatrixBase<Derived>& m)
+ {
+ // FIXME if it is really guaranteed that the eigenvalues are already sorted,
+ // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
+ return m.eigenvalues().cwise().abs().maxCoeff();
+ }
+};
+
+template<typename Derived> struct ei_operatorNorm_selector<Derived, false>
+{
+ static inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
+ operatorNorm(const MatrixBase<Derived>& m)
+ {
+ typename Derived::PlainMatrixType m_eval(m);
+ // FIXME if it is really guaranteed that the eigenvalues are already sorted,
+ // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
+ return ei_sqrt(
+ (m_eval*m_eval.adjoint())
+ .template marked<SelfAdjoint>()
+ .eigenvalues()
+ .maxCoeff()
+ );
+ }
+};
+
+/** \qr_module
+ *
+ * \returns the matrix norm of this matrix.
+ */
+template<typename Derived>
+inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
+MatrixBase<Derived>::operatorNorm() const
+{
+ return ei_operatorNorm_selector<Derived, Flags&SelfAdjointBit>
+ ::operatorNorm(derived());
+}
+
+#ifndef EIGEN_EXTERN_INSTANTIATIONS
+template<typename RealScalar, typename Scalar>
+static void ei_tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, int start, int end, Scalar* matrixQ, int n)
+{
+ RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
+ RealScalar e2 = ei_abs2(subdiag[end-1]);
+ RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * ei_sqrt(td*td + e2));
+ RealScalar x = diag[start] - mu;
+ RealScalar z = subdiag[start];
+
+ for (int k = start; k < end; ++k)
+ {
+ RealScalar c, s;
+ ei_givens_rotation(x, z, c, s);
+
+ // do T = G' T G
+ RealScalar sdk = s * diag[k] + c * subdiag[k];
+ RealScalar dkp1 = s * subdiag[k] + c * diag[k+1];
+
+ diag[k] = c * (c * diag[k] - s * subdiag[k]) - s * (c * subdiag[k] - s * diag[k+1]);
+ diag[k+1] = s * sdk + c * dkp1;
+ subdiag[k] = c * sdk - s * dkp1;
+
+ if (k > start)
+ subdiag[k - 1] = c * subdiag[k-1] - s * z;
+
+ x = subdiag[k];
+
+ if (k < end - 1)
+ {
+ z = -s * subdiag[k+1];
+ subdiag[k + 1] = c * subdiag[k+1];
+ }
+
+ // apply the givens rotation to the unit matrix Q = Q * G
+ // G only modifies the two columns k and k+1
+ if (matrixQ)
+ {
+ #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
+ #else
+ int kn = k*n;
+ int kn1 = (k+1)*n;
+ #endif
+ // let's do the product manually to avoid the need of temporaries...
+ for (int i=0; i<n; ++i)
+ {
+ #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
+ Scalar matrixQ_i_k = matrixQ[i*n+k];
+ matrixQ[i*n+k] = c * matrixQ_i_k - s * matrixQ[i*n+k+1];
+ matrixQ[i*n+k+1] = s * matrixQ_i_k + c * matrixQ[i*n+k+1];
+ #else
+ Scalar matrixQ_i_k = matrixQ[i+kn];
+ matrixQ[i+kn] = c * matrixQ_i_k - s * matrixQ[i+kn1];
+ matrixQ[i+kn1] = s * matrixQ_i_k + c * matrixQ[i+kn1];
+ #endif
+ }
+ }
+ }
+}
+#endif
+
+#endif // EIGEN_SELFADJOINTEIGENSOLVER_H
diff --git a/extern/Eigen2/Eigen/src/QR/Tridiagonalization.h b/extern/Eigen2/Eigen/src/QR/Tridiagonalization.h
new file mode 100644
index 00000000000..9ea39be717c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/QR/Tridiagonalization.h
@@ -0,0 +1,431 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_TRIDIAGONALIZATION_H
+#define EIGEN_TRIDIAGONALIZATION_H
+
+/** \ingroup QR_Module
+ * \nonstableyet
+ *
+ * \class Tridiagonalization
+ *
+ * \brief Trigiagonal decomposition of a selfadjoint matrix
+ *
+ * \param MatrixType the type of the matrix of which we are performing the tridiagonalization
+ *
+ * This class performs a tridiagonal decomposition of a selfadjoint matrix \f$ A \f$ such that:
+ * \f$ A = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real symmetric tridiagonal matrix.
+ *
+ * \sa MatrixBase::tridiagonalize()
+ */
+template<typename _MatrixType> class Tridiagonalization
+{
+ public:
+
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+
+ enum {
+ Size = MatrixType::RowsAtCompileTime,
+ SizeMinusOne = MatrixType::RowsAtCompileTime==Dynamic
+ ? Dynamic
+ : MatrixType::RowsAtCompileTime-1,
+ PacketSize = ei_packet_traits<Scalar>::size
+ };
+
+ typedef Matrix<Scalar, SizeMinusOne, 1> CoeffVectorType;
+ typedef Matrix<RealScalar, Size, 1> DiagonalType;
+ typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
+
+ typedef typename NestByValue<DiagonalCoeffs<MatrixType> >::RealReturnType DiagonalReturnType;
+
+ typedef typename NestByValue<DiagonalCoeffs<
+ NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> > > >::RealReturnType SubDiagonalReturnType;
+
+ /** This constructor initializes a Tridiagonalization object for
+ * further use with Tridiagonalization::compute()
+ */
+ Tridiagonalization(int size = Size==Dynamic ? 2 : Size)
+ : m_matrix(size,size), m_hCoeffs(size-1)
+ {}
+
+ Tridiagonalization(const MatrixType& matrix)
+ : m_matrix(matrix),
+ m_hCoeffs(matrix.cols()-1)
+ {
+ _compute(m_matrix, m_hCoeffs);
+ }
+
+ /** Computes or re-compute the tridiagonalization for the matrix \a matrix.
+ *
+ * This method allows to re-use the allocated data.
+ */
+ void compute(const MatrixType& matrix)
+ {
+ m_matrix = matrix;
+ m_hCoeffs.resize(matrix.rows()-1, 1);
+ _compute(m_matrix, m_hCoeffs);
+ }
+
+ /** \returns the householder coefficients allowing to
+ * reconstruct the matrix Q from the packed data.
+ *
+ * \sa packedMatrix()
+ */
+ inline CoeffVectorType householderCoefficients(void) const { return m_hCoeffs; }
+
+ /** \returns the internal result of the decomposition.
+ *
+ * The returned matrix contains the following information:
+ * - the strict upper part is equal to the input matrix A
+ * - the diagonal and lower sub-diagonal represent the tridiagonal symmetric matrix (real).
+ * - the rest of the lower part contains the Householder vectors that, combined with
+ * Householder coefficients returned by householderCoefficients(),
+ * allows to reconstruct the matrix Q as follow:
+ * Q = H_{N-1} ... H_1 H_0
+ * where the matrices H are the Householder transformations:
+ * H_i = (I - h_i * v_i * v_i')
+ * where h_i == householderCoefficients()[i] and v_i is a Householder vector:
+ * v_i = [ 0, ..., 0, 1, M(i+2,i), ..., M(N-1,i) ]
+ *
+ * See LAPACK for further details on this packed storage.
+ */
+ inline const MatrixType& packedMatrix(void) const { return m_matrix; }
+
+ MatrixType matrixQ(void) const;
+ MatrixType matrixT(void) const;
+ const DiagonalReturnType diagonal(void) const;
+ const SubDiagonalReturnType subDiagonal(void) const;
+
+ static void decomposeInPlace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ = true);
+
+ private:
+
+ static void _compute(MatrixType& matA, CoeffVectorType& hCoeffs);
+
+ static void _decomposeInPlace3x3(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ = true);
+
+ protected:
+ MatrixType m_matrix;
+ CoeffVectorType m_hCoeffs;
+};
+
+/** \returns an expression of the diagonal vector */
+template<typename MatrixType>
+const typename Tridiagonalization<MatrixType>::DiagonalReturnType
+Tridiagonalization<MatrixType>::diagonal(void) const
+{
+ return m_matrix.diagonal().nestByValue().real();
+}
+
+/** \returns an expression of the sub-diagonal vector */
+template<typename MatrixType>
+const typename Tridiagonalization<MatrixType>::SubDiagonalReturnType
+Tridiagonalization<MatrixType>::subDiagonal(void) const
+{
+ int n = m_matrix.rows();
+ return Block<MatrixType,SizeMinusOne,SizeMinusOne>(m_matrix, 1, 0, n-1,n-1)
+ .nestByValue().diagonal().nestByValue().real();
+}
+
+/** constructs and returns the tridiagonal matrix T.
+ * Note that the matrix T is equivalent to the diagonal and sub-diagonal of the packed matrix.
+ * Therefore, it might be often sufficient to directly use the packed matrix, or the vector
+ * expressions returned by diagonal() and subDiagonal() instead of creating a new matrix.
+ */
+template<typename MatrixType>
+typename Tridiagonalization<MatrixType>::MatrixType
+Tridiagonalization<MatrixType>::matrixT(void) const
+{
+ // FIXME should this function (and other similar ones) rather take a matrix as argument
+ // and fill it ? (to avoid temporaries)
+ int n = m_matrix.rows();
+ MatrixType matT = m_matrix;
+ matT.corner(TopRight,n-1, n-1).diagonal() = subDiagonal().template cast<Scalar>().conjugate();
+ if (n>2)
+ {
+ matT.corner(TopRight,n-2, n-2).template part<UpperTriangular>().setZero();
+ matT.corner(BottomLeft,n-2, n-2).template part<LowerTriangular>().setZero();
+ }
+ return matT;
+}
+
+#ifndef EIGEN_HIDE_HEAVY_CODE
+
+/** \internal
+ * Performs a tridiagonal decomposition of \a matA in place.
+ *
+ * \param matA the input selfadjoint matrix
+ * \param hCoeffs returned Householder coefficients
+ *
+ * The result is written in the lower triangular part of \a matA.
+ *
+ * Implemented from Golub's "Matrix Computations", algorithm 8.3.1.
+ *
+ * \sa packedMatrix()
+ */
+template<typename MatrixType>
+void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs)
+{
+ assert(matA.rows()==matA.cols());
+ int n = matA.rows();
+// std::cerr << matA << "\n\n";
+ for (int i = 0; i<n-2; ++i)
+ {
+ // let's consider the vector v = i-th column starting at position i+1
+
+ // start of the householder transformation
+ // squared norm of the vector v skipping the first element
+ RealScalar v1norm2 = matA.col(i).end(n-(i+2)).squaredNorm();
+
+ // FIXME comparing against 1
+ if (ei_isMuchSmallerThan(v1norm2,static_cast<Scalar>(1)))
+ {
+ hCoeffs.coeffRef(i) = 0.;
+ }
+ else
+ {
+ Scalar v0 = matA.col(i).coeff(i+1);
+ RealScalar beta = ei_sqrt(ei_abs2(v0)+v1norm2);
+ if (ei_real(v0)>=0.)
+ beta = -beta;
+ matA.col(i).end(n-(i+2)) *= (Scalar(1)/(v0-beta));
+ matA.col(i).coeffRef(i+1) = beta;
+ Scalar h = (beta - v0) / beta;
+ // end of the householder transformation
+
+ // Apply similarity transformation to remaining columns,
+ // i.e., A = H' A H where H = I - h v v' and v = matA.col(i).end(n-i-1)
+
+ matA.col(i).coeffRef(i+1) = 1;
+
+ /* This is the initial algorithm which minimize operation counts and maximize
+ * the use of Eigen's expression. Unfortunately, the first matrix-vector product
+ * using Part<LowerTriangular|Selfadjoint> is very very slow */
+ #ifdef EIGEN_NEVER_DEFINED
+ // matrix - vector product
+ hCoeffs.end(n-i-1) = (matA.corner(BottomRight,n-i-1,n-i-1).template part<LowerTriangular|SelfAdjoint>()
+ * (h * matA.col(i).end(n-i-1))).lazy();
+ // simple axpy
+ hCoeffs.end(n-i-1) += (h * Scalar(-0.5) * matA.col(i).end(n-i-1).dot(hCoeffs.end(n-i-1)))
+ * matA.col(i).end(n-i-1);
+ // rank-2 update
+ //Block<MatrixType,Dynamic,1> B(matA,i+1,i,n-i-1,1);
+ matA.corner(BottomRight,n-i-1,n-i-1).template part<LowerTriangular>() -=
+ (matA.col(i).end(n-i-1) * hCoeffs.end(n-i-1).adjoint()).lazy()
+ + (hCoeffs.end(n-i-1) * matA.col(i).end(n-i-1).adjoint()).lazy();
+ #endif
+ /* end initial algorithm */
+
+ /* If we still want to minimize operation count (i.e., perform operation on the lower part only)
+ * then we could provide the following algorithm for selfadjoint - vector product. However, a full
+ * matrix-vector product is still faster (at least for dynamic size, and not too small, did not check
+ * small matrices). The algo performs block matrix-vector and transposed matrix vector products. */
+ #ifdef EIGEN_NEVER_DEFINED
+ int n4 = (std::max(0,n-4)/4)*4;
+ hCoeffs.end(n-i-1).setZero();
+ for (int b=i+1; b<n4; b+=4)
+ {
+ // the ?x4 part:
+ hCoeffs.end(b-4) +=
+ Block<MatrixType,Dynamic,4>(matA,b+4,b,n-b-4,4) * matA.template block<4,1>(b,i);
+ // the respective transposed part:
+ Block<CoeffVectorType,4,1>(hCoeffs, b, 0, 4,1) +=
+ Block<MatrixType,Dynamic,4>(matA,b+4,b,n-b-4,4).adjoint() * Block<MatrixType,Dynamic,1>(matA,b+4,i,n-b-4,1);
+ // the 4x4 block diagonal:
+ Block<CoeffVectorType,4,1>(hCoeffs, b, 0, 4,1) +=
+ (Block<MatrixType,4,4>(matA,b,b,4,4).template part<LowerTriangular|SelfAdjoint>()
+ * (h * Block<MatrixType,4,1>(matA,b,i,4,1))).lazy();
+ }
+ #endif
+ // todo: handle the remaining part
+ /* end optimized selfadjoint - vector product */
+
+ /* Another interesting note: the above rank-2 update is much slower than the following hand written loop.
+ * After an analyze of the ASM, it seems GCC (4.2) generate poor code because of the Block. Moreover,
+ * if we remove the specialization of Block for Matrix then it is even worse, much worse ! */
+ #ifdef EIGEN_NEVER_DEFINED
+ for (int j1=i+1; j1<n; ++j1)
+ for (int i1=j1; i1<n; ++i1)
+ matA.coeffRef(i1,j1) -= matA.coeff(i1,i)*ei_conj(hCoeffs.coeff(j1-1))
+ + hCoeffs.coeff(i1-1)*ei_conj(matA.coeff(j1,i));
+ #endif
+ /* end hand writen partial rank-2 update */
+
+ /* The current fastest implementation: the full matrix is used, no "optimization" to use/compute
+ * only half of the matrix. Custom vectorization of the inner col -= alpha X + beta Y such that access
+ * to col are always aligned. Once we support that in Assign, then the algorithm could be rewriten as
+ * a single compact expression. This code is therefore a good benchmark when will do that. */
+
+ // let's use the end of hCoeffs to store temporary values:
+ hCoeffs.end(n-i-1) = (matA.corner(BottomRight,n-i-1,n-i-1) * (h * matA.col(i).end(n-i-1))).lazy();
+ // FIXME in the above expr a temporary is created because of the scalar multiple by h
+
+ hCoeffs.end(n-i-1) += (h * Scalar(-0.5) * matA.col(i).end(n-i-1).dot(hCoeffs.end(n-i-1)))
+ * matA.col(i).end(n-i-1);
+
+ const Scalar* EIGEN_RESTRICT pb = &matA.coeffRef(0,i);
+ const Scalar* EIGEN_RESTRICT pa = (&hCoeffs.coeffRef(0)) - 1;
+ for (int j1=i+1; j1<n; ++j1)
+ {
+ int starti = i+1;
+ int alignedEnd = starti;
+ if (PacketSize>1)
+ {
+ int alignedStart = (starti) + ei_alignmentOffset(&matA.coeffRef(starti,j1), n-starti);
+ alignedEnd = alignedStart + ((n-alignedStart)/PacketSize)*PacketSize;
+
+ for (int i1=starti; i1<alignedStart; ++i1)
+ matA.coeffRef(i1,j1) -= matA.coeff(i1,i)*ei_conj(hCoeffs.coeff(j1-1))
+ + hCoeffs.coeff(i1-1)*ei_conj(matA.coeff(j1,i));
+
+ Packet tmp0 = ei_pset1(hCoeffs.coeff(j1-1));
+ Packet tmp1 = ei_pset1(matA.coeff(j1,i));
+ Scalar* pc = &matA.coeffRef(0,j1);
+ for (int i1=alignedStart ; i1<alignedEnd; i1+=PacketSize)
+ ei_pstore(pc+i1,ei_psub(ei_pload(pc+i1),
+ ei_padd(ei_pmul(tmp0, ei_ploadu(pb+i1)),
+ ei_pmul(tmp1, ei_ploadu(pa+i1)))));
+ }
+ for (int i1=alignedEnd; i1<n; ++i1)
+ matA.coeffRef(i1,j1) -= matA.coeff(i1,i)*ei_conj(hCoeffs.coeff(j1-1))
+ + hCoeffs.coeff(i1-1)*ei_conj(matA.coeff(j1,i));
+ }
+ /* end optimized implementation */
+
+ // note: at that point matA(i+1,i+1) is the (i+1)-th element of the final diagonal
+ // note: the sequence of the beta values leads to the subdiagonal entries
+ matA.col(i).coeffRef(i+1) = beta;
+
+ hCoeffs.coeffRef(i) = h;
+ }
+ }
+ if (NumTraits<Scalar>::IsComplex)
+ {
+ // Householder transformation on the remaining single scalar
+ int i = n-2;
+ Scalar v0 = matA.col(i).coeff(i+1);
+ RealScalar beta = ei_abs(v0);
+ if (ei_real(v0)>=0.)
+ beta = -beta;
+ matA.col(i).coeffRef(i+1) = beta;
+ if(ei_isMuchSmallerThan(beta, Scalar(1))) hCoeffs.coeffRef(i) = Scalar(0);
+ else hCoeffs.coeffRef(i) = (beta - v0) / beta;
+ }
+ else
+ {
+ hCoeffs.coeffRef(n-2) = 0;
+ }
+}
+
+/** reconstructs and returns the matrix Q */
+template<typename MatrixType>
+typename Tridiagonalization<MatrixType>::MatrixType
+Tridiagonalization<MatrixType>::matrixQ(void) const
+{
+ int n = m_matrix.rows();
+ MatrixType matQ = MatrixType::Identity(n,n);
+ for (int i = n-2; i>=0; i--)
+ {
+ Scalar tmp = m_matrix.coeff(i+1,i);
+ m_matrix.const_cast_derived().coeffRef(i+1,i) = 1;
+
+ matQ.corner(BottomRight,n-i-1,n-i-1) -=
+ ((m_hCoeffs.coeff(i) * m_matrix.col(i).end(n-i-1)) *
+ (m_matrix.col(i).end(n-i-1).adjoint() * matQ.corner(BottomRight,n-i-1,n-i-1)).lazy()).lazy();
+
+ m_matrix.const_cast_derived().coeffRef(i+1,i) = tmp;
+ }
+ return matQ;
+}
+
+/** Performs a full decomposition in place */
+template<typename MatrixType>
+void Tridiagonalization<MatrixType>::decomposeInPlace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
+{
+ int n = mat.rows();
+ ei_assert(mat.cols()==n && diag.size()==n && subdiag.size()==n-1);
+ if (n==3 && (!NumTraits<Scalar>::IsComplex) )
+ {
+ _decomposeInPlace3x3(mat, diag, subdiag, extractQ);
+ }
+ else
+ {
+ Tridiagonalization tridiag(mat);
+ diag = tridiag.diagonal();
+ subdiag = tridiag.subDiagonal();
+ if (extractQ)
+ mat = tridiag.matrixQ();
+ }
+}
+
+/** \internal
+ * Optimized path for 3x3 matrices.
+ * Especially useful for plane fitting.
+ */
+template<typename MatrixType>
+void Tridiagonalization<MatrixType>::_decomposeInPlace3x3(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
+{
+ diag[0] = ei_real(mat(0,0));
+ RealScalar v1norm2 = ei_abs2(mat(0,2));
+ if (ei_isMuchSmallerThan(v1norm2, RealScalar(1)))
+ {
+ diag[1] = ei_real(mat(1,1));
+ diag[2] = ei_real(mat(2,2));
+ subdiag[0] = ei_real(mat(0,1));
+ subdiag[1] = ei_real(mat(1,2));
+ if (extractQ)
+ mat.setIdentity();
+ }
+ else
+ {
+ RealScalar beta = ei_sqrt(ei_abs2(mat(0,1))+v1norm2);
+ RealScalar invBeta = RealScalar(1)/beta;
+ Scalar m01 = mat(0,1) * invBeta;
+ Scalar m02 = mat(0,2) * invBeta;
+ Scalar q = RealScalar(2)*m01*mat(1,2) + m02*(mat(2,2) - mat(1,1));
+ diag[1] = ei_real(mat(1,1) + m02*q);
+ diag[2] = ei_real(mat(2,2) - m02*q);
+ subdiag[0] = beta;
+ subdiag[1] = ei_real(mat(1,2) - m01 * q);
+ if (extractQ)
+ {
+ mat(0,0) = 1;
+ mat(0,1) = 0;
+ mat(0,2) = 0;
+ mat(1,0) = 0;
+ mat(1,1) = m01;
+ mat(1,2) = m02;
+ mat(2,0) = 0;
+ mat(2,1) = m02;
+ mat(2,2) = -m01;
+ }
+ }
+}
+
+#endif // EIGEN_HIDE_HEAVY_CODE
+
+#endif // EIGEN_TRIDIAGONALIZATION_H
diff --git a/extern/Eigen2/Eigen/src/SVD/SVD.h b/extern/Eigen2/Eigen/src/SVD/SVD.h
new file mode 100644
index 00000000000..0a52acf3d5b
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/SVD/SVD.h
@@ -0,0 +1,645 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SVD_H
+#define EIGEN_SVD_H
+
+/** \ingroup SVD_Module
+ * \nonstableyet
+ *
+ * \class SVD
+ *
+ * \brief Standard SVD decomposition of a matrix and associated features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition
+ *
+ * This class performs a standard SVD decomposition of a real matrix A of size \c M x \c N
+ * with \c M \>= \c N.
+ *
+ *
+ * \sa MatrixBase::SVD()
+ */
+template<typename MatrixType> class SVD
+{
+ private:
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+
+ enum {
+ PacketSize = ei_packet_traits<Scalar>::size,
+ AlignmentMask = int(PacketSize)-1,
+ MinSize = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime)
+ };
+
+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVector;
+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> RowVector;
+
+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MinSize> MatrixUType;
+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> MatrixVType;
+ typedef Matrix<Scalar, MinSize, 1> SingularValuesType;
+
+ public:
+
+ SVD(const MatrixType& matrix)
+ : m_matU(matrix.rows(), std::min(matrix.rows(), matrix.cols())),
+ m_matV(matrix.cols(),matrix.cols()),
+ m_sigma(std::min(matrix.rows(),matrix.cols()))
+ {
+ compute(matrix);
+ }
+
+ template<typename OtherDerived, typename ResultType>
+ bool solve(const MatrixBase<OtherDerived> &b, ResultType* result) const;
+
+ const MatrixUType& matrixU() const { return m_matU; }
+ const SingularValuesType& singularValues() const { return m_sigma; }
+ const MatrixVType& matrixV() const { return m_matV; }
+
+ void compute(const MatrixType& matrix);
+ SVD& sort();
+
+ template<typename UnitaryType, typename PositiveType>
+ void computeUnitaryPositive(UnitaryType *unitary, PositiveType *positive) const;
+ template<typename PositiveType, typename UnitaryType>
+ void computePositiveUnitary(PositiveType *positive, UnitaryType *unitary) const;
+ template<typename RotationType, typename ScalingType>
+ void computeRotationScaling(RotationType *unitary, ScalingType *positive) const;
+ template<typename ScalingType, typename RotationType>
+ void computeScalingRotation(ScalingType *positive, RotationType *unitary) const;
+
+ protected:
+ /** \internal */
+ MatrixUType m_matU;
+ /** \internal */
+ MatrixVType m_matV;
+ /** \internal */
+ SingularValuesType m_sigma;
+};
+
+/** Computes / recomputes the SVD decomposition A = U S V^* of \a matrix
+ *
+ * \note this code has been adapted from JAMA (public domain)
+ */
+template<typename MatrixType>
+void SVD<MatrixType>::compute(const MatrixType& matrix)
+{
+ const int m = matrix.rows();
+ const int n = matrix.cols();
+ const int nu = std::min(m,n);
+
+ m_matU.resize(m, nu);
+ m_matU.setZero();
+ m_sigma.resize(std::min(m,n));
+ m_matV.resize(n,n);
+
+ RowVector e(n);
+ ColVector work(m);
+ MatrixType matA(matrix);
+ const bool wantu = true;
+ const bool wantv = true;
+ int i=0, j=0, k=0;
+
+ // Reduce A to bidiagonal form, storing the diagonal elements
+ // in s and the super-diagonal elements in e.
+ int nct = std::min(m-1,n);
+ int nrt = std::max(0,std::min(n-2,m));
+ for (k = 0; k < std::max(nct,nrt); ++k)
+ {
+ if (k < nct)
+ {
+ // Compute the transformation for the k-th column and
+ // place the k-th diagonal in m_sigma[k].
+ m_sigma[k] = matA.col(k).end(m-k).norm();
+ if (m_sigma[k] != 0.0) // FIXME
+ {
+ if (matA(k,k) < 0.0)
+ m_sigma[k] = -m_sigma[k];
+ matA.col(k).end(m-k) /= m_sigma[k];
+ matA(k,k) += 1.0;
+ }
+ m_sigma[k] = -m_sigma[k];
+ }
+
+ for (j = k+1; j < n; ++j)
+ {
+ if ((k < nct) && (m_sigma[k] != 0.0))
+ {
+ // Apply the transformation.
+ Scalar t = matA.col(k).end(m-k).dot(matA.col(j).end(m-k)); // FIXME dot product or cwise prod + .sum() ??
+ t = -t/matA(k,k);
+ matA.col(j).end(m-k) += t * matA.col(k).end(m-k);
+ }
+
+ // Place the k-th row of A into e for the
+ // subsequent calculation of the row transformation.
+ e[j] = matA(k,j);
+ }
+
+ // Place the transformation in U for subsequent back multiplication.
+ if (wantu & (k < nct))
+ m_matU.col(k).end(m-k) = matA.col(k).end(m-k);
+
+ if (k < nrt)
+ {
+ // Compute the k-th row transformation and place the
+ // k-th super-diagonal in e[k].
+ e[k] = e.end(n-k-1).norm();
+ if (e[k] != 0.0)
+ {
+ if (e[k+1] < 0.0)
+ e[k] = -e[k];
+ e.end(n-k-1) /= e[k];
+ e[k+1] += 1.0;
+ }
+ e[k] = -e[k];
+ if ((k+1 < m) & (e[k] != 0.0))
+ {
+ // Apply the transformation.
+ work.end(m-k-1) = matA.corner(BottomRight,m-k-1,n-k-1) * e.end(n-k-1);
+ for (j = k+1; j < n; ++j)
+ matA.col(j).end(m-k-1) += (-e[j]/e[k+1]) * work.end(m-k-1);
+ }
+
+ // Place the transformation in V for subsequent back multiplication.
+ if (wantv)
+ m_matV.col(k).end(n-k-1) = e.end(n-k-1);
+ }
+ }
+
+
+ // Set up the final bidiagonal matrix or order p.
+ int p = std::min(n,m+1);
+ if (nct < n)
+ m_sigma[nct] = matA(nct,nct);
+ if (m < p)
+ m_sigma[p-1] = 0.0;
+ if (nrt+1 < p)
+ e[nrt] = matA(nrt,p-1);
+ e[p-1] = 0.0;
+
+ // If required, generate U.
+ if (wantu)
+ {
+ for (j = nct; j < nu; ++j)
+ {
+ m_matU.col(j).setZero();
+ m_matU(j,j) = 1.0;
+ }
+ for (k = nct-1; k >= 0; k--)
+ {
+ if (m_sigma[k] != 0.0)
+ {
+ for (j = k+1; j < nu; ++j)
+ {
+ Scalar t = m_matU.col(k).end(m-k).dot(m_matU.col(j).end(m-k)); // FIXME is it really a dot product we want ?
+ t = -t/m_matU(k,k);
+ m_matU.col(j).end(m-k) += t * m_matU.col(k).end(m-k);
+ }
+ m_matU.col(k).end(m-k) = - m_matU.col(k).end(m-k);
+ m_matU(k,k) = Scalar(1) + m_matU(k,k);
+ if (k-1>0)
+ m_matU.col(k).start(k-1).setZero();
+ }
+ else
+ {
+ m_matU.col(k).setZero();
+ m_matU(k,k) = 1.0;
+ }
+ }
+ }
+
+ // If required, generate V.
+ if (wantv)
+ {
+ for (k = n-1; k >= 0; k--)
+ {
+ if ((k < nrt) & (e[k] != 0.0))
+ {
+ for (j = k+1; j < nu; ++j)
+ {
+ Scalar t = m_matV.col(k).end(n-k-1).dot(m_matV.col(j).end(n-k-1)); // FIXME is it really a dot product we want ?
+ t = -t/m_matV(k+1,k);
+ m_matV.col(j).end(n-k-1) += t * m_matV.col(k).end(n-k-1);
+ }
+ }
+ m_matV.col(k).setZero();
+ m_matV(k,k) = 1.0;
+ }
+ }
+
+ // Main iteration loop for the singular values.
+ int pp = p-1;
+ int iter = 0;
+ Scalar eps = ei_pow(Scalar(2),ei_is_same_type<Scalar,float>::ret ? Scalar(-23) : Scalar(-52));
+ while (p > 0)
+ {
+ int k=0;
+ int kase=0;
+
+ // Here is where a test for too many iterations would go.
+
+ // This section of the program inspects for
+ // negligible elements in the s and e arrays. On
+ // completion the variables kase and k are set as follows.
+
+ // kase = 1 if s(p) and e[k-1] are negligible and k<p
+ // kase = 2 if s(k) is negligible and k<p
+ // kase = 3 if e[k-1] is negligible, k<p, and
+ // s(k), ..., s(p) are not negligible (qr step).
+ // kase = 4 if e(p-1) is negligible (convergence).
+
+ for (k = p-2; k >= -1; --k)
+ {
+ if (k == -1)
+ break;
+ if (ei_abs(e[k]) <= eps*(ei_abs(m_sigma[k]) + ei_abs(m_sigma[k+1])))
+ {
+ e[k] = 0.0;
+ break;
+ }
+ }
+ if (k == p-2)
+ {
+ kase = 4;
+ }
+ else
+ {
+ int ks;
+ for (ks = p-1; ks >= k; --ks)
+ {
+ if (ks == k)
+ break;
+ Scalar t = (ks != p ? ei_abs(e[ks]) : Scalar(0)) + (ks != k+1 ? ei_abs(e[ks-1]) : Scalar(0));
+ if (ei_abs(m_sigma[ks]) <= eps*t)
+ {
+ m_sigma[ks] = 0.0;
+ break;
+ }
+ }
+ if (ks == k)
+ {
+ kase = 3;
+ }
+ else if (ks == p-1)
+ {
+ kase = 1;
+ }
+ else
+ {
+ kase = 2;
+ k = ks;
+ }
+ }
+ ++k;
+
+ // Perform the task indicated by kase.
+ switch (kase)
+ {
+
+ // Deflate negligible s(p).
+ case 1:
+ {
+ Scalar f(e[p-2]);
+ e[p-2] = 0.0;
+ for (j = p-2; j >= k; --j)
+ {
+ Scalar t(ei_hypot(m_sigma[j],f));
+ Scalar cs(m_sigma[j]/t);
+ Scalar sn(f/t);
+ m_sigma[j] = t;
+ if (j != k)
+ {
+ f = -sn*e[j-1];
+ e[j-1] = cs*e[j-1];
+ }
+ if (wantv)
+ {
+ for (i = 0; i < n; ++i)
+ {
+ t = cs*m_matV(i,j) + sn*m_matV(i,p-1);
+ m_matV(i,p-1) = -sn*m_matV(i,j) + cs*m_matV(i,p-1);
+ m_matV(i,j) = t;
+ }
+ }
+ }
+ }
+ break;
+
+ // Split at negligible s(k).
+ case 2:
+ {
+ Scalar f(e[k-1]);
+ e[k-1] = 0.0;
+ for (j = k; j < p; ++j)
+ {
+ Scalar t(ei_hypot(m_sigma[j],f));
+ Scalar cs( m_sigma[j]/t);
+ Scalar sn(f/t);
+ m_sigma[j] = t;
+ f = -sn*e[j];
+ e[j] = cs*e[j];
+ if (wantu)
+ {
+ for (i = 0; i < m; ++i)
+ {
+ t = cs*m_matU(i,j) + sn*m_matU(i,k-1);
+ m_matU(i,k-1) = -sn*m_matU(i,j) + cs*m_matU(i,k-1);
+ m_matU(i,j) = t;
+ }
+ }
+ }
+ }
+ break;
+
+ // Perform one qr step.
+ case 3:
+ {
+ // Calculate the shift.
+ Scalar scale = std::max(std::max(std::max(std::max(
+ ei_abs(m_sigma[p-1]),ei_abs(m_sigma[p-2])),ei_abs(e[p-2])),
+ ei_abs(m_sigma[k])),ei_abs(e[k]));
+ Scalar sp = m_sigma[p-1]/scale;
+ Scalar spm1 = m_sigma[p-2]/scale;
+ Scalar epm1 = e[p-2]/scale;
+ Scalar sk = m_sigma[k]/scale;
+ Scalar ek = e[k]/scale;
+ Scalar b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/Scalar(2);
+ Scalar c = (sp*epm1)*(sp*epm1);
+ Scalar shift = 0.0;
+ if ((b != 0.0) || (c != 0.0))
+ {
+ shift = ei_sqrt(b*b + c);
+ if (b < 0.0)
+ shift = -shift;
+ shift = c/(b + shift);
+ }
+ Scalar f = (sk + sp)*(sk - sp) + shift;
+ Scalar g = sk*ek;
+
+ // Chase zeros.
+
+ for (j = k; j < p-1; ++j)
+ {
+ Scalar t = ei_hypot(f,g);
+ Scalar cs = f/t;
+ Scalar sn = g/t;
+ if (j != k)
+ e[j-1] = t;
+ f = cs*m_sigma[j] + sn*e[j];
+ e[j] = cs*e[j] - sn*m_sigma[j];
+ g = sn*m_sigma[j+1];
+ m_sigma[j+1] = cs*m_sigma[j+1];
+ if (wantv)
+ {
+ for (i = 0; i < n; ++i)
+ {
+ t = cs*m_matV(i,j) + sn*m_matV(i,j+1);
+ m_matV(i,j+1) = -sn*m_matV(i,j) + cs*m_matV(i,j+1);
+ m_matV(i,j) = t;
+ }
+ }
+ t = ei_hypot(f,g);
+ cs = f/t;
+ sn = g/t;
+ m_sigma[j] = t;
+ f = cs*e[j] + sn*m_sigma[j+1];
+ m_sigma[j+1] = -sn*e[j] + cs*m_sigma[j+1];
+ g = sn*e[j+1];
+ e[j+1] = cs*e[j+1];
+ if (wantu && (j < m-1))
+ {
+ for (i = 0; i < m; ++i)
+ {
+ t = cs*m_matU(i,j) + sn*m_matU(i,j+1);
+ m_matU(i,j+1) = -sn*m_matU(i,j) + cs*m_matU(i,j+1);
+ m_matU(i,j) = t;
+ }
+ }
+ }
+ e[p-2] = f;
+ iter = iter + 1;
+ }
+ break;
+
+ // Convergence.
+ case 4:
+ {
+ // Make the singular values positive.
+ if (m_sigma[k] <= 0.0)
+ {
+ m_sigma[k] = m_sigma[k] < Scalar(0) ? -m_sigma[k] : Scalar(0);
+ if (wantv)
+ m_matV.col(k).start(pp+1) = -m_matV.col(k).start(pp+1);
+ }
+
+ // Order the singular values.
+ while (k < pp)
+ {
+ if (m_sigma[k] >= m_sigma[k+1])
+ break;
+ Scalar t = m_sigma[k];
+ m_sigma[k] = m_sigma[k+1];
+ m_sigma[k+1] = t;
+ if (wantv && (k < n-1))
+ m_matV.col(k).swap(m_matV.col(k+1));
+ if (wantu && (k < m-1))
+ m_matU.col(k).swap(m_matU.col(k+1));
+ ++k;
+ }
+ iter = 0;
+ p--;
+ }
+ break;
+ } // end big switch
+ } // end iterations
+}
+
+template<typename MatrixType>
+SVD<MatrixType>& SVD<MatrixType>::sort()
+{
+ int mu = m_matU.rows();
+ int mv = m_matV.rows();
+ int n = m_matU.cols();
+
+ for (int i=0; i<n; ++i)
+ {
+ int k = i;
+ Scalar p = m_sigma.coeff(i);
+
+ for (int j=i+1; j<n; ++j)
+ {
+ if (m_sigma.coeff(j) > p)
+ {
+ k = j;
+ p = m_sigma.coeff(j);
+ }
+ }
+ if (k != i)
+ {
+ m_sigma.coeffRef(k) = m_sigma.coeff(i); // i.e.
+ m_sigma.coeffRef(i) = p; // swaps the i-th and the k-th elements
+
+ int j = mu;
+ for(int s=0; j!=0; ++s, --j)
+ std::swap(m_matU.coeffRef(s,i), m_matU.coeffRef(s,k));
+
+ j = mv;
+ for (int s=0; j!=0; ++s, --j)
+ std::swap(m_matV.coeffRef(s,i), m_matV.coeffRef(s,k));
+ }
+ }
+ return *this;
+}
+
+/** \returns the solution of \f$ A x = b \f$ using the current SVD decomposition of A.
+ * The parts of the solution corresponding to zero singular values are ignored.
+ *
+ * \sa MatrixBase::svd(), LU::solve(), LLT::solve()
+ */
+template<typename MatrixType>
+template<typename OtherDerived, typename ResultType>
+bool SVD<MatrixType>::solve(const MatrixBase<OtherDerived> &b, ResultType* result) const
+{
+ const int rows = m_matU.rows();
+ ei_assert(b.rows() == rows);
+
+ Scalar maxVal = m_sigma.cwise().abs().maxCoeff();
+ for (int j=0; j<b.cols(); ++j)
+ {
+ Matrix<Scalar,MatrixUType::RowsAtCompileTime,1> aux = m_matU.transpose() * b.col(j);
+
+ for (int i = 0; i <m_matU.cols(); ++i)
+ {
+ Scalar si = m_sigma.coeff(i);
+ if (ei_isMuchSmallerThan(ei_abs(si),maxVal))
+ aux.coeffRef(i) = 0;
+ else
+ aux.coeffRef(i) /= si;
+ }
+
+ result->col(j) = m_matV * aux;
+ }
+ return true;
+}
+
+/** Computes the polar decomposition of the matrix, as a product unitary x positive.
+ *
+ * If either pointer is zero, the corresponding computation is skipped.
+ *
+ * Only for square matrices.
+ *
+ * \sa computePositiveUnitary(), computeRotationScaling()
+ */
+template<typename MatrixType>
+template<typename UnitaryType, typename PositiveType>
+void SVD<MatrixType>::computeUnitaryPositive(UnitaryType *unitary,
+ PositiveType *positive) const
+{
+ ei_assert(m_matU.cols() == m_matV.cols() && "Polar decomposition is only for square matrices");
+ if(unitary) *unitary = m_matU * m_matV.adjoint();
+ if(positive) *positive = m_matV * m_sigma.asDiagonal() * m_matV.adjoint();
+}
+
+/** Computes the polar decomposition of the matrix, as a product positive x unitary.
+ *
+ * If either pointer is zero, the corresponding computation is skipped.
+ *
+ * Only for square matrices.
+ *
+ * \sa computeUnitaryPositive(), computeRotationScaling()
+ */
+template<typename MatrixType>
+template<typename UnitaryType, typename PositiveType>
+void SVD<MatrixType>::computePositiveUnitary(UnitaryType *positive,
+ PositiveType *unitary) const
+{
+ ei_assert(m_matU.rows() == m_matV.rows() && "Polar decomposition is only for square matrices");
+ if(unitary) *unitary = m_matU * m_matV.adjoint();
+ if(positive) *positive = m_matU * m_sigma.asDiagonal() * m_matU.adjoint();
+}
+
+/** decomposes the matrix as a product rotation x scaling, the scaling being
+ * not necessarily positive.
+ *
+ * If either pointer is zero, the corresponding computation is skipped.
+ *
+ * This method requires the Geometry module.
+ *
+ * \sa computeScalingRotation(), computeUnitaryPositive()
+ */
+template<typename MatrixType>
+template<typename RotationType, typename ScalingType>
+void SVD<MatrixType>::computeRotationScaling(RotationType *rotation, ScalingType *scaling) const
+{
+ ei_assert(m_matU.rows() == m_matV.rows() && "Polar decomposition is only for square matrices");
+ Scalar x = (m_matU * m_matV.adjoint()).determinant(); // so x has absolute value 1
+ Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> sv(m_sigma);
+ sv.coeffRef(0) *= x;
+ if(scaling) scaling->lazyAssign(m_matV * sv.asDiagonal() * m_matV.adjoint());
+ if(rotation)
+ {
+ MatrixType m(m_matU);
+ m.col(0) /= x;
+ rotation->lazyAssign(m * m_matV.adjoint());
+ }
+}
+
+/** decomposes the matrix as a product scaling x rotation, the scaling being
+ * not necessarily positive.
+ *
+ * If either pointer is zero, the corresponding computation is skipped.
+ *
+ * This method requires the Geometry module.
+ *
+ * \sa computeRotationScaling(), computeUnitaryPositive()
+ */
+template<typename MatrixType>
+template<typename ScalingType, typename RotationType>
+void SVD<MatrixType>::computeScalingRotation(ScalingType *scaling, RotationType *rotation) const
+{
+ ei_assert(m_matU.rows() == m_matV.rows() && "Polar decomposition is only for square matrices");
+ Scalar x = (m_matU * m_matV.adjoint()).determinant(); // so x has absolute value 1
+ Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> sv(m_sigma);
+ sv.coeffRef(0) *= x;
+ if(scaling) scaling->lazyAssign(m_matU * sv.asDiagonal() * m_matU.adjoint());
+ if(rotation)
+ {
+ MatrixType m(m_matU);
+ m.col(0) /= x;
+ rotation->lazyAssign(m * m_matV.adjoint());
+ }
+}
+
+
+/** \svd_module
+ * \returns the SVD decomposition of \c *this
+ */
+template<typename Derived>
+inline SVD<typename MatrixBase<Derived>::PlainMatrixType>
+MatrixBase<Derived>::svd() const
+{
+ return SVD<PlainMatrixType>(derived());
+}
+
+#endif // EIGEN_SVD_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h b/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h
new file mode 100644
index 00000000000..75001a2fa25
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h
@@ -0,0 +1,371 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_AMBIVECTOR_H
+#define EIGEN_AMBIVECTOR_H
+
+/** \internal
+ * Hybrid sparse/dense vector class designed for intensive read-write operations.
+ *
+ * See BasicSparseLLT and SparseProduct for usage examples.
+ */
+template<typename _Scalar> class AmbiVector
+{
+ public:
+ typedef _Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ AmbiVector(int size)
+ : m_buffer(0), m_size(0), m_allocatedSize(0), m_allocatedElements(0), m_mode(-1)
+ {
+ resize(size);
+ }
+
+ void init(RealScalar estimatedDensity);
+ void init(int mode);
+
+ void nonZeros() const;
+
+ /** Specifies a sub-vector to work on */
+ void setBounds(int start, int end) { m_start = start; m_end = end; }
+
+ void setZero();
+
+ void restart();
+ Scalar& coeffRef(int i);
+ Scalar coeff(int i);
+
+ class Iterator;
+
+ ~AmbiVector() { delete[] m_buffer; }
+
+ void resize(int size)
+ {
+ if (m_allocatedSize < size)
+ reallocate(size);
+ m_size = size;
+ }
+
+ int size() const { return m_size; }
+
+ protected:
+
+ void reallocate(int size)
+ {
+ // if the size of the matrix is not too large, let's allocate a bit more than needed such
+ // that we can handle dense vector even in sparse mode.
+ delete[] m_buffer;
+ if (size<1000)
+ {
+ int allocSize = (size * sizeof(ListEl))/sizeof(Scalar);
+ m_allocatedElements = (allocSize*sizeof(Scalar))/sizeof(ListEl);
+ m_buffer = new Scalar[allocSize];
+ }
+ else
+ {
+ m_allocatedElements = (size*sizeof(Scalar))/sizeof(ListEl);
+ m_buffer = new Scalar[size];
+ }
+ m_size = size;
+ m_start = 0;
+ m_end = m_size;
+ }
+
+ void reallocateSparse()
+ {
+ int copyElements = m_allocatedElements;
+ m_allocatedElements = std::min(int(m_allocatedElements*1.5),m_size);
+ int allocSize = m_allocatedElements * sizeof(ListEl);
+ allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0);
+ Scalar* newBuffer = new Scalar[allocSize];
+ memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
+ }
+
+ protected:
+ // element type of the linked list
+ struct ListEl
+ {
+ int next;
+ int index;
+ Scalar value;
+ };
+
+ // used to store data in both mode
+ Scalar* m_buffer;
+ int m_size;
+ int m_start;
+ int m_end;
+ int m_allocatedSize;
+ int m_allocatedElements;
+ int m_mode;
+
+ // linked list mode
+ int m_llStart;
+ int m_llCurrent;
+ int m_llSize;
+
+ private:
+ AmbiVector(const AmbiVector&);
+
+};
+
+/** \returns the number of non zeros in the current sub vector */
+template<typename Scalar>
+void AmbiVector<Scalar>::nonZeros() const
+{
+ if (m_mode==IsSparse)
+ return m_llSize;
+ else
+ return m_end - m_start;
+}
+
+template<typename Scalar>
+void AmbiVector<Scalar>::init(RealScalar estimatedDensity)
+{
+ if (estimatedDensity>0.1)
+ init(IsDense);
+ else
+ init(IsSparse);
+}
+
+template<typename Scalar>
+void AmbiVector<Scalar>::init(int mode)
+{
+ m_mode = mode;
+ if (m_mode==IsSparse)
+ {
+ m_llSize = 0;
+ m_llStart = -1;
+ }
+}
+
+/** Must be called whenever we might perform a write access
+ * with an index smaller than the previous one.
+ *
+ * Don't worry, this function is extremely cheap.
+ */
+template<typename Scalar>
+void AmbiVector<Scalar>::restart()
+{
+ m_llCurrent = m_llStart;
+}
+
+/** Set all coefficients of current subvector to zero */
+template<typename Scalar>
+void AmbiVector<Scalar>::setZero()
+{
+ if (m_mode==IsDense)
+ {
+ for (int i=m_start; i<m_end; ++i)
+ m_buffer[i] = Scalar(0);
+ }
+ else
+ {
+ ei_assert(m_mode==IsSparse);
+ m_llSize = 0;
+ m_llStart = -1;
+ }
+}
+
+template<typename Scalar>
+Scalar& AmbiVector<Scalar>::coeffRef(int i)
+{
+ if (m_mode==IsDense)
+ return m_buffer[i];
+ else
+ {
+ ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_buffer);
+ // TODO factorize the following code to reduce code generation
+ ei_assert(m_mode==IsSparse);
+ if (m_llSize==0)
+ {
+ // this is the first element
+ m_llStart = 0;
+ m_llCurrent = 0;
+ ++m_llSize;
+ llElements[0].value = Scalar(0);
+ llElements[0].index = i;
+ llElements[0].next = -1;
+ return llElements[0].value;
+ }
+ else if (i<llElements[m_llStart].index)
+ {
+ // this is going to be the new first element of the list
+ ListEl& el = llElements[m_llSize];
+ el.value = Scalar(0);
+ el.index = i;
+ el.next = m_llStart;
+ m_llStart = m_llSize;
+ ++m_llSize;
+ m_llCurrent = m_llStart;
+ return el.value;
+ }
+ else
+ {
+ int nextel = llElements[m_llCurrent].next;
+ ei_assert(i>=llElements[m_llCurrent].index && "you must call restart() before inserting an element with lower or equal index");
+ while (nextel >= 0 && llElements[nextel].index<=i)
+ {
+ m_llCurrent = nextel;
+ nextel = llElements[nextel].next;
+ }
+
+ if (llElements[m_llCurrent].index==i)
+ {
+ // the coefficient already exists and we found it !
+ return llElements[m_llCurrent].value;
+ }
+ else
+ {
+ if (m_llSize>=m_allocatedElements)
+ reallocateSparse();
+ ei_internal_assert(m_llSize<m_size && "internal error: overflow in sparse mode");
+ // let's insert a new coefficient
+ ListEl& el = llElements[m_llSize];
+ el.value = Scalar(0);
+ el.index = i;
+ el.next = llElements[m_llCurrent].next;
+ llElements[m_llCurrent].next = m_llSize;
+ ++m_llSize;
+ return el.value;
+ }
+ }
+ }
+}
+
+template<typename Scalar>
+Scalar AmbiVector<Scalar>::coeff(int i)
+{
+ if (m_mode==IsDense)
+ return m_buffer[i];
+ else
+ {
+ ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_buffer);
+ ei_assert(m_mode==IsSparse);
+ if ((m_llSize==0) || (i<llElements[m_llStart].index))
+ {
+ return Scalar(0);
+ }
+ else
+ {
+ int elid = m_llStart;
+ while (elid >= 0 && llElements[elid].index<i)
+ elid = llElements[elid].next;
+
+ if (llElements[elid].index==i)
+ return llElements[m_llCurrent].value;
+ else
+ return Scalar(0);
+ }
+ }
+}
+
+/** Iterator over the nonzero coefficients */
+template<typename _Scalar>
+class AmbiVector<_Scalar>::Iterator
+{
+ public:
+ typedef _Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ /** Default constructor
+ * \param vec the vector on which we iterate
+ * \param epsilon the minimal value used to prune zero coefficients.
+ * In practice, all coefficients having a magnitude smaller than \a epsilon
+ * are skipped.
+ */
+ Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*precision<RealScalar>())
+ : m_vector(vec)
+ {
+ m_epsilon = epsilon;
+ m_isDense = m_vector.m_mode==IsDense;
+ if (m_isDense)
+ {
+ m_cachedIndex = m_vector.m_start-1;
+ ++(*this);
+ }
+ else
+ {
+ ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
+ m_currentEl = m_vector.m_llStart;
+ while (m_currentEl>=0 && ei_abs(llElements[m_currentEl].value)<m_epsilon)
+ m_currentEl = llElements[m_currentEl].next;
+ if (m_currentEl<0)
+ {
+ m_cachedIndex = -1;
+ }
+ else
+ {
+ m_cachedIndex = llElements[m_currentEl].index;
+ m_cachedValue = llElements[m_currentEl].value;
+ }
+ }
+ }
+
+ int index() const { return m_cachedIndex; }
+ Scalar value() const { return m_cachedValue; }
+
+ operator bool() const { return m_cachedIndex>=0; }
+
+ Iterator& operator++()
+ {
+ if (m_isDense)
+ {
+ do {
+ ++m_cachedIndex;
+ } while (m_cachedIndex<m_vector.m_end && ei_abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
+ if (m_cachedIndex<m_vector.m_end)
+ m_cachedValue = m_vector.m_buffer[m_cachedIndex];
+ else
+ m_cachedIndex=-1;
+ }
+ else
+ {
+ ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
+ do {
+ m_currentEl = llElements[m_currentEl].next;
+ } while (m_currentEl>=0 && ei_abs(llElements[m_currentEl].value)<m_epsilon);
+ if (m_currentEl<0)
+ {
+ m_cachedIndex = -1;
+ }
+ else
+ {
+ m_cachedIndex = llElements[m_currentEl].index;
+ m_cachedValue = llElements[m_currentEl].value;
+ }
+ }
+ return *this;
+ }
+
+ protected:
+ const AmbiVector& m_vector; // the target vector
+ int m_currentEl; // the current element in sparse/linked-list mode
+ RealScalar m_epsilon; // epsilon used to prune zero coefficients
+ int m_cachedIndex; // current coordinate
+ Scalar m_cachedValue; // current value
+ bool m_isDense; // mode of the vector
+};
+
+
+#endif // EIGEN_AMBIVECTOR_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/CholmodSupport.h b/extern/Eigen2/Eigen/src/Sparse/CholmodSupport.h
new file mode 100644
index 00000000000..dfd9c787ae9
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/CholmodSupport.h
@@ -0,0 +1,236 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_CHOLMODSUPPORT_H
+#define EIGEN_CHOLMODSUPPORT_H
+
+template<typename Scalar, typename CholmodType>
+void ei_cholmod_configure_matrix(CholmodType& mat)
+{
+ if (ei_is_same_type<Scalar,float>::ret)
+ {
+ mat.xtype = CHOLMOD_REAL;
+ mat.dtype = 1;
+ }
+ else if (ei_is_same_type<Scalar,double>::ret)
+ {
+ mat.xtype = CHOLMOD_REAL;
+ mat.dtype = 0;
+ }
+ else if (ei_is_same_type<Scalar,std::complex<float> >::ret)
+ {
+ mat.xtype = CHOLMOD_COMPLEX;
+ mat.dtype = 1;
+ }
+ else if (ei_is_same_type<Scalar,std::complex<double> >::ret)
+ {
+ mat.xtype = CHOLMOD_COMPLEX;
+ mat.dtype = 0;
+ }
+ else
+ {
+ ei_assert(false && "Scalar type not supported by CHOLMOD");
+ }
+}
+
+template<typename Derived>
+cholmod_sparse SparseMatrixBase<Derived>::asCholmodMatrix()
+{
+ typedef typename Derived::Scalar Scalar;
+ cholmod_sparse res;
+ res.nzmax = nonZeros();
+ res.nrow = rows();;
+ res.ncol = cols();
+ res.p = derived()._outerIndexPtr();
+ res.i = derived()._innerIndexPtr();
+ res.x = derived()._valuePtr();
+ res.xtype = CHOLMOD_REAL;
+ res.itype = CHOLMOD_INT;
+ res.sorted = 1;
+ res.packed = 1;
+ res.dtype = 0;
+ res.stype = -1;
+
+ ei_cholmod_configure_matrix<Scalar>(res);
+
+ if (Derived::Flags & SelfAdjoint)
+ {
+ if (Derived::Flags & UpperTriangular)
+ res.stype = 1;
+ else if (Derived::Flags & LowerTriangular)
+ res.stype = -1;
+ else
+ res.stype = 0;
+ }
+ else
+ res.stype = 0;
+
+ return res;
+}
+
+template<typename Derived>
+cholmod_dense ei_cholmod_map_eigen_to_dense(MatrixBase<Derived>& mat)
+{
+ EIGEN_STATIC_ASSERT((ei_traits<Derived>::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
+ typedef typename Derived::Scalar Scalar;
+
+ cholmod_dense res;
+ res.nrow = mat.rows();
+ res.ncol = mat.cols();
+ res.nzmax = res.nrow * res.ncol;
+ res.d = mat.derived().stride();
+ res.x = mat.derived().data();
+ res.z = 0;
+
+ ei_cholmod_configure_matrix<Scalar>(res);
+
+ return res;
+}
+
+template<typename Scalar, int Flags>
+MappedSparseMatrix<Scalar,Flags>::MappedSparseMatrix(cholmod_sparse& cm)
+{
+ m_innerSize = cm.nrow;
+ m_outerSize = cm.ncol;
+ m_outerIndex = reinterpret_cast<int*>(cm.p);
+ m_innerIndices = reinterpret_cast<int*>(cm.i);
+ m_values = reinterpret_cast<Scalar*>(cm.x);
+ m_nnz = m_outerIndex[cm.ncol];
+}
+
+template<typename MatrixType>
+class SparseLLT<MatrixType,Cholmod> : public SparseLLT<MatrixType>
+{
+ protected:
+ typedef SparseLLT<MatrixType> Base;
+ typedef typename Base::Scalar Scalar;
+ typedef typename Base::RealScalar RealScalar;
+ using Base::MatrixLIsDirty;
+ using Base::SupernodalFactorIsDirty;
+ using Base::m_flags;
+ using Base::m_matrix;
+ using Base::m_status;
+
+ public:
+
+ SparseLLT(int flags = 0)
+ : Base(flags), m_cholmodFactor(0)
+ {
+ cholmod_start(&m_cholmod);
+ }
+
+ SparseLLT(const MatrixType& matrix, int flags = 0)
+ : Base(flags), m_cholmodFactor(0)
+ {
+ cholmod_start(&m_cholmod);
+ compute(matrix);
+ }
+
+ ~SparseLLT()
+ {
+ if (m_cholmodFactor)
+ cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
+ cholmod_finish(&m_cholmod);
+ }
+
+ inline const typename Base::CholMatrixType& matrixL(void) const;
+
+ template<typename Derived>
+ void solveInPlace(MatrixBase<Derived> &b) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+ mutable cholmod_common m_cholmod;
+ cholmod_factor* m_cholmodFactor;
+};
+
+template<typename MatrixType>
+void SparseLLT<MatrixType,Cholmod>::compute(const MatrixType& a)
+{
+ if (m_cholmodFactor)
+ {
+ cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
+ m_cholmodFactor = 0;
+ }
+
+ cholmod_sparse A = const_cast<MatrixType&>(a).asCholmodMatrix();
+ m_cholmod.supernodal = CHOLMOD_AUTO;
+ // TODO
+ if (m_flags&IncompleteFactorization)
+ {
+ m_cholmod.nmethods = 1;
+ m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
+ m_cholmod.postorder = 0;
+ }
+ else
+ {
+ m_cholmod.nmethods = 1;
+ m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
+ m_cholmod.postorder = 0;
+ }
+ m_cholmod.final_ll = 1;
+ m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
+ cholmod_factorize(&A, m_cholmodFactor, &m_cholmod);
+
+ m_status = (m_status & ~SupernodalFactorIsDirty) | MatrixLIsDirty;
+}
+
+template<typename MatrixType>
+inline const typename SparseLLT<MatrixType>::CholMatrixType&
+SparseLLT<MatrixType,Cholmod>::matrixL() const
+{
+ if (m_status & MatrixLIsDirty)
+ {
+ ei_assert(!(m_status & SupernodalFactorIsDirty));
+
+ cholmod_sparse* cmRes = cholmod_factor_to_sparse(m_cholmodFactor, &m_cholmod);
+ const_cast<typename Base::CholMatrixType&>(m_matrix) = MappedSparseMatrix<Scalar>(*cmRes);
+ free(cmRes);
+
+ m_status = (m_status & ~MatrixLIsDirty);
+ }
+ return m_matrix;
+}
+
+template<typename MatrixType>
+template<typename Derived>
+void SparseLLT<MatrixType,Cholmod>::solveInPlace(MatrixBase<Derived> &b) const
+{
+ const int size = m_cholmodFactor->n;
+ ei_assert(size==b.rows());
+
+ // this uses Eigen's triangular sparse solver
+// if (m_status & MatrixLIsDirty)
+// matrixL();
+// Base::solveInPlace(b);
+ // as long as our own triangular sparse solver is not fully optimal,
+ // let's use CHOLMOD's one:
+ cholmod_dense cdb = ei_cholmod_map_eigen_to_dense(b);
+ cholmod_dense* x = cholmod_solve(CHOLMOD_LDLt, m_cholmodFactor, &cdb, &m_cholmod);
+ b = Matrix<typename Base::Scalar,Dynamic,1>::Map(reinterpret_cast<typename Base::Scalar*>(x->x),b.rows());
+ cholmod_free_dense(&x, &m_cholmod);
+}
+
+#endif // EIGEN_CHOLMODSUPPORT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/CompressedStorage.h b/extern/Eigen2/Eigen/src/Sparse/CompressedStorage.h
new file mode 100644
index 00000000000..4dbd3230985
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/CompressedStorage.h
@@ -0,0 +1,230 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_COMPRESSED_STORAGE_H
+#define EIGEN_COMPRESSED_STORAGE_H
+
+/** Stores a sparse set of values as a list of values and a list of indices.
+ *
+ */
+template<typename Scalar>
+class CompressedStorage
+{
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ public:
+ CompressedStorage()
+ : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
+ {}
+
+ CompressedStorage(size_t size)
+ : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
+ {
+ resize(size);
+ }
+
+ CompressedStorage(const CompressedStorage& other)
+ : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
+ {
+ *this = other;
+ }
+
+ CompressedStorage& operator=(const CompressedStorage& other)
+ {
+ resize(other.size());
+ memcpy(m_values, other.m_values, m_size * sizeof(Scalar));
+ memcpy(m_indices, other.m_indices, m_size * sizeof(int));
+ return *this;
+ }
+
+ void swap(CompressedStorage& other)
+ {
+ std::swap(m_values, other.m_values);
+ std::swap(m_indices, other.m_indices);
+ std::swap(m_size, other.m_size);
+ std::swap(m_allocatedSize, other.m_allocatedSize);
+ }
+
+ ~CompressedStorage()
+ {
+ delete[] m_values;
+ delete[] m_indices;
+ }
+
+ void reserve(size_t size)
+ {
+ size_t newAllocatedSize = m_size + size;
+ if (newAllocatedSize > m_allocatedSize)
+ reallocate(newAllocatedSize);
+ }
+
+ void squeeze()
+ {
+ if (m_allocatedSize>m_size)
+ reallocate(m_size);
+ }
+
+ void resize(size_t size, float reserveSizeFactor = 0)
+ {
+ if (m_allocatedSize<size)
+ reallocate(size + size_t(reserveSizeFactor*size));
+ m_size = size;
+ }
+
+ void append(const Scalar& v, int i)
+ {
+ int id = m_size;
+ resize(m_size+1, 1);
+ m_values[id] = v;
+ m_indices[id] = i;
+ }
+
+ inline size_t size() const { return m_size; }
+ inline size_t allocatedSize() const { return m_allocatedSize; }
+ inline void clear() { m_size = 0; }
+
+ inline Scalar& value(size_t i) { return m_values[i]; }
+ inline const Scalar& value(size_t i) const { return m_values[i]; }
+
+ inline int& index(size_t i) { return m_indices[i]; }
+ inline const int& index(size_t i) const { return m_indices[i]; }
+
+ static CompressedStorage Map(int* indices, Scalar* values, size_t size)
+ {
+ CompressedStorage res;
+ res.m_indices = indices;
+ res.m_values = values;
+ res.m_allocatedSize = res.m_size = size;
+ return res;
+ }
+
+ /** \returns the largest \c k such that for all \c j in [0,k) index[\c j]\<\a key */
+ inline int searchLowerIndex(int key) const
+ {
+ return searchLowerIndex(0, m_size, key);
+ }
+
+ /** \returns the largest \c k in [start,end) such that for all \c j in [start,k) index[\c j]\<\a key */
+ inline int searchLowerIndex(size_t start, size_t end, int key) const
+ {
+ while(end>start)
+ {
+ size_t mid = (end+start)>>1;
+ if (m_indices[mid]<key)
+ start = mid+1;
+ else
+ end = mid;
+ }
+ return start;
+ }
+
+ /** \returns the stored value at index \a key
+ * If the value does not exist, then the value \a defaultValue is returned without any insertion. */
+ inline Scalar at(int key, Scalar defaultValue = Scalar(0)) const
+ {
+ if (m_size==0)
+ return defaultValue;
+ else if (key==m_indices[m_size-1])
+ return m_values[m_size-1];
+ // ^^ optimization: let's first check if it is the last coefficient
+ // (very common in high level algorithms)
+ const size_t id = searchLowerIndex(0,m_size-1,key);
+ return ((id<m_size) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
+ }
+
+ /** Like at(), but the search is performed in the range [start,end) */
+ inline Scalar atInRange(size_t start, size_t end, int key, Scalar defaultValue = Scalar(0)) const
+ {
+ if (start==end)
+ return Scalar(0);
+ else if (end>start && key==m_indices[end-1])
+ return m_values[end-1];
+ // ^^ optimization: let's first check if it is the last coefficient
+ // (very common in high level algorithms)
+ const size_t id = searchLowerIndex(start,end-1,key);
+ return ((id<end) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
+ }
+
+ /** \returns a reference to the value at index \a key
+ * If the value does not exist, then the value \a defaultValue is inserted
+ * such that the keys are sorted. */
+ inline Scalar& atWithInsertion(int key, Scalar defaultValue = Scalar(0))
+ {
+ size_t id = searchLowerIndex(0,m_size,key);
+ if (id>=m_size || m_indices[id]!=key)
+ {
+ resize(m_size+1,1);
+ for (size_t j=m_size-1; j>id; --j)
+ {
+ m_indices[j] = m_indices[j-1];
+ m_values[j] = m_values[j-1];
+ }
+ m_indices[id] = key;
+ m_values[id] = defaultValue;
+ }
+ return m_values[id];
+ }
+
+ void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ {
+ size_t k = 0;
+ size_t n = size();
+ for (size_t i=0; i<n; ++i)
+ {
+ if (!ei_isMuchSmallerThan(value(i), reference, epsilon))
+ {
+ value(k) = value(i);
+ index(k) = index(i);
+ ++k;
+ }
+ }
+ resize(k,0);
+ }
+
+ protected:
+
+ inline void reallocate(size_t size)
+ {
+ Scalar* newValues = new Scalar[size];
+ int* newIndices = new int[size];
+ size_t copySize = std::min(size, m_size);
+ // copy
+ memcpy(newValues, m_values, copySize * sizeof(Scalar));
+ memcpy(newIndices, m_indices, copySize * sizeof(int));
+ // delete old stuff
+ delete[] m_values;
+ delete[] m_indices;
+ m_values = newValues;
+ m_indices = newIndices;
+ m_allocatedSize = size;
+ }
+
+ protected:
+ Scalar* m_values;
+ int* m_indices;
+ size_t m_size;
+ size_t m_allocatedSize;
+
+};
+
+#endif // EIGEN_COMPRESSED_STORAGE_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/CoreIterators.h b/extern/Eigen2/Eigen/src/Sparse/CoreIterators.h
new file mode 100644
index 00000000000..f1520a585ca
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/CoreIterators.h
@@ -0,0 +1,68 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_COREITERATORS_H
+#define EIGEN_COREITERATORS_H
+
+/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
+ */
+
+/** \class InnerIterator
+ * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression
+ *
+ * todo
+ */
+
+// generic version for dense matrix and expressions
+template<typename Derived> class MatrixBase<Derived>::InnerIterator
+{
+ typedef typename Derived::Scalar Scalar;
+ enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit };
+ public:
+ EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, int outer)
+ : m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.rows())
+ {}
+
+ EIGEN_STRONG_INLINE Scalar value() const
+ {
+ return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner)
+ : m_expression.coeff(m_inner, m_outer);
+ }
+
+ EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; }
+
+ EIGEN_STRONG_INLINE int index() const { return m_inner; }
+ inline int row() const { return IsRowMajor ? m_outer : index(); }
+ inline int col() const { return IsRowMajor ? index() : m_outer; }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
+
+ protected:
+ const Derived& m_expression;
+ int m_inner;
+ const int m_outer;
+ const int m_end;
+};
+
+#endif // EIGEN_COREITERATORS_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h b/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h
new file mode 100644
index 00000000000..7119a84bd51
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h
@@ -0,0 +1,297 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H
+#define EIGEN_DYNAMIC_SPARSEMATRIX_H
+
+/** \class DynamicSparseMatrix
+ *
+ * \brief A sparse matrix class designed for matrix assembly purpose
+ *
+ * \param _Scalar the scalar type, i.e. the type of the coefficients
+ *
+ * Unlike SparseMatrix, this class provides a much higher degree of flexibility. In particular, it allows
+ * random read/write accesses in log(rho*outer_size) where \c rho is the probability that a coefficient is
+ * nonzero and outer_size is the number of columns if the matrix is column-major and the number of rows
+ * otherwise.
+ *
+ * Internally, the data are stored as a std::vector of compressed vector. The performances of random writes might
+ * decrease as the number of nonzeros per inner-vector increase. In practice, we observed very good performance
+ * till about 100 nonzeros/vector, and the performance remains relatively good till 500 nonzeros/vectors.
+ *
+ * \see SparseMatrix
+ */
+template<typename _Scalar, int _Flags>
+struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags> >
+{
+ typedef _Scalar Scalar;
+ enum {
+ RowsAtCompileTime = Dynamic,
+ ColsAtCompileTime = Dynamic,
+ MaxRowsAtCompileTime = Dynamic,
+ MaxColsAtCompileTime = Dynamic,
+ Flags = SparseBit | _Flags,
+ CoeffReadCost = NumTraits<Scalar>::ReadCost,
+ SupportedAccessPatterns = OuterRandomAccessPattern
+ };
+};
+
+template<typename _Scalar, int _Flags>
+class DynamicSparseMatrix
+ : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> >
+{
+ public:
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(DynamicSparseMatrix)
+ // FIXME: why are these operator already alvailable ???
+ // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=)
+ // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=)
+ typedef MappedSparseMatrix<Scalar,Flags> Map;
+
+ protected:
+
+ enum { IsRowMajor = Base::IsRowMajor };
+ typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix;
+
+ int m_innerSize;
+ std::vector<CompressedStorage<Scalar> > m_data;
+
+ public:
+
+ inline int rows() const { return IsRowMajor ? outerSize() : m_innerSize; }
+ inline int cols() const { return IsRowMajor ? m_innerSize : outerSize(); }
+ inline int innerSize() const { return m_innerSize; }
+ inline int outerSize() const { return m_data.size(); }
+ inline int innerNonZeros(int j) const { return m_data[j].size(); }
+
+ std::vector<CompressedStorage<Scalar> >& _data() { return m_data; }
+ const std::vector<CompressedStorage<Scalar> >& _data() const { return m_data; }
+
+ /** \returns the coefficient value at given position \a row, \a col
+ * This operation involes a log(rho*outer_size) binary search.
+ */
+ inline Scalar coeff(int row, int col) const
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+ return m_data[outer].at(inner);
+ }
+
+ /** \returns a reference to the coefficient value at given position \a row, \a col
+ * This operation involes a log(rho*outer_size) binary search. If the coefficient does not
+ * exist yet, then a sorted insertion into a sequential buffer is performed.
+ */
+ inline Scalar& coeffRef(int row, int col)
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+ return m_data[outer].atWithInsertion(inner);
+ }
+
+ class InnerIterator;
+
+ inline void setZero()
+ {
+ for (int j=0; j<outerSize(); ++j)
+ m_data[j].clear();
+ }
+
+ /** \returns the number of non zero coefficients */
+ inline int nonZeros() const
+ {
+ int res = 0;
+ for (int j=0; j<outerSize(); ++j)
+ res += m_data[j].size();
+ return res;
+ }
+
+ /** Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */
+ inline void startFill(int reserveSize = 1000)
+ {
+ if (outerSize()>0)
+ {
+ int reserveSizePerVector = std::max(reserveSize/outerSize(),4);
+ for (int j=0; j<outerSize(); ++j)
+ {
+ m_data[j].clear();
+ m_data[j].reserve(reserveSizePerVector);
+ }
+ }
+ }
+
+ /** inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that:
+ * 1 - the coefficient does not exist yet
+ * 2 - this the coefficient with greater inner coordinate for the given outer coordinate.
+ * In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates
+ * \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid.
+ *
+ * \see fillrand(), coeffRef()
+ */
+ inline Scalar& fill(int row, int col)
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+ ei_assert(outer<int(m_data.size()) && inner<m_innerSize);
+ ei_assert((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner));
+ m_data[outer].append(0, inner);
+ return m_data[outer].value(m_data[outer].size()-1);
+ }
+
+ /** Like fill() but with random inner coordinates.
+ * Compared to the generic coeffRef(), the unique limitation is that we assume
+ * the coefficient does not exist yet.
+ */
+ inline Scalar& fillrand(int row, int col)
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+
+ int startId = 0;
+ int id = m_data[outer].size() - 1;
+ m_data[outer].resize(id+2,1);
+
+ while ( (id >= startId) && (m_data[outer].index(id) > inner) )
+ {
+ m_data[outer].index(id+1) = m_data[outer].index(id);
+ m_data[outer].value(id+1) = m_data[outer].value(id);
+ --id;
+ }
+ m_data[outer].index(id+1) = inner;
+ m_data[outer].value(id+1) = 0;
+ return m_data[outer].value(id+1);
+ }
+
+ /** Does nothing. Provided for compatibility with SparseMatrix. */
+ inline void endFill() {}
+
+ void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ {
+ for (int j=0; j<outerSize(); ++j)
+ m_data[j].prune(reference,epsilon);
+ }
+
+ /** Resize the matrix without preserving the data (the matrix is set to zero)
+ */
+ void resize(int rows, int cols)
+ {
+ const int outerSize = IsRowMajor ? rows : cols;
+ m_innerSize = IsRowMajor ? cols : rows;
+ setZero();
+ if (int(m_data.size()) != outerSize)
+ {
+ m_data.resize(outerSize);
+ }
+ }
+
+ void resizeAndKeepData(int rows, int cols)
+ {
+ const int outerSize = IsRowMajor ? rows : cols;
+ const int innerSize = IsRowMajor ? cols : rows;
+ if (m_innerSize>innerSize)
+ {
+ // remove all coefficients with innerCoord>=innerSize
+ // TODO
+ std::cerr << "not implemented yet\n";
+ exit(2);
+ }
+ if (m_data.size() != outerSize)
+ {
+ m_data.resize(outerSize);
+ }
+ }
+
+ inline DynamicSparseMatrix()
+ : m_innerSize(0), m_data(0)
+ {
+ ei_assert(innerSize()==0 && outerSize()==0);
+ }
+
+ inline DynamicSparseMatrix(int rows, int cols)
+ : m_innerSize(0)
+ {
+ resize(rows, cols);
+ }
+
+ template<typename OtherDerived>
+ inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other)
+ : m_innerSize(0)
+ {
+ *this = other.derived();
+ }
+
+ inline DynamicSparseMatrix(const DynamicSparseMatrix& other)
+ : Base(), m_innerSize(0)
+ {
+ *this = other.derived();
+ }
+
+ inline void swap(DynamicSparseMatrix& other)
+ {
+ //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n");
+ std::swap(m_innerSize, other.m_innerSize);
+ //std::swap(m_outerSize, other.m_outerSize);
+ m_data.swap(other.m_data);
+ }
+
+ inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other)
+ {
+ if (other.isRValue())
+ {
+ swap(other.const_cast_derived());
+ }
+ else
+ {
+ resize(other.rows(), other.cols());
+ m_data = other.m_data;
+ }
+ return *this;
+ }
+
+ template<typename OtherDerived>
+ inline DynamicSparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ return SparseMatrixBase<DynamicSparseMatrix>::operator=(other.derived());
+ }
+
+ /** Destructor */
+ inline ~DynamicSparseMatrix() {}
+};
+
+template<typename Scalar, int _Flags>
+class DynamicSparseMatrix<Scalar,_Flags>::InnerIterator : public SparseVector<Scalar,_Flags>::InnerIterator
+{
+ typedef typename SparseVector<Scalar,_Flags>::InnerIterator Base;
+ public:
+ InnerIterator(const DynamicSparseMatrix& mat, int outer)
+ : Base(mat.m_data[outer]), m_outer(outer)
+ {}
+
+ inline int row() const { return IsRowMajor ? m_outer : Base::index(); }
+ inline int col() const { return IsRowMajor ? Base::index() : m_outer; }
+
+
+ protected:
+ const int m_outer;
+};
+
+#endif // EIGEN_DYNAMIC_SPARSEMATRIX_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/MappedSparseMatrix.h b/extern/Eigen2/Eigen/src/Sparse/MappedSparseMatrix.h
new file mode 100644
index 00000000000..f4935d8344e
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/MappedSparseMatrix.h
@@ -0,0 +1,175 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MAPPED_SPARSEMATRIX_H
+#define EIGEN_MAPPED_SPARSEMATRIX_H
+
+/** \class MappedSparseMatrix
+ *
+ * \brief Sparse matrix
+ *
+ * \param _Scalar the scalar type, i.e. the type of the coefficients
+ *
+ * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
+ *
+ */
+template<typename _Scalar, int _Flags>
+struct ei_traits<MappedSparseMatrix<_Scalar, _Flags> > : ei_traits<SparseMatrix<_Scalar, _Flags> >
+{};
+
+template<typename _Scalar, int _Flags>
+class MappedSparseMatrix
+ : public SparseMatrixBase<MappedSparseMatrix<_Scalar, _Flags> >
+{
+ public:
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(MappedSparseMatrix)
+
+ protected:
+ enum { IsRowMajor = Base::IsRowMajor };
+
+ int m_outerSize;
+ int m_innerSize;
+ int m_nnz;
+ int* m_outerIndex;
+ int* m_innerIndices;
+ Scalar* m_values;
+
+ public:
+
+ inline int rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
+ inline int cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
+ inline int innerSize() const { return m_innerSize; }
+ inline int outerSize() const { return m_outerSize; }
+ inline int innerNonZeros(int j) const { return m_outerIndex[j+1]-m_outerIndex[j]; }
+
+ //----------------------------------------
+ // direct access interface
+ inline const Scalar* _valuePtr() const { return m_values; }
+ inline Scalar* _valuePtr() { return m_values; }
+
+ inline const int* _innerIndexPtr() const { return m_innerIndices; }
+ inline int* _innerIndexPtr() { return m_innerIndices; }
+
+ inline const int* _outerIndexPtr() const { return m_outerIndex; }
+ inline int* _outerIndexPtr() { return m_outerIndex; }
+ //----------------------------------------
+
+ inline Scalar coeff(int row, int col) const
+ {
+ const int outer = RowMajor ? row : col;
+ const int inner = RowMajor ? col : row;
+
+ int start = m_outerIndex[outer];
+ int end = m_outerIndex[outer+1];
+ if (start==end)
+ return Scalar(0);
+ else if (end>0 && inner==m_innerIndices[end-1])
+ return m_values[end-1];
+ // ^^ optimization: let's first check if it is the last coefficient
+ // (very common in high level algorithms)
+
+ const int* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
+ const int id = r-&m_innerIndices[0];
+ return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
+ }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ const int outer = RowMajor ? row : col;
+ const int inner = RowMajor ? col : row;
+
+ int start = m_outerIndex[outer];
+ int end = m_outerIndex[outer+1];
+ ei_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
+ ei_assert(end>start && "coeffRef cannot be called on a zero coefficient");
+ int* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end],inner);
+ const int id = r-&m_innerIndices[0];
+ ei_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
+ return m_values[id];
+ }
+
+ class InnerIterator;
+
+ /** \returns the number of non zero coefficients */
+ inline int nonZeros() const { return m_nnz; }
+
+ inline MappedSparseMatrix(int rows, int cols, int nnz, int* outerIndexPtr, int* innerIndexPtr, Scalar* valuePtr)
+ : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr),
+ m_innerIndices(innerIndexPtr), m_values(valuePtr)
+ {}
+
+ #ifdef EIGEN_TAUCS_SUPPORT
+ explicit MappedSparseMatrix(taucs_ccs_matrix& taucsMatrix);
+ #endif
+
+ #ifdef EIGEN_CHOLMOD_SUPPORT
+ explicit MappedSparseMatrix(cholmod_sparse& cholmodMatrix);
+ #endif
+
+ #ifdef EIGEN_SUPERLU_SUPPORT
+ explicit MappedSparseMatrix(SluMatrix& sluMatrix);
+ #endif
+
+ /** Empty destructor */
+ inline ~MappedSparseMatrix() {}
+};
+
+template<typename Scalar, int _Flags>
+class MappedSparseMatrix<Scalar,_Flags>::InnerIterator
+{
+ public:
+ InnerIterator(const MappedSparseMatrix& mat, int outer)
+ : m_matrix(mat),
+ m_outer(outer),
+ m_id(mat._outerIndexPtr()[outer]),
+ m_start(m_id),
+ m_end(mat._outerIndexPtr()[outer+1])
+ {}
+
+ template<unsigned int Added, unsigned int Removed>
+ InnerIterator(const Flagged<MappedSparseMatrix,Added,Removed>& mat, int outer)
+ : m_matrix(mat._expression()), m_id(m_matrix._outerIndexPtr()[outer]),
+ m_start(m_id), m_end(m_matrix._outerIndexPtr()[outer+1])
+ {}
+
+ inline InnerIterator& operator++() { m_id++; return *this; }
+
+ inline Scalar value() const { return m_matrix._valuePtr()[m_id]; }
+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix._valuePtr()[m_id]); }
+
+ inline int index() const { return m_matrix._innerIndexPtr()[m_id]; }
+ inline int row() const { return IsRowMajor ? m_outer : index(); }
+ inline int col() const { return IsRowMajor ? index() : m_outer; }
+
+ inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
+
+ protected:
+ const MappedSparseMatrix& m_matrix;
+ const int m_outer;
+ int m_id;
+ const int m_start;
+ const int m_end;
+};
+
+#endif // EIGEN_MAPPED_SPARSEMATRIX_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/RandomSetter.h b/extern/Eigen2/Eigen/src/Sparse/RandomSetter.h
new file mode 100644
index 00000000000..d908e315f3b
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/RandomSetter.h
@@ -0,0 +1,330 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_RANDOMSETTER_H
+#define EIGEN_RANDOMSETTER_H
+
+/** Represents a std::map
+ *
+ * \see RandomSetter
+ */
+template<typename Scalar> struct StdMapTraits
+{
+ typedef int KeyType;
+ typedef std::map<KeyType,Scalar> Type;
+ enum {
+ IsSorted = 1
+ };
+
+ static void setInvalidKey(Type&, const KeyType&) {}
+};
+
+#ifdef EIGEN_UNORDERED_MAP_SUPPORT
+/** Represents a std::unordered_map
+ *
+ * To use it you need to both define EIGEN_UNORDERED_MAP_SUPPORT and include the unordered_map header file
+ * yourself making sure that unordered_map is defined in the std namespace.
+ *
+ * For instance, with current version of gcc you can either enable C++0x standard (-std=c++0x) or do:
+ * \code
+ * #include <tr1/unordered_map>
+ * #define EIGEN_UNORDERED_MAP_SUPPORT
+ * namespace std {
+ * using std::tr1::unordered_map;
+ * }
+ * \endcode
+ *
+ * \see RandomSetter
+ */
+template<typename Scalar> struct StdUnorderedMapTraits
+{
+ typedef int KeyType;
+ typedef std::unordered_map<KeyType,Scalar> Type;
+ enum {
+ IsSorted = 0
+ };
+
+ static void setInvalidKey(Type&, const KeyType&) {}
+};
+#endif // EIGEN_UNORDERED_MAP_SUPPORT
+
+#ifdef _DENSE_HASH_MAP_H_
+/** Represents a google::dense_hash_map
+ *
+ * \see RandomSetter
+ */
+template<typename Scalar> struct GoogleDenseHashMapTraits
+{
+ typedef int KeyType;
+ typedef google::dense_hash_map<KeyType,Scalar> Type;
+ enum {
+ IsSorted = 0
+ };
+
+ static void setInvalidKey(Type& map, const KeyType& k)
+ { map.set_empty_key(k); }
+};
+#endif
+
+#ifdef _SPARSE_HASH_MAP_H_
+/** Represents a google::sparse_hash_map
+ *
+ * \see RandomSetter
+ */
+template<typename Scalar> struct GoogleSparseHashMapTraits
+{
+ typedef int KeyType;
+ typedef google::sparse_hash_map<KeyType,Scalar> Type;
+ enum {
+ IsSorted = 0
+ };
+
+ static void setInvalidKey(Type&, const KeyType&) {}
+};
+#endif
+
+/** \class RandomSetter
+ *
+ * \brief The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access
+ *
+ * \param SparseMatrixType the type of the sparse matrix we are updating
+ * \param MapTraits a traits class representing the map implementation used for the temporary sparse storage.
+ * Its default value depends on the system.
+ * \param OuterPacketBits defines the number of rows (or columns) manage by a single map object
+ * as a power of two exponent.
+ *
+ * This class temporarily represents a sparse matrix object using a generic map implementation allowing for
+ * efficient random access. The conversion from the compressed representation to a hash_map object is performed
+ * in the RandomSetter constructor, while the sparse matrix is updated back at destruction time. This strategy
+ * suggest the use of nested blocks as in this example:
+ *
+ * \code
+ * SparseMatrix<double> m(rows,cols);
+ * {
+ * RandomSetter<SparseMatrix<double> > w(m);
+ * // don't use m but w instead with read/write random access to the coefficients:
+ * for(;;)
+ * w(rand(),rand()) = rand;
+ * }
+ * // when w is deleted, the data are copied back to m
+ * // and m is ready to use.
+ * \endcode
+ *
+ * Since hash_map objects are not fully sorted, representing a full matrix as a single hash_map would
+ * involve a big and costly sort to update the compressed matrix back. To overcome this issue, a RandomSetter
+ * use multiple hash_map, each representing 2^OuterPacketBits columns or rows according to the storage order.
+ * To reach optimal performance, this value should be adjusted according to the average number of nonzeros
+ * per rows/columns.
+ *
+ * The possible values for the template parameter MapTraits are:
+ * - \b StdMapTraits: corresponds to std::map. (does not perform very well)
+ * - \b GnuHashMapTraits: corresponds to __gnu_cxx::hash_map (available only with GCC)
+ * - \b GoogleDenseHashMapTraits: corresponds to google::dense_hash_map (best efficiency, reasonable memory consumption)
+ * - \b GoogleSparseHashMapTraits: corresponds to google::sparse_hash_map (best memory consumption, relatively good performance)
+ *
+ * The default map implementation depends on the availability, and the preferred order is:
+ * GoogleSparseHashMapTraits, GnuHashMapTraits, and finally StdMapTraits.
+ *
+ * For performance and memory consumption reasons it is highly recommended to use one of
+ * the Google's hash_map implementation. To enable the support for them, you have two options:
+ * - \#include <google/dense_hash_map> yourself \b before Eigen/Sparse header
+ * - define EIGEN_GOOGLEHASH_SUPPORT
+ * In the later case the inclusion of <google/dense_hash_map> is made for you.
+ *
+ * \see http://code.google.com/p/google-sparsehash/
+ */
+template<typename SparseMatrixType,
+ template <typename T> class MapTraits =
+#if defined _DENSE_HASH_MAP_H_
+ GoogleDenseHashMapTraits
+#elif defined _HASH_MAP
+ GnuHashMapTraits
+#else
+ StdMapTraits
+#endif
+ ,int OuterPacketBits = 6>
+class RandomSetter
+{
+ typedef typename ei_traits<SparseMatrixType>::Scalar Scalar;
+ struct ScalarWrapper
+ {
+ ScalarWrapper() : value(0) {}
+ Scalar value;
+ };
+ typedef typename MapTraits<ScalarWrapper>::KeyType KeyType;
+ typedef typename MapTraits<ScalarWrapper>::Type HashMapType;
+ static const int OuterPacketMask = (1 << OuterPacketBits) - 1;
+ enum {
+ SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted,
+ TargetRowMajor = (SparseMatrixType::Flags & RowMajorBit) ? 1 : 0,
+ SetterRowMajor = SwapStorage ? 1-TargetRowMajor : TargetRowMajor,
+ IsUpperTriangular = SparseMatrixType::Flags & UpperTriangularBit,
+ IsLowerTriangular = SparseMatrixType::Flags & LowerTriangularBit
+ };
+
+ public:
+
+ /** Constructs a random setter object from the sparse matrix \a target
+ *
+ * Note that the initial value of \a target are imported. If you want to re-set
+ * a sparse matrix from scratch, then you must set it to zero first using the
+ * setZero() function.
+ */
+ inline RandomSetter(SparseMatrixType& target)
+ : mp_target(&target)
+ {
+ const int outerSize = SwapStorage ? target.innerSize() : target.outerSize();
+ const int innerSize = SwapStorage ? target.outerSize() : target.innerSize();
+ m_outerPackets = outerSize >> OuterPacketBits;
+ if (outerSize&OuterPacketMask)
+ m_outerPackets += 1;
+ m_hashmaps = new HashMapType[m_outerPackets];
+ // compute number of bits needed to store inner indices
+ int aux = innerSize - 1;
+ m_keyBitsOffset = 0;
+ while (aux)
+ {
+ ++m_keyBitsOffset;
+ aux = aux >> 1;
+ }
+ KeyType ik = (1<<(OuterPacketBits+m_keyBitsOffset));
+ for (int k=0; k<m_outerPackets; ++k)
+ MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k],ik);
+
+ // insert current coeffs
+ for (int j=0; j<mp_target->outerSize(); ++j)
+ for (typename SparseMatrixType::InnerIterator it(*mp_target,j); it; ++it)
+ (*this)(TargetRowMajor?j:it.index(), TargetRowMajor?it.index():j) = it.value();
+ }
+
+ /** Destructor updating back the sparse matrix target */
+ ~RandomSetter()
+ {
+ KeyType keyBitsMask = (1<<m_keyBitsOffset)-1;
+ if (!SwapStorage) // also means the map is sorted
+ {
+ mp_target->startFill(nonZeros());
+ for (int k=0; k<m_outerPackets; ++k)
+ {
+ const int outerOffset = (1<<OuterPacketBits) * k;
+ typename HashMapType::iterator end = m_hashmaps[k].end();
+ for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
+ {
+ const int outer = (it->first >> m_keyBitsOffset) + outerOffset;
+ const int inner = it->first & keyBitsMask;
+ mp_target->fill(TargetRowMajor ? outer : inner, TargetRowMajor ? inner : outer) = it->second.value;
+ }
+ }
+ mp_target->endFill();
+ }
+ else
+ {
+ VectorXi positions(mp_target->outerSize());
+ positions.setZero();
+ // pass 1
+ for (int k=0; k<m_outerPackets; ++k)
+ {
+ typename HashMapType::iterator end = m_hashmaps[k].end();
+ for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
+ {
+ const int outer = it->first & keyBitsMask;
+ ++positions[outer];
+ }
+ }
+ // prefix sum
+ int count = 0;
+ for (int j=0; j<mp_target->outerSize(); ++j)
+ {
+ int tmp = positions[j];
+ mp_target->_outerIndexPtr()[j] = count;
+ positions[j] = count;
+ count += tmp;
+ }
+ mp_target->_outerIndexPtr()[mp_target->outerSize()] = count;
+ mp_target->resizeNonZeros(count);
+ // pass 2
+ for (int k=0; k<m_outerPackets; ++k)
+ {
+ const int outerOffset = (1<<OuterPacketBits) * k;
+ typename HashMapType::iterator end = m_hashmaps[k].end();
+ for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
+ {
+ const int inner = (it->first >> m_keyBitsOffset) + outerOffset;
+ const int outer = it->first & keyBitsMask;
+ // sorted insertion
+ // Note that we have to deal with at most 2^OuterPacketBits unsorted coefficients,
+ // moreover those 2^OuterPacketBits coeffs are likely to be sparse, an so only a
+ // small fraction of them have to be sorted, whence the following simple procedure:
+ int posStart = mp_target->_outerIndexPtr()[outer];
+ int i = (positions[outer]++) - 1;
+ while ( (i >= posStart) && (mp_target->_innerIndexPtr()[i] > inner) )
+ {
+ mp_target->_valuePtr()[i+1] = mp_target->_valuePtr()[i];
+ mp_target->_innerIndexPtr()[i+1] = mp_target->_innerIndexPtr()[i];
+ --i;
+ }
+ mp_target->_innerIndexPtr()[i+1] = inner;
+ mp_target->_valuePtr()[i+1] = it->second.value;
+ }
+ }
+ }
+ delete[] m_hashmaps;
+ }
+
+ /** \returns a reference to the coefficient at given coordinates \a row, \a col */
+ Scalar& operator() (int row, int col)
+ {
+ ei_assert(((!IsUpperTriangular) || (row<=col)) && "Invalid access to an upper triangular matrix");
+ ei_assert(((!IsLowerTriangular) || (col<=row)) && "Invalid access to an upper triangular matrix");
+ const int outer = SetterRowMajor ? row : col;
+ const int inner = SetterRowMajor ? col : row;
+ const int outerMajor = outer >> OuterPacketBits; // index of the packet/map
+ const int outerMinor = outer & OuterPacketMask; // index of the inner vector in the packet
+ const KeyType key = (KeyType(outerMinor)<<m_keyBitsOffset) | inner;
+ return m_hashmaps[outerMajor][key].value;
+ }
+
+ /** \returns the number of non zero coefficients
+ *
+ * \note According to the underlying map/hash_map implementation,
+ * this function might be quite expensive.
+ */
+ int nonZeros() const
+ {
+ int nz = 0;
+ for (int k=0; k<m_outerPackets; ++k)
+ nz += m_hashmaps[k].size();
+ return nz;
+ }
+
+
+ protected:
+
+ HashMapType* m_hashmaps;
+ SparseMatrixType* mp_target;
+ int m_outerPackets;
+ unsigned char m_keyBitsOffset;
+};
+
+#endif // EIGEN_RANDOMSETTER_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseAssign.h b/extern/Eigen2/Eigen/src/Sparse/SparseAssign.h
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseAssign.h
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h b/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h
new file mode 100644
index 00000000000..c39066676b6
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h
@@ -0,0 +1,449 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_BLOCK_H
+#define EIGEN_SPARSE_BLOCK_H
+
+template<typename MatrixType, int Size>
+struct ei_traits<SparseInnerVectorSet<MatrixType, Size> >
+{
+ typedef typename ei_traits<MatrixType>::Scalar Scalar;
+ enum {
+ IsRowMajor = (int(MatrixType::Flags)&RowMajorBit)==RowMajorBit,
+ Flags = MatrixType::Flags,
+ RowsAtCompileTime = IsRowMajor ? Size : MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = IsRowMajor ? MatrixType::ColsAtCompileTime : Size,
+ CoeffReadCost = MatrixType::CoeffReadCost
+ };
+};
+
+template<typename MatrixType, int Size>
+class SparseInnerVectorSet : ei_no_assignment_operator,
+ public SparseMatrixBase<SparseInnerVectorSet<MatrixType, Size> >
+{
+ enum { IsRowMajor = ei_traits<SparseInnerVectorSet>::IsRowMajor };
+ public:
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseInnerVectorSet)
+ class InnerIterator: public MatrixType::InnerIterator
+ {
+ public:
+ inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
+ : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
+ {}
+ };
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)
+ : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
+ {
+ ei_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
+ }
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outer)
+ : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
+ {
+ ei_assert(Size!=Dynamic);
+ ei_assert( (outer>=0) && (outer<matrix.outerSize()) );
+ }
+
+// template<typename OtherDerived>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
+
+// template<typename Sparse>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
+
+ EIGEN_STRONG_INLINE int rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+ int m_outerStart;
+ const ei_int_if_dynamic<Size> m_outerSize;
+
+};
+
+/***************************************************************************
+* specialisation for DynamicSparseMatrix
+***************************************************************************/
+
+template<typename _Scalar, int _Options, int Size>
+class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size>
+ : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> >
+{
+ typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
+ enum { IsRowMajor = ei_traits<SparseInnerVectorSet>::IsRowMajor };
+ public:
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseInnerVectorSet)
+ class InnerIterator: public MatrixType::InnerIterator
+ {
+ public:
+ inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
+ : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
+ {}
+ };
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)
+ : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
+ {
+ ei_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
+ }
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outer)
+ : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
+ {
+ ei_assert(Size!=Dynamic);
+ ei_assert( (outer>=0) && (outer<matrix.outerSize()) );
+ }
+
+ template<typename OtherDerived>
+ inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
+ {
+ // need to transpose => perform a block evaluation followed by a big swap
+ DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
+ *this = aux.markAsRValue();
+ }
+ else
+ {
+ // evaluate/copy vector per vector
+ for (int j=0; j<m_outerSize.value(); ++j)
+ {
+ SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
+ m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
+ }
+ }
+ return *this;
+ }
+
+ inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
+ {
+ return operator=<SparseInnerVectorSet>(other);
+ }
+
+// template<typename Sparse>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
+
+ EIGEN_STRONG_INLINE int rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+ int m_outerStart;
+ const ei_int_if_dynamic<Size> m_outerSize;
+
+};
+
+
+/***************************************************************************
+* specialisation for SparseMatrix
+***************************************************************************/
+/*
+template<typename _Scalar, int _Options, int Size>
+class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options>, Size>
+ : public SparseMatrixBase<SparseInnerVectorSet<SparseMatrix<_Scalar, _Options>, Size> >
+{
+ typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
+ enum { IsRowMajor = ei_traits<SparseInnerVectorSet>::IsRowMajor };
+ public:
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseInnerVectorSet)
+ class InnerIterator: public MatrixType::InnerIterator
+ {
+ public:
+ inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
+ : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
+ {}
+ };
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)
+ : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
+ {
+ ei_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
+ }
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outer)
+ : m_matrix(matrix), m_outerStart(outer)
+ {
+ ei_assert(Size==1);
+ ei_assert( (outer>=0) && (outer<matrix.outerSize()) );
+ }
+
+ template<typename OtherDerived>
+ inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
+ {
+ // need to transpose => perform a block evaluation followed by a big swap
+ DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
+ *this = aux.markAsRValue();
+ }
+ else
+ {
+ // evaluate/copy vector per vector
+ for (int j=0; j<m_outerSize.value(); ++j)
+ {
+ SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
+ m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
+ }
+ }
+ return *this;
+ }
+
+ inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
+ {
+ return operator=<SparseInnerVectorSet>(other);
+ }
+
+ inline const Scalar* _valuePtr() const
+ { return m_matrix._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; }
+ inline const int* _innerIndexPtr() const
+ { return m_matrix._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; }
+ inline const int* _outerIndexPtr() const { return m_matrix._outerIndexPtr() + m_outerStart; }
+
+// template<typename Sparse>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
+
+ EIGEN_STRONG_INLINE int rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+ int m_outerStart;
+ const ei_int_if_dynamic<Size> m_outerSize;
+
+};
+*/
+//----------
+
+/** \returns the i-th row of the matrix \c *this. For row-major matrix only. */
+template<typename Derived>
+SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(int i)
+{
+ EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ return innerVector(i);
+}
+
+/** \returns the i-th row of the matrix \c *this. For row-major matrix only.
+ * (read-only version) */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(int i) const
+{
+ EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ return innerVector(i);
+}
+
+/** \returns the i-th column of the matrix \c *this. For column-major matrix only. */
+template<typename Derived>
+SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(int i)
+{
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
+ return innerVector(i);
+}
+
+/** \returns the i-th column of the matrix \c *this. For column-major matrix only.
+ * (read-only version) */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(int i) const
+{
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
+ return innerVector(i);
+}
+
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major).
+ */
+template<typename Derived>
+SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(int outer)
+{ return SparseInnerVectorSet<Derived,1>(derived(), outer); }
+
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major). Read-only.
+ */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(int outer) const
+{ return SparseInnerVectorSet<Derived,1>(derived(), outer); }
+
+//----------
+
+/** \returns the i-th row of the matrix \c *this. For row-major matrix only. */
+template<typename Derived>
+SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(int start, int size)
+{
+ EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the i-th row of the matrix \c *this. For row-major matrix only.
+ * (read-only version) */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(int start, int size) const
+{
+ EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the i-th column of the matrix \c *this. For column-major matrix only. */
+template<typename Derived>
+SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(int start, int size)
+{
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the i-th column of the matrix \c *this. For column-major matrix only.
+ * (read-only version) */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(int start, int size) const
+{
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major).
+ */
+template<typename Derived>
+SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(int outerStart, int outerSize)
+{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
+
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major). Read-only.
+ */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(int outerStart, int outerSize) const
+{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
+
+# if 0
+template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess>
+class Block<MatrixType,BlockRows,BlockCols,PacketAccess,IsSparse>
+ : public SparseMatrixBase<Block<MatrixType,BlockRows,BlockCols,PacketAccess,IsSparse> >
+{
+public:
+
+ _EIGEN_GENERIC_PUBLIC_INTERFACE(Block, SparseMatrixBase<Block>)
+ class InnerIterator;
+
+ /** Column or Row constructor
+ */
+ inline Block(const MatrixType& matrix, int i)
+ : m_matrix(matrix),
+ // It is a row if and only if BlockRows==1 and BlockCols==MatrixType::ColsAtCompileTime,
+ // and it is a column if and only if BlockRows==MatrixType::RowsAtCompileTime and BlockCols==1,
+ // all other cases are invalid.
+ // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
+ m_startRow( (BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0),
+ m_startCol( (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
+ m_blockRows(matrix.rows()), // if it is a row, then m_blockRows has a fixed-size of 1, so no pb to try to overwrite it
+ m_blockCols(matrix.cols()) // same for m_blockCols
+ {
+ ei_assert( (i>=0) && (
+ ((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
+ ||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
+ }
+
+ /** Fixed-size constructor
+ */
+ inline Block(const MatrixType& matrix, int startRow, int startCol)
+ : m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
+ m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
+ {
+ EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
+ ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
+ && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
+ }
+
+ /** Dynamic-size constructor
+ */
+ inline Block(const MatrixType& matrix,
+ int startRow, int startCol,
+ int blockRows, int blockCols)
+ : m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
+ m_blockRows(blockRows), m_blockCols(blockCols)
+ {
+ ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
+ && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
+ ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
+ && startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
+ }
+
+ inline int rows() const { return m_blockRows.value(); }
+ inline int cols() const { return m_blockCols.value(); }
+
+ inline int stride(void) const { return m_matrix.stride(); }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived()
+ .coeffRef(row + m_startRow.value(), col + m_startCol.value());
+ }
+
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
+ }
+
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived()
+ .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+
+ inline const Scalar coeff(int index) const
+ {
+ return m_matrix
+ .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+ const ei_int_if_dynamic<MatrixType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
+ const ei_int_if_dynamic<MatrixType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
+ const ei_int_if_dynamic<RowsAtCompileTime> m_blockRows;
+ const ei_int_if_dynamic<ColsAtCompileTime> m_blockCols;
+
+};
+#endif
+
+#endif // EIGEN_SPARSE_BLOCK_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h b/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h
new file mode 100644
index 00000000000..2206883cc76
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h
@@ -0,0 +1,175 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_CWISE_H
+#define EIGEN_SPARSE_CWISE_H
+
+/** \internal
+ * convenient macro to defined the return type of a cwise binary operation */
+#define EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(OP) \
+ CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived>
+
+#define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
+ SparseCwiseBinaryOp< \
+ ei_scalar_product_op< \
+ typename ei_scalar_product_traits< \
+ typename ei_traits<ExpressionType>::Scalar, \
+ typename ei_traits<OtherDerived>::Scalar \
+ >::ReturnType \
+ >, \
+ ExpressionType, \
+ OtherDerived \
+ >
+
+/** \internal
+ * convenient macro to defined the return type of a cwise unary operation */
+#define EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(OP) \
+ SparseCwiseUnaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType>
+
+/** \internal
+ * convenient macro to defined the return type of a cwise comparison to a scalar */
+/*#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
+ CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \
+ NestByValue<typename ExpressionType::ConstantReturnType> >*/
+
+template<typename ExpressionType> class SparseCwise
+{
+ public:
+
+ typedef typename ei_traits<ExpressionType>::Scalar Scalar;
+ typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
+ ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
+ typedef CwiseUnaryOp<ei_scalar_add_op<Scalar>, ExpressionType> ScalarAddReturnType;
+
+ inline SparseCwise(const ExpressionType& matrix) : m_matrix(matrix) {}
+
+ /** \internal */
+ inline const ExpressionType& _expression() const { return m_matrix; }
+
+ template<typename OtherDerived>
+ const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
+ operator*(const SparseMatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
+ operator*(const MatrixBase<OtherDerived> &other) const;
+
+// template<typename OtherDerived>
+// const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
+// operator/(const SparseMatrixBase<OtherDerived> &other) const;
+//
+// template<typename OtherDerived>
+// const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
+// operator/(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
+ min(const SparseMatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
+ max(const SparseMatrixBase<OtherDerived> &other) const;
+
+ const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op) abs() const;
+ const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op) abs2() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_square_op) square() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_cube_op) cube() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_inverse_op) inverse() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_sqrt_op) sqrt() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op) exp() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op) log() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op) cos() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op) sin() const;
+// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op) pow(const Scalar& exponent) const;
+
+ template<typename OtherDerived>
+ inline ExpressionType& operator*=(const SparseMatrixBase<OtherDerived> &other);
+
+// template<typename OtherDerived>
+// inline ExpressionType& operator/=(const SparseMatrixBase<OtherDerived> &other);
+
+ /*
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)
+ operator<(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)
+ operator<=(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)
+ operator>(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)
+ operator>=(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)
+ operator==(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)
+ operator!=(const MatrixBase<OtherDerived>& other) const;
+
+ // comparisons to a scalar value
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
+ operator<(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
+ operator<=(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
+ operator>(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
+ operator>=(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
+ operator==(Scalar s) const;
+
+ const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
+ operator!=(Scalar s) const;
+ */
+
+ // allow to extend SparseCwise outside Eigen
+ #ifdef EIGEN_SPARSE_CWISE_PLUGIN
+ #include EIGEN_SPARSE_CWISE_PLUGIN
+ #endif
+
+ protected:
+ ExpressionTypeNested m_matrix;
+};
+
+template<typename Derived>
+inline const SparseCwise<Derived>
+SparseMatrixBase<Derived>::cwise() const
+{
+ return derived();
+}
+
+template<typename Derived>
+inline SparseCwise<Derived>
+SparseMatrixBase<Derived>::cwise()
+{
+ return derived();
+}
+
+#endif // EIGEN_SPARSE_CWISE_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h
new file mode 100644
index 00000000000..d19970efcb1
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h
@@ -0,0 +1,442 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
+#define EIGEN_SPARSE_CWISE_BINARY_OP_H
+
+// Here we have to handle 3 cases:
+// 1 - sparse op dense
+// 2 - dense op sparse
+// 3 - sparse op sparse
+// We also need to implement a 4th iterator for:
+// 4 - dense op dense
+// Finally, we also need to distinguish between the product and other operations :
+// configuration returned mode
+// 1 - sparse op dense product sparse
+// generic dense
+// 2 - dense op sparse product sparse
+// generic dense
+// 3 - sparse op sparse product sparse
+// generic sparse
+// 4 - dense op dense product dense
+// generic dense
+
+template<typename BinaryOp, typename Lhs, typename Rhs>
+struct ei_traits<SparseCwiseBinaryOp<BinaryOp, Lhs, Rhs> >
+{
+ typedef typename ei_result_of<
+ BinaryOp(
+ typename Lhs::Scalar,
+ typename Rhs::Scalar
+ )
+ >::type Scalar;
+ typedef typename Lhs::Nested LhsNested;
+ typedef typename Rhs::Nested RhsNested;
+ typedef typename ei_unref<LhsNested>::type _LhsNested;
+ typedef typename ei_unref<RhsNested>::type _RhsNested;
+ enum {
+ LhsCoeffReadCost = _LhsNested::CoeffReadCost,
+ RhsCoeffReadCost = _RhsNested::CoeffReadCost,
+ LhsFlags = _LhsNested::Flags,
+ RhsFlags = _RhsNested::Flags,
+ RowsAtCompileTime = Lhs::RowsAtCompileTime,
+ ColsAtCompileTime = Lhs::ColsAtCompileTime,
+ MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime,
+ Flags = (int(LhsFlags) | int(RhsFlags)) & HereditaryBits,
+ CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
+ };
+};
+
+template<typename BinaryOp, typename Lhs, typename Rhs>
+class SparseCwiseBinaryOp : ei_no_assignment_operator,
+ public SparseMatrixBase<SparseCwiseBinaryOp<BinaryOp, Lhs, Rhs> >
+{
+ public:
+
+ class InnerIterator;
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseCwiseBinaryOp)
+ typedef typename ei_traits<SparseCwiseBinaryOp>::LhsNested LhsNested;
+ typedef typename ei_traits<SparseCwiseBinaryOp>::RhsNested RhsNested;
+ typedef typename ei_unref<LhsNested>::type _LhsNested;
+ typedef typename ei_unref<RhsNested>::type _RhsNested;
+
+ EIGEN_STRONG_INLINE SparseCwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
+ : m_lhs(lhs), m_rhs(rhs), m_functor(func)
+ {
+ EIGEN_STATIC_ASSERT((_LhsNested::Flags&RowMajorBit)==(_RhsNested::Flags&RowMajorBit),
+ BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER)
+ EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret
+ ? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret)
+ : int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+ // require the sizes to match
+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
+ ei_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
+ }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); }
+
+ EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
+ EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
+ EIGEN_STRONG_INLINE const BinaryOp& functor() const { return m_functor; }
+
+ protected:
+ const LhsNested m_lhs;
+ const RhsNested m_rhs;
+ const BinaryOp m_functor;
+};
+
+template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived,
+ int _LhsStorageMode = int(Lhs::Flags) & SparseBit,
+ int _RhsStorageMode = int(Rhs::Flags) & SparseBit>
+class ei_sparse_cwise_binary_op_inner_iterator_selector;
+
+template<typename BinaryOp, typename Lhs, typename Rhs>
+class SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator
+ : public ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs, typename SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator>
+{
+ public:
+ typedef ei_sparse_cwise_binary_op_inner_iterator_selector<
+ BinaryOp,Lhs,Rhs, InnerIterator> Base;
+
+ EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseBinaryOp& binOp, int outer)
+ : Base(binOp,outer)
+ {}
+};
+
+/***************************************************************************
+* Implementation of inner-iterators
+***************************************************************************/
+
+// template<typename T> struct ei_func_is_conjunction { enum { ret = false }; };
+// template<typename T> struct ei_func_is_conjunction<ei_scalar_product_op<T> > { enum { ret = true }; };
+
+// TODO generalize the ei_scalar_product_op specialization to all conjunctions if any !
+
+// sparse - sparse (generic)
+template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived>
+class ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, IsSparse, IsSparse>
+{
+ typedef SparseCwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
+ typedef typename ei_traits<CwiseBinaryXpr>::Scalar Scalar;
+ typedef typename ei_traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
+ typedef typename ei_traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
+ typedef typename _LhsNested::InnerIterator LhsIterator;
+ typedef typename _RhsNested::InnerIterator RhsIterator;
+ public:
+
+ EIGEN_STRONG_INLINE ei_sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, int outer)
+ : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
+ {
+ this->operator++();
+ }
+
+ EIGEN_STRONG_INLINE Derived& operator++()
+ {
+ if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
+ {
+ m_id = m_lhsIter.index();
+ m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
+ ++m_lhsIter;
+ ++m_rhsIter;
+ }
+ else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
+ {
+ m_id = m_lhsIter.index();
+ m_value = m_functor(m_lhsIter.value(), Scalar(0));
+ ++m_lhsIter;
+ }
+ else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
+ {
+ m_id = m_rhsIter.index();
+ m_value = m_functor(Scalar(0), m_rhsIter.value());
+ ++m_rhsIter;
+ }
+ else
+ {
+ m_id = -1;
+ }
+ return *static_cast<Derived*>(this);
+ }
+
+ EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
+
+ EIGEN_STRONG_INLINE int index() const { return m_id; }
+ EIGEN_STRONG_INLINE int row() const { return m_lhsIter.row(); }
+ EIGEN_STRONG_INLINE int col() const { return m_lhsIter.col(); }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; }
+
+ protected:
+ LhsIterator m_lhsIter;
+ RhsIterator m_rhsIter;
+ const BinaryOp& m_functor;
+ Scalar m_value;
+ int m_id;
+};
+
+// sparse - sparse (product)
+template<typename T, typename Lhs, typename Rhs, typename Derived>
+class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, IsSparse, IsSparse>
+{
+ typedef ei_scalar_product_op<T> BinaryFunc;
+ typedef SparseCwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
+ typedef typename CwiseBinaryXpr::Scalar Scalar;
+ typedef typename ei_traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
+ typedef typename _LhsNested::InnerIterator LhsIterator;
+ typedef typename ei_traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
+ typedef typename _RhsNested::InnerIterator RhsIterator;
+ public:
+
+ EIGEN_STRONG_INLINE ei_sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, int outer)
+ : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
+ {
+ while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
+ {
+ if (m_lhsIter.index() < m_rhsIter.index())
+ ++m_lhsIter;
+ else
+ ++m_rhsIter;
+ }
+ }
+
+ EIGEN_STRONG_INLINE Derived& operator++()
+ {
+ ++m_lhsIter;
+ ++m_rhsIter;
+ while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
+ {
+ if (m_lhsIter.index() < m_rhsIter.index())
+ ++m_lhsIter;
+ else
+ ++m_rhsIter;
+ }
+ return *static_cast<Derived*>(this);
+ }
+
+ EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
+
+ EIGEN_STRONG_INLINE int index() const { return m_lhsIter.index(); }
+ EIGEN_STRONG_INLINE int row() const { return m_lhsIter.row(); }
+ EIGEN_STRONG_INLINE int col() const { return m_lhsIter.col(); }
+
+ EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); }
+
+ protected:
+ LhsIterator m_lhsIter;
+ RhsIterator m_rhsIter;
+ const BinaryFunc& m_functor;
+};
+
+// sparse - dense (product)
+template<typename T, typename Lhs, typename Rhs, typename Derived>
+class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, IsSparse, IsDense>
+{
+ typedef ei_scalar_product_op<T> BinaryFunc;
+ typedef SparseCwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
+ typedef typename CwiseBinaryXpr::Scalar Scalar;
+ typedef typename ei_traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
+ typedef typename ei_traits<CwiseBinaryXpr>::RhsNested RhsNested;
+ typedef typename _LhsNested::InnerIterator LhsIterator;
+ enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit };
+ public:
+
+ EIGEN_STRONG_INLINE ei_sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, int outer)
+ : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer)
+ {}
+
+ EIGEN_STRONG_INLINE Derived& operator++()
+ {
+ ++m_lhsIter;
+ return *static_cast<Derived*>(this);
+ }
+
+ EIGEN_STRONG_INLINE Scalar value() const
+ { return m_functor(m_lhsIter.value(),
+ m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
+
+ EIGEN_STRONG_INLINE int index() const { return m_lhsIter.index(); }
+ EIGEN_STRONG_INLINE int row() const { return m_lhsIter.row(); }
+ EIGEN_STRONG_INLINE int col() const { return m_lhsIter.col(); }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; }
+
+ protected:
+ const RhsNested m_rhs;
+ LhsIterator m_lhsIter;
+ const BinaryFunc m_functor;
+ const int m_outer;
+};
+
+// sparse - dense (product)
+template<typename T, typename Lhs, typename Rhs, typename Derived>
+class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, IsDense, IsSparse>
+{
+ typedef ei_scalar_product_op<T> BinaryFunc;
+ typedef SparseCwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
+ typedef typename CwiseBinaryXpr::Scalar Scalar;
+ typedef typename ei_traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
+ typedef typename _RhsNested::InnerIterator RhsIterator;
+ enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit };
+ public:
+
+ EIGEN_STRONG_INLINE ei_sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, int outer)
+ : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
+ {}
+
+ EIGEN_STRONG_INLINE Derived& operator++()
+ {
+ ++m_rhsIter;
+ return *static_cast<Derived*>(this);
+ }
+
+ EIGEN_STRONG_INLINE Scalar value() const
+ { return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
+
+ EIGEN_STRONG_INLINE int index() const { return m_rhsIter.index(); }
+ EIGEN_STRONG_INLINE int row() const { return m_rhsIter.row(); }
+ EIGEN_STRONG_INLINE int col() const { return m_rhsIter.col(); }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; }
+
+ protected:
+ const CwiseBinaryXpr& m_xpr;
+ RhsIterator m_rhsIter;
+ const BinaryFunc& m_functor;
+ const int m_outer;
+};
+
+
+/***************************************************************************
+* Implementation of SparseMatrixBase and SparseCwise functions/operators
+***************************************************************************/
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const SparseCwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>,
+ Derived, OtherDerived>
+SparseMatrixBase<Derived>::operator-(const SparseMatrixBase<OtherDerived> &other) const
+{
+ return SparseCwiseBinaryOp<ei_scalar_difference_op<Scalar>,
+ Derived, OtherDerived>(derived(), other.derived());
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other)
+{
+ return *this = derived() - other.derived();
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const SparseCwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
+SparseMatrixBase<Derived>::operator+(const SparseMatrixBase<OtherDerived> &other) const
+{
+ return SparseCwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived());
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE Derived &
+SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other)
+{
+ return *this = derived() + other.derived();
+}
+
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
+SparseCwise<ExpressionType>::operator*(const SparseMatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
+}
+
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
+SparseCwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
+}
+
+// template<typename ExpressionType>
+// template<typename OtherDerived>
+// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
+// SparseCwise<ExpressionType>::operator/(const SparseMatrixBase<OtherDerived> &other) const
+// {
+// return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived());
+// }
+//
+// template<typename ExpressionType>
+// template<typename OtherDerived>
+// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
+// SparseCwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
+// {
+// return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived());
+// }
+
+template<typename ExpressionType>
+template<typename OtherDerived>
+inline ExpressionType& SparseCwise<ExpressionType>::operator*=(const SparseMatrixBase<OtherDerived> &other)
+{
+ return m_matrix.const_cast_derived() = _expression() * other.derived();
+}
+
+// template<typename ExpressionType>
+// template<typename OtherDerived>
+// inline ExpressionType& SparseCwise<ExpressionType>::operator/=(const SparseMatrixBase<OtherDerived> &other)
+// {
+// return m_matrix.const_cast_derived() = *this / other;
+// }
+
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
+SparseCwise<ExpressionType>::min(const SparseMatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived());
+}
+
+template<typename ExpressionType>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
+SparseCwise<ExpressionType>::max(const SparseMatrixBase<OtherDerived> &other) const
+{
+ return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived());
+}
+
+// template<typename Derived>
+// template<typename CustomBinaryOp, typename OtherDerived>
+// EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
+// SparseMatrixBase<Derived>::binaryExpr(const SparseMatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const
+// {
+// return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func);
+// }
+
+#endif // EIGEN_SPARSE_CWISE_BINARY_OP_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h
new file mode 100644
index 00000000000..b11c0f8a377
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h
@@ -0,0 +1,183 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H
+#define EIGEN_SPARSE_CWISE_UNARY_OP_H
+
+template<typename UnaryOp, typename MatrixType>
+struct ei_traits<SparseCwiseUnaryOp<UnaryOp, MatrixType> > : ei_traits<MatrixType>
+{
+ typedef typename ei_result_of<
+ UnaryOp(typename MatrixType::Scalar)
+ >::type Scalar;
+ typedef typename MatrixType::Nested MatrixTypeNested;
+ typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
+ enum {
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost
+ };
+};
+
+template<typename UnaryOp, typename MatrixType>
+class SparseCwiseUnaryOp : ei_no_assignment_operator,
+ public SparseMatrixBase<SparseCwiseUnaryOp<UnaryOp, MatrixType> >
+{
+ public:
+
+ class InnerIterator;
+// typedef typename ei_unref<LhsNested>::type _LhsNested;
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseCwiseUnaryOp)
+
+ inline SparseCwiseUnaryOp(const MatrixType& mat, const UnaryOp& func = UnaryOp())
+ : m_matrix(mat), m_functor(func) {}
+
+ EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); }
+
+// EIGEN_STRONG_INLINE const typename MatrixType::Nested& _matrix() const { return m_matrix; }
+// EIGEN_STRONG_INLINE const UnaryOp& _functor() const { return m_functor; }
+
+ protected:
+ const typename MatrixType::Nested m_matrix;
+ const UnaryOp m_functor;
+};
+
+
+template<typename UnaryOp, typename MatrixType>
+class SparseCwiseUnaryOp<UnaryOp,MatrixType>::InnerIterator
+{
+ typedef typename SparseCwiseUnaryOp::Scalar Scalar;
+ typedef typename ei_traits<SparseCwiseUnaryOp>::_MatrixTypeNested _MatrixTypeNested;
+ typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator;
+ public:
+
+ EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseUnaryOp& unaryOp, int outer)
+ : m_iter(unaryOp.m_matrix,outer), m_functor(unaryOp.m_functor)
+ {}
+
+ EIGEN_STRONG_INLINE InnerIterator& operator++()
+ { ++m_iter; return *this; }
+
+ EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_iter.value()); }
+
+ EIGEN_STRONG_INLINE int index() const { return m_iter.index(); }
+ EIGEN_STRONG_INLINE int row() const { return m_iter.row(); }
+ EIGEN_STRONG_INLINE int col() const { return m_iter.col(); }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_iter; }
+
+ protected:
+ MatrixTypeIterator m_iter;
+ const UnaryOp m_functor;
+};
+
+template<typename Derived>
+template<typename CustomUnaryOp>
+EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<CustomUnaryOp, Derived>
+SparseMatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const
+{
+ return SparseCwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func);
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived>
+SparseMatrixBase<Derived>::operator-() const
+{
+ return derived();
+}
+
+template<typename ExpressionType>
+EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op)
+SparseCwise<ExpressionType>::abs() const
+{
+ return _expression();
+}
+
+template<typename ExpressionType>
+EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op)
+SparseCwise<ExpressionType>::abs2() const
+{
+ return _expression();
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE typename SparseMatrixBase<Derived>::ConjugateReturnType
+SparseMatrixBase<Derived>::conjugate() const
+{
+ return ConjugateReturnType(derived());
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename SparseMatrixBase<Derived>::RealReturnType
+SparseMatrixBase<Derived>::real() const { return derived(); }
+
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename SparseMatrixBase<Derived>::ImagReturnType
+SparseMatrixBase<Derived>::imag() const { return derived(); }
+
+template<typename Derived>
+template<typename NewType>
+EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived>
+SparseMatrixBase<Derived>::cast() const
+{
+ return derived();
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
+SparseMatrixBase<Derived>::operator*(const Scalar& scalar) const
+{
+ return SparseCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived>
+ (derived(), ei_scalar_multiple_op<Scalar>(scalar));
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
+SparseMatrixBase<Derived>::operator/(const Scalar& scalar) const
+{
+ return SparseCwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived>
+ (derived(), ei_scalar_quotient1_op<Scalar>(scalar));
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived&
+SparseMatrixBase<Derived>::operator*=(const Scalar& other)
+{
+ for (int j=0; j<outerSize(); ++j)
+ for (typename Derived::InnerIterator i(derived(),j); i; ++i)
+ i.valueRef() *= other;
+ return derived();
+}
+
+template<typename Derived>
+EIGEN_STRONG_INLINE Derived&
+SparseMatrixBase<Derived>::operator/=(const Scalar& other)
+{
+ for (int j=0; j<outerSize(); ++j)
+ for (typename Derived::InnerIterator i(derived(),j); i; ++i)
+ i.valueRef() /= other;
+ return derived();
+}
+
+#endif // EIGEN_SPARSE_CWISE_UNARY_OP_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h b/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h
new file mode 100644
index 00000000000..932daf220b9
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h
@@ -0,0 +1,157 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H
+#define EIGEN_SPARSE_DIAGONAL_PRODUCT_H
+
+// the product a diagonal matrix with a sparse matrix can be easily
+// implemented using expression template. We have two very different cases:
+// 1 - diag * row-major sparse
+// => each inner vector <=> scalar * sparse vector product
+// => so we can reuse CwiseUnaryOp::InnerIterator
+// 2 - diag * col-major sparse
+// => each inner vector <=> densevector * sparse vector cwise product
+// => again, we can reuse specialization of CwiseBinaryOp::InnerIterator
+// for that particular case
+// The two other cases are symmetric.
+
+template<typename Lhs, typename Rhs>
+struct ei_traits<SparseDiagonalProduct<Lhs, Rhs> > : ei_traits<SparseProduct<Lhs, Rhs, DiagonalProduct> >
+{
+ typedef typename ei_cleantype<Lhs>::type _Lhs;
+ typedef typename ei_cleantype<Rhs>::type _Rhs;
+ enum {
+ SparseFlags = ((int(_Lhs::Flags)&Diagonal)==Diagonal) ? int(_Rhs::Flags) : int(_Lhs::Flags),
+ Flags = SparseBit | (SparseFlags&RowMajorBit)
+ };
+};
+
+enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor};
+template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode>
+class ei_sparse_diagonal_product_inner_iterator_selector;
+
+template<typename LhsNested, typename RhsNested>
+class SparseDiagonalProduct : public SparseMatrixBase<SparseDiagonalProduct<LhsNested,RhsNested> >, ei_no_assignment_operator
+{
+ typedef typename ei_traits<SparseDiagonalProduct>::_LhsNested _LhsNested;
+ typedef typename ei_traits<SparseDiagonalProduct>::_RhsNested _RhsNested;
+
+ enum {
+ LhsMode = (_LhsNested::Flags&Diagonal)==Diagonal ? SDP_IsDiagonal
+ : (_LhsNested::Flags&RowMajorBit) ? SDP_IsSparseRowMajor : SDP_IsSparseColMajor,
+ RhsMode = (_RhsNested::Flags&Diagonal)==Diagonal ? SDP_IsDiagonal
+ : (_RhsNested::Flags&RowMajorBit) ? SDP_IsSparseRowMajor : SDP_IsSparseColMajor
+ };
+
+ public:
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseDiagonalProduct)
+
+ typedef ei_sparse_diagonal_product_inner_iterator_selector
+ <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
+
+ template<typename Lhs, typename Rhs>
+ EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
+ : m_lhs(lhs), m_rhs(rhs)
+ {
+ ei_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
+ }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_rhs.cols(); }
+
+ EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
+ EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
+
+ protected:
+ LhsNested m_lhs;
+ RhsNested m_rhs;
+};
+
+
+template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
+class ei_sparse_diagonal_product_inner_iterator_selector
+<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor>
+ : public SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator
+{
+ typedef typename SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator Base;
+ public:
+ inline ei_sparse_diagonal_product_inner_iterator_selector(
+ const SparseDiagonalProductType& expr, int outer)
+ : Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer)
+ {}
+};
+
+template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
+class ei_sparse_diagonal_product_inner_iterator_selector
+<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
+ : public SparseCwiseBinaryOp<
+ ei_scalar_product_op<typename Lhs::Scalar>,
+ SparseInnerVectorSet<Rhs,1>,
+ typename Lhs::_CoeffsVectorType>::InnerIterator
+{
+ typedef typename SparseCwiseBinaryOp<
+ ei_scalar_product_op<typename Lhs::Scalar>,
+ SparseInnerVectorSet<Rhs,1>,
+ typename Lhs::_CoeffsVectorType>::InnerIterator Base;
+ public:
+ inline ei_sparse_diagonal_product_inner_iterator_selector(
+ const SparseDiagonalProductType& expr, int outer)
+ : Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0)
+ {}
+};
+
+template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
+class ei_sparse_diagonal_product_inner_iterator_selector
+<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal>
+ : public SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator
+{
+ typedef typename SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator Base;
+ public:
+ inline ei_sparse_diagonal_product_inner_iterator_selector(
+ const SparseDiagonalProductType& expr, int outer)
+ : Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer)
+ {}
+};
+
+template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
+class ei_sparse_diagonal_product_inner_iterator_selector
+<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
+ : public SparseCwiseBinaryOp<
+ ei_scalar_product_op<typename Rhs::Scalar>,
+ SparseInnerVectorSet<Lhs,1>,
+ NestByValue<Transpose<typename Rhs::_CoeffsVectorType> > >::InnerIterator
+{
+ typedef typename SparseCwiseBinaryOp<
+ ei_scalar_product_op<typename Rhs::Scalar>,
+ SparseInnerVectorSet<Lhs,1>,
+ NestByValue<Transpose<typename Rhs::_CoeffsVectorType> > >::InnerIterator Base;
+ public:
+ inline ei_sparse_diagonal_product_inner_iterator_selector(
+ const SparseDiagonalProductType& expr, int outer)
+ : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose().nestByValue(), 0)
+ {}
+};
+
+#endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseDot.h b/extern/Eigen2/Eigen/src/Sparse/SparseDot.h
new file mode 100644
index 00000000000..7a26e0f4ba5
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseDot.h
@@ -0,0 +1,97 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_DOT_H
+#define EIGEN_SPARSE_DOT_H
+
+template<typename Derived>
+template<typename OtherDerived>
+typename ei_traits<Derived>::Scalar
+SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
+ EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+
+ ei_assert(size() == other.size());
+ ei_assert(other.size()>0 && "you are using a non initialized vector");
+
+ typename Derived::InnerIterator i(derived(),0);
+ Scalar res = 0;
+ while (i)
+ {
+ res += i.value() * ei_conj(other.coeff(i.index()));
+ ++i;
+ }
+ return res;
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+typename ei_traits<Derived>::Scalar
+SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
+ EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+
+ ei_assert(size() == other.size());
+
+ typename Derived::InnerIterator i(derived(),0);
+ typename OtherDerived::InnerIterator j(other.derived(),0);
+ Scalar res = 0;
+ while (i && j)
+ {
+ if (i.index()==j.index())
+ {
+ res += i.value() * ei_conj(j.value());
+ ++i; ++j;
+ }
+ else if (i.index()<j.index())
+ ++i;
+ else
+ ++j;
+ }
+ return res;
+}
+
+template<typename Derived>
+inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
+SparseMatrixBase<Derived>::squaredNorm() const
+{
+ return ei_real((*this).cwise().abs2().sum());
+}
+
+template<typename Derived>
+inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
+SparseMatrixBase<Derived>::norm() const
+{
+ return ei_sqrt(squaredNorm());
+}
+
+#endif // EIGEN_SPARSE_DOT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h b/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h
new file mode 100644
index 00000000000..c47e162f538
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h
@@ -0,0 +1,97 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_FLAGGED_H
+#define EIGEN_SPARSE_FLAGGED_H
+
+template<typename ExpressionType, unsigned int Added, unsigned int Removed>
+struct ei_traits<SparseFlagged<ExpressionType, Added, Removed> > : ei_traits<ExpressionType>
+{
+ enum { Flags = (ExpressionType::Flags | Added) & ~Removed };
+};
+
+template<typename ExpressionType, unsigned int Added, unsigned int Removed> class SparseFlagged
+ : public SparseMatrixBase<SparseFlagged<ExpressionType, Added, Removed> >
+{
+ public:
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseFlagged)
+ class InnerIterator;
+ class ReverseInnerIterator;
+
+ typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
+ ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
+
+ inline SparseFlagged(const ExpressionType& matrix) : m_matrix(matrix) {}
+
+ inline int rows() const { return m_matrix.rows(); }
+ inline int cols() const { return m_matrix.cols(); }
+
+ // FIXME should be keep them ?
+ inline Scalar& coeffRef(int row, int col)
+ { return m_matrix.const_cast_derived().coeffRef(col, row); }
+
+ inline const Scalar coeff(int row, int col) const
+ { return m_matrix.coeff(col, row); }
+
+ inline const Scalar coeff(int index) const
+ { return m_matrix.coeff(index); }
+
+ inline Scalar& coeffRef(int index)
+ { return m_matrix.const_cast_derived().coeffRef(index); }
+
+ protected:
+ ExpressionTypeNested m_matrix;
+};
+
+template<typename ExpressionType, unsigned int Added, unsigned int Removed>
+ class SparseFlagged<ExpressionType,Added,Removed>::InnerIterator : public ExpressionType::InnerIterator
+{
+ public:
+
+ EIGEN_STRONG_INLINE InnerIterator(const SparseFlagged& xpr, int outer)
+ : ExpressionType::InnerIterator(xpr.m_matrix, outer)
+ {}
+};
+
+template<typename ExpressionType, unsigned int Added, unsigned int Removed>
+ class SparseFlagged<ExpressionType,Added,Removed>::ReverseInnerIterator : public ExpressionType::ReverseInnerIterator
+{
+ public:
+
+ EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseFlagged& xpr, int outer)
+ : ExpressionType::ReverseInnerIterator(xpr.m_matrix, outer)
+ {}
+};
+
+template<typename Derived>
+template<unsigned int Added>
+inline const SparseFlagged<Derived, Added, 0>
+SparseMatrixBase<Derived>::marked() const
+{
+ return derived();
+}
+
+#endif // EIGEN_SPARSE_FLAGGED_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseFuzzy.h b/extern/Eigen2/Eigen/src/Sparse/SparseFuzzy.h
new file mode 100644
index 00000000000..355f4d52eab
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseFuzzy.h
@@ -0,0 +1,41 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_FUZZY_H
+#define EIGEN_SPARSE_FUZZY_H
+
+// template<typename Derived>
+// template<typename OtherDerived>
+// bool SparseMatrixBase<Derived>::isApprox(
+// const OtherDerived& other,
+// typename NumTraits<Scalar>::Real prec
+// ) const
+// {
+// const typename ei_nested<Derived,2>::type nested(derived());
+// const typename ei_nested<OtherDerived,2>::type otherNested(other.derived());
+// return (nested - otherNested).cwise().abs2().sum()
+// <= prec * prec * std::min(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum());
+// }
+
+#endif // EIGEN_SPARSE_FUZZY_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseLDLT.h b/extern/Eigen2/Eigen/src/Sparse/SparseLDLT.h
new file mode 100644
index 00000000000..a1bac4d084d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseLDLT.h
@@ -0,0 +1,346 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+/*
+
+NOTE: the _symbolic, and _numeric functions has been adapted from
+ the LDL library:
+
+LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved.
+
+LDL License:
+
+ Your use or distribution of LDL or any modified version of
+ LDL implies that you agree to this License.
+
+ This library 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 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that 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 this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+ Permission is hereby granted to use or copy this program under the
+ terms of the GNU LGPL, provided that the Copyright, this License,
+ and the Availability of the original version is retained on all copies.
+ User documentation of any code that uses this code or any modified
+ version of this code must cite the Copyright, this License, the
+ Availability note, and "Used by permission." Permission to modify
+ the code and to distribute modified code is granted, provided the
+ Copyright, this License, and the Availability note are retained,
+ and a notice that the code was modified is included.
+ */
+
+#ifndef EIGEN_SPARSELDLT_H
+#define EIGEN_SPARSELDLT_H
+
+/** \ingroup Sparse_Module
+ *
+ * \class SparseLDLT
+ *
+ * \brief LDLT Cholesky decomposition of a sparse matrix and associated features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the LDLT Cholesky decomposition
+ *
+ * \sa class LDLT, class LDLT
+ */
+template<typename MatrixType, int Backend = DefaultBackend>
+class SparseLDLT
+{
+ protected:
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> CholMatrixType;
+ typedef Matrix<Scalar,MatrixType::ColsAtCompileTime,1> VectorType;
+
+ enum {
+ SupernodalFactorIsDirty = 0x10000,
+ MatrixLIsDirty = 0x20000
+ };
+
+ public:
+
+ /** Creates a dummy LDLT factorization object with flags \a flags. */
+ SparseLDLT(int flags = 0)
+ : m_flags(flags), m_status(0)
+ {
+ ei_assert((MatrixType::Flags&RowMajorBit)==0);
+ m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ }
+
+ /** Creates a LDLT object and compute the respective factorization of \a matrix using
+ * flags \a flags. */
+ SparseLDLT(const MatrixType& matrix, int flags = 0)
+ : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
+ {
+ ei_assert((MatrixType::Flags&RowMajorBit)==0);
+ m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ compute(matrix);
+ }
+
+ /** Sets the relative threshold value used to prune zero coefficients during the decomposition.
+ *
+ * Setting a value greater than zero speeds up computation, and yields to an imcomplete
+ * factorization with fewer non zero coefficients. Such approximate factors are especially
+ * useful to initialize an iterative solver.
+ *
+ * \warning if precision is greater that zero, the LDLT factorization is not guaranteed to succeed
+ * even if the matrix is positive definite.
+ *
+ * Note that the exact meaning of this parameter might depends on the actual
+ * backend. Moreover, not all backends support this feature.
+ *
+ * \sa precision() */
+ void setPrecision(RealScalar v) { m_precision = v; }
+
+ /** \returns the current precision.
+ *
+ * \sa setPrecision() */
+ RealScalar precision() const { return m_precision; }
+
+ /** Sets the flags. Possible values are:
+ * - CompleteFactorization
+ * - IncompleteFactorization
+ * - MemoryEfficient (hint to use the memory most efficient method offered by the backend)
+ * - SupernodalMultifrontal (implies a complete factorization if supported by the backend,
+ * overloads the MemoryEfficient flags)
+ * - SupernodalLeftLooking (implies a complete factorization if supported by the backend,
+ * overloads the MemoryEfficient flags)
+ *
+ * \sa flags() */
+ void settagss(int f) { m_flags = f; }
+ /** \returns the current flags */
+ int flags() const { return m_flags; }
+
+ /** Computes/re-computes the LDLT factorization */
+ void compute(const MatrixType& matrix);
+
+ /** Perform a symbolic factorization */
+ void _symbolic(const MatrixType& matrix);
+ /** Perform the actual factorization using the previously
+ * computed symbolic factorization */
+ bool _numeric(const MatrixType& matrix);
+
+ /** \returns the lower triangular matrix L */
+ inline const CholMatrixType& matrixL(void) const { return m_matrix; }
+
+ /** \returns the coefficients of the diagonal matrix D */
+ inline VectorType vectorD(void) const { return m_diag; }
+
+ template<typename Derived>
+ bool solveInPlace(MatrixBase<Derived> &b) const;
+
+ /** \returns true if the factorization succeeded */
+ inline bool succeeded(void) const { return m_succeeded; }
+
+ protected:
+ CholMatrixType m_matrix;
+ VectorType m_diag;
+ VectorXi m_parent; // elimination tree
+ VectorXi m_nonZerosPerCol;
+// VectorXi m_w; // workspace
+ RealScalar m_precision;
+ int m_flags;
+ mutable int m_status;
+ bool m_succeeded;
+};
+
+/** Computes / recomputes the LDLT decomposition of matrix \a a
+ * using the default algorithm.
+ */
+template<typename MatrixType, int Backend>
+void SparseLDLT<MatrixType,Backend>::compute(const MatrixType& a)
+{
+ _symbolic(a);
+ m_succeeded = _numeric(a);
+}
+
+template<typename MatrixType, int Backend>
+void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
+{
+ assert(a.rows()==a.cols());
+ const int size = a.rows();
+ m_matrix.resize(size, size);
+ m_parent.resize(size);
+ m_nonZerosPerCol.resize(size);
+ int * tags = ei_aligned_stack_new(int, size);
+
+ const int* Ap = a._outerIndexPtr();
+ const int* Ai = a._innerIndexPtr();
+ int* Lp = m_matrix._outerIndexPtr();
+ const int* P = 0;
+ int* Pinv = 0;
+
+ if (P)
+ {
+ /* If P is present then compute Pinv, the inverse of P */
+ for (int k = 0; k < size; ++k)
+ Pinv[P[k]] = k;
+ }
+ for (int k = 0; k < size; ++k)
+ {
+ /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */
+ m_parent[k] = -1; /* parent of k is not yet known */
+ tags[k] = k; /* mark node k as visited */
+ m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */
+ int kk = P ? P[k] : k; /* kth original, or permuted, column */
+ int p2 = Ap[kk+1];
+ for (int p = Ap[kk]; p < p2; ++p)
+ {
+ /* A (i,k) is nonzero (original or permuted A) */
+ int i = Pinv ? Pinv[Ai[p]] : Ai[p];
+ if (i < k)
+ {
+ /* follow path from i to root of etree, stop at flagged node */
+ for (; tags[i] != k; i = m_parent[i])
+ {
+ /* find parent of i if not yet determined */
+ if (m_parent[i] == -1)
+ m_parent[i] = k;
+ ++m_nonZerosPerCol[i]; /* L (k,i) is nonzero */
+ tags[i] = k; /* mark i as visited */
+ }
+ }
+ }
+ }
+ /* construct Lp index array from m_nonZerosPerCol column counts */
+ Lp[0] = 0;
+ for (int k = 0; k < size; ++k)
+ Lp[k+1] = Lp[k] + m_nonZerosPerCol[k];
+
+ m_matrix.resizeNonZeros(Lp[size]);
+ ei_aligned_stack_delete(int, tags, size);
+}
+
+template<typename MatrixType, int Backend>
+bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
+{
+ assert(a.rows()==a.cols());
+ const int size = a.rows();
+ assert(m_parent.size()==size);
+ assert(m_nonZerosPerCol.size()==size);
+
+ const int* Ap = a._outerIndexPtr();
+ const int* Ai = a._innerIndexPtr();
+ const Scalar* Ax = a._valuePtr();
+ const int* Lp = m_matrix._outerIndexPtr();
+ int* Li = m_matrix._innerIndexPtr();
+ Scalar* Lx = m_matrix._valuePtr();
+ m_diag.resize(size);
+
+ Scalar * y = ei_aligned_stack_new(Scalar, size);
+ int * pattern = ei_aligned_stack_new(int, size);
+ int * tags = ei_aligned_stack_new(int, size);
+
+ const int* P = 0;
+ const int* Pinv = 0;
+ bool ok = true;
+
+ for (int k = 0; k < size; ++k)
+ {
+ /* compute nonzero pattern of kth row of L, in topological order */
+ y[k] = 0.0; /* Y(0:k) is now all zero */
+ int top = size; /* stack for pattern is empty */
+ tags[k] = k; /* mark node k as visited */
+ m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */
+ int kk = (P) ? (P[k]) : (k); /* kth original, or permuted, column */
+ int p2 = Ap[kk+1];
+ for (int p = Ap[kk]; p < p2; ++p)
+ {
+ int i = Pinv ? Pinv[Ai[p]] : Ai[p]; /* get A(i,k) */
+ if (i <= k)
+ {
+ y[i] += Ax[p]; /* scatter A(i,k) into Y (sum duplicates) */
+ int len;
+ for (len = 0; tags[i] != k; i = m_parent[i])
+ {
+ pattern[len++] = i; /* L(k,i) is nonzero */
+ tags[i] = k; /* mark i as visited */
+ }
+ while (len > 0)
+ pattern[--top] = pattern[--len];
+ }
+ }
+ /* compute numerical values kth row of L (a sparse triangular solve) */
+ m_diag[k] = y[k]; /* get D(k,k) and clear Y(k) */
+ y[k] = 0.0;
+ for (; top < size; ++top)
+ {
+ int i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */
+ Scalar yi = y[i]; /* get and clear Y(i) */
+ y[i] = 0.0;
+ int p2 = Lp[i] + m_nonZerosPerCol[i];
+ int p;
+ for (p = Lp[i]; p < p2; ++p)
+ y[Li[p]] -= Lx[p] * yi;
+ Scalar l_ki = yi / m_diag[i]; /* the nonzero entry L(k,i) */
+ m_diag[k] -= l_ki * yi;
+ Li[p] = k; /* store L(k,i) in column form of L */
+ Lx[p] = l_ki;
+ ++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */
+ }
+ if (m_diag[k] == 0.0)
+ {
+ ok = false; /* failure, D(k,k) is zero */
+ break;
+ }
+ }
+
+ ei_aligned_stack_delete(Scalar, y, size);
+ ei_aligned_stack_delete(int, pattern, size);
+ ei_aligned_stack_delete(int, tags, size);
+
+ return ok; /* success, diagonal of D is all nonzero */
+}
+
+/** Computes b = L^-T L^-1 b */
+template<typename MatrixType, int Backend>
+template<typename Derived>
+bool SparseLDLT<MatrixType, Backend>::solveInPlace(MatrixBase<Derived> &b) const
+{
+ const int size = m_matrix.rows();
+ ei_assert(size==b.rows());
+ if (!m_succeeded)
+ return false;
+
+ if (m_matrix.nonZeros()>0) // otherwise L==I
+ m_matrix.solveTriangularInPlace(b);
+ b = b.cwise() / m_diag;
+ // FIXME should be .adjoint() but it fails to compile...
+
+ if (m_matrix.nonZeros()>0) // otherwise L==I
+ m_matrix.transpose().solveTriangularInPlace(b);
+
+ return true;
+}
+
+#endif // EIGEN_SPARSELDLT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseLLT.h b/extern/Eigen2/Eigen/src/Sparse/SparseLLT.h
new file mode 100644
index 00000000000..e7c314c2cad
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseLLT.h
@@ -0,0 +1,205 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSELLT_H
+#define EIGEN_SPARSELLT_H
+
+/** \ingroup Sparse_Module
+ *
+ * \class SparseLLT
+ *
+ * \brief LLT Cholesky decomposition of a sparse matrix and associated features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the LLT Cholesky decomposition
+ *
+ * \sa class LLT, class LDLT
+ */
+template<typename MatrixType, int Backend = DefaultBackend>
+class SparseLLT
+{
+ protected:
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef SparseMatrix<Scalar,LowerTriangular> CholMatrixType;
+
+ enum {
+ SupernodalFactorIsDirty = 0x10000,
+ MatrixLIsDirty = 0x20000
+ };
+
+ public:
+
+ /** Creates a dummy LLT factorization object with flags \a flags. */
+ SparseLLT(int flags = 0)
+ : m_flags(flags), m_status(0)
+ {
+ m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ }
+
+ /** Creates a LLT object and compute the respective factorization of \a matrix using
+ * flags \a flags. */
+ SparseLLT(const MatrixType& matrix, int flags = 0)
+ : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
+ {
+ m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ compute(matrix);
+ }
+
+ /** Sets the relative threshold value used to prune zero coefficients during the decomposition.
+ *
+ * Setting a value greater than zero speeds up computation, and yields to an imcomplete
+ * factorization with fewer non zero coefficients. Such approximate factors are especially
+ * useful to initialize an iterative solver.
+ *
+ * \warning if precision is greater that zero, the LLT factorization is not guaranteed to succeed
+ * even if the matrix is positive definite.
+ *
+ * Note that the exact meaning of this parameter might depends on the actual
+ * backend. Moreover, not all backends support this feature.
+ *
+ * \sa precision() */
+ void setPrecision(RealScalar v) { m_precision = v; }
+
+ /** \returns the current precision.
+ *
+ * \sa setPrecision() */
+ RealScalar precision() const { return m_precision; }
+
+ /** Sets the flags. Possible values are:
+ * - CompleteFactorization
+ * - IncompleteFactorization
+ * - MemoryEfficient (hint to use the memory most efficient method offered by the backend)
+ * - SupernodalMultifrontal (implies a complete factorization if supported by the backend,
+ * overloads the MemoryEfficient flags)
+ * - SupernodalLeftLooking (implies a complete factorization if supported by the backend,
+ * overloads the MemoryEfficient flags)
+ *
+ * \sa flags() */
+ void setFlags(int f) { m_flags = f; }
+ /** \returns the current flags */
+ int flags() const { return m_flags; }
+
+ /** Computes/re-computes the LLT factorization */
+ void compute(const MatrixType& matrix);
+
+ /** \returns the lower triangular matrix L */
+ inline const CholMatrixType& matrixL(void) const { return m_matrix; }
+
+ template<typename Derived>
+ bool solveInPlace(MatrixBase<Derived> &b) const;
+
+ /** \returns true if the factorization succeeded */
+ inline bool succeeded(void) const { return m_succeeded; }
+
+ protected:
+ CholMatrixType m_matrix;
+ RealScalar m_precision;
+ int m_flags;
+ mutable int m_status;
+ bool m_succeeded;
+};
+
+/** Computes / recomputes the LLT decomposition of matrix \a a
+ * using the default algorithm.
+ */
+template<typename MatrixType, int Backend>
+void SparseLLT<MatrixType,Backend>::compute(const MatrixType& a)
+{
+ assert(a.rows()==a.cols());
+ const int size = a.rows();
+ m_matrix.resize(size, size);
+
+ // allocate a temporary vector for accumulations
+ AmbiVector<Scalar> tempVector(size);
+ RealScalar density = a.nonZeros()/RealScalar(size*size);
+
+ // TODO estimate the number of non zeros
+ m_matrix.startFill(a.nonZeros()*2);
+ for (int j = 0; j < size; ++j)
+ {
+ Scalar x = ei_real(a.coeff(j,j));
+
+ // TODO better estimate of the density !
+ tempVector.init(density>0.001? IsDense : IsSparse);
+ tempVector.setBounds(j+1,size);
+ tempVector.setZero();
+ // init with current matrix a
+ {
+ typename MatrixType::InnerIterator it(a,j);
+ ++it; // skip diagonal element
+ for (; it; ++it)
+ tempVector.coeffRef(it.index()) = it.value();
+ }
+ for (int k=0; k<j+1; ++k)
+ {
+ typename CholMatrixType::InnerIterator it(m_matrix, k);
+ while (it && it.index()<j)
+ ++it;
+ if (it && it.index()==j)
+ {
+ Scalar y = it.value();
+ x -= ei_abs2(y);
+ ++it; // skip j-th element, and process remaining column coefficients
+ tempVector.restart();
+ for (; it; ++it)
+ {
+ tempVector.coeffRef(it.index()) -= it.value() * y;
+ }
+ }
+ }
+ // copy the temporary vector to the respective m_matrix.col()
+ // while scaling the result by 1/real(x)
+ RealScalar rx = ei_sqrt(ei_real(x));
+ m_matrix.fill(j,j) = rx;
+ Scalar y = Scalar(1)/rx;
+ for (typename AmbiVector<Scalar>::Iterator it(tempVector, m_precision*rx); it; ++it)
+ {
+ m_matrix.fill(it.index(), j) = it.value() * y;
+ }
+ }
+ m_matrix.endFill();
+}
+
+/** Computes b = L^-T L^-1 b */
+template<typename MatrixType, int Backend>
+template<typename Derived>
+bool SparseLLT<MatrixType, Backend>::solveInPlace(MatrixBase<Derived> &b) const
+{
+ const int size = m_matrix.rows();
+ ei_assert(size==b.rows());
+
+ m_matrix.solveTriangularInPlace(b);
+ // FIXME should be simply .adjoint() but it fails to compile...
+ if (NumTraits<Scalar>::IsComplex)
+ {
+ CholMatrixType aux = m_matrix.conjugate();
+ aux.transpose().solveTriangularInPlace(b);
+ }
+ else
+ m_matrix.transpose().solveTriangularInPlace(b);
+
+ return true;
+}
+
+#endif // EIGEN_SPARSELLT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseLU.h b/extern/Eigen2/Eigen/src/Sparse/SparseLU.h
new file mode 100644
index 00000000000..1425920509f
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseLU.h
@@ -0,0 +1,148 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSELU_H
+#define EIGEN_SPARSELU_H
+
+/** \ingroup Sparse_Module
+ *
+ * \class SparseLU
+ *
+ * \brief LU decomposition of a sparse matrix and associated features
+ *
+ * \param MatrixType the type of the matrix of which we are computing the LU factorization
+ *
+ * \sa class LU, class SparseLLT
+ */
+template<typename MatrixType, int Backend = DefaultBackend>
+class SparseLU
+{
+ protected:
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef SparseMatrix<Scalar,LowerTriangular> LUMatrixType;
+
+ enum {
+ MatrixLUIsDirty = 0x10000
+ };
+
+ public:
+
+ /** Creates a dummy LU factorization object with flags \a flags. */
+ SparseLU(int flags = 0)
+ : m_flags(flags), m_status(0)
+ {
+ m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ }
+
+ /** Creates a LU object and compute the respective factorization of \a matrix using
+ * flags \a flags. */
+ SparseLU(const MatrixType& matrix, int flags = 0)
+ : /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0)
+ {
+ m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ compute(matrix);
+ }
+
+ /** Sets the relative threshold value used to prune zero coefficients during the decomposition.
+ *
+ * Setting a value greater than zero speeds up computation, and yields to an imcomplete
+ * factorization with fewer non zero coefficients. Such approximate factors are especially
+ * useful to initialize an iterative solver.
+ *
+ * Note that the exact meaning of this parameter might depends on the actual
+ * backend. Moreover, not all backends support this feature.
+ *
+ * \sa precision() */
+ void setPrecision(RealScalar v) { m_precision = v; }
+
+ /** \returns the current precision.
+ *
+ * \sa setPrecision() */
+ RealScalar precision() const { return m_precision; }
+
+ /** Sets the flags. Possible values are:
+ * - CompleteFactorization
+ * - IncompleteFactorization
+ * - MemoryEfficient
+ * - one of the ordering methods
+ * - etc...
+ *
+ * \sa flags() */
+ void setFlags(int f) { m_flags = f; }
+ /** \returns the current flags */
+ int flags() const { return m_flags; }
+
+ void setOrderingMethod(int m)
+ {
+ ei_assert(m&~OrderingMask == 0 && m!=0 && "invalid ordering method");
+ m_flags = m_flags&~OrderingMask | m&OrderingMask;
+ }
+
+ int orderingMethod() const
+ {
+ return m_flags&OrderingMask;
+ }
+
+ /** Computes/re-computes the LU factorization */
+ void compute(const MatrixType& matrix);
+
+ /** \returns the lower triangular matrix L */
+ //inline const MatrixType& matrixL() const { return m_matrixL; }
+
+ /** \returns the upper triangular matrix U */
+ //inline const MatrixType& matrixU() const { return m_matrixU; }
+
+ template<typename BDerived, typename XDerived>
+ bool solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x) const;
+
+ /** \returns true if the factorization succeeded */
+ inline bool succeeded(void) const { return m_succeeded; }
+
+ protected:
+ RealScalar m_precision;
+ int m_flags;
+ mutable int m_status;
+ bool m_succeeded;
+};
+
+/** Computes / recomputes the LU decomposition of matrix \a a
+ * using the default algorithm.
+ */
+template<typename MatrixType, int Backend>
+void SparseLU<MatrixType,Backend>::compute(const MatrixType& a)
+{
+ ei_assert(false && "not implemented yet");
+}
+
+/** Computes *x = U^-1 L^-1 b */
+template<typename MatrixType, int Backend>
+template<typename BDerived, typename XDerived>
+bool SparseLU<MatrixType,Backend>::solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x) const
+{
+ ei_assert(false && "not implemented yet");
+ return false;
+}
+
+#endif // EIGEN_SPARSELU_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h b/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h
new file mode 100644
index 00000000000..3f09596bc64
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h
@@ -0,0 +1,447 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSEMATRIX_H
+#define EIGEN_SPARSEMATRIX_H
+
+/** \class SparseMatrix
+ *
+ * \brief Sparse matrix
+ *
+ * \param _Scalar the scalar type, i.e. the type of the coefficients
+ *
+ * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
+ *
+ */
+template<typename _Scalar, int _Flags>
+struct ei_traits<SparseMatrix<_Scalar, _Flags> >
+{
+ typedef _Scalar Scalar;
+ enum {
+ RowsAtCompileTime = Dynamic,
+ ColsAtCompileTime = Dynamic,
+ MaxRowsAtCompileTime = Dynamic,
+ MaxColsAtCompileTime = Dynamic,
+ Flags = SparseBit | _Flags,
+ CoeffReadCost = NumTraits<Scalar>::ReadCost,
+ SupportedAccessPatterns = InnerRandomAccessPattern
+ };
+};
+
+
+
+template<typename _Scalar, int _Flags>
+class SparseMatrix
+ : public SparseMatrixBase<SparseMatrix<_Scalar, _Flags> >
+{
+ public:
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseMatrix)
+ EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=)
+ EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=)
+ // FIXME: why are these operator already alvailable ???
+ // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, *=)
+ // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, /=)
+
+ typedef MappedSparseMatrix<Scalar,Flags> Map;
+
+ protected:
+
+ enum { IsRowMajor = Base::IsRowMajor };
+ typedef SparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix;
+
+ int m_outerSize;
+ int m_innerSize;
+ int* m_outerIndex;
+ CompressedStorage<Scalar> m_data;
+
+ public:
+
+ inline int rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
+ inline int cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
+
+ inline int innerSize() const { return m_innerSize; }
+ inline int outerSize() const { return m_outerSize; }
+ inline int innerNonZeros(int j) const { return m_outerIndex[j+1]-m_outerIndex[j]; }
+
+ inline const Scalar* _valuePtr() const { return &m_data.value(0); }
+ inline Scalar* _valuePtr() { return &m_data.value(0); }
+
+ inline const int* _innerIndexPtr() const { return &m_data.index(0); }
+ inline int* _innerIndexPtr() { return &m_data.index(0); }
+
+ inline const int* _outerIndexPtr() const { return m_outerIndex; }
+ inline int* _outerIndexPtr() { return m_outerIndex; }
+
+ inline Scalar coeff(int row, int col) const
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+ return m_data.atInRange(m_outerIndex[outer], m_outerIndex[outer+1], inner);
+ }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+
+ int start = m_outerIndex[outer];
+ int end = m_outerIndex[outer+1];
+ ei_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
+ ei_assert(end>start && "coeffRef cannot be called on a zero coefficient");
+ const int id = m_data.searchLowerIndex(start,end-1,inner);
+ ei_assert((id<end) && (m_data.index(id)==inner) && "coeffRef cannot be called on a zero coefficient");
+ return m_data.value(id);
+ }
+
+ public:
+
+ class InnerIterator;
+
+ inline void setZero()
+ {
+ m_data.clear();
+ //if (m_outerSize)
+ memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
+// for (int i=0; i<m_outerSize; ++i)
+// m_outerIndex[i] = 0;
+// if (m_outerSize)
+// m_outerIndex[i] = 0;
+ }
+
+ /** \returns the number of non zero coefficients */
+ inline int nonZeros() const { return m_data.size(); }
+
+ /** Initializes the filling process of \c *this.
+ * \param reserveSize approximate number of nonzeros
+ * Note that the matrix \c *this is zero-ed.
+ */
+ inline void startFill(int reserveSize = 1000)
+ {
+ setZero();
+ m_data.reserve(reserveSize);
+ }
+
+ /**
+ */
+ inline Scalar& fill(int row, int col)
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+
+ if (m_outerIndex[outer+1]==0)
+ {
+ // we start a new inner vector
+ int i = outer;
+ while (i>=0 && m_outerIndex[i]==0)
+ {
+ m_outerIndex[i] = m_data.size();
+ --i;
+ }
+ m_outerIndex[outer+1] = m_outerIndex[outer];
+ }
+ else
+ {
+ ei_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion");
+ }
+ assert(size_t(m_outerIndex[outer+1]) == m_data.size());
+ int id = m_outerIndex[outer+1];
+ ++m_outerIndex[outer+1];
+
+ m_data.append(0, inner);
+ return m_data.value(id);
+ }
+
+ /** Like fill() but with random inner coordinates.
+ */
+ inline Scalar& fillrand(int row, int col)
+ {
+ const int outer = IsRowMajor ? row : col;
+ const int inner = IsRowMajor ? col : row;
+ if (m_outerIndex[outer+1]==0)
+ {
+ // we start a new inner vector
+ // nothing special to do here
+ int i = outer;
+ while (i>=0 && m_outerIndex[i]==0)
+ {
+ m_outerIndex[i] = m_data.size();
+ --i;
+ }
+ m_outerIndex[outer+1] = m_outerIndex[outer];
+ }
+ assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "invalid outer index");
+ size_t startId = m_outerIndex[outer];
+ // FIXME let's make sure sizeof(long int) == sizeof(size_t)
+ size_t id = m_outerIndex[outer+1];
+ ++m_outerIndex[outer+1];
+
+ float reallocRatio = 1;
+ if (m_data.allocatedSize()<id+1)
+ {
+ // we need to reallocate the data, to reduce multiple reallocations
+ // we use a smart resize algorithm based on the current filling ratio
+ // we use float to avoid overflows
+ float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer);
+ reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size());
+ // let's bounds the realloc ratio to
+ // 1) reduce multiple minor realloc when the matrix is almost filled
+ // 2) avoid to allocate too much memory when the matrix is almost empty
+ reallocRatio = std::min(std::max(reallocRatio,1.5f),8.f);
+ }
+ m_data.resize(id+1,reallocRatio);
+
+ while ( (id > startId) && (m_data.index(id-1) > inner) )
+ {
+ m_data.index(id) = m_data.index(id-1);
+ m_data.value(id) = m_data.value(id-1);
+ --id;
+ }
+
+ m_data.index(id) = inner;
+ return (m_data.value(id) = 0);
+ }
+
+ inline void endFill()
+ {
+ int size = m_data.size();
+ int i = m_outerSize;
+ // find the last filled column
+ while (i>=0 && m_outerIndex[i]==0)
+ --i;
+ ++i;
+ while (i<=m_outerSize)
+ {
+ m_outerIndex[i] = size;
+ ++i;
+ }
+ }
+
+ void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ {
+ int k = 0;
+ for (int j=0; j<m_outerSize; ++j)
+ {
+ int previousStart = m_outerIndex[j];
+ m_outerIndex[j] = k;
+ int end = m_outerIndex[j+1];
+ for (int i=previousStart; i<end; ++i)
+ {
+ if (!ei_isMuchSmallerThan(m_data.value(i), reference, epsilon))
+ {
+ m_data.value(k) = m_data.value(i);
+ m_data.index(k) = m_data.index(i);
+ ++k;
+ }
+ }
+ }
+ m_outerIndex[m_outerSize] = k;
+ m_data.resize(k,0);
+ }
+
+ void resize(int rows, int cols)
+ {
+// std::cerr << this << " resize " << rows << "x" << cols << "\n";
+ const int outerSize = IsRowMajor ? rows : cols;
+ m_innerSize = IsRowMajor ? cols : rows;
+ m_data.clear();
+ if (m_outerSize != outerSize)
+ {
+ delete[] m_outerIndex;
+ m_outerIndex = new int [outerSize+1];
+ m_outerSize = outerSize;
+ memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
+ }
+ }
+ void resizeNonZeros(int size)
+ {
+ m_data.resize(size);
+ }
+
+ inline SparseMatrix()
+ : m_outerSize(-1), m_innerSize(0), m_outerIndex(0)
+ {
+ resize(0, 0);
+ }
+
+ inline SparseMatrix(int rows, int cols)
+ : m_outerSize(0), m_innerSize(0), m_outerIndex(0)
+ {
+ resize(rows, cols);
+ }
+
+ template<typename OtherDerived>
+ inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other)
+ : m_outerSize(0), m_innerSize(0), m_outerIndex(0)
+ {
+ *this = other.derived();
+ }
+
+ inline SparseMatrix(const SparseMatrix& other)
+ : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0)
+ {
+ *this = other.derived();
+ }
+
+ inline void swap(SparseMatrix& other)
+ {
+ //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n");
+ std::swap(m_outerIndex, other.m_outerIndex);
+ std::swap(m_innerSize, other.m_innerSize);
+ std::swap(m_outerSize, other.m_outerSize);
+ m_data.swap(other.m_data);
+ }
+
+ inline SparseMatrix& operator=(const SparseMatrix& other)
+ {
+// std::cout << "SparseMatrix& operator=(const SparseMatrix& other)\n";
+ if (other.isRValue())
+ {
+ swap(other.const_cast_derived());
+ }
+ else
+ {
+ resize(other.rows(), other.cols());
+ memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(int));
+ m_data = other.m_data;
+ }
+ return *this;
+ }
+
+ template<typename OtherDerived>
+ inline SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
+ if (needToTranspose)
+ {
+ // two passes algorithm:
+ // 1 - compute the number of coeffs per dest inner vector
+ // 2 - do the actual copy/eval
+ // Since each coeff of the rhs has to be evaluated twice, let's evauluate it if needed
+ //typedef typename ei_nested<OtherDerived,2>::type OtherCopy;
+ typedef typename ei_eval<OtherDerived>::type OtherCopy;
+ typedef typename ei_cleantype<OtherCopy>::type _OtherCopy;
+ OtherCopy otherCopy(other.derived());
+
+ resize(other.rows(), other.cols());
+ Eigen::Map<VectorXi>(m_outerIndex,outerSize()).setZero();
+ // pass 1
+ // FIXME the above copy could be merged with that pass
+ for (int j=0; j<otherCopy.outerSize(); ++j)
+ for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
+ ++m_outerIndex[it.index()];
+
+ // prefix sum
+ int count = 0;
+ VectorXi positions(outerSize());
+ for (int j=0; j<outerSize(); ++j)
+ {
+ int tmp = m_outerIndex[j];
+ m_outerIndex[j] = count;
+ positions[j] = count;
+ count += tmp;
+ }
+ m_outerIndex[outerSize()] = count;
+ // alloc
+ m_data.resize(count);
+ // pass 2
+ for (int j=0; j<otherCopy.outerSize(); ++j)
+ for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
+ {
+ int pos = positions[it.index()]++;
+ m_data.index(pos) = j;
+ m_data.value(pos) = it.value();
+ }
+
+ return *this;
+ }
+ else
+ {
+ // there is no special optimization
+ return SparseMatrixBase<SparseMatrix>::operator=(other.derived());
+ }
+ }
+
+ friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m)
+ {
+ EIGEN_DBG_SPARSE(
+ s << "Nonzero entries:\n";
+ for (int i=0; i<m.nonZeros(); ++i)
+ {
+ s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
+ }
+ s << std::endl;
+ s << std::endl;
+ s << "Column pointers:\n";
+ for (int i=0; i<m.outerSize(); ++i)
+ {
+ s << m.m_outerIndex[i] << " ";
+ }
+ s << " $" << std::endl;
+ s << std::endl;
+ );
+ s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m);
+ return s;
+ }
+
+ /** Destructor */
+ inline ~SparseMatrix()
+ {
+ delete[] m_outerIndex;
+ }
+};
+
+template<typename Scalar, int _Flags>
+class SparseMatrix<Scalar,_Flags>::InnerIterator
+{
+ public:
+ InnerIterator(const SparseMatrix& mat, int outer)
+ : m_matrix(mat), m_outer(outer), m_id(mat.m_outerIndex[outer]), m_start(m_id), m_end(mat.m_outerIndex[outer+1])
+ {}
+
+ template<unsigned int Added, unsigned int Removed>
+ InnerIterator(const Flagged<SparseMatrix,Added,Removed>& mat, int outer)
+ : m_matrix(mat._expression()), m_outer(outer), m_id(m_matrix.m_outerIndex[outer]),
+ m_start(m_id), m_end(m_matrix.m_outerIndex[outer+1])
+ {}
+
+ inline InnerIterator& operator++() { m_id++; return *this; }
+
+ inline Scalar value() const { return m_matrix.m_data.value(m_id); }
+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.m_data.value(m_id)); }
+
+ inline int index() const { return m_matrix.m_data.index(m_id); }
+ inline int row() const { return IsRowMajor ? m_outer : index(); }
+ inline int col() const { return IsRowMajor ? index() : m_outer; }
+
+ inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
+
+ protected:
+ const SparseMatrix& m_matrix;
+ const int m_outer;
+ int m_id;
+ const int m_start;
+ const int m_end;
+};
+
+#endif // EIGEN_SPARSEMATRIX_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseMatrixBase.h b/extern/Eigen2/Eigen/src/Sparse/SparseMatrixBase.h
new file mode 100644
index 00000000000..468bc9e227c
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseMatrixBase.h
@@ -0,0 +1,626 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSEMATRIXBASE_H
+#define EIGEN_SPARSEMATRIXBASE_H
+
+template<typename Derived> class SparseMatrixBase
+{
+ public:
+
+ typedef typename ei_traits<Derived>::Scalar Scalar;
+// typedef typename Derived::InnerIterator InnerIterator;
+
+ enum {
+
+ RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
+ /**< The number of rows at compile-time. This is just a copy of the value provided
+ * by the \a Derived type. If a value is not known at compile-time,
+ * it is set to the \a Dynamic constant.
+ * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
+
+ ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
+ /**< The number of columns at compile-time. This is just a copy of the value provided
+ * by the \a Derived type. If a value is not known at compile-time,
+ * it is set to the \a Dynamic constant.
+ * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
+
+
+ SizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime,
+ ei_traits<Derived>::ColsAtCompileTime>::ret),
+ /**< This is equal to the number of coefficients, i.e. the number of
+ * rows times the number of columns, or to \a Dynamic if this is not
+ * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
+
+ MaxRowsAtCompileTime = RowsAtCompileTime,
+ MaxColsAtCompileTime = ColsAtCompileTime,
+
+ MaxSizeAtCompileTime = (ei_size_at_compile_time<MaxRowsAtCompileTime,
+ MaxColsAtCompileTime>::ret),
+
+ IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
+ /**< This is set to true if either the number of rows or the number of
+ * columns is known at compile-time to be equal to 1. Indeed, in that case,
+ * we are dealing with a column-vector (if there is only one column) or with
+ * a row-vector (if there is only one row). */
+
+ Flags = ei_traits<Derived>::Flags,
+ /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
+ * constructed from this one. See the \ref flags "list of flags".
+ */
+
+ CoeffReadCost = ei_traits<Derived>::CoeffReadCost,
+ /**< This is a rough measure of how expensive it is to read one coefficient from
+ * this expression.
+ */
+
+ IsRowMajor = Flags&RowMajorBit ? 1 : 0
+ };
+
+ /** \internal the return type of MatrixBase::conjugate() */
+ typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
+ const SparseCwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
+ const Derived&
+ >::ret ConjugateReturnType;
+ /** \internal the return type of MatrixBase::real() */
+ typedef CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType;
+ /** \internal the return type of MatrixBase::imag() */
+ typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
+ /** \internal the return type of MatrixBase::adjoint() */
+ typedef SparseTranspose</*NestByValue<*/typename ei_cleantype<ConjugateReturnType>::type> /*>*/
+ AdjointReturnType;
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** This is the "real scalar" type; if the \a Scalar type is already real numbers
+ * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
+ * \a Scalar is \a std::complex<T> then RealScalar is \a T.
+ *
+ * \sa class NumTraits
+ */
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ /** type of the equivalent square matrix */
+ typedef Matrix<Scalar,EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime),
+ EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
+
+ inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
+ inline Derived& derived() { return *static_cast<Derived*>(this); }
+ inline Derived& const_cast_derived() const
+ { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
+#endif // not EIGEN_PARSED_BY_DOXYGEN
+
+ /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
+ inline int rows() const { return derived().rows(); }
+ /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
+ inline int cols() const { return derived().cols(); }
+ /** \returns the number of coefficients, which is \a rows()*cols().
+ * \sa rows(), cols(), SizeAtCompileTime. */
+ inline int size() const { return rows() * cols(); }
+ /** \returns the number of nonzero coefficients which is in practice the number
+ * of stored coefficients. */
+ inline int nonZeros() const { return derived().nonZeros(); }
+ /** \returns true if either the number of rows or the number of columns is equal to 1.
+ * In other words, this function returns
+ * \code rows()==1 || cols()==1 \endcode
+ * \sa rows(), cols(), IsVectorAtCompileTime. */
+ inline bool isVector() const { return rows()==1 || cols()==1; }
+ /** \returns the size of the storage major dimension,
+ * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
+ int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
+ /** \returns the size of the inner dimension according to the storage order,
+ * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
+ int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
+
+ bool isRValue() const { return m_isRValue; }
+ Derived& markAsRValue() { m_isRValue = true; return derived(); }
+
+ SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
+
+ inline Derived& operator=(const Derived& other)
+ {
+// std::cout << "Derived& operator=(const Derived& other)\n";
+// if (other.isRValue())
+// derived().swap(other.const_cast_derived());
+// else
+ this->operator=<Derived>(other);
+ return derived();
+ }
+
+
+ template<typename OtherDerived>
+ inline void assignGeneric(const OtherDerived& other)
+ {
+// std::cout << "Derived& operator=(const MatrixBase<OtherDerived>& other)\n";
+ //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
+ ei_assert(( ((ei_traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
+ (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
+ "the transpose operation is supposed to be handled in SparseMatrix::operator=");
+
+ const int outerSize = other.outerSize();
+ //typedef typename ei_meta_if<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::ret TempType;
+ // thanks to shallow copies, we always eval to a tempary
+ Derived temp(other.rows(), other.cols());
+
+ temp.startFill(std::max(this->rows(),this->cols())*2);
+ for (int j=0; j<outerSize; ++j)
+ {
+ for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
+ {
+ Scalar v = it.value();
+ if (v!=Scalar(0))
+ {
+ if (OtherDerived::Flags & RowMajorBit) temp.fill(j,it.index()) = v;
+ else temp.fill(it.index(),j) = v;
+ }
+ }
+ }
+ temp.endFill();
+
+ derived() = temp.markAsRValue();
+ }
+
+
+ template<typename OtherDerived>
+ inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+// std::cout << typeid(OtherDerived).name() << "\n";
+// std::cout << Flags << " " << OtherDerived::Flags << "\n";
+ const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
+// std::cout << "eval transpose = " << transpose << "\n";
+ const int outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
+ if ((!transpose) && other.isRValue())
+ {
+ // eval without temporary
+ derived().resize(other.rows(), other.cols());
+ derived().startFill(std::max(this->rows(),this->cols())*2);
+ for (int j=0; j<outerSize; ++j)
+ {
+ for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
+ {
+ Scalar v = it.value();
+ if (v!=Scalar(0))
+ {
+ if (IsRowMajor) derived().fill(j,it.index()) = v;
+ else derived().fill(it.index(),j) = v;
+ }
+ }
+ }
+ derived().endFill();
+ }
+ else
+ {
+ assignGeneric(other.derived());
+ }
+ return derived();
+ }
+
+ template<typename Lhs, typename Rhs>
+ inline Derived& operator=(const SparseProduct<Lhs,Rhs,SparseTimeSparseProduct>& product);
+
+ friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
+ {
+ if (Flags&RowMajorBit)
+ {
+ for (int row=0; row<m.outerSize(); ++row)
+ {
+ int col = 0;
+ for (typename Derived::InnerIterator it(m.derived(), row); it; ++it)
+ {
+ for ( ; col<it.index(); ++col)
+ s << "0 ";
+ s << it.value() << " ";
+ ++col;
+ }
+ for ( ; col<m.cols(); ++col)
+ s << "0 ";
+ s << std::endl;
+ }
+ }
+ else
+ {
+ if (m.cols() == 1) {
+ int row = 0;
+ for (typename Derived::InnerIterator it(m.derived(), 0); it; ++it)
+ {
+ for ( ; row<it.index(); ++row)
+ s << "0" << std::endl;
+ s << it.value() << std::endl;
+ ++row;
+ }
+ for ( ; row<m.rows(); ++row)
+ s << "0" << std::endl;
+ }
+ else
+ {
+ SparseMatrix<Scalar, RowMajorBit> trans = m.derived();
+ s << trans;
+ }
+ }
+ return s;
+ }
+
+ const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const;
+
+ template<typename OtherDerived>
+ const SparseCwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
+ operator+(const SparseMatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const SparseCwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
+ operator-(const SparseMatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
+ template<typename OtherDerived>
+ Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
+
+// template<typename Lhs,typename Rhs>
+// Derived& operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProduct>, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other);
+
+ Derived& operator*=(const Scalar& other);
+ Derived& operator/=(const Scalar& other);
+
+ const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
+ operator*(const Scalar& scalar) const;
+ const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
+ operator/(const Scalar& scalar) const;
+
+ inline friend const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
+ operator*(const Scalar& scalar, const SparseMatrixBase& matrix)
+ { return matrix*scalar; }
+
+
+ template<typename OtherDerived>
+ const typename SparseProductReturnType<Derived,OtherDerived>::Type
+ operator*(const SparseMatrixBase<OtherDerived> &other) const;
+
+ // dense * sparse (return a dense object)
+ template<typename OtherDerived> friend
+ const typename SparseProductReturnType<OtherDerived,Derived>::Type
+ operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
+ { return typename SparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
+
+ template<typename OtherDerived>
+ const typename SparseProductReturnType<Derived,OtherDerived>::Type
+ operator*(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
+
+ template<typename OtherDerived>
+ typename ei_plain_matrix_type_column_major<OtherDerived>::type
+ solveTriangular(const MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived>
+ void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
+
+ template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
+ template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
+ RealScalar squaredNorm() const;
+ RealScalar norm() const;
+// const PlainMatrixType normalized() const;
+// void normalize();
+
+ SparseTranspose<Derived> transpose() { return derived(); }
+ const SparseTranspose<Derived> transpose() const { return derived(); }
+ // void transposeInPlace();
+ const AdjointReturnType adjoint() const { return conjugate()/*.nestByValue()*/; }
+
+ // sub-vector
+ SparseInnerVectorSet<Derived,1> row(int i);
+ const SparseInnerVectorSet<Derived,1> row(int i) const;
+ SparseInnerVectorSet<Derived,1> col(int j);
+ const SparseInnerVectorSet<Derived,1> col(int j) const;
+ SparseInnerVectorSet<Derived,1> innerVector(int outer);
+ const SparseInnerVectorSet<Derived,1> innerVector(int outer) const;
+
+ // set of sub-vectors
+ SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size);
+ const SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size) const;
+ SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size);
+ const SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size) const;
+ SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize);
+ const SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize) const;
+
+// typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols);
+// const typename BlockReturnType<Derived>::Type
+// block(int startRow, int startCol, int blockRows, int blockCols) const;
+//
+// typename BlockReturnType<Derived>::SubVectorType segment(int start, int size);
+// const typename BlockReturnType<Derived>::SubVectorType segment(int start, int size) const;
+//
+// typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size);
+// const typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size) const;
+//
+// typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size);
+// const typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size) const;
+//
+// typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols);
+// const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const;
+//
+// template<int BlockRows, int BlockCols>
+// typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol);
+// template<int BlockRows, int BlockCols>
+// const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const;
+
+// template<int CRows, int CCols>
+// typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type);
+// template<int CRows, int CCols>
+// const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const;
+
+// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType start(void);
+// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType start() const;
+
+// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType end();
+// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType end() const;
+
+// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType segment(int start);
+// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType segment(int start) const;
+
+// DiagonalCoeffs<Derived> diagonal();
+// const DiagonalCoeffs<Derived> diagonal() const;
+
+// template<unsigned int Mode> Part<Derived, Mode> part();
+// template<unsigned int Mode> const Part<Derived, Mode> part() const;
+
+
+// static const ConstantReturnType Constant(int rows, int cols, const Scalar& value);
+// static const ConstantReturnType Constant(int size, const Scalar& value);
+// static const ConstantReturnType Constant(const Scalar& value);
+
+// template<typename CustomNullaryOp>
+// static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(int rows, int cols, const CustomNullaryOp& func);
+// template<typename CustomNullaryOp>
+// static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(int size, const CustomNullaryOp& func);
+// template<typename CustomNullaryOp>
+// static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(const CustomNullaryOp& func);
+
+// static const ConstantReturnType Zero(int rows, int cols);
+// static const ConstantReturnType Zero(int size);
+// static const ConstantReturnType Zero();
+// static const ConstantReturnType Ones(int rows, int cols);
+// static const ConstantReturnType Ones(int size);
+// static const ConstantReturnType Ones();
+// static const IdentityReturnType Identity();
+// static const IdentityReturnType Identity(int rows, int cols);
+// static const BasisReturnType Unit(int size, int i);
+// static const BasisReturnType Unit(int i);
+// static const BasisReturnType UnitX();
+// static const BasisReturnType UnitY();
+// static const BasisReturnType UnitZ();
+// static const BasisReturnType UnitW();
+
+// const DiagonalMatrix<Derived> asDiagonal() const;
+
+// Derived& setConstant(const Scalar& value);
+// Derived& setZero();
+// Derived& setOnes();
+// Derived& setRandom();
+// Derived& setIdentity();
+
+ Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
+ {
+ Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> res(rows(),cols());
+ res.setZero();
+ for (int j=0; j<outerSize(); ++j)
+ {
+ for (typename Derived::InnerIterator i(derived(),j); i; ++i)
+ if(IsRowMajor)
+ res.coeffRef(j,i.index()) = i.value();
+ else
+ res.coeffRef(i.index(),j) = i.value();
+ }
+ return res;
+ }
+
+ template<typename OtherDerived>
+ bool isApprox(const SparseMatrixBase<OtherDerived>& other,
+ RealScalar prec = precision<Scalar>()) const
+ { return toDense().isApprox(other.toDense(),prec); }
+
+ template<typename OtherDerived>
+ bool isApprox(const MatrixBase<OtherDerived>& other,
+ RealScalar prec = precision<Scalar>()) const
+ { return toDense().isApprox(other,prec); }
+// bool isMuchSmallerThan(const RealScalar& other,
+// RealScalar prec = precision<Scalar>()) const;
+// template<typename OtherDerived>
+// bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
+// RealScalar prec = precision<Scalar>()) const;
+
+// bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
+// bool isZero(RealScalar prec = precision<Scalar>()) const;
+// bool isOnes(RealScalar prec = precision<Scalar>()) const;
+// bool isIdentity(RealScalar prec = precision<Scalar>()) const;
+// bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
+
+// bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
+// bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
+
+// template<typename OtherDerived>
+// bool isOrthogonal(const MatrixBase<OtherDerived>& other,
+// RealScalar prec = precision<Scalar>()) const;
+// bool isUnitary(RealScalar prec = precision<Scalar>()) const;
+
+// template<typename OtherDerived>
+// inline bool operator==(const MatrixBase<OtherDerived>& other) const
+// { return (cwise() == other).all(); }
+
+// template<typename OtherDerived>
+// inline bool operator!=(const MatrixBase<OtherDerived>& other) const
+// { return (cwise() != other).any(); }
+
+
+ template<typename NewType>
+ const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const;
+
+ /** \returns the matrix or vector obtained by evaluating this expression.
+ *
+ * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
+ * a const reference, in order to avoid a useless copy.
+ */
+ EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const
+ { return typename ei_eval<Derived>::type(derived()); }
+
+// template<typename OtherDerived>
+// void swap(const MatrixBase<OtherDerived>& other);
+
+ template<unsigned int Added>
+ const SparseFlagged<Derived, Added, 0> marked() const;
+// const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit> lazy() const;
+
+ /** \returns number of elements to skip to pass from one row (resp. column) to another
+ * for a row-major (resp. column-major) matrix.
+ * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data
+ * of the underlying matrix.
+ */
+// inline int stride(void) const { return derived().stride(); }
+
+// inline const NestByValue<Derived> nestByValue() const;
+
+
+ ConjugateReturnType conjugate() const;
+ const RealReturnType real() const;
+ const ImagReturnType imag() const;
+
+ template<typename CustomUnaryOp>
+ const SparseCwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const;
+
+// template<typename CustomBinaryOp, typename OtherDerived>
+// const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
+// binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const;
+
+
+ Scalar sum() const;
+// Scalar trace() const;
+
+// typename ei_traits<Derived>::Scalar minCoeff() const;
+// typename ei_traits<Derived>::Scalar maxCoeff() const;
+
+// typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col = 0) const;
+// typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col = 0) const;
+
+// template<typename BinaryOp>
+// typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
+// redux(const BinaryOp& func) const;
+
+// template<typename Visitor>
+// void visit(Visitor& func) const;
+
+
+ const SparseCwise<Derived> cwise() const;
+ SparseCwise<Derived> cwise();
+
+// inline const WithFormat<Derived> format(const IOFormat& fmt) const;
+
+/////////// Array module ///////////
+ /*
+ bool all(void) const;
+ bool any(void) const;
+
+ const PartialRedux<Derived,Horizontal> rowwise() const;
+ const PartialRedux<Derived,Vertical> colwise() const;
+
+ static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int rows, int cols);
+ static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int size);
+ static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random();
+
+ template<typename ThenDerived,typename ElseDerived>
+ const Select<Derived,ThenDerived,ElseDerived>
+ select(const MatrixBase<ThenDerived>& thenMatrix,
+ const MatrixBase<ElseDerived>& elseMatrix) const;
+
+ template<typename ThenDerived>
+ inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
+ select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
+
+ template<typename ElseDerived>
+ inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
+ select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
+
+ template<int p> RealScalar lpNorm() const;
+ */
+
+
+// template<typename OtherDerived>
+// Scalar dot(const MatrixBase<OtherDerived>& other) const
+// {
+// EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+// EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
+// EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
+// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+//
+// ei_assert(derived().size() == other.size());
+// // short version, but the assembly looks more complicated because
+// // of the CwiseBinaryOp iterator complexity
+// // return res = (derived().cwise() * other.derived().conjugate()).sum();
+//
+// // optimized, generic version
+// typename Derived::InnerIterator i(derived(),0);
+// typename OtherDerived::InnerIterator j(other.derived(),0);
+// Scalar res = 0;
+// while (i && j)
+// {
+// if (i.index()==j.index())
+// {
+// // std::cerr << i.value() << " * " << j.value() << "\n";
+// res += i.value() * ei_conj(j.value());
+// ++i; ++j;
+// }
+// else if (i.index()<j.index())
+// ++i;
+// else
+// ++j;
+// }
+// return res;
+// }
+//
+// Scalar sum() const
+// {
+// Scalar res = 0;
+// for (typename Derived::InnerIterator iter(*this,0); iter; ++iter)
+// {
+// res += iter.value();
+// }
+// return res;
+// }
+
+ #ifdef EIGEN_TAUCS_SUPPORT
+ taucs_ccs_matrix asTaucsMatrix();
+ #endif
+
+ #ifdef EIGEN_CHOLMOD_SUPPORT
+ cholmod_sparse asCholmodMatrix();
+ #endif
+
+ #ifdef EIGEN_SUPERLU_SUPPORT
+ SluMatrix asSluMatrix();
+ #endif
+
+ protected:
+
+ bool m_isRValue;
+};
+
+#endif // EIGEN_SPARSEMATRIXBASE_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseProduct.h b/extern/Eigen2/Eigen/src/Sparse/SparseProduct.h
new file mode 100644
index 00000000000..c98a71e993b
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseProduct.h
@@ -0,0 +1,415 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSEPRODUCT_H
+#define EIGEN_SPARSEPRODUCT_H
+
+template<typename Lhs, typename Rhs> struct ei_sparse_product_mode
+{
+ enum {
+
+ value = ((Lhs::Flags&Diagonal)==Diagonal || (Rhs::Flags&Diagonal)==Diagonal)
+ ? DiagonalProduct
+ : (Rhs::Flags&Lhs::Flags&SparseBit)==SparseBit
+ ? SparseTimeSparseProduct
+ : (Lhs::Flags&SparseBit)==SparseBit
+ ? SparseTimeDenseProduct
+ : DenseTimeSparseProduct };
+};
+
+template<typename Lhs, typename Rhs, int ProductMode>
+struct SparseProductReturnType
+{
+ typedef const typename ei_nested<Lhs,Rhs::RowsAtCompileTime>::type LhsNested;
+ typedef const typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
+
+ typedef SparseProduct<LhsNested, RhsNested, ProductMode> Type;
+};
+
+template<typename Lhs, typename Rhs>
+struct SparseProductReturnType<Lhs,Rhs,DiagonalProduct>
+{
+ typedef const typename ei_nested<Lhs,Rhs::RowsAtCompileTime>::type LhsNested;
+ typedef const typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
+
+ typedef SparseDiagonalProduct<LhsNested, RhsNested> Type;
+};
+
+// sparse product return type specialization
+template<typename Lhs, typename Rhs>
+struct SparseProductReturnType<Lhs,Rhs,SparseTimeSparseProduct>
+{
+ typedef typename ei_traits<Lhs>::Scalar Scalar;
+ enum {
+ LhsRowMajor = ei_traits<Lhs>::Flags & RowMajorBit,
+ RhsRowMajor = ei_traits<Rhs>::Flags & RowMajorBit,
+ TransposeRhs = (!LhsRowMajor) && RhsRowMajor,
+ TransposeLhs = LhsRowMajor && (!RhsRowMajor)
+ };
+
+ // FIXME if we transpose let's evaluate to a LinkedVectorMatrix since it is the
+ // type of the temporary to perform the transpose op
+ typedef typename ei_meta_if<TransposeLhs,
+ SparseMatrix<Scalar,0>,
+ const typename ei_nested<Lhs,Rhs::RowsAtCompileTime>::type>::ret LhsNested;
+
+ typedef typename ei_meta_if<TransposeRhs,
+ SparseMatrix<Scalar,0>,
+ const typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type>::ret RhsNested;
+
+ typedef SparseProduct<LhsNested, RhsNested, SparseTimeSparseProduct> Type;
+};
+
+template<typename LhsNested, typename RhsNested, int ProductMode>
+struct ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> >
+{
+ // clean the nested types:
+ typedef typename ei_cleantype<LhsNested>::type _LhsNested;
+ typedef typename ei_cleantype<RhsNested>::type _RhsNested;
+ typedef typename _LhsNested::Scalar Scalar;
+
+ enum {
+ LhsCoeffReadCost = _LhsNested::CoeffReadCost,
+ RhsCoeffReadCost = _RhsNested::CoeffReadCost,
+ LhsFlags = _LhsNested::Flags,
+ RhsFlags = _RhsNested::Flags,
+
+ RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
+ ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
+ InnerSize = EIGEN_ENUM_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
+
+ MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
+
+// LhsIsRowMajor = (LhsFlags & RowMajorBit)==RowMajorBit,
+// RhsIsRowMajor = (RhsFlags & RowMajorBit)==RowMajorBit,
+
+ EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit),
+ ResultIsSparse = ProductMode==SparseTimeSparseProduct || ProductMode==DiagonalProduct,
+
+ RemovedBits = ~( (EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSparse ? 0 : SparseBit) ),
+
+ Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
+ | EvalBeforeAssigningBit
+ | EvalBeforeNestingBit,
+
+ CoeffReadCost = Dynamic
+ };
+
+ typedef typename ei_meta_if<ResultIsSparse,
+ SparseMatrixBase<SparseProduct<LhsNested, RhsNested, ProductMode> >,
+ MatrixBase<SparseProduct<LhsNested, RhsNested, ProductMode> > >::ret Base;
+};
+
+template<typename LhsNested, typename RhsNested, int ProductMode>
+class SparseProduct : ei_no_assignment_operator,
+ public ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> >::Base
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(SparseProduct)
+
+ private:
+
+ typedef typename ei_traits<SparseProduct>::_LhsNested _LhsNested;
+ typedef typename ei_traits<SparseProduct>::_RhsNested _RhsNested;
+
+ public:
+
+ template<typename Lhs, typename Rhs>
+ EIGEN_STRONG_INLINE SparseProduct(const Lhs& lhs, const Rhs& rhs)
+ : m_lhs(lhs), m_rhs(rhs)
+ {
+ ei_assert(lhs.cols() == rhs.rows());
+
+ enum {
+ ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic
+ || _RhsNested::RowsAtCompileTime==Dynamic
+ || int(_LhsNested::ColsAtCompileTime)==int(_RhsNested::RowsAtCompileTime),
+ AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
+ SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested,_RhsNested)
+ };
+ // note to the lost user:
+ // * for a dot product use: v1.dot(v2)
+ // * for a coeff-wise product use: v1.cwise()*v2
+ EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
+ INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
+ EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
+ INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
+ EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
+ }
+
+ EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return m_rhs.cols(); }
+
+ EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
+ EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
+
+ protected:
+ LhsNested m_lhs;
+ RhsNested m_rhs;
+};
+
+// perform a pseudo in-place sparse * sparse product assuming all matrices are col major
+template<typename Lhs, typename Rhs, typename ResultType>
+static void ei_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res)
+{
+ typedef typename ei_traits<typename ei_cleantype<Lhs>::type>::Scalar Scalar;
+
+ // make sure to call innerSize/outerSize since we fake the storage order.
+ int rows = lhs.innerSize();
+ int cols = rhs.outerSize();
+ //int size = lhs.outerSize();
+ ei_assert(lhs.outerSize() == rhs.innerSize());
+
+ // allocate a temporary buffer
+ AmbiVector<Scalar> tempVector(rows);
+
+ // estimate the number of non zero entries
+ float ratioLhs = float(lhs.nonZeros())/(float(lhs.rows())*float(lhs.cols()));
+ float avgNnzPerRhsColumn = float(rhs.nonZeros())/float(cols);
+ float ratioRes = std::min(ratioLhs * avgNnzPerRhsColumn, 1.f);
+
+ res.resize(rows, cols);
+ res.startFill(int(ratioRes*rows*cols));
+ for (int j=0; j<cols; ++j)
+ {
+ // let's do a more accurate determination of the nnz ratio for the current column j of res
+ //float ratioColRes = std::min(ratioLhs * rhs.innerNonZeros(j), 1.f);
+ // FIXME find a nice way to get the number of nonzeros of a sub matrix (here an inner vector)
+ float ratioColRes = ratioRes;
+ tempVector.init(ratioColRes);
+ tempVector.setZero();
+ for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt)
+ {
+ // FIXME should be written like this: tmp += rhsIt.value() * lhs.col(rhsIt.index())
+ tempVector.restart();
+ Scalar x = rhsIt.value();
+ for (typename Lhs::InnerIterator lhsIt(lhs, rhsIt.index()); lhsIt; ++lhsIt)
+ {
+ tempVector.coeffRef(lhsIt.index()) += lhsIt.value() * x;
+ }
+ }
+ for (typename AmbiVector<Scalar>::Iterator it(tempVector); it; ++it)
+ if (ResultType::Flags&RowMajorBit)
+ res.fill(j,it.index()) = it.value();
+ else
+ res.fill(it.index(), j) = it.value();
+ }
+ res.endFill();
+}
+
+template<typename Lhs, typename Rhs, typename ResultType,
+ int LhsStorageOrder = ei_traits<Lhs>::Flags&RowMajorBit,
+ int RhsStorageOrder = ei_traits<Rhs>::Flags&RowMajorBit,
+ int ResStorageOrder = ei_traits<ResultType>::Flags&RowMajorBit>
+struct ei_sparse_product_selector;
+
+template<typename Lhs, typename Rhs, typename ResultType>
+struct ei_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor>
+{
+ typedef typename ei_traits<typename ei_cleantype<Lhs>::type>::Scalar Scalar;
+
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
+ {
+ typename ei_cleantype<ResultType>::type _res(res.rows(), res.cols());
+ ei_sparse_product_impl<Lhs,Rhs,ResultType>(lhs, rhs, _res);
+ res.swap(_res);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename ResultType>
+struct ei_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor>
+{
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
+ {
+ // we need a col-major matrix to hold the result
+ typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType;
+ SparseTemporaryType _res(res.rows(), res.cols());
+ ei_sparse_product_impl<Lhs,Rhs,SparseTemporaryType>(lhs, rhs, _res);
+ res = _res;
+ }
+};
+
+template<typename Lhs, typename Rhs, typename ResultType>
+struct ei_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor>
+{
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
+ {
+ // let's transpose the product to get a column x column product
+ typename ei_cleantype<ResultType>::type _res(res.rows(), res.cols());
+ ei_sparse_product_impl<Rhs,Lhs,ResultType>(rhs, lhs, _res);
+ res.swap(_res);
+ }
+};
+
+template<typename Lhs, typename Rhs, typename ResultType>
+struct ei_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor>
+{
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
+ {
+ // let's transpose the product to get a column x column product
+ typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType;
+ SparseTemporaryType _res(res.cols(), res.rows());
+ ei_sparse_product_impl<Rhs,Lhs,SparseTemporaryType>(rhs, lhs, _res);
+ res = _res.transpose();
+ }
+};
+
+// NOTE eventually let's transpose one argument even in this case since it might be expensive if
+// the result is not dense.
+// template<typename Lhs, typename Rhs, typename ResultType, int ResStorageOrder>
+// struct ei_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,ResStorageOrder>
+// {
+// static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
+// {
+// // trivial product as lhs.row/rhs.col dot products
+// // loop over the preferred order of the result
+// }
+// };
+
+// NOTE the 2 others cases (col row *) must never occurs since they are caught
+// by ProductReturnType which transform it to (col col *) by evaluating rhs.
+
+
+// template<typename Derived>
+// template<typename Lhs, typename Rhs>
+// inline Derived& SparseMatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs>& product)
+// {
+// // std::cout << "sparse product to dense\n";
+// ei_sparse_product_selector<
+// typename ei_cleantype<Lhs>::type,
+// typename ei_cleantype<Rhs>::type,
+// typename ei_cleantype<Derived>::type>::run(product.lhs(),product.rhs(),derived());
+// return derived();
+// }
+
+// sparse = sparse * sparse
+template<typename Derived>
+template<typename Lhs, typename Rhs>
+inline Derived& SparseMatrixBase<Derived>::operator=(const SparseProduct<Lhs,Rhs,SparseTimeSparseProduct>& product)
+{
+ ei_sparse_product_selector<
+ typename ei_cleantype<Lhs>::type,
+ typename ei_cleantype<Rhs>::type,
+ Derived>::run(product.lhs(),product.rhs(),derived());
+ return derived();
+}
+
+// dense = sparse * dense
+// template<typename Derived>
+// template<typename Lhs, typename Rhs>
+// Derived& MatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs,SparseTimeDenseProduct>& product)
+// {
+// typedef typename ei_cleantype<Lhs>::type _Lhs;
+// typedef typename _Lhs::InnerIterator LhsInnerIterator;
+// enum { LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit };
+// derived().setZero();
+// for (int j=0; j<product.lhs().outerSize(); ++j)
+// for (LhsInnerIterator i(product.lhs(),j); i; ++i)
+// derived().row(LhsIsRowMajor ? j : i.index()) += i.value() * product.rhs().row(LhsIsRowMajor ? i.index() : j);
+// return derived();
+// }
+
+template<typename Derived>
+template<typename Lhs, typename Rhs>
+Derived& MatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs,SparseTimeDenseProduct>& product)
+{
+ typedef typename ei_cleantype<Lhs>::type _Lhs;
+ typedef typename ei_cleantype<Rhs>::type _Rhs;
+ typedef typename _Lhs::InnerIterator LhsInnerIterator;
+ enum {
+ LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit,
+ LhsIsSelfAdjoint = (_Lhs::Flags&SelfAdjointBit)==SelfAdjointBit,
+ ProcessFirstHalf = LhsIsSelfAdjoint
+ && ( ((_Lhs::Flags&(UpperTriangularBit|LowerTriangularBit))==0)
+ || ( (_Lhs::Flags&UpperTriangularBit) && !LhsIsRowMajor)
+ || ( (_Lhs::Flags&LowerTriangularBit) && LhsIsRowMajor) ),
+ ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
+ };
+ derived().setZero();
+ for (int j=0; j<product.lhs().outerSize(); ++j)
+ {
+ LhsInnerIterator i(product.lhs(),j);
+ if (ProcessSecondHalf && i && (i.index()==j))
+ {
+ derived().row(j) += i.value() * product.rhs().row(j);
+ ++i;
+ }
+ Block<Derived,1,Derived::ColsAtCompileTime> res(derived().row(LhsIsRowMajor ? j : 0));
+ for (; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i)
+ {
+ if (LhsIsSelfAdjoint)
+ {
+ int a = LhsIsRowMajor ? j : i.index();
+ int b = LhsIsRowMajor ? i.index() : j;
+ Scalar v = i.value();
+ derived().row(a) += (v) * product.rhs().row(b);
+ derived().row(b) += ei_conj(v) * product.rhs().row(a);
+ }
+ else if (LhsIsRowMajor)
+ res += i.value() * product.rhs().row(i.index());
+ else
+ derived().row(i.index()) += i.value() * product.rhs().row(j);
+ }
+ if (ProcessFirstHalf && i && (i.index()==j))
+ derived().row(j) += i.value() * product.rhs().row(j);
+ }
+ return derived();
+}
+
+// dense = dense * sparse
+template<typename Derived>
+template<typename Lhs, typename Rhs>
+Derived& MatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs,DenseTimeSparseProduct>& product)
+{
+ typedef typename ei_cleantype<Rhs>::type _Rhs;
+ typedef typename _Rhs::InnerIterator RhsInnerIterator;
+ enum { RhsIsRowMajor = (_Rhs::Flags&RowMajorBit)==RowMajorBit };
+ derived().setZero();
+ for (int j=0; j<product.rhs().outerSize(); ++j)
+ for (RhsInnerIterator i(product.rhs(),j); i; ++i)
+ derived().col(RhsIsRowMajor ? i.index() : j) += i.value() * product.lhs().col(RhsIsRowMajor ? j : i.index());
+ return derived();
+}
+
+// sparse * sparse
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const typename SparseProductReturnType<Derived,OtherDerived>::Type
+SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const
+{
+ return typename SparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
+}
+
+// sparse * dense
+template<typename Derived>
+template<typename OtherDerived>
+EIGEN_STRONG_INLINE const typename SparseProductReturnType<Derived,OtherDerived>::Type
+SparseMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
+{
+ return typename SparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
+}
+
+#endif // EIGEN_SPARSEPRODUCT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseRedux.h b/extern/Eigen2/Eigen/src/Sparse/SparseRedux.h
new file mode 100644
index 00000000000..f0d3705488e
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseRedux.h
@@ -0,0 +1,40 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSEREDUX_H
+#define EIGEN_SPARSEREDUX_H
+
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+SparseMatrixBase<Derived>::sum() const
+{
+ ei_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix");
+ Scalar res = 0;
+ for (int j=0; j<outerSize(); ++j)
+ for (typename Derived::InnerIterator iter(derived(),j); iter; ++iter)
+ res += iter.value();
+ return res;
+}
+
+#endif // EIGEN_SPARSEREDUX_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h b/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h
new file mode 100644
index 00000000000..89a14d70707
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h
@@ -0,0 +1,85 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSETRANSPOSE_H
+#define EIGEN_SPARSETRANSPOSE_H
+
+template<typename MatrixType>
+struct ei_traits<SparseTranspose<MatrixType> > : ei_traits<Transpose<MatrixType> >
+{};
+
+template<typename MatrixType> class SparseTranspose
+ : public SparseMatrixBase<SparseTranspose<MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(SparseTranspose)
+
+ class InnerIterator;
+ class ReverseInnerIterator;
+
+ inline SparseTranspose(const MatrixType& matrix) : m_matrix(matrix) {}
+
+ //EIGEN_INHERIT_ASSIGNMENT_OPERATORS(SparseTranspose)
+
+ inline int rows() const { return m_matrix.cols(); }
+ inline int cols() const { return m_matrix.rows(); }
+ inline int nonZeros() const { return m_matrix.nonZeros(); }
+
+ // FIXME should be keep them ?
+ inline Scalar& coeffRef(int row, int col)
+ { return m_matrix.const_cast_derived().coeffRef(col, row); }
+
+ inline const Scalar coeff(int row, int col) const
+ { return m_matrix.coeff(col, row); }
+
+ inline const Scalar coeff(int index) const
+ { return m_matrix.coeff(index); }
+
+ inline Scalar& coeffRef(int index)
+ { return m_matrix.const_cast_derived().coeffRef(index); }
+
+ protected:
+ const typename MatrixType::Nested m_matrix;
+};
+
+template<typename MatrixType> class SparseTranspose<MatrixType>::InnerIterator : public MatrixType::InnerIterator
+{
+ public:
+
+ EIGEN_STRONG_INLINE InnerIterator(const SparseTranspose& trans, int outer)
+ : MatrixType::InnerIterator(trans.m_matrix, outer)
+ {}
+};
+
+template<typename MatrixType> class SparseTranspose<MatrixType>::ReverseInnerIterator : public MatrixType::ReverseInnerIterator
+{
+ public:
+
+ EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTranspose& xpr, int outer)
+ : MatrixType::ReverseInnerIterator(xpr.m_matrix, outer)
+ {}
+};
+
+#endif // EIGEN_SPARSETRANSPOSE_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseUtil.h b/extern/Eigen2/Eigen/src/Sparse/SparseUtil.h
new file mode 100644
index 00000000000..393cdda6ea2
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseUtil.h
@@ -0,0 +1,148 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSEUTIL_H
+#define EIGEN_SPARSEUTIL_H
+
+#ifdef NDEBUG
+#define EIGEN_DBG_SPARSE(X)
+#else
+#define EIGEN_DBG_SPARSE(X) X
+#endif
+
+#define EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \
+template<typename OtherDerived> \
+EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::SparseMatrixBase<OtherDerived>& other) \
+{ \
+ return Base::operator Op(other.derived()); \
+} \
+EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \
+{ \
+ return Base::operator Op(other); \
+}
+
+#define EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \
+template<typename Other> \
+EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \
+{ \
+ return Base::operator Op(scalar); \
+}
+
+#define EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
+EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \
+EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \
+EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \
+EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \
+EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)
+
+#define _EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \
+typedef BaseClass Base; \
+typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \
+typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \
+typedef typename Eigen::ei_nested<Derived>::type Nested; \
+enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
+ ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
+ Flags = Eigen::ei_traits<Derived>::Flags, \
+ CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \
+ SizeAtCompileTime = Base::SizeAtCompileTime, \
+ IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
+
+#define EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(Derived) \
+_EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived>)
+
+enum SparseBackend {
+ DefaultBackend,
+ Taucs,
+ Cholmod,
+ SuperLU,
+ UmfPack
+};
+
+// solver flags
+enum {
+ CompleteFactorization = 0x0000, // the default
+ IncompleteFactorization = 0x0001,
+ MemoryEfficient = 0x0002,
+
+ // For LLT Cholesky:
+ SupernodalMultifrontal = 0x0010,
+ SupernodalLeftLooking = 0x0020,
+
+ // Ordering methods:
+ NaturalOrdering = 0x0100, // the default
+ MinimumDegree_AT_PLUS_A = 0x0200,
+ MinimumDegree_ATA = 0x0300,
+ ColApproxMinimumDegree = 0x0400,
+ Metis = 0x0500,
+ Scotch = 0x0600,
+ Chaco = 0x0700,
+ OrderingMask = 0x0f00
+};
+
+template<typename Derived> class SparseMatrixBase;
+template<typename _Scalar, int _Flags = 0> class SparseMatrix;
+template<typename _Scalar, int _Flags = 0> class DynamicSparseMatrix;
+template<typename _Scalar, int _Flags = 0> class SparseVector;
+template<typename _Scalar, int _Flags = 0> class MappedSparseMatrix;
+
+template<typename MatrixType> class SparseTranspose;
+template<typename MatrixType, int Size> class SparseInnerVectorSet;
+template<typename Derived> class SparseCwise;
+template<typename UnaryOp, typename MatrixType> class SparseCwiseUnaryOp;
+template<typename BinaryOp, typename Lhs, typename Rhs> class SparseCwiseBinaryOp;
+template<typename ExpressionType,
+ unsigned int Added, unsigned int Removed> class SparseFlagged;
+template<typename Lhs, typename Rhs> class SparseDiagonalProduct;
+
+template<typename Lhs, typename Rhs> struct ei_sparse_product_mode;
+template<typename Lhs, typename Rhs, int ProductMode = ei_sparse_product_mode<Lhs,Rhs>::value> struct SparseProductReturnType;
+
+const int CoherentAccessPattern = 0x1;
+const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern;
+const int OuterRandomAccessPattern = 0x4 | CoherentAccessPattern;
+const int RandomAccessPattern = 0x8 | OuterRandomAccessPattern | InnerRandomAccessPattern;
+
+// const int AccessPatternNotSupported = 0x0;
+// const int AccessPatternSupported = 0x1;
+//
+// template<typename MatrixType, int AccessPattern> struct ei_support_access_pattern
+// {
+// enum { ret = (int(ei_traits<MatrixType>::SupportedAccessPatterns) & AccessPattern) == AccessPattern
+// ? AccessPatternSupported
+// : AccessPatternNotSupported
+// };
+// };
+
+template<typename T> class ei_eval<T,IsSparse>
+{
+ typedef typename ei_traits<T>::Scalar _Scalar;
+ enum {
+ _Flags = ei_traits<T>::Flags
+ };
+
+ public:
+ typedef SparseMatrix<_Scalar, _Flags> type;
+};
+
+#endif // EIGEN_SPARSEUTIL_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseVector.h b/extern/Eigen2/Eigen/src/Sparse/SparseVector.h
new file mode 100644
index 00000000000..8e5a6efeda8
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SparseVector.h
@@ -0,0 +1,365 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSEVECTOR_H
+#define EIGEN_SPARSEVECTOR_H
+
+/** \class SparseVector
+ *
+ * \brief a sparse vector class
+ *
+ * \param _Scalar the scalar type, i.e. the type of the coefficients
+ *
+ * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
+ *
+ */
+template<typename _Scalar, int _Flags>
+struct ei_traits<SparseVector<_Scalar, _Flags> >
+{
+ typedef _Scalar Scalar;
+ enum {
+ IsColVector = _Flags & RowMajorBit ? 0 : 1,
+
+ RowsAtCompileTime = IsColVector ? Dynamic : 1,
+ ColsAtCompileTime = IsColVector ? 1 : Dynamic,
+ MaxRowsAtCompileTime = RowsAtCompileTime,
+ MaxColsAtCompileTime = ColsAtCompileTime,
+ Flags = SparseBit | _Flags,
+ CoeffReadCost = NumTraits<Scalar>::ReadCost,
+ SupportedAccessPatterns = InnerRandomAccessPattern
+ };
+};
+
+template<typename _Scalar, int _Flags>
+class SparseVector
+ : public SparseMatrixBase<SparseVector<_Scalar, _Flags> >
+{
+ public:
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseVector)
+ EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
+ EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
+// EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, =)
+
+ protected:
+ public:
+
+ typedef SparseMatrixBase<SparseVector> SparseBase;
+ enum { IsColVector = ei_traits<SparseVector>::IsColVector };
+
+ CompressedStorage<Scalar> m_data;
+ int m_size;
+
+ CompressedStorage<Scalar>& _data() { return m_data; }
+ CompressedStorage<Scalar>& _data() const { return m_data; }
+
+ public:
+
+ EIGEN_STRONG_INLINE int rows() const { return IsColVector ? m_size : 1; }
+ EIGEN_STRONG_INLINE int cols() const { return IsColVector ? 1 : m_size; }
+ EIGEN_STRONG_INLINE int innerSize() const { return m_size; }
+ EIGEN_STRONG_INLINE int outerSize() const { return 1; }
+ EIGEN_STRONG_INLINE int innerNonZeros(int j) const { ei_assert(j==0); return m_size; }
+
+ EIGEN_STRONG_INLINE const Scalar* _valuePtr() const { return &m_data.value(0); }
+ EIGEN_STRONG_INLINE Scalar* _valuePtr() { return &m_data.value(0); }
+
+ EIGEN_STRONG_INLINE const int* _innerIndexPtr() const { return &m_data.index(0); }
+ EIGEN_STRONG_INLINE int* _innerIndexPtr() { return &m_data.index(0); }
+
+ inline Scalar coeff(int row, int col) const
+ {
+ ei_assert((IsColVector ? col : row)==0);
+ return coeff(IsColVector ? row : col);
+ }
+ inline Scalar coeff(int i) const { return m_data.at(i); }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ ei_assert((IsColVector ? col : row)==0);
+ return coeff(IsColVector ? row : col);
+ }
+
+ /** \returns a reference to the coefficient value at given index \a i
+ * This operation involes a log(rho*size) binary search. If the coefficient does not
+ * exist yet, then a sorted insertion into a sequential buffer is performed.
+ *
+ * This insertion might be very costly if the number of nonzeros above \a i is large.
+ */
+ inline Scalar& coeffRef(int i)
+ {
+ return m_data.atWithInsertion(i);
+ }
+
+ public:
+
+ class InnerIterator;
+
+ inline void setZero() { m_data.clear(); }
+
+ /** \returns the number of non zero coefficients */
+ inline int nonZeros() const { return m_data.size(); }
+
+ /**
+ */
+ inline void reserve(int reserveSize) { m_data.reserve(reserveSize); }
+
+ inline void startFill(int reserve)
+ {
+ setZero();
+ m_data.reserve(reserve);
+ }
+
+ /**
+ */
+ inline Scalar& fill(int r, int c)
+ {
+ ei_assert(r==0 || c==0);
+ return fill(IsColVector ? r : c);
+ }
+
+ inline Scalar& fill(int i)
+ {
+ m_data.append(0, i);
+ return m_data.value(m_data.size()-1);
+ }
+
+ inline Scalar& fillrand(int r, int c)
+ {
+ ei_assert(r==0 || c==0);
+ return fillrand(IsColVector ? r : c);
+ }
+
+ /** Like fill() but with random coordinates.
+ */
+ inline Scalar& fillrand(int i)
+ {
+ int startId = 0;
+ int id = m_data.size() - 1;
+ m_data.resize(id+2,1);
+
+ while ( (id >= startId) && (m_data.index(id) > i) )
+ {
+ m_data.index(id+1) = m_data.index(id);
+ m_data.value(id+1) = m_data.value(id);
+ --id;
+ }
+ m_data.index(id+1) = i;
+ m_data.value(id+1) = 0;
+ return m_data.value(id+1);
+ }
+
+ inline void endFill() {}
+
+ void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ {
+ m_data.prune(reference,epsilon);
+ }
+
+ void resize(int rows, int cols)
+ {
+ ei_assert(rows==1 || cols==1);
+ resize(IsColVector ? rows : cols);
+ }
+
+ void resize(int newSize)
+ {
+ m_size = newSize;
+ m_data.clear();
+ }
+
+ void resizeNonZeros(int size) { m_data.resize(size); }
+
+ inline SparseVector() : m_size(0) { resize(0); }
+
+ inline SparseVector(int size) : m_size(0) { resize(size); }
+
+ inline SparseVector(int rows, int cols) : m_size(0) { resize(rows,cols); }
+
+ template<typename OtherDerived>
+ inline SparseVector(const MatrixBase<OtherDerived>& other)
+ : m_size(0)
+ {
+ *this = other.derived();
+ }
+
+ template<typename OtherDerived>
+ inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
+ : m_size(0)
+ {
+ *this = other.derived();
+ }
+
+ inline SparseVector(const SparseVector& other)
+ : m_size(0)
+ {
+ *this = other.derived();
+ }
+
+ inline void swap(SparseVector& other)
+ {
+ std::swap(m_size, other.m_size);
+ m_data.swap(other.m_data);
+ }
+
+ inline SparseVector& operator=(const SparseVector& other)
+ {
+ if (other.isRValue())
+ {
+ swap(other.const_cast_derived());
+ }
+ else
+ {
+ resize(other.size());
+ m_data = other.m_data;
+ }
+ return *this;
+ }
+
+ template<typename OtherDerived>
+ inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ return Base::operator=(other);
+ }
+
+// const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
+// if (needToTranspose)
+// {
+// // two passes algorithm:
+// // 1 - compute the number of coeffs per dest inner vector
+// // 2 - do the actual copy/eval
+// // Since each coeff of the rhs has to be evaluated twice, let's evauluate it if needed
+// typedef typename ei_nested<OtherDerived,2>::type OtherCopy;
+// OtherCopy otherCopy(other.derived());
+// typedef typename ei_cleantype<OtherCopy>::type _OtherCopy;
+//
+// resize(other.rows(), other.cols());
+// Eigen::Map<VectorXi>(m_outerIndex,outerSize()).setZero();
+// // pass 1
+// // FIXME the above copy could be merged with that pass
+// for (int j=0; j<otherCopy.outerSize(); ++j)
+// for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
+// ++m_outerIndex[it.index()];
+//
+// // prefix sum
+// int count = 0;
+// VectorXi positions(outerSize());
+// for (int j=0; j<outerSize(); ++j)
+// {
+// int tmp = m_outerIndex[j];
+// m_outerIndex[j] = count;
+// positions[j] = count;
+// count += tmp;
+// }
+// m_outerIndex[outerSize()] = count;
+// // alloc
+// m_data.resize(count);
+// // pass 2
+// for (int j=0; j<otherCopy.outerSize(); ++j)
+// for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
+// {
+// int pos = positions[it.index()]++;
+// m_data.index(pos) = j;
+// m_data.value(pos) = it.value();
+// }
+//
+// return *this;
+// }
+// else
+// {
+// // there is no special optimization
+// return SparseMatrixBase<SparseMatrix>::operator=(other.derived());
+// }
+// }
+
+ friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
+ {
+ for (unsigned int i=0; i<m.nonZeros(); ++i)
+ s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
+ s << std::endl;
+ return s;
+ }
+
+ // this specialized version does not seems to be faster
+// Scalar dot(const SparseVector& other) const
+// {
+// int i=0, j=0;
+// Scalar res = 0;
+// asm("#begindot");
+// while (i<nonZeros() && j<other.nonZeros())
+// {
+// if (m_data.index(i)==other.m_data.index(j))
+// {
+// res += m_data.value(i) * ei_conj(other.m_data.value(j));
+// ++i; ++j;
+// }
+// else if (m_data.index(i)<other.m_data.index(j))
+// ++i;
+// else
+// ++j;
+// }
+// asm("#enddot");
+// return res;
+// }
+
+ /** Destructor */
+ inline ~SparseVector() {}
+};
+
+template<typename Scalar, int _Flags>
+class SparseVector<Scalar,_Flags>::InnerIterator
+{
+ public:
+ InnerIterator(const SparseVector& vec, int outer=0)
+ : m_data(vec.m_data), m_id(0), m_end(m_data.size())
+ {
+ ei_assert(outer==0);
+ }
+
+ InnerIterator(const CompressedStorage<Scalar>& data)
+ : m_data(data), m_id(0), m_end(m_data.size())
+ {}
+
+ template<unsigned int Added, unsigned int Removed>
+ InnerIterator(const Flagged<SparseVector,Added,Removed>& vec, int outer)
+ : m_data(vec._expression().m_data), m_id(0), m_end(m_data.size())
+ {}
+
+ inline InnerIterator& operator++() { m_id++; return *this; }
+
+ inline Scalar value() const { return m_data.value(m_id); }
+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id)); }
+
+ inline int index() const { return m_data.index(m_id); }
+ inline int row() const { return IsColVector ? index() : 0; }
+ inline int col() const { return IsColVector ? 0 : index(); }
+
+ inline operator bool() const { return (m_id < m_end); }
+
+ protected:
+ const CompressedStorage<Scalar>& m_data;
+ int m_id;
+ const int m_end;
+};
+
+#endif // EIGEN_SPARSEVECTOR_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/SuperLUSupport.h b/extern/Eigen2/Eigen/src/Sparse/SuperLUSupport.h
new file mode 100644
index 00000000000..3c9a4fcced6
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/SuperLUSupport.h
@@ -0,0 +1,565 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SUPERLUSUPPORT_H
+#define EIGEN_SUPERLUSUPPORT_H
+
+// declaration of gssvx taken from GMM++
+#define DECL_GSSVX(NAMESPACE,FNAME,FLOATTYPE,KEYTYPE) \
+ inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, \
+ int *perm_c, int *perm_r, int *etree, char *equed, \
+ FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \
+ SuperMatrix *U, void *work, int lwork, \
+ SuperMatrix *B, SuperMatrix *X, \
+ FLOATTYPE *recip_pivot_growth, \
+ FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, \
+ SuperLUStat_t *stats, int *info, KEYTYPE) { \
+ using namespace NAMESPACE; \
+ mem_usage_t mem_usage; \
+ NAMESPACE::FNAME(options, A, perm_c, perm_r, etree, equed, R, C, L, \
+ U, work, lwork, B, X, recip_pivot_growth, rcond, \
+ ferr, berr, &mem_usage, stats, info); \
+ return mem_usage.for_lu; /* bytes used by the factor storage */ \
+ }
+
+DECL_GSSVX(SuperLU_S,sgssvx,float,float)
+DECL_GSSVX(SuperLU_C,cgssvx,float,std::complex<float>)
+DECL_GSSVX(SuperLU_D,dgssvx,double,double)
+DECL_GSSVX(SuperLU_Z,zgssvx,double,std::complex<double>)
+
+template<typename MatrixType>
+struct SluMatrixMapHelper;
+
+/** \internal
+ *
+ * A wrapper class for SuperLU matrices. It supports only compressed sparse matrices
+ * and dense matrices. Supernodal and other fancy format are not supported by this wrapper.
+ *
+ * This wrapper class mainly aims to avoids the need of dynamic allocation of the storage structure.
+ */
+struct SluMatrix : SuperMatrix
+{
+ SluMatrix()
+ {
+ Store = &storage;
+ }
+
+ SluMatrix(const SluMatrix& other)
+ : SuperMatrix(other)
+ {
+ Store = &storage;
+ storage = other.storage;
+ }
+
+ SluMatrix& operator=(const SluMatrix& other)
+ {
+ SuperMatrix::operator=(static_cast<const SuperMatrix&>(other));
+ Store = &storage;
+ storage = other.storage;
+ return *this;
+ }
+
+ struct
+ {
+ union {int nnz;int lda;};
+ void *values;
+ int *innerInd;
+ int *outerInd;
+ } storage;
+
+ void setStorageType(Stype_t t)
+ {
+ Stype = t;
+ if (t==SLU_NC || t==SLU_NR || t==SLU_DN)
+ Store = &storage;
+ else
+ {
+ ei_assert(false && "storage type not supported");
+ Store = 0;
+ }
+ }
+
+ template<typename Scalar>
+ void setScalarType()
+ {
+ if (ei_is_same_type<Scalar,float>::ret)
+ Dtype = SLU_S;
+ else if (ei_is_same_type<Scalar,double>::ret)
+ Dtype = SLU_D;
+ else if (ei_is_same_type<Scalar,std::complex<float> >::ret)
+ Dtype = SLU_C;
+ else if (ei_is_same_type<Scalar,std::complex<double> >::ret)
+ Dtype = SLU_Z;
+ else
+ {
+ ei_assert(false && "Scalar type not supported by SuperLU");
+ }
+ }
+
+ template<typename Scalar, int Rows, int Cols, int Options, int MRows, int MCols>
+ static SluMatrix Map(Matrix<Scalar,Rows,Cols,Options,MRows,MCols>& mat)
+ {
+ typedef Matrix<Scalar,Rows,Cols,Options,MRows,MCols> MatrixType;
+ ei_assert( ((Options&RowMajor)!=RowMajor) && "row-major dense matrices is not supported by SuperLU");
+ SluMatrix res;
+ res.setStorageType(SLU_DN);
+ res.setScalarType<Scalar>();
+ res.Mtype = SLU_GE;
+
+ res.nrow = mat.rows();
+ res.ncol = mat.cols();
+
+ res.storage.lda = mat.stride();
+ res.storage.values = mat.data();
+ return res;
+ }
+
+ template<typename MatrixType>
+ static SluMatrix Map(SparseMatrixBase<MatrixType>& mat)
+ {
+ SluMatrix res;
+ if ((MatrixType::Flags&RowMajorBit)==RowMajorBit)
+ {
+ res.setStorageType(SLU_NR);
+ res.nrow = mat.cols();
+ res.ncol = mat.rows();
+ }
+ else
+ {
+ res.setStorageType(SLU_NC);
+ res.nrow = mat.rows();
+ res.ncol = mat.cols();
+ }
+
+ res.Mtype = SLU_GE;
+
+ res.storage.nnz = mat.nonZeros();
+ res.storage.values = mat.derived()._valuePtr();
+ res.storage.innerInd = mat.derived()._innerIndexPtr();
+ res.storage.outerInd = mat.derived()._outerIndexPtr();
+
+ res.setScalarType<typename MatrixType::Scalar>();
+
+ // FIXME the following is not very accurate
+ if (MatrixType::Flags & UpperTriangular)
+ res.Mtype = SLU_TRU;
+ if (MatrixType::Flags & LowerTriangular)
+ res.Mtype = SLU_TRL;
+ if (MatrixType::Flags & SelfAdjoint)
+ ei_assert(false && "SelfAdjoint matrix shape not supported by SuperLU");
+ return res;
+ }
+};
+
+template<typename Scalar, int Rows, int Cols, int Options, int MRows, int MCols>
+struct SluMatrixMapHelper<Matrix<Scalar,Rows,Cols,Options,MRows,MCols> >
+{
+ typedef Matrix<Scalar,Rows,Cols,Options,MRows,MCols> MatrixType;
+ static void run(MatrixType& mat, SluMatrix& res)
+ {
+ ei_assert( ((Options&RowMajor)!=RowMajor) && "row-major dense matrices is not supported by SuperLU");
+ res.setStorageType(SLU_DN);
+ res.setScalarType<Scalar>();
+ res.Mtype = SLU_GE;
+
+ res.nrow = mat.rows();
+ res.ncol = mat.cols();
+
+ res.storage.lda = mat.stride();
+ res.storage.values = mat.data();
+ }
+};
+
+template<typename Derived>
+struct SluMatrixMapHelper<SparseMatrixBase<Derived> >
+{
+ typedef Derived MatrixType;
+ static void run(MatrixType& mat, SluMatrix& res)
+ {
+ if ((MatrixType::Flags&RowMajorBit)==RowMajorBit)
+ {
+ res.setStorageType(SLU_NR);
+ res.nrow = mat.cols();
+ res.ncol = mat.rows();
+ }
+ else
+ {
+ res.setStorageType(SLU_NC);
+ res.nrow = mat.rows();
+ res.ncol = mat.cols();
+ }
+
+ res.Mtype = SLU_GE;
+
+ res.storage.nnz = mat.nonZeros();
+ res.storage.values = mat._valuePtr();
+ res.storage.innerInd = mat._innerIndexPtr();
+ res.storage.outerInd = mat._outerIndexPtr();
+
+ res.setScalarType<typename MatrixType::Scalar>();
+
+ // FIXME the following is not very accurate
+ if (MatrixType::Flags & UpperTriangular)
+ res.Mtype = SLU_TRU;
+ if (MatrixType::Flags & LowerTriangular)
+ res.Mtype = SLU_TRL;
+ if (MatrixType::Flags & SelfAdjoint)
+ ei_assert(false && "SelfAdjoint matrix shape not supported by SuperLU");
+ }
+};
+
+template<typename Derived>
+SluMatrix SparseMatrixBase<Derived>::asSluMatrix()
+{
+ return SluMatrix::Map(derived());
+}
+
+/** View a Super LU matrix as an Eigen expression */
+template<typename Scalar, int Flags>
+MappedSparseMatrix<Scalar,Flags>::MappedSparseMatrix(SluMatrix& sluMat)
+{
+ if ((Flags&RowMajorBit)==RowMajorBit)
+ {
+ assert(sluMat.Stype == SLU_NR);
+ m_innerSize = sluMat.ncol;
+ m_outerSize = sluMat.nrow;
+ }
+ else
+ {
+ assert(sluMat.Stype == SLU_NC);
+ m_innerSize = sluMat.nrow;
+ m_outerSize = sluMat.ncol;
+ }
+ m_outerIndex = sluMat.storage.outerInd;
+ m_innerIndices = sluMat.storage.innerInd;
+ m_values = reinterpret_cast<Scalar*>(sluMat.storage.values);
+ m_nnz = sluMat.storage.outerInd[m_outerSize];
+}
+
+template<typename MatrixType>
+class SparseLU<MatrixType,SuperLU> : public SparseLU<MatrixType>
+{
+ protected:
+ typedef SparseLU<MatrixType> Base;
+ typedef typename Base::Scalar Scalar;
+ typedef typename Base::RealScalar RealScalar;
+ typedef Matrix<Scalar,Dynamic,1> Vector;
+ typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
+ typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
+ typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> LMatrixType;
+ typedef SparseMatrix<Scalar,UpperTriangular> UMatrixType;
+ using Base::m_flags;
+ using Base::m_status;
+
+ public:
+
+ SparseLU(int flags = NaturalOrdering)
+ : Base(flags)
+ {
+ }
+
+ SparseLU(const MatrixType& matrix, int flags = NaturalOrdering)
+ : Base(flags)
+ {
+ compute(matrix);
+ }
+
+ ~SparseLU()
+ {
+ }
+
+ inline const LMatrixType& matrixL() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_l;
+ }
+
+ inline const UMatrixType& matrixU() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_u;
+ }
+
+ inline const IntColVectorType& permutationP() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_p;
+ }
+
+ inline const IntRowVectorType& permutationQ() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_q;
+ }
+
+ Scalar determinant() const;
+
+ template<typename BDerived, typename XDerived>
+ bool solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+
+ void extractData() const;
+
+ protected:
+ // cached data to reduce reallocation, etc.
+ mutable LMatrixType m_l;
+ mutable UMatrixType m_u;
+ mutable IntColVectorType m_p;
+ mutable IntRowVectorType m_q;
+
+ mutable SparseMatrix<Scalar> m_matrix;
+ mutable SluMatrix m_sluA;
+ mutable SuperMatrix m_sluL, m_sluU;
+ mutable SluMatrix m_sluB, m_sluX;
+ mutable SuperLUStat_t m_sluStat;
+ mutable superlu_options_t m_sluOptions;
+ mutable std::vector<int> m_sluEtree;
+ mutable std::vector<RealScalar> m_sluRscale, m_sluCscale;
+ mutable std::vector<RealScalar> m_sluFerr, m_sluBerr;
+ mutable char m_sluEqued;
+ mutable bool m_extractedDataAreDirty;
+};
+
+template<typename MatrixType>
+void SparseLU<MatrixType,SuperLU>::compute(const MatrixType& a)
+{
+ const int size = a.rows();
+ m_matrix = a;
+
+ set_default_options(&m_sluOptions);
+ m_sluOptions.ColPerm = NATURAL;
+ m_sluOptions.PrintStat = NO;
+ m_sluOptions.ConditionNumber = NO;
+ m_sluOptions.Trans = NOTRANS;
+ // m_sluOptions.Equil = NO;
+
+ switch (Base::orderingMethod())
+ {
+ case NaturalOrdering : m_sluOptions.ColPerm = NATURAL; break;
+ case MinimumDegree_AT_PLUS_A : m_sluOptions.ColPerm = MMD_AT_PLUS_A; break;
+ case MinimumDegree_ATA : m_sluOptions.ColPerm = MMD_ATA; break;
+ case ColApproxMinimumDegree : m_sluOptions.ColPerm = COLAMD; break;
+ default:
+ std::cerr << "Eigen: ordering method \"" << Base::orderingMethod() << "\" not supported by the SuperLU backend\n";
+ m_sluOptions.ColPerm = NATURAL;
+ };
+
+ m_sluA = m_matrix.asSluMatrix();
+ memset(&m_sluL,0,sizeof m_sluL);
+ memset(&m_sluU,0,sizeof m_sluU);
+ m_sluEqued = 'B';
+ int info = 0;
+
+ m_p.resize(size);
+ m_q.resize(size);
+ m_sluRscale.resize(size);
+ m_sluCscale.resize(size);
+ m_sluEtree.resize(size);
+
+ RealScalar recip_pivot_gross, rcond;
+ RealScalar ferr, berr;
+
+ // set empty B and X
+ m_sluB.setStorageType(SLU_DN);
+ m_sluB.setScalarType<Scalar>();
+ m_sluB.Mtype = SLU_GE;
+ m_sluB.storage.values = 0;
+ m_sluB.nrow = m_sluB.ncol = 0;
+ m_sluB.storage.lda = size;
+ m_sluX = m_sluB;
+
+ StatInit(&m_sluStat);
+ SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0],
+ &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0],
+ &m_sluL, &m_sluU,
+ NULL, 0,
+ &m_sluB, &m_sluX,
+ &recip_pivot_gross, &rcond,
+ &ferr, &berr,
+ &m_sluStat, &info, Scalar());
+ StatFree(&m_sluStat);
+
+ m_extractedDataAreDirty = true;
+
+ // FIXME how to better check for errors ???
+ Base::m_succeeded = (info == 0);
+}
+
+template<typename MatrixType>
+template<typename BDerived,typename XDerived>
+bool SparseLU<MatrixType,SuperLU>::solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> *x) const
+{
+ const int size = m_matrix.rows();
+ const int rhsCols = b.cols();
+ ei_assert(size==b.rows());
+
+ m_sluOptions.Fact = FACTORED;
+ m_sluOptions.IterRefine = NOREFINE;
+
+ m_sluFerr.resize(rhsCols);
+ m_sluBerr.resize(rhsCols);
+ m_sluB = SluMatrix::Map(b.const_cast_derived());
+ m_sluX = SluMatrix::Map(x->derived());
+
+ StatInit(&m_sluStat);
+ int info = 0;
+ RealScalar recip_pivot_gross, rcond;
+ SuperLU_gssvx(
+ &m_sluOptions, &m_sluA,
+ m_q.data(), m_p.data(),
+ &m_sluEtree[0], &m_sluEqued,
+ &m_sluRscale[0], &m_sluCscale[0],
+ &m_sluL, &m_sluU,
+ NULL, 0,
+ &m_sluB, &m_sluX,
+ &recip_pivot_gross, &rcond,
+ &m_sluFerr[0], &m_sluBerr[0],
+ &m_sluStat, &info, Scalar());
+ StatFree(&m_sluStat);
+
+ return info==0;
+}
+
+//
+// the code of this extractData() function has been adapted from the SuperLU's Matlab support code,
+//
+// Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+//
+// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+//
+template<typename MatrixType>
+void SparseLU<MatrixType,SuperLU>::extractData() const
+{
+ if (m_extractedDataAreDirty)
+ {
+ int upper;
+ int fsupc, istart, nsupr;
+ int lastl = 0, lastu = 0;
+ SCformat *Lstore = static_cast<SCformat*>(m_sluL.Store);
+ NCformat *Ustore = static_cast<NCformat*>(m_sluU.Store);
+ Scalar *SNptr;
+
+ const int size = m_matrix.rows();
+ m_l.resize(size,size);
+ m_l.resizeNonZeros(Lstore->nnz);
+ m_u.resize(size,size);
+ m_u.resizeNonZeros(Ustore->nnz);
+
+ int* Lcol = m_l._outerIndexPtr();
+ int* Lrow = m_l._innerIndexPtr();
+ Scalar* Lval = m_l._valuePtr();
+
+ int* Ucol = m_u._outerIndexPtr();
+ int* Urow = m_u._innerIndexPtr();
+ Scalar* Uval = m_u._valuePtr();
+
+ Ucol[0] = 0;
+ Ucol[0] = 0;
+
+ /* for each supernode */
+ for (int k = 0; k <= Lstore->nsuper; ++k)
+ {
+ fsupc = L_FST_SUPC(k);
+ istart = L_SUB_START(fsupc);
+ nsupr = L_SUB_START(fsupc+1) - istart;
+ upper = 1;
+
+ /* for each column in the supernode */
+ for (int j = fsupc; j < L_FST_SUPC(k+1); ++j)
+ {
+ SNptr = &((Scalar*)Lstore->nzval)[L_NZ_START(j)];
+
+ /* Extract U */
+ for (int i = U_NZ_START(j); i < U_NZ_START(j+1); ++i)
+ {
+ Uval[lastu] = ((Scalar*)Ustore->nzval)[i];
+ /* Matlab doesn't like explicit zero. */
+ if (Uval[lastu] != 0.0)
+ Urow[lastu++] = U_SUB(i);
+ }
+ for (int i = 0; i < upper; ++i)
+ {
+ /* upper triangle in the supernode */
+ Uval[lastu] = SNptr[i];
+ /* Matlab doesn't like explicit zero. */
+ if (Uval[lastu] != 0.0)
+ Urow[lastu++] = L_SUB(istart+i);
+ }
+ Ucol[j+1] = lastu;
+
+ /* Extract L */
+ Lval[lastl] = 1.0; /* unit diagonal */
+ Lrow[lastl++] = L_SUB(istart + upper - 1);
+ for (int i = upper; i < nsupr; ++i)
+ {
+ Lval[lastl] = SNptr[i];
+ /* Matlab doesn't like explicit zero. */
+ if (Lval[lastl] != 0.0)
+ Lrow[lastl++] = L_SUB(istart+i);
+ }
+ Lcol[j+1] = lastl;
+
+ ++upper;
+ } /* for j ... */
+
+ } /* for k ... */
+
+ // squeeze the matrices :
+ m_l.resizeNonZeros(lastl);
+ m_u.resizeNonZeros(lastu);
+
+ m_extractedDataAreDirty = false;
+ }
+}
+
+template<typename MatrixType>
+typename SparseLU<MatrixType,SuperLU>::Scalar SparseLU<MatrixType,SuperLU>::determinant() const
+{
+ if (m_extractedDataAreDirty)
+ extractData();
+
+ // TODO this code coule be moved to the default/base backend
+ // FIXME perhaps we have to take into account the scale factors m_sluRscale and m_sluCscale ???
+ Scalar det = Scalar(1);
+ for (int j=0; j<m_u.cols(); ++j)
+ {
+ if (m_u._outerIndexPtr()[j+1]-m_u._outerIndexPtr()[j] > 0)
+ {
+ int lastId = m_u._outerIndexPtr()[j+1]-1;
+ ei_assert(m_u._innerIndexPtr()[lastId]<=j);
+ if (m_u._innerIndexPtr()[lastId]==j)
+ {
+ det *= m_u._valuePtr()[lastId];
+ }
+ }
+ // std::cout << m_sluRscale[j] << " " << m_sluCscale[j] << " ";
+ }
+ return det;
+}
+
+#endif // EIGEN_SUPERLUSUPPORT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/TaucsSupport.h b/extern/Eigen2/Eigen/src/Sparse/TaucsSupport.h
new file mode 100644
index 00000000000..4dddca7b622
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/TaucsSupport.h
@@ -0,0 +1,210 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_TAUCSSUPPORT_H
+#define EIGEN_TAUCSSUPPORT_H
+
+template<typename Derived>
+taucs_ccs_matrix SparseMatrixBase<Derived>::asTaucsMatrix()
+{
+ taucs_ccs_matrix res;
+ res.n = cols();
+ res.m = rows();
+ res.flags = 0;
+ res.colptr = derived()._outerIndexPtr();
+ res.rowind = derived()._innerIndexPtr();
+ res.values.v = derived()._valuePtr();
+ if (ei_is_same_type<Scalar,int>::ret)
+ res.flags |= TAUCS_INT;
+ else if (ei_is_same_type<Scalar,float>::ret)
+ res.flags |= TAUCS_SINGLE;
+ else if (ei_is_same_type<Scalar,double>::ret)
+ res.flags |= TAUCS_DOUBLE;
+ else if (ei_is_same_type<Scalar,std::complex<float> >::ret)
+ res.flags |= TAUCS_SCOMPLEX;
+ else if (ei_is_same_type<Scalar,std::complex<double> >::ret)
+ res.flags |= TAUCS_DCOMPLEX;
+ else
+ {
+ ei_assert(false && "Scalar type not supported by TAUCS");
+ }
+
+ if (Flags & UpperTriangular)
+ res.flags |= TAUCS_UPPER;
+ if (Flags & LowerTriangular)
+ res.flags |= TAUCS_LOWER;
+ if (Flags & SelfAdjoint)
+ res.flags |= (NumTraits<Scalar>::IsComplex ? TAUCS_HERMITIAN : TAUCS_SYMMETRIC);
+ else if ((Flags & UpperTriangular) || (Flags & LowerTriangular))
+ res.flags |= TAUCS_TRIANGULAR;
+
+ return res;
+}
+
+template<typename Scalar, int Flags>
+MappedSparseMatrix<Scalar,Flags>::MappedSparseMatrix(taucs_ccs_matrix& taucsMat)
+{
+ m_innerSize = taucsMat.m;
+ m_outerSize = taucsMat.n;
+ m_outerIndex = taucsMat.colptr;
+ m_innerIndices = taucsMat.rowind;
+ m_values = reinterpret_cast<Scalar*>(taucsMat.values.v);
+ m_nnz = taucsMat.colptr[taucsMat.n];
+}
+
+template<typename MatrixType>
+class SparseLLT<MatrixType,Taucs> : public SparseLLT<MatrixType>
+{
+ protected:
+ typedef SparseLLT<MatrixType> Base;
+ typedef typename Base::Scalar Scalar;
+ typedef typename Base::RealScalar RealScalar;
+ using Base::MatrixLIsDirty;
+ using Base::SupernodalFactorIsDirty;
+ using Base::m_flags;
+ using Base::m_matrix;
+ using Base::m_status;
+
+ public:
+
+ SparseLLT(int flags = 0)
+ : Base(flags), m_taucsSupernodalFactor(0)
+ {
+ }
+
+ SparseLLT(const MatrixType& matrix, int flags = 0)
+ : Base(flags), m_taucsSupernodalFactor(0)
+ {
+ compute(matrix);
+ }
+
+ ~SparseLLT()
+ {
+ if (m_taucsSupernodalFactor)
+ taucs_supernodal_factor_free(m_taucsSupernodalFactor);
+ }
+
+ inline const typename Base::CholMatrixType& matrixL(void) const;
+
+ template<typename Derived>
+ void solveInPlace(MatrixBase<Derived> &b) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+ void* m_taucsSupernodalFactor;
+};
+
+template<typename MatrixType>
+void SparseLLT<MatrixType,Taucs>::compute(const MatrixType& a)
+{
+ if (m_taucsSupernodalFactor)
+ {
+ taucs_supernodal_factor_free(m_taucsSupernodalFactor);
+ m_taucsSupernodalFactor = 0;
+ }
+
+ if (m_flags & IncompleteFactorization)
+ {
+ taucs_ccs_matrix taucsMatA = const_cast<MatrixType&>(a).asTaucsMatrix();
+ taucs_ccs_matrix* taucsRes = taucs_ccs_factor_llt(&taucsMatA, Base::m_precision, 0);
+ // the matrix returned by Taucs is not necessarily sorted,
+ // so let's copy it in two steps
+ DynamicSparseMatrix<Scalar,RowMajor> tmp = MappedSparseMatrix<Scalar>(*taucsRes);
+ m_matrix = tmp;
+ free(taucsRes);
+ m_status = (m_status & ~(CompleteFactorization|MatrixLIsDirty))
+ | IncompleteFactorization
+ | SupernodalFactorIsDirty;
+ }
+ else
+ {
+ taucs_ccs_matrix taucsMatA = const_cast<MatrixType&>(a).asTaucsMatrix();
+ if ( (m_flags & SupernodalLeftLooking)
+ || ((!(m_flags & SupernodalMultifrontal)) && (m_flags & MemoryEfficient)) )
+ {
+ m_taucsSupernodalFactor = taucs_ccs_factor_llt_ll(&taucsMatA);
+ }
+ else
+ {
+ // use the faster Multifrontal routine
+ m_taucsSupernodalFactor = taucs_ccs_factor_llt_mf(&taucsMatA);
+ }
+ m_status = (m_status & ~IncompleteFactorization) | CompleteFactorization | MatrixLIsDirty;
+ }
+}
+
+template<typename MatrixType>
+inline const typename SparseLLT<MatrixType>::CholMatrixType&
+SparseLLT<MatrixType,Taucs>::matrixL() const
+{
+ if (m_status & MatrixLIsDirty)
+ {
+ ei_assert(!(m_status & SupernodalFactorIsDirty));
+
+ taucs_ccs_matrix* taucsL = taucs_supernodal_factor_to_ccs(m_taucsSupernodalFactor);
+
+ // the matrix returned by Taucs is not necessarily sorted,
+ // so let's copy it in two steps
+ DynamicSparseMatrix<Scalar,RowMajor> tmp = MappedSparseMatrix<Scalar>(*taucsL);
+ const_cast<typename Base::CholMatrixType&>(m_matrix) = tmp;
+ free(taucsL);
+ m_status = (m_status & ~MatrixLIsDirty);
+ }
+ return m_matrix;
+}
+
+template<typename MatrixType>
+template<typename Derived>
+void SparseLLT<MatrixType,Taucs>::solveInPlace(MatrixBase<Derived> &b) const
+{
+ bool inputIsCompatibleWithTaucs = (Derived::Flags&RowMajorBit)==0;
+
+ if (!inputIsCompatibleWithTaucs)
+ {
+ matrixL();
+ Base::solveInPlace(b);
+ }
+ else if (m_flags & IncompleteFactorization)
+ {
+ taucs_ccs_matrix taucsLLT = const_cast<typename Base::CholMatrixType&>(m_matrix).asTaucsMatrix();
+ typename ei_plain_matrix_type<Derived>::type x(b.rows());
+ for (int j=0; j<b.cols(); ++j)
+ {
+ taucs_ccs_solve_llt(&taucsLLT,x.data(),&b.col(j).coeffRef(0));
+ b.col(j) = x;
+ }
+ }
+ else
+ {
+ typename ei_plain_matrix_type<Derived>::type x(b.rows());
+ for (int j=0; j<b.cols(); ++j)
+ {
+ taucs_supernodal_solve_llt(m_taucsSupernodalFactor,x.data(),&b.col(j).coeffRef(0));
+ b.col(j) = x;
+ }
+ }
+}
+
+#endif // EIGEN_TAUCSSUPPORT_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/TriangularSolver.h b/extern/Eigen2/Eigen/src/Sparse/TriangularSolver.h
new file mode 100644
index 00000000000..8948ae45e1d
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/TriangularSolver.h
@@ -0,0 +1,178 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSETRIANGULARSOLVER_H
+#define EIGEN_SPARSETRIANGULARSOLVER_H
+
+// forward substitution, row-major
+template<typename Lhs, typename Rhs>
+struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,RowMajor|IsSparse>
+{
+ typedef typename Rhs::Scalar Scalar;
+ static void run(const Lhs& lhs, Rhs& other)
+ {
+ for(int col=0 ; col<other.cols() ; ++col)
+ {
+ for(int i=0; i<lhs.rows(); ++i)
+ {
+ Scalar tmp = other.coeff(i,col);
+ Scalar lastVal = 0;
+ int lastIndex = 0;
+ for(typename Lhs::InnerIterator it(lhs, i); it; ++it)
+ {
+ lastVal = it.value();
+ lastIndex = it.index();
+ tmp -= lastVal * other.coeff(lastIndex,col);
+ }
+ if (Lhs::Flags & UnitDiagBit)
+ other.coeffRef(i,col) = tmp;
+ else
+ {
+ ei_assert(lastIndex==i);
+ other.coeffRef(i,col) = tmp/lastVal;
+ }
+ }
+ }
+ }
+};
+
+// backward substitution, row-major
+template<typename Lhs, typename Rhs>
+struct ei_solve_triangular_selector<Lhs,Rhs,UpperTriangular,RowMajor|IsSparse>
+{
+ typedef typename Rhs::Scalar Scalar;
+ static void run(const Lhs& lhs, Rhs& other)
+ {
+ for(int col=0 ; col<other.cols() ; ++col)
+ {
+ for(int i=lhs.rows()-1 ; i>=0 ; --i)
+ {
+ Scalar tmp = other.coeff(i,col);
+ typename Lhs::InnerIterator it(lhs, i);
+ if (it.index() == i)
+ ++it;
+ for(; it; ++it)
+ {
+ tmp -= it.value() * other.coeff(it.index(),col);
+ }
+
+ if (Lhs::Flags & UnitDiagBit)
+ other.coeffRef(i,col) = tmp;
+ else
+ {
+ typename Lhs::InnerIterator it(lhs, i);
+ ei_assert(it.index() == i);
+ other.coeffRef(i,col) = tmp/it.value();
+ }
+ }
+ }
+ }
+};
+
+// forward substitution, col-major
+template<typename Lhs, typename Rhs>
+struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,ColMajor|IsSparse>
+{
+ typedef typename Rhs::Scalar Scalar;
+ static void run(const Lhs& lhs, Rhs& other)
+ {
+ for(int col=0 ; col<other.cols() ; ++col)
+ {
+ for(int i=0; i<lhs.cols(); ++i)
+ {
+ typename Lhs::InnerIterator it(lhs, i);
+ if(!(Lhs::Flags & UnitDiagBit))
+ {
+ // std::cerr << it.value() << " ; " << it.index() << " == " << i << "\n";
+ ei_assert(it.index()==i);
+ other.coeffRef(i,col) /= it.value();
+ }
+ Scalar tmp = other.coeffRef(i,col);
+ if (it.index()==i)
+ ++it;
+ for(; it; ++it)
+ other.coeffRef(it.index(), col) -= tmp * it.value();
+ }
+ }
+ }
+};
+
+// backward substitution, col-major
+template<typename Lhs, typename Rhs>
+struct ei_solve_triangular_selector<Lhs,Rhs,UpperTriangular,ColMajor|IsSparse>
+{
+ typedef typename Rhs::Scalar Scalar;
+ static void run(const Lhs& lhs, Rhs& other)
+ {
+ for(int col=0 ; col<other.cols() ; ++col)
+ {
+ for(int i=lhs.cols()-1; i>=0; --i)
+ {
+ if(!(Lhs::Flags & UnitDiagBit))
+ {
+ // FIXME lhs.coeff(i,i) might not be always efficient while it must simply be the
+ // last element of the column !
+ other.coeffRef(i,col) /= lhs.coeff(i,i);
+ }
+ Scalar tmp = other.coeffRef(i,col);
+ typename Lhs::InnerIterator it(lhs, i);
+ for(; it && it.index()<i; ++it)
+ other.coeffRef(it.index(), col) -= tmp * it.value();
+ }
+ }
+ }
+};
+
+template<typename Derived>
+template<typename OtherDerived>
+void SparseMatrixBase<Derived>::solveTriangularInPlace(MatrixBase<OtherDerived>& other) const
+{
+ ei_assert(derived().cols() == derived().rows());
+ ei_assert(derived().cols() == other.rows());
+ ei_assert(!(Flags & ZeroDiagBit));
+ ei_assert(Flags & (UpperTriangularBit|LowerTriangularBit));
+
+ enum { copy = ei_traits<OtherDerived>::Flags & RowMajorBit };
+
+ typedef typename ei_meta_if<copy,
+ typename ei_plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy;
+ OtherCopy otherCopy(other.derived());
+
+ ei_solve_triangular_selector<Derived, typename ei_unref<OtherCopy>::type>::run(derived(), otherCopy);
+
+ if (copy)
+ other = otherCopy;
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+typename ei_plain_matrix_type_column_major<OtherDerived>::type
+SparseMatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other) const
+{
+ typename ei_plain_matrix_type_column_major<OtherDerived>::type res(other);
+ solveTriangularInPlace(res);
+ return res;
+}
+
+#endif // EIGEN_SPARSETRIANGULARSOLVER_H
diff --git a/extern/Eigen2/Eigen/src/Sparse/UmfPackSupport.h b/extern/Eigen2/Eigen/src/Sparse/UmfPackSupport.h
new file mode 100644
index 00000000000..b76ffb25248
--- /dev/null
+++ b/extern/Eigen2/Eigen/src/Sparse/UmfPackSupport.h
@@ -0,0 +1,289 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen 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.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that 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 or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_UMFPACKSUPPORT_H
+#define EIGEN_UMFPACKSUPPORT_H
+
+/* TODO extract L, extract U, compute det, etc... */
+
+// generic double/complex<double> wrapper functions:
+
+inline void umfpack_free_numeric(void **Numeric, double)
+{ umfpack_di_free_numeric(Numeric); }
+
+inline void umfpack_free_numeric(void **Numeric, std::complex<double>)
+{ umfpack_zi_free_numeric(Numeric); }
+
+inline void umfpack_free_symbolic(void **Symbolic, double)
+{ umfpack_di_free_symbolic(Symbolic); }
+
+inline void umfpack_free_symbolic(void **Symbolic, std::complex<double>)
+{ umfpack_zi_free_symbolic(Symbolic); }
+
+inline int umfpack_symbolic(int n_row,int n_col,
+ const int Ap[], const int Ai[], const double Ax[], void **Symbolic,
+ const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])
+{
+ return umfpack_di_symbolic(n_row,n_col,Ap,Ai,Ax,Symbolic,Control,Info);
+}
+
+inline int umfpack_symbolic(int n_row,int n_col,
+ const int Ap[], const int Ai[], const std::complex<double> Ax[], void **Symbolic,
+ const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])
+{
+ return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&Ax[0].real(),0,Symbolic,Control,Info);
+}
+
+inline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[],
+ void *Symbolic, void **Numeric,
+ const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO])
+{
+ return umfpack_di_numeric(Ap,Ai,Ax,Symbolic,Numeric,Control,Info);
+}
+
+inline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex<double> Ax[],
+ void *Symbolic, void **Numeric,
+ const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO])
+{
+ return umfpack_zi_numeric(Ap,Ai,&Ax[0].real(),0,Symbolic,Numeric,Control,Info);
+}
+
+inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[],
+ double X[], const double B[], void *Numeric,
+ const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO])
+{
+ return umfpack_di_solve(sys,Ap,Ai,Ax,X,B,Numeric,Control,Info);
+}
+
+inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::complex<double> Ax[],
+ std::complex<double> X[], const std::complex<double> B[], void *Numeric,
+ const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO])
+{
+ return umfpack_zi_solve(sys,Ap,Ai,&Ax[0].real(),0,&X[0].real(),0,&B[0].real(),0,Numeric,Control,Info);
+}
+
+inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double)
+{
+ return umfpack_di_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric);
+}
+
+inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, std::complex<double>)
+{
+ return umfpack_zi_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric);
+}
+
+inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui[], double Ux[],
+ int P[], int Q[], double Dx[], int *do_recip, double Rs[], void *Numeric)
+{
+ return umfpack_di_get_numeric(Lp,Lj,Lx,Up,Ui,Ux,P,Q,Dx,do_recip,Rs,Numeric);
+}
+
+inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex<double> Lx[], int Up[], int Ui[], std::complex<double> Ux[],
+ int P[], int Q[], std::complex<double> Dx[], int *do_recip, double Rs[], void *Numeric)
+{
+ return umfpack_zi_get_numeric(Lp,Lj,Lx?&Lx[0].real():0,0,Up,Ui,Ux?&Ux[0].real():0,0,P,Q,
+ Dx?&Dx[0].real():0,0,do_recip,Rs,Numeric);
+}
+
+inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO])
+{
+ return umfpack_di_get_determinant(Mx,Ex,NumericHandle,User_Info);
+}
+
+inline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO])
+{
+ return umfpack_zi_get_determinant(&Mx->real(),0,Ex,NumericHandle,User_Info);
+}
+
+
+template<typename MatrixType>
+class SparseLU<MatrixType,UmfPack> : public SparseLU<MatrixType>
+{
+ protected:
+ typedef SparseLU<MatrixType> Base;
+ typedef typename Base::Scalar Scalar;
+ typedef typename Base::RealScalar RealScalar;
+ typedef Matrix<Scalar,Dynamic,1> Vector;
+ typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
+ typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
+ typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> LMatrixType;
+ typedef SparseMatrix<Scalar,UpperTriangular> UMatrixType;
+ using Base::m_flags;
+ using Base::m_status;
+
+ public:
+
+ SparseLU(int flags = NaturalOrdering)
+ : Base(flags), m_numeric(0)
+ {
+ }
+
+ SparseLU(const MatrixType& matrix, int flags = NaturalOrdering)
+ : Base(flags), m_numeric(0)
+ {
+ compute(matrix);
+ }
+
+ ~SparseLU()
+ {
+ if (m_numeric)
+ umfpack_free_numeric(&m_numeric,Scalar());
+ }
+
+ inline const LMatrixType& matrixL() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_l;
+ }
+
+ inline const UMatrixType& matrixU() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_u;
+ }
+
+ inline const IntColVectorType& permutationP() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_p;
+ }
+
+ inline const IntRowVectorType& permutationQ() const
+ {
+ if (m_extractedDataAreDirty) extractData();
+ return m_q;
+ }
+
+ Scalar determinant() const;
+
+ template<typename BDerived, typename XDerived>
+ bool solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x) const;
+
+ void compute(const MatrixType& matrix);
+
+ protected:
+
+ void extractData() const;
+
+ protected:
+ // cached data:
+ void* m_numeric;
+ const MatrixType* m_matrixRef;
+ mutable LMatrixType m_l;
+ mutable UMatrixType m_u;
+ mutable IntColVectorType m_p;
+ mutable IntRowVectorType m_q;
+ mutable bool m_extractedDataAreDirty;
+};
+
+template<typename MatrixType>
+void SparseLU<MatrixType,UmfPack>::compute(const MatrixType& a)
+{
+ const int rows = a.rows();
+ const int cols = a.cols();
+ ei_assert((MatrixType::Flags&RowMajorBit)==0 && "Row major matrices are not supported yet");
+
+ m_matrixRef = &a;
+
+ if (m_numeric)
+ umfpack_free_numeric(&m_numeric,Scalar());
+
+ void* symbolic;
+ int errorCode = 0;
+ errorCode = umfpack_symbolic(rows, cols, a._outerIndexPtr(), a._innerIndexPtr(), a._valuePtr(),
+ &symbolic, 0, 0);
+ if (errorCode==0)
+ errorCode = umfpack_numeric(a._outerIndexPtr(), a._innerIndexPtr(), a._valuePtr(),
+ symbolic, &m_numeric, 0, 0);
+
+ umfpack_free_symbolic(&symbolic,Scalar());
+
+ m_extractedDataAreDirty = true;
+
+ Base::m_succeeded = (errorCode==0);
+}
+
+template<typename MatrixType>
+void SparseLU<MatrixType,UmfPack>::extractData() const
+{
+ if (m_extractedDataAreDirty)
+ {
+ // get size of the data
+ int lnz, unz, rows, cols, nz_udiag;
+ umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar());
+
+ // allocate data
+ m_l.resize(rows,std::min(rows,cols));
+ m_l.resizeNonZeros(lnz);
+
+ m_u.resize(std::min(rows,cols),cols);
+ m_u.resizeNonZeros(unz);
+
+ m_p.resize(rows);
+ m_q.resize(cols);
+
+ // extract
+ umfpack_get_numeric(m_l._outerIndexPtr(), m_l._innerIndexPtr(), m_l._valuePtr(),
+ m_u._outerIndexPtr(), m_u._innerIndexPtr(), m_u._valuePtr(),
+ m_p.data(), m_q.data(), 0, 0, 0, m_numeric);
+
+ m_extractedDataAreDirty = false;
+ }
+}
+
+template<typename MatrixType>
+typename SparseLU<MatrixType,UmfPack>::Scalar SparseLU<MatrixType,UmfPack>::determinant() const
+{
+ Scalar det;
+ umfpack_get_determinant(&det, 0, m_numeric, 0);
+ return det;
+}
+
+template<typename MatrixType>
+template<typename BDerived,typename XDerived>
+bool SparseLU<MatrixType,UmfPack>::solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> *x) const
+{
+ //const int size = m_matrix.rows();
+ const int rhsCols = b.cols();
+// ei_assert(size==b.rows());
+ ei_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPack backend does not support non col-major rhs yet");
+ ei_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPack backend does not support non col-major result yet");
+
+ int errorCode;
+ for (int j=0; j<rhsCols; ++j)
+ {
+ errorCode = umfpack_solve(UMFPACK_A,
+ m_matrixRef->_outerIndexPtr(), m_matrixRef->_innerIndexPtr(), m_matrixRef->_valuePtr(),
+ &x->col(j).coeffRef(0), &b.const_cast_derived().col(j).coeffRef(0), m_numeric, 0, 0);
+ if (errorCode!=0)
+ return false;
+ }
+// errorCode = umfpack_di_solve(UMFPACK_A,
+// m_matrixRef._outerIndexPtr(), m_matrixRef._innerIndexPtr(), m_matrixRef._valuePtr(),
+// x->derived().data(), b.derived().data(), m_numeric, 0, 0);
+
+ return true;
+}
+
+#endif // EIGEN_UMFPACKSUPPORT_H
diff --git a/extern/Eigen2/eigen-update.sh b/extern/Eigen2/eigen-update.sh
new file mode 100755
index 00000000000..926a36ef120
--- /dev/null
+++ b/extern/Eigen2/eigen-update.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+echo "*** EIGEN2-HG Update utility"
+echo "*** This gets a new eigen2-hg tree and adapts it to blenders build structure"
+echo "*** Warning! This script will wipe all the header file"
+
+if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
+ echo Proceeding as requested by command line ...
+else
+ echo "*** Please run again with --i-really-know-what-im-doing ..."
+ exit 1
+fi
+
+# get the latest revision from repository.
+hg clone http://bitbucket.org/eigen/eigen2
+if [ -d eigen2 ]
+then
+ cd eigen2
+ # put here the version you want to use
+ hg up 2.0.6
+ rm -f `find Eigen/ -type f -name "CMakeLists.txt"`
+ cp -r Eigen ..
+ cd ..
+ rm -rf eigen2
+else
+ echo "Did you install Mercurial?"
+fi
+
diff --git a/extern/Makefile b/extern/Makefile
index 1bebf1e1994..a30cd1d7ca3 100644
--- a/extern/Makefile
+++ b/extern/Makefile
@@ -32,19 +32,10 @@ SOURCEDIR = extern
DIR = $(OCGDIR)/extern
DIRS = glew/src
-ifeq ($(WITH_FFMPEG), true)
-ifeq ($(NAN_FFMPEG), $(LCGDIR)/ffmpeg)
- DIRS += ffmpeg
-endif
-ifeq ($(NAN_FFMPEG), $(LCGDIR)/gcc/ffmpeg)
- DIRS += ffmpeg
-endif
-endif
-
# Cloth requires it
-#ifneq ($(NAN_NO_KETSJI), true)
-DIRS += bullet2
-#endif
+ifeq ($(NAN_USE_BULLET), true)
+ DIRS += bullet2
+endif
ifeq ($(WITH_BINRELOC), true)
DIRS += binreloc
diff --git a/extern/SConscript b/extern/SConscript
index 20604d87e45..af057a73927 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -22,5 +22,8 @@ if env['WITH_BF_REDCODE'] and env['BF_REDCODE_LIB'] == '':
if env['OURPLATFORM'] == 'linux2':
SConscript(['binreloc/SConscript']);
-SConscript(['lzo/SConscript'])
-SConscript(['lzma/SConscript'])
+if env['WITH_BF_LZO']:
+ SConscript(['lzo/SConscript'])
+
+if env['WITH_BF_LZMA']:
+ SConscript(['lzma/SConscript'])
diff --git a/extern/glew/make/msvc_9_0/glew.vcproj b/extern/glew/make/msvc_9_0/glew.vcproj
index f9d8df478ca..a7186f61cbc 100644
--- a/extern/glew/make/msvc_9_0/glew.vcproj
+++ b/extern/glew/make/msvc_9_0/glew.vcproj
@@ -112,6 +112,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index 9efd1a6ee7c..ac08b780ab8 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -33,6 +33,7 @@ ADD_SUBDIRECTORY(container)
ADD_SUBDIRECTORY(memutil)
ADD_SUBDIRECTORY(decimation)
ADD_SUBDIRECTORY(iksolver)
+ADD_SUBDIRECTORY(itasc)
ADD_SUBDIRECTORY(boolop)
ADD_SUBDIRECTORY(opennl)
ADD_SUBDIRECTORY(smoke)
diff --git a/intern/Makefile b/intern/Makefile
index 4bf18f987a4..ed0b0cfff28 100644
--- a/intern/Makefile
+++ b/intern/Makefile
@@ -32,7 +32,7 @@ SOURCEDIR = intern
# include nan_subdirs.mk
ALLDIRS = string ghost guardedalloc moto container memutil
-ALLDIRS += decimation iksolver bsp opennl elbeem boolop smoke audaspace
+ALLDIRS += decimation iksolver itasc bsp opennl elbeem boolop smoke audaspace
all::
@for i in $(ALLDIRS); do \
diff --git a/intern/SConscript b/intern/SConscript
index af5d0671c27..241662b7088 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -10,6 +10,7 @@ SConscript(['audaspace/SConscript',
'memutil/SConscript/',
'decimation/SConscript',
'iksolver/SConscript',
+ 'itasc/SConscript',
'boolop/SConscript',
'opennl/SConscript',
'smoke/SConscript'])
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index b33afa2b955..aa9f425d6fb 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -127,101 +127,103 @@ void AUD_OpenALDevice::updateStreams()
alcSuspendContext(m_context);
- // for all sounds
- AUD_HandleIterator it = m_playingSounds->begin();
- while(it != m_playingSounds->end())
{
- sound = *it;
- // increment the iterator to make sure it's valid,
- // in case the sound gets deleted after stopping
- ++it;
-
- // is it a streamed sound?
- if(!sound->isBuffered)
+ // for all sounds
+ AUD_HandleIterator it = m_playingSounds->begin();
+ while(it != m_playingSounds->end())
{
- // check for buffer refilling
- alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
+ sound = *it;
+ // increment the iterator to make sure it's valid,
+ // in case the sound gets deleted after stopping
+ ++it;
- if(info)
+ // is it a streamed sound?
+ if(!sound->isBuffered)
{
- specs = sound->reader->getSpecs();
+ // check for buffer refilling
+ alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
- // for all empty buffers
- while(info--)
+ if(info)
{
- // if there's still data to play back
- if(!sound->data_end)
- {
- // read data
- length = m_buffersize;
- sound->reader->read(length, buffer);
-
- // read nothing?
- if(length == 0)
- {
- sound->data_end = true;
- break;
- }
-
- // unqueue buffer
- alSourceUnqueueBuffers(sound->source, 1,
- &sound->buffers[sound->current]);
- ALenum err;
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->data_end = true;
- break;
- }
-
- // fill with new data
- alBufferData(sound->buffers[sound->current],
- sound->format,
- buffer,
- length * AUD_SAMPLE_SIZE(specs),
- specs.rate);
+ specs = sound->reader->getSpecs();
- if(alGetError() != AL_NO_ERROR)
+ // for all empty buffers
+ while(info--)
+ {
+ // if there's still data to play back
+ if(!sound->data_end)
{
- sound->data_end = true;
- break;
+ // read data
+ length = m_buffersize;
+ sound->reader->read(length, buffer);
+
+ // read nothing?
+ if(length == 0)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ // unqueue buffer
+ alSourceUnqueueBuffers(sound->source, 1,
+ &sound->buffers[sound->current]);
+ ALenum err;
+ if((err = alGetError()) != AL_NO_ERROR)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ // fill with new data
+ alBufferData(sound->buffers[sound->current],
+ sound->format,
+ buffer,
+ length * AUD_SAMPLE_SIZE(specs),
+ specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ // and queue again
+ alSourceQueueBuffers(sound->source, 1,
+ &sound->buffers[sound->current]);
+ if(alGetError() != AL_NO_ERROR)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ sound->current = (sound->current+1) %
+ AUD_OPENAL_CYCLE_BUFFERS;
}
-
- // and queue again
- alSourceQueueBuffers(sound->source, 1,
- &sound->buffers[sound->current]);
- if(alGetError() != AL_NO_ERROR)
- {
- sound->data_end = true;
+ else
break;
- }
-
- sound->current = (sound->current+1) %
- AUD_OPENAL_CYCLE_BUFFERS;
}
- else
- break;
}
}
- }
- // check if the sound has been stopped
- alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
+ // check if the sound has been stopped
+ alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
- if(info != AL_PLAYING)
- {
- // if it really stopped
- if(sound->data_end)
+ if(info != AL_PLAYING)
{
- // pause or
- if(sound->keep)
- pause(sound);
- // stop
+ // if it really stopped
+ if(sound->data_end)
+ {
+ // pause or
+ if(sound->keep)
+ pause(sound);
+ // stop
+ else
+ stop(sound);
+ }
+ // continue playing
else
- stop(sound);
+ alSourcePlay(sound->source);
}
- // continue playing
- else
- alSourcePlay(sound->source);
}
}
@@ -516,60 +518,73 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
{
- // check if it is a buffered factory
- for(AUD_BFIterator i = m_bufferedFactories->begin();
- i != m_bufferedFactories->end(); i++)
- {
- if((*i)->factory == factory)
- {
- // create the handle
- AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle")
- sound->keep = keep;
- sound->current = -1;
- sound->isBuffered = true;
- sound->data_end = true;
+ lock();
- alcSuspendContext(m_context);
+ AUD_OpenALHandle* sound = NULL;
- // OpenAL playback code
- try
+ try
+ {
+ // check if it is a buffered factory
+ for(AUD_BFIterator i = m_bufferedFactories->begin();
+ i != m_bufferedFactories->end(); i++)
+ {
+ if((*i)->factory == factory)
{
- alGenSources(1, &sound->source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL);
+ // create the handle
+ sound = new AUD_OpenALHandle; AUD_NEW("handle")
+ sound->keep = keep;
+ sound->current = -1;
+ sound->isBuffered = true;
+ sound->data_end = true;
+
+ alcSuspendContext(m_context);
+ // OpenAL playback code
try
{
- alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
+ alGenSources(1, &sound->source);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
+
+ try
+ {
+ alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+ }
+ catch(AUD_Exception)
+ {
+ alDeleteSources(1, &sound->source);
+ throw;
+ }
}
catch(AUD_Exception)
{
- alDeleteSources(1, &sound->source);
+ delete sound; AUD_DELETE("handle")
+ alcProcessContext(m_context);
throw;
}
- }
- catch(AUD_Exception)
- {
- delete sound; AUD_DELETE("handle")
- alcProcessContext(m_context);
- unlock();
- throw;
- }
- // play sound
- m_playingSounds->push_back(sound);
+ // play sound
+ m_playingSounds->push_back(sound);
- alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
- start();
+ alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+ start();
- alcProcessContext(m_context);
- unlock();
-
- return sound;
+ alcProcessContext(m_context);
+ }
}
}
+ catch(AUD_Exception)
+ {
+ unlock();
+ throw;
+ }
+
+ unlock();
+
+ if(sound)
+ return sound;
AUD_IReader* reader = factory->createReader();
@@ -596,7 +611,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
}
// create the handle
- AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle")
+ sound = new AUD_OpenALHandle; AUD_NEW("handle")
sound->keep = keep;
sound->reader = reader;
sound->current = 0;
@@ -683,8 +698,11 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
bool AUD_OpenALDevice::pause(AUD_Handle* handle)
{
- // only songs that are played can be paused
+ bool result = false;
+
lock();
+
+ // only songs that are played can be paused
for(AUD_HandleIterator i = m_playingSounds->begin();
i != m_playingSounds->end(); i++)
{
@@ -693,16 +711,20 @@ bool AUD_OpenALDevice::pause(AUD_Handle* handle)
m_pausedSounds->push_back(*i);
alSourcePause((*i)->source);
m_playingSounds->erase(i);
- unlock();
- return true;
+ result = true;
+ break;
}
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_OpenALDevice::resume(AUD_Handle* handle)
{
+ bool result = false;
+
lock();
// only songs that are paused can be resumed
@@ -714,19 +736,24 @@ bool AUD_OpenALDevice::resume(AUD_Handle* handle)
m_playingSounds->push_back(*i);
start();
m_pausedSounds->erase(i);
- unlock();
- return true;
+ result = true;
+ break;
}
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_OpenALDevice::stop(AUD_Handle* handle)
{
AUD_OpenALHandle* sound;
+ bool result = false;
+
lock();
+
for(AUD_HandleIterator i = m_playingSounds->begin();
i != m_playingSounds->end(); i++)
{
@@ -741,51 +768,60 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
}
delete *i; AUD_DELETE("handle")
m_playingSounds->erase(i);
- unlock();
- return true;
+ result = true;
+ break;
}
}
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
+ if(!result)
{
- if(*i == handle)
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
{
- sound = *i;
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
+ if(*i == handle)
{
- delete sound->reader; AUD_DELETE("reader")
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ sound = *i;
+ alDeleteSources(1, &sound->source);
+ if(!sound->isBuffered)
+ {
+ delete sound->reader; AUD_DELETE("reader")
+ alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ }
+ delete *i; AUD_DELETE("handle")
+ m_pausedSounds->erase(i);
+ result = true;
+ break;
}
- delete *i; AUD_DELETE("handle")
- m_pausedSounds->erase(i);
- unlock();
- return true;
}
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
{
+ bool result = false;
+
lock();
+
if(isValid(handle))
{
((AUD_OpenALHandle*)handle)->keep = keep;
- unlock();
- return true;
+ result = true;
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
{
- lock();
-
bool result = false;
+ lock();
+
if(handle == 0)
{
for(AUD_HandleIterator i = m_playingSounds->begin();
@@ -800,12 +836,16 @@ bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
else if(isValid(handle))
if(!((AUD_OpenALHandle*)handle)->isBuffered)
result = ((AUD_OpenALHandle*)handle)->reader->notify(message);
+
unlock();
+
return result;
}
bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
{
+ bool result = false;
+
lock();
if(isValid(handle))
@@ -857,20 +897,19 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
alSourceRewind(alhandle->source);
}
}
- unlock();
- return true;
+ result = true;
}
unlock();
- return false;
+ return result;
}
float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
{
- lock();
-
float position = 0.0;
+ lock();
+
if(isValid(handle))
{
AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
@@ -887,27 +926,35 @@ float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
{
+ AUD_Status status = AUD_STATUS_INVALID;
+
lock();
+
for(AUD_HandleIterator i = m_playingSounds->begin();
i != m_playingSounds->end(); i++)
{
if(*i == handle)
{
- unlock();
- return AUD_STATUS_PLAYING;
+ status = AUD_STATUS_PLAYING;
+ break;
}
}
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
+ if(status == AUD_STATUS_INVALID)
{
- if(*i == handle)
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
{
- unlock();
- return AUD_STATUS_PAUSED;
+ if(*i == handle)
+ {
+ status = AUD_STATUS_PAUSED;
+ break;
+ }
}
}
+
unlock();
- return AUD_STATUS_INVALID;
+
+ return status;
}
void AUD_OpenALDevice::lock()
@@ -935,6 +982,7 @@ bool AUD_OpenALDevice::checkCapability(int capability)
bool AUD_OpenALDevice::setCapability(int capability, void *value)
{
+ bool result = false;
switch(capability)
{
case AUD_CAPS_VOLUME:
@@ -948,8 +996,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
{
alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_GAIN, caps->value);
- unlock();
- return true;
+ result = true;
}
unlock();
}
@@ -962,8 +1009,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
{
alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_PITCH, caps->value);
- unlock();
- return true;
+ result = true;
}
unlock();
}
@@ -981,11 +1027,13 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
{
if((*i)->factory == factory)
{
- unlock();
- return true;
+ result = true;
+ break;
}
}
unlock();
+ if(result)
+ return result;
AUD_IReader* reader = factory->createReader();
@@ -1104,11 +1152,13 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
}
break;
}
- return false;
+ return result;
}
bool AUD_OpenALDevice::getCapability(int capability, void *value)
{
+ bool result = false;
+
switch(capability)
{
case AUD_CAPS_VOLUME:
@@ -1122,8 +1172,7 @@ bool AUD_OpenALDevice::getCapability(int capability, void *value)
{
alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_GAIN, &caps->value);
- unlock();
- return true;
+ result = true;
}
unlock();
}
@@ -1136,14 +1185,14 @@ bool AUD_OpenALDevice::getCapability(int capability, void *value)
{
alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_PITCH, &caps->value);
- unlock();
- return true;
+ result = true;
}
unlock();
}
break;
}
- return false;
+
+ return result;
}
/******************************************************************************/
@@ -1233,6 +1282,8 @@ float AUD_OpenALDevice::getSetting(AUD_3DSetting setting)
bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data)
{
+ bool result = false;
+
lock();
if(isValid(handle))
@@ -1241,12 +1292,12 @@ bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data)
alSourcefv(source, AL_POSITION, (ALfloat*)data.position);
alSourcefv(source, AL_VELOCITY, (ALfloat*)data.velocity);
alSourcefv(source, AL_DIRECTION, (ALfloat*)&(data.orientation[3]));
- unlock();
- return true;
+ result = true;
}
unlock();
- return false;
+
+ return result;
}
bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 45faebc7e97..255d1d2f1f6 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -516,19 +516,51 @@ AUD_Device* AUD_openReadDevice(AUD_Specs specs)
}
}
-int AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
+AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
{
assert(device);
assert(sound);
try
{
- return device->play(sound) != NULL;
+ return device->play(sound);
}
catch(AUD_Exception)
{
- return false;
+ return NULL;
+ }
+}
+
+int AUD_setDeviceVolume(AUD_Device* device, float volume)
+{
+ assert(device);
+
+ try
+ {
+ return device->setCapability(AUD_CAPS_VOLUME, &volume);
+ }
+ catch(AUD_Exception) {}
+
+ return false;
+}
+
+int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
+ float volume)
+{
+ if(handle)
+ {
+ assert(device);
+ AUD_SourceCaps caps;
+ caps.handle = handle;
+ caps.value = volume;
+
+ try
+ {
+ return device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
+ }
+ catch(AUD_Exception) {}
}
+ return false;
}
int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 6ec5ec87ad5..66a5a5147b3 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -300,12 +300,31 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
extern AUD_Device* AUD_openReadDevice(AUD_Specs specs);
/**
+ * Sets the main volume of a device.
+ * \param device The device.
+ * \param volume The new volume, must be between 0.0 and 1.0.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setDeviceVolume(AUD_Device* device, float volume);
+
+/**
* Plays back a sound file through a read device.
* \param device The read device.
* \param sound The handle of the sound file.
- * \return Whether the sound could be played back.
+ * \return A handle to the played back sound.
+ */
+extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound);
+
+/**
+ * Sets the volume of a played back sound of a read device.
+ * \param device The read device.
+ * \param handle The handle to the sound.
+ * \param volume The new volume, must be between 0.0 and 1.0.
+ * \return Whether the action succeeded.
*/
-extern int AUD_playDevice(AUD_Device* device, AUD_Sound* sound);
+extern int AUD_setDeviceSoundVolume(AUD_Device* device,
+ AUD_Handle* handle,
+ float volume);
/**
* Reads the next samples into the supplied buffer.
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 174ff8c8979..42a90a6f15e 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -94,51 +94,53 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
{
lock();
- AUD_SoftwareHandle* sound;
- int len;
- sample_t* buf;
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
- std::list<AUD_SoftwareHandle*> stopSounds;
-
- // for all sounds
- AUD_HandleIterator it = m_playingSounds->begin();
- while(it != m_playingSounds->end())
{
- sound = *it;
- // increment the iterator to make sure it's valid,
- // in case the sound gets deleted after stopping
- ++it;
+ AUD_SoftwareHandle* sound;
+ int len;
+ sample_t* buf;
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ std::list<AUD_SoftwareHandle*> stopSounds;
+
+ // for all sounds
+ AUD_HandleIterator it = m_playingSounds->begin();
+ while(it != m_playingSounds->end())
+ {
+ sound = *it;
+ // increment the iterator to make sure it's valid,
+ // in case the sound gets deleted after stopping
+ ++it;
- // get the buffer from the source
- len = length;
- sound->reader->read(len, buf);
+ // get the buffer from the source
+ len = length;
+ sound->reader->read(len, buf);
- m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
+ m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
- // in case the end of the sound is reached
- if(len < length)
- {
- if(sound->keep)
- pause(sound);
- else
- stopSounds.push_back(sound);
+ // in case the end of the sound is reached
+ if(len < length)
+ {
+ if(sound->keep)
+ pause(sound);
+ else
+ stopSounds.push_back(sound);
+ }
}
- }
- // fill with silence
- if(m_specs.format == AUD_FORMAT_U8)
- memset(buffer, 0x80, length * sample_size);
- else
- memset(buffer, 0, length * sample_size);
+ // fill with silence
+ if(m_specs.format == AUD_FORMAT_U8)
+ memset(buffer, 0x80, length * sample_size);
+ else
+ memset(buffer, 0, length * sample_size);
- // superpose
- m_mixer->superpose(buffer, length, m_volume);
+ // superpose
+ m_mixer->superpose(buffer, length, m_volume);
- while(!stopSounds.empty())
- {
- sound = stopSounds.front();
- stopSounds.pop_front();
- stop(sound);
+ while(!stopSounds.empty())
+ {
+ sound = stopSounds.front();
+ stopSounds.pop_front();
+ stop(sound);
+ }
}
unlock();
@@ -201,8 +203,11 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
{
- // only songs that are played can be paused
+ bool result = false;
+
lock();
+
+ // only songs that are played can be paused
for(AUD_HandleIterator i = m_playingSounds->begin();
i != m_playingSounds->end(); i++)
{
@@ -212,18 +217,23 @@ bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
m_playingSounds->erase(i);
if(m_playingSounds->empty())
playing(m_playback = false);
- unlock();
- return true;
+ result = true;
+ break;
}
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
{
- // only songs that are paused can be resumed
+ bool result = false;
+
lock();
+
+ // only songs that are paused can be resumed
for(AUD_HandleIterator i = m_pausedSounds->begin();
i != m_pausedSounds->end(); i++)
{
@@ -233,17 +243,22 @@ bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
m_pausedSounds->erase(i);
if(!m_playback)
playing(m_playback = true);
- unlock();
- return true;
+ result = true;
+ break;
}
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
{
+ bool result = false;
+
lock();
+
for(AUD_HandleIterator i = m_playingSounds->begin();
i != m_playingSounds->end(); i++)
{
@@ -254,37 +269,46 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
m_playingSounds->erase(i);
if(m_playingSounds->empty())
playing(m_playback = false);
- unlock();
- return true;
+ result = true;
+ break;
}
}
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
+ if(!result)
{
- if(*i == handle)
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
{
- delete (*i)->reader; AUD_DELETE("reader")
- delete *i; AUD_DELETE("handle")
- m_pausedSounds->erase(i);
- unlock();
- return true;
+ if(*i == handle)
+ {
+ delete (*i)->reader; AUD_DELETE("reader")
+ delete *i; AUD_DELETE("handle")
+ m_pausedSounds->erase(i);
+ result = true;
+ break;
+ }
}
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep)
{
+ bool result = false;
+
lock();
+
if(isValid(handle))
{
((AUD_SoftwareHandle*)handle)->keep = keep;
- unlock();
- return true;
+ result = true;
}
+
unlock();
- return false;
+
+ return result;
}
bool AUD_SoftwareDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
@@ -312,16 +336,18 @@ bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
{
lock();
+ bool result = false;
+
if(isValid(handle))
{
AUD_IReader* reader = ((AUD_SoftwareHandle*)handle)->reader;
reader->seek((int)(position * reader->getSpecs().rate));
- unlock();
- return true;
+ result = true;
}
unlock();
- return false;
+
+ return result;
}
float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
@@ -337,32 +363,41 @@ float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
}
unlock();
+
return position;
}
AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
{
+ AUD_Status status = AUD_STATUS_INVALID;
+
lock();
+
for(AUD_HandleIterator i = m_playingSounds->begin();
i != m_playingSounds->end(); i++)
{
if(*i == handle)
{
- unlock();
- return AUD_STATUS_PLAYING;
+ status = AUD_STATUS_PLAYING;
+ break;
}
}
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
+ if(status == AUD_STATUS_INVALID)
{
- if(*i == handle)
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
{
- unlock();
- return AUD_STATUS_PAUSED;
+ if(*i == handle)
+ {
+ status = AUD_STATUS_PAUSED;
+ break;
+ }
}
}
+
unlock();
- return AUD_STATUS_INVALID;
+
+ return status;
}
void AUD_SoftwareDevice::lock()
@@ -384,6 +419,8 @@ bool AUD_SoftwareDevice::checkCapability(int capability)
bool AUD_SoftwareDevice::setCapability(int capability, void *value)
{
+ bool result = false;
+
switch(capability)
{
case AUD_CAPS_VOLUME:
@@ -407,18 +444,20 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value)
handle->volume = 1.0;
else if(handle->volume < 0.0)
handle->volume = 0.0;
- unlock();
- return true;
+ result = true;
}
unlock();
}
break;
}
- return false;
+
+ return result;;
}
bool AUD_SoftwareDevice::getCapability(int capability, void *value)
{
+ bool result = false;
+
switch(capability)
{
case AUD_CAPS_VOLUME:
@@ -429,16 +468,19 @@ bool AUD_SoftwareDevice::getCapability(int capability, void *value)
case AUD_CAPS_SOURCE_VOLUME:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+
lock();
+
if(isValid(caps->handle))
{
caps->value = ((AUD_SoftwareHandle*)caps->handle)->volume;
- unlock();
- return true;
+ result = true;
}
+
unlock();
}
break;
}
- return false;
+
+ return result;
}
diff --git a/intern/audaspace/make/msvc_9_0/audaspace.vcproj b/intern/audaspace/make/msvc_9_0/audaspace.vcproj
index 0d8ade43e07..93dcdd66628 100644
--- a/intern/audaspace/make/msvc_9_0/audaspace.vcproj
+++ b/intern/audaspace/make/msvc_9_0/audaspace.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
diff --git a/intern/boolop/make/msvc_9_0/boolop.vcproj b/intern/boolop/make/msvc_9_0/boolop.vcproj
index 7fe83962695..357d189376a 100644
--- a/intern/boolop/make/msvc_9_0/boolop.vcproj
+++ b/intern/boolop/make/msvc_9_0/boolop.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\extern;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\container\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\makesdna;$(NOINHERIT)"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/bsp/make/msvc_9_0/bsplib.vcproj b/intern/bsp/make/msvc_9_0/bsplib.vcproj
index a1b16d5b93f..ed6978b8229 100644
--- a/intern/bsp/make/msvc_9_0/bsplib.vcproj
+++ b/intern/bsp/make/msvc_9_0/bsplib.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\container\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/container/make/msvc_9_0/container.vcproj b/intern/container/make/msvc_9_0/container.vcproj
index 2b40571672d..76bc56f413f 100644
--- a/intern/container/make/msvc_9_0/container.vcproj
+++ b/intern/container/make/msvc_9_0/container.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
diff --git a/intern/decimation/make/msvc_9_0/decimation.vcproj b/intern/decimation/make/msvc_9_0/decimation.vcproj
index 7d58bf1f4c6..a75332857ad 100644
--- a/intern/decimation/make/msvc_9_0/decimation.vcproj
+++ b/intern/decimation/make/msvc_9_0/decimation.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\container\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/elbeem/make/msvc_9_0/elbeem.vcproj b/intern/elbeem/make/msvc_9_0/elbeem.vcproj
index 4108e09799d..2369a76fff0 100644
--- a/intern/elbeem/make/msvc_9_0/elbeem.vcproj
+++ b/intern/elbeem/make/msvc_9_0/elbeem.vcproj
@@ -114,6 +114,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
AdditionalIncludeDirectories="..\..\intern;..\..\extern;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\source\kernel\gen_messaging;..\..\..\..\..\lib\windows\sdl\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;NOGUI;ELBEEM_BLENDER=1;LBM_INCLUDE_CONTROL=1"
StringPooling="true"
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 9128e923e19..33af61baa07 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -26,9 +26,18 @@
SET(INC . ../string)
-FILE(GLOB SRC intern/*.cpp)
+FILE(GLOB SRC intern/*.cpp intern/*.mm)
IF(APPLE)
+ IF(WITH_COCOA)
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+ ELSE(WITH_COCOA)
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
+ ENDIF(WITH_COCOA)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
@@ -41,6 +50,9 @@ ELSE(APPLE)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
@@ -52,6 +64,9 @@ ELSE(APPLE)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
ENDIF(WIN32)
ENDIF(APPLE)
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 2441251dc33..31819f341a0 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -64,8 +64,14 @@ typedef enum
* the pen's angle in 3D space vertically downwards on to the XY plane
* --Matt
*/
+typedef enum {
+ GHOST_kTabletModeNone = 0,
+ GHOST_kTabletModeStylus,
+ GHOST_kTabletModeEraser
+} GHOST_TTabletMode;
+
typedef struct GHOST_TabletData {
- char Active; /* 0=None, 1=Stylus, 2=Eraser */
+ GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */
float Ytilt; /* as above */
@@ -126,6 +132,8 @@ typedef enum {
GHOST_kButtonMaskLeft = 0,
GHOST_kButtonMaskMiddle,
GHOST_kButtonMaskRight,
+ GHOST_kButtonMaskButton4,
+ GHOST_kButtonMaskButton5,
GHOST_kButtonNumMasks
} GHOST_TButtonMask;
diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp
index a06692797c7..712ded7ea20 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManager.cpp
@@ -27,8 +27,6 @@
*/
/**
-
- * $Id$
* Copyright (C) 2001 NaN Technologies B.V.
* @author Maarten Gribnau
* @date September 21, 2001
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
new file mode 100644
index 00000000000..f67f51e1380
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
@@ -0,0 +1,113 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 GHOST_DisplayManagerCocoa.h
+ * Declaration of GHOST_DisplayManagerCocoa class.
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_COCOA_H_
+#define _GHOST_DISPLAY_MANAGER_COCOA_H_
+
+#ifndef __APPLE__
+#error Apple only!
+#endif // __APPLE__
+
+#include "GHOST_DisplayManager.h"
+
+/**
+ * Manages system displays (Mac OSX/Cocoa implementation).
+ * @see GHOST_DisplayManager
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager
+{
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_DisplayManagerCocoa(void);
+
+ /**
+ * Returns the number of display devices on this system.
+ * @param numDisplays The number of displays on this system.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+
+ /**
+ * Returns the number of display settings for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The number of settings of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param index The setting index to be returned.
+ * @param setting The setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Returns the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+
+ /**
+ * Changes the current setting for this display device.
+ * @param display The index of the display to query with 0 <= display < getNumDisplays().
+ * @param setting The current setting of the display device with this index.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+
+protected:
+ /**
+ * Returns a value from a dictionary.
+ * @param values Dictionary to return value from.
+ * @param key Key to return value for.
+ * @return The value for this key.
+ */
+ long getValue(CFDictionaryRef values, CFStringRef key) const;
+
+ /** Cached number of displays. */
+ CGDisplayCount m_numDisplays;
+ /** Cached display id's for each display. */
+ CGDirectDisplayID* m_displayIDs;
+};
+
+
+#endif // _GHOST_DISPLAY_MANAGER_COCOA_H_
+
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
new file mode 100644
index 00000000000..82e31c01d25
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
@@ -0,0 +1,178 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+ */
+
+/**
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date September 21, 2001
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Carbon/Carbon.h>
+
+#include "GHOST_DisplayManagerCocoa.h"
+#include "GHOST_Debug.h"
+
+// We do not support multiple monitors at the moment
+
+
+GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void)
+{
+ if (::CGGetActiveDisplayList(0, NULL, &m_numDisplays) != CGDisplayNoErr)
+ {
+ m_numDisplays = 0;
+ m_displayIDs = NULL;
+ }
+ if (m_numDisplays > 0)
+ {
+ m_displayIDs = new CGDirectDisplayID [m_numDisplays];
+ GHOST_ASSERT((m_displayIDs!=NULL), "GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(): memory allocation failed");
+ ::CGGetActiveDisplayList(m_numDisplays, m_displayIDs, &m_numDisplays);
+ }
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const
+{
+ numDisplays = (GHOST_TUns8) m_numDisplays;
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported");
+
+ CFArrayRef displayModes;
+ displayModes = ::CGDisplayAvailableModes(m_displayIDs[display]);
+ CFIndex numModes = ::CFArrayGetCount(displayModes);
+ numSettings = (GHOST_TInt32)numModes;
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported");
+
+ CFArrayRef displayModes;
+ CGDirectDisplayID d = m_displayIDs[display];
+ displayModes = ::CGDisplayAvailableModes(d);
+ //CFIndex numModes = ::CFArrayGetCount(displayModes);/*unused*/
+ //GHOST_TInt32 numSettings = (GHOST_TInt32)numModes; /*unused*/
+ CFDictionaryRef displayModeValues = (CFDictionaryRef)::CFArrayGetValueAtIndex(displayModes, index);
+
+ setting.xPixels = getValue(displayModeValues, kCGDisplayWidth);
+ setting.yPixels = getValue(displayModeValues, kCGDisplayHeight);
+ setting.bpp = getValue(displayModeValues, kCGDisplayBitsPerPixel);
+ setting.frequency = getValue(displayModeValues, kCGDisplayRefreshRate);
+
+#ifdef GHOST_DEBUG
+ printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
+#endif // GHOST_DEBUG
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");
+
+ CFDictionaryRef displayModeValues = ::CGDisplayCurrentMode(m_displayIDs[display]);
+
+ setting.xPixels = getValue(displayModeValues, kCGDisplayWidth);
+ setting.yPixels = getValue(displayModeValues, kCGDisplayHeight);
+ setting.bpp = getValue(displayModeValues, kCGDisplayBitsPerPixel);
+ setting.frequency = getValue(displayModeValues, kCGDisplayRefreshRate);
+
+#ifdef GHOST_DEBUG
+ printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
+#endif // GHOST_DEBUG
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
+{
+ GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");
+
+#ifdef GHOST_DEBUG
+ printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");
+ printf(" setting.xPixels=%d\n", setting.xPixels);
+ printf(" setting.yPixels=%d\n", setting.yPixels);
+ printf(" setting.bpp=%d\n", setting.bpp);
+ printf(" setting.frequency=%d\n", setting.frequency);
+#endif // GHOST_DEBUG
+
+ CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
+ m_displayIDs[display],
+ (size_t)setting.bpp,
+ (size_t)setting.xPixels,
+ (size_t)setting.yPixels,
+ (CGRefreshRate)setting.frequency,
+ NULL);
+
+#ifdef GHOST_DEBUG
+ printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
+ printf(" setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
+ printf(" setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
+ printf(" setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
+ printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));
+#endif // GHOST_DEBUG
+
+ CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
+
+ return err == CGDisplayNoErr ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+long GHOST_DisplayManagerCocoa::getValue(CFDictionaryRef values, CFStringRef key) const
+{
+ CFNumberRef numberValue = (CFNumberRef) CFDictionaryGetValue(values, key);
+
+ if (!numberValue)
+ {
+ return -1;
+ }
+
+ long intValue;
+
+ if (!CFNumberGetValue(numberValue, kCFNumberLongType, &intValue))
+ {
+ return -1;
+ }
+
+ return intValue;
+}
+
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 9329e68132b..fc338c182a9 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -44,7 +44,11 @@
# include "GHOST_SystemWin32.h"
#else
# ifdef __APPLE__
-# include "GHOST_SystemCarbon.h"
+# ifdef GHOST_COCOA
+# include "GHOST_SystemCocoa.h"
+# else
+# include "GHOST_SystemCarbon.h"
+# endif
# else
# include "GHOST_SystemX11.h"
# endif
@@ -62,7 +66,11 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
m_system = new GHOST_SystemWin32 ();
#else
# ifdef __APPLE__
- m_system = new GHOST_SystemCarbon ();
+# ifdef GHOST_COCOA
+ m_system = new GHOST_SystemCocoa ();
+# else
+ m_system = new GHOST_SystemCarbon ();
+# endif
# else
m_system = new GHOST_SystemX11 ();
# endif
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 229744e2000..84298d3e3ff 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -291,7 +291,7 @@ GHOST_TSuccess GHOST_System::init()
#ifdef GHOST_DEBUG
if (m_eventManager) {
m_eventPrinter = new GHOST_EventPrinter();
- //m_eventManager->addConsumer(m_eventPrinter);
+ m_eventManager->addConsumer(m_eventPrinter);
}
#endif // GHOST_DEBUG
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index fb1b96fcbc7..57d6f6c06cc 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -788,21 +788,21 @@ OSStatus GHOST_SystemCarbon::handleTabletEvent(EventRef event)
switch(tabletProximityRecord.pointerType)
{
case 1: /* stylus */
- ct.Active = 1;
+ ct.Active = GHOST_kTabletModeStylus;
break;
case 2: /* puck, not supported so far */
- ct.Active = 0;
+ ct.Active = GHOST_kTabletModeNone;
break;
case 3: /* eraser */
- ct.Active = 2;
+ ct.Active = GHOST_kTabletModeEraser;
break;
default:
- ct.Active = 0;
+ ct.Active = GHOST_kTabletModeNone;
break;
}
} else {
// pointer is leaving - return to mouse
- ct.Active = 0;
+ ct.Active = GHOST_kTabletModeNone;
}
}
}
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
new file mode 100644
index 00000000000..cd2cf12daa1
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -0,0 +1,274 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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): Maarten Gribnau 05/2001
+ * Damien Plisson 09/2009
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * @file GHOST_SystemCocoa.h
+ * Declaration of GHOST_SystemCocoa class.
+ */
+
+#ifndef _GHOST_SYSTEM_COCOA_H_
+#define _GHOST_SYSTEM_COCOA_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+//#define __CARBONSOUND__
+
+
+#include "GHOST_System.h"
+
+class GHOST_EventCursor;
+class GHOST_EventKey;
+class GHOST_EventWindow;
+
+
+class GHOST_SystemCocoa : public GHOST_System {
+public:
+ /**
+ * Constructor.
+ */
+ GHOST_SystemCocoa();
+
+ /**
+ * Destructor.
+ */
+ ~GHOST_SystemCocoa();
+
+ /***************************************************************************************
+ ** Time(r) functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the system time.
+ * Returns the number of milliseconds since the start of the system process.
+ * Based on ANSI clock() routine.
+ * @return The number of milliseconds.
+ */
+ virtual GHOST_TUns64 getMilliSeconds() const;
+
+ /***************************************************************************************
+ ** Display/window management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the number of displays on this system.
+ * @return The number of displays.
+ */
+ virtual GHOST_TUns8 getNumDisplays() const;
+
+ /**
+ * Returns the dimensions of the main display on this system.
+ * @return The dimension of the main display.
+ */
+ virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+
+ /**
+ * Create a new window.
+ * The new window is added to the list of windows managed.
+ * Never explicitly delete the window, use disposeWindow() instead.
+ * @param title The name of the window (displayed in the title bar of the window if the OS supports it).
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state of the window when opened.
+ * @param type The type of drawing context installed in this window.
+ * @param parentWindow Parent (embedder) window
+ * @return The new window (or 0 if creation failed).
+ */
+ virtual GHOST_IWindow* createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const GHOST_TEmbedderWindowID parentWindow = 0
+ );
+
+ virtual GHOST_TSuccess beginFullScreen(
+ const GHOST_DisplaySetting& setting,
+ GHOST_IWindow** window,
+ const bool stereoVisual
+ );
+
+ virtual GHOST_TSuccess endFullScreen( void );
+
+ /***************************************************************************************
+ ** Event management functionality
+ ***************************************************************************************/
+
+ /**
+ * Gets events from the system and stores them in the queue.
+ * @param waitForEvent Flag to wait for an event (or return immediately).
+ * @return Indication of the presence of events.
+ */
+ virtual bool processEvents(bool waitForEvent);
+
+ /***************************************************************************************
+ ** Cursor management functionality
+ ***************************************************************************************/
+
+ /**
+ * Returns the current location of the cursor (location in screen coordinates)
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
+
+ /**
+ * Updates the location of the cursor (location in screen coordinates).
+ * @param x The x-coordinate of the cursor.
+ * @param y The y-coordinate of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const;
+
+ /***************************************************************************************
+ ** Access to mouse button and keyboard states.
+ ***************************************************************************************/
+
+ /**
+ * Returns the state of all modifier keys.
+ * @param keys The state of all modifier keys (true == pressed).
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
+
+ /**
+ * Returns the state of the mouse buttons (ouside the message queue).
+ * @param buttons The state of the buttons.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+
+ /**
+ * Returns Clipboard data
+ * @param selection Indicate which buffer to return
+ * @return Returns the selected buffer
+ */
+ virtual GHOST_TUns8* getClipboard(bool selection) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * @param buffer The buffer to be copied
+ * @param selection Indicates which buffer to copy too, only used on X11
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+
+protected:
+ /**
+ * Initializes the system.
+ * For now, it justs registers the window class (WNDCLASS).
+ * @return A success value.
+ */
+ virtual GHOST_TSuccess init();
+
+ /**
+ * Closes the system down.
+ * @return A success value.
+ */
+ virtual GHOST_TSuccess exit();
+
+
+ /**
+ * Handles a tablet event.
+ * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * @return Indication whether the event was handled.
+ */
+ int handleTabletEvent(void *eventPtr);
+ /**
+ * Handles a mouse event.
+ * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * @return Indication whether the event was handled.
+ */
+ int handleMouseEvent(void *eventPtr);
+
+ /**
+ * Handles a key event.
+ * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * @return Indication whether the event was handled.
+ */
+ int handleKeyEvent(void *eventPtr);
+
+ /**
+ * Handles a window event.
+ * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * @return Indication whether the event was handled.
+ */
+ int handleWindowEvent(void *eventPtr);
+
+ /**
+ * Handles all basic Mac application stuff for a mouse down event.
+ * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+ * @return Indication whether the event was handled.
+ */
+ // bool handleMouseDown(void *eventPtr);
+
+ /**
+ * Handles a Mac menu command.
+ * @param menuResult A Mac menu/item identifier.
+ * @return Indication whether the event was handled.
+ */
+ // bool handleMenuCommand(GHOST_TInt32 menuResult);
+
+ /* callback for blender generated events */
+// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
+
+
+ /**
+ * Callback for Mac Timer tasks that expire.
+ * @param tmTask Pointer to the timer task that expired.
+ */
+ //static void s_timerCallback(TMTaskPtr tmTask);
+
+ /** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */
+ void* m_autoReleasePool;
+
+ /** Event handler reference. */
+ //EventHandlerRef m_handler;
+
+ /** Start time at initialization. */
+ GHOST_TUns64 m_start_time;
+
+ /** Mouse buttons state */
+ GHOST_TUns32 m_pressedMouseButtons;
+
+ /** State of the modifiers. */
+ GHOST_TUns32 m_modifierMask;
+
+ /** Ignores window size messages (when window is dragged). */
+ bool m_ignoreWindowSizedMessages;
+};
+
+#endif // _GHOST_SYSTEM_COCOA_H_
+
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
new file mode 100644
index 00000000000..252ac9e6318
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -0,0 +1,1292 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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): Maarten Gribnau 05/2001
+ * Damien Plisson 09/2009
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#import <Cocoa/Cocoa.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include "GHOST_SystemCocoa.h"
+
+#include "GHOST_DisplayManagerCocoa.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventWheel.h"
+#include "GHOST_EventNDOF.h"
+
+#include "GHOST_TimerManager.h"
+#include "GHOST_TimerTask.h"
+#include "GHOST_WindowManager.h"
+#include "GHOST_WindowCocoa.h"
+#include "GHOST_NDOFManager.h"
+#include "AssertMacros.h"
+
+#pragma mark KeyMap, mouse converters
+
+//TODO: remove (kept as reminder to implement window events)
+/*
+const EventTypeSpec kEvents[] =
+{
+ { kEventClassAppleEvent, kEventAppleEvent },
+
+// { kEventClassApplication, kEventAppActivated },
+// { kEventClassApplication, kEventAppDeactivated },
+
+ { kEventClassKeyboard, kEventRawKeyDown },
+ { kEventClassKeyboard, kEventRawKeyRepeat },
+ { kEventClassKeyboard, kEventRawKeyUp },
+ { kEventClassKeyboard, kEventRawKeyModifiersChanged },
+
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseUp },
+ { kEventClassMouse, kEventMouseMoved },
+ { kEventClassMouse, kEventMouseDragged },
+ { kEventClassMouse, kEventMouseWheelMoved },
+
+ { kEventClassWindow, kEventWindowClickZoomRgn } , // for new zoom behaviour
+ { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour
+ { kEventClassWindow, kEventWindowExpand } , // for new zoom behaviour
+ { kEventClassWindow, kEventWindowExpandAll }, // for new zoom behaviour
+
+ { kEventClassWindow, kEventWindowClose },
+ { kEventClassWindow, kEventWindowActivated },
+ { kEventClassWindow, kEventWindowDeactivated },
+ { kEventClassWindow, kEventWindowUpdate },
+ { kEventClassWindow, kEventWindowBoundsChanged },
+
+ { kEventClassBlender, kEventBlenderNdofAxis },
+ { kEventClassBlender, kEventBlenderNdofButtons }
+
+
+
+};*/
+
+static GHOST_TButtonMask convertButton(EventMouseButton button)
+{
+ switch (button) {
+ case 0:
+ return GHOST_kButtonMaskLeft;
+ case 1:
+ return GHOST_kButtonMaskRight;
+ case 2:
+ return GHOST_kButtonMaskMiddle;
+ case 3:
+ return GHOST_kButtonMaskButton4;
+ case 4:
+ return GHOST_kButtonMaskButton5;
+ default:
+ return GHOST_kButtonMaskLeft;
+ }
+}
+
+/**
+ * Converts Mac rawkey codes (same for Cocoa & Carbon)
+ * into GHOST key codes
+ * @param rawCode The raw physical key code
+ * @param recvChar the character ignoring modifiers (except for shift)
+ * @return Ghost key code
+ */
+static GHOST_TKey convertKey(int rawCode, unichar recvChar)
+{
+
+ //printf("\nrecvchar %c 0x%x",recvChar,recvChar);
+ switch (rawCode) {
+ /*Physical keycodes not used due to map changes in int'l keyboards
+ case kVK_ANSI_A: return GHOST_kKeyA;
+ case kVK_ANSI_B: return GHOST_kKeyB;
+ case kVK_ANSI_C: return GHOST_kKeyC;
+ case kVK_ANSI_D: return GHOST_kKeyD;
+ case kVK_ANSI_E: return GHOST_kKeyE;
+ case kVK_ANSI_F: return GHOST_kKeyF;
+ case kVK_ANSI_G: return GHOST_kKeyG;
+ case kVK_ANSI_H: return GHOST_kKeyH;
+ case kVK_ANSI_I: return GHOST_kKeyI;
+ case kVK_ANSI_J: return GHOST_kKeyJ;
+ case kVK_ANSI_K: return GHOST_kKeyK;
+ case kVK_ANSI_L: return GHOST_kKeyL;
+ case kVK_ANSI_M: return GHOST_kKeyM;
+ case kVK_ANSI_N: return GHOST_kKeyN;
+ case kVK_ANSI_O: return GHOST_kKeyO;
+ case kVK_ANSI_P: return GHOST_kKeyP;
+ case kVK_ANSI_Q: return GHOST_kKeyQ;
+ case kVK_ANSI_R: return GHOST_kKeyR;
+ case kVK_ANSI_S: return GHOST_kKeyS;
+ case kVK_ANSI_T: return GHOST_kKeyT;
+ case kVK_ANSI_U: return GHOST_kKeyU;
+ case kVK_ANSI_V: return GHOST_kKeyV;
+ case kVK_ANSI_W: return GHOST_kKeyW;
+ case kVK_ANSI_X: return GHOST_kKeyX;
+ case kVK_ANSI_Y: return GHOST_kKeyY;
+ case kVK_ANSI_Z: return GHOST_kKeyZ;*/
+
+ /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/
+ case kVK_ISO_Section: return GHOST_kKeyUnknown;
+ case kVK_ANSI_1: return GHOST_kKey1;
+ case kVK_ANSI_2: return GHOST_kKey2;
+ case kVK_ANSI_3: return GHOST_kKey3;
+ case kVK_ANSI_4: return GHOST_kKey4;
+ case kVK_ANSI_5: return GHOST_kKey5;
+ case kVK_ANSI_6: return GHOST_kKey6;
+ case kVK_ANSI_7: return GHOST_kKey7;
+ case kVK_ANSI_8: return GHOST_kKey8;
+ case kVK_ANSI_9: return GHOST_kKey9;
+ case kVK_ANSI_0: return GHOST_kKey0;
+
+ case kVK_ANSI_Keypad0: return GHOST_kKeyNumpad0;
+ case kVK_ANSI_Keypad1: return GHOST_kKeyNumpad1;
+ case kVK_ANSI_Keypad2: return GHOST_kKeyNumpad2;
+ case kVK_ANSI_Keypad3: return GHOST_kKeyNumpad3;
+ case kVK_ANSI_Keypad4: return GHOST_kKeyNumpad4;
+ case kVK_ANSI_Keypad5: return GHOST_kKeyNumpad5;
+ case kVK_ANSI_Keypad6: return GHOST_kKeyNumpad6;
+ case kVK_ANSI_Keypad7: return GHOST_kKeyNumpad7;
+ case kVK_ANSI_Keypad8: return GHOST_kKeyNumpad8;
+ case kVK_ANSI_Keypad9: return GHOST_kKeyNumpad9;
+ case kVK_ANSI_KeypadDecimal: return GHOST_kKeyNumpadPeriod;
+ case kVK_ANSI_KeypadEnter: return GHOST_kKeyNumpadEnter;
+ case kVK_ANSI_KeypadPlus: return GHOST_kKeyNumpadPlus;
+ case kVK_ANSI_KeypadMinus: return GHOST_kKeyNumpadMinus;
+ case kVK_ANSI_KeypadMultiply: return GHOST_kKeyNumpadAsterisk;
+ case kVK_ANSI_KeypadDivide: return GHOST_kKeyNumpadSlash;
+ case kVK_ANSI_KeypadClear: return GHOST_kKeyUnknown;
+
+ case kVK_F1: return GHOST_kKeyF1;
+ case kVK_F2: return GHOST_kKeyF2;
+ case kVK_F3: return GHOST_kKeyF3;
+ case kVK_F4: return GHOST_kKeyF4;
+ case kVK_F5: return GHOST_kKeyF5;
+ case kVK_F6: return GHOST_kKeyF6;
+ case kVK_F7: return GHOST_kKeyF7;
+ case kVK_F8: return GHOST_kKeyF8;
+ case kVK_F9: return GHOST_kKeyF9;
+ case kVK_F10: return GHOST_kKeyF10;
+ case kVK_F11: return GHOST_kKeyF11;
+ case kVK_F12: return GHOST_kKeyF12;
+ case kVK_F13: return GHOST_kKeyF13;
+ case kVK_F14: return GHOST_kKeyF14;
+ case kVK_F15: return GHOST_kKeyF15;
+ case kVK_F16: return GHOST_kKeyF16;
+ case kVK_F17: return GHOST_kKeyF17;
+ case kVK_F18: return GHOST_kKeyF18;
+ case kVK_F19: return GHOST_kKeyF19;
+ case kVK_F20: return GHOST_kKeyF20;
+
+ case kVK_UpArrow: return GHOST_kKeyUpArrow;
+ case kVK_DownArrow: return GHOST_kKeyDownArrow;
+ case kVK_LeftArrow: return GHOST_kKeyLeftArrow;
+ case kVK_RightArrow: return GHOST_kKeyRightArrow;
+
+ case kVK_Return: return GHOST_kKeyEnter;
+ case kVK_Delete: return GHOST_kKeyBackSpace;
+ case kVK_ForwardDelete: return GHOST_kKeyDelete;
+ case kVK_Escape: return GHOST_kKeyEsc;
+ case kVK_Tab: return GHOST_kKeyTab;
+ case kVK_Space: return GHOST_kKeySpace;
+
+ case kVK_Home: return GHOST_kKeyHome;
+ case kVK_End: return GHOST_kKeyEnd;
+ case kVK_PageUp: return GHOST_kKeyUpPage;
+ case kVK_PageDown: return GHOST_kKeyDownPage;
+
+ /*case kVK_ANSI_Minus: return GHOST_kKeyMinus;
+ case kVK_ANSI_Equal: return GHOST_kKeyEqual;
+ case kVK_ANSI_Comma: return GHOST_kKeyComma;
+ case kVK_ANSI_Period: return GHOST_kKeyPeriod;
+ case kVK_ANSI_Slash: return GHOST_kKeySlash;
+ case kVK_ANSI_Semicolon: return GHOST_kKeySemicolon;
+ case kVK_ANSI_Quote: return GHOST_kKeyQuote;
+ case kVK_ANSI_Backslash: return GHOST_kKeyBackslash;
+ case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket;
+ case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket;
+ case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/
+
+ case kVK_VolumeUp:
+ case kVK_VolumeDown:
+ case kVK_Mute:
+ return GHOST_kKeyUnknown;
+
+ default:
+ /*Then detect on character value for "remappable" keys in int'l keyboards*/
+ if ((recvChar >= 'A') && (recvChar <= 'Z')) {
+ return (GHOST_TKey) (recvChar - 'A' + GHOST_kKeyA);
+ } else if ((recvChar >= 'a') && (recvChar <= 'z')) {
+ return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA);
+ } else
+ switch (recvChar) {
+ case '-': return GHOST_kKeyMinus;
+ case '=': return GHOST_kKeyEqual;
+ case ',': return GHOST_kKeyComma;
+ case '.': return GHOST_kKeyPeriod;
+ case '/': return GHOST_kKeySlash;
+ case ';': return GHOST_kKeySemicolon;
+ case '\'': return GHOST_kKeyQuote;
+ case '\\': return GHOST_kKeyBackslash;
+ case '[': return GHOST_kKeyLeftBracket;
+ case ']': return GHOST_kKeyRightBracket;
+ case '`': return GHOST_kKeyAccentGrave;
+ default:
+ return GHOST_kKeyUnknown;
+ }
+ }
+ return GHOST_kKeyUnknown;
+}
+
+/* MacOSX returns a Roman charset with kEventParamKeyMacCharCodes
+ * as defined here: http://developer.apple.com/documentation/mac/Text/Text-516.html
+ * I am not sure how international this works...
+ * For cross-platform convention, we'll use the Latin ascii set instead.
+ * As defined at: http://www.ramsch.org/martin/uni/fmi-hp/iso8859-1.html
+ *
+ */
+static unsigned char convertRomanToLatin(unsigned char ascii)
+{
+
+ if(ascii<128) return ascii;
+
+ switch(ascii) {
+ case 128: return 142;
+ case 129: return 143;
+ case 130: return 128;
+ case 131: return 201;
+ case 132: return 209;
+ case 133: return 214;
+ case 134: return 220;
+ case 135: return 225;
+ case 136: return 224;
+ case 137: return 226;
+ case 138: return 228;
+ case 139: return 227;
+ case 140: return 229;
+ case 141: return 231;
+ case 142: return 233;
+ case 143: return 232;
+ case 144: return 234;
+ case 145: return 235;
+ case 146: return 237;
+ case 147: return 236;
+ case 148: return 238;
+ case 149: return 239;
+ case 150: return 241;
+ case 151: return 243;
+ case 152: return 242;
+ case 153: return 244;
+ case 154: return 246;
+ case 155: return 245;
+ case 156: return 250;
+ case 157: return 249;
+ case 158: return 251;
+ case 159: return 252;
+ case 160: return 0;
+ case 161: return 176;
+ case 162: return 162;
+ case 163: return 163;
+ case 164: return 167;
+ case 165: return 183;
+ case 166: return 182;
+ case 167: return 223;
+ case 168: return 174;
+ case 169: return 169;
+ case 170: return 174;
+ case 171: return 180;
+ case 172: return 168;
+ case 173: return 0;
+ case 174: return 198;
+ case 175: return 216;
+ case 176: return 0;
+ case 177: return 177;
+ case 178: return 0;
+ case 179: return 0;
+ case 180: return 165;
+ case 181: return 181;
+ case 182: return 0;
+ case 183: return 0;
+ case 184: return 215;
+ case 185: return 0;
+ case 186: return 0;
+ case 187: return 170;
+ case 188: return 186;
+ case 189: return 0;
+ case 190: return 230;
+ case 191: return 248;
+ case 192: return 191;
+ case 193: return 161;
+ case 194: return 172;
+ case 195: return 0;
+ case 196: return 0;
+ case 197: return 0;
+ case 198: return 0;
+ case 199: return 171;
+ case 200: return 187;
+ case 201: return 201;
+ case 202: return 0;
+ case 203: return 192;
+ case 204: return 195;
+ case 205: return 213;
+ case 206: return 0;
+ case 207: return 0;
+ case 208: return 0;
+ case 209: return 0;
+ case 210: return 0;
+
+ case 214: return 247;
+
+ case 229: return 194;
+ case 230: return 202;
+ case 231: return 193;
+ case 232: return 203;
+ case 233: return 200;
+ case 234: return 205;
+ case 235: return 206;
+ case 236: return 207;
+ case 237: return 204;
+ case 238: return 211;
+ case 239: return 212;
+ case 240: return 0;
+ case 241: return 210;
+ case 242: return 218;
+ case 243: return 219;
+ case 244: return 217;
+ case 245: return 0;
+ case 246: return 0;
+ case 247: return 0;
+ case 248: return 0;
+ case 249: return 0;
+ case 250: return 0;
+
+
+ default: return 0;
+ }
+
+}
+
+#define FIRSTFILEBUFLG 512
+static bool g_hasFirstFile = false;
+static char g_firstFileBuf[512];
+
+//TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true
+extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
+ if (g_hasFirstFile) {
+ strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
+ buf[FIRSTFILEBUFLG - 1] = '\0';
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+#pragma mark Cocoa objects
+
+/**
+ * CocoaAppDelegate
+ * ObjC object to capture applicationShouldTerminate, and send quit event
+ **/
+@interface CocoaAppDelegate : NSObject
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+@end
+
+@implementation CocoaAppDelegate : NSObject
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+ //Note that Cmd+Q is already handled by keyhandler
+ //FIXME: Cocoa_SendQuit();
+ //sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );
+ return NSTerminateCancel;
+}
+@end
+
+
+
+#pragma mark initialization/finalization
+
+/***/
+
+GHOST_SystemCocoa::GHOST_SystemCocoa()
+{
+ m_modifierMask =0;
+ m_pressedMouseButtons =0;
+ m_displayManager = new GHOST_DisplayManagerCocoa ();
+ GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
+ m_displayManager->initialize();
+
+ //NSEvent timeStamp is given in system uptime, state start date is boot time
+ //FIXME : replace by Cocoa equivalent
+ int mib[2];
+ struct timeval boottime;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
+ len = sizeof(struct timeval);
+
+ sysctl(mib, 2, &boottime, &len, NULL, 0);
+ m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
+
+ m_ignoreWindowSizedMessages = false;
+}
+
+GHOST_SystemCocoa::~GHOST_SystemCocoa()
+{
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::init()
+{
+
+ GHOST_TSuccess success = GHOST_System::init();
+ if (success) {
+ //ProcessSerialNumber psn;
+
+ //FIXME: Carbon stuff to move window & menu to foreground
+ /*if (!GetCurrentProcess(&psn)) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
+ }*/
+
+ m_autoReleasePool = [[NSAutoreleasePool alloc] init];
+ if (NSApp == nil) {
+ [NSApplication sharedApplication];
+
+ if ([NSApp mainMenu] == nil) {
+ //FIXME: CreateApplicationMenus();
+ }
+ [NSApp finishLaunching];
+ }
+ if ([NSApp delegate] == nil) {
+ [NSApp setDelegate:[[CocoaAppDelegate alloc] init]];
+ }
+
+
+ /*
+ * Initialize the cursor to the standard arrow shape (so that we can change it later on).
+ * This initializes the cursor's visibility counter to 0.
+ */
+ /*::InitCursor();
+
+ MenuRef windMenu;
+ ::CreateStandardWindowMenu(0, &windMenu);
+ ::InsertMenu(windMenu, 0);
+ ::DrawMenuBar();
+
+ ::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler);
+
+ ::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false);
+ ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false);
+ ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false);
+ ::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false);
+ */
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::exit()
+{
+ NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool;
+ [pool drain];
+ return GHOST_System::exit();
+}
+
+#pragma mark window management
+
+GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
+{
+ //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])
+ int mib[2];
+ struct timeval boottime;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
+ len = sizeof(struct timeval);
+
+ sysctl(mib, 2, &boottime, &len, NULL, 0);
+
+ return ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
+}
+
+
+GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const
+{
+ //Note that OS X supports monitor hot plug
+ // We do not support multiple monitors at the moment
+ return [[NSScreen screens] count];
+}
+
+
+void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+ //TODO: Provide visible frame or total frame, check for consistency with rest of code
+ NSRect frame = [[NSScreen mainScreen] visibleFrame];
+
+ width = frame.size.width;
+ height = frame.size.height;
+}
+
+
+GHOST_IWindow* GHOST_SystemCocoa::createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ bool stereoVisual,
+ const GHOST_TEmbedderWindowID parentWindow
+)
+{
+ GHOST_IWindow* window = 0;
+
+ window = new GHOST_WindowCocoa (title, left, top, width, height, state, type);
+
+ if (window) {
+ if (window->getValid()) {
+ // Store the pointer to the window
+ GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
+ delete window;
+ window = 0;
+ }
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n");
+ }
+ return window;
+}
+
+GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+
+ //TODO: update this method
+ // need yo make this Carbon all on 10.5 for fullscreen to work correctly
+ CGCaptureAllDisplays();
+
+ success = GHOST_System::beginFullScreen( setting, window, stereoVisual);
+
+ if( success != GHOST_kSuccess ) {
+ // fullscreen failed for other reasons, release
+ CGReleaseAllDisplays();
+ }
+
+ return success;
+}
+
+GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)
+{
+ //TODO: update this method
+ CGReleaseAllDisplays();
+ return GHOST_System::endFullScreen();
+}
+
+
+
+
+GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
+{
+ NSPoint mouseLoc = [NSEvent mouseLocation];
+
+ // Convert the coordinates to screen coordinates
+ x = (GHOST_TInt32)mouseLoc.x;
+ y = (GHOST_TInt32)mouseLoc.y;
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const
+{
+ float xf=(float)x, yf=(float)y;
+
+ CGAssociateMouseAndMouseCursorPosition(false);
+ CGWarpMouseCursorPosition(CGPointMake(xf, yf));
+ CGAssociateMouseAndMouseCursorPosition(true);
+
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const
+{
+ NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
+ //Direct query to modifierFlags can be used in 10.6
+
+ keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & NSAlternateKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftShift, (modifiers & NSShiftKeyMask) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftControl, (modifiers & NSControlKeyMask) ? true : false);
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
+{
+ buttons.clear();
+ buttons.set(GHOST_kButtonMaskLeft, m_pressedMouseButtons & GHOST_kButtonMaskLeft);
+ buttons.set(GHOST_kButtonMaskRight, m_pressedMouseButtons & GHOST_kButtonMaskRight);
+ buttons.set(GHOST_kButtonMaskMiddle, m_pressedMouseButtons & GHOST_kButtonMaskMiddle);
+ buttons.set(GHOST_kButtonMaskButton4, m_pressedMouseButtons & GHOST_kButtonMaskButton4);
+ buttons.set(GHOST_kButtonMaskButton5, m_pressedMouseButtons & GHOST_kButtonMaskButton5);
+ return GHOST_kSuccess;
+}
+
+
+
+#pragma mark Event handlers
+
+/**
+ * The event queue polling function
+ */
+bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
+{
+ NSAutoreleasePool* pool = (NSAutoreleasePool*)m_autoReleasePool;
+ //bool anyProcessed = false;
+ NSEvent *event;
+
+ //Reinit the AutoReleasePool
+ //This is not done the typical Cocoa way (init at beginning of loop, and drain at the end)
+ //to allow pool to work with other function calls outside this loop (but in same thread)
+ [pool drain];
+ m_autoReleasePool = [[NSAutoreleasePool alloc] init];
+
+ // SetMouseCoalescingEnabled(false, NULL);
+ //TODO : implement timer ??
+
+ /*do {
+ GHOST_TimerManager* timerMgr = getTimerManager();
+
+ if (waitForEvent) {
+ GHOST_TUns64 next = timerMgr->nextFireTime();
+ double timeOut;
+
+ if (next == GHOST_kFireTimeNever) {
+ timeOut = kEventDurationForever;
+ } else {
+ timeOut = (double)(next - getMilliSeconds())/1000.0;
+ if (timeOut < 0.0)
+ timeOut = 0.0;
+ }
+
+ ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed = true;
+ }
+
+ //TODO: check fullscreen redrawing issues
+ if (getFullScreen()) {
+ // Check if the full-screen window is dirty
+ GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
+ if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
+ anyProcessed = true;
+ }
+ }*/
+
+ do {
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event==nil)
+ break;
+
+ //anyProcessed = true;
+
+ switch ([event type]) {
+ case NSKeyDown:
+ case NSKeyUp:
+ case NSFlagsChanged:
+ handleKeyEvent(event);
+
+ /* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */
+ /* if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {
+ [NSApp sendEvent:event];
+ }*/
+ break;
+
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSMouseMoved:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSScrollWheel:
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSOtherMouseDragged:
+ handleMouseEvent(event);
+ break;
+
+ case NSTabletPoint:
+ case NSTabletProximity:
+ handleTabletEvent(event);
+ break;
+
+ /* Trackpad features, will need OS X 10.6 for implementation
+ case NSEventTypeGesture:
+ case NSEventTypeMagnify:
+ case NSEventTypeSwipe:
+ case NSEventTypeRotate:
+ case NSEventTypeBeginGesture:
+ case NSEventTypeEndGesture:
+ break; */
+
+ /*Unused events
+ NSMouseEntered = 8,
+ NSMouseExited = 9,
+ NSAppKitDefined = 13,
+ NSSystemDefined = 14,
+ NSApplicationDefined = 15,
+ NSPeriodic = 16,
+ NSCursorUpdate = 17,*/
+
+ default:
+ break;
+ }
+ //Resend event to NSApp to ensure Mac wide events are handled
+ [NSApp sendEvent:event];
+ } while (event!= nil);
+ //} while (waitForEvent && !anyProcessed); Needed only for timer implementation
+
+
+ return true; //anyProcessed;
+}
+
+//TODO: To be called from NSWindow delegate
+int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
+{
+ /*WindowRef windowRef;
+ GHOST_WindowCocoa *window;
+
+ // Check if the event was send to a GHOST window
+ ::GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &windowRef);
+ window = (GHOST_WindowCarbon*) ::GetWRefCon(windowRef);
+ if (!validWindow(window)) {
+ return err;
+ }
+
+ //if (!getFullScreen()) {
+ err = noErr;
+ switch([event ])
+ {
+ case kEventWindowClose:
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
+ break;
+ case kEventWindowActivated:
+ m_windowManager->setActiveWindow(window);
+ window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
+ break;
+ case kEventWindowDeactivated:
+ m_windowManager->setWindowInactive(window);
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
+ break;
+ case kEventWindowUpdate:
+ //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n");
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
+ break;
+ case kEventWindowBoundsChanged:
+ if (!m_ignoreWindowSizedMessages)
+ {
+ window->updateDrawingContext();
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
+ }
+ break;
+ default:
+ err = eventNotHandledErr;
+ break;
+ }
+// }
+ //else {
+ //window = (GHOST_WindowCarbon*) m_windowManager->getFullScreenWindow();
+ //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n");
+ //::RemoveEventFromQueue(::GetMainEventQueue(), event);
+ //}
+ */
+ return GHOST_kSuccess;
+}
+
+int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
+{
+ NSEvent *event = (NSEvent *)eventPtr;
+ GHOST_IWindow* window = m_windowManager->getActiveWindow();
+ GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
+ NSUInteger tabletEvent;
+
+ ct.Pressure = 0;
+ ct.Xtilt = 0;
+ ct.Ytilt = 0;
+
+ //Handle tablet events combined with mouse events
+ switch ([event subtype]) {
+ case NX_SUBTYPE_TABLET_POINT:
+ tabletEvent = NSTabletPoint;
+ break;
+ case NX_SUBTYPE_TABLET_PROXIMITY:
+ tabletEvent = NSTabletProximity;
+ break;
+
+ default:
+ tabletEvent = [event type];
+ break;
+ }
+
+ switch (tabletEvent) {
+ case NSTabletPoint:
+ ct.Pressure = [event tangentialPressure];
+ ct.Xtilt = [event tilt].x;
+ ct.Ytilt = [event tilt].y;
+ break;
+
+ case NSTabletProximity:
+ if ([event isEnteringProximity])
+ {
+ //pointer is entering tablet area proximity
+ switch ([event pointingDeviceType]) {
+ case NSPenPointingDevice:
+ ct.Active = GHOST_kTabletModeStylus;
+ break;
+ case NSEraserPointingDevice:
+ ct.Active = GHOST_kTabletModeEraser;
+ break;
+ case NSCursorPointingDevice:
+ case NSUnknownPointingDevice:
+ default:
+ ct.Active = GHOST_kTabletModeNone;
+ break;
+ }
+ } else {
+ // pointer is leaving - return to mouse
+ ct.Active = GHOST_kTabletModeNone;
+ }
+ break;
+
+ default:
+ GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received");
+ return GHOST_kFailure;
+ break;
+ }
+ return GHOST_kSuccess;
+}
+
+
+int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
+{
+ NSEvent *event = (NSEvent *)eventPtr;
+ GHOST_IWindow* window = m_windowManager->getActiveWindow();
+
+ switch ([event type])
+ {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ if (m_windowManager->getActiveWindow()) {
+ pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
+ }
+ handleTabletEvent(eventPtr);
+ break;
+
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ if (m_windowManager->getActiveWindow()) {
+ pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
+ }
+ handleTabletEvent(eventPtr);
+ break;
+
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ handleTabletEvent(eventPtr);
+ case NSMouseMoved:
+ {
+ NSPoint mousePos = [event locationInWindow];
+ pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
+ break;
+ }
+
+ case NSScrollWheel:
+ {
+ GHOST_TInt32 delta;
+ delta = [event deltaY] > 0 ? 1 : -1;
+ pushEvent(new GHOST_EventWheel(getMilliSeconds(), window, delta));
+
+ }
+ break;
+
+ default:
+ return GHOST_kFailure;
+ break;
+ }
+
+ return GHOST_kSuccess;
+}
+
+
+int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
+{
+ NSEvent *event = (NSEvent *)eventPtr;
+ GHOST_IWindow* window = m_windowManager->getActiveWindow();
+ NSUInteger modifiers;
+ GHOST_TKey keyCode;
+ unsigned char ascii;
+
+ /* Can happen, very rarely - seems to only be when command-H makes
+ * the window go away and we still get an HKey up.
+ */
+ if (!window) {
+ return GHOST_kFailure;
+ }
+
+ switch ([event type]) {
+ case NSKeyDown:
+ case NSKeyUp:
+ keyCode = convertKey([event keyCode],
+ [[event charactersIgnoringModifiers] characterAtIndex:0]);
+ ascii= convertRomanToLatin((char)[[event characters] characterAtIndex:0]);
+
+ if ([event type] == NSKeyDown) {
+ pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) );
+ //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii);
+ } else {
+ pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyUp, window, keyCode, ascii) );
+ }
+ break;
+
+ case NSFlagsChanged:
+ modifiers = [event modifierFlags];
+ if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
+ }
+ if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
+ }
+ if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
+ }
+ if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
+ }
+
+ m_modifierMask = modifiers;
+ break;
+
+ default:
+ return GHOST_kFailure;
+ break;
+ }
+
+ return GHOST_kSuccess;
+}
+
+
+/* System wide mouse clicks are handled directly through systematic event forwarding to Cocoa
+bool GHOST_SystemCarbon::handleMouseDown(void *eventPtr)
+{
+ NSEvent *event = (NSEvent *)eventPtr;
+ WindowPtr window;
+ short part;
+ BitMap screenBits;
+ bool handled = true;
+ GHOST_WindowCarbon* ghostWindow;
+ Point mousePos = {0 , 0};
+
+ ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
+
+ part = ::FindWindow(mousePos, &window);
+ ghostWindow = (GHOST_WindowCarbon*) ::GetWRefCon(window);
+
+ switch (part) {
+ case inMenuBar:
+ handleMenuCommand(::MenuSelect(mousePos));
+ break;
+
+ case inDrag:
+ // *
+ // * The DragWindow() routine creates a lot of kEventWindowBoundsChanged
+ // * events. By setting m_ignoreWindowSizedMessages these are suppressed.
+ // * @see GHOST_SystemCarbon::handleWindowEvent(EventRef event)
+ // *
+ // even worse: scale window also generates a load of events, and nothing
+ // is handled (read: client's event proc called) until you release mouse (ton)
+
+ GHOST_ASSERT(validWindow(ghostWindow), "GHOST_SystemCarbon::handleMouseDown: invalid window");
+ m_ignoreWindowSizedMessages = true;
+ ::DragWindow(window, mousePos, &GetQDGlobalsScreenBits(&screenBits)->bounds);
+ m_ignoreWindowSizedMessages = false;
+
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, ghostWindow) );
+
+ break;
+
+ case inContent:
+ if (window != ::FrontWindow()) {
+ ::SelectWindow(window);
+ //
+ // * We add a mouse down event on the newly actived window
+ // *
+ //GHOST_PRINT("GHOST_SystemCarbon::handleMouseDown(): adding mouse down event, " << ghostWindow << "\n");
+ EventMouseButton button;
+ ::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
+ pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonDown, ghostWindow, convertButton(button)));
+ } else {
+ handled = false;
+ }
+ break;
+
+ case inGoAway:
+ GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+ if (::TrackGoAway(window, mousePos))
+ {
+ // todo: add option-close, because itÿs in the HIG
+ // if (event.modifiers & optionKey) {
+ // Close the clean documents, others will be confirmed one by one.
+ //}
+ // else {
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, ghostWindow));
+ //}
+ }
+ break;
+
+ case inGrow:
+ GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+ ::ResizeWindow(window, mousePos, NULL, NULL);
+ break;
+
+ case inZoomIn:
+ case inZoomOut:
+ GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+ if (::TrackBox(window, mousePos, part)) {
+ int macState;
+
+ macState = ghostWindow->getMac_windowState();
+ if ( macState== 0)
+ ::ZoomWindow(window, part, true);
+ else
+ if (macState == 2) { // always ok
+ ::ZoomWindow(window, part, true);
+ ghostWindow->setMac_windowState(1);
+ } else { // need to force size again
+ // GHOST_TUns32 scr_x,scr_y; //unused
+ Rect outAvailableRect;
+
+ ghostWindow->setMac_windowState(2);
+ ::GetAvailableWindowPositioningBounds ( GetMainDevice(), &outAvailableRect);
+
+ //this->getMainDisplayDimensions(scr_x,scr_y);
+ ::SizeWindow (window, outAvailableRect.right-outAvailableRect.left,outAvailableRect.bottom-outAvailableRect.top-1,false);
+ ::MoveWindow (window, outAvailableRect.left, outAvailableRect.top,true);
+ }
+
+ }
+ break;
+
+ default:
+ handled = false;
+ break;
+ }
+
+ return handled;
+}
+
+
+bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult)
+{
+ short menuID;
+ short menuItem;
+ UInt32 command;
+ bool handled;
+ OSErr err;
+
+ menuID = HiWord(menuResult);
+ menuItem = LoWord(menuResult);
+
+ err = ::GetMenuItemCommandID(::GetMenuHandle(menuID), menuItem, &command);
+
+ handled = false;
+
+ if (err || command == 0) {
+ }
+ else {
+ switch(command) {
+ }
+ }
+
+ ::HiliteMenu(0);
+ return handled;
+}*/
+
+
+
+#pragma mark Clipboard get/set
+
+GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
+{
+ GHOST_TUns8 * temp_buff;
+ size_t pastedTextSize;
+
+ NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+
+ if (pasteBoard = nil) {
+ return NULL;
+ }
+
+ NSArray *supportedTypes =
+ [NSArray arrayWithObjects: @"public.utf8-plain-text", nil];
+
+ NSString *bestType = [[NSPasteboard generalPasteboard]
+ availableTypeFromArray:supportedTypes];
+
+ if (bestType == nil) { return NULL; }
+
+ NSString * textPasted = [pasteBoard stringForType:@"public.utf8-plain-text"];
+
+ pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1);
+
+ if (temp_buff == NULL) return NULL;
+
+ strncpy((char*)temp_buff, [textPasted UTF8String], pastedTextSize);
+
+ temp_buff[pastedTextSize] = '\0';
+
+ if(temp_buff) {
+ return temp_buff;
+ } else {
+ return NULL;
+ }
+}
+
+void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
+{
+ NSString *textToCopy;
+
+ if(selection) {return;} // for copying the selection, used on X11
+
+
+ NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+
+ if (pasteBoard = nil) {
+ return;
+ }
+
+ NSArray *supportedTypes = [NSArray arrayWithObjects: @"public.utf8-plain-text",nil];
+
+ [pasteBoard declareTypes:supportedTypes owner:nil];
+
+ textToCopy = [NSString stringWithUTF8String:buffer];
+
+ [pasteBoard setString:textToCopy forType:@"public.utf8-plain-text"];
+
+ printf("\nCopy");
+
+}
+
+#pragma mark Carbon stuff to remove
+
+#ifdef WITH_CARBON
+
+
+OSErr GHOST_SystemCarbon::sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+
+ return noErr;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+ AEDescList docs;
+ SInt32 ndocs;
+ OSErr err;
+
+ err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docs);
+ if (err != noErr) return err;
+
+ err = AECountItems(&docs, &ndocs);
+ if (err==noErr) {
+ int i;
+
+ for (i=0; i<ndocs; i++) {
+ FSSpec fss;
+ AEKeyword kwd;
+ DescType actType;
+ Size actSize;
+
+ err = AEGetNthPtr(&docs, i+1, typeFSS, &kwd, &actType, &fss, sizeof(fss), &actSize);
+ if (err!=noErr)
+ break;
+
+ if (i==0) {
+ FSRef fsref;
+
+ if (FSpMakeFSRef(&fss, &fsref)!=noErr)
+ break;
+ if (FSRefMakePath(&fsref, (UInt8*) g_firstFileBuf, sizeof(g_firstFileBuf))!=noErr)
+ break;
+
+ g_hasFirstFile = true;
+ }
+ }
+ }
+
+ AEDisposeDesc(&docs);
+
+ return err;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+
+ return noErr;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+ GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+
+ sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );
+
+ return noErr;
+}
+#endif \ No newline at end of file
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 8513d056795..2e89be40bcb 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -39,7 +39,6 @@
#endif
#include "GHOST_SystemWin32.h"
-//#include <stdio.h> //for printf()
// win64 doesn't define GWL_USERDATA
#ifdef WIN32
@@ -61,6 +60,23 @@
#define WHEEL_DELTA 120 /* Value for rolling one detent, (old convention! MS changed it) */
#endif // WHEEL_DELTA
+/*
+ * Defines for mouse buttons 4 and 5 aka xbutton1 and xbutton2.
+ * MSDN: Declared in Winuser.h, include Windows.h
+ * This does not seem to work with MinGW so we define our own here.
+ */
+#ifndef XBUTTON1
+#define XBUTTON1 0x0001
+#endif // XBUTTON1
+#ifndef XBUTTON2
+#define XBUTTON2 0x0002
+#endif // XBUTTON2
+#ifndef WM_XBUTTONUP
+#define WM_XBUTTONUP 524
+#endif // WM_XBUTTONUP
+#ifndef WM_XBUTTONDOWN
+#define WM_XBUTTONDOWN 523
+#endif // WM_XBUTTONDOWN
#include "GHOST_Debug.h"
#include "GHOST_DisplayManagerWin32.h"
@@ -672,6 +688,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->registerMouseClickEvent(true);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
break;
+ case WM_XBUTTONDOWN:
+ window->registerMouseClickEvent(true);
+ if ((short) HIWORD(wParam) == XBUTTON1){
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
+ }else if((short) HIWORD(wParam) == XBUTTON2){
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5);
+ }
+ break;
case WM_LBUTTONUP:
window->registerMouseClickEvent(false);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
@@ -684,6 +708,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->registerMouseClickEvent(false);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
break;
+ case WM_XBUTTONUP:
+ window->registerMouseClickEvent(false);
+ if ((short) HIWORD(wParam) == XBUTTON1){
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
+ }else if((short) HIWORD(wParam) == XBUTTON2){
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
+ }
+ break;
case WM_MOUSEMOVE:
event = processCursorEvent(GHOST_kEventCursorMove, window);
break;
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 5dba76adb02..cdbdce9c2ca 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -444,10 +444,15 @@ GHOST_SystemX11::processEvent(XEvent *xe)
XButtonEvent & xbe = xe->xbutton;
GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
-
switch (xbe.button) {
case Button1 : gbmask = GHOST_kButtonMaskLeft; break;
case Button3 : gbmask = GHOST_kButtonMaskRight; break;
+ /* It seems events 6 and 7 are for horizontal scrolling.
+ * you can re-order button mapping like this... (swaps 6,7 with 8,9)
+ * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
+ */
+ case 8 : gbmask = GHOST_kButtonMaskButton4; break; /* Button4 is the wheel */
+ case 9 : gbmask = GHOST_kButtonMaskButton5; break; /* Button5 is a wheel too */
default:
case Button2 : gbmask = GHOST_kButtonMaskMiddle; break;
}
@@ -684,12 +689,12 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XProximityNotifyEvent* data = (XProximityNotifyEvent*)xe;
if(data->deviceid == window->GetXTablet().StylusID)
- window->GetXTablet().CommonData.Active= 1;
+ window->GetXTablet().CommonData.Active= GHOST_kTabletModeStylus;
else if(data->deviceid == window->GetXTablet().EraserID)
- window->GetXTablet().CommonData.Active= 2;
+ window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser;
}
else if(xe->type == window->GetXTablet().ProxOutEvent)
- window->GetXTablet().CommonData.Active= 0;
+ window->GetXTablet().CommonData.Active= GHOST_kTabletModeNone;
break;
}
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index dee890830a1..951c3bc381d 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -27,8 +27,6 @@
*/
/**
-
- * $Id$
* Copyright (C) 2001 NaN Technologies B.V.
* @author Maarten Gribnau
* @date May 10, 2001
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
index 87bb86a37e7..362e949a0a4 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.cpp
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -183,7 +183,7 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
updateDrawingContext();
activateDrawingContext();
- m_tablet.Active = 0;
+ m_tablet.Active = GHOST_kTabletModeNone;
}
}
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
new file mode 100644
index 00000000000..146d0ff47de
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -0,0 +1,308 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 GHOST_WindowCocoa.h
+ * Declaration of GHOST_WindowCocoa class.
+ */
+
+#ifndef _GHOST_WINDOW_COCOA_H_
+#define _GHOST_WINDOW_COCOA_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+#include "GHOST_Window.h"
+#include "STR_String.h"
+
+#include <AGL/agl.h>
+
+
+/**
+ * Window on Mac OSX/Cocoa.
+ * Carbon windows have a size widget in the lower right corner of the window.
+ * To force it to be visible, the height of the client rectangle is reduced so
+ * that applications do not draw in that area. GHOST will manage that area
+ * which is called the gutter.
+ * When OpenGL contexts are active, GHOST will use AGL_BUFFER_RECT to prevent
+ * OpenGL drawing outside the reduced client rectangle.
+ * @author Maarten Gribnau
+ * @date May 23, 2001
+ */
+class GHOST_WindowCocoa : public GHOST_Window {
+public:
+ /**
+ * Constructor.
+ * Creates a new window and opens it.
+ * To check if the window was created properly, use the getValid() method.
+ * @param title The text shown in the title bar of the window.
+ * @param left The coordinate of the left edge of the window.
+ * @param top The coordinate of the top edge of the window.
+ * @param width The width the window.
+ * @param height The height the window.
+ * @param state The state the window is initially opened with.
+ * @param type The type of drawing context installed in this window.
+ * @param stereoVisual Stereo visual for quad buffered stereo.
+ */
+ GHOST_WindowCocoa(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false
+ );
+
+ /**
+ * Destructor.
+ * Closes the window and disposes resources allocated.
+ */
+ virtual ~GHOST_WindowCocoa();
+
+ /**
+ * Returns indication as to whether the window is valid.
+ * @return The validity of the window.
+ */
+ virtual bool getValid() const;
+
+ /**
+ * Sets the title displayed in the title bar.
+ * @param title The title to display in the title bar.
+ */
+ virtual void setTitle(const STR_String& title);
+
+ /**
+ * Returns the title displayed in the title bar.
+ * @param title The title displayed in the title bar.
+ */
+ virtual void getTitle(STR_String& title) const;
+
+ /**
+ * Returns the window rectangle dimensions.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * @param bounds The bounding rectangle of the window.
+ */
+ virtual void getWindowBounds(GHOST_Rect& bounds) const;
+
+ /**
+ * Returns the client rectangle dimensions.
+ * The left and top members of the rectangle are always zero.
+ * @param bounds The bounding rectangle of the cleient area of the window.
+ */
+ virtual void getClientBounds(GHOST_Rect& bounds) const;
+
+ /**
+ * Resizes client rectangle width.
+ * @param width The new width of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+ /**
+ * Resizes client rectangle height.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+ /**
+ * Resizes client rectangle.
+ * @param width The new width of the client area of the window.
+ * @param height The new height of the client area of the window.
+ */
+ virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+ /**
+ * Returns the state of the window (normal, minimized, maximized).
+ * @return The state of the window.
+ */
+ virtual GHOST_TWindowState getState() const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate on the screen.
+ * @param inY The y-coordinate on the screen.
+ * @param outX The x-coordinate in the client rectangle.
+ * @param outY The y-coordinate in the client rectangle.
+ */
+ virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+ /**
+ * Converts a point in screen coordinates to client rectangle coordinates
+ * @param inX The x-coordinate in the client rectangle.
+ * @param inY The y-coordinate in the client rectangle.
+ * @param outX The x-coordinate on the screen.
+ * @param outY The y-coordinate on the screen.
+ */
+ virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+ /**
+ * Sets the state of the window (normal, minimized, maximized).
+ * @param state The state of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setState(GHOST_TWindowState state);
+
+ /**
+ * Sets the order of the window (bottom, top).
+ * @param order The order of the window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+ /**
+ * Swaps front and back buffers of a window.
+ * @return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess swapBuffers();
+
+ /**
+ * Updates the drawing context of this window. Needed
+ * whenever the window is changed.
+ * @return Indication of success.
+ */
+ GHOST_TSuccess updateDrawingContext();
+
+ /**
+ * Activates the drawing context of this window.
+ * @return A boolean success indicator.
+ */
+ virtual GHOST_TSuccess activateDrawingContext();
+
+ virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
+
+ /**
+ * Returns the dirty state of the window when in full-screen mode.
+ * @return Whether it is dirty.
+ */
+ virtual bool getFullScreenDirty();
+
+ /* accessor for fullscreen window */
+ virtual void setMac_windowState(short value);
+ virtual short getMac_windowState();
+
+
+ const GHOST_TabletData* GetTabletData()
+ { return &m_tablet; }
+
+ GHOST_TabletData& GetCocoaTabletData()
+ { return m_tablet; }
+protected:
+ /**
+ * Tries to install a rendering context in this window.
+ * @param type The type of rendering context installed.
+ * @return Indication as to whether installation has succeeded.
+ */
+ virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
+
+ /**
+ * Removes the current drawing context.
+ * @return Indication as to whether removal has succeeded.
+ */
+ virtual GHOST_TSuccess removeDrawingContext();
+
+ /**
+ * Invalidates the contents of this window.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess invalidate();
+
+ /**
+ * Sets the cursor visibility on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+ /**
+ * Sets the cursor shape on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+ int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
+
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
+
+ /**
+ * Converts a string object to a Mac Pascal string.
+ * @param in The string object to be converted.
+ * @param out The converted string.
+ */
+ virtual void gen2mac(const STR_String& in, Str255 out) const;
+
+ /**
+ * Converts a Mac Pascal string to a string object.
+ * @param in The string to be converted.
+ * @param out The converted string object.
+ */
+ virtual void mac2gen(const Str255 in, STR_String& out) const;
+
+ WindowRef m_windowRef;
+ CGrafPtr m_grafPtr;
+ AGLContext m_aglCtx;
+
+ /** The first created OpenGL context (for sharing display lists) */
+ static AGLContext s_firstaglCtx;
+
+ Cursor* m_customCursor;
+
+ GHOST_TabletData m_tablet;
+
+ /** When running in full-screen this tells whether to refresh the window. */
+ bool m_fullScreenDirty;
+
+ /** specific MacOs X full screen window setting as we use partially system mechanism
+ values : 0 not maximizable default
+ 1 normal state
+ 2 maximized state
+
+ this will be reworked when rebuilding GHOST carbon to use new OS X apis
+ in order to be unified with GHOST fullscreen/maximised settings
+
+ (lukep)
+ **/
+
+ short mac_windowState;
+
+
+ /**
+ * The width/height of the size rectangle in the lower right corner of a
+ * Mac/Carbon window. This is also the height of the gutter area.
+ */
+#ifdef GHOST_DRAW_CARBON_GUTTER
+ static const GHOST_TInt32 s_sizeRectSize;
+#endif // GHOST_DRAW_CARBON_GUTTER
+};
+
+#endif // _GHOST_WINDOW_COCOA_H_
+
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
new file mode 100644
index 00000000000..53d7fa9b245
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -0,0 +1,745 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+ */
+
+/**
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author Maarten Gribnau
+ * @date May 10, 2001
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Carbon/Carbon.h>
+
+#include "GHOST_WindowCocoa.h"
+#include "GHOST_Debug.h"
+
+AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL;
+#ifdef GHOST_DRAW_CARBON_GUTTER
+const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16;
+#endif //GHOST_DRAW_CARBON_GUTTER
+
+static const GLint sPreferredFormatWindow[8] = {
+AGL_RGBA,
+AGL_DOUBLEBUFFER,
+AGL_ACCELERATED,
+AGL_DEPTH_SIZE, 32,
+AGL_NONE,
+};
+
+static const GLint sPreferredFormatFullScreen[9] = {
+AGL_RGBA,
+AGL_DOUBLEBUFFER,
+AGL_ACCELERATED,
+AGL_FULLSCREEN,
+AGL_DEPTH_SIZE, 32,
+AGL_NONE,
+};
+
+
+
+WindowRef ugly_hack=NULL;
+
+const EventTypeSpec kWEvents[] = {
+ { kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */
+};
+
+static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
+ WindowRef mywindow;
+ GHOST_WindowCocoa *ghost_window;
+ OSStatus err;
+ int theState;
+
+ if (::GetEventKind(event) == kEventWindowZoom) {
+ err = ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow);
+ ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow);
+ theState = ghost_window->getMac_windowState();
+ if (theState == 1)
+ ghost_window->setMac_windowState(2);
+ else if (theState == 2)
+ ghost_window->setMac_windowState(1);
+
+ }
+ return eventNotHandledErr;
+}
+
+GHOST_WindowCocoa::GHOST_WindowCocoa(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual
+) :
+ GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
+ m_windowRef(0),
+ m_grafPtr(0),
+ m_aglCtx(0),
+ m_customCursor(0),
+ m_fullScreenDirty(false)
+{
+ Str255 title255;
+ OSStatus err;
+
+ //fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width);
+
+ if (state >= GHOST_kWindowState8Normal ) {
+ if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal;
+ else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized;
+ else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized;
+ else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen;
+
+ // state = state - 8; this was the simple version of above code, doesnt work in gcc 4.0
+
+ setMac_windowState(1);
+ } else
+ setMac_windowState(0);
+
+ if (state != GHOST_kWindowStateFullScreen) {
+ Rect bnds = { top, left, top+height, left+width };
+ // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/
+ gen2mac(title, title255);
+
+ err = ::CreateNewWindow( kDocumentWindowClass,
+ kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute,
+ &bnds,
+ &m_windowRef);
+
+ if ( err != noErr) {
+ fprintf(stderr," error creating window %i \n",err);
+ } else {
+
+ ::SetWRefCon(m_windowRef,(SInt32)this);
+ setTitle(title);
+ err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL);
+ if ( err != noErr) {
+ fprintf(stderr," error creating handler %i \n",err);
+ } else {
+ // ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
+ ::ShowWindow(m_windowRef);
+ ::MoveWindow (m_windowRef, left, top,true);
+
+ }
+ }
+ if (m_windowRef) {
+ m_grafPtr = ::GetWindowPort(m_windowRef);
+ setDrawingContextType(type);
+ updateDrawingContext();
+ activateDrawingContext();
+ }
+ if(ugly_hack==NULL) {
+ ugly_hack= m_windowRef;
+ // when started from commandline, window remains in the back... also for play anim
+ ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+ SetFrontProcess(&psn);
+ }
+ }
+ else {
+ /*
+ Rect bnds = { top, left, top+height, left+width };
+ gen2mac("", title255);
+ m_windowRef = ::NewCWindow(
+ nil, // Storage
+ &bnds, // Bounding rectangle of the window
+ title255, // Title of the window
+ 0, // Window initially visible
+ plainDBox, // procID
+ (WindowRef)-1L, // Put window before all other windows
+ 0, // Window has minimize box
+ (SInt32)this); // Store a pointer to the class in the refCon
+ */
+ //GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n");
+ setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);;installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
+ updateDrawingContext();
+ activateDrawingContext();
+
+ m_tablet.Active = GHOST_kTabletModeNone;
+ }
+}
+
+
+GHOST_WindowCocoa::~GHOST_WindowCocoa()
+{
+ if (m_customCursor) delete m_customCursor;
+
+ if(ugly_hack==m_windowRef) ugly_hack= NULL;
+
+ // printf("GHOST_WindowCocoa::~GHOST_WindowCocoa(): removing drawing context\n");
+ if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);
+ if (m_windowRef) {
+ ::DisposeWindow(m_windowRef);
+ m_windowRef = 0;
+ }
+}
+
+bool GHOST_WindowCocoa::getValid() const
+{
+ bool valid;
+ if (!m_fullScreen) {
+ valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef);
+ }
+ else {
+ valid = true;
+ }
+ return valid;
+}
+
+
+void GHOST_WindowCocoa::setTitle(const STR_String& title)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
+ Str255 title255;
+ gen2mac(title, title255);
+ ::SetWTitle(m_windowRef, title255);
+}
+
+
+void GHOST_WindowCocoa::getTitle(STR_String& title) const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid")
+ Str255 title255;
+ ::GetWTitle(m_windowRef, title255);
+ mac2gen(title255, title);
+}
+
+
+void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
+{
+ OSStatus success;
+ Rect rect;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
+ success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect);
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
+}
+
+
+void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
+{
+ Rect rect;
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
+ //::GetPortBounds(m_grafPtr, &rect);
+ ::GetWindowBounds(m_windowRef, kWindowContentRgn, &rect);
+
+ bounds.m_b = rect.bottom;
+ bounds.m_l = rect.left;
+ bounds.m_r = rect.right;
+ bounds.m_t = rect.top;
+
+ // Subtract gutter height from bottom
+#ifdef GHOST_DRAW_CARBON_GUTTER
+ if ((bounds.m_b - bounds.m_t) > s_sizeRectSize)
+ {
+ bounds.m_b -= s_sizeRectSize;
+ }
+ else
+ {
+ bounds.m_t = bounds.m_b;
+ }
+#endif //GHOST_DRAW_CARBON_GUTTER
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+ if (((GHOST_TUns32)cBnds.getWidth()) != width) {
+ ::SizeWindow(m_windowRef, width, cBnds.getHeight(), true);
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+#ifdef GHOST_DRAW_CARBON_GUTTER
+ if (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize) {
+ ::SizeWindow(m_windowRef, cBnds.getWidth(), height+s_sizeRectSize, true);
+ }
+#else //GHOST_DRAW_CARBON_GUTTER
+ if (((GHOST_TUns32)cBnds.getHeight()) != height) {
+ ::SizeWindow(m_windowRef, cBnds.getWidth(), height, true);
+ }
+#endif //GHOST_DRAW_CARBON_GUTTER
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
+ GHOST_Rect cBnds, wBnds;
+ getClientBounds(cBnds);
+#ifdef GHOST_DRAW_CARBON_GUTTER
+ if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
+ (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize)) {
+ ::SizeWindow(m_windowRef, width, height+s_sizeRectSize, true);
+ }
+#else //GHOST_DRAW_CARBON_GUTTER
+ if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
+ (((GHOST_TUns32)cBnds.getHeight()) != height)) {
+ ::SizeWindow(m_windowRef, width, height, true);
+ }
+#endif //GHOST_DRAW_CARBON_GUTTER
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TWindowState GHOST_WindowCocoa::getState() const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
+ GHOST_TWindowState state;
+ if (::IsWindowVisible(m_windowRef) == false) {
+ state = GHOST_kWindowStateMinimized;
+ }
+ else if (::IsWindowInStandardState(m_windowRef, nil, nil)) {
+ state = GHOST_kWindowStateMaximized;
+ }
+ else {
+ state = GHOST_kWindowStateNormal;
+ }
+ return state;
+}
+
+
+void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
+ Point point;
+ point.h = inX;
+ point.v = inY;
+ GrafPtr oldPort;
+ ::GetPort(&oldPort);
+ ::SetPort(m_grafPtr);
+ ::GlobalToLocal(&point);
+ ::SetPort(oldPort);
+ outX = point.h;
+ outY = point.v;
+}
+
+
+void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid")
+ Point point;
+ point.h = inX;
+ point.v = inY;
+ GrafPtr oldPort;
+ ::GetPort(&oldPort);
+ ::SetPort(m_grafPtr);
+ ::LocalToGlobal(&point);
+ ::SetPort(oldPort);
+ outX = point.h;
+ outY = point.v;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
+ switch (state) {
+ case GHOST_kWindowStateMinimized:
+ ::HideWindow(m_windowRef);
+ break;
+ case GHOST_kWindowStateModified:
+ SetWindowModified(m_windowRef, 1);
+ break;
+ case GHOST_kWindowStateUnModified:
+ SetWindowModified(m_windowRef, 0);
+ break;
+ case GHOST_kWindowStateMaximized:
+ case GHOST_kWindowStateNormal:
+ default:
+ ::ShowWindow(m_windowRef);
+ break;
+ }
+ return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
+ if (order == GHOST_kWindowOrderTop) {
+ //::BringToFront(m_windowRef); is wrong, front window should be active for input too
+ ::SelectWindow(m_windowRef);
+ }
+ else {
+ /* doesnt work if you do this with a mouseclick */
+ ::SendBehind(m_windowRef, nil);
+ }
+ return GHOST_kSuccess;
+}
+
+/*#define WAIT_FOR_VSYNC 1*/
+#ifdef WAIT_FOR_VSYNC
+#include <OpenGL/OpenGL.h>
+#endif
+
+GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
+{
+#ifdef WAIT_FOR_VSYNC
+/* wait for vsync, to avoid tearing artifacts */
+long VBL = 1;
+CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
+#endif
+
+ GHOST_TSuccess succeeded = GHOST_kSuccess;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_aglCtx) {
+ ::aglSwapBuffers(m_aglCtx);
+ }
+ else {
+ succeeded = GHOST_kFailure;
+ }
+ }
+ return succeeded;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
+{
+ GHOST_TSuccess succeeded = GHOST_kSuccess;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_aglCtx) {
+ ::aglUpdateContext(m_aglCtx);
+ }
+ else {
+ succeeded = GHOST_kFailure;
+ }
+ }
+ return succeeded;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
+{
+ GHOST_TSuccess succeeded = GHOST_kSuccess;
+ if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+ if (m_aglCtx) {
+ ::aglSetCurrentContext(m_aglCtx);
+#ifdef GHOST_DRAW_CARBON_GUTTER
+ // Restrict drawing to non-gutter area
+ ::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
+ GHOST_Rect bnds;
+ getClientBounds(bnds);
+ GLint b[4] =
+ {
+ bnds.m_l,
+ bnds.m_t+s_sizeRectSize,
+ bnds.m_r-bnds.m_l,
+ bnds.m_b-bnds.m_t
+ };
+ GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
+#endif //GHOST_DRAW_CARBON_GUTTER
+ }
+ else {
+ succeeded = GHOST_kFailure;
+ }
+ }
+ return succeeded;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ switch (type) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ {
+ if (!getValid()) break;
+
+ AGLPixelFormat pixelFormat;
+ if (!m_fullScreen) {
+ pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
+ m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx);
+ if (!m_aglCtx) break;
+ if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
+ success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ }
+ else {
+ //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n");
+GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen);
+ m_aglCtx = ::aglCreateContext(pixelFormat, 0);
+ if (!m_aglCtx) break;
+ if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
+ //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n");
+ //::CGGetActiveDisplayList(0, NULL, &m_numDisplays)
+ success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ /*
+ if (success == GHOST_kSuccess) {
+ GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n");
+ }
+ else {
+ GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n");
+ }
+ */
+ }
+ ::aglDestroyPixelFormat(pixelFormat);
+ }
+ break;
+
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+
+ default:
+ break;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
+{
+ GHOST_TSuccess success = GHOST_kFailure;
+ switch (m_drawingContextType) {
+ case GHOST_kDrawingContextTypeOpenGL:
+ if (m_aglCtx) {
+ aglSetCurrentContext(NULL);
+ aglSetDrawable(m_aglCtx, NULL);
+ //aglDestroyContext(m_aglCtx);
+ if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL;
+ success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+ m_aglCtx = 0;
+ }
+ break;
+ case GHOST_kDrawingContextTypeNone:
+ success = GHOST_kSuccess;
+ break;
+ default:
+ break;
+ }
+ return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::invalidate()
+{
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
+ if (!m_fullScreen) {
+ Rect rect;
+ ::GetPortBounds(m_grafPtr, &rect);
+ ::InvalWindowRect(m_windowRef, &rect);
+ }
+ else {
+ //EventRef event;
+ //OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event);
+ //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n");
+ //status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this);
+ //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n");
+ //status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard);
+ //status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget());
+ //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n");
+ m_fullScreenDirty = true;
+ }
+ return GHOST_kSuccess;
+}
+
+
+void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const
+{
+ STR_String tempStr = in;
+ int num = tempStr.Length();
+ if (num > 255) num = 255;
+ ::memcpy(out+1, tempStr.Ptr(), num);
+ out[0] = num;
+}
+
+
+void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const
+{
+ char tmp[256];
+ ::memcpy(tmp, in+1, in[0]);
+ tmp[in[0]] = '\0';
+ out = tmp;
+}
+
+void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
+{
+ static bool systemCursorVisible = true;
+
+ if (visible != systemCursorVisible) {
+ if (visible) {
+ ::ShowCursor();
+ systemCursorVisible = true;
+ }
+ else {
+ ::HideCursor();
+ systemCursorVisible = false;
+ }
+ }
+
+ if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
+ ::SetCursor( m_customCursor );
+ } else {
+ int carbon_cursor;
+
+#define GCMAP(ghostCursor, carbonCursor) case ghostCursor: carbon_cursor = carbonCursor; break
+ switch (cursor) {
+ default:
+ GCMAP( GHOST_kStandardCursorDefault, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorRightArrow, kThemeAliasArrowCursor);
+ GCMAP( GHOST_kStandardCursorLeftArrow, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorInfo, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorDestroy, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorHelp, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorCycle, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorSpray, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorWait, kThemeWatchCursor);
+ GCMAP( GHOST_kStandardCursorText, kThemeIBeamCursor);
+ GCMAP( GHOST_kStandardCursorCrosshair, kThemeCrossCursor);
+ GCMAP( GHOST_kStandardCursorUpDown, kThemeClosedHandCursor);
+ GCMAP( GHOST_kStandardCursorLeftRight, kThemeClosedHandCursor);
+ GCMAP( GHOST_kStandardCursorTopSide, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorBottomSide, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorLeftSide, kThemeResizeLeftCursor);
+ GCMAP( GHOST_kStandardCursorRightSide, kThemeResizeRightCursor);
+ GCMAP( GHOST_kStandardCursorTopLeftCorner, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorTopRightCorner, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorBottomRightCorner, kThemeArrowCursor);
+ GCMAP( GHOST_kStandardCursorBottomLeftCorner, kThemeArrowCursor);
+ };
+#undef GCMAP
+
+ ::SetThemeCursor(carbon_cursor);
+ }
+}
+
+
+bool GHOST_WindowCocoa::getFullScreenDirty()
+{
+ return m_fullScreen && m_fullScreenDirty;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
+{
+ if (::FrontWindow() == m_windowRef) {
+ loadCursor(visible, getCursorShape());
+ }
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
+{
+ if (m_customCursor) {
+ delete m_customCursor;
+ m_customCursor = 0;
+ }
+
+ if (::FrontWindow() == m_windowRef) {
+ loadCursor(getCursorVisibility(), shape);
+ }
+
+ return GHOST_kSuccess;
+}
+
+#if 0
+/** Reverse the bits in a GHOST_TUns8 */
+static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
+{
+ ch= ((ch>>1)&0x55) | ((ch<<1)&0xAA);
+ ch= ((ch>>2)&0x33) | ((ch<<2)&0xCC);
+ ch= ((ch>>4)&0x0F) | ((ch<<4)&0xF0);
+ return ch;
+}
+#endif
+
+
+/** Reverse the bits in a GHOST_TUns16 */
+static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
+{
+ shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
+ shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
+ shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
+ shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
+ return shrt;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+ int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
+{
+ int y;
+
+ if (m_customCursor) {
+ delete m_customCursor;
+ m_customCursor = 0;
+ }
+
+ m_customCursor = new Cursor;
+ if (!m_customCursor) return GHOST_kFailure;
+
+ for (y=0; y<16; y++) {
+#if !defined(__LITTLE_ENDIAN__)
+ m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
+ m_customCursor->mask[y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
+#else
+ m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
+ m_customCursor->mask[y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
+#endif
+
+ }
+
+ m_customCursor->hotSpot.h = hotX;
+ m_customCursor->hotSpot.v = hotY;
+
+ if (::FrontWindow() == m_windowRef) {
+ loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
+ }
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2], int hotX, int hotY)
+{
+ return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
+}
+
+
+void GHOST_WindowCocoa::setMac_windowState(short value)
+{
+ mac_windowState = value;
+}
+
+short GHOST_WindowCocoa::getMac_windowState()
+{
+ return mac_windowState;
+}
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 366adb3ab86..e2caf31edee 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -244,7 +244,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
m_tablet = fpWTOpen( m_hWnd, &lc, TRUE );
if (m_tablet) {
m_tabletData = new GHOST_TabletData();
- m_tabletData->Active = 0;
+ m_tabletData->Active = GHOST_kTabletModeNone;
}
}
}
@@ -704,7 +704,7 @@ void GHOST_WindowWin32::processWin32TabletInitEvent()
}
}
- m_tabletData->Active = 0;
+ m_tabletData->Active = GHOST_kTabletModeNone;
}
}
}
@@ -720,15 +720,15 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
switch (pkt.pkCursor) {
case 0: /* first device */
case 3: /* second device */
- m_tabletData->Active = 0; /* puck - not yet supported */
+ m_tabletData->Active = GHOST_kTabletModeNone; /* puck - not yet supported */
break;
case 1:
case 4:
- m_tabletData->Active = 1; /* stylus */
+ m_tabletData->Active = GHOST_kTabletModeStylus; /* stylus */
break;
case 2:
case 5:
- m_tabletData->Active = 2; /* eraser */
+ m_tabletData->Active = GHOST_kTabletModeEraser; /* eraser */
break;
}
if (m_maxPressure > 0) {
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 88ae8afd0ce..060e9ca6f6c 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -294,7 +294,7 @@ GHOST_WindowX11(
}
// Create some hints for the window manager on how
- // we want this window treated.
+ // we want this window treated.
XSizeHints * xsizehints = XAllocSizeHints();
xsizehints->flags = USPosition | USSize;
@@ -414,6 +414,100 @@ static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) {
return 0 ;
}
+/* These C functions are copied from Wine 1.1.13's wintab.c */
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+static bool match_token(const char *haystack, const char *needle)
+{
+ const char *p, *q;
+ for (p = haystack; *p; )
+ {
+ while (*p && isspace(*p))
+ p++;
+ if (! *p)
+ break;
+
+ for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
+ p++;
+ if (! *q && (isspace(*p) || !*p))
+ return TRUE;
+
+ while (*p && ! isspace(*p))
+ p++;
+ }
+ return FALSE;
+}
+
+/* Determining if an X device is a Tablet style device is an imperfect science.
+** We rely on common conventions around device names as well as the type reported
+** by Wacom tablets. This code will likely need to be expanded for alternate tablet types
+**
+** Wintab refers to any device that interacts with the tablet as a cursor,
+** (stylus, eraser, tablet mouse, airbrush, etc)
+** this is not to be confused with wacom x11 configuration "cursor" device.
+** Wacoms x11 config "cursor" refers to its device slot (which we mirror with
+** our gSysCursors) for puck like devices (tablet mice essentially).
+*/
+#if 0 // unused
+static BOOL is_tablet_cursor(const char *name, const char *type)
+{
+ int i;
+ static const char *tablet_cursor_whitelist[] = {
+ "wacom",
+ "wizardpen",
+ "acecad",
+ "tablet",
+ "cursor",
+ "stylus",
+ "eraser",
+ "pad",
+ NULL
+ };
+
+ for (i=0; tablet_cursor_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_cursor_whitelist[i]))
+ return TRUE;
+ if (type && match_token(type, tablet_cursor_whitelist[i]))
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+static BOOL is_stylus(const char *name, const char *type)
+{
+ int i;
+ static const char* tablet_stylus_whitelist[] = {
+ "stylus",
+ "wizardpen",
+ "acecad",
+ NULL
+ };
+
+ for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_stylus_whitelist[i]))
+ return TRUE;
+ if (type && match_token(type, tablet_stylus_whitelist[i]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL is_eraser(const char *name, const char *type)
+{
+ if (name && match_token(name, "eraser"))
+ return TRUE;
+ if (type && match_token(type, "eraser"))
+ return TRUE;
+ return FALSE;
+}
+#undef BOOL
+#undef TRUE
+#undef FALSE
+/* end code copied from wine */
+
void GHOST_WindowX11::initXInputDevices()
{
static XErrorHandler old_handler = (XErrorHandler) 0 ;
@@ -423,28 +517,21 @@ void GHOST_WindowX11::initXInputDevices()
if(version->present) {
int device_count;
XDeviceInfo* device_info = XListInputDevices(m_display, &device_count);
- m_xtablet.StylusDevice = 0;
- m_xtablet.EraserDevice = 0;
- m_xtablet.CommonData.Active= 0;
+ m_xtablet.StylusDevice = NULL;
+ m_xtablet.EraserDevice = NULL;
+ m_xtablet.CommonData.Active= GHOST_kTabletModeNone;
/* Install our error handler to override Xlib's termination behavior */
old_handler = XSetErrorHandler(ApplicationErrorHandler) ;
for(int i=0; i<device_count; ++i) {
- std::string type = "";
+ char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
- if(device_info[i].type) {
- const char *orig = XGetAtomName(m_display, device_info[i].type);
- // Make a copy so we can convert to lower case
- if(orig) {
- type = orig;
- XFree((void*)orig);
- std::transform(type.begin(), type.end(), type.begin(), ::tolower);
- }
- }
+// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
- if(type.find("stylus") != std::string::npos) {
+ if(m_xtablet.StylusDevice==NULL && is_stylus(device_info[i].name, device_type)) {
+// printf("\tfound stylus\n");
m_xtablet.StylusID= device_info[i].id;
m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
@@ -453,6 +540,7 @@ void GHOST_WindowX11::initXInputDevices()
XAnyClassPtr ici = device_info[i].inputclassinfo;
for(int j=0; j<m_xtablet.StylusDevice->num_classes; ++j) {
if(ici->c_class==ValuatorClass) {
+// printf("\t\tfound ValuatorClass\n");
XValuatorInfo* xvi = (XValuatorInfo*)ici;
m_xtablet.PressureLevels = xvi->axes[2].max_value;
@@ -469,11 +557,16 @@ void GHOST_WindowX11::initXInputDevices()
m_xtablet.StylusID= 0;
}
}
- if(type.find("eraser") != std::string::npos) {
+ else if(m_xtablet.EraserDevice==NULL && is_eraser(device_info[i].name, device_type)) {
+// printf("\tfound eraser\n");
m_xtablet.EraserID= device_info[i].id;
m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID= 0;
}
+
+ if(device_type) {
+ XFree((void*)device_type);
+ }
}
/* Restore handler */
@@ -514,7 +607,7 @@ GHOST_WindowX11::
getXWindow(
){
return m_window;
-}
+}
bool
GHOST_WindowX11::
@@ -528,7 +621,17 @@ GHOST_WindowX11::
setTitle(
const STR_String& title
){
+ Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
+ Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
+ XChangeProperty(m_display, m_window,
+ name, utf8str, 8, PropModeReplace,
+ (const unsigned char*) title.ReadPtr(),
+ strlen(title.ReadPtr()));
+
+// This should convert to valid x11 string
+// and getTitle would need matching change
XStoreName(m_display,m_window,title);
+
XFlush(m_display);
}
@@ -1115,6 +1218,13 @@ GHOST_WindowX11::
XFreeCursor(m_display, m_custom_cursor);
}
+ /* close tablet devices */
+ if(m_xtablet.StylusDevice)
+ XCloseDevice(m_display, m_xtablet.StylusDevice);
+
+ if(m_xtablet.EraserDevice)
+ XCloseDevice(m_display, m_xtablet.EraserDevice);
+
if (m_context) {
if (m_context == s_firstContext) {
s_firstContext = NULL;
diff --git a/intern/ghost/make/msvc_9_0/ghost.vcproj b/intern/ghost/make/msvc_9_0/ghost.vcproj
index fa128786a90..6b3a49cfc9c 100644
--- a/intern/ghost/make/msvc_9_0/ghost.vcproj
+++ b/intern/ghost/make/msvc_9_0/ghost.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\wintab\INCLUDE"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 1d4c753802b..9e3927314d3 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -27,8 +27,6 @@
*/
/**
-
- * $Id$
* Copyright (C) 2001 NaN Technologies B.V.
* Guarded memory (de)allocation
*
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 3b5f6a0caf9..ca7f2a4d506 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -688,17 +688,35 @@ static const char *check_memlist(MemHead *memh)
uintptr_t MEM_get_memory_in_use(void)
{
- return mem_in_use;
+ uintptr_t _mem_in_use;
+
+ mem_lock_thread();
+ _mem_in_use= mem_in_use;
+ mem_unlock_thread();
+
+ return _mem_in_use;
}
uintptr_t MEM_get_mapped_memory_in_use(void)
{
- return mmap_in_use;
+ uintptr_t _mmap_in_use;
+
+ mem_lock_thread();
+ _mmap_in_use= mmap_in_use;
+ mem_unlock_thread();
+
+ return _mmap_in_use;
}
int MEM_get_memory_blocks_in_use(void)
{
- return totblock;
+ int _totblock;
+
+ mem_lock_thread();
+ _totblock= totblock;
+ mem_unlock_thread();
+
+ return _totblock;
}
/* eof */
diff --git a/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj b/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj
index d59b80f7b62..16deb7b71fa 100644
--- a/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj
+++ b/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\.."
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/iksolver/make/msvc_9_0/iksolver.vcproj b/intern/iksolver/make/msvc_9_0/iksolver.vcproj
index 0e87556380b..296a23e57cc 100644
--- a/intern/iksolver/make/msvc_9_0/iksolver.vcproj
+++ b/intern/iksolver/make/msvc_9_0/iksolver.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp
new file mode 100644
index 00000000000..7776b6aa3b6
--- /dev/null
+++ b/intern/itasc/Armature.cpp
@@ -0,0 +1,775 @@
+/* $Id$
+ * Armature.cpp
+ *
+ * Created on: Feb 3, 2009
+ * Author: benoitbolsee
+ */
+
+#include "Armature.hpp"
+#include <algorithm>
+#include <string.h>
+#include <stdlib.h>
+
+namespace iTaSC {
+
+// a joint constraint is characterized by 5 values: tolerance, K, alpha, yd, yddot
+static const unsigned int constraintCacheSize = 5;
+std::string Armature::m_root = "root";
+
+Armature::Armature():
+ ControlledObject(),
+ m_tree(),
+ m_njoint(0),
+ m_nconstraint(0),
+ m_noutput(0),
+ m_neffector(0),
+ m_finalized(false),
+ m_cache(NULL),
+ m_buf(NULL),
+ m_qCCh(-1),
+ m_qCTs(0),
+ m_yCCh(-1),
+ m_yCTs(0),
+ m_qKdl(),
+ m_oldqKdl(),
+ m_newqKdl(),
+ m_qdotKdl(),
+ m_jac(NULL),
+ m_armlength(0.0),
+ m_jacsolver(NULL),
+ m_fksolver(NULL)
+{
+}
+
+Armature::~Armature()
+{
+ if (m_jac)
+ delete m_jac;
+ if (m_jacsolver)
+ delete m_jacsolver;
+ if (m_fksolver)
+ delete m_fksolver;
+ for (JointConstraintList::iterator it=m_constraints.begin(); it != m_constraints.end(); it++) {
+ if (*it != NULL)
+ delete (*it);
+ }
+ if (m_buf)
+ delete [] m_buf;
+ m_constraints.clear();
+}
+
+Armature::JointConstraint_struct::JointConstraint_struct(SegmentMap::const_iterator _segment, unsigned int _y_nr, ConstraintCallback _function, void* _param, bool _freeParam, bool _substep):
+ segment(_segment), value(), values(), function(_function), y_nr(_y_nr), param(_param), freeParam(_freeParam), substep(_substep)
+{
+ memset(values, 0, sizeof(values));
+ memset(value, 0, sizeof(value));
+ values[0].feedback = 20.0;
+ values[1].feedback = 20.0;
+ values[2].feedback = 20.0;
+ values[0].tolerance = 1.0;
+ values[1].tolerance = 1.0;
+ values[2].tolerance = 1.0;
+ values[0].values = &value[0];
+ values[1].values = &value[1];
+ values[2].values = &value[2];
+ values[0].number = 1;
+ values[1].number = 1;
+ values[2].number = 1;
+ switch (segment->second.segment.getJoint().getType()) {
+ case Joint::RotX:
+ value[0].id = ID_JOINT_RX;
+ values[0].id = ID_JOINT_RX;
+ v_nr = 1;
+ break;
+ case Joint::RotY:
+ value[0].id = ID_JOINT_RY;
+ values[0].id = ID_JOINT_RY;
+ v_nr = 1;
+ break;
+ case Joint::RotZ:
+ value[0].id = ID_JOINT_RZ;
+ values[0].id = ID_JOINT_RZ;
+ v_nr = 1;
+ break;
+ case Joint::TransX:
+ value[0].id = ID_JOINT_TX;
+ values[0].id = ID_JOINT_TX;
+ v_nr = 1;
+ break;
+ case Joint::TransY:
+ value[0].id = ID_JOINT_TY;
+ values[0].id = ID_JOINT_TY;
+ v_nr = 1;
+ break;
+ case Joint::TransZ:
+ value[0].id = ID_JOINT_TZ;
+ values[0].id = ID_JOINT_TZ;
+ v_nr = 1;
+ break;
+ case Joint::Sphere:
+ values[0].id = value[0].id = ID_JOINT_RX;
+ values[1].id = value[1].id = ID_JOINT_RY;
+ values[2].id = value[2].id = ID_JOINT_RZ;
+ v_nr = 3;
+ break;
+ case Joint::Swing:
+ values[0].id = value[0].id = ID_JOINT_RX;
+ values[1].id = value[1].id = ID_JOINT_RZ;
+ v_nr = 2;
+ break;
+ case Joint::None:
+ break;
+ }
+}
+
+Armature::JointConstraint_struct::~JointConstraint_struct()
+{
+ if (freeParam && param)
+ free(param);
+}
+
+void Armature::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_qCCh = -1;
+ m_yCCh = -1;
+ m_buf = NULL;
+ if (m_cache) {
+ // add a special channel for the joint
+ m_qCCh = m_cache->addChannel(this, "q", m_qKdl.rows()*sizeof(double));
+#if 0
+ // for the constraints, instead of creating many different channels, we will
+ // create a single channel for all the constraints
+ if (m_nconstraint) {
+ m_yCCh = m_cache->addChannel(this, "y", m_nconstraint*constraintCacheSize*sizeof(double));
+ m_buf = new double[m_nconstraint*constraintCacheSize];
+ }
+ // store the initial cache position at timestamp 0
+ pushConstraints(0);
+#endif
+ pushQ(0);
+ }
+}
+
+void Armature::pushQ(CacheTS timestamp)
+{
+ if (m_qCCh >= 0) {
+ // try to keep the cache if the joints are the same
+ m_cache->addCacheVectorIfDifferent(this, m_qCCh, timestamp, &m_qKdl(0), m_qKdl.rows(), KDL::epsilon);
+ m_qCTs = timestamp;
+ }
+}
+
+/* return true if a m_cache position was loaded */
+bool Armature::popQ(CacheTS timestamp)
+{
+ if (m_qCCh >= 0) {
+ double* item;
+ item = (double*)m_cache->getPreviousCacheItem(this, m_qCCh, &timestamp);
+ if (item && m_qCTs != timestamp) {
+ double& q = m_qKdl(0);
+ memcpy(&q, item, m_qKdl.rows()*sizeof(q));
+ m_qCTs = timestamp;
+ // changing the joint => recompute the jacobian
+ updateJacobian();
+ }
+ return (item) ? true : false;
+ }
+ return true;
+}
+#if 0
+void Armature::pushConstraints(CacheTS timestamp)
+{
+ if (m_yCCh >= 0) {
+ double *buf = NULL;
+ if (m_nconstraint) {
+ double *item = m_buf;
+ for (unsigned int i=0; i<m_nconstraint; i++) {
+ JointConstraint_struct* pConstraint = m_constraints[i];
+ *item++ = pConstraint->values.feedback;
+ *item++ = pConstraint->values.tolerance;
+ *item++ = pConstraint->value.yd;
+ *item++ = pConstraint->value.yddot;
+ *item++ = pConstraint->values.alpha;
+ }
+ }
+ m_cache->addCacheVectorIfDifferent(this, m_yCCh, timestamp, m_buf, m_nconstraint*constraintCacheSize, KDL::epsilon);
+ m_yCTs = timestamp;
+ }
+}
+
+/* return true if a cache position was loaded */
+bool Armature::popConstraints(CacheTS timestamp)
+{
+ if (m_yCCh >= 0) {
+ double *item = (double*)m_cache->getPreviousCacheItem(this, m_yCCh, &timestamp);
+ if (item && m_yCTs != timestamp) {
+ for (unsigned int i=0; i<m_nconstraint; i++) {
+ JointConstraint_struct* pConstraint = m_constraints[i];
+ if (pConstraint->function != Joint1DOFLimitCallback) {
+ pConstraint->values.feedback = *item++;
+ pConstraint->values.tolerance = *item++;
+ pConstraint->value.yd = *item++;
+ pConstraint->value.yddot = *item++;
+ pConstraint->values.alpha = *item++;
+ } else {
+ item += constraintCacheSize;
+ }
+ }
+ m_yCTs = timestamp;
+ }
+ return (item) ? true : false;
+ }
+ return true;
+}
+#endif
+
+bool Armature::addSegment(const std::string& segment_name, const std::string& hook_name, const Joint& joint, const double& q_rest, const Frame& f_tip, const Inertia& M)
+{
+ if (m_finalized)
+ return false;
+
+ Segment segment(joint, f_tip, M);
+ if (!m_tree.addSegment(segment, segment_name, hook_name))
+ return false;
+ int ndof = joint.getNDof();
+ for (int dof=0; dof<ndof; dof++) {
+ Joint_struct js(joint.getType(), ndof, (&q_rest)[dof]);
+ m_joints.push_back(js);
+ }
+ m_njoint+=ndof;
+ return true;
+}
+
+bool Armature::getSegment(const std::string& name, const unsigned int q_size, const Joint* &p_joint, double &q_rest, double &q, const Frame* &p_tip)
+{
+ SegmentMap::const_iterator sit = m_tree.getSegment(name);
+ if (sit == m_tree.getSegments().end())
+ return false;
+ p_joint = &sit->second.segment.getJoint();
+ if (q_size < p_joint->getNDof())
+ return false;
+ p_tip = &sit->second.segment.getFrameToTip();
+ for (unsigned int dof=0; dof<p_joint->getNDof(); dof++) {
+ (&q_rest)[dof] = m_joints[sit->second.q_nr+dof].rest;
+ (&q)[dof] = m_qKdl(sit->second.q_nr+dof);
+ }
+ return true;
+}
+
+double Armature::getMaxJointChange()
+{
+ if (!m_finalized)
+ return 0.0;
+ double maxJoint = 0.0;
+ for (unsigned int i=0; i<m_njoint; i++) {
+ // this is a very rough calculation, it doesn't work well for spherical joint
+ double joint = fabs(m_oldqKdl(i)-m_qKdl(i));
+ if (maxJoint < joint)
+ maxJoint = joint;
+ }
+ return maxJoint;
+}
+
+double Armature::getMaxEndEffectorChange()
+{
+ if (!m_finalized)
+ return 0.0;
+ double maxDelta = 0.0;
+ double delta;
+ Twist twist;
+ for (unsigned int i = 0; i<m_neffector; i++) {
+ twist = diff(m_effectors[i].pose, m_effectors[i].oldpose);
+ delta = twist.rot.Norm();
+ if (delta > maxDelta)
+ maxDelta = delta;
+ delta = twist.vel.Norm();
+ if (delta > maxDelta)
+ maxDelta = delta;
+ }
+ return maxDelta;
+}
+
+int Armature::addConstraint(const std::string& segment_name, ConstraintCallback _function, void* _param, bool _freeParam, bool _substep)
+{
+ SegmentMap::const_iterator segment_it = m_tree.getSegment(segment_name);
+ // not suitable for NDof joints
+ if (segment_it == m_tree.getSegments().end()) {
+ if (_freeParam && _param)
+ free(_param);
+ return -1;
+ }
+ JointConstraintList::iterator constraint_it;
+ JointConstraint_struct* pConstraint;
+ int iConstraint;
+ for (iConstraint=0, constraint_it=m_constraints.begin(); constraint_it != m_constraints.end(); constraint_it++, iConstraint++) {
+ pConstraint = *constraint_it;
+ if (pConstraint->segment == segment_it) {
+ // redefining a constraint
+ if (pConstraint->freeParam && pConstraint->param) {
+ free(pConstraint->param);
+ }
+ pConstraint->function = _function;
+ pConstraint->param = _param;
+ pConstraint->freeParam = _freeParam;
+ pConstraint->substep = _substep;
+ return iConstraint;
+ }
+ }
+ if (m_finalized) {
+ if (_freeParam && _param)
+ free(_param);
+ return -1;
+ }
+ // new constraint, append
+ pConstraint = new JointConstraint_struct(segment_it, m_noutput, _function, _param, _freeParam, _substep);
+ m_constraints.push_back(pConstraint);
+ m_noutput += pConstraint->v_nr;
+ return m_nconstraint++;
+}
+
+int Armature::addLimitConstraint(const std::string& segment_name, unsigned int dof, double _min, double _max)
+{
+ SegmentMap::const_iterator segment_it = m_tree.getSegment(segment_name);
+ if (segment_it == m_tree.getSegments().end())
+ return -1;
+ const Joint& joint = segment_it->second.segment.getJoint();
+ if (joint.getNDof() != 1 && joint.getType() != Joint::Swing) {
+ // not suitable for Sphere joints
+ return -1;
+ }
+ if ((joint.getNDof() == 1 && dof > 0) || (joint.getNDof() == 2 && dof > 1))
+ return -1;
+ if (joint.getType() < Joint::TransX || joint.getType() == Joint::Swing) {
+ // for rotation joint, the limit is given in degree, convert to radian
+ _min *= KDL::deg2rad;
+ _max *= KDL::deg2rad;
+ }
+ Joint_struct& p_joint = m_joints[segment_it->second.q_nr+dof];
+ p_joint.min = _min;
+ p_joint.max = _max;
+ p_joint.useLimit = true;
+ return 0;
+}
+
+int Armature::addEndEffector(const std::string& name)
+{
+ const SegmentMap& segments = m_tree.getSegments();
+ if (segments.find(name) == segments.end())
+ return -1;
+
+ EffectorList::const_iterator it;
+ int ee;
+ for (it=m_effectors.begin(), ee=0; it!=m_effectors.end(); it++, ee++) {
+ if (it->name == name)
+ return ee;
+ }
+ if (m_finalized)
+ return -1;
+ Effector_struct effector(name);
+ m_effectors.push_back(effector);
+ return m_neffector++;
+}
+
+void Armature::finalize()
+{
+ unsigned int i, j, c;
+ if (m_finalized)
+ return;
+ initialize(m_njoint, m_noutput, m_neffector);
+ for (i=c=0; i<m_nconstraint; i++) {
+ JointConstraint_struct* pConstraint = m_constraints[i];
+ for (j=0; j<pConstraint->v_nr; j++, c++) {
+ m_Cq(c,pConstraint->segment->second.q_nr+j) = 1.0;
+ m_Wy(c) = pConstraint->values[j].alpha/*/(pConstraint->values.tolerance*pConstraint->values.feedback)*/;
+ }
+ }
+ m_jacsolver= new KDL::TreeJntToJacSolver(m_tree);
+ m_fksolver = new KDL::TreeFkSolverPos_recursive(m_tree);
+ m_jac = new Jacobian(m_njoint);
+ m_qKdl.resize(m_njoint);
+ m_oldqKdl.resize(m_njoint);
+ m_newqKdl.resize(m_njoint);
+ m_qdotKdl.resize(m_njoint);
+ for (i=0; i<m_njoint; i++) {
+ m_newqKdl(i) = m_oldqKdl(i) = m_qKdl(i) = m_joints[i].rest;
+ }
+ updateJacobian();
+ // estimate the maximum size of the robot arms
+ double length;
+ m_armlength = 0.0;
+ for (i=0; i<m_neffector; i++) {
+ length = 0.0;
+ KDL::SegmentMap::const_iterator sit = m_tree.getSegment(m_effectors[i].name);
+ while (sit->first != "root") {
+ Frame tip = sit->second.segment.pose(m_qKdl(sit->second.q_nr));
+ length += tip.p.Norm();
+ sit = sit->second.parent;
+ }
+ if (length > m_armlength)
+ m_armlength = length;
+ }
+ if (m_armlength < KDL::epsilon)
+ m_armlength = KDL::epsilon;
+ m_finalized = true;
+}
+
+void Armature::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache) {
+ pushQ(timestamp.cacheTimestamp);
+ //pushConstraints(timestamp.cacheTimestamp);
+ }
+}
+
+bool Armature::setJointArray(const KDL::JntArray& joints)
+{
+ if (!m_finalized)
+ return false;
+ if (joints.rows() != m_qKdl.rows())
+ return false;
+ m_qKdl = joints;
+ updateJacobian();
+ return true;
+}
+
+const KDL::JntArray& Armature::getJointArray()
+{
+ return m_qKdl;
+}
+
+bool Armature::updateJoint(const Timestamp& timestamp, JointLockCallback& callback)
+{
+ if (!m_finalized)
+ return false;
+
+ // integration and joint limit
+ // for spherical joint we must use a more sophisticated method
+ unsigned int q_nr;
+ double* qdot=&m_qdotKdl(0);
+ double* q=&m_qKdl(0);
+ double* newq=&m_newqKdl(0);
+ double norm, qx, qz, CX, CZ, sx, sz;
+ bool locked = false;
+ int unlocked = 0;
+
+ for (q_nr=0; q_nr<m_nq; ++q_nr)
+ m_qdotKdl(q_nr)=m_qdot(q_nr);
+
+ for (q_nr=0; q_nr<m_nq; ) {
+ Joint_struct* joint = &m_joints[q_nr];
+ if (!joint->locked) {
+ switch (joint->type) {
+ case KDL::Joint::Swing:
+ {
+ KDL::Rotation base = KDL::Rot(KDL::Vector(q[0],0.0,q[1]));
+ (base*KDL::Rot(KDL::Vector(qdot[0],0.0,qdot[1])*timestamp.realTimestep)).GetXZRot().GetValue(newq);
+ if (joint[0].useLimit) {
+ if (joint[1].useLimit) {
+ // elliptical limit
+ sx = sz = 1.0;
+ qx = newq[0];
+ qz = newq[1];
+ // determine in which quadrant we are
+ if (qx > 0.0 && qz > 0.0) {
+ CX = joint[0].max;
+ CZ = joint[1].max;
+ } else if (qx <= 0.0 && qz > 0.0) {
+ CX = -joint[0].min;
+ CZ = joint[1].max;
+ qx = -qx;
+ sx = -1.0;
+ } else if (qx <= 0.0 && qz <= 0.0) {
+ CX = -joint[0].min;
+ CZ = -joint[1].min;
+ qx = -qx;
+ qz = -qz;
+ sx = sz = -1.0;
+ } else {
+ CX = joint[0].max;
+ CZ = -joint[0].min;
+ qz = -qz;
+ sz = -1.0;
+ }
+ if (CX < KDL::epsilon || CZ < KDL::epsilon) {
+ // quadrant is degenerated
+ if (qx > CX) {
+ newq[0] = CX*sx;
+ joint[0].locked = true;
+ }
+ if (qz > CZ) {
+ newq[1] = CZ*sz;
+ joint[0].locked = true;
+ }
+ } else {
+ // general case
+ qx /= CX;
+ qz /= CZ;
+ norm = KDL::sqrt(KDL::sqr(qx)+KDL::sqr(qz));
+ if (norm > 1.0) {
+ norm = 1.0/norm;
+ newq[0] = qx*norm*CX*sx;
+ newq[1] = qz*norm*CZ*sz;
+ joint[0].locked = true;
+ }
+ }
+ } else {
+ // limit on X only
+ qx = newq[0];
+ if (qx > joint[0].max) {
+ newq[0] = joint[0].max;
+ joint[0].locked = true;
+ } else if (qx < joint[0].min) {
+ newq[0] = joint[0].min;
+ joint[0].locked = true;
+ }
+ }
+ } else if (joint[1].useLimit) {
+ // limit on Z only
+ qz = newq[1];
+ if (qz > joint[1].max) {
+ newq[1] = joint[1].max;
+ joint[0].locked = true;
+ } else if (qz < joint[1].min) {
+ newq[1] = joint[1].min;
+ joint[0].locked = true;
+ }
+ }
+ if (joint[0].locked) {
+ // check the difference from previous position
+ locked = true;
+ norm = KDL::sqr(newq[0]-q[0])+KDL::sqr(newq[1]-q[1]);
+ if (norm < KDL::epsilon2) {
+ // joint didn't move, no need to update the jacobian
+ callback.lockJoint(q_nr, 2);
+ } else {
+ // joint moved, compute the corresponding velocity
+ double deltaq[2];
+ (base.Inverse()*KDL::Rot(KDL::Vector(newq[0],0.0,newq[1]))).GetXZRot().GetValue(deltaq);
+ deltaq[0] /= timestamp.realTimestep;
+ deltaq[1] /= timestamp.realTimestep;
+ callback.lockJoint(q_nr, 2, deltaq);
+ // no need to update the other joints, it will be done after next rerun
+ goto end_loop;
+ }
+ } else
+ unlocked++;
+ break;
+ }
+ case KDL::Joint::Sphere:
+ {
+ (KDL::Rot(KDL::Vector(q))*KDL::Rot(KDL::Vector(qdot)*timestamp.realTimestep)).GetRot().GetValue(newq);
+ // no limit on this joint
+ unlocked++;
+ break;
+ }
+ default:
+ for (unsigned int i=0; i<joint->ndof; i++) {
+ newq[i] = q[i]+qdot[i]*timestamp.realTimestep;
+ if (joint[i].useLimit) {
+ if (newq[i] > joint[i].max) {
+ newq[i] = joint[i].max;
+ joint[0].locked = true;
+ } else if (newq[i] < joint[i].min) {
+ newq[i] = joint[i].min;
+ joint[0].locked = true;
+ }
+ }
+ }
+ if (joint[0].locked) {
+ locked = true;
+ norm = 0.0;
+ // compute delta to locked position
+ for (unsigned int i=0; i<joint->ndof; i++) {
+ qdot[i] = newq[i] - q[i];
+ norm += qdot[i]*qdot[i];
+ }
+ if (norm < KDL::epsilon2) {
+ // joint didn't move, no need to update the jacobian
+ callback.lockJoint(q_nr, joint->ndof);
+ } else {
+ // solver needs velocity, compute equivalent velocity
+ for (unsigned int i=0; i<joint->ndof; i++) {
+ qdot[i] /= timestamp.realTimestep;
+ }
+ callback.lockJoint(q_nr, joint->ndof, qdot);
+ goto end_loop;
+ }
+ } else
+ unlocked++;
+ }
+ }
+ qdot += joint->ndof;
+ q += joint->ndof;
+ newq += joint->ndof;
+ q_nr += joint->ndof;
+ }
+end_loop:
+ // check if there any other unlocked joint
+ for ( ; q_nr<m_nq; ) {
+ Joint_struct* joint = &m_joints[q_nr];
+ if (!joint->locked)
+ unlocked++;
+ q_nr += joint->ndof;
+ }
+ // if all joints have been locked no need to run the solver again
+ return (unlocked) ? locked : false;
+}
+
+void Armature::updateKinematics(const Timestamp& timestamp){
+
+ //Integrate m_qdot
+ if (!m_finalized)
+ return;
+
+ // the new joint value have been computed already, just copy
+ memcpy(&m_qKdl(0), &m_newqKdl(0), sizeof(double)*m_qKdl.rows());
+ pushCache(timestamp);
+ updateJacobian();
+ // here update the desired output.
+ // We assume constant desired output for the joint limit constraint, no need to update it.
+}
+
+void Armature::updateJacobian()
+{
+ //calculate pose and jacobian
+ for (unsigned int ee=0; ee<m_nee; ee++) {
+ m_fksolver->JntToCart(m_qKdl,m_effectors[ee].pose,m_effectors[ee].name,m_root);
+ m_jacsolver->JntToJac(m_qKdl,*m_jac,m_effectors[ee].name);
+ // get the jacobian for the base point, to prepare transformation to world reference
+ changeRefPoint(*m_jac,-m_effectors[ee].pose.p,*m_jac);
+ //copy to Jq:
+ e_matrix& Jq = m_JqArray[ee];
+ for(unsigned int i=0;i<6;i++) {
+ for(unsigned int j=0;j<m_nq;j++)
+ Jq(i,j)=(*m_jac)(i,j);
+ }
+ }
+ // remember that this object has moved
+ m_updated = true;
+}
+
+const Frame& Armature::getPose(const unsigned int ee)
+{
+ if (!m_finalized)
+ return F_identity;
+ return (ee >= m_nee) ? F_identity : m_effectors[ee].pose;
+}
+
+bool Armature::getRelativeFrame(Frame& result, const std::string& segment_name, const std::string& base_name)
+{
+ if (!m_finalized)
+ return false;
+ return (m_fksolver->JntToCart(m_qKdl,result,segment_name,base_name) < 0) ? false : true;
+}
+
+void Armature::updateControlOutput(const Timestamp& timestamp)
+{
+ if (!m_finalized)
+ return;
+
+
+ if (!timestamp.substep && !timestamp.reiterate && timestamp.interpolate) {
+ popQ(timestamp.cacheTimestamp);
+ //popConstraints(timestamp.cacheTimestamp);
+ }
+
+ if (!timestamp.substep) {
+ // save previous joint state for getMaxJointChange()
+ memcpy(&m_oldqKdl(0), &m_qKdl(0), sizeof(double)*m_qKdl.rows());
+ for (unsigned int i=0; i<m_neffector; i++) {
+ m_effectors[i].oldpose = m_effectors[i].pose;
+ }
+ }
+
+ // remove all joint lock
+ for (JointList::iterator jit=m_joints.begin(); jit!=m_joints.end(); ++jit) {
+ (*jit).locked = false;
+ }
+
+ JointConstraintList::iterator it;
+ unsigned int iConstraint;
+
+ // scan through the constraints and call the callback functions
+ for (iConstraint=0, it=m_constraints.begin(); it!=m_constraints.end(); it++, iConstraint++) {
+ JointConstraint_struct* pConstraint = *it;
+ unsigned int nr, i;
+ for (i=0, nr = pConstraint->segment->second.q_nr; i<pConstraint->v_nr; i++, nr++) {
+ *(double*)&pConstraint->value[i].y = m_qKdl(nr);
+ *(double*)&pConstraint->value[i].ydot = m_qdotKdl(nr);
+ }
+ if (pConstraint->function && (pConstraint->substep || (!timestamp.reiterate && !timestamp.substep))) {
+ (*pConstraint->function)(timestamp, pConstraint->values, pConstraint->v_nr, pConstraint->param);
+ }
+ // recompute the weight in any case, that's the most likely modification
+ for (i=0, nr=pConstraint->y_nr; i<pConstraint->v_nr; i++, nr++) {
+ m_Wy(nr) = pConstraint->values[i].alpha/*/(pConstraint->values.tolerance*pConstraint->values.feedback)*/;
+ m_ydot(nr)=pConstraint->value[i].yddot+pConstraint->values[i].feedback*(pConstraint->value[i].yd-pConstraint->value[i].y);
+ }
+ }
+}
+
+bool Armature::setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, double value, double timestep)
+{
+ unsigned int lastid, i;
+ if (constraintId == CONSTRAINT_ID_ALL) {
+ constraintId = 0;
+ lastid = m_nconstraint;
+ } else if (constraintId < m_nconstraint) {
+ lastid = constraintId+1;
+ } else {
+ return false;
+ }
+ for ( ; constraintId<lastid; ++constraintId) {
+ JointConstraint_struct* pConstraint = m_constraints[constraintId];
+ if (valueId == ID_JOINT) {
+ for (i=0; i<pConstraint->v_nr; i++) {
+ switch (action) {
+ case ACT_TOLERANCE:
+ pConstraint->values[i].tolerance = value;
+ break;
+ case ACT_FEEDBACK:
+ pConstraint->values[i].feedback = value;
+ break;
+ case ACT_ALPHA:
+ pConstraint->values[i].alpha = value;
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ for (i=0; i<pConstraint->v_nr; i++) {
+ if (valueId == pConstraint->value[i].id) {
+ switch (action) {
+ case ACT_VALUE:
+ pConstraint->value[i].yd = value;
+ break;
+ case ACT_VELOCITY:
+ pConstraint->value[i].yddot = value;
+ break;
+ case ACT_TOLERANCE:
+ pConstraint->values[i].tolerance = value;
+ break;
+ case ACT_FEEDBACK:
+ pConstraint->values[i].feedback = value;
+ break;
+ case ACT_ALPHA:
+ pConstraint->values[i].alpha = value;
+ break;
+ case ACT_NONE:
+ break;
+ }
+ }
+ }
+ }
+ if (m_finalized) {
+ for (i=0; i<pConstraint->v_nr; i++)
+ m_Wy(pConstraint->y_nr+i) = pConstraint->values[i].alpha/*/(pConstraint->values.tolerance*pConstraint->values.feedback)*/;
+ }
+ }
+ return true;
+}
+
+}
+
diff --git a/intern/itasc/Armature.hpp b/intern/itasc/Armature.hpp
new file mode 100644
index 00000000000..312ca1b28c3
--- /dev/null
+++ b/intern/itasc/Armature.hpp
@@ -0,0 +1,137 @@
+/* $Id: Armature.hpp 20853 2009-06-13 12:29:46Z ben2610 $
+ * Armature.hpp
+ *
+ * Created on: Feb 3, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef ARMATURE_HPP_
+#define ARMATURE_HPP_
+
+#include "ControlledObject.hpp"
+#include "ConstraintSet.hpp"
+#include "kdl/treejnttojacsolver.hpp"
+#include "kdl/treefksolverpos_recursive.hpp"
+#include <vector>
+
+namespace iTaSC {
+
+class Armature: public iTaSC::ControlledObject {
+public:
+ Armature();
+ virtual ~Armature();
+
+ bool addSegment(const std::string& segment_name, const std::string& hook_name, const Joint& joint, const double& q_rest, const Frame& f_tip=F_identity, const Inertia& M = Inertia::Zero());
+ // general purpose constraint on joint
+ int addConstraint(const std::string& segment_name, ConstraintCallback _function, void* _param=NULL, bool _freeParam=false, bool _substep=false);
+ // specific limit constraint on joint
+ int addLimitConstraint(const std::string& segment_name, unsigned int dof, double _min, double _max);
+ double getMaxJointChange();
+ double getMaxEndEffectorChange();
+ bool getSegment(const std::string& segment_name, const unsigned int q_size, const Joint* &p_joint, double &q_rest, double &q, const Frame* &p_tip);
+ bool getRelativeFrame(Frame& result, const std::string& segment_name, const std::string& base_name=m_root);
+
+ virtual void finalize();
+
+ virtual int addEndEffector(const std::string& name);
+ virtual const Frame& getPose(const unsigned int end_effector);
+ virtual bool updateJoint(const Timestamp& timestamp, JointLockCallback& callback);
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void updateControlOutput(const Timestamp& timestamp);
+ virtual bool setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, double value, double timestep=0.0);
+ virtual void initCache(Cache *_cache);
+ virtual bool setJointArray(const KDL::JntArray& joints);
+ virtual const KDL::JntArray& getJointArray();
+
+ virtual double getArmLength()
+ {
+ return m_armlength;
+ }
+
+ struct Effector_struct {
+ std::string name;
+ Frame oldpose;
+ Frame pose;
+ Effector_struct(const std::string& _name) {name = _name; oldpose = pose = F_identity;}
+ };
+ typedef std::vector<Effector_struct> EffectorList;
+
+ enum ID {
+ ID_JOINT=1,
+ ID_JOINT_RX=2,
+ ID_JOINT_RY=3,
+ ID_JOINT_RZ=4,
+ ID_JOINT_TX=2,
+ ID_JOINT_TY=3,
+ ID_JOINT_TZ=4,
+ };
+ struct JointConstraint_struct {
+ SegmentMap::const_iterator segment;
+ ConstraintSingleValue value[3];
+ ConstraintValues values[3];
+ ConstraintCallback function;
+ unsigned int v_nr;
+ unsigned int y_nr; // first coordinate of constraint in Y vector
+ void* param;
+ bool freeParam;
+ bool substep;
+ JointConstraint_struct(SegmentMap::const_iterator _segment, unsigned int _y_nr, ConstraintCallback _function, void* _param, bool _freeParam, bool _substep);
+ ~JointConstraint_struct();
+ };
+ typedef std::vector<JointConstraint_struct*> JointConstraintList;
+
+ struct Joint_struct {
+ KDL::Joint::JointType type;
+ unsigned short ndof;
+ bool useLimit;
+ bool locked;
+ double rest;
+ double min;
+ double max;
+
+ Joint_struct(KDL::Joint::JointType _type, unsigned int _ndof, double _rest) :
+ type(_type), ndof(_ndof), rest(_rest) { useLimit=locked=false; min=0.0; max=0.0; }
+ };
+ typedef std::vector<Joint_struct> JointList;
+
+protected:
+ virtual void updateJacobian();
+
+private:
+ static std::string m_root;
+ Tree m_tree;
+ unsigned int m_njoint;
+ unsigned int m_nconstraint;
+ unsigned int m_noutput;
+ unsigned int m_neffector;
+ bool m_finalized;
+ Cache* m_cache;
+ double *m_buf;
+ int m_qCCh;
+ CacheTS m_qCTs;
+ int m_yCCh;
+ CacheTS m_yCTs;
+ JntArray m_qKdl;
+ JntArray m_oldqKdl;
+ JntArray m_newqKdl;
+ JntArray m_qdotKdl;
+ Jacobian* m_jac;
+ double m_armlength;
+
+ KDL::TreeJntToJacSolver* m_jacsolver;
+ KDL::TreeFkSolverPos_recursive* m_fksolver;
+ EffectorList m_effectors;
+ JointConstraintList m_constraints;
+ JointList m_joints;
+
+ void pushQ(CacheTS timestamp);
+ bool popQ(CacheTS timestamp);
+ //void pushConstraints(CacheTS timestamp);
+ //bool popConstraints(CacheTS timestamp);
+
+};
+
+}
+
+#endif /* ARMATURE_HPP_ */
diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt
new file mode 100644
index 00000000000..405d74d17ac
--- /dev/null
+++ b/intern/itasc/CMakeLists.txt
@@ -0,0 +1,32 @@
+# $Id: CMakeLists.txt 19905 2009-04-23 13:29:54Z ben2610 $
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jacques Beaurain.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+SET(INC ../../extern/Eigen2)
+
+FILE(GLOB SRC *.cpp kdl/*.cpp kdl/utilities/*.cpp)
+
+BLENDERLIB(bf_ITASC "${SRC}" "${INC}")
+#, libtype=['blender'], priority = [10] )
diff --git a/intern/itasc/Cache.cpp b/intern/itasc/Cache.cpp
new file mode 100644
index 00000000000..ccd9cef4655
--- /dev/null
+++ b/intern/itasc/Cache.cpp
@@ -0,0 +1,620 @@
+/* $Id$
+ * Cache.cpp
+ *
+ * Created on: Feb 24, 2009
+ * Author: benoit bolsee
+ */
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include "Cache.hpp"
+
+namespace iTaSC {
+
+CacheEntry::~CacheEntry()
+{
+ for (unsigned int id=0; id < m_count; id++)
+ m_channelArray[id].clear();
+ if (m_channelArray)
+ free(m_channelArray);
+}
+
+CacheItem *CacheChannel::_findBlock(CacheBuffer *buffer, unsigned short timeOffset, unsigned int *retBlock)
+{
+ // the timestamp is necessarily in this buffer
+ unsigned int lowBlock, highBlock, midBlock;
+ if (timeOffset <= buffer->lookup[0].m_timeOffset) {
+ // special case: the item is in the first block, search from start
+ *retBlock = 0;
+ return &buffer->m_firstItem;
+ }
+ // general case, the item is in the middle of the buffer
+ // before doing a dycotomic search, we will assume that timestamp
+ // are regularly spaced so that we can try to locate the block directly
+ highBlock = buffer->m_lastItemPositionW>>m_positionToBlockShiftW;
+ lowBlock = midBlock = (timeOffset*highBlock)/(buffer->m_lastTimestamp-buffer->m_firstTimestamp);
+ // give some space for security
+ if (lowBlock > 0)
+ lowBlock--;
+ if (timeOffset <= buffer->lookup[lowBlock].m_timeOffset) {
+ // bad guess, but we know this block is a good high block, just use it
+ highBlock = lowBlock;
+ lowBlock = 0;
+ } else {
+ // ok, good guess, now check the high block, give some space
+ if (midBlock < highBlock)
+ midBlock++;
+ if (timeOffset <= buffer->lookup[midBlock].m_timeOffset) {
+ // good guess, keep that block as the high block
+ highBlock = midBlock;
+ }
+ }
+ // the item is in a different block, do a dycotomic search
+ // the timestamp is alway > lowBlock and <= highBlock
+ while (1) {
+ midBlock = (lowBlock+highBlock)/2;
+ if (midBlock == lowBlock) {
+ // low block and high block are contigous, we can start search from the low block
+ break;
+ } else if (timeOffset <= buffer->lookup[midBlock].m_timeOffset) {
+ highBlock = midBlock;
+ } else {
+ lowBlock = midBlock;
+ }
+ }
+ assert (lowBlock != highBlock);
+ *retBlock = highBlock;
+ return CACHE_BLOCK_ITEM_ADDR(this,buffer,lowBlock);
+}
+
+void CacheChannel::clear()
+{
+ CacheBuffer *buffer, *next;
+ for (buffer=m_firstBuffer; buffer != 0; buffer = next) {
+ next = buffer->m_next;
+ free(buffer);
+ }
+ m_firstBuffer = NULL;
+ m_lastBuffer = NULL;
+ if (initItem) {
+ free(initItem);
+ initItem = NULL;
+ }
+}
+
+CacheBuffer* CacheChannel::allocBuffer()
+{
+ CacheBuffer* buffer;
+ if (!m_busy)
+ return NULL;
+ buffer = (CacheBuffer*)malloc(CACHE_BUFFER_HEADER_SIZE+(m_bufferSizeW<<2));
+ if (buffer) {
+ memset(buffer, 0, CACHE_BUFFER_HEADER_SIZE);
+ }
+ return buffer;
+}
+
+CacheItem* CacheChannel::findItemOrLater(unsigned int timestamp, CacheBuffer **rBuffer)
+{
+ CacheBuffer* buffer;
+ CacheItem *item, *limit;
+ if (!m_busy)
+ return NULL;
+ if (timestamp == 0 && initItem) {
+ *rBuffer = NULL;
+ return initItem;
+ }
+ for (buffer=m_firstBuffer; buffer; buffer = buffer->m_next) {
+ if (buffer->m_firstFreePositionW == 0)
+ // buffer is empty, this must be the last and we didn't find the timestamp
+ return NULL;
+ if (timestamp < buffer->m_firstTimestamp) {
+ *rBuffer = buffer;
+ return &buffer->m_firstItem;
+ }
+ if (timestamp <= buffer->m_lastTimestamp) {
+ // the timestamp is necessarily in this buffer
+ unsigned short timeOffset = (unsigned short)(timestamp-buffer->m_firstTimestamp);
+ unsigned int highBlock;
+ item = _findBlock(buffer, timeOffset, &highBlock);
+ // now we do a linear search until we find a timestamp that is equal or higher
+ // we should normally always find an item but let's put a limit just in case
+ limit = CACHE_BLOCK_ITEM_ADDR(this,buffer,highBlock);
+ while (item<=limit && item->m_timeOffset < timeOffset )
+ item = CACHE_NEXT_ITEM(item);
+ assert(item<=limit);
+ *rBuffer = buffer;
+ return item;
+ }
+ // search in next buffer
+ }
+ return NULL;
+}
+
+CacheItem* CacheChannel::findItemEarlier(unsigned int timestamp, CacheBuffer **rBuffer)
+{
+ CacheBuffer *buffer, *prevBuffer;
+ CacheItem *item, *limit, *prevItem;
+ if (!m_busy)
+ return NULL;
+ if (timestamp == 0)
+ return NULL;
+ for (prevBuffer=NULL, buffer=m_firstBuffer; buffer; prevBuffer = buffer, buffer = buffer->m_next) {
+ if (buffer->m_firstFreePositionW == 0)
+ // buffer is empty, this must be the last and we didn't find the timestamp
+ return NULL;
+ if (timestamp <= buffer->m_firstTimestamp) {
+ if (prevBuffer == NULL) {
+ // no item before, except the initial item
+ *rBuffer = NULL;
+ return initItem;
+ }
+ // the item is necessarily the last one of previous buffer
+ *rBuffer = prevBuffer;
+ return CACHE_ITEM_ADDR(prevBuffer,prevBuffer->m_lastItemPositionW);
+ }
+ if (timestamp <= buffer->m_lastTimestamp) {
+ // the timestamp is necessarily in this buffer
+ unsigned short timeOffset = (unsigned short)(timestamp-buffer->m_firstTimestamp);
+ unsigned int highBlock;
+ item = _findBlock(buffer, timeOffset, &highBlock);
+ // now we do a linear search until we find a timestamp that is equal or higher
+ // we should normally always find an item but let's put a limit just in case
+ limit = CACHE_BLOCK_ITEM_ADDR(this,buffer,highBlock);
+ prevItem = NULL;
+ while (item<=limit && item->m_timeOffset < timeOffset) {
+ prevItem = item;
+ item = CACHE_NEXT_ITEM(item);
+ }
+ assert(item<=limit && prevItem!=NULL);
+ *rBuffer = buffer;
+ return prevItem;
+ }
+ // search in next buffer
+ }
+ // pass all buffer, the last item is the last item of the last buffer
+ if (prevBuffer == NULL) {
+ // no item before, except the initial item
+ *rBuffer = NULL;
+ return initItem;
+ }
+ // the item is necessarily the last one of previous buffer
+ *rBuffer = prevBuffer;
+ return CACHE_ITEM_ADDR(prevBuffer,prevBuffer->m_lastItemPositionW);
+}
+
+
+Cache::Cache()
+{
+}
+
+Cache::~Cache()
+{
+ CacheMap::iterator it;
+ for (it=m_cache.begin(); it!=m_cache.end(); it=m_cache.begin()) {
+ deleteDevice(it->first);
+ }
+}
+
+int Cache::addChannel(const void *device, const char *name, unsigned int maxItemSize)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+ CacheChannel *channel;
+ unsigned int id;
+
+ if (maxItemSize > 0x3FFF0)
+ return -1;
+
+ if (it == m_cache.end()) {
+ // device does not exist yet, create a new entry
+ entry = new CacheEntry();
+ if (entry == NULL)
+ return -1;
+ if (!m_cache.insert(CacheMap::value_type(device,entry)).second)
+ return -1;
+ } else {
+ entry = it->second;
+ }
+ // locate a channel with the same name and reuse
+ for (channel=entry->m_channelArray, id=0; id<entry->m_count; id++, channel++) {
+ if (channel->m_busy && !strcmp(name, channel->m_name)) {
+ // make this channel free again
+ deleteChannel(device, id);
+ // there can only be one channel with the same name
+ break;
+ }
+ }
+ for (channel=entry->m_channelArray, id=0; id<entry->m_count; id++, channel++) {
+ // locate a free channel
+ if (!channel->m_busy)
+ break;
+ }
+ if (id == entry->m_count) {
+ // no channel free, create new channels
+ int newcount = entry->m_count + CACHE_CHANNEL_EXTEND_SIZE;
+ channel = (CacheChannel*)realloc(entry->m_channelArray, newcount*sizeof(CacheChannel));
+ if (channel == NULL)
+ return -1;
+ entry->m_channelArray = channel;
+ memset(&entry->m_channelArray[entry->m_count], 0, CACHE_CHANNEL_EXTEND_SIZE*sizeof(CacheChannel));
+ entry->m_count = newcount;
+ channel = &entry->m_channelArray[id];
+ }
+ // compute the optimal buffer size
+ // The buffer size must be selected so that
+ // - it does not contain more than 1630 items (=1s of cache assuming 25 items per second)
+ // - it contains at least one item
+ // - it's not bigger than 256kb and preferably around 32kb
+ // - it a multiple of 4
+ unsigned int bufSize = 1630*(maxItemSize+4);
+ if (bufSize >= CACHE_DEFAULT_BUFFER_SIZE)
+ bufSize = CACHE_DEFAULT_BUFFER_SIZE;
+ if (bufSize < maxItemSize+16)
+ bufSize = maxItemSize+16;
+ bufSize = (bufSize + 3) & ~0x3;
+ // compute block size and offset bit mask
+ // the block size is computed so that
+ // - it is a power of 2
+ // - there is at least one item per block
+ // - there is no more than CACHE_LOOKUP_TABLE_SIZE blocks per buffer
+ unsigned int blockSize = bufSize/CACHE_LOOKUP_TABLE_SIZE;
+ if (blockSize < maxItemSize+12)
+ blockSize = maxItemSize+12;
+ // find the power of 2 that is immediately larger than blockSize
+ unsigned int m;
+ unsigned int pwr2Size = blockSize;
+ while ((m = (pwr2Size & (pwr2Size-1))) != 0)
+ pwr2Size = m;
+ blockSize = (pwr2Size < blockSize) ? pwr2Size<<1 : pwr2Size;
+ // convert byte size to word size because all positions and size are expressed in 32 bit words
+ blockSize >>= 2;
+ channel->m_blockSizeW = blockSize;
+ channel->m_bufferSizeW = bufSize>>2;
+ channel->m_firstBuffer = NULL;
+ channel->m_lastBuffer = NULL;
+ channel->m_busy = 1;
+ channel->initItem = NULL;
+ channel->m_maxItemSizeB = maxItemSize;
+ strncpy(channel->m_name, name, sizeof(channel->m_name));
+ channel->m_name[sizeof(channel->m_name)-1] = 0;
+ channel->m_positionToOffsetMaskW = (blockSize-1);
+ for (m=0; blockSize!=1; m++, blockSize>>=1);
+ channel->m_positionToBlockShiftW = m;
+ return (int)id;
+}
+
+int Cache::deleteChannel(const void *device, int id)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return -1;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int)entry->m_count || !entry->m_channelArray[id].m_busy)
+ return -1;
+ entry->m_channelArray[id].clear();
+ entry->m_channelArray[id].m_busy = 0;
+ return 0;
+}
+
+int Cache::deleteDevice(const void *device)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return -1;
+ }
+ entry = it->second;
+ delete entry;
+ m_cache.erase(it);
+ return 0;
+}
+
+void Cache::clearCacheFrom(const void *device, CacheTS timestamp)
+{
+ CacheMap::iterator it = (device) ? m_cache.find(device) : m_cache.begin();
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer, *nextBuffer, *prevBuffer;
+ CacheItem *item, *prevItem, *nextItem;
+ unsigned int positionW, block;
+
+ while (it != m_cache.end()) {
+ entry = it->second;
+ for (unsigned int ch=0; ch<entry->m_count; ch++) {
+ channel = &entry->m_channelArray[ch];
+ if (channel->m_busy) {
+ item = channel->findItemOrLater(timestamp, &buffer);
+ if (item ) {
+ if (!buffer) {
+ // this is possible if we return the special timestamp=0 item, delete all buffers
+ channel->clear();
+ } else {
+ // this item and all later items will be removed, clear any later buffer
+ while ((nextBuffer = buffer->m_next) != NULL) {
+ buffer->m_next = nextBuffer->m_next;
+ free(nextBuffer);
+ }
+ positionW = CACHE_ITEM_POSITIONW(buffer,item);
+ if (positionW == 0) {
+ // this item is the first one of the buffer, remove the buffer completely
+ // first find the buffer just before it
+ nextBuffer = channel->m_firstBuffer;
+ prevBuffer = NULL;
+ while (nextBuffer != buffer) {
+ prevBuffer = nextBuffer;
+ nextBuffer = nextBuffer->m_next;
+ // we must quit this loop before reaching the end of the list
+ assert(nextBuffer);
+ }
+ free(buffer);
+ buffer = prevBuffer;
+ if (buffer == NULL)
+ // this was also the first buffer
+ channel->m_firstBuffer = NULL;
+ } else {
+ // removing this item means finding the previous item to make it the last one
+ block = positionW>>channel->m_positionToBlockShiftW;
+ if (block == 0) {
+ // start from first item, we know it is not our item because positionW > 0
+ prevItem = &buffer->m_firstItem;
+ } else {
+ // no need to check the current block, it will point to our item or a later one
+ // but the previous block will be a good start for sure.
+ block--;
+ prevItem = CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+ }
+ while ((nextItem = CACHE_NEXT_ITEM(prevItem)) < item)
+ prevItem = nextItem;
+ // we must have found our item
+ assert(nextItem==item);
+ // now set the buffer
+ buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,prevItem);
+ buffer->m_firstFreePositionW = positionW;
+ buffer->m_lastTimestamp = buffer->m_firstTimestamp + prevItem->m_timeOffset;
+ block = buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
+ buffer->lookup[block].m_offsetW = buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
+ buffer->lookup[block].m_timeOffset = prevItem->m_timeOffset;
+ }
+ // set the channel
+ channel->m_lastBuffer = buffer;
+ if (buffer) {
+ channel->m_lastTimestamp = buffer->m_lastTimestamp;
+ channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
+ }
+ }
+ }
+ }
+ }
+ if (device)
+ break;
+ ++it;
+ }
+}
+
+void *Cache::addCacheItem(const void *device, int id, unsigned int timestamp, void *data, unsigned int length)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer, *next;
+ CacheItem *item;
+ unsigned int positionW, sizeW, block;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return NULL;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int) entry->m_count || !entry->m_channelArray[id].m_busy)
+ return NULL;
+ channel = &entry->m_channelArray[id];
+ if (length > channel->m_maxItemSizeB)
+ return NULL;
+ if (timestamp == 0) {
+ // initial item, delete all buffers
+ channel->clear();
+ // and create initial item
+ item = NULL;
+ // we will allocate the memory, which is always pointer aligned => compute size
+ // with NULL will give same result.
+ sizeW = CACHE_ITEM_SIZEW(item,length);
+ item = (CacheItem*)calloc(sizeW, 4);
+ item->m_sizeW = sizeW;
+ channel->initItem = item;
+ } else {
+ if (!channel->m_lastBuffer) {
+ // no item in buffer, insert item at first position of first buffer
+ positionW = 0;
+ if ((buffer = channel->m_firstBuffer) == NULL) {
+ buffer = channel->allocBuffer();
+ channel->m_firstBuffer = buffer;
+ }
+ } else if (timestamp > channel->m_lastTimestamp) {
+ // this is the normal case: we are writing past lastest timestamp
+ buffer = channel->m_lastBuffer;
+ positionW = buffer->m_firstFreePositionW;
+ } else if (timestamp == channel->m_lastTimestamp) {
+ // common case, rewriting the last timestamp, just reuse the last position
+ buffer = channel->m_lastBuffer;
+ positionW = channel->m_lastItemPositionW;
+ } else {
+ // general case, write in the middle of the buffer, locate the timestamp
+ // (or the timestamp just after), clear this item and all future items,
+ // and write at that position
+ item = channel->findItemOrLater(timestamp, &buffer);
+ if (item == NULL) {
+ // this should not happen
+ return NULL;
+ }
+ // this item will become the last one of this channel, clear any later buffer
+ while ((next = buffer->m_next) != NULL) {
+ buffer->m_next = next->m_next;
+ free(next);
+ }
+ // no need to update the buffer, this will be done when the item is written
+ positionW = CACHE_ITEM_POSITIONW(buffer,item);
+ }
+ item = CACHE_ITEM_ADDR(buffer,positionW);
+ sizeW = CACHE_ITEM_SIZEW(item,length);
+ // we have positionW pointing where we can put the item
+ // before we do that we have to check if we can:
+ // - enough room
+ // - timestamp not too late
+ if ((positionW+sizeW > channel->m_bufferSizeW) ||
+ (positionW > 0 && timestamp >= buffer->m_firstTimestamp+0x10000)) {
+ // we must allocate a new buffer to store this item
+ // but before we must make sure that the current buffer is consistent
+ if (positionW != buffer->m_firstFreePositionW) {
+ // This means that we were trying to write in the middle of the buffer.
+ // We must set the buffer right with positionW being the last position
+ // and find the item before positionW to make it the last.
+ block = positionW>>channel->m_positionToBlockShiftW;
+ CacheItem *previousItem, *nextItem;
+ if (block == 0) {
+ // start from first item, we know it is not our item because positionW > 0
+ previousItem = &buffer->m_firstItem;
+ } else {
+ // no need to check the current block, it will point to our item or a later one
+ // but the previous block will be a good start for sure.
+ block--;
+ previousItem = CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+ }
+ while ((nextItem = CACHE_NEXT_ITEM(previousItem)) < item)
+ previousItem = nextItem;
+ // we must have found our item
+ assert(nextItem==item);
+ // now set the buffer
+ buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,previousItem);
+ buffer->m_firstFreePositionW = positionW;
+ buffer->m_lastTimestamp = buffer->m_firstTimestamp + previousItem->m_timeOffset;
+ block = buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
+ buffer->lookup[block].m_offsetW = buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
+ buffer->lookup[block].m_timeOffset = previousItem->m_timeOffset;
+ // and also the channel, just in case
+ channel->m_lastBuffer = buffer;
+ channel->m_lastTimestamp = buffer->m_lastTimestamp;
+ channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
+ }
+ // now allocate a new buffer
+ buffer->m_next = channel->allocBuffer();
+ if (buffer->m_next == NULL)
+ return NULL;
+ buffer = buffer->m_next;
+ positionW = 0;
+ item = &buffer->m_firstItem;
+ sizeW = CACHE_ITEM_SIZEW(item,length);
+ }
+ // all check passed, ready to write the item
+ item->m_sizeW = sizeW;
+ if (positionW == 0) {
+ item->m_timeOffset = 0;
+ buffer->m_firstTimestamp = timestamp;
+ } else {
+ item->m_timeOffset = (unsigned short)(timestamp-buffer->m_firstTimestamp);
+ }
+ buffer->m_lastItemPositionW = positionW;
+ buffer->m_firstFreePositionW = positionW+sizeW;
+ buffer->m_lastTimestamp = timestamp;
+ block = positionW>>channel->m_positionToBlockShiftW;
+ buffer->lookup[block].m_offsetW = positionW&channel->m_positionToOffsetMaskW;
+ buffer->lookup[block].m_timeOffset = item->m_timeOffset;
+ buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,item);
+ buffer->m_firstFreePositionW = buffer->m_lastItemPositionW+item->m_sizeW;
+ channel->m_lastBuffer = buffer;
+ channel->m_lastItemPositionW = positionW;
+ channel->m_lastTimestamp = timestamp;
+ }
+ // now copy the item
+ void *itemData = CACHE_ITEM_DATA_POINTER(item);
+ if (data)
+ memcpy(itemData, data, length);
+ return itemData;
+}
+
+const void *Cache::getPreviousCacheItem(const void *device, int id, unsigned int *timestamp)
+{
+ CacheMap::iterator it;
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer;
+ CacheItem *item;
+
+ if (device) {
+ it = m_cache.find(device);
+ } else {
+ it = m_cache.begin();
+ }
+ if (it == m_cache.end()) {
+ // device does not exist
+ return NULL;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int) entry->m_count || !entry->m_channelArray[id].m_busy)
+ return NULL;
+ channel = &entry->m_channelArray[id];
+ if ((item = channel->findItemEarlier(*timestamp,&buffer)) == NULL)
+ return NULL;
+ *timestamp = (buffer) ? buffer->m_firstTimestamp+item->m_timeOffset : 0;
+ return CACHE_ITEM_DATA_POINTER(item);
+}
+
+const CacheItem *Cache::getCurrentCacheItemInternal(const void *device, int id, CacheTS timestamp)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer;
+ CacheItem *item;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return NULL;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int) entry->m_count || !entry->m_channelArray[id].m_busy)
+ return NULL;
+ channel = &entry->m_channelArray[id];
+ if ((item = channel->findItemOrLater(timestamp,&buffer)) == NULL)
+ return NULL;
+ if (buffer && buffer->m_firstTimestamp+item->m_timeOffset != timestamp)
+ return NULL;
+ return item;
+}
+
+const void *Cache::getCurrentCacheItem(const void *device, int channel, unsigned int timestamp)
+{
+ const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp);
+ return (item) ? CACHE_ITEM_DATA_POINTER(item) : NULL;
+}
+
+double *Cache::addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *newdata, unsigned int length, double threshold)
+{
+ const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp);
+ unsigned int sizeW = CACHE_ITEM_SIZEW(item,length*sizeof(double));
+ if (!item || item->m_sizeW != sizeW)
+ return (double*)addCacheItem(device, channel, timestamp, newdata, length*sizeof(double));
+ double *olddata = (double*)CACHE_ITEM_DATA_POINTER(item);
+ if (!length)
+ return olddata;
+ double *ref = olddata;
+ double *v = newdata;
+ unsigned int i;
+ for (i=length; i>0; --i) {
+ if (fabs(*v-*ref) > threshold)
+ break;
+ *ref++ = *v++;
+ }
+ if (i)
+ olddata = (double*)addCacheItem(device, channel, timestamp, newdata, length*sizeof(double));
+ return olddata;
+}
+
+}
diff --git a/intern/itasc/Cache.hpp b/intern/itasc/Cache.hpp
new file mode 100644
index 00000000000..64707782e6f
--- /dev/null
+++ b/intern/itasc/Cache.hpp
@@ -0,0 +1,227 @@
+/* $Id: Cache.hpp 21152 2009-06-25 11:57:19Z ben2610 $
+ * Cache.hpp
+ *
+ * Created on: Feb 24, 2009
+ * Author: benoit tbolsee
+ */
+
+#ifndef CACHE_HPP_
+#define CACHE_HPP_
+
+#include <map>
+
+namespace iTaSC {
+
+#define CACHE_LOOKUP_TABLE_SIZE 128
+#define CACHE_DEFAULT_BUFFER_SIZE 32768
+#define CACHE_CHANNEL_EXTEND_SIZE 10
+#define CACHE_MAX_ITEM_SIZE 0x3FFF0
+
+/* macro to get the alignement gap after an item header */
+#define CACHE_ITEM_GAPB(item) (unsigned int)(((size_t)item+sizeof(CacheItem))&(sizeof(void*)-1))
+/* macro to get item data position, item=CacheItem pointer */
+#define CACHE_ITEM_DATA_POINTER(item) (void*)((unsigned char*)item+sizeof(CacheItem)+CACHE_ITEM_GAPB(item))
+/* macro to get item size in 32bit words from item address and length, item=CacheItem pointer */
+#define CACHE_ITEM_SIZEW(item,length) (unsigned int)((sizeof(CacheItem)+CACHE_ITEM_GAPB(item)+(((length)+3)&~0x3))>>2)
+/* macto to move from one item to the next, item=CacheItem pointer, updated by the macro */
+#define CACHE_NEXT_ITEM(item) ((item)+(item)->m_sizeW)
+#define CACHE_BLOCK_ITEM_ADDR(chan,buf,block) (&(buf)->m_firstItem+(((unsigned int)(block)<<chan->m_positionToBlockShiftW)+(buf)->lookup[block].m_offsetW))
+#define CACHE_ITEM_ADDR(buf,pos) (&(buf)->m_firstItem+(pos))
+#define CACHE_ITEM_POSITIONW(buf,item) (unsigned int)(item-&buf->m_firstItem)
+
+typedef unsigned int CacheTS;
+
+struct Timestamp
+{
+ double realTimestamp;
+ double realTimestep;
+ CacheTS cacheTimestamp;
+ unsigned int numstep:8;
+ unsigned int substep:1;
+ unsigned int reiterate:1;
+ unsigned int cache:1;
+ unsigned int update:1;
+ unsigned int interpolate:1;
+ unsigned int dummy:19;
+
+ Timestamp() { memset(this, 0, sizeof(Timestamp)); }
+};
+
+/* utility function to return second timestamp to millisecond */
+inline void setCacheTimestamp(Timestamp& timestamp)
+{
+ if (timestamp.realTimestamp < 0.0 || timestamp.realTimestamp > 4294967.295)
+ timestamp.cacheTimestamp = 0;
+ else
+ timestamp.cacheTimestamp = (CacheTS)(timestamp.realTimestamp*1000.0+0.5);
+}
+
+
+/*
+class Cache:
+Top level class, only one instance of this class should exists.
+A device (=constraint, object) uses this class to create a cache entry for its data.
+A cache entry is divided into cache channels, each providing a separate buffer for cache items.
+The cache channels must be declared by the devices before they can be used.
+The device must specify the largest cache item (limited to 256Kb) so that the cache
+buffer can be organized optimally.
+Cache channels are identified by small number (starting from 0) allocated by the cache system.
+Cache items are inserted into cache channels ordered by timestamp. Writing is always done
+at the end of the cache buffer: writing an item automatically clears all items with
+higher timestamp.
+A cache item is an array of bytes provided by the device; the format of the cache item is left
+to the device.
+The device can retrieve a cache item associated with a certain timestamp. The cache system
+returns a pointer that points directly in the cache buffer to avoid unnecessary copy.
+The pointer is guaranteed to be pointer aligned so that direct mapping to C structure is possible
+(=32 bit aligned on 32 systems and 64 bit aligned on 64 bits system).
+
+Timestamp = rounded time in millisecond.
+*/
+
+struct CacheEntry;
+struct CacheBuffer;
+struct CacheItem;
+struct CacheChannel;
+
+class Cache
+{
+private:
+ /* map between device and cache entry.
+ Dynamically updated when more devices create cache channels */
+ typedef std::map<const void *, struct CacheEntry*> CacheMap;
+ CacheMap m_cache;
+ const CacheItem *getCurrentCacheItemInternal(const void *device, int channel, CacheTS timestamp);
+
+public:
+ Cache();
+ ~Cache();
+ /* add a cache channel, maxItemSize must be < 256k.
+ name : channel name, truncated at 31 characters
+ msxItemSize : maximum size of item in bytes, items of larger size will be rejected
+ return value >= 0: channel id, -1: error */
+ int addChannel(const void *device, const char *name, unsigned int maxItemSize);
+
+ /* delete a cache channel (and all associated buffers and items) */
+ int deleteChannel(const void *device, int channel);
+ /* delete all channels of a device and remove the device from the map */
+ int deleteDevice(const void *device);
+ /* removes all cache items, leaving the special item at timestamp=0.
+ if device=NULL, apply to all devices. */
+ void clearCacheFrom(const void *device, CacheTS timestamp);
+
+ /* add a new cache item
+ channel: the cache channel (as returned by AddChannel
+ data, length: the cache item and length in bytes
+ If data is NULL, the memory is allocated in the cache but not writen
+ return: error: NULL, success: pointer to item in cache */
+ void *addCacheItem(const void *device, int channel, CacheTS timestamp, void *data, unsigned int length);
+
+ /* specialized function to add a vector of double in the cache
+ It will first check if a vector exist already in the cache for the same timestamp
+ and compared the cached vector with the new values.
+ If all values are within threshold, the vector is updated but the cache is not deleted
+ for the future timestamps. */
+ double *addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *data, unsigned int length, double threshold);
+
+ /* returns the cache item with timestamp that is just before the given timestamp.
+ returns the data pointer or NULL if there is no cache item before timestamp.
+ On return, timestamp is updated with the actual timestamp of the item being returned.
+ Note that the length of the item is not returned, it is up to the device to organize
+ the data so that length can be retrieved from the data if needed.
+ Device can NULL, it will then just look the first channel available, useful to
+ test the status of the cache. */
+ const void *getPreviousCacheItem(const void *device, int channel, CacheTS *timestamp);
+
+ /* returns the cache item with the timestamp that is exactly equal to the given timestamp
+ If there is no cache item for this timestamp, returns NULL.*/
+ const void *getCurrentCacheItem(const void *device, int channel, CacheTS timestamp);
+
+};
+
+/* the following structures are not internal use only, they should not be used directly */
+
+struct CacheEntry
+{
+ CacheChannel *m_channelArray; // array of channels, automatically resized if more channels are created
+ unsigned int m_count; // number of channel in channelArray
+ CacheEntry() : m_channelArray(NULL), m_count(0) {}
+ ~CacheEntry();
+};
+
+struct CacheChannel
+{
+ CacheItem* initItem; // item corresponding to timestamp=0
+ struct CacheBuffer *m_firstBuffer; // first buffer of list
+ struct CacheBuffer *m_lastBuffer; // last buffer of list to which an item was written
+ char m_name[32]; // channel name
+ unsigned char m_busy; // =0 if channel is free, !=0 when channel is in use
+ unsigned char m_positionToBlockShiftW; // number of bits to shift a position in word to get the block number
+ unsigned short m_positionToOffsetMaskW; // bit mask to apply on a position in word to get offset in a block
+ unsigned int m_maxItemSizeB; // maximum item size in bytes
+ unsigned int m_bufferSizeW; // size of item buffer in word to allocate when a new buffer must be created
+ unsigned int m_blockSizeW; // block size in words of the lookup table
+ unsigned int m_lastTimestamp; // timestamp of the last item that was written
+ unsigned int m_lastItemPositionW; // position in words in lastBuffer of the last item written
+ void clear();
+ CacheBuffer* allocBuffer();
+ CacheItem* findItemOrLater(unsigned int timestamp, CacheBuffer **rBuffer);
+ CacheItem* findItemEarlier(unsigned int timestamp, CacheBuffer **rBuffer);
+ // Internal function: finds an item in a buffer that is < timeOffset
+ // timeOffset must be a valid offset for the buffer and the buffer must not be empty
+ // on return highBlock contains the block with items above or equal to timeOffset
+ CacheItem *_findBlock(CacheBuffer *buffer, unsigned short timeOffset, unsigned int *highBlock);
+};
+
+struct CacheBlock {
+ unsigned short m_timeOffset; // timestamp relative to m_firstTimestamp
+ unsigned short m_offsetW; // position in words of item relative to start of block
+};
+
+/* CacheItem is the header of each item in the buffer, must be 32bit
+ Items are always 32 bits aligned and size is the number of 32 bit words until the
+ next item header, including an eventual pre and post padding gap for pointer alignment */
+struct CacheItem
+{
+ unsigned short m_timeOffset; // timestamp relative to m_firstTimestamp
+ unsigned short m_sizeW; // size of item in 32 bit words
+ // item data follows header immediately or after a gap if position is not pointer aligned
+};
+
+// Buffer header
+// Defined in a macro to avoid sizeof() potential problem.
+// next for linked list. = NULL for last buffer
+// m_firstTimestamp timestamp of first item in this buffer
+// m_lastTimestamp timestamp of last item in this buffer
+// m_lastTimestamp must be < m_firstTimestamp+65536
+// m_lastItemPositionW position in word of last item written
+// m_firstFreePositionW position in word where a new item can be written, 0 if buffer is empty
+// lookup lookup table for fast access to item by timestamp
+// The buffer is divided in blocks of 2**n bytes with n chosen so that
+// there are no more than CACHE_LOOKUP_TABLE_SIZE blocks and that each
+// block will contain at least one item.
+// Each element of the lookup table gives the timestamp and offset
+// of the last cache item occupying (=starting in) the corresponding block.
+#define CACHE_HEADER \
+ struct CacheBuffer *m_next; \
+ unsigned int m_firstTimestamp; \
+ unsigned int m_lastTimestamp; \
+ \
+ unsigned int m_lastItemPositionW; \
+ unsigned int m_firstFreePositionW;\
+ struct CacheBlock lookup[CACHE_LOOKUP_TABLE_SIZE]
+
+struct CacheBufferHeader {
+ CACHE_HEADER;
+};
+#define CACHE_BUFFER_HEADER_SIZE (sizeof(struct CacheBufferHeader))
+struct CacheBuffer
+{
+ CACHE_HEADER;
+ struct CacheItem m_firstItem; // the address of this field marks the start of the buffer
+};
+
+
+}
+
+#endif /* CACHE_HPP_ */
diff --git a/intern/itasc/ConstraintSet.cpp b/intern/itasc/ConstraintSet.cpp
new file mode 100644
index 00000000000..a38db445ea2
--- /dev/null
+++ b/intern/itasc/ConstraintSet.cpp
@@ -0,0 +1,170 @@
+/* $Id$
+ * ConstraintSet.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "ConstraintSet.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+
+namespace iTaSC {
+
+ConstraintSet::ConstraintSet(unsigned int _nc,double accuracy,unsigned int maximum_iterations):
+ m_nc(_nc),
+ m_Cf(e_zero_matrix(m_nc,6)),
+ m_Wy(e_scalar_vector(m_nc,1.0)),
+ m_y(m_nc),m_ydot(e_zero_vector(m_nc)),m_chi(e_zero_vector(6)),
+ m_S(6),m_temp(6),m_tdelta(6),
+ m_Jf(e_identity_matrix(6,6)),
+ m_U(e_identity_matrix(6,6)),m_V(e_identity_matrix(6,6)),m_B(e_zero_matrix(6,6)),
+ m_Jf_inv(e_zero_matrix(6,6)),
+ m_internalPose(F_identity), m_externalPose(F_identity),
+ m_constraintCallback(NULL), m_constraintParam(NULL),
+ m_toggle(false),m_substep(false),
+ m_threshold(accuracy),m_maxIter(maximum_iterations)
+{
+ m_maxDeltaChi = e_scalar(0.52);
+}
+
+ConstraintSet::ConstraintSet():
+ m_nc(0),
+ m_internalPose(F_identity), m_externalPose(F_identity),
+ m_constraintCallback(NULL), m_constraintParam(NULL),
+ m_toggle(false),m_substep(false),
+ m_threshold(0.0),m_maxIter(0)
+{
+ m_maxDeltaChi = e_scalar(0.52);
+}
+
+void ConstraintSet::reset(unsigned int _nc,double accuracy,unsigned int maximum_iterations)
+{
+ m_nc = _nc;
+ m_Jf = e_identity_matrix(6,6);
+ m_Cf = e_zero_matrix(m_nc,6);
+ m_U = e_identity_matrix(6,6);
+ m_V = e_identity_matrix(6,6);
+ m_B = e_zero_matrix(6,6);
+ m_Jf_inv = e_zero_matrix(6,6),
+ m_Wy = e_scalar_vector(m_nc,1.0),
+ m_chi = e_zero_vector(6);
+ m_chidot = e_zero_vector(6);
+ m_y = e_zero_vector(m_nc);
+ m_ydot = e_zero_vector(m_nc);
+ m_S = e_zero_vector(6);
+ m_temp = e_zero_vector(6);
+ m_tdelta = e_zero_vector(6);
+ m_threshold = accuracy;
+ m_maxIter = maximum_iterations;
+}
+
+ConstraintSet::~ConstraintSet() {
+
+}
+
+void ConstraintSet::modelUpdate(Frame& _external_pose,const Timestamp& timestamp)
+{
+ m_chi+=m_chidot*timestamp.realTimestep;
+ m_externalPose = _external_pose;
+
+ //update the internal pose and Jf
+ updateJacobian();
+ //check if loop is already closed, if not update the pose and Jf
+ unsigned int iter=0;
+ while(iter<5&&!closeLoop())
+ iter++;
+}
+
+double ConstraintSet::getMaxTimestep(double& timestep)
+{
+ e_scalar maxChidot = m_chidot.cwise().abs().maxCoeff();
+ if (timestep*maxChidot > m_maxDeltaChi) {
+ timestep = m_maxDeltaChi/maxChidot;
+ }
+ return timestep;
+}
+
+bool ConstraintSet::initialise(Frame& init_pose){
+ m_externalPose=init_pose;
+ // get current Jf
+ updateJacobian();
+
+ unsigned int iter=0;
+ while(iter<m_maxIter&&!closeLoop()){
+ iter++;
+ }
+ if (iter<m_maxIter)
+ return true;
+ else
+ return false;
+}
+
+bool ConstraintSet::setControlParameter(int id, ConstraintAction action, double data, double timestep)
+{
+ ConstraintValues values;
+ ConstraintSingleValue value;
+ values.values = &value;
+ values.number = 0;
+ values.action = action;
+ values.id = id;
+ value.action = action;
+ value.id = id;
+ switch (action) {
+ case ACT_NONE:
+ return true;
+ case ACT_VALUE:
+ value.yd = data;
+ values.number = 1;
+ break;
+ case ACT_VELOCITY:
+ value.yddot = data;
+ values.number = 1;
+ break;
+ case ACT_TOLERANCE:
+ values.tolerance = data;
+ break;
+ case ACT_FEEDBACK:
+ values.feedback = data;
+ break;
+ case ACT_ALPHA:
+ values.alpha = data;
+ break;
+ default:
+ assert(action==ACT_NONE);
+ }
+ return setControlParameters(&values, 1, timestep);
+}
+
+bool ConstraintSet::closeLoop(){
+ //Invert Jf
+ //TODO: svd_boost_Macie has problems if Jf contains zero-rows
+ //toggle=!toggle;
+ //svd_boost_Macie(Jf,U,S,V,B,temp,1e-3*threshold,toggle);
+ int ret = KDL::svd_eigen_HH(m_Jf,m_U,m_S,m_V,m_temp);
+ if(ret<0)
+ return false;
+
+ // the reference point and frame of the jacobian is the base frame
+ // m_externalPose-m_internalPose is the twist to extend the end effector
+ // to get the required pose => change the reference point to the base frame
+ Twist twist_delta(diff(m_internalPose,m_externalPose));
+ twist_delta=twist_delta.RefPoint(-m_internalPose.p);
+ for(unsigned int i=0;i<6;i++)
+ m_tdelta(i)=twist_delta(i);
+ //TODO: use damping in constraintset inversion?
+ for(unsigned int i=0;i<6;i++)
+ if(m_S(i)<m_threshold){
+ m_B.row(i).setConstant(0.0);
+ }else
+ m_B.row(i) = m_U.col(i)/m_S(i);
+
+ m_Jf_inv=(m_V*m_B).lazy();
+
+ m_chi+=(m_Jf_inv*m_tdelta).lazy();
+ updateJacobian();
+ // m_externalPose-m_internalPose in end effector frame
+ // this is just to compare the pose, a different formula would work too
+ return Equal(m_internalPose.Inverse()*m_externalPose,F_identity,m_threshold);
+
+}
+}
diff --git a/intern/itasc/ConstraintSet.hpp b/intern/itasc/ConstraintSet.hpp
new file mode 100644
index 00000000000..12bb085c911
--- /dev/null
+++ b/intern/itasc/ConstraintSet.hpp
@@ -0,0 +1,115 @@
+/* $Id: ConstraintSet.hpp 20307 2009-05-20 20:39:18Z ben2610 $
+ * ConstraintSet.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef CONSTRAINTSET_HPP_
+#define CONSTRAINTSET_HPP_
+
+#include "kdl/frames.hpp"
+#include "eigen_types.hpp"
+#include "Cache.hpp"
+#include <vector>
+
+namespace iTaSC {
+
+enum ConstraintAction {
+ ACT_NONE= 0,
+ ACT_VALUE= 1,
+ ACT_VELOCITY= 2,
+ ACT_TOLERANCE= 4,
+ ACT_FEEDBACK= 8,
+ ACT_ALPHA= 16
+};
+
+struct ConstraintSingleValue {
+ unsigned int id; // identifier of constraint value, depends on constraint
+ unsigned int action;// action performed, compbination of ACT_..., set on return
+ const double y; // actual constraint value
+ const double ydot; // actual constraint velocity
+ double yd; // current desired constraint value, changed on return
+ double yddot; // current desired constraint velocity, changed on return
+ ConstraintSingleValue(): id(0), action(0), y(0.0), ydot(0.0) {}
+};
+
+struct ConstraintValues {
+ unsigned int id; // identifier of group of constraint values, depend on constraint
+ unsigned short number; // number of constraints in list
+ unsigned short action; // action performed, ACT_..., set on return
+ double alpha; // constraint activation coefficient, should be [0..1]
+ double tolerance; // current desired tolerance on constraint, same unit than yd, changed on return
+ double feedback; // current desired feedback on error, in 1/sec, changed on return
+ struct ConstraintSingleValue* values;
+ ConstraintValues(): id(0), number(0), action(0), values(NULL) {}
+};
+
+class ConstraintSet;
+typedef bool (*ConstraintCallback)(const Timestamp& timestamp, struct ConstraintValues* const _values, unsigned int _nvalues, void* _param);
+
+class ConstraintSet {
+protected:
+ unsigned int m_nc;
+ e_scalar m_maxDeltaChi;
+ e_matrix m_Cf;
+ e_vector m_Wy,m_y,m_ydot;
+ e_vector6 m_chi,m_chidot,m_S,m_temp,m_tdelta;
+ e_matrix6 m_Jf,m_U,m_V,m_B,m_Jf_inv;
+ KDL::Frame m_internalPose,m_externalPose;
+ ConstraintCallback m_constraintCallback;
+ void* m_constraintParam;
+ void* m_poseParam;
+ bool m_toggle;
+ bool m_substep;
+ double m_threshold;
+ unsigned int m_maxIter;
+
+ friend class Scene;
+ virtual void modelUpdate(KDL::Frame& _external_pose,const Timestamp& timestamp);
+ virtual void updateKinematics(const Timestamp& timestamp)=0;
+ virtual void pushCache(const Timestamp& timestamp)=0;
+ virtual void updateJacobian()=0;
+ virtual void updateControlOutput(const Timestamp& timestamp)=0;
+ virtual void initCache(Cache *_cache) = 0;
+ virtual bool initialise(KDL::Frame& init_pose);
+ virtual void reset(unsigned int nc,double accuracy,unsigned int maximum_iterations);
+ virtual bool closeLoop();
+ virtual double getMaxTimestep(double& timestep);
+
+
+public:
+ ConstraintSet(unsigned int nc,double accuracy,unsigned int maximum_iterations);
+ ConstraintSet();
+ virtual ~ConstraintSet();
+
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
+ virtual bool registerCallback(ConstraintCallback _function, void* _param)
+ {
+ m_constraintCallback = _function;
+ m_constraintParam = _param;
+ return true;
+ }
+
+ virtual const e_vector& getControlOutput()const{return m_ydot;};
+ virtual const ConstraintValues* getControlParameters(unsigned int* _nvalues) = 0;
+ virtual bool setControlParameters(ConstraintValues* _values, unsigned int _nvalues, double timestep=0.0) = 0;
+ bool setControlParameter(int id, ConstraintAction action, double value, double timestep=0.0);
+
+ virtual const e_matrix6& getJf() const{return m_Jf;};
+ virtual const KDL::Frame& getPose() const{return m_internalPose;};
+ virtual const e_matrix& getCf() const{return m_Cf;};
+
+ virtual const e_vector& getWy() const {return m_Wy;};
+ virtual void setWy(const e_vector& Wy_in){m_Wy = Wy_in;};
+ virtual void setJointVelocity(const e_vector chidot_in){m_chidot = chidot_in;};
+
+ virtual unsigned int getNrOfConstraints(){return m_nc;};
+ void substep(bool _substep) {m_substep=_substep;}
+ bool substep() {return m_substep;}
+};
+
+}
+
+#endif /* CONSTRAINTSET_HPP_ */
diff --git a/intern/itasc/ControlledObject.cpp b/intern/itasc/ControlledObject.cpp
new file mode 100644
index 00000000000..b987e176031
--- /dev/null
+++ b/intern/itasc/ControlledObject.cpp
@@ -0,0 +1,61 @@
+/* $Id$
+ * ControlledObject.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "ControlledObject.hpp"
+
+
+namespace iTaSC {
+ControlledObject::ControlledObject():
+ Object(Controlled),m_nq(0),m_nc(0),m_nee(0)
+{
+ // max joint variable = 0.52 radian or 0.52 meter in one timestep
+ m_maxDeltaQ = e_scalar(0.52);
+}
+
+void ControlledObject::initialize(unsigned int _nq,unsigned int _nc, unsigned int _nee)
+{
+ assert(_nee >= 1);
+ m_nq = _nq;
+ m_nc = _nc;
+ m_nee = _nee;
+ if (m_nq > 0) {
+ m_Wq = e_identity_matrix(m_nq,m_nq);
+ m_qdot = e_zero_vector(m_nq);
+ }
+ if (m_nc > 0) {
+ m_Wy = e_scalar_vector(m_nc,1.0);
+ m_ydot = e_zero_vector(m_nc);
+ }
+ if (m_nc > 0 && m_nq > 0)
+ m_Cq = e_zero_matrix(m_nc,m_nq);
+ // clear all Jacobian if any
+ m_JqArray.clear();
+ // reserve one more to have a zero matrix handy
+ if (m_nq > 0)
+ m_JqArray.resize(m_nee+1, e_zero_matrix(6,m_nq));
+}
+
+ControlledObject::~ControlledObject() {}
+
+
+
+const e_matrix& ControlledObject::getJq(unsigned int ee) const
+{
+ assert(m_nq > 0);
+ return m_JqArray[(ee>m_nee)?m_nee:ee];
+}
+
+double ControlledObject::getMaxTimestep(double& timestep)
+{
+ e_scalar maxQdot = m_qdot.cwise().abs().maxCoeff();
+ if (timestep*maxQdot > m_maxDeltaQ) {
+ timestep = m_maxDeltaQ/maxQdot;
+ }
+ return timestep;
+}
+
+}
diff --git a/intern/itasc/ControlledObject.hpp b/intern/itasc/ControlledObject.hpp
new file mode 100644
index 00000000000..2370f6594ed
--- /dev/null
+++ b/intern/itasc/ControlledObject.hpp
@@ -0,0 +1,70 @@
+/* $Id: ControlledObject.hpp 20853 2009-06-13 12:29:46Z ben2610 $
+ * ControlledObject.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef CONTROLLEDOBJECT_HPP_
+#define CONTROLLEDOBJECT_HPP_
+
+#include "kdl/frames.hpp"
+#include "eigen_types.hpp"
+
+#include "Object.hpp"
+#include "ConstraintSet.hpp"
+#include <vector>
+
+namespace iTaSC {
+
+#define CONSTRAINT_ID_ALL ((unsigned int)-1)
+
+class ControlledObject : public Object {
+protected:
+ e_scalar m_maxDeltaQ;
+ unsigned int m_nq,m_nc,m_nee;
+ e_matrix m_Wq,m_Cq;
+ e_vector m_Wy,m_ydot,m_qdot;
+ std::vector<e_matrix> m_JqArray;
+public:
+ ControlledObject();
+ virtual ~ControlledObject();
+
+ class JointLockCallback {
+ public:
+ JointLockCallback() {}
+ virtual ~JointLockCallback() {}
+
+ // lock a joint, no need to update output
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof) = 0;
+ // lock a joint and update output in view of reiteration
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double* qdot) = 0;
+ };
+
+ virtual void initialize(unsigned int _nq,unsigned int _nc, unsigned int _nee);
+
+ // returns true when a joint has been locked via the callback and the solver must run again
+ virtual bool updateJoint(const Timestamp& timestamp, JointLockCallback& callback) = 0;
+ virtual void updateControlOutput(const Timestamp& timestamp)=0;
+ virtual void setJointVelocity(const e_vector qdot_in){m_qdot = qdot_in;};
+ virtual double getMaxTimestep(double& timestep);
+ virtual bool setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, e_scalar value, double timestep=0.0)=0;
+
+ virtual const e_vector& getControlOutput() const{return m_ydot;}
+
+ virtual const e_matrix& getJq(unsigned int ee) const;
+
+ virtual const e_matrix& getCq() const{return m_Cq;};
+
+ virtual e_matrix& getWq() {return m_Wq;};
+ virtual void setWq(const e_matrix& Wq_in){m_Wq = Wq_in;};
+
+ virtual const e_vector& getWy() const {return m_Wy;};
+
+ virtual const unsigned int getNrOfCoordinates(){return m_nq;};
+ virtual const unsigned int getNrOfConstraints(){return m_nc;};
+};
+
+}
+
+#endif /* CONTROLLEDOBJECT_HPP_ */
diff --git a/intern/itasc/CopyPose.cpp b/intern/itasc/CopyPose.cpp
new file mode 100644
index 00000000000..69722909ed1
--- /dev/null
+++ b/intern/itasc/CopyPose.cpp
@@ -0,0 +1,480 @@
+/* $Id$
+ * CopyPose.cpp
+ *
+ * Created on: Mar 17, 2009
+ * Author: benoit bolsee
+ */
+
+#include "CopyPose.hpp"
+#include "kdl/kinfam_io.hpp"
+#include <math.h>
+#include <string.h>
+
+namespace iTaSC
+{
+
+const unsigned int maxPoseCacheSize = (2*(3+3*2));
+CopyPose::CopyPose(unsigned int control_output, unsigned int dynamic_output, double armlength, double accuracy, unsigned int maximum_iterations):
+ ConstraintSet(),
+ m_cache(NULL),
+ m_poseCCh(-1),m_poseCTs(0)
+{
+ m_maxerror = armlength/2.0;
+ m_outputControl = (control_output & CTL_ALL);
+ unsigned int _nc = nBitsOn(m_outputControl);
+ if (!_nc)
+ return;
+ // reset the constraint set
+ reset(_nc, accuracy, maximum_iterations);
+ _nc = 0;
+ m_nvalues = 0;
+ int nrot = 0, npos = 0;
+ int nposCache = 0, nrotCache = 0;
+ m_outputDynamic = (dynamic_output & m_outputControl);
+ memset(m_values, 0, sizeof(m_values));
+ memset(m_posData, 0, sizeof(m_posData));
+ memset(m_rotData, 0, sizeof(m_rotData));
+ memset(&m_rot, 0, sizeof(m_rot));
+ memset(&m_pos, 0, sizeof(m_pos));
+ if (m_outputControl & CTL_POSITION) {
+ m_pos.alpha = 1.0;
+ m_pos.K = 20.0;
+ m_pos.tolerance = 0.05;
+ m_values[m_nvalues].alpha = m_pos.alpha;
+ m_values[m_nvalues].feedback = m_pos.K;
+ m_values[m_nvalues].tolerance = m_pos.tolerance;
+ m_values[m_nvalues].id = ID_POSITION;
+ if (m_outputControl & CTL_POSITIONX) {
+ m_Wy(_nc) = m_pos.alpha/*/(m_pos.tolerance*m_pos.K)*/;
+ m_Cf(_nc++,0)=1.0;
+ m_posData[npos++].id = ID_POSITIONX;
+ if (m_outputDynamic & CTL_POSITIONX)
+ nposCache++;
+ }
+ if (m_outputControl & CTL_POSITIONY) {
+ m_Wy(_nc) = m_pos.alpha/*/(m_pos.tolerance*m_pos.K)*/;
+ m_Cf(_nc++,1)=1.0;
+ m_posData[npos++].id = ID_POSITIONY;
+ if (m_outputDynamic & CTL_POSITIONY)
+ nposCache++;
+ }
+ if (m_outputControl & CTL_POSITIONZ) {
+ m_Wy(_nc) = m_pos.alpha/*/(m_pos.tolerance*m_pos.K)*/;
+ m_Cf(_nc++,2)=1.0;
+ m_posData[npos++].id = ID_POSITIONZ;
+ if (m_outputDynamic & CTL_POSITIONZ)
+ nposCache++;
+ }
+ m_values[m_nvalues].number = npos;
+ m_values[m_nvalues++].values = m_posData;
+ m_pos.firsty = 0;
+ m_pos.ny = npos;
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ m_rot.alpha = 1.0;
+ m_rot.K = 20.0;
+ m_rot.tolerance = 0.05;
+ m_values[m_nvalues].alpha = m_rot.alpha;
+ m_values[m_nvalues].feedback = m_rot.K;
+ m_values[m_nvalues].tolerance = m_rot.tolerance;
+ m_values[m_nvalues].id = ID_ROTATION;
+ if (m_outputControl & CTL_ROTATIONX) {
+ m_Wy(_nc) = m_rot.alpha/*/(m_rot.tolerance*m_rot.K)*/;
+ m_Cf(_nc++,3)=1.0;
+ m_rotData[nrot++].id = ID_ROTATIONX;
+ if (m_outputDynamic & CTL_ROTATIONX)
+ nrotCache++;
+ }
+ if (m_outputControl & CTL_ROTATIONY) {
+ m_Wy(_nc) = m_rot.alpha/*/(m_rot.tolerance*m_rot.K)*/;
+ m_Cf(_nc++,4)=1.0;
+ m_rotData[nrot++].id = ID_ROTATIONY;
+ if (m_outputDynamic & CTL_ROTATIONY)
+ nrotCache++;
+ }
+ if (m_outputControl & CTL_ROTATIONZ) {
+ m_Wy(_nc) = m_rot.alpha/*/(m_rot.tolerance*m_rot.K)*/;
+ m_Cf(_nc++,5)=1.0;
+ m_rotData[nrot++].id = ID_ROTATIONZ;
+ if (m_outputDynamic & CTL_ROTATIONZ)
+ nrotCache++;
+ }
+ m_values[m_nvalues].number = nrot;
+ m_values[m_nvalues++].values = m_rotData;
+ m_rot.firsty = npos;
+ m_rot.ny = nrot;
+ }
+ assert(_nc == m_nc);
+ m_Jf=e_identity_matrix(6,6);
+ m_poseCacheSize = ((nrotCache)?(3+nrotCache*2):0)+((nposCache)?(3+nposCache*2):0);
+}
+
+CopyPose::~CopyPose()
+{
+}
+
+bool CopyPose::initialise(Frame& init_pose)
+{
+ m_externalPose = m_internalPose = init_pose;
+ updateJacobian();
+ return true;
+}
+
+void CopyPose::modelUpdate(Frame& _external_pose,const Timestamp& timestamp)
+{
+ m_internalPose = m_externalPose = _external_pose;
+ updateJacobian();
+}
+
+void CopyPose::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_poseCCh = -1;
+ if (m_cache) {
+ // create one channel for the coordinates
+ m_poseCCh = m_cache->addChannel(this, "Xf", m_poseCacheSize*sizeof(double));
+ // don't save initial value, it will be recomputed from external pose
+ //pushPose(0);
+ }
+}
+
+double* CopyPose::pushValues(double* item, ControlState* _state, unsigned int mask)
+{
+ ControlState::ControlValue* _yval;
+ int i;
+
+ *item++ = _state->alpha;
+ *item++ = _state->K;
+ *item++ = _state->tolerance;
+
+ for (i=0, _yval=_state->output; i<_state->ny; mask<<=1) {
+ if (m_outputControl & mask) {
+ if (m_outputDynamic & mask) {
+ *item++ = _yval->yd;
+ *item++ = _yval->yddot;
+ }
+ _yval++;
+ i++;
+ }
+ }
+ return item;
+}
+
+void CopyPose::pushPose(CacheTS timestamp)
+{
+ if (m_poseCCh >= 0) {
+ if (m_poseCacheSize) {
+ double buf[maxPoseCacheSize];
+ double *item = buf;
+ if (m_outputDynamic & CTL_POSITION)
+ item = pushValues(item, &m_pos, CTL_POSITIONX);
+ if (m_outputDynamic & CTL_ROTATION)
+ item = pushValues(item, &m_rot, CTL_ROTATIONX);
+ m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, buf, m_poseCacheSize, KDL::epsilon);
+ } else
+ m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, NULL, 0, KDL::epsilon);
+ m_poseCTs = timestamp;
+ }
+}
+
+double* CopyPose::restoreValues(double* item, ConstraintValues* _values, ControlState* _state, unsigned int mask)
+{
+ ConstraintSingleValue* _data;
+ ControlState::ControlValue* _yval;
+ int i, j;
+
+ _values->alpha = _state->alpha = *item++;
+ _values->feedback = _state->K = *item++;
+ _values->tolerance = _state->tolerance = *item++;
+
+ for (i=_state->firsty, j=i+_state->ny, _yval=_state->output, _data=_values->values; i<j; mask<<=1) {
+ if (m_outputControl & mask) {
+ m_Wy(i) = _state->alpha/*/(_state->tolerance*_state->K)*/;
+ if (m_outputDynamic & mask) {
+ _data->yd = _yval->yd = *item++;
+ _data->yddot = _yval->yddot = *item++;
+ }
+ _data++;
+ _yval++;
+ i++;
+ }
+ }
+ return item;
+}
+
+bool CopyPose::popPose(CacheTS timestamp)
+{
+ bool found = false;
+ if (m_poseCCh >= 0) {
+ double *item = (double*)m_cache->getPreviousCacheItem(this, m_poseCCh, &timestamp);
+ if (item) {
+ found = true;
+ if (timestamp != m_poseCTs) {
+ int i=0;
+ if (m_outputControl & CTL_POSITION) {
+ if (m_outputDynamic & CTL_POSITION) {
+ item = restoreValues(item, &m_values[i], &m_pos, CTL_POSITIONX);
+ }
+ i++;
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ if (m_outputDynamic & CTL_ROTATION) {
+ item = restoreValues(item, &m_values[i], &m_rot, CTL_ROTATIONX);
+ }
+ i++;
+ }
+ m_poseCTs = timestamp;
+ item = NULL;
+ }
+ }
+ }
+ return found;
+}
+
+void CopyPose::interpolateOutput(ControlState* _state, unsigned int mask, const Timestamp& timestamp)
+{
+ ControlState::ControlValue* _yval;
+ int i;
+
+ for (i=0, _yval=_state->output; i<_state->ny; mask <<= 1) {
+ if (m_outputControl & mask) {
+ if (m_outputDynamic & mask) {
+ if (timestamp.substep && timestamp.interpolate) {
+ _yval->yd += _yval->yddot*timestamp.realTimestep;
+ } else {
+ _yval->yd = _yval->nextyd;
+ _yval->yddot = _yval->nextyddot;
+ }
+ }
+ i++;
+ _yval++;
+ }
+ }
+}
+
+void CopyPose::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache) {
+ pushPose(timestamp.cacheTimestamp);
+ }
+}
+
+void CopyPose::updateKinematics(const Timestamp& timestamp)
+{
+ if (timestamp.interpolate) {
+ if (m_outputDynamic & CTL_POSITION)
+ interpolateOutput(&m_pos, CTL_POSITIONX, timestamp);
+ if (m_outputDynamic & CTL_ROTATION)
+ interpolateOutput(&m_rot, CTL_ROTATIONX, timestamp);
+ }
+ pushCache(timestamp);
+}
+
+void CopyPose::updateJacobian()
+{
+ //Jacobian is always identity at the start of the constraint chain
+ //instead of going through complicated jacobian operation, implemented direct formula
+ //m_Jf(1,3) = m_internalPose.p.z();
+ //m_Jf(2,3) = -m_internalPose.p.y();
+ //m_Jf(0,4) = -m_internalPose.p.z();
+ //m_Jf(2,4) = m_internalPose.p.x();
+ //m_Jf(0,5) = m_internalPose.p.y();
+ //m_Jf(1,5) = -m_internalPose.p.x();
+}
+
+void CopyPose::updateState(ConstraintValues* _values, ControlState* _state, unsigned int mask, double timestep)
+{
+ unsigned int id = (mask == CTL_ROTATIONX) ? ID_ROTATIONX : ID_POSITIONX;
+ ControlState::ControlValue* _yval;
+ ConstraintSingleValue* _data;
+ int i, j, k;
+ int action = 0;
+
+ if ((_values->action & ACT_ALPHA) && _values->alpha >= 0.0) {
+ _state->alpha = _values->alpha;
+ action |= ACT_ALPHA;
+ }
+ if ((_values->action & ACT_TOLERANCE) && _values->tolerance > KDL::epsilon) {
+ _state->tolerance = _values->tolerance;
+ action |= ACT_TOLERANCE;
+ }
+ if ((_values->action & ACT_FEEDBACK) && _values->feedback > KDL::epsilon) {
+ _state->K = _values->feedback;
+ action |= ACT_FEEDBACK;
+ }
+ for (i=_state->firsty, j=_state->firsty+_state->ny, _yval=_state->output; i<j; mask <<= 1, id++) {
+ if (m_outputControl & mask) {
+ if (action)
+ m_Wy(i) = _state->alpha/*/(_state->tolerance*_state->K)*/;
+ // check if this controlled output is provided
+ for (k=0, _data=_values->values; k<_values->number; k++, _data++) {
+ if (_data->id == id) {
+ switch (_data->action & (ACT_VALUE|ACT_VELOCITY)) {
+ case 0:
+ // no indication, keep current values
+ break;
+ case ACT_VELOCITY:
+ // only the velocity is given estimate the new value by integration
+ _data->yd = _yval->yd+_data->yddot*timestep;
+ // walkthrough
+ case ACT_VALUE:
+ _yval->nextyd = _data->yd;
+ // if the user sets the value, we assume future velocity is zero
+ // (until the user changes the value again)
+ _yval->nextyddot = (_data->action & ACT_VALUE) ? 0.0 : _data->yddot;
+ if (timestep>0.0) {
+ _yval->yddot = (_data->yd-_yval->yd)/timestep;
+ } else {
+ // allow the user to change target instantenously when this function
+ // if called from setControlParameter with timestep = 0
+ _yval->yd = _yval->nextyd;
+ _yval->yddot = _yval->nextyddot;
+ }
+ break;
+ case (ACT_VALUE|ACT_VELOCITY):
+ // the user should not set the value and velocity at the same time.
+ // In this case, we will assume that he wants to set the future value
+ // and we compute the current value to match the velocity
+ _yval->yd = _data->yd - _data->yddot*timestep;
+ _yval->nextyd = _data->yd;
+ _yval->nextyddot = _data->yddot;
+ if (timestep>0.0) {
+ _yval->yddot = (_data->yd-_yval->yd)/timestep;
+ } else {
+ _yval->yd = _yval->nextyd;
+ _yval->yddot = _yval->nextyddot;
+ }
+ break;
+ }
+ }
+ }
+ _yval++;
+ i++;
+ }
+ }
+}
+
+
+bool CopyPose::setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep)
+{
+ while (_nvalues > 0) {
+ if (_values->id >= ID_POSITION && _values->id <= ID_POSITIONZ && (m_outputControl & CTL_POSITION)) {
+ updateState(_values, &m_pos, CTL_POSITIONX, timestep);
+ }
+ if (_values->id >= ID_ROTATION && _values->id <= ID_ROTATIONZ && (m_outputControl & CTL_ROTATION)) {
+ updateState(_values, &m_rot, CTL_ROTATIONX, timestep);
+ }
+ _values++;
+ _nvalues--;
+ }
+ return true;
+}
+
+void CopyPose::updateValues(Vector& vel, ConstraintValues* _values, ControlState* _state, unsigned int mask)
+{
+ ConstraintSingleValue* _data;
+ ControlState::ControlValue* _yval;
+ int i, j;
+
+ _values->action = 0;
+
+ for (i=_state->firsty, j=0, _yval=_state->output, _data=_values->values; j<3; j++, mask<<=1) {
+ if (m_outputControl & mask) {
+ *(double*)&_data->y = vel(j);
+ *(double*)&_data->ydot = m_ydot(i);
+ _data->yd = _yval->yd;
+ _data->yddot = _yval->yddot;
+ _data->action = 0;
+ i++;
+ _data++;
+ _yval++;
+ }
+ }
+}
+
+void CopyPose::updateOutput(Vector& vel, ControlState* _state, unsigned int mask)
+{
+ ControlState::ControlValue* _yval;
+ int i, j;
+ double coef=1.0;
+ if (mask & CTL_POSITION) {
+ // put a limit on position error
+ double len=0.0;
+ for (j=0, _yval=_state->output; j<3; j++) {
+ if (m_outputControl & (mask<<j)) {
+ len += KDL::sqr(_yval->yd-vel(j));
+ _yval++;
+ }
+ }
+ len = KDL::sqrt(len);
+ if (len > m_maxerror)
+ coef = m_maxerror/len;
+ }
+ for (i=_state->firsty, j=0, _yval=_state->output; j<3; j++) {
+ if (m_outputControl & (mask<<j)) {
+ m_ydot(i)=_yval->yddot+_state->K*coef*(_yval->yd-vel(j));
+ _yval++;
+ i++;
+ }
+ }
+}
+
+void CopyPose::updateControlOutput(const Timestamp& timestamp)
+{
+ //IMO this should be done, no idea if it is enough (wrt Distance impl)
+ Twist y = diff(F_identity, m_internalPose);
+ bool found = true;
+ if (!timestamp.substep) {
+ if (!timestamp.reiterate) {
+ found = popPose(timestamp.cacheTimestamp);
+ }
+ }
+ if (m_constraintCallback && (m_substep || (!timestamp.reiterate && !timestamp.substep))) {
+ // initialize first callback the application to get the current values
+ int i=0;
+ if (m_outputControl & CTL_POSITION) {
+ updateValues(y.vel, &m_values[i++], &m_pos, CTL_POSITIONX);
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ updateValues(y.rot, &m_values[i++], &m_rot, CTL_ROTATIONX);
+ }
+ if ((*m_constraintCallback)(timestamp, m_values, m_nvalues, m_constraintParam)) {
+ setControlParameters(m_values, m_nvalues, (found && timestamp.interpolate)?timestamp.realTimestep:0.0);
+ }
+ }
+ if (m_outputControl & CTL_POSITION) {
+ updateOutput(y.vel, &m_pos, CTL_POSITIONX);
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ updateOutput(y.rot, &m_rot, CTL_ROTATIONX);
+ }
+}
+
+const ConstraintValues* CopyPose::getControlParameters(unsigned int* _nvalues)
+{
+ Twist y = diff(m_internalPose,F_identity);
+ int i=0;
+ if (m_outputControl & CTL_POSITION) {
+ updateValues(y.vel, &m_values[i++], &m_pos, CTL_POSITIONX);
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ updateValues(y.rot, &m_values[i++], &m_rot, CTL_ROTATIONX);
+ }
+ if (_nvalues)
+ *_nvalues=m_nvalues;
+ return m_values;
+}
+
+double CopyPose::getMaxTimestep(double& timestep)
+{
+ // CopyPose should not have any limit on linear velocity:
+ // in case the target is out of reach, this can be very high.
+ // We will simply limit on rotation
+ e_scalar maxChidot = m_chidot.block(3,0,3,1).cwise().abs().maxCoeff();
+ if (timestep*maxChidot > m_maxDeltaChi) {
+ timestep = m_maxDeltaChi/maxChidot;
+ }
+ return timestep;
+}
+
+}
diff --git a/intern/itasc/CopyPose.hpp b/intern/itasc/CopyPose.hpp
new file mode 100644
index 00000000000..3a3f60a9f37
--- /dev/null
+++ b/intern/itasc/CopyPose.hpp
@@ -0,0 +1,99 @@
+/* $Id: CopyPose.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * CopyPose.h
+ *
+ * Created on: Mar 17, 2009
+ * Author: benoit bolsee
+ */
+
+#ifndef COPYPOSE_H_
+#define COPYPOSE_H_
+
+#include "ConstraintSet.hpp"
+namespace iTaSC{
+
+using namespace KDL;
+
+class CopyPose: public iTaSC::ConstraintSet
+{
+protected:
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void updateJacobian();
+ virtual bool initialise(Frame& init_pose);
+ virtual void initCache(Cache *_cache);
+ virtual void updateControlOutput(const Timestamp& timestamp);
+ virtual void modelUpdate(Frame& _external_pose,const Timestamp& timestamp);
+ virtual double getMaxTimestep(double& timestep);
+
+public:
+ enum ID { // constraint ID in callback and setControlParameter
+ ID_POSITION=0,
+ ID_POSITIONX=1,
+ ID_POSITIONY=2,
+ ID_POSITIONZ=3,
+ ID_ROTATION=4,
+ ID_ROTATIONX=5,
+ ID_ROTATIONY=6,
+ ID_ROTATIONZ=7,
+ };
+ enum CTL { // control ID in constructor to specify which output is constrainted
+ CTL_NONE=0x00,
+ CTL_POSITIONX=0x01, // the bit order is important: it matches the y output order
+ CTL_POSITIONY=0x02,
+ CTL_POSITIONZ=0x04,
+ CTL_POSITION=0x07,
+ CTL_ROTATIONX=0x08,
+ CTL_ROTATIONY=0x10,
+ CTL_ROTATIONZ=0x20,
+ CTL_ROTATION=0x38,
+ CTL_ALL=0x3F,
+ };
+
+ // use a combination of CTL_.. in control_output to specify which
+ CopyPose(unsigned int control_output=CTL_ALL, unsigned int dynamic_output=CTL_NONE, double armlength=1.0, double accuracy=1e-6, unsigned int maximum_iterations=100);
+ virtual ~CopyPose();
+
+ virtual bool setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep);
+ virtual const ConstraintValues* getControlParameters(unsigned int* _nvalues);
+
+private:
+ struct ConstraintSingleValue m_posData[3]; // index = controlled output in X,Y,Z order
+ struct ConstraintSingleValue m_rotData[3];
+ struct ConstraintValues m_values[2]; // index = group of controlled output, in position, rotation order
+ Cache* m_cache;
+ int m_poseCCh;
+ CacheTS m_poseCTs;
+ unsigned int m_poseCacheSize;
+ unsigned int m_outputDynamic; // combination of CTL_... determine which variables are dynamically controlled by the application
+ unsigned int m_outputControl; // combination of CTL_... determine which output are constrained
+ unsigned int m_nvalues; // number of elements used in m_values[]
+ double m_maxerror;
+
+ struct ControlState {
+ int firsty; // first y index
+ int ny; // number of y in output
+ double alpha;
+ double K;
+ double tolerance;
+ struct ControlValue {
+ double yddot;
+ double yd;
+ double nextyd;
+ double nextyddot;
+ } output[3]; // inded numbex = same as m_rotData
+ } m_rot, m_pos;
+
+ void pushPose(CacheTS timestamp);
+ bool popPose(CacheTS timestamp);
+ int nBitsOn(unsigned int v)
+ { int n=0; while(v) { if (v&1) n++; v>>=1; } return n; }
+ double* restoreValues(double* item, ConstraintValues* _values, ControlState* _state, unsigned int mask);
+ double* pushValues(double* item, ControlState* _state, unsigned int mask);
+ void updateState(ConstraintValues* _values, ControlState* _state, unsigned int mask, double timestep);
+ void updateValues(Vector& vel, ConstraintValues* _values, ControlState* _state, unsigned int mask);
+ void updateOutput(Vector& vel, ControlState* _state, unsigned int mask);
+ void interpolateOutput(ControlState* _state, unsigned int mask, const Timestamp& timestamp);
+
+};
+}
+#endif /* COPYROTATION_H_ */
diff --git a/intern/itasc/Distance.cpp b/intern/itasc/Distance.cpp
new file mode 100644
index 00000000000..bf19a978888
--- /dev/null
+++ b/intern/itasc/Distance.cpp
@@ -0,0 +1,321 @@
+/* $Id$
+ * Distance.cpp
+ *
+ * Created on: Jan 30, 2009
+ * Author: rsmits
+ */
+
+#include "Distance.hpp"
+#include "kdl/kinfam_io.hpp"
+#include <math.h>
+#include <string.h>
+
+namespace iTaSC
+{
+// a distance constraint is characterized by 5 values: alpha, tolerance, K, yd, yddot
+static const unsigned int distanceCacheSize = sizeof(double)*5 + sizeof(e_scalar)*6;
+
+Distance::Distance(double armlength, double accuracy, unsigned int maximum_iterations):
+ ConstraintSet(1,accuracy,maximum_iterations),
+ m_chiKdl(6),m_jac(6),m_cache(NULL),
+ m_distCCh(-1),m_distCTs(0)
+{
+ m_chain.addSegment(Segment(Joint(Joint::RotZ)));
+ m_chain.addSegment(Segment(Joint(Joint::RotX)));
+ m_chain.addSegment(Segment(Joint(Joint::TransY)));
+ m_chain.addSegment(Segment(Joint(Joint::RotZ)));
+ m_chain.addSegment(Segment(Joint(Joint::RotY)));
+ m_chain.addSegment(Segment(Joint(Joint::RotX)));
+
+ m_fksolver = new KDL::ChainFkSolverPos_recursive(m_chain);
+ m_jacsolver = new KDL::ChainJntToJacSolver(m_chain);
+ m_Cf(0,2)=1.0;
+ m_alpha = 1.0;
+ m_tolerance = 0.05;
+ m_maxerror = armlength/2.0;
+ m_K = 20.0;
+ m_Wy(0) = m_alpha/*/(m_tolerance*m_K)*/;
+ m_yddot = m_nextyddot = 0.0;
+ m_yd = m_nextyd = KDL::epsilon;
+ memset(&m_data, 0, sizeof(m_data));
+ // initialize the data with normally fixed values
+ m_data.id = ID_DISTANCE;
+ m_values.id = ID_DISTANCE;
+ m_values.number = 1;
+ m_values.alpha = m_alpha;
+ m_values.feedback = m_K;
+ m_values.tolerance = m_tolerance;
+ m_values.values = &m_data;
+}
+
+Distance::~Distance()
+{
+ delete m_fksolver;
+ delete m_jacsolver;
+}
+
+bool Distance::computeChi(Frame& pose)
+{
+ double dist, alpha, beta, gamma;
+ dist = pose.p.Norm();
+ Rotation basis;
+ if (dist < KDL::epsilon) {
+ // distance is almost 0, no need for initial rotation
+ m_chi(0) = 0.0;
+ m_chi(1) = 0.0;
+ } else {
+ // find the XZ angles that bring the Y axis to point to init_pose.p
+ Vector axis(pose.p/dist);
+ beta = 0.0;
+ if (fabs(axis(2)) > 1-KDL::epsilon) {
+ // direction is aligned on Z axis, just rotation on X
+ alpha = 0.0;
+ gamma = KDL::sign(axis(2))*KDL::PI/2;
+ } else {
+ alpha = -KDL::atan2(axis(0), axis(1));
+ gamma = KDL::atan2(axis(2), KDL::sqrt(KDL::sqr(axis(0))+KDL::sqr(axis(1))));
+ }
+ // rotation after first 2 joints
+ basis = Rotation::EulerZYX(alpha, beta, gamma);
+ m_chi(0) = alpha;
+ m_chi(1) = gamma;
+ }
+ m_chi(2) = dist;
+ basis = basis.Inverse()*pose.M;
+ basis.GetEulerZYX(alpha, beta, gamma);
+ // alpha = rotation on Z
+ // beta = rotation on Y
+ // gamma = rotation on X in that order
+ // it corresponds to the joint order, so just assign
+ m_chi(3) = alpha;
+ m_chi(4) = beta;
+ m_chi(5) = gamma;
+ return true;
+}
+
+bool Distance::initialise(Frame& init_pose)
+{
+ // we will initialize m_chi to values that match the pose
+ m_externalPose=init_pose;
+ computeChi(m_externalPose);
+ // get current Jf and update internal pose
+ updateJacobian();
+ return true;
+}
+
+bool Distance::closeLoop()
+{
+ if (!Equal(m_internalPose.Inverse()*m_externalPose,F_identity,m_threshold)){
+ computeChi(m_externalPose);
+ updateJacobian();
+ }
+ return true;
+}
+
+void Distance::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_distCCh = -1;
+ if (m_cache) {
+ // create one channel for the coordinates
+ m_distCCh = m_cache->addChannel(this, "Xf", distanceCacheSize);
+ // save initial constraint in cache position 0
+ pushDist(0);
+ }
+}
+
+void Distance::pushDist(CacheTS timestamp)
+{
+ if (m_distCCh >= 0) {
+ double *item = (double*)m_cache->addCacheItem(this, m_distCCh, timestamp, NULL, distanceCacheSize);
+ if (item) {
+ *item++ = m_K;
+ *item++ = m_tolerance;
+ *item++ = m_yd;
+ *item++ = m_yddot;
+ *item++ = m_alpha;
+ memcpy(item, &m_chi[0], 6*sizeof(e_scalar));
+ }
+ m_distCTs = timestamp;
+ }
+}
+
+bool Distance::popDist(CacheTS timestamp)
+{
+ if (m_distCCh >= 0) {
+ double *item = (double*)m_cache->getPreviousCacheItem(this, m_distCCh, &timestamp);
+ if (item && timestamp != m_distCTs) {
+ m_values.feedback = m_K = *item++;
+ m_values.tolerance = m_tolerance = *item++;
+ m_yd = *item++;
+ m_yddot = *item++;
+ m_values.alpha = m_alpha = *item++;
+ memcpy(&m_chi[0], item, 6*sizeof(e_scalar));
+ m_distCTs = timestamp;
+ m_Wy(0) = m_alpha/*/(m_tolerance*m_K)*/;
+ updateJacobian();
+ }
+ return (item) ? true : false;
+ }
+ return true;
+}
+
+void Distance::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache)
+ pushDist(timestamp.cacheTimestamp);
+}
+
+void Distance::updateKinematics(const Timestamp& timestamp)
+{
+ if (timestamp.interpolate) {
+ //the internal pose and Jf is already up to date (see model_update)
+ //update the desired output based on yddot
+ if (timestamp.substep) {
+ m_yd += m_yddot*timestamp.realTimestep;
+ if (m_yd < KDL::epsilon)
+ m_yd = KDL::epsilon;
+ } else {
+ m_yd = m_nextyd;
+ m_yddot = m_nextyddot;
+ }
+ }
+ pushCache(timestamp);
+}
+
+void Distance::updateJacobian()
+{
+ for(unsigned int i=0;i<6;i++)
+ m_chiKdl(i)=m_chi(i);
+
+ m_fksolver->JntToCart(m_chiKdl,m_internalPose);
+ m_jacsolver->JntToJac(m_chiKdl,m_jac);
+ changeRefPoint(m_jac,-m_internalPose.p,m_jac);
+ for(unsigned int i=0;i<6;i++)
+ for(unsigned int j=0;j<6;j++)
+ m_Jf(i,j)=m_jac(i,j);
+}
+
+bool Distance::setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep)
+{
+ int action = 0;
+ int i;
+ ConstraintSingleValue* _data;
+
+ while (_nvalues > 0) {
+ if (_values->id == ID_DISTANCE) {
+ if ((_values->action & ACT_ALPHA) && _values->alpha >= 0.0) {
+ m_alpha = _values->alpha;
+ action |= ACT_ALPHA;
+ }
+ if ((_values->action & ACT_TOLERANCE) && _values->tolerance > KDL::epsilon) {
+ m_tolerance = _values->tolerance;
+ action |= ACT_TOLERANCE;
+ }
+ if ((_values->action & ACT_FEEDBACK) && _values->feedback > KDL::epsilon) {
+ m_K = _values->feedback;
+ action |= ACT_FEEDBACK;
+ }
+ for (_data = _values->values, i=0; i<_values->number; i++, _data++) {
+ if (_data->id == ID_DISTANCE) {
+ switch (_data->action & (ACT_VALUE|ACT_VELOCITY)) {
+ case 0:
+ // no indication, keep current values
+ break;
+ case ACT_VELOCITY:
+ // only the velocity is given estimate the new value by integration
+ _data->yd = m_yd+_data->yddot*timestep;
+ // walkthrough for negative value correction
+ case ACT_VALUE:
+ // only the value is given, estimate the velocity from previous value
+ if (_data->yd < KDL::epsilon)
+ _data->yd = KDL::epsilon;
+ m_nextyd = _data->yd;
+ // if the user sets the value, we assume future velocity is zero
+ // (until the user changes the value again)
+ m_nextyddot = (_data->action & ACT_VALUE) ? 0.0 : _data->yddot;
+ if (timestep>0.0) {
+ m_yddot = (_data->yd-m_yd)/timestep;
+ } else {
+ // allow the user to change target instantenously when this function
+ // if called from setControlParameter with timestep = 0
+ m_yddot = m_nextyddot;
+ m_yd = m_nextyd;
+ }
+ break;
+ case (ACT_VALUE|ACT_VELOCITY):
+ // the user should not set the value and velocity at the same time.
+ // In this case, we will assume that he want to set the future value
+ // and we compute the current value to match the velocity
+ if (_data->yd < KDL::epsilon)
+ _data->yd = KDL::epsilon;
+ m_yd = _data->yd - _data->yddot*timestep;
+ if (m_yd < KDL::epsilon)
+ m_yd = KDL::epsilon;
+ m_nextyd = _data->yd;
+ m_nextyddot = _data->yddot;
+ if (timestep>0.0) {
+ m_yddot = (_data->yd-m_yd)/timestep;
+ } else {
+ m_yd = m_nextyd;
+ m_yddot = m_nextyddot;
+ }
+ break;
+ }
+ }
+ }
+ }
+ _nvalues--;
+ _values++;
+ }
+ if (action & (ACT_TOLERANCE|ACT_FEEDBACK|ACT_ALPHA)) {
+ // recompute the weight
+ m_Wy(0) = m_alpha/*/(m_tolerance*m_K)*/;
+ }
+ return true;
+}
+
+const ConstraintValues* Distance::getControlParameters(unsigned int* _nvalues)
+{
+ *(double*)&m_data.y = m_chi(2);
+ *(double*)&m_data.ydot = m_ydot(0);
+ m_data.yd = m_yd;
+ m_data.yddot = m_yddot;
+ m_data.action = 0;
+ m_values.action = 0;
+ if (_nvalues)
+ *_nvalues=1;
+ return &m_values;
+}
+
+void Distance::updateControlOutput(const Timestamp& timestamp)
+{
+ bool cacheAvail = true;
+ if (!timestamp.substep) {
+ if (!timestamp.reiterate)
+ cacheAvail = popDist(timestamp.cacheTimestamp);
+ }
+ if (m_constraintCallback && (m_substep || (!timestamp.reiterate && !timestamp.substep))) {
+ // initialize first callback the application to get the current values
+ *(double*)&m_data.y = m_chi(2);
+ *(double*)&m_data.ydot = m_ydot(0);
+ m_data.yd = m_yd;
+ m_data.yddot = m_yddot;
+ m_data.action = 0;
+ m_values.action = 0;
+ if ((*m_constraintCallback)(timestamp, &m_values, 1, m_constraintParam)) {
+ setControlParameters(&m_values, 1, timestamp.realTimestep);
+ }
+ }
+ if (!cacheAvail || !timestamp.interpolate) {
+ // first position in cache: set the desired output immediately as we cannot interpolate
+ m_yd = m_nextyd;
+ m_yddot = m_nextyddot;
+ }
+ double error = m_yd-m_chi(2);
+ if (KDL::Norm(error) > m_maxerror)
+ error = KDL::sign(error)*m_maxerror;
+ m_ydot(0)=m_yddot+m_K*error;
+}
+
+}
diff --git a/intern/itasc/Distance.hpp b/intern/itasc/Distance.hpp
new file mode 100644
index 00000000000..1366693743e
--- /dev/null
+++ b/intern/itasc/Distance.hpp
@@ -0,0 +1,62 @@
+/* $Id: Distance.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * Distance.hpp
+ *
+ * Created on: Jan 30, 2009
+ * Author: rsmits
+ */
+
+#ifndef DISTANCE_HPP_
+#define DISTANCE_HPP_
+
+#include "ConstraintSet.hpp"
+#include "kdl/chain.hpp"
+#include "kdl/chainfksolverpos_recursive.hpp"
+#include "kdl/chainjnttojacsolver.hpp"
+
+namespace iTaSC
+{
+
+class Distance: public iTaSC::ConstraintSet
+{
+protected:
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void updateJacobian();
+ virtual bool initialise(Frame& init_pose);
+ virtual void initCache(Cache *_cache);
+ virtual void updateControlOutput(const Timestamp& timestamp);
+ virtual bool closeLoop();
+
+public:
+ enum ID {
+ ID_DISTANCE=1,
+ };
+ Distance(double armlength=1.0, double accuracy=1e-6, unsigned int maximum_iterations=100);
+ virtual ~Distance();
+
+ virtual bool setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep);
+ virtual const ConstraintValues* getControlParameters(unsigned int* _nvalues);
+
+private:
+ bool computeChi(Frame& pose);
+ KDL::Chain m_chain;
+ KDL::ChainFkSolverPos_recursive* m_fksolver;
+ KDL::ChainJntToJacSolver* m_jacsolver;
+ KDL::JntArray m_chiKdl;
+ KDL::Jacobian m_jac;
+ struct ConstraintSingleValue m_data;
+ struct ConstraintValues m_values;
+ Cache* m_cache;
+ int m_distCCh;
+ CacheTS m_distCTs;
+ double m_maxerror;
+
+ void pushDist(CacheTS timestamp);
+ bool popDist(CacheTS timestamp);
+
+ double m_alpha,m_yddot,m_yd,m_nextyd,m_nextyddot,m_K,m_tolerance;
+};
+
+}
+
+#endif /* DISTANCE_HPP_ */
diff --git a/intern/itasc/FixedObject.cpp b/intern/itasc/FixedObject.cpp
new file mode 100644
index 00000000000..fad77d4825e
--- /dev/null
+++ b/intern/itasc/FixedObject.cpp
@@ -0,0 +1,70 @@
+/* $Id$
+ * FixedObject.cpp
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#include "FixedObject.hpp"
+
+namespace iTaSC{
+
+
+FixedObject::FixedObject():UncontrolledObject(),
+ m_finalized(false), m_nframe(0)
+{
+}
+
+FixedObject::~FixedObject()
+{
+ m_frameArray.clear();
+}
+
+int FixedObject::addFrame(const std::string& name, const Frame& frame)
+{
+ if (m_finalized)
+ return -1;
+ FrameList::iterator it;
+ unsigned int i;
+ for (i=0, it=m_frameArray.begin(); i<m_nframe; i++, it++) {
+ if (it->first == name) {
+ // this frame will replace the old frame
+ it->second = frame;
+ return i;
+ }
+ }
+ m_frameArray.push_back(FrameList::value_type(name,frame));
+ return m_nframe++;
+}
+
+int FixedObject::addEndEffector(const std::string& name)
+{
+ // verify that this frame name exist
+ FrameList::iterator it;
+ unsigned int i;
+ for (i=0, it=m_frameArray.begin(); i<m_nframe; i++, it++) {
+ if (it->first == name) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void FixedObject::finalize()
+{
+ if (m_finalized)
+ return;
+ initialize(0, m_nframe);
+ m_finalized = true;
+}
+
+const Frame& FixedObject::getPose(const unsigned int frameIndex)
+{
+ if (frameIndex < m_nframe) {
+ return m_frameArray[frameIndex].second;
+ } else {
+ return F_identity;
+ }
+}
+
+}
diff --git a/intern/itasc/FixedObject.hpp b/intern/itasc/FixedObject.hpp
new file mode 100644
index 00000000000..01ab3355259
--- /dev/null
+++ b/intern/itasc/FixedObject.hpp
@@ -0,0 +1,45 @@
+/* $Id: FixedObject.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * FixedObject.h
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef FIXEDOBJECT_HPP_
+#define FIXEDOBJECT_HPP_
+
+#include "UncontrolledObject.hpp"
+#include <vector>
+
+
+namespace iTaSC{
+
+class FixedObject: public UncontrolledObject {
+public:
+ FixedObject();
+ virtual ~FixedObject();
+
+ int addFrame(const std::string& name, const Frame& frame);
+
+ virtual void updateCoordinates(const Timestamp& timestamp) {};
+ virtual int addEndEffector(const std::string& name);
+ virtual void finalize();
+ virtual const Frame& getPose(const unsigned int frameIndex);
+ virtual void updateKinematics(const Timestamp& timestamp) {};
+ virtual void pushCache(const Timestamp& timestamp) {};
+ virtual void initCache(Cache *_cache) {};
+
+protected:
+ virtual void updateJacobian() {}
+private:
+ typedef std::vector<std::pair<std::string, Frame> > FrameList;
+
+ bool m_finalized;
+ unsigned int m_nframe;
+ FrameList m_frameArray;
+
+};
+
+}
+
+#endif /* FIXEDOBJECT_H_ */
diff --git a/intern/itasc/Makefile b/intern/itasc/Makefile
new file mode 100644
index 00000000000..2be46a017df
--- /dev/null
+++ b/intern/itasc/Makefile
@@ -0,0 +1,53 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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): Hans Lambermont
+#
+# ***** END GPL LICENSE BLOCK *****
+# iksolver main makefile.
+#
+
+include nan_definitions.mk
+
+LIBNAME = itasc
+SOURCEDIR = intern/$(LIBNAME)
+DIR = $(OCGDIR)/$(SOURCEDIR)
+DIRS = kdl
+include nan_subdirs.mk
+include nan_compile.mk
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../../extern/Eigen2
+
+install: $(ALL_OR_DEBUG)
+ @[ -d $(NAN_ITASC) ] || mkdir $(NAN_ITASC)
+ @[ -d $(NAN_ITASC)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_ITASC)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libitasc.a $(DIR)/$(DEBUG_DIR)libitasc_kdl.a $(DIR)/$(DEBUG_DIR)libitasc_kdl_util.a $(NAN_ITASC)/lib/$(DEBUG_DIR)
+ifeq ($(OS),darwin)
+ ranlib $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a
+ ranlib $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl.a
+ ranlib $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl_util.a
+endif
+##############################
+include nan_subdirs.mk
diff --git a/intern/itasc/MovingFrame.cpp b/intern/itasc/MovingFrame.cpp
new file mode 100644
index 00000000000..e923b1fab27
--- /dev/null
+++ b/intern/itasc/MovingFrame.cpp
@@ -0,0 +1,156 @@
+/* $Id$
+ * MovingFrame.cpp
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#include "MovingFrame.hpp"
+#include <string.h>
+namespace iTaSC{
+
+static const unsigned int frameCacheSize = (sizeof(((Frame*)0)->p.data)+sizeof(((Frame*)0)->M.data))/sizeof(double);
+
+MovingFrame::MovingFrame(const Frame& frame):UncontrolledObject(),
+ m_function(NULL), m_param(NULL), m_velocity(), m_poseCCh(-1), m_poseCTs(0)
+{
+ m_internalPose = m_nextPose = frame;
+ initialize(6, 1);
+ e_matrix& Ju = m_JuArray[0];
+ Ju = e_identity_matrix(6,6);
+}
+
+MovingFrame::~MovingFrame()
+{
+}
+
+void MovingFrame::finalize()
+{
+ updateJacobian();
+}
+
+void MovingFrame::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_poseCCh = -1;
+ if (m_cache) {
+ m_poseCCh = m_cache->addChannel(this,"pose",frameCacheSize*sizeof(double));
+ // don't store the initial pose, it's causing unnecessary large velocity on the first step
+ //pushInternalFrame(0);
+ }
+}
+
+void MovingFrame::pushInternalFrame(CacheTS timestamp)
+{
+ if (m_poseCCh >= 0) {
+ double buf[frameCacheSize];
+ memcpy(buf, m_internalPose.p.data, sizeof(m_internalPose.p.data));
+ memcpy(&buf[sizeof(m_internalPose.p.data)/sizeof(double)], m_internalPose.M.data, sizeof(m_internalPose.M.data));
+
+ m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, buf, frameCacheSize, KDL::epsilon);
+ m_poseCTs = timestamp;
+ }
+}
+
+// load pose just preceeding timestamp
+// return false if no cache position was found
+bool MovingFrame::popInternalFrame(CacheTS timestamp)
+{
+ if (m_poseCCh >= 0) {
+ char *item;
+ item = (char *)m_cache->getPreviousCacheItem(this, m_poseCCh, &timestamp);
+ if (item && m_poseCTs != timestamp) {
+ memcpy(m_internalPose.p.data, item, sizeof(m_internalPose.p.data));
+ item += sizeof(m_internalPose.p.data);
+ memcpy(m_internalPose.M.data, item, sizeof(m_internalPose.M.data));
+ m_poseCTs = timestamp;
+ // changing the starting pose, recompute the jacobian
+ updateJacobian();
+ }
+ return (item) ? true : false;
+ }
+ // in case of no cache, there is always a previous position
+ return true;
+}
+
+bool MovingFrame::setFrame(const Frame& frame)
+{
+ m_internalPose = m_nextPose = frame;
+ return true;
+}
+
+bool MovingFrame::setCallback(MovingFrameCallback _function, void* _param)
+{
+ m_function = _function;
+ m_param = _param;
+ return true;
+}
+
+void MovingFrame::updateCoordinates(const Timestamp& timestamp)
+{
+ // don't compute the velocity during substepping, it is assumed constant.
+ if (!timestamp.substep) {
+ bool cacheAvail = true;
+ if (!timestamp.reiterate) {
+ cacheAvail = popInternalFrame(timestamp.cacheTimestamp);
+ if (m_function)
+ (*m_function)(timestamp, m_internalPose, m_nextPose, m_param);
+ }
+ // only compute velocity if we have a previous pose
+ if (cacheAvail && timestamp.interpolate) {
+ unsigned int iXu;
+ m_velocity = diff(m_internalPose, m_nextPose, timestamp.realTimestep);
+ for (iXu=0; iXu<6; iXu++)
+ m_xudot(iXu) = m_velocity(iXu);
+ } else if (!timestamp.reiterate) {
+ // new position is forced, no velocity as we cannot interpolate
+ m_internalPose = m_nextPose;
+ m_velocity = Twist::Zero();
+ m_xudot = e_zero_vector(6);
+ // recompute the jacobian
+ updateJacobian();
+ }
+ }
+}
+
+void MovingFrame::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache)
+ pushInternalFrame(timestamp.cacheTimestamp);
+}
+
+void MovingFrame::updateKinematics(const Timestamp& timestamp)
+{
+ if (timestamp.interpolate) {
+ if (timestamp.substep) {
+ // during substepping, update the internal pose from velocity information
+ Twist localvel = m_internalPose.M.Inverse(m_velocity);
+ m_internalPose.Integrate(localvel, 1.0/timestamp.realTimestep);
+ } else {
+ m_internalPose = m_nextPose;
+ }
+ // m_internalPose is updated, recompute the jacobian
+ updateJacobian();
+ }
+ pushCache(timestamp);
+}
+
+void MovingFrame::updateJacobian()
+{
+ Twist m_jac;
+ e_matrix& Ju = m_JuArray[0];
+
+ //Jacobian is always identity at position on the object,
+ //we ust change the reference to the world.
+ //instead of going through complicated jacobian operation, implemented direct formula
+ Ju(1,3) = m_internalPose.p.z();
+ Ju(2,3) = -m_internalPose.p.y();
+ Ju(0,4) = -m_internalPose.p.z();
+ Ju(2,4) = m_internalPose.p.x();
+ Ju(0,5) = m_internalPose.p.y();
+ Ju(1,5) = -m_internalPose.p.x();
+ // remember that this object has moved
+ m_updated = true;
+}
+
+}
diff --git a/intern/itasc/MovingFrame.hpp b/intern/itasc/MovingFrame.hpp
new file mode 100644
index 00000000000..edaa3136a13
--- /dev/null
+++ b/intern/itasc/MovingFrame.hpp
@@ -0,0 +1,48 @@
+/* $Id: MovingFrame.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * MovingFrame.h
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef MOVINGFRAME_HPP_
+#define MOVINGFRAME_HPP_
+
+#include "UncontrolledObject.hpp"
+#include <vector>
+
+
+namespace iTaSC{
+
+typedef bool (*MovingFrameCallback)(const Timestamp& timestamp, const Frame& _current, Frame& _next, void *param);
+
+class MovingFrame: public UncontrolledObject {
+public:
+ MovingFrame(const Frame& frame=F_identity);
+ virtual ~MovingFrame();
+
+ bool setFrame(const Frame& frame);
+ bool setCallback(MovingFrameCallback _function, void* _param);
+
+ virtual void updateCoordinates(const Timestamp& timestamp);
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void initCache(Cache *_cache);
+ virtual void finalize();
+protected:
+ virtual void updateJacobian();
+
+private:
+ void pushInternalFrame(CacheTS timestamp);
+ bool popInternalFrame(CacheTS timestamp);
+ MovingFrameCallback m_function;
+ void* m_param;
+ Frame m_nextPose;
+ Twist m_velocity;
+ int m_poseCCh; // cache channel for pose
+ unsigned int m_poseCTs;
+};
+
+}
+
+#endif /* MOVINGFRAME_H_ */
diff --git a/intern/itasc/Object.hpp b/intern/itasc/Object.hpp
new file mode 100644
index 00000000000..5c312cab768
--- /dev/null
+++ b/intern/itasc/Object.hpp
@@ -0,0 +1,48 @@
+/* $Id: Object.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * Object.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef OBJECT_HPP_
+#define OBJECT_HPP_
+
+#include "Cache.hpp"
+#include "kdl/frames.hpp"
+#include <string>
+
+namespace iTaSC{
+
+class WorldObject;
+
+class Object {
+public:
+ enum ObjectType {Controlled, UnControlled};
+ static WorldObject world;
+
+private:
+ ObjectType m_type;
+protected:
+ Cache *m_cache;
+ KDL::Frame m_internalPose;
+ bool m_updated;
+ virtual void updateJacobian()=0;
+public:
+ Object(ObjectType _type):m_type(_type), m_cache(NULL), m_internalPose(F_identity), m_updated(false) {};
+ virtual ~Object(){};
+
+ virtual int addEndEffector(const std::string& name){return 0;};
+ virtual void finalize(){};
+ virtual const KDL::Frame& getPose(const unsigned int end_effector=0){return m_internalPose;};
+ virtual const ObjectType getType(){return m_type;};
+ virtual const unsigned int getNrOfCoordinates(){return 0;};
+ virtual void updateKinematics(const Timestamp& timestamp)=0;
+ virtual void pushCache(const Timestamp& timestamp)=0;
+ virtual void initCache(Cache *_cache) = 0;
+ bool updated() {return m_updated;};
+ void updated(bool val) {m_updated=val;};
+};
+
+}
+#endif /* OBJECT_HPP_ */
diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript
new file mode 100644
index 00000000000..9e11b6c7119
--- /dev/null
+++ b/intern/itasc/SConscript
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('*.cpp')
+sources += env.Glob('kdl/*.cpp')
+sources += env.Glob('kdl/utilities/*.cpp')
+
+incs = '. ../../extern/Eigen2'
+
+env.BlenderLib ('bf_ITASC', sources, Split(incs), [], libtype=['intern','player'], priority=[20,100] )
+
diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp
new file mode 100644
index 00000000000..8aa423584f1
--- /dev/null
+++ b/intern/itasc/Scene.cpp
@@ -0,0 +1,543 @@
+/* $Id$
+ * Scene.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "Scene.hpp"
+#include "ControlledObject.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+#include <cstdio>
+
+namespace iTaSC {
+
+class SceneLock : public ControlledObject::JointLockCallback {
+private:
+ Scene* m_scene;
+ Range m_qrange;
+
+public:
+ SceneLock(Scene* scene) :
+ m_scene(scene), m_qrange(0,0) {}
+ virtual ~SceneLock() {}
+
+ void setRange(Range& range)
+ {
+ m_qrange = range;
+ }
+ // lock a joint, no need to update output
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof)
+ {
+ q_nr += m_qrange.start;
+ project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
+ }
+ // lock a joint and update output in view of reiteration
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double* qdot)
+ {
+ q_nr += m_qrange.start;
+ project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
+ // update the ouput vector so that the movement of this joint will be
+ // taken into account and we can put the joint back in its initial position
+ // which means that the jacobian doesn't need to be changed
+ for (unsigned int i=0 ;i<ndof ; ++i, ++q_nr) {
+ m_scene->m_ydot -= m_scene->m_A.col(q_nr)*qdot[i];
+ }
+ }
+};
+
+Scene::Scene():
+ m_A(), m_B(), m_Atemp(), m_Wq(), m_Jf(), m_Jq(), m_Ju(), m_Cf(), m_Cq(), m_Jf_inv(),
+ m_Vf(),m_Uf(), m_Wy(), m_ydot(), m_qdot(), m_xdot(), m_Sf(),m_tempf(),
+ m_ncTotal(0),m_nqTotal(0),m_nuTotal(0),m_nsets(0),
+ m_solver(NULL),m_cache(NULL)
+{
+ m_minstep = 0.01;
+ m_maxstep = 0.06;
+}
+
+Scene::~Scene()
+{
+ ConstraintMap::iterator constraint_it;
+ while ((constraint_it = constraints.begin()) != constraints.end()) {
+ delete constraint_it->second;
+ constraints.erase(constraint_it);
+ }
+ ObjectMap::iterator object_it;
+ while ((object_it = objects.begin()) != objects.end()) {
+ delete object_it->second;
+ objects.erase(object_it);
+ }
+}
+
+bool Scene::setParam(SceneParam paramId, double value)
+{
+ switch (paramId) {
+ case MIN_TIMESTEP:
+ m_minstep = value;
+ break;
+ case MAX_TIMESTEP:
+ m_maxstep = value;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool Scene::addObject(const std::string& name, Object* object, UncontrolledObject* base, const std::string& baseFrame)
+{
+ // finalize the object before adding
+ object->finalize();
+ //Check if Object is controlled or uncontrolled.
+ if(object->getType()==Object::Controlled){
+ int baseFrameIndex = base->addEndEffector(baseFrame);
+ if (baseFrameIndex < 0)
+ return false;
+ std::pair<ObjectMap::iterator, bool> result;
+ if (base->getNrOfCoordinates() == 0) {
+ // base is fixed object, no coordinate range
+ result = objects.insert(ObjectMap::value_type(
+ name, new Object_struct(object,base,baseFrameIndex,
+ Range(m_nqTotal,object->getNrOfCoordinates()),
+ Range(m_ncTotal,((ControlledObject*)object)->getNrOfConstraints()),
+ Range(0,0))));
+ } else {
+ // base is a moving object, must be in list already
+ ObjectMap::iterator base_it;
+ for (base_it=objects.begin(); base_it != objects.end(); base_it++) {
+ if (base_it->second->object == base)
+ break;
+ }
+ if (base_it == objects.end())
+ return false;
+ result = objects.insert(ObjectMap::value_type(
+ name, new Object_struct(object,base,baseFrameIndex,
+ Range(m_nqTotal,object->getNrOfCoordinates()),
+ Range(m_ncTotal,((ControlledObject*)object)->getNrOfConstraints()),
+ base_it->second->coordinaterange)));
+ }
+ if (!result.second) {
+ return false;
+ }
+ m_nqTotal+=object->getNrOfCoordinates();
+ m_ncTotal+=((ControlledObject*)object)->getNrOfConstraints();
+ return true;
+ }
+ if(object->getType()==Object::UnControlled){
+ if ((WorldObject*)base != &Object::world)
+ return false;
+ std::pair<ObjectMap::iterator,bool> result = objects.insert(ObjectMap::value_type(
+ name,new Object_struct(object,base,0,
+ Range(0,0),
+ Range(0,0),
+ Range(m_nuTotal,object->getNrOfCoordinates()))));
+ if(!result.second)
+ return false;
+ m_nuTotal+=object->getNrOfCoordinates();
+ return true;
+ }
+ return false;
+}
+
+bool Scene::addConstraintSet(const std::string& name,ConstraintSet* task,const std::string& object1,const std::string& object2, const std::string& ee1, const std::string& ee2)
+{
+ //Check if objects exist:
+ ObjectMap::iterator object1_it = objects.find(object1);
+ ObjectMap::iterator object2_it = objects.find(object2);
+ if(object1_it==objects.end()||object2_it==objects.end())
+ return false;
+ int ee1_index = object1_it->second->object->addEndEffector(ee1);
+ int ee2_index = object2_it->second->object->addEndEffector(ee2);
+ if (ee1_index < 0 || ee2_index < 0)
+ return false;
+ std::pair<ConstraintMap::iterator,bool> result =
+ constraints.insert(ConstraintMap::value_type(name,new ConstraintSet_struct(
+ task,object1_it,ee1_index,object2_it,ee2_index,
+ Range(m_ncTotal,task->getNrOfConstraints()),Range(6*m_nsets,6))));
+ if(!result.second)
+ return false;
+ m_ncTotal+=task->getNrOfConstraints();
+ m_nsets+=1;
+ return true;
+}
+
+bool Scene::addSolver(Solver* _solver){
+ if(m_solver==NULL){
+ m_solver=_solver;
+ return true;
+ }
+ else
+ return false;
+}
+
+bool Scene::addCache(Cache* _cache){
+ if(m_cache==NULL){
+ m_cache=_cache;
+ return true;
+ }
+ else
+ return false;
+}
+
+bool Scene::initialize(){
+
+ //prepare all matrices:
+ if (m_ncTotal == 0 || m_nqTotal == 0 || m_nsets == 0)
+ return false;
+
+ m_A = e_zero_matrix(m_ncTotal,m_nqTotal);
+ if (m_nuTotal > 0) {
+ m_B = e_zero_matrix(m_ncTotal,m_nuTotal);
+ m_xdot = e_zero_vector(m_nuTotal);
+ m_Ju = e_zero_matrix(6*m_nsets,m_nuTotal);
+ }
+ m_Atemp = e_zero_matrix(m_ncTotal,6*m_nsets);
+ m_ydot = e_zero_vector(m_ncTotal);
+ m_qdot = e_zero_vector(m_nqTotal);
+ m_Wq = e_zero_matrix(m_nqTotal,m_nqTotal);
+ m_Wy = e_zero_vector(m_ncTotal);
+ m_Jq = e_zero_matrix(6*m_nsets,m_nqTotal);
+ m_Jf = e_zero_matrix(6*m_nsets,6*m_nsets);
+ m_Jf_inv = m_Jf;
+ m_Cf = e_zero_matrix(m_ncTotal,m_Jf.rows());
+ m_Cq = e_zero_matrix(m_ncTotal,m_nqTotal);
+
+ bool result=true;
+ // finalize all objects
+ for (ObjectMap::iterator it=objects.begin(); it!=objects.end(); ++it) {
+ Object_struct* os = it->second;
+
+ os->object->initCache(m_cache);
+ if (os->constraintrange.count > 0)
+ project(m_Cq,os->constraintrange,os->jointrange) = (((ControlledObject*)(os->object))->getCq());
+ }
+
+ m_ytask.resize(m_ncTotal);
+ bool toggle=true;
+ int cnt = 0;
+ //Initialize all ConstraintSets:
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ //Calculate the external pose:
+ ConstraintSet_struct* cs = it->second;
+ Frame external_pose;
+ getConstraintPose(cs->task, cs, external_pose);
+ result&=cs->task->initialise(external_pose);
+ cs->task->initCache(m_cache);
+ for (int i=0; i<cs->constraintrange.count; i++, cnt++) {
+ m_ytask[cnt] = toggle;
+ }
+ toggle = !toggle;
+ project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
+ }
+
+ if(m_solver!=NULL)
+ m_solver->init(m_nqTotal,m_ncTotal,m_ytask);
+ else
+ return false;
+
+
+ return result;
+}
+
+bool Scene::getConstraintPose(ConstraintSet* constraint, void *_param, KDL::Frame& _pose)
+{
+ // function called from constraint when they need to get the external pose
+ ConstraintSet_struct* cs = (ConstraintSet_struct*)_param;
+ // verification, the pointer MUST match
+ assert (constraint == cs->task);
+ Object_struct* ob1 = cs->object1->second;
+ Object_struct* ob2 = cs->object2->second;
+ //Calculate the external pose:
+ _pose=(ob1->base->getPose(ob1->baseFrameIndex)*ob1->object->getPose(cs->ee1index)).Inverse()*(ob2->base->getPose(ob2->baseFrameIndex)*ob2->object->getPose(cs->ee2index));
+ return true;
+}
+
+bool Scene::update(double timestamp, double timestep, unsigned int numsubstep, bool reiterate, bool cache, bool interpolate)
+{
+ // we must have valid timestep and timestamp
+ if (timestamp < KDL::epsilon || timestep < 0.0)
+ return false;
+ Timestamp ts;
+ ts.realTimestamp = timestamp;
+ // initially we start with the full timestep to allow velocity estimation over the full interval
+ ts.realTimestep = timestep;
+ setCacheTimestamp(ts);
+ ts.substep = 0;
+ // for reiteration don't load cache
+ // reiteration=additional iteration with same timestamp if application finds the convergence not good enough
+ ts.reiterate = (reiterate) ? 1 : 0;
+ ts.interpolate = (interpolate) ? 1 : 0;
+ ts.cache = (cache) ? 1 : 0;
+ ts.update = 1;
+ ts.numstep = (numsubstep & 0xFF);
+ bool autosubstep = (numsubstep == 0) ? true : false;
+ if (numsubstep < 1)
+ numsubstep = 1;
+ double timesubstep = timestep/numsubstep;
+ double timeleft = timestep;
+
+ if (timeleft == 0.0) {
+ // this special case correspond to a request to cache data
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
+ it->second->object->pushCache(ts);
+ }
+ //Update the Constraints
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ it->second->task->pushCache(ts);
+ }
+ return true;
+ }
+
+ double maxqdot;
+ e_scalar nlcoef;
+ SceneLock lockCallback(this);
+ Frame external_pose;
+ bool locked;
+
+ // initially we keep timestep unchanged so that update function compute the velocity over
+ while (numsubstep > 0) {
+ // get objects
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it) {
+ Object_struct* os = it->second;
+ if (os->object->getType()==Object::Controlled) {
+ ((ControlledObject*)(os->object))->updateControlOutput(ts);
+ if (os->constraintrange.count > 0) {
+ project(m_ydot, os->constraintrange) = ((ControlledObject*)(os->object))->getControlOutput();
+ project(m_Wy, os->constraintrange) = ((ControlledObject*)(os->object))->getWy();
+ // project(m_Cq,os->constraintrange,os->jointrange) = (((ControlledObject*)(os->object))->getCq());
+ }
+ if (os->jointrange.count > 0) {
+ project(m_Wq,os->jointrange,os->jointrange) = ((ControlledObject*)(os->object))->getWq();
+ }
+ }
+ if (os->object->getType()==Object::UnControlled && ((UncontrolledObject*)os->object)->getNrOfCoordinates() != 0) {
+ ((UncontrolledObject*)(os->object))->updateCoordinates(ts);
+ if (!ts.substep) {
+ // velocity of uncontrolled object remains constant during substepping
+ project(m_xdot,os->coordinaterange) = ((UncontrolledObject*)(os->object))->getXudot();
+ }
+ }
+ }
+
+ //get new Constraints values
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it) {
+ ConstraintSet_struct* cs = it->second;
+ Object_struct* ob1 = cs->object1->second;
+ Object_struct* ob2 = cs->object2->second;
+
+ if (ob1->base->updated() || ob1->object->updated() || ob2->base->updated() || ob2->object->updated()) {
+ // the object from which the constraint depends have changed position
+ // recompute the constraint pose
+ getConstraintPose(cs->task, cs, external_pose);
+ cs->task->initialise(external_pose);
+ }
+ cs->task->updateControlOutput(ts);
+ project(m_ydot,cs->constraintrange)=cs->task->getControlOutput();
+ if (!ts.substep || cs->task->substep()) {
+ project(m_Wy,cs->constraintrange)=(cs->task)->getWy();
+ //project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
+ }
+
+ project(m_Jf,cs->featurerange,cs->featurerange)=cs->task->getJf();
+ //std::cout << "Jf = " << Jf << std::endl;
+ //Transform the reference frame of this jacobian to the world reference frame
+ Eigen::Block<e_matrix> Jf_part = project(m_Jf,cs->featurerange,cs->featurerange);
+ changeBase(Jf_part,ob1->base->getPose(ob1->baseFrameIndex)*ob1->object->getPose(cs->ee1index));
+ //std::cout << "Jf_w = " << Jf << std::endl;
+
+ //calculate the inverse of Jf
+ KDL::svd_eigen_HH(project(m_Jf,cs->featurerange,cs->featurerange),m_Uf,m_Sf,m_Vf,m_tempf);
+ for(unsigned int i=0;i<6;++i)
+ if(m_Sf(i)<KDL::epsilon)
+ m_Uf.col(i).setConstant(0.0);
+ else
+ m_Uf.col(i)*=(1/m_Sf(i));
+ project(m_Jf_inv,cs->featurerange,cs->featurerange)=(m_Vf*m_Uf.transpose()).lazy();
+
+ //Get the robotjacobian associated with this constraintset
+ //Each jacobian is expressed in robot base frame => convert to world reference
+ //and negate second robot because it is taken reversed when closing the loop:
+ if(ob1->object->getType()==Object::Controlled){
+ project(m_Jq,cs->featurerange,ob1->jointrange) = (((ControlledObject*)(ob1->object))->getJq(cs->ee1index));
+ //Transform the reference frame of this jacobian to the world reference frame:
+ Eigen::Block<e_matrix> Jq_part = project(m_Jq,cs->featurerange,ob1->jointrange);
+ changeBase(Jq_part,ob1->base->getPose(ob1->baseFrameIndex));
+ // if the base of this object is moving, get the Ju part
+ if (ob1->base->getNrOfCoordinates() != 0) {
+ // Ju is already computed for world reference frame
+ project(m_Ju,cs->featurerange,ob1->coordinaterange)=ob1->base->getJu(ob1->baseFrameIndex);
+ }
+ } else if (ob1->object->getType() == Object::UnControlled && ((UncontrolledObject*)ob1->object)->getNrOfCoordinates() != 0) {
+ // object1 is uncontrolled moving object
+ project(m_Ju,cs->featurerange,ob1->coordinaterange)=((UncontrolledObject*)ob1->object)->getJu(cs->ee1index);
+ }
+ if(ob2->object->getType()==Object::Controlled){
+ //Get the robotjacobian associated with this constraintset
+ // process a special case where object2 and object1 are equal but using different end effector
+ if (ob1->object == ob2->object) {
+ // we must create a temporary matrix
+ e_matrix JqTemp(((ControlledObject*)(ob2->object))->getJq(cs->ee2index));
+ //Transform the reference frame of this jacobian to the world reference frame:
+ changeBase(JqTemp,ob2->base->getPose(ob2->baseFrameIndex));
+ // substract in place
+ project(m_Jq,cs->featurerange,ob2->jointrange) -= JqTemp;
+ } else {
+ project(m_Jq,cs->featurerange,ob2->jointrange) = -(((ControlledObject*)(ob2->object))->getJq(cs->ee2index));
+ //Transform the reference frame of this jacobian to the world reference frame:
+ Eigen::Block<e_matrix> Jq_part = project(m_Jq,cs->featurerange,ob2->jointrange);
+ changeBase(Jq_part,ob2->base->getPose(ob2->baseFrameIndex));
+ }
+ if (ob2->base->getNrOfCoordinates() != 0) {
+ // if base is the same as first object or first object base,
+ // that portion of m_Ju has been set already => substract inplace
+ if (ob2->base == ob1->base || ob2->base == ob1->object) {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) -= ob2->base->getJu(ob2->baseFrameIndex);
+ } else {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) = -ob2->base->getJu(ob2->baseFrameIndex);
+ }
+ }
+ } else if (ob2->object->getType() == Object::UnControlled && ((UncontrolledObject*)ob2->object)->getNrOfCoordinates() != 0) {
+ if (ob2->object == ob1->base || ob2->object == ob1->object) {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) -= ((UncontrolledObject*)ob2->object)->getJu(cs->ee2index);
+ } else {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) = -((UncontrolledObject*)ob2->object)->getJu(cs->ee2index);
+ }
+ }
+ }
+
+ //Calculate A
+ m_Atemp=(m_Cf*m_Jf_inv).lazy();
+ m_A = m_Cq-(m_Atemp*m_Jq).lazy();
+ if (m_nuTotal > 0) {
+ m_B=(m_Atemp*m_Ju).lazy();
+ m_ydot += (m_B*m_xdot).lazy();
+ }
+
+ //Call the solver with A, Wq, Wy, ydot to solver qdot:
+ if(!m_solver->solve(m_A,m_Wy,m_ydot,m_Wq,m_qdot,nlcoef))
+ // this should never happen
+ return false;
+ //send result to the objects
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it) {
+ Object_struct* os = it->second;
+ if(os->object->getType()==Object::Controlled)
+ ((ControlledObject*)(os->object))->setJointVelocity(project(m_qdot,os->jointrange));
+ }
+ // compute the constraint velocity
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ ConstraintSet_struct* cs = it->second;
+ Object_struct* ob1 = cs->object1->second;
+ Object_struct* ob2 = cs->object2->second;
+ //Calculate the twist of the world reference frame due to the robots (Jq*qdot+Ju*chiudot):
+ e_vector6 external_vel = e_zero_vector(6);
+ if (ob1->jointrange.count > 0)
+ external_vel += (project(m_Jq,cs->featurerange,ob1->jointrange)*project(m_qdot,ob1->jointrange)).lazy();
+ if (ob2->jointrange.count > 0)
+ external_vel += (project(m_Jq,cs->featurerange,ob2->jointrange)*project(m_qdot,ob2->jointrange)).lazy();
+ if (ob1->coordinaterange.count > 0)
+ external_vel += (project(m_Ju,cs->featurerange,ob1->coordinaterange)*project(m_xdot,ob1->coordinaterange)).lazy();
+ if (ob2->coordinaterange.count > 0)
+ external_vel += (project(m_Ju,cs->featurerange,ob2->coordinaterange)*project(m_xdot,ob2->coordinaterange)).lazy();
+ //the twist caused by the constraint must be opposite because of the closed loop
+ //estimate the velocity of the joints using the inverse jacobian
+ e_vector6 estimated_chidot = project(m_Jf_inv,cs->featurerange,cs->featurerange)*(-external_vel);
+ cs->task->setJointVelocity(estimated_chidot);
+ }
+
+ if (autosubstep) {
+ // automatic computing of substep based on maximum joint change
+ // and joint limit gain variation
+ // We will pass the joint velocity to each object and they will recommend a maximum timestep
+ timesubstep = timeleft;
+ // get armature max joint velocity to estimate the maximum duration of integration
+ maxqdot = m_qdot.cwise().abs().maxCoeff();
+ double maxsubstep = nlcoef*m_maxstep;
+ if (maxsubstep < m_minstep)
+ maxsubstep = m_minstep;
+ if (timesubstep > maxsubstep)
+ timesubstep = maxsubstep;
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
+ Object_struct* os = it->second;
+ if(os->object->getType()==Object::Controlled)
+ ((ControlledObject*)(os->object))->getMaxTimestep(timesubstep);
+ }
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ ConstraintSet_struct* cs = it->second;
+ cs->task->getMaxTimestep(timesubstep);
+ }
+ // use substep that are even dividers of timestep for more regularity
+ maxsubstep = 2.0*floor(timestep/2.0/timesubstep-0.66666);
+ timesubstep = (maxsubstep < 0.0) ? timestep : timestep/(2.0+maxsubstep);
+ if (timesubstep >= timeleft-(m_minstep/2.0)) {
+ timesubstep = timeleft;
+ numsubstep = 1;
+ timeleft = 0.;
+ } else {
+ numsubstep = 2;
+ timeleft -= timesubstep;
+ }
+ }
+ if (numsubstep > 1) {
+ ts.substep = 1;
+ } else {
+ // set substep to false for last iteration so that controlled output
+ // can be updated in updateKinematics() and model_update)() before next call to Secne::update()
+ ts.substep = 0;
+ }
+ // change timestep so that integration is done correctly
+ ts.realTimestep = timesubstep;
+
+ do {
+ ObjectMap::iterator it;
+ Object_struct* os;
+ locked = false;
+ for(it=objects.begin();it!=objects.end();++it){
+ os = it->second;
+ if (os->object->getType()==Object::Controlled) {
+ lockCallback.setRange(os->jointrange);
+ if (((ControlledObject*)os->object)->updateJoint(ts, lockCallback)) {
+ // this means one of the joint was locked and we must rerun
+ // the solver to update the remaining joints
+ locked = true;
+ break;
+ }
+ }
+ }
+ if (locked) {
+ // Some rows of m_Wq have been cleared so that the corresponding joint will not move
+ if(!m_solver->solve(m_A,m_Wy,m_ydot,m_Wq,m_qdot,nlcoef))
+ // this should never happen
+ return false;
+
+ //send result to the objects
+ for(it=objects.begin();it!=objects.end();++it) {
+ os = it->second;
+ if(os->object->getType()==Object::Controlled)
+ ((ControlledObject*)(os->object))->setJointVelocity(project(m_qdot,os->jointrange));
+ }
+ }
+ } while (locked);
+
+ //Update the Objects
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
+ it->second->object->updateKinematics(ts);
+ // mark this object not updated since the constraint will be updated anyway
+ // this flag is only useful to detect external updates
+ it->second->object->updated(false);
+ }
+ //Update the Constraints
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ ConstraintSet_struct* cs = it->second;
+ //Calculate the external pose:
+ getConstraintPose(cs->task, cs, external_pose);
+ cs->task->modelUpdate(external_pose,ts);
+ // update the constraint output and cache
+ cs->task->updateKinematics(ts);
+ }
+ numsubstep--;
+ }
+ return true;
+}
+
+}
diff --git a/intern/itasc/Scene.hpp b/intern/itasc/Scene.hpp
new file mode 100644
index 00000000000..a2d63361d95
--- /dev/null
+++ b/intern/itasc/Scene.hpp
@@ -0,0 +1,104 @@
+/* $Id: Scene.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * Scene.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef SCENE_HPP_
+#define SCENE_HPP_
+
+#include "eigen_types.hpp"
+
+#include "WorldObject.hpp"
+#include "ConstraintSet.hpp"
+#include "Solver.hpp"
+
+#include <map>
+
+namespace iTaSC {
+
+class SceneLock;
+
+class Scene {
+ friend class SceneLock;
+public:
+ enum SceneParam {
+ MIN_TIMESTEP = 0,
+ MAX_TIMESTEP,
+
+ COUNT
+ };
+
+
+ Scene();
+ virtual ~Scene();
+
+ bool addObject(const std::string& name, Object* object, UncontrolledObject* base=&Object::world, const std::string& baseFrame="");
+ bool addConstraintSet(const std::string& name, ConstraintSet* task,const std::string& object1,const std::string& object2,const std::string& ee1="",const std::string& ee2="");
+ bool addSolver(Solver* _solver);
+ bool addCache(Cache* _cache);
+ bool initialize();
+ bool update(double timestamp, double timestep, unsigned int numsubstep=1, bool reiterate=false, bool cache=true, bool interpolate=true);
+ bool setParam(SceneParam paramId, double value);
+
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
+private:
+ e_matrix m_A,m_B,m_Atemp,m_Wq,m_Jf,m_Jq,m_Ju,m_Cf,m_Cq,m_Jf_inv;
+ e_matrix6 m_Vf,m_Uf;
+ e_vector m_Wy,m_ydot,m_qdot,m_xdot;
+ e_vector6 m_Sf,m_tempf;
+ double m_minstep;
+ double m_maxstep;
+ unsigned int m_ncTotal,m_nqTotal,m_nuTotal,m_nsets;
+ std::vector<bool> m_ytask;
+
+ Solver* m_solver;
+ Cache* m_cache;
+
+
+ struct Object_struct{
+ Object* object;
+ UncontrolledObject* base;
+ unsigned int baseFrameIndex;
+ Range constraintrange;
+ Range jointrange;
+ Range coordinaterange; // Xu range of base when object is controlled
+ // Xu range of object when object is uncontrolled
+
+ Object_struct(Object* _object,UncontrolledObject* _base,unsigned int _baseFrameIndex,Range nq_range,Range nc_range,Range nu_range):
+ object(_object),base(_base),baseFrameIndex(_baseFrameIndex),constraintrange(nc_range),jointrange(nq_range),coordinaterange(nu_range)
+ {};
+ };
+ typedef std::map<std::string,Object_struct*> ObjectMap;
+
+ struct ConstraintSet_struct{
+ ConstraintSet* task;
+ ObjectMap::iterator object1;
+ ObjectMap::iterator object2;
+ Range constraintrange;
+ Range featurerange;
+ unsigned int ee1index;
+ unsigned int ee2index;
+ ConstraintSet_struct(ConstraintSet* _task,
+ ObjectMap::iterator _object1,unsigned int _ee1index,
+ ObjectMap::iterator _object2,unsigned int _ee2index,
+ Range nc_range,Range coord_range):
+ task(_task),
+ object1(_object1),object2(_object2),
+ constraintrange(nc_range),featurerange(coord_range),
+ ee1index(_ee1index), ee2index(_ee2index)
+ {};
+ };
+ typedef std::map<std::string,ConstraintSet_struct*> ConstraintMap;
+
+ ObjectMap objects;
+ ConstraintMap constraints;
+
+ static bool getConstraintPose(ConstraintSet* constraint, void *_param, KDL::Frame& _pose);
+};
+
+}
+
+#endif /* SCENE_HPP_ */
diff --git a/intern/itasc/Solver.hpp b/intern/itasc/Solver.hpp
new file mode 100644
index 00000000000..e3aa1e1abc8
--- /dev/null
+++ b/intern/itasc/Solver.hpp
@@ -0,0 +1,33 @@
+/* $Id: Solver.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * Solver.hpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#ifndef SOLVER_HPP_
+#define SOLVER_HPP_
+
+#include <vector>
+#include "eigen_types.hpp"
+
+namespace iTaSC{
+
+class Solver{
+public:
+ enum SolverParam {
+ DLS_QMAX = 0,
+ DLS_LAMBDA_MAX,
+ DLS_EPSILON
+ };
+ virtual ~Solver(){};
+
+ // gc = grouping of constraint output ,
+ // size of vector = nc, alternance of true / false to indicate the grouping of output
+ virtual bool init(unsigned int nq, unsigned int nc, const std::vector<bool>& gc)=0;
+ virtual bool solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef)=0;
+ virtual void setParam(SolverParam param, double value)=0;
+};
+
+}
+#endif /* SOLVER_HPP_ */
diff --git a/intern/itasc/UncontrolledObject.cpp b/intern/itasc/UncontrolledObject.cpp
new file mode 100644
index 00000000000..4db44aaf7dc
--- /dev/null
+++ b/intern/itasc/UncontrolledObject.cpp
@@ -0,0 +1,43 @@
+/* $Id$
+ * UncontrolledObject.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "UncontrolledObject.hpp"
+
+namespace iTaSC{
+
+UncontrolledObject::UncontrolledObject():Object(UnControlled),
+ m_nu(0), m_nf(0), m_xudot()
+{
+}
+
+UncontrolledObject::~UncontrolledObject()
+{
+}
+
+void UncontrolledObject::initialize(unsigned int _nu, unsigned int _nf)
+{
+ assert (_nf >= 1);
+ m_nu = _nu;
+ m_nf = _nf;
+ if (_nu > 0)
+ m_xudot = e_zero_vector(_nu);
+ // clear all Jacobian if any
+ m_JuArray.clear();
+ // reserve one more to have an zero matrix handy
+ if (m_nu > 0)
+ m_JuArray.resize(m_nf+1, e_zero_matrix(6,m_nu));
+}
+
+const e_matrix& UncontrolledObject::getJu(unsigned int frameIndex) const
+{
+ assert (m_nu > 0);
+ return m_JuArray[(frameIndex>m_nf)?m_nf:frameIndex];
+}
+
+
+
+}
diff --git a/intern/itasc/UncontrolledObject.hpp b/intern/itasc/UncontrolledObject.hpp
new file mode 100644
index 00000000000..3b693a0b2ed
--- /dev/null
+++ b/intern/itasc/UncontrolledObject.hpp
@@ -0,0 +1,37 @@
+/* $Id: UncontrolledObject.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * UncontrolledObject.h
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef UNCONTROLLEDOBJECT_HPP_
+#define UNCONTROLLEDOBJECT_HPP_
+
+#include "eigen_types.hpp"
+
+#include "Object.hpp"
+namespace iTaSC{
+
+class UncontrolledObject: public Object {
+protected:
+ unsigned int m_nu, m_nf;
+ e_vector m_xudot;
+ std::vector<e_matrix> m_JuArray;
+
+public:
+ UncontrolledObject();
+ virtual ~UncontrolledObject();
+
+ virtual void initialize(unsigned int _nu, unsigned int _nf);
+ virtual const e_matrix& getJu(unsigned int frameIndex) const;
+ virtual const e_vector& getXudot() const {return m_xudot;}
+ virtual void updateCoordinates(const Timestamp& timestamp)=0;
+ virtual const unsigned int getNrOfCoordinates(){return m_nu;};
+ virtual const unsigned int getNrOfFrames(){return m_nf;};
+
+};
+
+}
+
+#endif /* UNCONTROLLEDOBJECT_H_ */
diff --git a/intern/itasc/WDLSSolver.cpp b/intern/itasc/WDLSSolver.cpp
new file mode 100644
index 00000000000..1d0efde54c9
--- /dev/null
+++ b/intern/itasc/WDLSSolver.cpp
@@ -0,0 +1,101 @@
+/* $Id$
+ * WDLSSolver.hpp.cpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#include "WDLSSolver.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+
+namespace iTaSC {
+
+WDLSSolver::WDLSSolver() : m_lambda(0.5), m_epsilon(0.1)
+{
+ // maximum joint velocity
+ m_qmax = 50.0;
+}
+
+WDLSSolver::~WDLSSolver() {
+}
+
+bool WDLSSolver::init(unsigned int nq, unsigned int nc, const std::vector<bool>& gc)
+{
+ m_ns = std::min(nc,nq);
+ m_AWq = e_zero_matrix(nc,nq);
+ m_WyAWq = e_zero_matrix(nc,nq);
+ m_WyAWqt = e_zero_matrix(nq,nc);
+ m_S = e_zero_vector(std::max(nc,nq));
+ m_Wy_ydot = e_zero_vector(nc);
+ if (nq > nc) {
+ m_transpose = true;
+ m_temp = e_zero_vector(nc);
+ m_U = e_zero_matrix(nc,nc);
+ m_V = e_zero_matrix(nq,nc);
+ m_WqV = e_zero_matrix(nq,nc);
+ } else {
+ m_transpose = false;
+ m_temp = e_zero_vector(nq);
+ m_U = e_zero_matrix(nc,nq);
+ m_V = e_zero_matrix(nq,nq);
+ m_WqV = e_zero_matrix(nq,nq);
+ }
+ return true;
+}
+
+bool WDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef)
+{
+ double alpha, vmax, norm;
+ // Create the Weighted jacobian
+ m_AWq = A*Wq;
+ for (int i=0; i<Wy.size(); i++)
+ m_WyAWq.row(i) = Wy(i)*m_AWq.row(i);
+
+ // Compute the SVD of the weighted jacobian
+ int ret;
+ if (m_transpose) {
+ m_WyAWqt = m_WyAWq.transpose();
+ ret = KDL::svd_eigen_HH(m_WyAWqt,m_V,m_S,m_U,m_temp);
+ } else {
+ ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp);
+ }
+ if(ret<0)
+ return false;
+
+ m_WqV = (Wq*m_V).lazy();
+
+ //Wy*ydot
+ m_Wy_ydot = Wy.cwise() * ydot;
+ //S^-1*U'*Wy*ydot
+ e_scalar maxDeltaS = e_scalar(0.0);
+ e_scalar prevS = e_scalar(0.0);
+ e_scalar maxS = e_scalar(1.0);
+ e_scalar S, lambda;
+ qdot.setZero();
+ for(int i=0;i<m_ns;++i) {
+ S = m_S(i);
+ if (S <= KDL::epsilon)
+ break;
+ if (i > 0 && (prevS-S) > maxDeltaS) {
+ maxDeltaS = (prevS-S);
+ maxS = prevS;
+ }
+ lambda = (S < m_epsilon) ? (e_scalar(1.0)-KDL::sqr(S/m_epsilon))*m_lambda*m_lambda : e_scalar(0.0);
+ alpha = m_U.col(i).dot(m_Wy_ydot)*S/(S*S+lambda);
+ vmax = m_WqV.col(i).cwise().abs().maxCoeff();
+ norm = fabs(alpha*vmax);
+ if (norm > m_qmax) {
+ qdot += m_WqV.col(i)*(alpha*m_qmax/norm);
+ } else {
+ qdot += m_WqV.col(i)*alpha;
+ }
+ prevS = S;
+ }
+ if (maxDeltaS == e_scalar(0.0))
+ nlcoef = e_scalar(KDL::epsilon);
+ else
+ nlcoef = (maxS-maxDeltaS)/maxS;
+ return true;
+}
+
+}
diff --git a/intern/itasc/WDLSSolver.hpp b/intern/itasc/WDLSSolver.hpp
new file mode 100644
index 00000000000..b56ad1ab2b8
--- /dev/null
+++ b/intern/itasc/WDLSSolver.hpp
@@ -0,0 +1,48 @@
+/* $Id: WDLSSolver.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * WDLSSolver.hpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#ifndef WDLSSOLVER_HPP_
+#define WDLSSOLVER_HPP_
+
+#include "Solver.hpp"
+
+namespace iTaSC {
+
+class WDLSSolver: public iTaSC::Solver {
+private:
+ e_matrix m_AWq,m_WyAWq,m_WyAWqt,m_U,m_V,m_WqV;
+ e_vector m_S,m_temp,m_Wy_ydot;
+ double m_lambda;
+ double m_epsilon;
+ double m_qmax;
+ int m_ns;
+ bool m_transpose;
+public:
+ WDLSSolver();
+ virtual ~WDLSSolver();
+
+ virtual bool init(unsigned int nq, unsigned int nc, const std::vector<bool>& gc);
+ virtual bool solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef);
+ virtual void setParam(SolverParam param, double value)
+ {
+ switch (param) {
+ case DLS_QMAX:
+ m_qmax = value;
+ break;
+ case DLS_LAMBDA_MAX:
+ m_lambda = value;
+ break;
+ case DLS_EPSILON:
+ m_epsilon = value;
+ break;
+ }
+ }
+};
+
+}
+
+#endif /* WDLSSOLVER_HPP_ */
diff --git a/intern/itasc/WSDLSSolver.cpp b/intern/itasc/WSDLSSolver.cpp
new file mode 100644
index 00000000000..9f7ebed960a
--- /dev/null
+++ b/intern/itasc/WSDLSSolver.cpp
@@ -0,0 +1,138 @@
+/* $Id$
+ * WDLSSolver.hpp.cpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#include "WSDLSSolver.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+#include <cstdio>
+
+namespace iTaSC {
+
+WSDLSSolver::WSDLSSolver() :
+ m_ns(0), m_nc(0), m_nq(0)
+
+{
+ // default maximum speed: 50 rad/s
+ m_qmax = 50.0;
+}
+
+WSDLSSolver::~WSDLSSolver() {
+}
+
+bool WSDLSSolver::init(unsigned int _nq, unsigned int _nc, const std::vector<bool>& gc)
+{
+ if (_nc == 0 || _nq == 0 || gc.size() != _nc)
+ return false;
+ m_nc = _nc;
+ m_nq = _nq;
+ m_ns = std::min(m_nc,m_nq);
+ m_AWq = e_zero_matrix(m_nc,m_nq);
+ m_WyAWq = e_zero_matrix(m_nc,m_nq);
+ m_WyAWqt = e_zero_matrix(m_nq,m_nc);
+ m_S = e_zero_vector(std::max(m_nc,m_nq));
+ m_Wy_ydot = e_zero_vector(m_nc);
+ m_ytask = gc;
+ if (m_nq > m_nc) {
+ m_transpose = true;
+ m_temp = e_zero_vector(m_nc);
+ m_U = e_zero_matrix(m_nc,m_nc);
+ m_V = e_zero_matrix(m_nq,m_nc);
+ m_WqV = e_zero_matrix(m_nq,m_nc);
+ } else {
+ m_transpose = false;
+ m_temp = e_zero_vector(m_nq);
+ m_U = e_zero_matrix(m_nc,m_nq);
+ m_V = e_zero_matrix(m_nq,m_nq);
+ m_WqV = e_zero_matrix(m_nq,m_nq);
+ }
+ return true;
+}
+
+bool WSDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef)
+{
+ unsigned int i, j, l;
+ e_scalar N, M;
+
+ // Create the Weighted jacobian
+ m_AWq = (A*Wq).lazy();
+ for (i=0; i<m_nc; i++)
+ m_WyAWq.row(i) = Wy(i)*m_AWq.row(i);
+
+ // Compute the SVD of the weighted jacobian
+ int ret;
+ if (m_transpose) {
+ m_WyAWqt = m_WyAWq.transpose();
+ ret = KDL::svd_eigen_HH(m_WyAWqt,m_V,m_S,m_U,m_temp);
+ } else {
+ ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp);
+ }
+ if(ret<0)
+ return false;
+
+ m_Wy_ydot = Wy.cwise() * ydot;
+ m_WqV = (Wq*m_V).lazy();
+ qdot.setZero();
+ e_scalar maxDeltaS = e_scalar(0.0);
+ e_scalar prevS = e_scalar(0.0);
+ e_scalar maxS = e_scalar(1.0);
+ for(i=0;i<m_ns;++i) {
+ e_scalar norm, mag, alpha, _qmax, Sinv, vmax, damp;
+ e_scalar S = m_S(i);
+ bool prev;
+ if (S < KDL::epsilon)
+ break;
+ Sinv = e_scalar(1.)/S;
+ if (i > 0) {
+ if ((prevS-S) > maxDeltaS) {
+ maxDeltaS = (prevS-S);
+ maxS = prevS;
+ }
+ }
+ N = M = e_scalar(0.);
+ for (l=0, prev=m_ytask[0], norm=e_scalar(0.); l<m_nc; l++) {
+ if (prev == m_ytask[l]) {
+ norm += m_U(l,i)*m_U(l,i);
+ } else {
+ N += std::sqrt(norm);
+ norm = m_U(l,i)*m_U(l,i);
+ }
+ prev = m_ytask[l];
+ }
+ N += std::sqrt(norm);
+ for (j=0; j<m_nq; j++) {
+ for (l=0, prev=m_ytask[0], norm=e_scalar(0.), mag=e_scalar(0.); l<m_nc; l++) {
+ if (prev == m_ytask[l]) {
+ norm += m_WyAWq(l,j)*m_WyAWq(l,j);
+ } else {
+ mag += std::sqrt(norm);
+ norm = m_WyAWq(l,j)*m_WyAWq(l,j);
+ }
+ prev = m_ytask[l];
+ }
+ mag += std::sqrt(norm);
+ M += fabs(m_V(j,i))*mag;
+ }
+ M *= Sinv;
+ alpha = m_U.col(i).dot(m_Wy_ydot);
+ _qmax = (N < M) ? m_qmax*N/M : m_qmax;
+ vmax = m_WqV.col(i).cwise().abs().maxCoeff();
+ norm = fabs(Sinv*alpha*vmax);
+ if (norm > _qmax) {
+ damp = Sinv*alpha*_qmax/norm;
+ } else {
+ damp = Sinv*alpha;
+ }
+ qdot += m_WqV.col(i)*damp;
+ prevS = S;
+ }
+ if (maxDeltaS == e_scalar(0.0))
+ nlcoef = e_scalar(KDL::epsilon);
+ else
+ nlcoef = (maxS-maxDeltaS)/maxS;
+ return true;
+}
+
+}
diff --git a/intern/itasc/WSDLSSolver.hpp b/intern/itasc/WSDLSSolver.hpp
new file mode 100644
index 00000000000..0b17f26ef47
--- /dev/null
+++ b/intern/itasc/WSDLSSolver.hpp
@@ -0,0 +1,43 @@
+/* $Id: WSDLSSolver.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * WSDLSSolver.hpp
+ *
+ * Created on: Mar 26, 2009
+ * Author: benoit bolsee
+ */
+
+#ifndef WSDLSSOLVER_HPP_
+#define WSDLSSOLVER_HPP_
+
+#include "Solver.hpp"
+
+namespace iTaSC {
+
+class WSDLSSolver: public iTaSC::Solver {
+private:
+ e_matrix m_AWq,m_WyAWq,m_WyAWqt,m_U,m_V,m_WqV;
+ e_vector m_S,m_temp,m_Wy_ydot;
+ std::vector<bool> m_ytask;
+ e_scalar m_qmax;
+ unsigned int m_ns, m_nc, m_nq;
+ bool m_transpose;
+public:
+ WSDLSSolver();
+ virtual ~WSDLSSolver();
+
+ virtual bool init(unsigned int _nq, unsigned int _nc, const std::vector<bool>& gc);
+ virtual bool solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef);
+ virtual void setParam(SolverParam param, double value)
+ {
+ switch (param) {
+ case DLS_QMAX:
+ m_qmax = value;
+ break;
+ default:
+ break;
+ }
+ }
+};
+
+}
+
+#endif /* WSDLSSOLVER_HPP_ */
diff --git a/intern/itasc/WorldObject.cpp b/intern/itasc/WorldObject.cpp
new file mode 100644
index 00000000000..99cb8773e77
--- /dev/null
+++ b/intern/itasc/WorldObject.cpp
@@ -0,0 +1,26 @@
+/* $Id$
+ * WorldObject.cpp
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#include "WorldObject.hpp"
+
+namespace iTaSC{
+
+/* special singleton to be used as base for uncontrolled object */
+WorldObject Object::world;
+
+WorldObject::WorldObject():UncontrolledObject()
+{
+ initialize(0,1);
+ m_internalPose = Frame::Identity();
+}
+
+WorldObject::~WorldObject()
+{
+}
+
+
+}
diff --git a/intern/itasc/WorldObject.hpp b/intern/itasc/WorldObject.hpp
new file mode 100644
index 00000000000..b309545a843
--- /dev/null
+++ b/intern/itasc/WorldObject.hpp
@@ -0,0 +1,30 @@
+/* $Id: WorldObject.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * WorldObject.h
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef WORLDOBJECT_HPP_
+#define WORLDOBJECT_HPP_
+
+#include "UncontrolledObject.hpp"
+namespace iTaSC{
+
+class WorldObject: public UncontrolledObject {
+public:
+ WorldObject();
+ virtual ~WorldObject();
+
+ virtual void updateCoordinates(const Timestamp& timestamp) {};
+ virtual void updateKinematics(const Timestamp& timestamp) {};
+ virtual void pushCache(const Timestamp& timestamp) {};
+ virtual void initCache(Cache *_cache) {};
+protected:
+ virtual void updateJacobian() {}
+
+};
+
+}
+
+#endif /* WORLDOBJECT_H_ */
diff --git a/intern/itasc/eigen_types.cpp b/intern/itasc/eigen_types.cpp
new file mode 100644
index 00000000000..2aa942f38c7
--- /dev/null
+++ b/intern/itasc/eigen_types.cpp
@@ -0,0 +1,12 @@
+/* $Id$
+ * eigen_types.cpp
+ *
+ * Created on: March 19, 2009
+ * Author: benoit bolsee
+ */
+
+#include "eigen_types.hpp"
+
+const KDL::Frame iTaSC::F_identity(Rotation::Identity(),Vector::Zero());
+
+
diff --git a/intern/itasc/eigen_types.hpp b/intern/itasc/eigen_types.hpp
new file mode 100644
index 00000000000..fe46f8b6bb3
--- /dev/null
+++ b/intern/itasc/eigen_types.hpp
@@ -0,0 +1,84 @@
+/* $Id: eigen_types.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * eigen_types.hpp
+ *
+ * Created on: March 6, 2009
+ * Author: benoit bolsee
+ */
+
+#ifndef EIGEN_TYPES_HPP_
+#define EIGEN_TYPES_HPP_
+
+#include <Eigen/Core>
+#include "kdl/frames.hpp"
+#include "kdl/tree.hpp"
+#include "kdl/chain.hpp"
+#include "kdl/jacobian.hpp"
+#include "kdl/jntarray.hpp"
+
+
+namespace iTaSC{
+
+using KDL::Twist;
+using KDL::Frame;
+using KDL::Joint;
+using KDL::Inertia;
+using KDL::SegmentMap;
+using KDL::Tree;
+using KDL::JntArray;
+using KDL::Jacobian;
+using KDL::Segment;
+using KDL::Rotation;
+using KDL::Vector;
+using KDL::Vector2;
+using KDL::Chain;
+
+extern const Frame F_identity;
+
+#define e_scalar double
+#define e_vector Eigen::Matrix<e_scalar, Eigen::Dynamic, 1>
+#define e_zero_vector Eigen::Matrix<e_scalar, Eigen::Dynamic, 1>::Zero
+#define e_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>
+#define e_matrix6 Eigen::Matrix<e_scalar,6,6>
+#define e_identity_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>::Identity
+#define e_scalar_vector Eigen::Matrix<e_scalar, Eigen::Dynamic, 1>::Constant
+#define e_zero_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>::Zero
+#define e_random_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>::Random
+#define e_vector6 Eigen::Matrix<e_scalar,6,1>
+#define e_vector3 Eigen::Matrix<e_scalar,3,1>
+
+class Range {
+public:
+ int start;
+ int count;
+ Range(int _start, int _count) { start = _start; count=_count; }
+ Range(const Range& other) { start=other.start; count=other.count; }
+};
+
+template<typename MatrixType> inline Eigen::Block<MatrixType> project(MatrixType& m, Range r)
+{
+ return Eigen::Block<MatrixType>(m,r.start,0,r.count,1);
+}
+
+template<typename MatrixType> inline Eigen::Block<MatrixType> project(MatrixType& m, Range r, Range c)
+{
+ return Eigen::Block<MatrixType>(m,r.start,c.start,r.count,c.count);
+}
+
+template<typename Derived> inline static int changeBase(Eigen::MatrixBase<Derived>& J, const Frame& T) {
+
+ if (J.rows() != 6)
+ return -1;
+ for (int j = 0; j < J.cols(); ++j) {
+ typename Derived::ColXpr Jj = J.col(j);
+ Twist arg;
+ for(unsigned int i=0;i<6;++i)
+ arg(i)=Jj[i];
+ Twist tmp(T*arg);
+ for(unsigned int i=0;i<6;++i)
+ Jj[i]=e_scalar(tmp(i));
+ }
+ return 0;
+}
+
+}
+#endif /* UBLAS_TYPES_HPP_ */
diff --git a/intern/itasc/kdl/Makefile b/intern/itasc/kdl/Makefile
new file mode 100644
index 00000000000..058f93da4e1
--- /dev/null
+++ b/intern/itasc/kdl/Makefile
@@ -0,0 +1,43 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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): Hans Lambermont
+#
+# ***** END GPL LICENSE BLOCK *****
+# iksolver main makefile.
+#
+
+include nan_definitions.mk
+
+LIBNAME = itasc_kdl
+# Yep, same dir than parent (itasc instead of $(LIBNAME))
+DIR = $(OCGDIR)/intern/itasc
+DIRS = utilities
+SOURCEDIR = intern/$(LIBNAME)/kdl
+
+include nan_subdirs.mk
+include nan_compile.mk
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../../../extern/Eigen2
diff --git a/intern/itasc/kdl/chain.cpp b/intern/itasc/kdl/chain.cpp
new file mode 100644
index 00000000000..638366c96be
--- /dev/null
+++ b/intern/itasc/kdl/chain.cpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "chain.hpp"
+
+namespace KDL {
+ using namespace std;
+
+ Chain::Chain():
+ segments(0),
+ nrOfJoints(0),
+ nrOfSegments(0)
+ {
+ }
+
+ Chain::Chain(const Chain& in):nrOfJoints(0),
+ nrOfSegments(0)
+ {
+ for(unsigned int i=0;i<in.getNrOfSegments();i++)
+ this->addSegment(in.getSegment(i));
+ }
+
+ Chain& Chain::operator=(const Chain& arg)
+ {
+ nrOfJoints=0;
+ nrOfSegments=0;
+ segments.resize(0);
+ for(unsigned int i=0;i<arg.nrOfSegments;i++)
+ addSegment(arg.getSegment(i));
+ return *this;
+
+ }
+
+ void Chain::addSegment(const Segment& segment)
+ {
+ segments.push_back(segment);
+ nrOfSegments++;
+ nrOfJoints += segment.getJoint().getNDof();
+ }
+
+ void Chain::addChain(const Chain& chain)
+ {
+ for(unsigned int i=0;i<chain.getNrOfSegments();i++)
+ this->addSegment(chain.getSegment(i));
+ }
+
+ const Segment& Chain::getSegment(unsigned int nr) const
+ {
+ return segments[nr];
+ }
+
+ Chain::~Chain()
+ {
+ }
+
+}
+
diff --git a/intern/itasc/kdl/chain.hpp b/intern/itasc/kdl/chain.hpp
new file mode 100644
index 00000000000..0d40690202a
--- /dev/null
+++ b/intern/itasc/kdl/chain.hpp
@@ -0,0 +1,95 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_CHAIN_HPP
+#define KDL_CHAIN_HPP
+
+#include "segment.hpp"
+#include <string>
+
+namespace KDL {
+ /**
+ * \brief This class encapsulates a <strong>serial</strong> kinematic
+ * interconnection structure. It is build out of segments.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Chain {
+ private:
+ std::vector<Segment> segments;
+ unsigned int nrOfJoints;
+ unsigned int nrOfSegments;
+ public:
+ /**
+ * The constructor of a chain, a new chain is always empty.
+ *
+ */
+ Chain();
+ Chain(const Chain& in);
+ Chain& operator = (const Chain& arg);
+
+ /**
+ * Adds a new segment to the <strong>end</strong> of the chain.
+ *
+ * @param segment The segment to add
+ */
+ void addSegment(const Segment& segment);
+ /**
+ * Adds a complete chain to the <strong>end</strong> of the chain
+ * The added chain is copied.
+ *
+ * @param chain The chain to add
+ */
+ void addChain(const Chain& chain);
+
+ /**
+ * Request the total number of joints in the chain.\n
+ * <strong> Important:</strong> It is not the
+ * same as the total number of segments since a segment does not
+ * need to have a joint. This function is important when
+ * creating a KDL::JntArray to use with this chain.
+ * @return total nr of joints
+ */
+ unsigned int getNrOfJoints()const {return nrOfJoints;};
+ /**
+ * Request the total number of segments in the chain.
+ * @return total number of segments
+ */
+ unsigned int getNrOfSegments()const {return nrOfSegments;};
+
+ /**
+ * Request the nr'd segment of the chain. There is no boundary
+ * checking.
+ *
+ * @param nr the nr of the segment starting from 0
+ *
+ * @return a constant reference to the nr'd segment
+ */
+ const Segment& getSegment(unsigned int nr)const;
+
+ virtual ~Chain();
+ };
+
+
+
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/chainfksolver.hpp b/intern/itasc/kdl/chainfksolver.hpp
new file mode 100644
index 00000000000..fa6f625ee9d
--- /dev/null
+++ b/intern/itasc/kdl/chainfksolver.hpp
@@ -0,0 +1,107 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_CHAIN_FKSOLVER_HPP
+#define KDL_CHAIN_FKSOLVER_HPP
+
+#include "chain.hpp"
+#include "framevel.hpp"
+#include "frameacc.hpp"
+#include "jntarray.hpp"
+#include "jntarrayvel.hpp"
+#include "jntarrayacc.hpp"
+
+namespace KDL {
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a
+ * solver for the forward position kinematics for a KDL::Chain.
+ *
+ * @ingroup KinematicFamily
+ */
+
+ //Forward definition
+ class ChainFkSolverPos {
+ public:
+ /**
+ * Calculate forward position kinematics for a KDL::Chain,
+ * from joint coordinates to cartesian pose.
+ *
+ * @param q_in input joint coordinates
+ * @param p_out reference to output cartesian pose
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out,int segmentNr=-1)=0;
+ virtual ~ChainFkSolverPos(){};
+ };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward velocity kinematics for a KDL::Chain.
+ *
+ * @ingroup KinematicFamily
+ */
+ class ChainFkSolverVel {
+ public:
+ /**
+ * Calculate forward position and velocity kinematics, from
+ * joint coordinates to cartesian coordinates.
+ *
+ * @param q_in input joint coordinates (position and velocity)
+ * @param out output cartesian coordinates (position and velocity)
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArrayVel& q_in, FrameVel& out,int segmentNr=-1)=0;
+
+ virtual ~ChainFkSolverVel(){};
+ };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward acceleration kinematics for a KDL::Chain.
+ *
+ * @ingroup KinematicFamily
+ */
+
+ class ChainFkSolverAcc {
+ public:
+ /**
+ * Calculate forward position, velocity and accelaration
+ * kinematics, from joint coordinates to cartesian coordinates
+ *
+ * @param q_in input joint coordinates (position, velocity and
+ * acceleration
+ @param out output cartesian coordinates (position, velocity
+ * and acceleration
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArrayAcc& q_in, FrameAcc& out,int segmentNr=-1)=0;
+
+ virtual ~ChainFkSolverAcc()=0;
+ };
+
+
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/chainfksolverpos_recursive.cpp b/intern/itasc/kdl/chainfksolverpos_recursive.cpp
new file mode 100644
index 00000000000..46c29c9c6e0
--- /dev/null
+++ b/intern/itasc/kdl/chainfksolverpos_recursive.cpp
@@ -0,0 +1,61 @@
+// Copyright (C) 2007 Francois Cauwe <francois at cauwe dot org>
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "chainfksolverpos_recursive.hpp"
+#include <iostream>
+
+namespace KDL {
+
+ ChainFkSolverPos_recursive::ChainFkSolverPos_recursive(const Chain& _chain):
+ chain(_chain)
+ {
+ }
+
+ int ChainFkSolverPos_recursive::JntToCart(const JntArray& q_in, Frame& p_out, int segmentNr)
+ {
+ unsigned int segNr = (unsigned int)segmentNr;
+ if(segmentNr<0)
+ segNr=chain.getNrOfSegments();
+
+ p_out = Frame::Identity();
+
+ if(q_in.rows()!=chain.getNrOfJoints())
+ return -1;
+ else if(segNr>chain.getNrOfSegments())
+ return -1;
+ else{
+ int j=0;
+ for(unsigned int i=0;i<segNr;i++){
+ p_out = p_out*chain.getSegment(i).pose(((JntArray&)q_in)(j));
+ j+=chain.getSegment(i).getJoint().getNDof();
+ }
+ return 0;
+ }
+ }
+
+
+ ChainFkSolverPos_recursive::~ChainFkSolverPos_recursive()
+ {
+ }
+
+
+}
diff --git a/intern/itasc/kdl/chainfksolverpos_recursive.hpp b/intern/itasc/kdl/chainfksolverpos_recursive.hpp
new file mode 100644
index 00000000000..72cdab0b28b
--- /dev/null
+++ b/intern/itasc/kdl/chainfksolverpos_recursive.hpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDLCHAINFKSOLVERPOS_RECURSIVE_HPP
+#define KDLCHAINFKSOLVERPOS_RECURSIVE_HPP
+
+#include "chainfksolver.hpp"
+
+namespace KDL {
+
+ /**
+ * Implementation of a recursive forward position kinematics
+ * algorithm to calculate the position transformation from joint
+ * space to Cartesian space of a general kinematic chain (KDL::Chain).
+ *
+ * @ingroup KinematicFamily
+ */
+ class ChainFkSolverPos_recursive : public ChainFkSolverPos
+ {
+ public:
+ ChainFkSolverPos_recursive(const Chain& chain);
+ ~ChainFkSolverPos_recursive();
+
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out, int segmentNr=-1);
+
+ private:
+ const Chain chain;
+ };
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/chainjnttojacsolver.cpp b/intern/itasc/kdl/chainjnttojacsolver.cpp
new file mode 100644
index 00000000000..4a801c041f3
--- /dev/null
+++ b/intern/itasc/kdl/chainjnttojacsolver.cpp
@@ -0,0 +1,80 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "chainjnttojacsolver.hpp"
+
+namespace KDL
+{
+ ChainJntToJacSolver::ChainJntToJacSolver(const Chain& _chain):
+ chain(_chain)
+ {
+ }
+
+ ChainJntToJacSolver::~ChainJntToJacSolver()
+ {
+ }
+
+ int ChainJntToJacSolver::JntToJac(const JntArray& q_in,Jacobian& jac)
+ {
+ assert(q_in.rows()==chain.getNrOfJoints()&&
+ q_in.rows()==jac.columns());
+
+
+ Frame T_local, T_joint;
+ T_total = Frame::Identity();
+ SetToZero(t_local);
+
+ int i=chain.getNrOfSegments()-1;
+ unsigned int q_nr = chain.getNrOfJoints();
+
+ //Lets recursively iterate until we are in the root segment
+ while (i >= 0) {
+ const Segment& segment = chain.getSegment(i);
+ int ndof = segment.getJoint().getNDof();
+ q_nr -= ndof;
+
+ //get the pose of the joint.
+ T_joint = segment.getJoint().pose(((JntArray&)q_in)(q_nr));
+ // combine with the tip to have the tip pose
+ T_local = T_joint*segment.getFrameToTip();
+ //calculate new T_end:
+ T_total = T_local * T_total;
+
+ for (int dof=0; dof<ndof; dof++) {
+ // combine joint rotation with tip position to get a reference frame for the joint
+ T_joint.p = T_local.p;
+ // in which the twist can be computed (needed for NDof joint)
+ t_local = segment.twist(T_joint, 1.0, dof);
+ //transform the endpoint of the local twist to the global endpoint:
+ t_local = t_local.RefPoint(T_total.p - T_local.p);
+ //transform the base of the twist to the endpoint
+ t_local = T_total.M.Inverse(t_local);
+ //store the twist in the jacobian:
+ jac.twists[q_nr+dof] = t_local;
+ }
+ i--;
+ }//endwhile
+ //Change the base of the complete jacobian from the endpoint to the base
+ changeBase(jac, T_total.M, jac);
+ return 0;
+ }
+}
+
diff --git a/intern/itasc/kdl/chainjnttojacsolver.hpp b/intern/itasc/kdl/chainjnttojacsolver.hpp
new file mode 100644
index 00000000000..98f9d06ee0d
--- /dev/null
+++ b/intern/itasc/kdl/chainjnttojacsolver.hpp
@@ -0,0 +1,65 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_CHAINJNTTOJACSOLVER_HPP
+#define KDL_CHAINJNTTOJACSOLVER_HPP
+
+#include "frames.hpp"
+#include "jacobian.hpp"
+#include "jntarray.hpp"
+#include "chain.hpp"
+
+namespace KDL
+{
+ /**
+ * @brief Class to calculate the jacobian of a general
+ * KDL::Chain, it is used by other solvers. It should not be used
+ * outside of KDL.
+ *
+ *
+ */
+
+ class ChainJntToJacSolver
+ {
+ public:
+ ChainJntToJacSolver(const Chain& chain);
+ ~ChainJntToJacSolver();
+ /**
+ * Calculate the jacobian expressed in the base frame of the
+ * chain, with reference point at the end effector of the
+ * *chain. The alghoritm is similar to the one used in
+ * KDL::ChainFkSolverVel_recursive
+ *
+ * @param q_in input joint positions
+ * @param jac output jacobian
+ *
+ * @return always returns 0
+ */
+ int JntToJac(const JntArray& q_in,Jacobian& jac);
+
+ private:
+ const Chain chain;
+ Twist t_local;
+ Frame T_total;
+ };
+}
+#endif
+
diff --git a/intern/itasc/kdl/frameacc.cpp b/intern/itasc/kdl/frameacc.cpp
new file mode 100644
index 00000000000..9defce0a00e
--- /dev/null
+++ b/intern/itasc/kdl/frameacc.cpp
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ ****************************************************************************/
+
+
+#include "frameacc.hpp"
+
+namespace KDL {
+
+#ifndef KDL_INLINE
+ #include "frameacc.inl"
+#endif
+
+}
+
diff --git a/intern/itasc/kdl/frameacc.hpp b/intern/itasc/kdl/frameacc.hpp
new file mode 100644
index 00000000000..4157237222e
--- /dev/null
+++ b/intern/itasc/kdl/frameacc.hpp
@@ -0,0 +1,259 @@
+/*****************************************************************************
+ * \file
+ * This file contains the definition of classes for a
+ * Rall Algebra of (subset of) the classes defined in frames,
+ * i.e. classes that contain a set (value,derivative,2nd derivative)
+ * and define operations on that set
+ * this classes are usefull for automatic differentiation ( <-> symbolic diff ,
+ * <-> numeric diff).
+ * Defines VectorAcc, RotationAcc, FrameAcc, doubleAcc.
+ * Look at the corresponding classes Vector Rotation Frame Twist and
+ * Wrench for the semantics of the methods.
+ *
+ * It also contains the 2nd derivative <-> RFrames.h
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: frameacc.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef RRFRAMES_H
+#define RRFRAMES_H
+
+
+#include "utilities/rall2d.h"
+#include "frames.hpp"
+
+
+
+namespace KDL {
+
+class TwistAcc;
+typedef Rall2d<double,double,double> doubleAcc;
+
+
+class VectorAcc
+{
+public:
+ Vector p; //!< position vector
+ Vector v; //!< velocity vector
+ Vector dv; //!< acceleration vector
+public:
+ VectorAcc():p(),v(),dv() {}
+ explicit VectorAcc(const Vector& _p):p(_p),v(Vector::Zero()),dv(Vector::Zero()) {}
+ VectorAcc(const Vector& _p,const Vector& _v):p(_p),v(_v),dv(Vector::Zero()) {}
+ VectorAcc(const Vector& _p,const Vector& _v,const Vector& _dv):
+ p(_p),v(_v),dv(_dv) {}
+ IMETHOD VectorAcc& operator = (const VectorAcc& arg);
+ IMETHOD VectorAcc& operator = (const Vector& arg);
+ IMETHOD VectorAcc& operator += (const VectorAcc& arg);
+ IMETHOD VectorAcc& operator -= (const VectorAcc& arg);
+ IMETHOD static VectorAcc Zero();
+ IMETHOD void ReverseSign();
+ IMETHOD doubleAcc Norm();
+ IMETHOD friend VectorAcc operator + (const VectorAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator - (const VectorAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator + (const Vector& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator - (const Vector& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator + (const VectorAcc& r1,const Vector& r2);
+ IMETHOD friend VectorAcc operator - (const VectorAcc& r1,const Vector& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r1,const Vector& r2);
+ IMETHOD friend VectorAcc operator * (const Vector& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r1,double r2);
+ IMETHOD friend VectorAcc operator * (double r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const doubleAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r2,const doubleAcc& r1);
+ IMETHOD friend VectorAcc operator*(const Rotation& R,const VectorAcc& x);
+
+ IMETHOD friend VectorAcc operator / (const VectorAcc& r1,double r2);
+ IMETHOD friend VectorAcc operator / (const VectorAcc& r2,const doubleAcc& r1);
+
+
+ IMETHOD friend bool Equal(const VectorAcc& r1,const VectorAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Vector& r1,const VectorAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const VectorAcc& r1,const Vector& r2,double eps=epsilon);
+ IMETHOD friend VectorAcc operator - (const VectorAcc& r);
+ IMETHOD friend doubleAcc dot(const VectorAcc& lhs,const VectorAcc& rhs);
+ IMETHOD friend doubleAcc dot(const VectorAcc& lhs,const Vector& rhs);
+ IMETHOD friend doubleAcc dot(const Vector& lhs,const VectorAcc& rhs);
+};
+
+
+
+class RotationAcc
+{
+public:
+ Rotation R; //!< rotation matrix
+ Vector w; //!< angular velocity vector
+ Vector dw; //!< angular acceration vector
+public:
+ RotationAcc():R(),w() {}
+ explicit RotationAcc(const Rotation& _R):R(_R),w(Vector::Zero()){}
+ RotationAcc(const Rotation& _R,const Vector& _w,const Vector& _dw):
+ R(_R),w(_w),dw(_dw) {}
+ IMETHOD RotationAcc& operator = (const RotationAcc& arg);
+ IMETHOD RotationAcc& operator = (const Rotation& arg);
+ IMETHOD static RotationAcc Identity();
+ IMETHOD RotationAcc Inverse() const;
+ IMETHOD VectorAcc Inverse(const VectorAcc& arg) const;
+ IMETHOD VectorAcc Inverse(const Vector& arg) const;
+ IMETHOD VectorAcc operator*(const VectorAcc& arg) const;
+ IMETHOD VectorAcc operator*(const Vector& arg) const;
+
+ // Rotations
+ // The SetRot.. functions set the value of *this to the appropriate rotation matrix.
+ // The Rot... static functions give the value of the appropriate rotation matrix back.
+ // The DoRot... functions apply a rotation R to *this,such that *this = *this * R.
+ // IMETHOD void DoRotX(const doubleAcc& angle);
+ // IMETHOD void DoRotY(const doubleAcc& angle);
+ // IMETHOD void DoRotZ(const doubleAcc& angle);
+ // IMETHOD static RRotation RotX(const doubleAcc& angle);
+ // IMETHOD static RRotation RotY(const doubleAcc& angle);
+ // IMETHOD static RRotation RotZ(const doubleAcc& angle);
+
+ // IMETHOD void SetRot(const Vector& rotaxis,const doubleAcc& angle);
+ // Along an arbitrary axes. The norm of rotvec is neglected.
+ // IMETHOD static RotationAcc Rot(const Vector& rotvec,const doubleAcc& angle);
+ // rotvec has arbitrary norm
+ // rotation around a constant vector !
+ // IMETHOD static RotationAcc Rot2(const Vector& rotvec,const doubleAcc& angle);
+ // rotvec is normalized.
+ // rotation around a constant vector !
+
+ IMETHOD friend RotationAcc operator* (const RotationAcc& r1,const RotationAcc& r2);
+ IMETHOD friend RotationAcc operator* (const Rotation& r1,const RotationAcc& r2);
+ IMETHOD friend RotationAcc operator* (const RotationAcc& r1,const Rotation& r2);
+ IMETHOD friend bool Equal(const RotationAcc& r1,const RotationAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Rotation& r1,const RotationAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const RotationAcc& r1,const Rotation& r2,double eps=epsilon);
+ IMETHOD TwistAcc Inverse(const TwistAcc& arg) const;
+ IMETHOD TwistAcc Inverse(const Twist& arg) const;
+ IMETHOD TwistAcc operator * (const TwistAcc& arg) const;
+ IMETHOD TwistAcc operator * (const Twist& arg) const;
+};
+
+
+
+
+class FrameAcc
+{
+public:
+ RotationAcc M; //!< Rotation,angular velocity, and angular acceleration of frame.
+ VectorAcc p; //!< Translation, velocity and acceleration of origin.
+public:
+ FrameAcc(){}
+ explicit FrameAcc(const Frame& _T):M(_T.M),p(_T.p) {}
+ FrameAcc(const Frame& _T,const Twist& _t,const Twist& _dt):
+ M(_T.M,_t.rot,_dt.rot),p(_T.p,_t.vel,_dt.vel) {}
+ FrameAcc(const RotationAcc& _M,const VectorAcc& _p):M(_M),p(_p) {}
+
+ IMETHOD FrameAcc& operator = (const FrameAcc& arg);
+ IMETHOD FrameAcc& operator = (const Frame& arg);
+ IMETHOD static FrameAcc Identity();
+ IMETHOD FrameAcc Inverse() const;
+ IMETHOD VectorAcc Inverse(const VectorAcc& arg) const;
+ IMETHOD VectorAcc operator*(const VectorAcc& arg) const;
+ IMETHOD VectorAcc operator*(const Vector& arg) const;
+ IMETHOD VectorAcc Inverse(const Vector& arg) const;
+ IMETHOD Frame GetFrame() const;
+ IMETHOD Twist GetTwist() const;
+ IMETHOD Twist GetAccTwist() const;
+ IMETHOD friend FrameAcc operator * (const FrameAcc& f1,const FrameAcc& f2);
+ IMETHOD friend FrameAcc operator * (const Frame& f1,const FrameAcc& f2);
+ IMETHOD friend FrameAcc operator * (const FrameAcc& f1,const Frame& f2);
+ IMETHOD friend bool Equal(const FrameAcc& r1,const FrameAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Frame& r1,const FrameAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const FrameAcc& r1,const Frame& r2,double eps=epsilon);
+
+ IMETHOD TwistAcc Inverse(const TwistAcc& arg) const;
+ IMETHOD TwistAcc Inverse(const Twist& arg) const;
+ IMETHOD TwistAcc operator * (const TwistAcc& arg) const;
+ IMETHOD TwistAcc operator * (const Twist& arg) const;
+};
+
+
+
+
+
+
+
+
+//very similar to Wrench class.
+class TwistAcc
+{
+public:
+ VectorAcc vel; //!< translational velocity and its 1st and 2nd derivative
+ VectorAcc rot; //!< rotational velocity and its 1st and 2nd derivative
+public:
+
+ TwistAcc():vel(),rot() {};
+ TwistAcc(const VectorAcc& _vel,const VectorAcc& _rot):vel(_vel),rot(_rot) {};
+
+ IMETHOD TwistAcc& operator-=(const TwistAcc& arg);
+ IMETHOD TwistAcc& operator+=(const TwistAcc& arg);
+
+ IMETHOD friend TwistAcc operator*(const TwistAcc& lhs,double rhs);
+ IMETHOD friend TwistAcc operator*(double lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator/(const TwistAcc& lhs,double rhs);
+
+ IMETHOD friend TwistAcc operator*(const TwistAcc& lhs,const doubleAcc& rhs);
+ IMETHOD friend TwistAcc operator*(const doubleAcc& lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator/(const TwistAcc& lhs,const doubleAcc& rhs);
+
+ IMETHOD friend TwistAcc operator+(const TwistAcc& lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator-(const TwistAcc& lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator-(const TwistAcc& arg);
+
+ IMETHOD friend void SetToZero(TwistAcc& v);
+
+ static IMETHOD TwistAcc Zero();
+
+ IMETHOD void ReverseSign();
+
+ IMETHOD TwistAcc RefPoint(const VectorAcc& v_base_AB);
+ // Changes the reference point of the RTwist.
+ // The RVector v_base_AB is expressed in the same base as the RTwist
+ // The RVector v_base_AB is a RVector from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+
+ IMETHOD friend bool Equal(const TwistAcc& a,const TwistAcc& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const Twist& a,const TwistAcc& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const TwistAcc& a,const Twist& b,double eps=epsilon);
+
+
+ IMETHOD Twist GetTwist() const;
+ IMETHOD Twist GetTwistDot() const;
+
+ friend class RotationAcc;
+ friend class FrameAcc;
+
+};
+
+
+
+
+
+
+
+#ifdef KDL_INLINE
+#include "frameacc.inl"
+#endif
+
+}
+
+
+
+
+
+#endif
diff --git a/intern/itasc/kdl/frameacc.inl b/intern/itasc/kdl/frameacc.inl
new file mode 100644
index 00000000000..a8ea35ad436
--- /dev/null
+++ b/intern/itasc/kdl/frameacc.inl
@@ -0,0 +1,598 @@
+/*****************************************************************************
+ * \file
+ * provides inline functions of rrframes.h
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: frameacc.inl 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+
+
+/////////////////// VectorAcc /////////////////////////////////////
+
+VectorAcc operator + (const VectorAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.p+r2.p,r1.v+r2.v,r1.dv+r2.dv);
+}
+
+VectorAcc operator - (const VectorAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.p-r2.p, r1.v-r2.v, r1.dv-r2.dv);
+}
+VectorAcc operator + (const Vector& r1,const VectorAcc& r2) {
+ return VectorAcc(r1+r2.p,r2.v,r2.dv);
+}
+
+VectorAcc operator - (const Vector& r1,const VectorAcc& r2) {
+ return VectorAcc(r1-r2.p, -r2.v, -r2.dv);
+}
+VectorAcc operator + (const VectorAcc& r1,const Vector& r2) {
+ return VectorAcc(r1.p+r2,r1.v,r1.dv);
+}
+
+VectorAcc operator - (const VectorAcc& r1,const Vector& r2) {
+ return VectorAcc(r1.p-r2, r1.v, r1.dv);
+}
+
+// unary -
+VectorAcc operator - (const VectorAcc& r) {
+ return VectorAcc(-r.p,-r.v,-r.dv);
+}
+
+// cross prod.
+VectorAcc operator * (const VectorAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.p*r2.p,
+ r1.p*r2.v+r1.v*r2.p,
+ r1.dv*r2.p+2*r1.v*r2.v+r1.p*r2.dv
+ );
+}
+
+VectorAcc operator * (const VectorAcc& r1,const Vector& r2) {
+ return VectorAcc(r1.p*r2, r1.v*r2, r1.dv*r2 );
+}
+
+VectorAcc operator * (const Vector& r1,const VectorAcc& r2) {
+ return VectorAcc(r1*r2.p, r1*r2.v, r1*r2.dv );
+}
+
+
+
+// scalar mult.
+VectorAcc operator * (double r1,const VectorAcc& r2) {
+ return VectorAcc(r1*r2.p, r1*r2.v, r1*r2.dv );
+}
+
+VectorAcc operator * (const VectorAcc& r1,double r2) {
+ return VectorAcc(r1.p*r2, r1.v*r2, r1.dv*r2 );
+}
+
+VectorAcc operator * (const doubleAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.t*r2.p,
+ r1.t*r2.v + r1.d*r2.p,
+ r1.t*r2.dv + 2*r1.d*r2.v + r1.dd*r2.p
+ );
+}
+
+VectorAcc operator * (const VectorAcc& r2,const doubleAcc& r1) {
+ return VectorAcc(r1.t*r2.p,
+ r1.t*r2.v + r1.d*r2.p,
+ r1.t*r2.dv + 2*r1.d*r2.v + r1.dd*r2.p
+ );
+}
+
+VectorAcc& VectorAcc::operator = (const VectorAcc& arg) {
+ p=arg.p;
+ v=arg.v;
+ dv=arg.dv;
+ return *this;
+}
+
+VectorAcc& VectorAcc::operator = (const Vector& arg) {
+ p=arg;
+ v=Vector::Zero();
+ dv=Vector::Zero();
+ return *this;
+}
+
+VectorAcc& VectorAcc::operator += (const VectorAcc& arg) {
+ p+=arg.p;
+ v+=arg.v;
+ dv+= arg.dv;
+ return *this;
+}
+VectorAcc& VectorAcc::operator -= (const VectorAcc& arg) {
+ p-=arg.p;
+ v-=arg.v;
+ dv-=arg.dv;
+ return *this;
+}
+
+VectorAcc VectorAcc::Zero() {
+ return VectorAcc(Vector::Zero(),Vector::Zero(),Vector::Zero());
+}
+
+void VectorAcc::ReverseSign() {
+ p.ReverseSign();
+ v.ReverseSign();
+ dv.ReverseSign();
+}
+
+doubleAcc VectorAcc::Norm() {
+ doubleAcc res;
+ res.t = p.Norm();
+ res.d = dot(p,v)/res.t;
+ res.dd = (dot(p,dv)+dot(v,v)-res.d*res.d)/res.t;
+ return res;
+}
+
+doubleAcc dot(const VectorAcc& lhs,const VectorAcc& rhs) {
+ return doubleAcc( dot(lhs.p,rhs.p),
+ dot(lhs.p,rhs.v)+dot(lhs.v,rhs.p),
+ dot(lhs.p,rhs.dv)+2*dot(lhs.v,rhs.v)+dot(lhs.dv,rhs.p)
+ );
+}
+
+doubleAcc dot(const VectorAcc& lhs,const Vector& rhs) {
+ return doubleAcc( dot(lhs.p,rhs),
+ dot(lhs.v,rhs),
+ dot(lhs.dv,rhs)
+ );
+}
+
+doubleAcc dot(const Vector& lhs,const VectorAcc& rhs) {
+ return doubleAcc( dot(lhs,rhs.p),
+ dot(lhs,rhs.v),
+ dot(lhs,rhs.dv)
+ );
+}
+
+
+bool Equal(const VectorAcc& r1,const VectorAcc& r2,double eps) {
+ return (Equal(r1.p,r2.p,eps)
+ && Equal(r1.v,r2.v,eps)
+ && Equal(r1.dv,r2.dv,eps)
+ );
+}
+
+bool Equal(const Vector& r1,const VectorAcc& r2,double eps) {
+ return (Equal(r1,r2.p,eps)
+ && Equal(Vector::Zero(),r2.v,eps)
+ && Equal(Vector::Zero(),r2.dv,eps)
+ );
+}
+
+bool Equal(const VectorAcc& r1,const Vector& r2,double eps) {
+ return (Equal(r1.p,r2,eps)
+ && Equal(r1.v,Vector::Zero(),eps)
+ && Equal(r1.dv,Vector::Zero(),eps)
+ );
+}
+
+VectorAcc operator / (const VectorAcc& r1,double r2) {
+ return r1*(1.0/r2);
+}
+
+VectorAcc operator / (const VectorAcc& r2,const doubleAcc& r1) {
+ return r2*(1.0/r1);
+}
+
+
+
+/////////////////// RotationAcc /////////////////////////////////////
+
+RotationAcc operator* (const RotationAcc& r1,const RotationAcc& r2) {
+ return RotationAcc( r1.R * r2.R,
+ r1.w + r1.R*r2.w,
+ r1.dw + r1.w*(r1.R*r2.w) + r1.R*r2.dw
+ );
+}
+
+RotationAcc operator* (const Rotation& r1,const RotationAcc& r2) {
+ return RotationAcc( r1*r2.R, r1*r2.w, r1*r2.dw);
+}
+
+RotationAcc operator* (const RotationAcc& r1,const Rotation& r2) {
+ return RotationAcc( r1.R*r2, r1.w, r1.dw );
+}
+
+RotationAcc& RotationAcc::operator = (const RotationAcc& arg) {
+ R=arg.R;
+ w=arg.w;
+ dw=arg.dw;
+ return *this;
+}
+RotationAcc& RotationAcc::operator = (const Rotation& arg) {
+ R = arg;
+ w = Vector::Zero();
+ dw = Vector::Zero();
+ return *this;
+}
+
+RotationAcc RotationAcc::Identity() {
+ return RotationAcc(Rotation::Identity(),Vector::Zero(),Vector::Zero());
+}
+
+RotationAcc RotationAcc::Inverse() const {
+ return RotationAcc(R.Inverse(),-R.Inverse(w),-R.Inverse(dw));
+}
+
+VectorAcc RotationAcc::Inverse(const VectorAcc& arg) const {
+ VectorAcc tmp;
+ tmp.p = R.Inverse(arg.p);
+ tmp.v = R.Inverse(arg.v - w * arg.p);
+ tmp.dv = R.Inverse(arg.dv - dw*arg.p - w*(arg.v+R*tmp.v));
+ return tmp;
+}
+
+VectorAcc RotationAcc::Inverse(const Vector& arg) const {
+ VectorAcc tmp;
+ tmp.p = R.Inverse(arg);
+ tmp.v = R.Inverse(-w*arg);
+ tmp.dv = R.Inverse(-dw*arg - w*(R*tmp.v));
+ return tmp;
+}
+
+
+VectorAcc RotationAcc::operator*(const VectorAcc& arg) const {
+ VectorAcc tmp;
+ tmp.p = R*arg.p;
+ tmp.dv = R*arg.v;
+ tmp.v = w*tmp.p + tmp.dv;
+ tmp.dv = dw*tmp.p + w*(tmp.v + tmp.dv) + R*arg.dv;
+ return tmp;
+}
+
+VectorAcc operator*(const Rotation& R,const VectorAcc& x) {
+ return VectorAcc(R*x.p,R*x.v,R*x.dv);
+}
+
+VectorAcc RotationAcc::operator*(const Vector& arg) const {
+ VectorAcc tmp;
+ tmp.p = R*arg;
+ tmp.v = w*tmp.p;
+ tmp.dv = dw*tmp.p + w*tmp.v;
+ return tmp;
+}
+
+/*
+ // = Rotations
+ // The Rot... static functions give the value of the appropriate rotation matrix back.
+ // The DoRot... functions apply a rotation R to *this,such that *this = *this * R.
+
+ void RRotation::DoRotX(const RDouble& angle) {
+ w+=R*Vector(angle.grad,0,0);
+ R.DoRotX(angle.t);
+ }
+RotationAcc RotationAcc::RotX(const doubleAcc& angle) {
+ return RotationAcc(Rotation::RotX(angle.t),
+ Vector(angle.d,0,0),
+ Vector(angle.dd,0,0)
+ );
+}
+
+ void RRotation::DoRotY(const RDouble& angle) {
+ w+=R*Vector(0,angle.grad,0);
+ R.DoRotY(angle.t);
+ }
+RotationAcc RotationAcc::RotY(const doubleAcc& angle) {
+ return RotationAcc(
+ Rotation::RotX(angle.t),
+ Vector(0,angle.d,0),
+ Vector(0,angle.dd,0)
+ );
+}
+
+ void RRotation::DoRotZ(const RDouble& angle) {
+ w+=R*Vector(0,0,angle.grad);
+ R.DoRotZ(angle.t);
+ }
+RotationAcc RotationAcc::RotZ(const doubleAcc& angle) {
+ return RotationAcc(
+ Rotation::RotZ(angle.t),
+ Vector(0,0,angle.d),
+ Vector(0,0,angle.dd)
+ );
+}
+
+
+ RRotation RRotation::Rot(const Vector& rotvec,const RDouble& angle)
+ // rotvec has arbitrary norm
+ // rotation around a constant vector !
+ {
+ Vector v = rotvec.Normalize();
+ return RRotation(Rotation::Rot2(v,angle.t),v*angle.grad);
+ }
+
+ RRotation RRotation::Rot2(const Vector& rotvec,const RDouble& angle)
+ // rotvec is normalized.
+ {
+ return RRotation(Rotation::Rot2(rotvec,angle.t),rotvec*angle.grad);
+ }
+
+*/
+
+bool Equal(const RotationAcc& r1,const RotationAcc& r2,double eps) {
+ return (Equal(r1.w,r2.w,eps) && Equal(r1.R,r2.R,eps) && Equal(r1.dw,r2.dw,eps) );
+}
+bool Equal(const Rotation& r1,const RotationAcc& r2,double eps) {
+ return (Equal(Vector::Zero(),r2.w,eps) && Equal(r1,r2.R,eps) &&
+ Equal(Vector::Zero(),r2.dw,eps) );
+}
+bool Equal(const RotationAcc& r1,const Rotation& r2,double eps) {
+ return (Equal(r1.w,Vector::Zero(),eps) && Equal(r1.R,r2,eps) &&
+ Equal(r1.dw,Vector::Zero(),eps) );
+}
+
+
+// Methods and operators related to FrameAcc
+// They all delegate most of the work to RotationAcc and VectorAcc
+FrameAcc& FrameAcc::operator = (const FrameAcc& arg) {
+ M=arg.M;
+ p=arg.p;
+ return *this;
+}
+
+FrameAcc FrameAcc::Identity() {
+ return FrameAcc(RotationAcc::Identity(),VectorAcc::Zero());
+}
+
+
+FrameAcc operator *(const FrameAcc& lhs,const FrameAcc& rhs)
+{
+ return FrameAcc(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameAcc operator *(const FrameAcc& lhs,const Frame& rhs)
+{
+ return FrameAcc(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameAcc operator *(const Frame& lhs,const FrameAcc& rhs)
+{
+ return FrameAcc(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+
+VectorAcc FrameAcc::operator *(const VectorAcc & arg) const
+{
+ return M*arg+p;
+}
+VectorAcc FrameAcc::operator *(const Vector & arg) const
+{
+ return M*arg+p;
+}
+
+VectorAcc FrameAcc::Inverse(const VectorAcc& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+VectorAcc FrameAcc::Inverse(const Vector& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+FrameAcc FrameAcc::Inverse() const
+{
+ return FrameAcc(M.Inverse(),-M.Inverse(p));
+}
+
+FrameAcc& FrameAcc::operator =(const Frame & arg)
+{
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+
+bool Equal(const FrameAcc& r1,const FrameAcc& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const Frame& r1,const FrameAcc& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const FrameAcc& r1,const Frame& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+
+
+Frame FrameAcc::GetFrame() const {
+ return Frame(M.R,p.p);
+}
+
+
+Twist FrameAcc::GetTwist() const {
+ return Twist(p.v,M.w);
+}
+
+
+Twist FrameAcc::GetAccTwist() const {
+ return Twist(p.dv,M.dw);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+TwistAcc TwistAcc::Zero()
+{
+ return TwistAcc(VectorAcc::Zero(),VectorAcc::Zero());
+}
+
+
+void TwistAcc::ReverseSign()
+{
+ vel.ReverseSign();
+ rot.ReverseSign();
+}
+
+TwistAcc TwistAcc::RefPoint(const VectorAcc& v_base_AB)
+ // Changes the reference point of the TwistAcc.
+ // The RVector v_base_AB is expressed in the same base as the TwistAcc
+ // The RVector v_base_AB is a RVector from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+{
+ return TwistAcc(this->vel+this->rot*v_base_AB,this->rot);
+}
+
+TwistAcc& TwistAcc::operator-=(const TwistAcc& arg)
+{
+ vel-=arg.vel;
+ rot -=arg.rot;
+ return *this;
+}
+
+TwistAcc& TwistAcc::operator+=(const TwistAcc& arg)
+{
+ vel+=arg.vel;
+ rot +=arg.rot;
+ return *this;
+}
+
+
+TwistAcc operator*(const TwistAcc& lhs,double rhs)
+{
+ return TwistAcc(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistAcc operator*(double lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistAcc operator/(const TwistAcc& lhs,double rhs)
+{
+ return TwistAcc(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+TwistAcc operator*(const TwistAcc& lhs,const doubleAcc& rhs)
+{
+ return TwistAcc(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistAcc operator*(const doubleAcc& lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistAcc operator/(const TwistAcc& lhs,const doubleAcc& rhs)
+{
+ return TwistAcc(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+
+// addition of TwistAcc's
+TwistAcc operator+(const TwistAcc& lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
+}
+
+TwistAcc operator-(const TwistAcc& lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
+}
+
+// unary -
+TwistAcc operator-(const TwistAcc& arg)
+{
+ return TwistAcc(-arg.vel,-arg.rot);
+}
+
+
+
+
+
+TwistAcc RotationAcc::Inverse(const TwistAcc& arg) const
+{
+ return TwistAcc(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistAcc RotationAcc::operator * (const TwistAcc& arg) const
+{
+ return TwistAcc((*this)*arg.vel,(*this)*arg.rot);
+}
+
+TwistAcc RotationAcc::Inverse(const Twist& arg) const
+{
+ return TwistAcc(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistAcc RotationAcc::operator * (const Twist& arg) const
+{
+ return TwistAcc((*this)*arg.vel,(*this)*arg.rot);
+}
+
+
+TwistAcc FrameAcc::operator * (const TwistAcc& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistAcc FrameAcc::operator * (const Twist& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistAcc FrameAcc::Inverse(const TwistAcc& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+TwistAcc FrameAcc::Inverse(const Twist& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+Twist TwistAcc::GetTwist() const {
+ return Twist(vel.p,rot.p);
+}
+
+Twist TwistAcc::GetTwistDot() const {
+ return Twist(vel.v,rot.v);
+}
+
+bool Equal(const TwistAcc& a,const TwistAcc& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const Twist& a,const TwistAcc& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const TwistAcc& a,const Twist& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+
diff --git a/intern/itasc/kdl/frames.cpp b/intern/itasc/kdl/frames.cpp
new file mode 100644
index 00000000000..7dcc39f2cd4
--- /dev/null
+++ b/intern/itasc/kdl/frames.cpp
@@ -0,0 +1,389 @@
+/***************************************************************************
+ frames.cxx - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+#include "frames.hpp"
+
+namespace KDL {
+
+#ifndef KDL_INLINE
+#include "frames.inl"
+#endif
+
+void Frame::Make4x4(double * d)
+{
+ int i;
+ int j;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ d[i*4+j]=M(i,j);
+ d[i*4+3] = p(i)/1000;
+ }
+ for (j=0;j<3;j++)
+ d[12+j] = 0.;
+ d[15] = 1;
+}
+
+Frame Frame::DH_Craig1989(double a,double alpha,double d,double theta)
+// returns Modified Denavit-Hartenberg parameters (According to Craig)
+{
+ double ct,st,ca,sa;
+ ct = cos(theta);
+ st = sin(theta);
+ sa = sin(alpha);
+ ca = cos(alpha);
+ return Frame(Rotation(
+ ct, -st, 0,
+ st*ca, ct*ca, -sa,
+ st*sa, ct*sa, ca ),
+ Vector(
+ a, -sa*d, ca*d )
+ );
+}
+
+Frame Frame::DH(double a,double alpha,double d,double theta)
+// returns Denavit-Hartenberg parameters (Non-Modified DH)
+{
+ double ct,st,ca,sa;
+ ct = cos(theta);
+ st = sin(theta);
+ sa = sin(alpha);
+ ca = cos(alpha);
+ return Frame(Rotation(
+ ct, -st*ca, st*sa,
+ st, ct*ca, -ct*sa,
+ 0, sa, ca ),
+ Vector(
+ a*ct, a*st, d )
+ );
+}
+
+double Vector2::Norm() const
+{
+ double tmp0 = fabs(data[0]);
+ double tmp1 = fabs(data[1]);
+ if (tmp0 >= tmp1) {
+ if (tmp1 == 0)
+ return 0;
+ return tmp0*sqrt(1+sqr(tmp1/tmp0));
+ } else {
+ return tmp1*sqrt(1+sqr(tmp0/tmp1));
+ }
+}
+// makes v a unitvector and returns the norm of v.
+// if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+// if this is not good, check the return value of this method.
+double Vector2::Normalize(double eps) {
+ double v = this->Norm();
+ if (v < eps) {
+ *this = Vector2(1,0);
+ return v;
+ } else {
+ *this = (*this)/v;
+ return v;
+ }
+}
+
+
+// do some effort not to lose precision
+double Vector::Norm() const
+{
+ double tmp1;
+ double tmp2;
+ tmp1 = fabs(data[0]);
+ tmp2 = fabs(data[1]);
+ if (tmp1 >= tmp2) {
+ tmp2=fabs(data[2]);
+ if (tmp1 >= tmp2) {
+ if (tmp1 == 0) {
+ // only to everything exactly zero case, all other are handled correctly
+ return 0;
+ }
+ return tmp1*sqrt(1+sqr(data[1]/data[0])+sqr(data[2]/data[0]));
+ } else {
+ return tmp2*sqrt(1+sqr(data[0]/data[2])+sqr(data[1]/data[2]));
+ }
+ } else {
+ tmp1=fabs(data[2]);
+ if (tmp2 > tmp1) {
+ return tmp2*sqrt(1+sqr(data[0]/data[1])+sqr(data[2]/data[1]));
+ } else {
+ return tmp1*sqrt(1+sqr(data[0]/data[2])+sqr(data[1]/data[2]));
+ }
+ }
+}
+
+// makes v a unitvector and returns the norm of v.
+// if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+// if this is not good, check the return value of this method.
+double Vector::Normalize(double eps) {
+ double v = this->Norm();
+ if (v < eps) {
+ *this = Vector(1,0,0);
+ return v;
+ } else {
+ *this = (*this)/v;
+ return v;
+ }
+}
+
+
+bool Equal(const Rotation& a,const Rotation& b,double eps) {
+ return (Equal(a.data[0],b.data[0],eps) &&
+ Equal(a.data[1],b.data[1],eps) &&
+ Equal(a.data[2],b.data[2],eps) &&
+ Equal(a.data[3],b.data[3],eps) &&
+ Equal(a.data[4],b.data[4],eps) &&
+ Equal(a.data[5],b.data[5],eps) &&
+ Equal(a.data[6],b.data[6],eps) &&
+ Equal(a.data[7],b.data[7],eps) &&
+ Equal(a.data[8],b.data[8],eps) );
+}
+
+void Rotation::Ortho()
+{
+ double n;
+ n=sqrt(sqr(data[0])+sqr(data[3])+sqr(data[6]));n=(n>1e-10)?1.0/n:0.0;data[0]*=n;data[3]*=n;data[6]*=n;
+ n=sqrt(sqr(data[1])+sqr(data[4])+sqr(data[7]));n=(n>1e-10)?1.0/n:0.0;data[1]*=n;data[4]*=n;data[7]*=n;
+ n=sqrt(sqr(data[2])+sqr(data[5])+sqr(data[8]));n=(n>1e-10)?1.0/n:0.0;data[2]*=n;data[5]*=n;data[8]*=n;
+}
+
+Rotation operator *(const Rotation& lhs,const Rotation& rhs)
+// Complexity : 27M+27A
+{
+ return Rotation(
+ lhs.data[0]*rhs.data[0]+lhs.data[1]*rhs.data[3]+lhs.data[2]*rhs.data[6],
+ lhs.data[0]*rhs.data[1]+lhs.data[1]*rhs.data[4]+lhs.data[2]*rhs.data[7],
+ lhs.data[0]*rhs.data[2]+lhs.data[1]*rhs.data[5]+lhs.data[2]*rhs.data[8],
+ lhs.data[3]*rhs.data[0]+lhs.data[4]*rhs.data[3]+lhs.data[5]*rhs.data[6],
+ lhs.data[3]*rhs.data[1]+lhs.data[4]*rhs.data[4]+lhs.data[5]*rhs.data[7],
+ lhs.data[3]*rhs.data[2]+lhs.data[4]*rhs.data[5]+lhs.data[5]*rhs.data[8],
+ lhs.data[6]*rhs.data[0]+lhs.data[7]*rhs.data[3]+lhs.data[8]*rhs.data[6],
+ lhs.data[6]*rhs.data[1]+lhs.data[7]*rhs.data[4]+lhs.data[8]*rhs.data[7],
+ lhs.data[6]*rhs.data[2]+lhs.data[7]*rhs.data[5]+lhs.data[8]*rhs.data[8]
+ );
+
+}
+
+
+Rotation Rotation::RPY(double roll,double pitch,double yaw)
+ {
+ double ca1,cb1,cc1,sa1,sb1,sc1;
+ ca1 = cos(yaw); sa1 = sin(yaw);
+ cb1 = cos(pitch);sb1 = sin(pitch);
+ cc1 = cos(roll);sc1 = sin(roll);
+ return Rotation(ca1*cb1,ca1*sb1*sc1 - sa1*cc1,ca1*sb1*cc1 + sa1*sc1,
+ sa1*cb1,sa1*sb1*sc1 + ca1*cc1,sa1*sb1*cc1 - ca1*sc1,
+ -sb1,cb1*sc1,cb1*cc1);
+ }
+
+// Gives back a rotation matrix specified with RPY convention
+void Rotation::GetRPY(double& roll,double& pitch,double& yaw) const
+ {
+ if (fabs(data[6]) > 1.0 - epsilon ) {
+ roll = -sign(data[6]) * atan2(data[1], data[4]);
+ pitch= -sign(data[6]) * PI / 2;
+ yaw = 0.0 ;
+ } else {
+ roll = atan2(data[7], data[8]);
+ pitch = atan2(-data[6], sqrt( sqr(data[0]) +sqr(data[3]) ) );
+ yaw = atan2(data[3], data[0]);
+ }
+ }
+
+Rotation Rotation::EulerZYZ(double Alfa,double Beta,double Gamma) {
+ double sa,ca,sb,cb,sg,cg;
+ sa = sin(Alfa);ca = cos(Alfa);
+ sb = sin(Beta);cb = cos(Beta);
+ sg = sin(Gamma);cg = cos(Gamma);
+ return Rotation( ca*cb*cg-sa*sg, -ca*cb*sg-sa*cg, ca*sb,
+ sa*cb*cg+ca*sg, -sa*cb*sg+ca*cg, sa*sb,
+ -sb*cg , sb*sg, cb
+ );
+
+ }
+
+
+void Rotation::GetEulerZYZ(double& alfa,double& beta,double& gamma) const {
+ if (fabs(data[6]) < epsilon ) {
+ alfa=0.0;
+ if (data[8]>0) {
+ beta = 0.0;
+ gamma= atan2(-data[1],data[0]);
+ } else {
+ beta = PI;
+ gamma= atan2(data[1],-data[0]);
+ }
+ } else {
+ alfa=atan2(data[5], data[2]);
+ beta=atan2(sqrt( sqr(data[6]) +sqr(data[7]) ),data[8]);
+ gamma=atan2(data[7], -data[6]);
+ }
+ }
+
+Rotation Rotation::Rot(const Vector& rotaxis,double angle) {
+ // The formula is
+ // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
+ // can be found by multiplying it with an arbitrary vector p
+ // and noting that this vector is rotated.
+ double ct = cos(angle);
+ double st = sin(angle);
+ double vt = 1-ct;
+ Vector rotvec = rotaxis;
+ rotvec.Normalize();
+ return Rotation(
+ ct + vt*rotvec(0)*rotvec(0),
+ -rotvec(2)*st + vt*rotvec(0)*rotvec(1),
+ rotvec(1)*st + vt*rotvec(0)*rotvec(2),
+ rotvec(2)*st + vt*rotvec(1)*rotvec(0),
+ ct + vt*rotvec(1)*rotvec(1),
+ -rotvec(0)*st + vt*rotvec(1)*rotvec(2),
+ -rotvec(1)*st + vt*rotvec(2)*rotvec(0),
+ rotvec(0)*st + vt*rotvec(2)*rotvec(1),
+ ct + vt*rotvec(2)*rotvec(2)
+ );
+ }
+
+Rotation Rotation::Rot2(const Vector& rotvec,double angle) {
+ // rotvec should be normalized !
+ // The formula is
+ // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
+ // can be found by multiplying it with an arbitrary vector p
+ // and noting that this vector is rotated.
+ double ct = cos(angle);
+ double st = sin(angle);
+ double vt = 1-ct;
+ return Rotation(
+ ct + vt*rotvec(0)*rotvec(0),
+ -rotvec(2)*st + vt*rotvec(0)*rotvec(1),
+ rotvec(1)*st + vt*rotvec(0)*rotvec(2),
+ rotvec(2)*st + vt*rotvec(1)*rotvec(0),
+ ct + vt*rotvec(1)*rotvec(1),
+ -rotvec(0)*st + vt*rotvec(1)*rotvec(2),
+ -rotvec(1)*st + vt*rotvec(2)*rotvec(0),
+ rotvec(0)*st + vt*rotvec(2)*rotvec(1),
+ ct + vt*rotvec(2)*rotvec(2)
+ );
+}
+
+
+
+Vector Rotation::GetRot() const
+ // Returns a vector with the direction of the equiv. axis
+ // and its norm is angle
+ {
+ Vector axis = Vector((data[7]-data[5]),
+ (data[2]-data[6]),
+ (data[3]-data[1]) )/2;
+
+ double sa = axis.Norm();
+ double ca = (data[0]+data[4]+data[8]-1)/2.0;
+ double alfa;
+ if (sa > epsilon)
+ alfa = ::atan2(sa,ca)/sa;
+ else {
+ if (ca < 0.0) {
+ alfa = KDL::PI;
+ axis.data[0] = 0.0;
+ axis.data[1] = 0.0;
+ axis.data[2] = 0.0;
+ if (data[0] > 0.0) {
+ axis.data[0] = 1.0;
+ } else if (data[4] > 0.0) {
+ axis.data[1] = 1.0;
+ } else {
+ axis.data[2] = 1.0;
+ }
+ } else {
+ alfa = 0.0;
+ }
+ }
+ return axis * alfa;
+ }
+
+Vector2 Rotation::GetXZRot() const
+{
+ // [0,1,0] x Y
+ Vector2 axis(data[7], -data[1]);
+ double norm = axis.Normalize();
+ if (norm < epsilon) {
+ norm = (data[4] < 0.0) ? PI : 0.0;
+ } else {
+ norm = acos(data[4]);
+ }
+ return axis*norm;
+}
+
+
+/** Returns the rotation angle around the equiv. axis
+ * @param axis the rotation axis is returned in this variable
+ * @param eps : in the case of angle == 0 : rot axis is undefined and choosen
+ * to be +/- Z-axis
+ * in the case of angle == PI : 2 solutions, positive Z-component
+ * of the axis is choosen.
+ * @result returns the rotation angle (between [0..PI] )
+ * /todo :
+ * Check corresponding routines in rframes and rrframes
+ */
+double Rotation::GetRotAngle(Vector& axis,double eps) const {
+ double ca = (data[0]+data[4]+data[8]-1)/2.0;
+ if (ca>1-eps) {
+ // undefined choose the Z-axis, and angle 0
+ axis = Vector(0,0,1);
+ return 0;
+ }
+ if (ca < -1+eps) {
+ // two solutions, choose a positive Z-component of the axis
+ double z = sqrt( (data[8]+1)/2 );
+ double x = (data[2])/2/z;
+ double y = (data[5])/2/z;
+ axis = Vector( x,y,z );
+ return PI;
+ }
+ double angle = acos(ca);
+ double sa = sin(angle);
+ axis = Vector((data[7]-data[5])/2/sa,
+ (data[2]-data[6])/2/sa,
+ (data[3]-data[1])/2/sa );
+ return angle;
+}
+
+bool operator==(const Rotation& a,const Rotation& b) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return ( a.data[0]==b.data[0] &&
+ a.data[1]==b.data[1] &&
+ a.data[2]==b.data[2] &&
+ a.data[3]==b.data[3] &&
+ a.data[4]==b.data[4] &&
+ a.data[5]==b.data[5] &&
+ a.data[6]==b.data[6] &&
+ a.data[7]==b.data[7] &&
+ a.data[8]==b.data[8] );
+#endif
+}
+}
diff --git a/intern/itasc/kdl/frames.hpp b/intern/itasc/kdl/frames.hpp
new file mode 100644
index 00000000000..20590c5303e
--- /dev/null
+++ b/intern/itasc/kdl/frames.hpp
@@ -0,0 +1,1097 @@
+/***************************************************************************
+ frames.hpp `- description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+/**
+ * \file
+ * \warning
+ * Efficienty can be improved by writing p2 = A*(B*(C*p1))) instead of
+ * p2=A*B*C*p1
+ *
+ * \par PROPOSED NAMING CONVENTION FOR FRAME-like OBJECTS
+ *
+ * \verbatim
+ * A naming convention of objects of the type defined in this file :
+ * (1) Frame : F...
+ * Rotation : R ...
+ * (2) Twist : T ...
+ * Wrench : W ...
+ * Vector : V ...
+ * This prefix is followed by :
+ * for category (1) :
+ * F_A_B : w.r.t. frame A, frame B expressed
+ * ( each column of F_A_B corresponds to an axis of B,
+ * expressed w.r.t. frame A )
+ * in mathematical convention :
+ * A
+ * F_A_B == F
+ * B
+ *
+ * for category (2) :
+ * V_B : a vector expressed w.r.t. frame B
+ *
+ * This can also be prepended by a name :
+ * e.g. : temporaryV_B
+ *
+ * With this convention one can write :
+ *
+ * F_A_B = F_B_A.Inverse();
+ * F_A_C = F_A_B * F_B_C;
+ * V_B = F_B_C * V_C; // both translation and rotation
+ * V_B = R_B_C * V_C; // only rotation
+ * \endverbatim
+ *
+ * \par CONVENTIONS FOR WHEN USED WITH ROBOTS :
+ *
+ * \verbatim
+ * world : represents the frame ([1 0 0,0 1 0,0 0 1],[0 0 0]')
+ * mp : represents mounting plate of a robot
+ * (i.e. everything before MP is constructed by robot manufacturer
+ * everything after MP is tool )
+ * tf : represents task frame of a robot
+ * (i.e. frame in which motion and force control is expressed)
+ * sf : represents sensor frame of a robot
+ * (i.e. frame at which the forces measured by the force sensor
+ * are expressed )
+ *
+ * Frame F_world_mp=...;
+ * Frame F_mp_sf(..)
+ * Frame F_mp_tf(,.)
+ *
+ * Wrench are measured in sensor frame SF, so one could write :
+ * Wrench_tf = F_mp_tf.Inverse()* ( F_mp_sf * Wrench_sf );
+ * \endverbatim
+ *
+ * \par CONVENTIONS REGARDING UNITS :
+ * Any consistent series of units can be used, e.g. N,mm,Nmm,..mm/sec
+ *
+ * \par Twist and Wrench transformations
+ * 3 different types of transformations do exist for the twists
+ * and wrenches.
+ *
+ * \verbatim
+ * 1) Frame * Twist or Frame * Wrench :
+ * this transforms both the velocity/force reference point
+ * and the basis to which the twist/wrench are expressed.
+ * 2) Rotation * Twist or Rotation * Wrench :
+ * this transforms the basis to which the twist/wrench are
+ * expressed, but leaves the reference point intact.
+ * 3) Twist.RefPoint(v_base_AB) or Wrench.RefPoint(v_base_AB)
+ * this transforms only the reference point. v is expressed
+ * in the same base as the twist/wrench and points from the
+ * old reference point to the new reference point.
+ * \endverbatim
+ *
+ * \par Complexity
+ * Sometimes the amount of work is given in the documentation
+ * e.g. 6M+3A means 6 multiplications and 3 additions.
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ ****************************************************************************/
+#ifndef KDL_FRAMES_H
+#define KDL_FRAMES_H
+
+
+#include "utilities/kdl-config.h"
+#include "utilities/utility.h"
+
+/////////////////////////////////////////////////////////////
+
+namespace KDL {
+
+
+
+class Vector;
+class Rotation;
+class Frame;
+class Wrench;
+class Twist;
+class Vector2;
+class Rotation2;
+class Frame2;
+
+
+
+/**
+ * \brief A concrete implementation of a 3 dimensional vector class
+ */
+class Vector
+{
+public:
+ double data[3];
+ //! Does not initialise the Vector to zero. use Vector::Zero() or SetToZero for that
+ inline Vector() {data[0]=data[1]=data[2] = 0.0;}
+
+ //! Constructs a vector out of the three values x, y and z
+ inline Vector(double x,double y, double z);
+
+ //! Constructs a vector out of an array of three values x, y and z
+ inline Vector(double* xyz);
+
+ //! Constructs a vector out of an array of three values x, y and z
+ inline Vector(float* xyz);
+
+ //! Assignment operator. The normal copy by value semantics.
+ inline Vector(const Vector& arg);
+
+ //! store vector components in array
+ inline void GetValue(double* xyz) const;
+
+ //! Assignment operator. The normal copy by value semantics.
+ inline Vector& operator = ( const Vector& arg);
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..2
+ inline double operator()(int index) const;
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..2
+ inline double& operator() (int index);
+
+ //! Equivalent to double operator()(int index) const
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ //! Equivalent to double& operator()(int index)
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ inline double x() const;
+ inline double y() const;
+ inline double z() const;
+ inline void x(double);
+ inline void y(double);
+ inline void z(double);
+
+ //! Reverses the sign of the Vector object itself
+ inline void ReverseSign();
+
+
+ //! subtracts a vector from the Vector object itself
+ inline Vector& operator-=(const Vector& arg);
+
+
+ //! Adds a vector from the Vector object itself
+ inline Vector& operator +=(const Vector& arg);
+
+ //! Scalar multiplication is defined
+ inline friend Vector operator*(const Vector& lhs,double rhs);
+ //! Scalar multiplication is defined
+ inline friend Vector operator*(double lhs,const Vector& rhs);
+ //! Scalar division is defined
+
+ inline friend Vector operator/(const Vector& lhs,double rhs);
+ inline friend Vector operator+(const Vector& lhs,const Vector& rhs);
+ inline friend Vector operator-(const Vector& lhs,const Vector& rhs);
+ inline friend Vector operator*(const Vector& lhs,const Vector& rhs);
+ inline friend Vector operator-(const Vector& arg);
+ inline friend double dot(const Vector& lhs,const Vector& rhs);
+
+ //! To have a uniform operator to put an element to zero, for scalar values
+ //! and for objects.
+ inline friend void SetToZero(Vector& v);
+
+ //! @return a zero vector
+ inline static Vector Zero();
+
+ /** Normalizes this vector and returns it norm
+ * makes v a unitvector and returns the norm of v.
+ * if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+ * if this is not good, check the return value of this method.
+ */
+ double Normalize(double eps=epsilon);
+
+ //! @return the norm of the vector
+ double Norm() const;
+
+
+
+ //! a 3D vector where the 2D vector v is put in the XY plane
+ inline void Set2DXY(const Vector2& v);
+ //! a 3D vector where the 2D vector v is put in the YZ plane
+ inline void Set2DYZ(const Vector2& v);
+ //! a 3D vector where the 2D vector v is put in the ZX plane
+ inline void Set2DZX(const Vector2& v);
+ //! a 3D vector where the 2D vector v_XY is put in the XY plane of the frame F_someframe_XY.
+ inline void Set2DPlane(const Frame& F_someframe_XY,const Vector2& v_XY);
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Vector& a,const Vector& b,double eps=epsilon);
+
+ //! return a normalized vector
+ inline friend Vector Normalize(const Vector& a, double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Vector& a,const Vector& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Vector& a,const Vector& b);
+
+ friend class Rotation;
+ friend class Frame;
+};
+
+
+/**
+ \brief represents rotations in 3 dimensional space.
+
+ This class represents a rotation matrix with the following
+ conventions :
+ \verbatim
+ Suppose V2 = R*V, (1)
+ V is expressed in frame B
+ V2 is expressed in frame A
+ This matrix R consists of 3 collumns [ X,Y,Z ],
+ X,Y, and Z contain the axes of frame B, expressed in frame A
+ Because of linearity expr(1) is valid.
+ \endverbatim
+ This class only represents rotational_interpolation, not translation
+ Two interpretations are possible for rotation angles.
+ * if you rotate with angle around X frame A to have frame B,
+ then the result of SetRotX is equal to frame B expressed wrt A.
+ In code:
+ \verbatim
+ Rotation R;
+ F_A_B = R.SetRotX(angle);
+ \endverbatim
+ * Secondly, if you take the following code :
+ \verbatim
+ Vector p,p2; Rotation R;
+ R.SetRotX(angle);
+ p2 = R*p;
+ \endverbatim
+ then the frame p2 is rotated around X axis with (-angle).
+ Analogue reasonings can be applyd to SetRotY,SetRotZ,SetRot
+ \par type
+ Concrete implementation
+*/
+class Rotation
+{
+public:
+ double data[9];
+
+ inline Rotation() {
+ *this = Rotation::Identity();
+ }
+ inline Rotation(double Xx,double Yx,double Zx,
+ double Xy,double Yy,double Zy,
+ double Xz,double Yz,double Zz);
+ inline Rotation(const Vector& x,const Vector& y,const Vector& z);
+ // default copy constructor is sufficient
+
+ inline void setValue(float* oglmat);
+ inline void getValue(float* oglmat) const;
+
+ inline Rotation& operator=(const Rotation& arg);
+
+ //! Defines a multiplication R*V between a Rotation R and a Vector V.
+ //! Complexity : 9M+6A
+ inline Vector operator*(const Vector& v) const;
+
+ //! Access to elements 0..2,0..2, bounds are checked when NDEBUG is not set
+ inline double& operator()(int i,int j);
+
+ //! Access to elements 0..2,0..2, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ friend Rotation operator *(const Rotation& lhs,const Rotation& rhs);
+
+ //! Sets the value of *this to its inverse.
+ inline void SetInverse();
+
+ //! Gives back the inverse rotation matrix of *this.
+ inline Rotation Inverse() const;
+
+ //! The same as R.Inverse()*v but more efficient.
+ inline Vector Inverse(const Vector& v) const;
+
+ //! The same as R.Inverse()*arg but more efficient.
+ inline Wrench Inverse(const Wrench& arg) const;
+
+ //! The same as R.Inverse()*arg but more efficient.
+ inline Twist Inverse(const Twist& arg) const;
+
+ //! Gives back an identity rotaton matrix
+ inline static Rotation Identity();
+
+
+// = Rotations
+ //! The Rot... static functions give the value of the appropriate rotation matrix back.
+ inline static Rotation RotX(double angle);
+ //! The Rot... static functions give the value of the appropriate rotation matrix back.
+ inline static Rotation RotY(double angle);
+ //! The Rot... static functions give the value of the appropriate rotation matrix back.
+ inline static Rotation RotZ(double angle);
+ //! The DoRot... functions apply a rotation R to *this,such that *this = *this * Rot..
+ //! DoRot... functions are only defined when they can be executed more efficiently
+ inline void DoRotX(double angle);
+ //! The DoRot... functions apply a rotation R to *this,such that *this = *this * Rot..
+ //! DoRot... functions are only defined when they can be executed more efficiently
+ inline void DoRotY(double angle);
+ //! The DoRot... functions apply a rotation R to *this,such that *this = *this * Rot..
+ //! DoRot... functions are only defined when they can be executed more efficiently
+ inline void DoRotZ(double angle);
+
+ //! Along an arbitrary axes. It is not necessary to normalize rotaxis.
+ //! returns identity rotation matrix in the case that the norm of rotaxis
+ //! is to small to be used.
+ // @see Rot2 if you want to handle this error in another way.
+ static Rotation Rot(const Vector& rotaxis,double angle);
+
+ //! Along an arbitrary axes. rotvec should be normalized.
+ static Rotation Rot2(const Vector& rotvec,double angle);
+
+ // make sure the matrix is a pure rotation (no scaling)
+ void Ortho();
+
+ //! Returns a vector with the direction of the equiv. axis
+ //! and its norm is angle
+ Vector GetRot() const;
+
+ //! Returns a 2D vector representing the equivalent rotation in the XZ plane that brings the
+ //! Y axis onto the Matrix Y axis and its norm is angle
+ Vector2 GetXZRot() const;
+
+ /** Returns the rotation angle around the equiv. axis
+ * @param axis the rotation axis is returned in this variable
+ * @param eps : in the case of angle == 0 : rot axis is undefined and choosen
+ * to be +/- Z-axis
+ * in the case of angle == PI : 2 solutions, positive Z-component
+ * of the axis is choosen.
+ * @result returns the rotation angle (between [0..PI] )
+ */
+ double GetRotAngle(Vector& axis,double eps=epsilon) const;
+
+
+ //! Gives back a rotation matrix specified with EulerZYZ convention :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new Z with gamma.
+ static Rotation EulerZYZ(double Alfa,double Beta,double Gamma);
+
+ //! Gives back the EulerZYZ convention description of the rotation matrix :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new Z with gamma.
+ //!
+ //! Variables are bound by
+ //! (-PI <= alfa <= PI),
+ //! (0 <= beta <= PI),
+ //! (-PI <= alfa <= PI)
+ void GetEulerZYZ(double& alfa,double& beta,double& gamma) const;
+
+
+ //! Sets the value of this object to a rotation specified with RPY convention:
+ //! first rotate around X with roll, then around the
+ //! old Y with pitch, then around old Z with alfa
+ static Rotation RPY(double roll,double pitch,double yaw);
+
+ //! Gives back a vector in RPY coordinates, variables are bound by
+ //! -PI <= roll <= PI
+ //! -PI <= Yaw <= PI
+ //! -PI/2 <= PITCH <= PI/2
+ //!
+ //! convention : first rotate around X with roll, then around the
+ //! old Y with pitch, then around old Z with alfa
+ void GetRPY(double& roll,double& pitch,double& yaw) const;
+
+
+ //! Gives back a rotation matrix specified with EulerZYX convention :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new X with gamma.
+ //!
+ //! closely related to RPY-convention
+ inline static Rotation EulerZYX(double Alfa,double Beta,double Gamma) {
+ return RPY(Gamma,Beta,Alfa);
+ }
+
+ //! GetEulerZYX gets the euler ZYX parameters of a rotation :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new X with gamma.
+ //!
+ //! Range of the results of GetEulerZYX :
+ //! -PI <= alfa <= PI
+ //! -PI <= gamma <= PI
+ //! -PI/2 <= beta <= PI/2
+ //!
+ //! Closely related to RPY-convention.
+ inline void GetEulerZYX(double& Alfa,double& Beta,double& Gamma) const {
+ GetRPY(Gamma,Beta,Alfa);
+ }
+
+ //! Transformation of the base to which the twist is expressed.
+ //! Complexity : 18M+12A
+ //! @see Frame*Twist for a transformation that also transforms
+ //! the velocity reference point.
+ inline Twist operator * (const Twist& arg) const;
+
+ //! Transformation of the base to which the wrench is expressed.
+ //! Complexity : 18M+12A
+ //! @see Frame*Wrench for a transformation that also transforms
+ //! the force reference point.
+ inline Wrench operator * (const Wrench& arg) const;
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline Vector UnitX() const {
+ return Vector(data[0],data[3],data[6]);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline void UnitX(const Vector& X) {
+ data[0] = X(0);
+ data[3] = X(1);
+ data[6] = X(2);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline Vector UnitY() const {
+ return Vector(data[1],data[4],data[7]);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline void UnitY(const Vector& X) {
+ data[1] = X(0);
+ data[4] = X(1);
+ data[7] = X(2);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline Vector UnitZ() const {
+ return Vector(data[2],data[5],data[8]);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline void UnitZ(const Vector& X) {
+ data[2] = X(0);
+ data[5] = X(1);
+ data[8] = X(2);
+ }
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ friend bool Equal(const Rotation& a,const Rotation& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ friend bool operator==(const Rotation& a,const Rotation& b);
+ //! The literal inequality operator!=()
+ friend bool operator!=(const Rotation& a,const Rotation& b);
+
+ friend class Frame;
+};
+ bool operator==(const Rotation& a,const Rotation& b);
+
+
+
+/**
+ \brief represents a frame transformation in 3D space (rotation + translation)
+
+ if V2 = Frame*V1 (V2 expressed in frame A, V1 expressed in frame B)
+ then V2 = Frame.M*V1+Frame.p
+
+ Frame.M contains columns that represent the axes of frame B wrt frame A
+ Frame.p contains the origin of frame B expressed in frame A.
+*/
+class Frame {
+public:
+ Vector p; //!< origine of the Frame
+ Rotation M; //!< Orientation of the Frame
+
+public:
+
+ inline Frame(const Rotation& R,const Vector& V);
+
+ //! The rotation matrix defaults to identity
+ explicit inline Frame(const Vector& V);
+ //! The position matrix defaults to zero
+ explicit inline Frame(const Rotation& R);
+
+ inline void setValue(float* oglmat);
+ inline void getValue(float* oglmat) const;
+
+ inline Frame() {}
+ //! The copy constructor. Normal copy by value semantics.
+ inline Frame(const Frame& arg);
+
+ //! Reads data from an double array
+ //\TODO should be formulated as a constructor
+ void Make4x4(double* d);
+
+ //! Treats a frame as a 4x4 matrix and returns element i,j
+ //! Access to elements 0..3,0..3, bounds are checked when NDEBUG is not set
+ inline double operator()(int i,int j);
+
+ //! Treats a frame as a 4x4 matrix and returns element i,j
+ //! Access to elements 0..3,0..3, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ // = Inverse
+ //! Gives back inverse transformation of a Frame
+ inline Frame Inverse() const;
+
+ //! The same as p2=R.Inverse()*p but more efficient.
+ inline Vector Inverse(const Vector& arg) const;
+
+ //! The same as p2=R.Inverse()*p but more efficient.
+ inline Wrench Inverse(const Wrench& arg) const;
+
+ //! The same as p2=R.Inverse()*p but more efficient.
+ inline Twist Inverse(const Twist& arg) const;
+
+ //! Normal copy-by-value semantics.
+ inline Frame& operator = (const Frame& arg);
+
+ //! Transformation of the base to which the vector
+ //! is expressed.
+ inline Vector operator * (const Vector& arg) const;
+
+ //! Transformation of both the force reference point
+ //! and of the base to which the wrench is expressed.
+ //! look at Rotation*Wrench operator for a transformation
+ //! of only the base to which the twist is expressed.
+ //!
+ //! Complexity : 24M+18A
+ inline Wrench operator * (const Wrench& arg) const;
+
+ //! Transformation of both the velocity reference point
+ //! and of the base to which the twist is expressed.
+ //! look at Rotation*Twist for a transformation of only the
+ //! base to which the twist is expressed.
+ //!
+ //! Complexity : 24M+18A
+ inline Twist operator * (const Twist& arg) const;
+
+ //! Composition of two frames.
+ inline friend Frame operator *(const Frame& lhs,const Frame& rhs);
+
+ //! @return the identity transformation Frame(Rotation::Identity(),Vector::Zero()).
+ inline static Frame Identity();
+
+ //! The twist <t_this> is expressed wrt the current
+ //! frame. This frame is integrated into an updated frame with
+ //! <samplefrequency>. Very simple first order integration rule.
+ inline void Integrate(const Twist& t_this,double frequency);
+
+ /*
+ // DH_Craig1989 : constructs a transformationmatrix
+ // T_link(i-1)_link(i) with the Denavit-Hartenberg convention as
+ // described in the Craigs book: Craig, J. J.,Introduction to
+ // Robotics: Mechanics and Control, Addison-Wesley,
+ // isbn:0-201-10326-5, 1986.
+ //
+ // Note that the frame is a redundant way to express the information
+ // in the DH-convention.
+ // \verbatim
+ // Parameters in full : a(i-1),alpha(i-1),d(i),theta(i)
+ //
+ // axis i-1 is connected by link i-1 to axis i numbering axis 1
+ // to axis n link 0 (immobile base) to link n
+ //
+ // link length a(i-1) length of the mutual perpendicular line
+ // (normal) between the 2 axes. This normal runs from (i-1) to
+ // (i) axis.
+ //
+ // link twist alpha(i-1): construct plane perpendicular to the
+ // normal project axis(i-1) and axis(i) into plane angle from
+ // (i-1) to (i) measured in the direction of the normal
+ //
+ // link offset d(i) signed distance between normal (i-1) to (i)
+ // and normal (i) to (i+1) along axis i joint angle theta(i)
+ // signed angle between normal (i-1) to (i) and normal (i) to
+ // (i+1) along axis i
+ //
+ // First and last joints : a(0)= a(n) = 0
+ // alpha(0) = alpha(n) = 0
+ //
+ // PRISMATIC : theta(1) = 0 d(1) arbitrarily
+ //
+ // REVOLUTE : theta(1) arbitrarily d(1) = 0
+ //
+ // Not unique : if intersecting joint axis 2 choices for normal
+ // Frame assignment of the DH convention : Z(i-1) follows axis
+ // (i-1) X(i-1) is the normal between axis(i-1) and axis(i)
+ // Y(i-1) follows out of Z(i-1) and X(i-1)
+ //
+ // a(i-1) = distance from Z(i-1) to Z(i) along X(i-1)
+ // alpha(i-1) = angle between Z(i-1) to Z(i) along X(i-1)
+ // d(i) = distance from X(i-1) to X(i) along Z(i)
+ // theta(i) = angle between X(i-1) to X(i) along X(i)
+ // \endverbatim
+ */
+ static Frame DH_Craig1989(double a,double alpha,double d,double theta);
+
+ // DH : constructs a transformationmatrix T_link(i-1)_link(i) with
+ // the Denavit-Hartenberg convention as described in the original
+ // publictation: Denavit, J. and Hartenberg, R. S., A kinematic
+ // notation for lower-pair mechanisms based on matrices, ASME
+ // Journal of Applied Mechanics, 23:215-221, 1955.
+
+ static Frame DH(double a,double alpha,double d,double theta);
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Frame& a,const Frame& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Frame& a,const Frame& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Frame& a,const Frame& b);
+};
+
+/**
+ * \brief represents both translational and rotational velocities.
+ *
+ * This class represents a twist. A twist is the combination of translational
+ * velocity and rotational velocity applied at one point.
+*/
+class Twist {
+public:
+ Vector vel; //!< The velocity of that point
+ Vector rot; //!< The rotational velocity of that point.
+public:
+
+ //! The default constructor initialises to Zero via the constructor of Vector.
+ Twist():vel(),rot() {};
+
+ Twist(const Vector& _vel,const Vector& _rot):vel(_vel),rot(_rot) {};
+
+ inline Twist& operator-=(const Twist& arg);
+ inline Twist& operator+=(const Twist& arg);
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ inline double& operator()(int i);
+
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ //! For use with a const Twist
+ inline double operator()(int i) const;
+
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ inline friend Twist operator*(const Twist& lhs,double rhs);
+ inline friend Twist operator*(double lhs,const Twist& rhs);
+ inline friend Twist operator/(const Twist& lhs,double rhs);
+ inline friend Twist operator+(const Twist& lhs,const Twist& rhs);
+ inline friend Twist operator-(const Twist& lhs,const Twist& rhs);
+ inline friend Twist operator-(const Twist& arg);
+ inline friend double dot(const Twist& lhs,const Wrench& rhs);
+ inline friend double dot(const Wrench& rhs,const Twist& lhs);
+ inline friend void SetToZero(Twist& v);
+
+
+ //! @return a zero Twist : Twist(Vector::Zero(),Vector::Zero())
+ static inline Twist Zero();
+
+ //! Reverses the sign of the twist
+ inline void ReverseSign();
+
+ //! Changes the reference point of the twist.
+ //! The vector v_base_AB is expressed in the same base as the twist
+ //! The vector v_base_AB is a vector from the old point to
+ //! the new point.
+ //!
+ //! Complexity : 6M+6A
+ inline Twist RefPoint(const Vector& v_base_AB) const;
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Twist& a,const Twist& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Twist& a,const Twist& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Twist& a,const Twist& b);
+
+// = Friends
+ friend class Rotation;
+ friend class Frame;
+
+};
+
+/**
+ * \brief represents both translational and rotational acceleration.
+ *
+ * This class represents an acceleration twist. A acceleration twist is
+ * the combination of translational
+ * acceleration and rotational acceleration applied at one point.
+*/
+/*
+class AccelerationTwist {
+public:
+ Vector trans; //!< The translational acceleration of that point
+ Vector rot; //!< The rotational acceleration of that point.
+public:
+
+ //! The default constructor initialises to Zero via the constructor of Vector.
+ AccelerationTwist():trans(),rot() {};
+
+ AccelerationTwist(const Vector& _trans,const Vector& _rot):trans(_trans),rot(_rot) {};
+
+ inline AccelerationTwist& operator-=(const AccelerationTwist& arg);
+ inline AccelerationTwist& operator+=(const AccelerationTwist& arg);
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ inline double& operator()(int i);
+
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ //! For use with a const AccelerationTwist
+ inline double operator()(int i) const;
+
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ inline friend AccelerationTwist operator*(const AccelerationTwist& lhs,double rhs);
+ inline friend AccelerationTwist operator*(double lhs,const AccelerationTwist& rhs);
+ inline friend AccelerationTwist operator/(const AccelerationTwist& lhs,double rhs);
+ inline friend AccelerationTwist operator+(const AccelerationTwist& lhs,const AccelerationTwist& rhs);
+ inline friend AccelerationTwist operator-(const AccelerationTwist& lhs,const AccelerationTwist& rhs);
+ inline friend AccelerationTwist operator-(const AccelerationTwist& arg);
+ //inline friend double dot(const AccelerationTwist& lhs,const Wrench& rhs);
+ //inline friend double dot(const Wrench& rhs,const AccelerationTwist& lhs);
+ inline friend void SetToZero(AccelerationTwist& v);
+
+
+ //! @return a zero AccelerationTwist : AccelerationTwist(Vector::Zero(),Vector::Zero())
+ static inline AccelerationTwist Zero();
+
+ //! Reverses the sign of the AccelerationTwist
+ inline void ReverseSign();
+
+ //! Changes the reference point of the AccelerationTwist.
+ //! The vector v_base_AB is expressed in the same base as the AccelerationTwist
+ //! The vector v_base_AB is a vector from the old point to
+ //! the new point.
+ //!
+ //! Complexity : 6M+6A
+ inline AccelerationTwist RefPoint(const Vector& v_base_AB) const;
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const AccelerationTwist& a,const AccelerationTwist& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const AccelerationTwist& a,const AccelerationTwist& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const AccelerationTwist& a,const AccelerationTwist& b);
+
+// = Friends
+ friend class Rotation;
+ friend class Frame;
+
+};
+*/
+/**
+ * \brief represents the combination of a force and a torque.
+ *
+ * This class represents a Wrench. A Wrench is the force and torque applied at a point
+ */
+class Wrench
+{
+public:
+ Vector force; //!< Force that is applied at the origin of the current ref frame
+ Vector torque; //!< Torque that is applied at the origin of the current ref frame
+public:
+
+ //! Does initialise force and torque to zero via the underlying constructor of Vector
+ Wrench():force(),torque() {};
+ Wrench(const Vector& _force,const Vector& _torque):force(_force),torque(_torque) {};
+
+// = Operators
+ inline Wrench& operator-=(const Wrench& arg);
+ inline Wrench& operator+=(const Wrench& arg);
+
+ //! index-based access to components, first force(0..2), then torque(3..5)
+ inline double& operator()(int i);
+
+ //! index-based access to components, first force(0..2), then torque(3..5)
+ //! for use with a const Wrench
+ inline double operator()(int i) const;
+
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ //! Scalar multiplication
+ inline friend Wrench operator*(const Wrench& lhs,double rhs);
+ //! Scalar multiplication
+ inline friend Wrench operator*(double lhs,const Wrench& rhs);
+ //! Scalar division
+ inline friend Wrench operator/(const Wrench& lhs,double rhs);
+
+ inline friend Wrench operator+(const Wrench& lhs,const Wrench& rhs);
+ inline friend Wrench operator-(const Wrench& lhs,const Wrench& rhs);
+
+ //! An unary - operator
+ inline friend Wrench operator-(const Wrench& arg);
+
+ //! Sets the Wrench to Zero, to have a uniform function that sets an object or
+ //! double to zero.
+ inline friend void SetToZero(Wrench& v);
+
+ //! @return a zero Wrench
+ static inline Wrench Zero();
+
+ //! Reverses the sign of the current Wrench
+ inline void ReverseSign();
+
+ //! Changes the reference point of the wrench.
+ //! The vector v_base_AB is expressed in the same base as the twist
+ //! The vector v_base_AB is a vector from the old point to
+ //! the new point.
+ //!
+ //! Complexity : 6M+6A
+ inline Wrench RefPoint(const Vector& v_base_AB) const;
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Wrench& a,const Wrench& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Wrench& a,const Wrench& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Wrench& a,const Wrench& b);
+
+ friend class Rotation;
+ friend class Frame;
+
+
+};
+
+
+//! 2D version of Vector
+class Vector2
+{
+ double data[2];
+public:
+ //! Does not initialise to Zero().
+ Vector2() {data[0]=data[1] = 0.0;}
+ inline Vector2(double x,double y);
+ inline Vector2(const Vector2& arg);
+ inline Vector2(double* xyz);
+ inline Vector2(float* xyz);
+
+ inline Vector2& operator = ( const Vector2& arg);
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..1
+ inline double operator()(int index) const;
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..1
+ inline double& operator() (int index);
+
+ //! store vector components in array
+ inline void GetValue(double* xy) const;
+
+ inline void ReverseSign();
+ inline Vector2& operator-=(const Vector2& arg);
+ inline Vector2& operator +=(const Vector2& arg);
+
+
+ inline friend Vector2 operator*(const Vector2& lhs,double rhs);
+ inline friend Vector2 operator*(double lhs,const Vector2& rhs);
+ inline friend Vector2 operator/(const Vector2& lhs,double rhs);
+ inline friend Vector2 operator+(const Vector2& lhs,const Vector2& rhs);
+ inline friend Vector2 operator-(const Vector2& lhs,const Vector2& rhs);
+ inline friend Vector2 operator*(const Vector2& lhs,const Vector2& rhs);
+ inline friend Vector2 operator-(const Vector2& arg);
+ inline friend void SetToZero(Vector2& v);
+
+ //! @return a zero 2D vector.
+ inline static Vector2 Zero();
+
+ /** Normalizes this vector and returns it norm
+ * makes v a unitvector and returns the norm of v.
+ * if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+ * if this is not good, check the return value of this method.
+ */
+ double Normalize(double eps=epsilon);
+
+ //! @return the norm of the vector
+ inline double Norm() const;
+
+ //! projects v in its XY plane, and sets *this to these values
+ inline void Set3DXY(const Vector& v);
+
+ //! projects v in its YZ plane, and sets *this to these values
+ inline void Set3DYZ(const Vector& v);
+
+ //! projects v in its ZX plane, and sets *this to these values
+ inline void Set3DZX(const Vector& v);
+
+ //! projects v_someframe in the XY plane of F_someframe_XY,
+ //! and sets *this to these values
+ //! expressed wrt someframe.
+ inline void Set3DPlane(const Frame& F_someframe_XY,const Vector& v_someframe);
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Vector2& a,const Vector2& b,double eps=epsilon);
+
+ friend class Rotation2;
+};
+
+
+//! A 2D Rotation class, for conventions see Rotation. For further documentation
+//! of the methods see Rotation class.
+class Rotation2
+{
+ double s,c;
+ //! c,s represent cos(angle), sin(angle), this also represents first col. of rot matrix
+ //! from outside, this class behaves as if it would store the complete 2x2 matrix.
+public:
+ //! Default constructor does NOT initialise to Zero().
+ Rotation2() {c=1.0;s=0.0;}
+
+ explicit Rotation2(double angle_rad):s(sin(angle_rad)),c(cos(angle_rad)) {}
+
+ Rotation2(double ca,double sa):s(sa),c(ca){}
+
+ inline Rotation2& operator=(const Rotation2& arg);
+ inline Vector2 operator*(const Vector2& v) const;
+ //! Access to elements 0..1,0..1, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ inline friend Rotation2 operator *(const Rotation2& lhs,const Rotation2& rhs);
+
+ inline void SetInverse();
+ inline Rotation2 Inverse() const;
+ inline Vector2 Inverse(const Vector2& v) const;
+
+ inline void SetIdentity();
+ inline static Rotation2 Identity();
+
+
+ //! The SetRot.. functions set the value of *this to the appropriate rotation matrix.
+ inline void SetRot(double angle);
+
+ //! The Rot... static functions give the value of the appropriate rotation matrix bac
+ inline static Rotation2 Rot(double angle);
+
+ //! Gets the angle (in radians)
+ inline double GetRot() const;
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Rotation2& a,const Rotation2& b,double eps=epsilon);
+};
+
+//! A 2D frame class, for further documentation see the Frames class
+//! for methods with unchanged semantics.
+class Frame2
+ {
+public:
+ Vector2 p; //!< origine of the Frame
+ Rotation2 M; //!< Orientation of the Frame
+
+public:
+
+ inline Frame2(const Rotation2& R,const Vector2& V);
+ explicit inline Frame2(const Vector2& V);
+ explicit inline Frame2(const Rotation2& R);
+ inline Frame2(void);
+ inline Frame2(const Frame2& arg);
+ inline void Make4x4(double* d);
+
+ //! Treats a frame as a 3x3 matrix and returns element i,j
+ //! Access to elements 0..2,0..2, bounds are checked when NDEBUG is not set
+ inline double operator()(int i,int j);
+
+ //! Treats a frame as a 4x4 matrix and returns element i,j
+ //! Access to elements 0..3,0..3, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ inline void SetInverse();
+ inline Frame2 Inverse() const;
+ inline Vector2 Inverse(const Vector2& arg) const;
+ inline Frame2& operator = (const Frame2& arg);
+ inline Vector2 operator * (const Vector2& arg);
+ inline friend Frame2 operator *(const Frame2& lhs,const Frame2& rhs);
+ inline void SetIdentity();
+ inline void Integrate(const Twist& t_this,double frequency);
+ inline static Frame2 Identity() {
+ Frame2 tmp;
+ tmp.SetIdentity();
+ return tmp;
+ }
+ inline friend bool Equal(const Frame2& a,const Frame2& b,double eps=epsilon);
+};
+
+IMETHOD Vector diff(const Vector& a,const Vector& b,double dt=1);
+IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt=1);
+IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt=1);
+IMETHOD Twist diff(const Twist& a,const Twist& b,double dt=1);
+IMETHOD Wrench diff(const Wrench& W_a_p1,const Wrench& W_a_p2,double dt=1);
+IMETHOD Vector addDelta(const Vector& a,const Vector&da,double dt=1);
+IMETHOD Rotation addDelta(const Rotation& a,const Vector&da,double dt=1);
+IMETHOD Frame addDelta(const Frame& a,const Twist& da,double dt=1);
+IMETHOD Twist addDelta(const Twist& a,const Twist&da,double dt=1);
+IMETHOD Wrench addDelta(const Wrench& a,const Wrench&da,double dt=1);
+#ifdef KDL_INLINE
+// #include "vector.inl"
+// #include "wrench.inl"
+ //#include "rotation.inl"
+ //#include "frame.inl"
+ //#include "twist.inl"
+ //#include "vector2.inl"
+ //#include "rotation2.inl"
+ //#include "frame2.inl"
+#include "frames.inl"
+#endif
+
+
+
+}
+
+
+#endif
diff --git a/intern/itasc/kdl/frames.inl b/intern/itasc/kdl/frames.inl
new file mode 100644
index 00000000000..9a176070171
--- /dev/null
+++ b/intern/itasc/kdl/frames.inl
@@ -0,0 +1,1390 @@
+/***************************************************************************
+ frames.inl - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+
+IMETHOD Vector::Vector(const Vector & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+ data[2] = arg.data[2];
+}
+
+IMETHOD Vector::Vector(double x,double y, double z)
+{
+ data[0]=x;data[1]=y;data[2]=z;
+}
+
+IMETHOD Vector::Vector(double* xyz)
+{
+ data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2];
+}
+
+IMETHOD Vector::Vector(float* xyz)
+{
+ data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2];
+}
+
+IMETHOD void Vector::GetValue(double* xyz) const
+{
+ xyz[0]=data[0];xyz[1]=data[1];xyz[2]=data[2];
+}
+
+
+IMETHOD Vector& Vector::operator =(const Vector & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+ data[2] = arg.data[2];
+ return *this;
+}
+
+IMETHOD Vector operator +(const Vector & lhs,const Vector& rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]+rhs.data[0];
+ tmp.data[1] = lhs.data[1]+rhs.data[1];
+ tmp.data[2] = lhs.data[2]+rhs.data[2];
+ return tmp;
+}
+
+IMETHOD Vector operator -(const Vector & lhs,const Vector& rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]-rhs.data[0];
+ tmp.data[1] = lhs.data[1]-rhs.data[1];
+ tmp.data[2] = lhs.data[2]-rhs.data[2];
+ return tmp;
+}
+
+IMETHOD double Vector::x() const { return data[0]; }
+IMETHOD double Vector::y() const { return data[1]; }
+IMETHOD double Vector::z() const { return data[2]; }
+
+IMETHOD void Vector::x( double _x ) { data[0] = _x; }
+IMETHOD void Vector::y( double _y ) { data[1] = _y; }
+IMETHOD void Vector::z( double _z ) { data[2] = _z; }
+
+Vector operator *(const Vector& lhs,double rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]*rhs;
+ tmp.data[1] = lhs.data[1]*rhs;
+ tmp.data[2] = lhs.data[2]*rhs;
+ return tmp;
+}
+
+Vector operator *(double lhs,const Vector& rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs*rhs.data[0];
+ tmp.data[1] = lhs*rhs.data[1];
+ tmp.data[2] = lhs*rhs.data[2];
+ return tmp;
+}
+
+Vector operator /(const Vector& lhs,double rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]/rhs;
+ tmp.data[1] = lhs.data[1]/rhs;
+ tmp.data[2] = lhs.data[2]/rhs;
+ return tmp;
+}
+
+Vector operator *(const Vector & lhs,const Vector& rhs)
+// Complexity : 6M+3A
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[1]*rhs.data[2]-lhs.data[2]*rhs.data[1];
+ tmp.data[1] = lhs.data[2]*rhs.data[0]-lhs.data[0]*rhs.data[2];
+ tmp.data[2] = lhs.data[0]*rhs.data[1]-lhs.data[1]*rhs.data[0];
+ return tmp;
+}
+
+Vector& Vector::operator +=(const Vector & arg)
+// Complexity : 3A
+{
+ data[0]+=arg.data[0];
+ data[1]+=arg.data[1];
+ data[2]+=arg.data[2];
+ return *this;
+}
+
+Vector& Vector::operator -=(const Vector & arg)
+// Complexity : 3A
+{
+ data[0]-=arg.data[0];
+ data[1]-=arg.data[1];
+ data[2]-=arg.data[2];
+ return *this;
+}
+
+Vector Vector::Zero()
+{
+ return Vector(0,0,0);
+}
+
+double Vector::operator()(int index) const {
+ FRAMES_CHECKI((0<=index)&&(index<=2));
+ return data[index];
+}
+
+double& Vector::operator () (int index)
+{
+ FRAMES_CHECKI((0<=index)&&(index<=2));
+ return data[index];
+}
+
+IMETHOD Vector Normalize(const Vector& a, double eps)
+{
+ double l=a.Norm();
+ return (l<eps) ? Vector(0.0,0.0,0.0) : a/l;
+}
+
+Wrench Frame::operator * (const Wrench& arg) const
+// Complexity : 24M+18A
+{
+ Wrench tmp;
+ tmp.force = M*arg.force;
+ tmp.torque = M*arg.torque + p*tmp.force;
+ return tmp;
+}
+
+Wrench Frame::Inverse(const Wrench& arg) const
+{
+ Wrench tmp;
+ tmp.force = M.Inverse(arg.force);
+ tmp.torque = M.Inverse(arg.torque-p*arg.force);
+ return tmp;
+}
+
+
+
+Wrench Rotation::Inverse(const Wrench& arg) const
+{
+ return Wrench(Inverse(arg.force),Inverse(arg.torque));
+}
+
+Twist Rotation::Inverse(const Twist& arg) const
+{
+ return Twist(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+Wrench Wrench::Zero()
+{
+ return Wrench(Vector::Zero(),Vector::Zero());
+}
+
+
+void Wrench::ReverseSign()
+{
+ torque.ReverseSign();
+ force.ReverseSign();
+}
+
+Wrench Wrench::RefPoint(const Vector& v_base_AB) const
+ // Changes the reference point of the Wrench.
+ // The vector v_base_AB is expressed in the same base as the twist
+ // The vector v_base_AB is a vector from the old point to
+ // the new point.
+{
+ return Wrench(this->force,
+ this->torque+this->force*v_base_AB
+ );
+}
+
+
+Wrench& Wrench::operator-=(const Wrench& arg)
+{
+ torque-=arg.torque;
+ force -=arg.force;
+ return *this;
+}
+
+Wrench& Wrench::operator+=(const Wrench& arg)
+{
+ torque+=arg.torque;
+ force +=arg.force;
+ return *this;
+}
+
+double& Wrench::operator()(int i)
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return force(i);
+ else
+ return torque(i-3);
+}
+
+double Wrench::operator()(int i) const
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return force(i);
+ else
+ return torque(i-3);
+}
+
+
+Wrench operator*(const Wrench& lhs,double rhs)
+{
+ return Wrench(lhs.force*rhs,lhs.torque*rhs);
+}
+
+Wrench operator*(double lhs,const Wrench& rhs)
+{
+ return Wrench(lhs*rhs.force,lhs*rhs.torque);
+}
+
+Wrench operator/(const Wrench& lhs,double rhs)
+{
+ return Wrench(lhs.force/rhs,lhs.torque/rhs);
+}
+
+// addition of Wrench's
+Wrench operator+(const Wrench& lhs,const Wrench& rhs)
+{
+ return Wrench(lhs.force+rhs.force,lhs.torque+rhs.torque);
+}
+
+Wrench operator-(const Wrench& lhs,const Wrench& rhs)
+{
+ return Wrench(lhs.force-rhs.force,lhs.torque-rhs.torque);
+}
+
+// unary -
+Wrench operator-(const Wrench& arg)
+{
+ return Wrench(-arg.force,-arg.torque);
+}
+
+Twist Frame::operator * (const Twist& arg) const
+// Complexity : 24M+18A
+{
+ Twist tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+Twist Frame::Inverse(const Twist& arg) const
+{
+ Twist tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+Twist Twist::Zero()
+{
+ return Twist(Vector::Zero(),Vector::Zero());
+}
+
+
+void Twist::ReverseSign()
+{
+ vel.ReverseSign();
+ rot.ReverseSign();
+}
+
+Twist Twist::RefPoint(const Vector& v_base_AB) const
+ // Changes the reference point of the twist.
+ // The vector v_base_AB is expressed in the same base as the twist
+ // The vector v_base_AB is a vector from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+{
+ return Twist(this->vel+this->rot*v_base_AB,this->rot);
+}
+
+Twist& Twist::operator-=(const Twist& arg)
+{
+ vel-=arg.vel;
+ rot -=arg.rot;
+ return *this;
+}
+
+Twist& Twist::operator+=(const Twist& arg)
+{
+ vel+=arg.vel;
+ rot +=arg.rot;
+ return *this;
+}
+
+double& Twist::operator()(int i)
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return vel(i);
+ else
+ return rot(i-3);
+}
+
+double Twist::operator()(int i) const
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return vel(i);
+ else
+ return rot(i-3);
+}
+
+
+Twist operator*(const Twist& lhs,double rhs)
+{
+ return Twist(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+Twist operator*(double lhs,const Twist& rhs)
+{
+ return Twist(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+Twist operator/(const Twist& lhs,double rhs)
+{
+ return Twist(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+// addition of Twist's
+Twist operator+(const Twist& lhs,const Twist& rhs)
+{
+ return Twist(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
+}
+
+Twist operator-(const Twist& lhs,const Twist& rhs)
+{
+ return Twist(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
+}
+
+// unary -
+Twist operator-(const Twist& arg)
+{
+ return Twist(-arg.vel,-arg.rot);
+}
+
+Frame::Frame(const Rotation & R)
+{
+ M=R;
+ p=Vector::Zero();
+}
+
+Frame::Frame(const Vector & V)
+{
+ M = Rotation::Identity();
+ p = V;
+}
+
+Frame::Frame(const Rotation & R, const Vector & V)
+{
+ M = R;
+ p = V;
+}
+
+ Frame operator *(const Frame& lhs,const Frame& rhs)
+// Complexity : 36M+36A
+{
+ return Frame(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+
+Vector Frame::operator *(const Vector & arg) const
+{
+ return M*arg+p;
+}
+
+Vector Frame::Inverse(const Vector& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+Frame Frame::Inverse() const
+{
+ return Frame(M.Inverse(),-M.Inverse(p));
+}
+
+
+Frame& Frame::operator =(const Frame & arg)
+{
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+
+Frame::Frame(const Frame & arg) :
+ p(arg.p),M(arg.M)
+{}
+
+
+void Vector::ReverseSign()
+{
+ data[0] = -data[0];
+ data[1] = -data[1];
+ data[2] = -data[2];
+}
+
+
+
+Vector operator-(const Vector & arg)
+{
+ Vector tmp;
+ tmp.data[0]=-arg.data[0];
+ tmp.data[1]=-arg.data[1];
+ tmp.data[2]=-arg.data[2];
+ return tmp;
+}
+
+void Vector::Set2DXY(const Vector2& v)
+// a 3D vector where the 2D vector v is put in the XY plane
+{
+ data[0]=v(0);
+ data[1]=v(1);
+ data[2]=0;
+
+}
+void Vector::Set2DYZ(const Vector2& v)
+// a 3D vector where the 2D vector v is put in the YZ plane
+{
+ data[1]=v(0);
+ data[2]=v(1);
+ data[0]=0;
+
+}
+
+void Vector::Set2DZX(const Vector2& v)
+// a 3D vector where the 2D vector v is put in the ZX plane
+{
+ data[2]=v(0);
+ data[0]=v(1);
+ data[1]=0;
+
+}
+
+
+
+
+
+double& Rotation::operator()(int i,int j) {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ return data[i*3+j];
+}
+
+double Rotation::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ return data[i*3+j];
+}
+
+Rotation::Rotation( double Xx,double Yx,double Zx,
+ double Xy,double Yy,double Zy,
+ double Xz,double Yz,double Zz)
+{
+ data[0] = Xx;data[1]=Yx;data[2]=Zx;
+ data[3] = Xy;data[4]=Yy;data[5]=Zy;
+ data[6] = Xz;data[7]=Yz;data[8]=Zz;
+}
+
+
+Rotation::Rotation(const Vector& x,const Vector& y,const Vector& z)
+{
+ data[0] = x.data[0];data[3] = x.data[1];data[6] = x.data[2];
+ data[1] = y.data[0];data[4] = y.data[1];data[7] = y.data[2];
+ data[2] = z.data[0];data[5] = z.data[1];data[8] = z.data[2];
+}
+
+Rotation& Rotation::operator=(const Rotation& arg) {
+ int count=9;
+ while (count--) data[count] = arg.data[count];
+ return *this;
+}
+
+Vector Rotation::operator*(const Vector& v) const {
+// Complexity : 9M+6A
+ return Vector(
+ data[0]*v.data[0] + data[1]*v.data[1] + data[2]*v.data[2],
+ data[3]*v.data[0] + data[4]*v.data[1] + data[5]*v.data[2],
+ data[6]*v.data[0] + data[7]*v.data[1] + data[8]*v.data[2]
+ );
+}
+
+Twist Rotation::operator * (const Twist& arg) const
+ // Transformation of the base to which the twist is expressed.
+ // look at Frame*Twist for a transformation that also transforms
+ // the velocity reference point.
+ // Complexity : 18M+12A
+{
+ return Twist((*this)*arg.vel,(*this)*arg.rot);
+}
+
+Wrench Rotation::operator * (const Wrench& arg) const
+ // Transformation of the base to which the wrench is expressed.
+ // look at Frame*Twist for a transformation that also transforms
+ // the force reference point.
+{
+ return Wrench((*this)*arg.force,(*this)*arg.torque);
+}
+
+Rotation Rotation::Identity() {
+ return Rotation(1,0,0,0,1,0,0,0,1);
+}
+// *this = *this * ROT(X,angle)
+void Rotation::DoRotX(double angle)
+{
+ double cs = cos(angle);
+ double sn = sin(angle);
+ double x1,x2,x3;
+ x1 = cs* (*this)(0,1) + sn* (*this)(0,2);
+ x2 = cs* (*this)(1,1) + sn* (*this)(1,2);
+ x3 = cs* (*this)(2,1) + sn* (*this)(2,2);
+ (*this)(0,2) = -sn* (*this)(0,1) + cs* (*this)(0,2);
+ (*this)(1,2) = -sn* (*this)(1,1) + cs* (*this)(1,2);
+ (*this)(2,2) = -sn* (*this)(2,1) + cs* (*this)(2,2);
+ (*this)(0,1) = x1;
+ (*this)(1,1) = x2;
+ (*this)(2,1) = x3;
+}
+
+void Rotation::DoRotY(double angle)
+{
+ double cs = cos(angle);
+ double sn = sin(angle);
+ double x1,x2,x3;
+ x1 = cs* (*this)(0,0) - sn* (*this)(0,2);
+ x2 = cs* (*this)(1,0) - sn* (*this)(1,2);
+ x3 = cs* (*this)(2,0) - sn* (*this)(2,2);
+ (*this)(0,2) = sn* (*this)(0,0) + cs* (*this)(0,2);
+ (*this)(1,2) = sn* (*this)(1,0) + cs* (*this)(1,2);
+ (*this)(2,2) = sn* (*this)(2,0) + cs* (*this)(2,2);
+ (*this)(0,0) = x1;
+ (*this)(1,0) = x2;
+ (*this)(2,0) = x3;
+}
+
+void Rotation::DoRotZ(double angle)
+{
+ double cs = cos(angle);
+ double sn = sin(angle);
+ double x1,x2,x3;
+ x1 = cs* (*this)(0,0) + sn* (*this)(0,1);
+ x2 = cs* (*this)(1,0) + sn* (*this)(1,1);
+ x3 = cs* (*this)(2,0) + sn* (*this)(2,1);
+ (*this)(0,1) = -sn* (*this)(0,0) + cs* (*this)(0,1);
+ (*this)(1,1) = -sn* (*this)(1,0) + cs* (*this)(1,1);
+ (*this)(2,1) = -sn* (*this)(2,0) + cs* (*this)(2,1);
+ (*this)(0,0) = x1;
+ (*this)(1,0) = x2;
+ (*this)(2,0) = x3;
+}
+
+
+Rotation Rotation::RotX(double angle) {
+ double cs=cos(angle);
+ double sn=sin(angle);
+ return Rotation(1,0,0,0,cs,-sn,0,sn,cs);
+}
+Rotation Rotation::RotY(double angle) {
+ double cs=cos(angle);
+ double sn=sin(angle);
+ return Rotation(cs,0,sn,0,1,0,-sn,0,cs);
+}
+Rotation Rotation::RotZ(double angle) {
+ double cs=cos(angle);
+ double sn=sin(angle);
+ return Rotation(cs,-sn,0,sn,cs,0,0,0,1);
+}
+
+
+
+
+void Frame::Integrate(const Twist& t_this,double samplefrequency)
+{
+ double n = t_this.rot.Norm()/samplefrequency;
+ if (n<epsilon) {
+ p += M*(t_this.vel/samplefrequency);
+ } else {
+ (*this) = (*this) *
+ Frame ( Rotation::Rot( t_this.rot, n ),
+ t_this.vel/samplefrequency
+ );
+ }
+}
+
+Rotation Rotation::Inverse() const
+{
+ Rotation tmp(*this);
+ tmp.SetInverse();
+ return tmp;
+}
+
+Vector Rotation::Inverse(const Vector& v) const {
+ return Vector(
+ data[0]*v.data[0] + data[3]*v.data[1] + data[6]*v.data[2],
+ data[1]*v.data[0] + data[4]*v.data[1] + data[7]*v.data[2],
+ data[2]*v.data[0] + data[5]*v.data[1] + data[8]*v.data[2]
+ );
+}
+
+void Rotation::setValue(float* oglmat)
+{
+ data[0] = *oglmat++; data[3] = *oglmat++; data[6] = *oglmat++; oglmat++;
+ data[1] = *oglmat++; data[4] = *oglmat++; data[7] = *oglmat++; oglmat++;
+ data[2] = *oglmat++; data[5] = *oglmat++; data[8] = *oglmat;
+ Ortho();
+}
+
+void Rotation::getValue(float* oglmat) const
+{
+ *oglmat++ = (float)data[0]; *oglmat++ = (float)data[3]; *oglmat++ = (float)data[6]; *oglmat++ = 0.f;
+ *oglmat++ = (float)data[1]; *oglmat++ = (float)data[4]; *oglmat++ = (float)data[7]; *oglmat++ = 0.f;
+ *oglmat++ = (float)data[2]; *oglmat++ = (float)data[5]; *oglmat++ = (float)data[8]; *oglmat++ = 0.f;
+ *oglmat++ = 0.f; *oglmat++ = 0.f; *oglmat++ = 0.f; *oglmat = 1.f;
+}
+
+void Rotation::SetInverse()
+{
+ double tmp;
+ tmp = data[1];data[1]=data[3];data[3]=tmp;
+ tmp = data[2];data[2]=data[6];data[6]=tmp;
+ tmp = data[5];data[5]=data[7];data[7]=tmp;
+}
+
+
+
+
+
+
+
+double Frame::operator()(int i,int j) {
+ FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3));
+ if (i==3) {
+ if (j==3)
+ return 1.0;
+ else
+ return 0.0;
+ } else {
+ if (j==3)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+double Frame::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3));
+ if (i==3) {
+ if (j==3)
+ return 1;
+ else
+ return 0;
+ } else {
+ if (j==3)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+
+Frame Frame::Identity() {
+ return Frame(Rotation::Identity(),Vector::Zero());
+}
+
+
+void Frame::setValue(float* oglmat)
+{
+ M.setValue(oglmat);
+ p.data[0] = oglmat[12];
+ p.data[1] = oglmat[13];
+ p.data[2] = oglmat[14];
+}
+
+void Frame::getValue(float* oglmat) const
+{
+ M.getValue(oglmat);
+ oglmat[12] = (float)p.data[0];
+ oglmat[13] = (float)p.data[1];
+ oglmat[14] = (float)p.data[2];
+}
+
+void Vector::Set2DPlane(const Frame& F_someframe_XY,const Vector2& v_XY)
+// a 3D vector where the 2D vector v is put in the XY plane of the frame
+// F_someframe_XY.
+{
+Vector tmp_XY;
+tmp_XY.Set2DXY(v_XY);
+tmp_XY = F_someframe_XY*(tmp_XY);
+}
+
+
+
+
+
+
+
+
+
+//============ 2 dimensional version of the frames objects =============
+IMETHOD Vector2::Vector2(const Vector2 & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+}
+
+IMETHOD Vector2::Vector2(double x,double y)
+{
+ data[0]=x;data[1]=y;
+}
+
+IMETHOD Vector2::Vector2(double* xy)
+{
+ data[0]=xy[0];data[1]=xy[1];
+}
+
+IMETHOD Vector2::Vector2(float* xy)
+{
+ data[0]=xy[0];data[1]=xy[1];
+}
+
+IMETHOD Vector2& Vector2::operator =(const Vector2 & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+ return *this;
+}
+
+IMETHOD void Vector2::GetValue(double* xy) const
+{
+ xy[0]=data[0];xy[1]=data[1];
+}
+
+IMETHOD Vector2 operator +(const Vector2 & lhs,const Vector2& rhs)
+{
+ return Vector2(lhs.data[0]+rhs.data[0],lhs.data[1]+rhs.data[1]);
+}
+
+IMETHOD Vector2 operator -(const Vector2 & lhs,const Vector2& rhs)
+{
+ return Vector2(lhs.data[0]-rhs.data[0],lhs.data[1]-rhs.data[1]);
+}
+
+IMETHOD Vector2 operator *(const Vector2& lhs,double rhs)
+{
+ return Vector2(lhs.data[0]*rhs,lhs.data[1]*rhs);
+}
+
+IMETHOD Vector2 operator *(double lhs,const Vector2& rhs)
+{
+ return Vector2(lhs*rhs.data[0],lhs*rhs.data[1]);
+}
+
+IMETHOD Vector2 operator /(const Vector2& lhs,double rhs)
+{
+ return Vector2(lhs.data[0]/rhs,lhs.data[1]/rhs);
+}
+
+IMETHOD Vector2& Vector2::operator +=(const Vector2 & arg)
+{
+ data[0]+=arg.data[0];
+ data[1]+=arg.data[1];
+ return *this;
+}
+
+IMETHOD Vector2& Vector2::operator -=(const Vector2 & arg)
+{
+ data[0]-=arg.data[0];
+ data[1]-=arg.data[1];
+ return *this;
+}
+
+IMETHOD Vector2 Vector2::Zero() {
+ return Vector2(0,0);
+}
+
+IMETHOD double Vector2::operator()(int index) const {
+ FRAMES_CHECKI((0<=index)&&(index<=1));
+ return data[index];
+}
+
+IMETHOD double& Vector2::operator () (int index)
+{
+ FRAMES_CHECKI((0<=index)&&(index<=1));
+ return data[index];
+}
+IMETHOD void Vector2::ReverseSign()
+{
+ data[0] = -data[0];
+ data[1] = -data[1];
+}
+
+
+IMETHOD Vector2 operator-(const Vector2 & arg)
+{
+ return Vector2(-arg.data[0],-arg.data[1]);
+}
+
+
+IMETHOD void Vector2::Set3DXY(const Vector& v)
+// projects v in its XY plane, and sets *this to these values
+{
+ data[0]=v(0);
+ data[1]=v(1);
+}
+IMETHOD void Vector2::Set3DYZ(const Vector& v)
+// projects v in its XY plane, and sets *this to these values
+{
+ data[0]=v(1);
+ data[1]=v(2);
+}
+IMETHOD void Vector2::Set3DZX(const Vector& v)
+// projects v in its XY plane, and and sets *this to these values
+{
+ data[0]=v(2);
+ data[1]=v(0);
+}
+
+IMETHOD void Vector2::Set3DPlane(const Frame& F_someframe_XY,const Vector& v_someframe)
+// projects v in the XY plane of F_someframe_XY, and sets *this to these values
+// expressed wrt someframe.
+{
+ Vector tmp = F_someframe_XY.Inverse(v_someframe);
+ data[0]=tmp(0);
+ data[1]=tmp(1);
+}
+
+
+
+IMETHOD Rotation2& Rotation2::operator=(const Rotation2& arg) {
+ c=arg.c;s=arg.s;
+ return *this;
+}
+
+IMETHOD Vector2 Rotation2::operator*(const Vector2& v) const {
+ return Vector2(v.data[0]*c-v.data[1]*s,v.data[0]*s+v.data[1]*c);
+}
+
+IMETHOD double Rotation2::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=1)&&(0<=j)&&(j<=1));
+ if (i==j) return c;
+ if (i==0)
+ return s;
+ else
+ return -s;
+}
+
+
+IMETHOD Rotation2 operator *(const Rotation2& lhs,const Rotation2& rhs) {
+ return Rotation2(lhs.c*rhs.c-lhs.s*rhs.s,lhs.s*rhs.c+lhs.c*rhs.s);
+}
+
+IMETHOD void Rotation2::SetInverse() {
+ s=-s;
+}
+
+IMETHOD Rotation2 Rotation2::Inverse() const {
+ return Rotation2(c,-s);
+}
+
+IMETHOD Vector2 Rotation2::Inverse(const Vector2& v) const {
+ return Vector2(v.data[0]*c+v.data[1]*s,-v.data[0]*s+v.data[1]*c);
+}
+
+IMETHOD Rotation2 Rotation2::Identity() {
+ return Rotation2(1,0);
+}
+
+IMETHOD void Rotation2::SetIdentity()
+{
+ c = 1;
+ s = 0;
+}
+
+IMETHOD void Rotation2::SetRot(double angle) {
+ c=cos(angle);s=sin(angle);
+}
+
+IMETHOD Rotation2 Rotation2::Rot(double angle) {
+ return Rotation2(cos(angle),sin(angle));
+}
+
+IMETHOD double Rotation2::GetRot() const {
+ return atan2(s,c);
+}
+
+
+IMETHOD Frame2::Frame2() {
+}
+
+IMETHOD Frame2::Frame2(const Rotation2 & R)
+{
+ M=R;
+ p=Vector2::Zero();
+}
+
+IMETHOD Frame2::Frame2(const Vector2 & V)
+{
+ M = Rotation2::Identity();
+ p = V;
+}
+
+IMETHOD Frame2::Frame2(const Rotation2 & R, const Vector2 & V)
+{
+ M = R;
+ p = V;
+}
+
+IMETHOD Frame2 operator *(const Frame2& lhs,const Frame2& rhs)
+{
+ return Frame2(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+
+IMETHOD Vector2 Frame2::operator *(const Vector2 & arg)
+{
+ return M*arg+p;
+}
+
+IMETHOD Vector2 Frame2::Inverse(const Vector2& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+IMETHOD void Frame2::SetIdentity()
+{
+ M.SetIdentity();
+ p = Vector2::Zero();
+}
+
+IMETHOD void Frame2::SetInverse()
+{
+ M.SetInverse();
+ p = M*p;
+ p.ReverseSign();
+}
+
+
+IMETHOD Frame2 Frame2::Inverse() const
+{
+ Frame2 tmp(*this);
+ tmp.SetInverse();
+ return tmp;
+}
+
+IMETHOD Frame2& Frame2::operator =(const Frame2 & arg)
+{
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+
+IMETHOD Frame2::Frame2(const Frame2 & arg) :
+ p(arg.p), M(arg.M)
+{}
+
+
+IMETHOD double Frame2::operator()(int i,int j) {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ if (i==2) {
+ if (j==2)
+ return 1;
+ else
+ return 0;
+ } else {
+ if (j==2)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+IMETHOD double Frame2::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ if (i==2) {
+ if (j==2)
+ return 1;
+ else
+ return 0;
+ } else {
+ if (j==2)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+// Scalar products.
+
+IMETHOD double dot(const Vector& lhs,const Vector& rhs) {
+ return rhs(0)*lhs(0)+rhs(1)*lhs(1)+rhs(2)*lhs(2);
+}
+
+IMETHOD double dot(const Twist& lhs,const Wrench& rhs) {
+ return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque);
+}
+
+IMETHOD double dot(const Wrench& rhs,const Twist& lhs) {
+ return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque);
+}
+
+
+
+
+
+// Equality operators
+
+
+
+IMETHOD bool Equal(const Vector& a,const Vector& b,double eps) {
+ return (Equal(a.data[0],b.data[0],eps)&&
+ Equal(a.data[1],b.data[1],eps)&&
+ Equal(a.data[2],b.data[2],eps) );
+ }
+
+
+IMETHOD bool Equal(const Frame& a,const Frame& b,double eps) {
+ return (Equal(a.p,b.p,eps)&&
+ Equal(a.M,b.M,eps) );
+}
+
+IMETHOD bool Equal(const Wrench& a,const Wrench& b,double eps) {
+ return (Equal(a.force,b.force,eps)&&
+ Equal(a.torque,b.torque,eps) );
+}
+
+IMETHOD bool Equal(const Twist& a,const Twist& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+
+IMETHOD bool Equal(const Vector2& a,const Vector2& b,double eps) {
+ return (Equal(a.data[0],b.data[0],eps)&&
+ Equal(a.data[1],b.data[1],eps) );
+ }
+
+IMETHOD bool Equal(const Rotation2& a,const Rotation2& b,double eps) {
+ return ( Equal(a.c,b.c,eps) && Equal(a.s,b.s,eps) );
+}
+
+IMETHOD bool Equal(const Frame2& a,const Frame2& b,double eps) {
+ return (Equal(a.p,b.p,eps)&&
+ Equal(a.M,b.M,eps) );
+}
+
+IMETHOD void SetToZero(Vector& v) {
+ v=Vector::Zero();
+}
+IMETHOD void SetToZero(Twist& v) {
+ SetToZero(v.rot);
+ SetToZero(v.vel);
+}
+IMETHOD void SetToZero(Wrench& v) {
+ SetToZero(v.force);
+ SetToZero(v.torque);
+}
+
+IMETHOD void SetToZero(Vector2& v) {
+ v = Vector2::Zero();
+}
+
+
+////////////////////////////////////////////////////////////////
+// The following defines the operations
+// diff
+// addDelta
+// random
+// posrandom
+// on all the types defined in this library.
+// (mostly for uniform integration, differentiation and testing).
+// Defined as functions because double is not a class and a method
+// would brake uniformity when defined for a double.
+////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+/**
+ * axis_a_b is a rotation vector, its norm is a rotation angle
+ * axis_a_b rotates the a frame towards the b frame.
+ * This routine returns the rotation matrix R_a_b
+ */
+IMETHOD Rotation Rot(const Vector& axis_a_b) {
+ // The formula is
+ // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
+ // can be found by multiplying it with an arbitrary vector p
+ // and noting that this vector is rotated.
+ Vector rotvec = axis_a_b;
+ double angle = rotvec.Normalize(1E-10);
+ double ct = ::cos(angle);
+ double st = ::sin(angle);
+ double vt = 1-ct;
+ return Rotation(
+ ct + vt*rotvec(0)*rotvec(0),
+ -rotvec(2)*st + vt*rotvec(0)*rotvec(1),
+ rotvec(1)*st + vt*rotvec(0)*rotvec(2),
+ rotvec(2)*st + vt*rotvec(1)*rotvec(0),
+ ct + vt*rotvec(1)*rotvec(1),
+ -rotvec(0)*st + vt*rotvec(1)*rotvec(2),
+ -rotvec(1)*st + vt*rotvec(2)*rotvec(0),
+ rotvec(0)*st + vt*rotvec(2)*rotvec(1),
+ ct + vt*rotvec(2)*rotvec(2)
+ );
+ }
+
+IMETHOD Vector diff(const Vector& a,const Vector& b,double dt) {
+ return (b-a)/dt;
+}
+
+/**
+ * \brief diff operator for displacement rotational velocity.
+ *
+ * The Vector arguments here represent a displacement rotational velocity. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \TODO represent a displacement twist and displacement rotational velocity with another
+ * class, instead of Vector and Twist.
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+IMETHOD Vector diff_displ(const Vector& a,const Vector& b,double dt) {
+ return diff(Rot(a),Rot(b),dt);
+}*/
+
+/**
+ * \brief diff operator for displacement twist.
+ *
+ * The Twist arguments here represent a displacement twist. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+
+IMETHOD Twist diff_displ(const Twist& a,const Twist& b,double dt) {
+ return Twist(diff(a.vel,b.vel,dt),diff(Rot(a.rot),Rot(b.rot),dt));
+}
+*/
+
+IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt) {
+ Rotation R_b1_b2(R_a_b1.Inverse()*R_a_b2);
+ return R_a_b1 * R_b1_b2.GetRot() / dt;
+}
+IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt) {
+ return Twist(
+ diff(F_a_b1.p,F_a_b2.p,dt),
+ diff(F_a_b1.M,F_a_b2.M,dt)
+ );
+}
+IMETHOD Twist diff(const Twist& a,const Twist& b,double dt) {
+ return Twist(diff(a.vel,b.vel,dt),diff(a.rot,b.rot,dt));
+}
+
+IMETHOD Wrench diff(const Wrench& a,const Wrench& b,double dt) {
+ return Wrench(
+ diff(a.force,b.force,dt),
+ diff(a.torque,b.torque,dt)
+ );
+}
+
+
+IMETHOD Vector addDelta(const Vector& a,const Vector&da,double dt) {
+ return a+da*dt;
+}
+
+IMETHOD Rotation addDelta(const Rotation& a,const Vector&da,double dt) {
+ return a*Rot(a.Inverse(da)*dt);
+}
+IMETHOD Frame addDelta(const Frame& a,const Twist& da,double dt) {
+ return Frame(
+ addDelta(a.M,da.rot,dt),
+ addDelta(a.p,da.vel,dt)
+ );
+}
+IMETHOD Twist addDelta(const Twist& a,const Twist&da,double dt) {
+ return Twist(addDelta(a.vel,da.vel,dt),addDelta(a.rot,da.rot,dt));
+}
+IMETHOD Wrench addDelta(const Wrench& a,const Wrench&da,double dt) {
+ return Wrench(addDelta(a.force,da.force,dt),addDelta(a.torque,da.torque,dt));
+}
+
+
+/**
+ * \brief addDelta operator for displacement rotational velocity.
+ *
+ * The Vector arguments here represent a displacement rotational velocity. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \param a : displacement rotational velocity
+ * \param da : rotational velocity
+ * \return displacement rotational velocity
+ *
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+IMETHOD Vector addDelta_displ(const Vector& a,const Vector&da,double dt) {
+ return getRot(addDelta(Rot(a),da,dt));
+}*/
+
+/**
+ * \brief addDelta operator for displacement twist.
+ *
+ * The Vector arguments here represent a displacement rotational velocity. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \param a : displacement twist
+ * \param da : twist
+ * \return displacement twist
+ *
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+IMETHOD Twist addDelta_displ(const Twist& a,const Twist&da,double dt) {
+ return Twist(addDelta(a.vel,da.vel,dt),addDelta_displ(a.rot,da.rot,dt));
+}*/
+
+
+IMETHOD void random(Vector& a) {
+ random(a[0]);
+ random(a[1]);
+ random(a[2]);
+}
+IMETHOD void random(Twist& a) {
+ random(a.rot);
+ random(a.vel);
+}
+IMETHOD void random(Wrench& a) {
+ random(a.torque);
+ random(a.force);
+}
+
+IMETHOD void random(Rotation& R) {
+ double alfa;
+ double beta;
+ double gamma;
+ random(alfa);
+ random(beta);
+ random(gamma);
+ R = Rotation::EulerZYX(alfa,beta,gamma);
+}
+
+IMETHOD void random(Frame& F) {
+ random(F.M);
+ random(F.p);
+}
+
+IMETHOD void posrandom(Vector& a) {
+ posrandom(a[0]);
+ posrandom(a[1]);
+ posrandom(a[2]);
+}
+IMETHOD void posrandom(Twist& a) {
+ posrandom(a.rot);
+ posrandom(a.vel);
+}
+IMETHOD void posrandom(Wrench& a) {
+ posrandom(a.torque);
+ posrandom(a.force);
+}
+
+IMETHOD void posrandom(Rotation& R) {
+ double alfa;
+ double beta;
+ double gamma;
+ posrandom(alfa);
+ posrandom(beta);
+ posrandom(gamma);
+ R = Rotation::EulerZYX(alfa,beta,gamma);
+}
+
+IMETHOD void posrandom(Frame& F) {
+ random(F.M);
+ random(F.p);
+}
+
+
+
+
+IMETHOD bool operator==(const Frame& a,const Frame& b ) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.p == b.p &&
+ a.M == b.M );
+#endif
+}
+
+IMETHOD bool operator!=(const Frame& a,const Frame& b) {
+ return !operator==(a,b);
+}
+
+IMETHOD bool operator==(const Vector& a,const Vector& b) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.data[0]==b.data[0]&&
+ a.data[1]==b.data[1]&&
+ a.data[2]==b.data[2] );
+#endif
+ }
+
+IMETHOD bool operator!=(const Vector& a,const Vector& b) {
+ return !operator==(a,b);
+}
+
+IMETHOD bool operator==(const Twist& a,const Twist& b) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.rot==b.rot &&
+ a.vel==b.vel );
+#endif
+}
+
+IMETHOD bool operator!=(const Twist& a,const Twist& b) {
+ return !operator==(a,b);
+}
+
+IMETHOD bool operator==(const Wrench& a,const Wrench& b ) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.force==b.force &&
+ a.torque==b.torque );
+#endif
+}
+
+IMETHOD bool operator!=(const Wrench& a,const Wrench& b) {
+ return !operator==(a,b);
+}
+IMETHOD bool operator!=(const Rotation& a,const Rotation& b) {
+ return !operator==(a,b);
+}
+
diff --git a/intern/itasc/kdl/frames_io.cpp b/intern/itasc/kdl/frames_io.cpp
new file mode 100644
index 00000000000..0af50bb0e07
--- /dev/null
+++ b/intern/itasc/kdl/frames_io.cpp
@@ -0,0 +1,310 @@
+
+/***************************************************************************
+ frames_io.h - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+#include "utilities/error.h"
+#include "utilities/error_stack.h"
+#include "frames.hpp"
+#include "frames_io.hpp"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <iostream>
+
+namespace KDL {
+
+
+std::ostream& operator << (std::ostream& os,const Vector& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v(0) << "," << std::setw(KDL_FRAME_WIDTH)<<v(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v(2) << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os,const Twist& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v.vel(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.vel(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.vel(2)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.rot(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.rot(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.rot(2)
+ << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os,const Wrench& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v.force(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.force(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.force(2)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.torque(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.torque(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.torque(2)
+ << "]";
+ return os;
+}
+
+
+std::ostream& operator << (std::ostream& os,const Rotation& R) {
+#ifdef KDL_ROTATION_PROPERTIES_RPY
+ double r,p,y;
+ R.GetRPY(r,p,y);
+ os << "[RPY]"<<endl;
+ os << "[";
+ os << std::setw(KDL_FRAME_WIDTH) << r << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << p << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << y << "]";
+#else
+# ifdef KDL_ROTATION_PROPERTIES_EULER
+ double z,y,x;
+ R.GetEulerZYX(z,y,x);
+ os << "[EULERZYX]"<<endl;
+ os << "[";
+ os << std::setw(KDL_FRAME_WIDTH) << z << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << y << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << x << "]";
+# else
+ os << "[";
+ for (int i=0;i<=2;i++) {
+ os << std::setw(KDL_FRAME_WIDTH) << R(i,0) << "," <<
+ std::setw(KDL_FRAME_WIDTH) << R(i,1) << "," <<
+ std::setw(KDL_FRAME_WIDTH) << R(i,2);
+ if (i<2)
+ os << ";"<< std::endl << " ";
+ else
+ os << "]";
+ }
+# endif
+#endif
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os, const Frame& T)
+{
+ os << "[" << T.M << std::endl<< T.p << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os,const Vector2& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v(0) << "," << std::setw(KDL_FRAME_WIDTH)<<v(1)
+ << "]";
+ return os;
+}
+
+// Rotation2 gives back an angle in degrees with the << and >> operators.
+std::ostream& operator << (std::ostream& os,const Rotation2& R) {
+ os << "[" << R.GetRot()*rad2deg << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os, const Frame2& T)
+{
+ os << T.M << T.p;
+ return os;
+}
+
+std::istream& operator >> (std::istream& is,Vector& v)
+{ IOTrace("Stream input Vector (vector or ZERO)");
+ char storage[10];
+ EatWord(is,"[]",storage,10);
+ if (strlen(storage)==0) {
+ Eat(is,'[');
+ is >> v(0);
+ Eat(is,',');
+ is >> v(1);
+ Eat(is,',');
+ is >> v(2);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"ZERO")==0) {
+ v = Vector::Zero();
+ IOTracePop();
+ return is;
+ }
+ throw Error_Frame_Vector_Unexpected_id();
+}
+
+std::istream& operator >> (std::istream& is,Twist& v)
+{ IOTrace("Stream input Twist");
+ Eat(is,'[');
+ is >> v.vel(0);
+ Eat(is,',');
+ is >> v.vel(1);
+ Eat(is,',');
+ is >> v.vel(2);
+ Eat(is,',');
+ is >> v.rot(0);
+ Eat(is,',');
+ is >> v.rot(1);
+ Eat(is,',');
+ is >> v.rot(2);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Wrench& v)
+{ IOTrace("Stream input Wrench");
+ Eat(is,'[');
+ is >> v.force(0);
+ Eat(is,',');
+ is >> v.force(1);
+ Eat(is,',');
+ is >> v.force(2);
+ Eat(is,',');
+ is >> v.torque(0);
+ Eat(is,',');
+ is >> v.torque(1);
+ Eat(is,',');
+ is >> v.torque(2);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Rotation& r)
+{ IOTrace("Stream input Rotation (Matrix or EULERZYX, EULERZYZ,RPY, ROT, IDENTITY)");
+ char storage[10];
+ EatWord(is,"[]",storage,10);
+ if (strlen(storage)==0) {
+ Eat(is,'[');
+ for (int i=0;i<3;i++) {
+ is >> r(i,0);
+ Eat(is,',') ;
+ is >> r(i,1);
+ Eat(is,',');
+ is >> r(i,2);
+ if (i<2)
+ Eat(is,';');
+ else
+ EatEnd(is,']');
+ }
+ IOTracePop();
+ return is;
+ }
+ Vector v;
+ if (strcmp(storage,"EULERZYX")==0) {
+ is >> v;
+ v=v*deg2rad;
+ r = Rotation::EulerZYX(v(0),v(1),v(2));
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"EULERZYZ")==0) {
+ is >> v;
+ v=v*deg2rad;
+ r = Rotation::EulerZYZ(v(0),v(1),v(2));
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"RPY")==0) {
+ is >> v;
+ v=v*deg2rad;
+ r = Rotation::RPY(v(0),v(1),v(2));
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"ROT")==0) {
+ is >> v;
+ double angle;
+ Eat(is,'[');
+ is >> angle;
+ EatEnd(is,']');
+ r = Rotation::Rot(v,angle*deg2rad);
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"IDENTITY")==0) {
+ r = Rotation::Identity();
+ IOTracePop();
+ return is;
+ }
+ throw Error_Frame_Rotation_Unexpected_id();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Frame& T)
+{ IOTrace("Stream input Frame (Rotation,Vector) or DH[...]");
+ char storage[10];
+ EatWord(is,"[",storage,10);
+ if (strlen(storage)==0) {
+ Eat(is,'[');
+ is >> T.M;
+ is >> T.p;
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"DH")==0) {
+ double a,alpha,d,theta;
+ Eat(is,'[');
+ is >> a;
+ Eat(is,',');
+ is >> alpha;
+ Eat(is,',');
+ is >> d;
+ Eat(is,',');
+ is >> theta;
+ EatEnd(is,']');
+ T = Frame::DH(a,alpha*deg2rad,d,theta*deg2rad);
+ IOTracePop();
+ return is;
+ }
+ throw Error_Frame_Frame_Unexpected_id();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Vector2& v)
+{ IOTrace("Stream input Vector2");
+ Eat(is,'[');
+ is >> v(0);
+ Eat(is,',');
+ is >> v(1);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+std::istream& operator >> (std::istream& is,Rotation2& r)
+{ IOTrace("Stream input Rotation2");
+ Eat(is,'[');
+ double val;
+ is >> val;
+ r.Rot(val*deg2rad);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+std::istream& operator >> (std::istream& is,Frame2& T)
+{ IOTrace("Stream input Frame2");
+ is >> T.M;
+ is >> T.p;
+ IOTracePop();
+ return is;
+}
+
+} // namespace Frame
diff --git a/intern/itasc/kdl/frames_io.hpp b/intern/itasc/kdl/frames_io.hpp
new file mode 100644
index 00000000000..a358d27383f
--- /dev/null
+++ b/intern/itasc/kdl/frames_io.hpp
@@ -0,0 +1,114 @@
+/***************************************************************************
+ frames_io.h - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ Ruben Smits - Added output for jacobian and jntarray 06/2007
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+/**
+//
+// \file
+// Defines routines for I/O of Frame and related objects.
+// \verbatim
+// Spaces, tabs and newlines do not have any importance.
+// Comments are allowed C-style,C++-style, make/perl/csh -style
+// Description of the I/O :
+// Vector : OUTPUT : e.g. [10,20,30]
+// INPUT :
+// 1) [10,20,30]
+// 2) Zero
+// Twist : e.g. [1,2,3,4,5,6]
+// where [1,2,3] is velocity vector
+// where [4,5,6] is rotational velocity vector
+// Wrench : e.g. [1,2,3,4,5,6]
+// where [1,2,3] represents a force vector
+// where [4,5,6] represents a torque vector
+// Rotation : output :
+// [1,2,3;
+// 4,5,6;
+// 7,8,9] cfr definition of Rotation object.
+// input :
+// 1) like the output
+// 2) EulerZYX,EulerZYZ,RPY word followed by a vector, e.g. :
+// Eulerzyx[10,20,30]
+// (ANGLES are always expressed in DEGREES for I/O)
+// (ANGELS are always expressed in RADIANS for internal representation)
+// 3) Rot [1,2,3] [20] Rotates around axis [1,2,3] with an angle
+// of 20 degrees.
+// 4) Identity returns identity rotation matrix.
+// Frames : output : [ Rotationmatrix positionvector ]
+// e.g. [ [1,0,0;0,1,0;0,0,1] [1,2,3] ]
+// Input :
+// 1) [ Rotationmatrix positionvector ]
+// 2) DH [ 10,10,50,30] Denavit-Hartenberg representation
+// ( is in fact not the representation of a Frame, but more
+// limited, cfr. documentation of Frame object.)
+// \endverbatim
+//
+// \warning
+// You can use iostream.h or iostream header files for file I/O,
+// if one declares the define WANT_STD_IOSTREAM then the standard C++
+// iostreams headers are included instead of the compiler-dependent version
+//
+ *
+ ****************************************************************************/
+#ifndef FRAMES_IO_H
+#define FRAMES_IO_H
+
+#include "utilities/utility_io.h"
+#include "frames.hpp"
+#include "jntarray.hpp"
+#include "jacobian.hpp"
+
+namespace KDL {
+
+ //! width to be used when printing variables out with frames_io.h
+ //! global variable, can be changed.
+
+
+ // I/O to C++ stream.
+ std::ostream& operator << (std::ostream& os,const Vector& v);
+ std::ostream& operator << (std::ostream& os,const Rotation& R);
+ std::ostream& operator << (std::ostream& os,const Frame& T);
+ std::ostream& operator << (std::ostream& os,const Twist& T);
+ std::ostream& operator << (std::ostream& os,const Wrench& T);
+ std::ostream& operator << (std::ostream& os,const Vector2& v);
+ std::ostream& operator << (std::ostream& os,const Rotation2& R);
+ std::ostream& operator << (std::ostream& os,const Frame2& T);
+
+
+
+ std::istream& operator >> (std::istream& is,Vector& v);
+ std::istream& operator >> (std::istream& is,Rotation& R);
+ std::istream& operator >> (std::istream& is,Frame& T);
+ std::istream& operator >> (std::istream& os,Twist& T);
+ std::istream& operator >> (std::istream& os,Wrench& T);
+ std::istream& operator >> (std::istream& is,Vector2& v);
+ std::istream& operator >> (std::istream& is,Rotation2& R);
+ std::istream& operator >> (std::istream& is,Frame2& T);
+
+
+} // namespace Frame
+
+#endif
diff --git a/intern/itasc/kdl/framevel.cpp b/intern/itasc/kdl/framevel.cpp
new file mode 100644
index 00000000000..f70bef2e923
--- /dev/null
+++ b/intern/itasc/kdl/framevel.cpp
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ ****************************************************************************/
+
+
+#include "framevel.hpp"
+
+namespace KDL {
+
+#ifndef KDL_INLINE
+ #include "framevel.inl"
+#endif
+
+
+
+}
diff --git a/intern/itasc/kdl/framevel.hpp b/intern/itasc/kdl/framevel.hpp
new file mode 100644
index 00000000000..21a7844f522
--- /dev/null
+++ b/intern/itasc/kdl/framevel.hpp
@@ -0,0 +1,382 @@
+/*****************************************************************************
+ * \file
+ * This file contains the definition of classes for a
+ * Rall Algebra of (subset of) the classes defined in frames,
+ * i.e. classes that contain a pair (value,derivative) and define operations on that pair
+ * this classes are usefull for automatic differentiation ( <-> symbolic diff , <-> numeric diff)
+ * Defines VectorVel, RotationVel, FrameVel. Look at Frames.h for details on how to work
+ * with Frame objects.
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: framevel.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef KDL_FRAMEVEL_H
+#define KDL_FRAMEVEL_H
+
+#include "utilities/utility.h"
+#include "utilities/rall1d.h"
+#include "utilities/traits.h"
+
+#include "frames.hpp"
+
+
+
+namespace KDL {
+
+typedef Rall1d<double> doubleVel;
+
+IMETHOD doubleVel diff(const doubleVel& a,const doubleVel& b,double dt=1.0) {
+ return doubleVel((b.t-a.t)/dt,(b.grad-a.grad)/dt);
+}
+
+IMETHOD doubleVel addDelta(const doubleVel& a,const doubleVel&da,double dt=1.0) {
+ return doubleVel(a.t+da.t*dt,a.grad+da.grad*dt);
+}
+
+IMETHOD void random(doubleVel& F) {
+ random(F.t);
+ random(F.grad);
+}
+IMETHOD void posrandom(doubleVel& F) {
+ posrandom(F.t);
+ posrandom(F.grad);
+}
+
+}
+
+template <>
+struct Traits<KDL::doubleVel> {
+ typedef double valueType;
+ typedef KDL::doubleVel derivType;
+};
+
+namespace KDL {
+
+class TwistVel;
+class VectorVel;
+class FrameVel;
+class RotationVel;
+
+class VectorVel
+// = TITLE
+// An VectorVel is a Vector and its first derivative
+// = CLASS TYPE
+// Concrete
+{
+public:
+ Vector p; // position vector
+ Vector v; // velocity vector
+public:
+ VectorVel():p(),v(){}
+ VectorVel(const Vector& _p,const Vector& _v):p(_p),v(_v) {}
+ explicit VectorVel(const Vector& _p):p(_p),v(Vector::Zero()) {}
+
+ Vector value() const { return p;}
+ Vector deriv() const { return v;}
+
+ IMETHOD VectorVel& operator = (const VectorVel& arg);
+ IMETHOD VectorVel& operator = (const Vector& arg);
+ IMETHOD VectorVel& operator += (const VectorVel& arg);
+ IMETHOD VectorVel& operator -= (const VectorVel& arg);
+ IMETHOD static VectorVel Zero();
+ IMETHOD void ReverseSign();
+ IMETHOD doubleVel Norm() const;
+ IMETHOD friend VectorVel operator + (const VectorVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator - (const VectorVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator + (const Vector& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator - (const Vector& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator + (const VectorVel& r1,const Vector& r2);
+ IMETHOD friend VectorVel operator - (const VectorVel& r1,const Vector& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r1,const Vector& r2);
+ IMETHOD friend VectorVel operator * (const Vector& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r1,double r2);
+ IMETHOD friend VectorVel operator * (double r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const doubleVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r2,const doubleVel& r1);
+ IMETHOD friend VectorVel operator*(const Rotation& R,const VectorVel& x);
+
+ IMETHOD friend VectorVel operator / (const VectorVel& r1,double r2);
+ IMETHOD friend VectorVel operator / (const VectorVel& r2,const doubleVel& r1);
+ IMETHOD friend void SetToZero(VectorVel& v);
+
+
+ IMETHOD friend bool Equal(const VectorVel& r1,const VectorVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Vector& r1,const VectorVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const VectorVel& r1,const Vector& r2,double eps=epsilon);
+ IMETHOD friend VectorVel operator - (const VectorVel& r);
+ IMETHOD friend doubleVel dot(const VectorVel& lhs,const VectorVel& rhs);
+ IMETHOD friend doubleVel dot(const VectorVel& lhs,const Vector& rhs);
+ IMETHOD friend doubleVel dot(const Vector& lhs,const VectorVel& rhs);
+};
+
+
+
+class RotationVel
+// = TITLE
+// An RotationVel is a Rotation and its first derivative, a rotation vector
+// = CLASS TYPE
+// Concrete
+{
+public:
+ Rotation R; // Rotation matrix
+ Vector w; // rotation vector
+public:
+ RotationVel():R(),w() {}
+ explicit RotationVel(const Rotation& _R):R(_R),w(Vector::Zero()){}
+ RotationVel(const Rotation& _R,const Vector& _w):R(_R),w(_w){}
+
+
+ Rotation value() const { return R;}
+ Vector deriv() const { return w;}
+
+
+ IMETHOD RotationVel& operator = (const RotationVel& arg);
+ IMETHOD RotationVel& operator = (const Rotation& arg);
+ IMETHOD VectorVel UnitX() const;
+ IMETHOD VectorVel UnitY() const;
+ IMETHOD VectorVel UnitZ() const;
+ IMETHOD static RotationVel Identity();
+ IMETHOD RotationVel Inverse() const;
+ IMETHOD VectorVel Inverse(const VectorVel& arg) const;
+ IMETHOD VectorVel Inverse(const Vector& arg) const;
+ IMETHOD VectorVel operator*(const VectorVel& arg) const;
+ IMETHOD VectorVel operator*(const Vector& arg) const;
+ IMETHOD void DoRotX(const doubleVel& angle);
+ IMETHOD void DoRotY(const doubleVel& angle);
+ IMETHOD void DoRotZ(const doubleVel& angle);
+ IMETHOD static RotationVel RotX(const doubleVel& angle);
+ IMETHOD static RotationVel RotY(const doubleVel& angle);
+ IMETHOD static RotationVel RotZ(const doubleVel& angle);
+ IMETHOD static RotationVel Rot(const Vector& rotvec,const doubleVel& angle);
+ // rotvec has arbitrary norm
+ // rotation around a constant vector !
+ IMETHOD static RotationVel Rot2(const Vector& rotvec,const doubleVel& angle);
+ // rotvec is normalized.
+ // rotation around a constant vector !
+ IMETHOD friend RotationVel operator* (const RotationVel& r1,const RotationVel& r2);
+ IMETHOD friend RotationVel operator* (const Rotation& r1,const RotationVel& r2);
+ IMETHOD friend RotationVel operator* (const RotationVel& r1,const Rotation& r2);
+ IMETHOD friend bool Equal(const RotationVel& r1,const RotationVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Rotation& r1,const RotationVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const RotationVel& r1,const Rotation& r2,double eps=epsilon);
+
+ IMETHOD TwistVel Inverse(const TwistVel& arg) const;
+ IMETHOD TwistVel Inverse(const Twist& arg) const;
+ IMETHOD TwistVel operator * (const TwistVel& arg) const;
+ IMETHOD TwistVel operator * (const Twist& arg) const;
+};
+
+
+
+
+class FrameVel
+// = TITLE
+// An FrameVel is a Frame and its first derivative, a Twist vector
+// = CLASS TYPE
+// Concrete
+// = CAVEATS
+//
+{
+public:
+ RotationVel M;
+ VectorVel p;
+public:
+ FrameVel(){}
+
+ explicit FrameVel(const Frame& _T):
+ M(_T.M),p(_T.p) {}
+
+ FrameVel(const Frame& _T,const Twist& _t):
+ M(_T.M,_t.rot),p(_T.p,_t.vel) {}
+
+ FrameVel(const RotationVel& _M,const VectorVel& _p):
+ M(_M),p(_p) {}
+
+
+ Frame value() const { return Frame(M.value(),p.value());}
+ Twist deriv() const { return Twist(p.deriv(),M.deriv());}
+
+
+ IMETHOD FrameVel& operator = (const Frame& arg);
+ IMETHOD FrameVel& operator = (const FrameVel& arg);
+ IMETHOD static FrameVel Identity();
+ IMETHOD FrameVel Inverse() const;
+ IMETHOD VectorVel Inverse(const VectorVel& arg) const;
+ IMETHOD VectorVel operator*(const VectorVel& arg) const;
+ IMETHOD VectorVel operator*(const Vector& arg) const;
+ IMETHOD VectorVel Inverse(const Vector& arg) const;
+ IMETHOD Frame GetFrame() const;
+ IMETHOD Twist GetTwist() const;
+ IMETHOD friend FrameVel operator * (const FrameVel& f1,const FrameVel& f2);
+ IMETHOD friend FrameVel operator * (const Frame& f1,const FrameVel& f2);
+ IMETHOD friend FrameVel operator * (const FrameVel& f1,const Frame& f2);
+ IMETHOD friend bool Equal(const FrameVel& r1,const FrameVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Frame& r1,const FrameVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const FrameVel& r1,const Frame& r2,double eps=epsilon);
+
+ IMETHOD TwistVel Inverse(const TwistVel& arg) const;
+ IMETHOD TwistVel Inverse(const Twist& arg) const;
+ IMETHOD TwistVel operator * (const TwistVel& arg) const;
+ IMETHOD TwistVel operator * (const Twist& arg) const;
+};
+
+
+
+
+
+//very similar to Wrench class.
+class TwistVel
+// = TITLE
+// This class represents a TwistVel. This is a velocity and rotational velocity together
+{
+public:
+ VectorVel vel;
+ VectorVel rot;
+public:
+
+// = Constructors
+ TwistVel():vel(),rot() {};
+ TwistVel(const VectorVel& _vel,const VectorVel& _rot):vel(_vel),rot(_rot) {};
+ TwistVel(const Twist& p,const Twist& v):vel(p.vel, v.vel), rot( p.rot, v.rot) {};
+ TwistVel(const Twist& p):vel(p.vel), rot( p.rot) {};
+
+ Twist value() const {
+ return Twist(vel.value(),rot.value());
+ }
+ Twist deriv() const {
+ return Twist(vel.deriv(),rot.deriv());
+ }
+// = Operators
+ IMETHOD TwistVel& operator-=(const TwistVel& arg);
+ IMETHOD TwistVel& operator+=(const TwistVel& arg);
+
+// = External operators
+ IMETHOD friend TwistVel operator*(const TwistVel& lhs,double rhs);
+ IMETHOD friend TwistVel operator*(double lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator/(const TwistVel& lhs,double rhs);
+
+ IMETHOD friend TwistVel operator*(const TwistVel& lhs,const doubleVel& rhs);
+ IMETHOD friend TwistVel operator*(const doubleVel& lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator/(const TwistVel& lhs,const doubleVel& rhs);
+
+ IMETHOD friend TwistVel operator+(const TwistVel& lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator-(const TwistVel& lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator-(const TwistVel& arg);
+ IMETHOD friend void SetToZero(TwistVel& v);
+
+
+// = Zero
+ static IMETHOD TwistVel Zero();
+
+// = Reverse Sign
+ IMETHOD void ReverseSign();
+
+// = Change Reference point
+ IMETHOD TwistVel RefPoint(const VectorVel& v_base_AB);
+ // Changes the reference point of the TwistVel.
+ // The VectorVel v_base_AB is expressed in the same base as the TwistVel
+ // The VectorVel v_base_AB is a VectorVel from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+
+ // = Equality operators
+ // do not use operator == because the definition of Equal(.,.) is slightly
+ // different. It compares whether the 2 arguments are equal in an eps-interval
+ IMETHOD friend bool Equal(const TwistVel& a,const TwistVel& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const Twist& a,const TwistVel& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const TwistVel& a,const Twist& b,double eps=epsilon);
+
+// = Conversion to other entities
+ IMETHOD Twist GetTwist() const;
+ IMETHOD Twist GetTwistDot() const;
+// = Friends
+ friend class RotationVel;
+ friend class FrameVel;
+
+};
+
+IMETHOD VectorVel diff(const VectorVel& a,const VectorVel& b,double dt=1.0) {
+ return VectorVel(diff(a.p,b.p,dt),diff(a.v,b.v,dt));
+}
+
+IMETHOD VectorVel addDelta(const VectorVel& a,const VectorVel&da,double dt=1.0) {
+ return VectorVel(addDelta(a.p,da.p,dt),addDelta(a.v,da.v,dt));
+}
+IMETHOD VectorVel diff(const RotationVel& a,const RotationVel& b,double dt = 1.0) {
+ return VectorVel(diff(a.R,b.R,dt),diff(a.w,b.w,dt));
+}
+
+IMETHOD RotationVel addDelta(const RotationVel& a,const VectorVel&da,double dt=1.0) {
+ return RotationVel(addDelta(a.R,da.p,dt),addDelta(a.w,da.v,dt));
+}
+
+IMETHOD TwistVel diff(const FrameVel& a,const FrameVel& b,double dt=1.0) {
+ return TwistVel(diff(a.M,b.M,dt),diff(a.p,b.p,dt));
+}
+
+IMETHOD FrameVel addDelta(const FrameVel& a,const TwistVel& da,double dt=1.0) {
+ return FrameVel(
+ addDelta(a.M,da.rot,dt),
+ addDelta(a.p,da.vel,dt)
+ );
+}
+
+IMETHOD void random(VectorVel& a) {
+ random(a.p);
+ random(a.v);
+}
+IMETHOD void random(TwistVel& a) {
+ random(a.vel);
+ random(a.rot);
+}
+
+IMETHOD void random(RotationVel& R) {
+ random(R.R);
+ random(R.w);
+}
+
+IMETHOD void random(FrameVel& F) {
+ random(F.M);
+ random(F.p);
+}
+IMETHOD void posrandom(VectorVel& a) {
+ posrandom(a.p);
+ posrandom(a.v);
+}
+IMETHOD void posrandom(TwistVel& a) {
+ posrandom(a.vel);
+ posrandom(a.rot);
+}
+
+IMETHOD void posrandom(RotationVel& R) {
+ posrandom(R.R);
+ posrandom(R.w);
+}
+
+IMETHOD void posrandom(FrameVel& F) {
+ posrandom(F.M);
+ posrandom(F.p);
+}
+
+#ifdef KDL_INLINE
+#include "framevel.inl"
+#endif
+
+} // namespace
+
+#endif
+
+
+
+
diff --git a/intern/itasc/kdl/framevel.inl b/intern/itasc/kdl/framevel.inl
new file mode 100644
index 00000000000..994b3d2028e
--- /dev/null
+++ b/intern/itasc/kdl/framevel.inl
@@ -0,0 +1,534 @@
+/*****************************************************************************
+ * \file
+ * provides inline functions of rframes.h
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: framevel.inl 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+// Methods and operators related to FrameVelVel
+// They all delegate most of the work to RotationVelVel and VectorVelVel
+FrameVel& FrameVel::operator = (const FrameVel& arg) {
+ M=arg.M;
+ p=arg.p;
+ return *this;
+}
+
+FrameVel FrameVel::Identity() {
+ return FrameVel(RotationVel::Identity(),VectorVel::Zero());
+}
+
+
+FrameVel operator *(const FrameVel& lhs,const FrameVel& rhs)
+{
+ return FrameVel(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameVel operator *(const FrameVel& lhs,const Frame& rhs)
+{
+ return FrameVel(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameVel operator *(const Frame& lhs,const FrameVel& rhs)
+{
+ return FrameVel(lhs.M*rhs.M , lhs.M*rhs.p+lhs.p );
+}
+
+VectorVel FrameVel::operator *(const VectorVel & arg) const
+{
+ return M*arg+p;
+}
+VectorVel FrameVel::operator *(const Vector & arg) const
+{
+ return M*arg+p;
+}
+
+VectorVel FrameVel::Inverse(const VectorVel& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+VectorVel FrameVel::Inverse(const Vector& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+FrameVel FrameVel::Inverse() const
+{
+ return FrameVel(M.Inverse(),-M.Inverse(p));
+}
+
+FrameVel& FrameVel::operator = (const Frame& arg) {
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+bool Equal(const FrameVel& r1,const FrameVel& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const Frame& r1,const FrameVel& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const FrameVel& r1,const Frame& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+
+Frame FrameVel::GetFrame() const {
+ return Frame(M.R,p.p);
+}
+
+Twist FrameVel::GetTwist() const {
+ return Twist(p.v,M.w);
+}
+
+
+RotationVel operator* (const RotationVel& r1,const RotationVel& r2) {
+ return RotationVel( r1.R*r2.R, r1.w + r1.R*r2.w );
+}
+
+RotationVel operator* (const Rotation& r1,const RotationVel& r2) {
+ return RotationVel( r1*r2.R, r1*r2.w );
+}
+
+RotationVel operator* (const RotationVel& r1,const Rotation& r2) {
+ return RotationVel( r1.R*r2, r1.w );
+}
+
+RotationVel& RotationVel::operator = (const RotationVel& arg) {
+ R=arg.R;
+ w=arg.w;
+ return *this;
+ }
+RotationVel& RotationVel::operator = (const Rotation& arg) {
+ R=arg;
+ w=Vector::Zero();
+ return *this;
+}
+
+VectorVel RotationVel::UnitX() const {
+ return VectorVel(R.UnitX(),w*R.UnitX());
+}
+
+VectorVel RotationVel::UnitY() const {
+ return VectorVel(R.UnitY(),w*R.UnitY());
+}
+
+VectorVel RotationVel::UnitZ() const {
+ return VectorVel(R.UnitZ(),w*R.UnitZ());
+}
+
+
+
+RotationVel RotationVel::Identity() {
+ return RotationVel(Rotation::Identity(),Vector::Zero());
+}
+
+RotationVel RotationVel::Inverse() const {
+ return RotationVel(R.Inverse(),-R.Inverse(w));
+}
+
+VectorVel RotationVel::Inverse(const VectorVel& arg) const {
+ Vector tmp=R.Inverse(arg.p);
+ return VectorVel(tmp,
+ R.Inverse(arg.v-w*arg.p)
+ );
+}
+
+VectorVel RotationVel::Inverse(const Vector& arg) const {
+ Vector tmp=R.Inverse(arg);
+ return VectorVel(tmp,
+ R.Inverse(-w*arg)
+ );
+}
+
+
+VectorVel RotationVel::operator*(const VectorVel& arg) const {
+ Vector tmp=R*arg.p;
+ return VectorVel(tmp,w*tmp+R*arg.v);
+}
+
+VectorVel RotationVel::operator*(const Vector& arg) const {
+ Vector tmp=R*arg;
+ return VectorVel(tmp,w*tmp);
+}
+
+
+// = Rotations
+// The Rot... static functions give the value of the appropriate rotation matrix back.
+// The DoRot... functions apply a rotation R to *this,such that *this = *this * R.
+
+void RotationVel::DoRotX(const doubleVel& angle) {
+ w+=R*Vector(angle.grad,0,0);
+ R.DoRotX(angle.t);
+}
+RotationVel RotationVel::RotX(const doubleVel& angle) {
+ return RotationVel(Rotation::RotX(angle.t),Vector(angle.grad,0,0));
+}
+
+void RotationVel::DoRotY(const doubleVel& angle) {
+ w+=R*Vector(0,angle.grad,0);
+ R.DoRotY(angle.t);
+}
+RotationVel RotationVel::RotY(const doubleVel& angle) {
+ return RotationVel(Rotation::RotX(angle.t),Vector(0,angle.grad,0));
+}
+
+void RotationVel::DoRotZ(const doubleVel& angle) {
+ w+=R*Vector(0,0,angle.grad);
+ R.DoRotZ(angle.t);
+}
+RotationVel RotationVel::RotZ(const doubleVel& angle) {
+ return RotationVel(Rotation::RotZ(angle.t),Vector(0,0,angle.grad));
+}
+
+
+RotationVel RotationVel::Rot(const Vector& rotvec,const doubleVel& angle)
+// rotvec has arbitrary norm
+// rotation around a constant vector !
+{
+ Vector v(rotvec);
+ v.Normalize();
+ return RotationVel(Rotation::Rot2(v,angle.t),v*angle.grad);
+}
+
+RotationVel RotationVel::Rot2(const Vector& rotvec,const doubleVel& angle)
+ // rotvec is normalized.
+{
+ return RotationVel(Rotation::Rot2(rotvec,angle.t),rotvec*angle.grad);
+}
+
+
+VectorVel operator + (const VectorVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.p+r2.p,r1.v+r2.v);
+}
+
+VectorVel operator - (const VectorVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.p-r2.p,r1.v-r2.v);
+}
+
+VectorVel operator + (const VectorVel& r1,const Vector& r2) {
+ return VectorVel(r1.p+r2,r1.v);
+}
+
+VectorVel operator - (const VectorVel& r1,const Vector& r2) {
+ return VectorVel(r1.p-r2,r1.v);
+}
+
+VectorVel operator + (const Vector& r1,const VectorVel& r2) {
+ return VectorVel(r1+r2.p,r2.v);
+}
+
+VectorVel operator - (const Vector& r1,const VectorVel& r2) {
+ return VectorVel(r1-r2.p,-r2.v);
+}
+
+// unary -
+VectorVel operator - (const VectorVel& r) {
+ return VectorVel(-r.p,-r.v);
+}
+
+void SetToZero(VectorVel& v){
+ SetToZero(v.p);
+ SetToZero(v.v);
+}
+
+// cross prod.
+VectorVel operator * (const VectorVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.p*r2.p, r1.p*r2.v+r1.v*r2.p);
+}
+
+VectorVel operator * (const VectorVel& r1,const Vector& r2) {
+ return VectorVel(r1.p*r2, r1.v*r2);
+}
+
+VectorVel operator * (const Vector& r1,const VectorVel& r2) {
+ return VectorVel(r1*r2.p, r1*r2.v);
+}
+
+
+
+// scalar mult.
+VectorVel operator * (double r1,const VectorVel& r2) {
+ return VectorVel(r1*r2.p, r1*r2.v);
+}
+
+VectorVel operator * (const VectorVel& r1,double r2) {
+ return VectorVel(r1.p*r2, r1.v*r2);
+}
+
+
+
+VectorVel operator * (const doubleVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.t*r2.p, r1.t*r2.v + r1.grad*r2.p);
+}
+
+VectorVel operator * (const VectorVel& r2,const doubleVel& r1) {
+ return VectorVel(r1.t*r2.p, r1.t*r2.v + r1.grad*r2.p);
+}
+
+VectorVel operator / (const VectorVel& r1,double r2) {
+ return VectorVel(r1.p/r2, r1.v/r2);
+}
+
+VectorVel operator / (const VectorVel& r2,const doubleVel& r1) {
+ return VectorVel(r2.p/r1.t, r2.v/r1.t - r2.p*r1.grad/r1.t/r1.t);
+}
+
+VectorVel operator*(const Rotation& R,const VectorVel& x) {
+ return VectorVel(R*x.p,R*x.v);
+}
+
+VectorVel& VectorVel::operator = (const VectorVel& arg) {
+ p=arg.p;
+ v=arg.v;
+ return *this;
+}
+VectorVel& VectorVel::operator = (const Vector& arg) {
+ p=arg;
+ v=Vector::Zero();
+ return *this;
+}
+VectorVel& VectorVel::operator += (const VectorVel& arg) {
+ p+=arg.p;
+ v+=arg.v;
+ return *this;
+}
+VectorVel& VectorVel::operator -= (const VectorVel& arg) {
+ p-=arg.p;
+ v-=arg.v;
+ return *this;
+}
+
+VectorVel VectorVel::Zero() {
+ return VectorVel(Vector::Zero(),Vector::Zero());
+}
+void VectorVel::ReverseSign() {
+ p.ReverseSign();
+ v.ReverseSign();
+}
+doubleVel VectorVel::Norm() const {
+ double n = p.Norm();
+ return doubleVel(n,dot(p,v)/n);
+}
+
+bool Equal(const VectorVel& r1,const VectorVel& r2,double eps) {
+ return (Equal(r1.p,r2.p,eps) && Equal(r1.v,r2.v,eps));
+}
+bool Equal(const Vector& r1,const VectorVel& r2,double eps) {
+ return (Equal(r1,r2.p,eps) && Equal(Vector::Zero(),r2.v,eps));
+}
+bool Equal(const VectorVel& r1,const Vector& r2,double eps) {
+ return (Equal(r1.p,r2,eps) && Equal(r1.v,Vector::Zero(),eps));
+}
+
+bool Equal(const RotationVel& r1,const RotationVel& r2,double eps) {
+ return (Equal(r1.w,r2.w,eps) && Equal(r1.R,r2.R,eps));
+}
+bool Equal(const Rotation& r1,const RotationVel& r2,double eps) {
+ return (Equal(Vector::Zero(),r2.w,eps) && Equal(r1,r2.R,eps));
+}
+bool Equal(const RotationVel& r1,const Rotation& r2,double eps) {
+ return (Equal(r1.w,Vector::Zero(),eps) && Equal(r1.R,r2,eps));
+}
+bool Equal(const TwistVel& a,const TwistVel& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const Twist& a,const TwistVel& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const TwistVel& a,const Twist& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+
+
+
+IMETHOD doubleVel dot(const VectorVel& lhs,const VectorVel& rhs) {
+ return doubleVel(dot(lhs.p,rhs.p),dot(lhs.p,rhs.v)+dot(lhs.v,rhs.p));
+}
+IMETHOD doubleVel dot(const VectorVel& lhs,const Vector& rhs) {
+ return doubleVel(dot(lhs.p,rhs),dot(lhs.v,rhs));
+}
+IMETHOD doubleVel dot(const Vector& lhs,const VectorVel& rhs) {
+ return doubleVel(dot(lhs,rhs.p),dot(lhs,rhs.v));
+}
+
+
+
+
+
+
+
+
+
+
+
+
+TwistVel TwistVel::Zero()
+{
+ return TwistVel(VectorVel::Zero(),VectorVel::Zero());
+}
+
+
+void TwistVel::ReverseSign()
+{
+ vel.ReverseSign();
+ rot.ReverseSign();
+}
+
+TwistVel TwistVel::RefPoint(const VectorVel& v_base_AB)
+ // Changes the reference point of the TwistVel.
+ // The VectorVel v_base_AB is expressed in the same base as the TwistVel
+ // The VectorVel v_base_AB is a VectorVel from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+{
+ return TwistVel(this->vel+this->rot*v_base_AB,this->rot);
+}
+
+TwistVel& TwistVel::operator-=(const TwistVel& arg)
+{
+ vel-=arg.vel;
+ rot -=arg.rot;
+ return *this;
+}
+
+TwistVel& TwistVel::operator+=(const TwistVel& arg)
+{
+ vel+=arg.vel;
+ rot +=arg.rot;
+ return *this;
+}
+
+
+TwistVel operator*(const TwistVel& lhs,double rhs)
+{
+ return TwistVel(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistVel operator*(double lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistVel operator/(const TwistVel& lhs,double rhs)
+{
+ return TwistVel(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+TwistVel operator*(const TwistVel& lhs,const doubleVel& rhs)
+{
+ return TwistVel(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistVel operator*(const doubleVel& lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistVel operator/(const TwistVel& lhs,const doubleVel& rhs)
+{
+ return TwistVel(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+
+// addition of TwistVel's
+TwistVel operator+(const TwistVel& lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
+}
+
+TwistVel operator-(const TwistVel& lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
+}
+
+// unary -
+TwistVel operator-(const TwistVel& arg)
+{
+ return TwistVel(-arg.vel,-arg.rot);
+}
+
+void SetToZero(TwistVel& v)
+{
+ SetToZero(v.vel);
+ SetToZero(v.rot);
+}
+
+
+
+
+
+TwistVel RotationVel::Inverse(const TwistVel& arg) const
+{
+ return TwistVel(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistVel RotationVel::operator * (const TwistVel& arg) const
+{
+ return TwistVel((*this)*arg.vel,(*this)*arg.rot);
+}
+
+TwistVel RotationVel::Inverse(const Twist& arg) const
+{
+ return TwistVel(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistVel RotationVel::operator * (const Twist& arg) const
+{
+ return TwistVel((*this)*arg.vel,(*this)*arg.rot);
+}
+
+
+TwistVel FrameVel::operator * (const TwistVel& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistVel FrameVel::operator * (const Twist& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistVel FrameVel::Inverse(const TwistVel& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+TwistVel FrameVel::Inverse(const Twist& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+Twist TwistVel::GetTwist() const {
+ return Twist(vel.p,rot.p);
+}
+
+Twist TwistVel::GetTwistDot() const {
+ return Twist(vel.v,rot.v);
+}
diff --git a/intern/itasc/kdl/inertia.cpp b/intern/itasc/kdl/inertia.cpp
new file mode 100644
index 00000000000..6c7337d0dc4
--- /dev/null
+++ b/intern/itasc/kdl/inertia.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "inertia.hpp"
+
+#include <Eigen/Array>
+
+namespace KDL {
+using namespace Eigen;
+
+Inertia::Inertia(double m,double Ixx,double Iyy,double Izz,double Ixy,double Ixz,double Iyz):
+data(Matrix<double,6,6>::Zero())
+{
+ data(0,0)=Ixx;
+ data(1,1)=Iyy;
+ data(2,2)=Izz;
+ data(2,1)=data(1,2)=Ixy;
+ data(3,1)=data(1,3)=Ixz;
+ data(3,2)=data(2,3)=Iyz;
+
+ data.block(3,3,3,3)=m*Matrix<double,3,3>::Identity();
+}
+
+Inertia::~Inertia()
+{
+}
+
+
+
+}
diff --git a/intern/itasc/kdl/inertia.hpp b/intern/itasc/kdl/inertia.hpp
new file mode 100644
index 00000000000..9f33859671c
--- /dev/null
+++ b/intern/itasc/kdl/inertia.hpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDLINERTIA_HPP
+#define KDLINERTIA_HPP
+
+#include <Eigen/Array>
+#include "frames.hpp"
+
+namespace KDL {
+
+using namespace Eigen;
+
+/**
+ * This class offers the inertia-structure of a body
+ * An inertia is defined in a certain reference point and a certain reference base.
+ * The reference point does not have to coincide with the origin of the reference frame.
+ */
+class Inertia{
+public:
+
+ /**
+ * This constructor creates a cartesian space inertia matrix,
+ * the arguments are the mass and the inertia moments in the cog.
+ */
+ Inertia(double m=0,double Ixx=0,double Iyy=0,double Izz=0,double Ixy=0,double Ixz=0,double Iyz=0);
+
+ static inline Inertia Zero(){
+ return Inertia(0,0,0,0,0,0,0);
+ };
+
+ friend class Rotation;
+ friend class Frame;
+
+ /**
+ * F = m*a
+ */
+ // Wrench operator* (const AccelerationTwist& acc);
+
+
+ ~Inertia();
+private:
+ Matrix<double,6,6,RowMajor> data;
+
+};
+
+
+
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/jacobian.cpp b/intern/itasc/kdl/jacobian.cpp
new file mode 100644
index 00000000000..f8f46b32619
--- /dev/null
+++ b/intern/itasc/kdl/jacobian.cpp
@@ -0,0 +1,129 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "jacobian.hpp"
+
+namespace KDL
+{
+ Jacobian::Jacobian(unsigned int _size,unsigned int _nr_blocks):
+ size(_size),nr_blocks(_nr_blocks)
+ {
+ twists = new Twist[size*nr_blocks];
+ }
+
+ Jacobian::Jacobian(const Jacobian& arg):
+ size(arg.columns()),
+ nr_blocks(arg.nr_blocks)
+ {
+ twists = new Twist[size*nr_blocks];
+ for(unsigned int i=0;i<size*nr_blocks;i++)
+ twists[i] = arg.twists[i];
+ }
+
+ Jacobian& Jacobian::operator = (const Jacobian& arg)
+ {
+ assert(size==arg.size);
+ assert(nr_blocks==arg.nr_blocks);
+ for(unsigned int i=0;i<size;i++)
+ twists[i]=arg.twists[i];
+ return *this;
+ }
+
+
+ Jacobian::~Jacobian()
+ {
+ delete [] twists;
+ }
+
+ double Jacobian::operator()(int i,int j)const
+ {
+ assert(i<6*(int)nr_blocks&&j<(int)size);
+ return twists[j+6*(int)(floor((double)i/6))](i%6);
+ }
+
+ double& Jacobian::operator()(int i,int j)
+ {
+ assert(i<6*(int)nr_blocks&&j<(int)size);
+ return twists[j+6*(int)(floor((double)i/6))](i%6);
+ }
+
+ unsigned int Jacobian::rows()const
+ {
+ return 6*nr_blocks;
+ }
+
+ unsigned int Jacobian::columns()const
+ {
+ return size;
+ }
+
+ void SetToZero(Jacobian& jac)
+ {
+ for(unsigned int i=0;i<jac.size*jac.nr_blocks;i++)
+ SetToZero(jac.twists[i]);
+ }
+
+ void changeRefPoint(const Jacobian& src1, const Vector& base_AB, Jacobian& dest)
+ {
+ assert(src1.size==dest.size);
+ assert(src1.nr_blocks==dest.nr_blocks);
+ for(unsigned int i=0;i<src1.size*src1.nr_blocks;i++)
+ dest.twists[i]=src1.twists[i].RefPoint(base_AB);
+ }
+
+ void changeBase(const Jacobian& src1, const Rotation& rot, Jacobian& dest)
+ {
+ assert(src1.size==dest.size);
+ assert(src1.nr_blocks==dest.nr_blocks);
+ for(unsigned int i=0;i<src1.size*src1.nr_blocks;i++)
+ dest.twists[i]=rot*src1.twists[i];
+ }
+
+ void changeRefFrame(const Jacobian& src1,const Frame& frame, Jacobian& dest)
+ {
+ assert(src1.size==dest.size);
+ assert(src1.nr_blocks==dest.nr_blocks);
+ for(unsigned int i=0;i<src1.size*src1.nr_blocks;i++)
+ dest.twists[i]=frame*src1.twists[i];
+ }
+
+ bool Jacobian::operator ==(const Jacobian& arg)
+ {
+ return Equal((*this),arg);
+ }
+
+ bool Jacobian::operator!=(const Jacobian& arg)
+ {
+ return !Equal((*this),arg);
+ }
+
+ bool Equal(const Jacobian& a,const Jacobian& b,double eps)
+ {
+ if(a.rows()==b.rows()&&a.columns()==b.columns()){
+ bool rc=true;
+ for(unsigned int i=0;i<a.columns();i++)
+ rc&=Equal(a.twists[i],b.twists[i],eps);
+ return rc;
+ }else
+ return false;
+ }
+
+}
diff --git a/intern/itasc/kdl/jacobian.hpp b/intern/itasc/kdl/jacobian.hpp
new file mode 100644
index 00000000000..e9057451c9f
--- /dev/null
+++ b/intern/itasc/kdl/jacobian.hpp
@@ -0,0 +1,68 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JACOBIAN_HPP
+#define KDL_JACOBIAN_HPP
+
+#include "frames.hpp"
+
+namespace KDL
+{
+ //Forward declaration
+ class ChainJntToJacSolver;
+
+ class Jacobian
+ {
+ friend class ChainJntToJacSolver;
+ private:
+ unsigned int size;
+ unsigned int nr_blocks;
+ public:
+ Twist* twists;
+ Jacobian(unsigned int size,unsigned int nr=1);
+ Jacobian(const Jacobian& arg);
+
+ Jacobian& operator=(const Jacobian& arg);
+
+ bool operator ==(const Jacobian& arg);
+ bool operator !=(const Jacobian& arg);
+
+ friend bool Equal(const Jacobian& a,const Jacobian& b,double eps=epsilon);
+
+
+ ~Jacobian();
+
+ double operator()(int i,int j)const;
+ double& operator()(int i,int j);
+ unsigned int rows()const;
+ unsigned int columns()const;
+
+ friend void SetToZero(Jacobian& jac);
+
+ friend void changeRefPoint(const Jacobian& src1, const Vector& base_AB, Jacobian& dest);
+ friend void changeBase(const Jacobian& src1, const Rotation& rot, Jacobian& dest);
+ friend void changeRefFrame(const Jacobian& src1,const Frame& frame, Jacobian& dest);
+
+
+ };
+}
+
+#endif
diff --git a/intern/itasc/kdl/jntarray.cpp b/intern/itasc/kdl/jntarray.cpp
new file mode 100644
index 00000000000..2adb76081f3
--- /dev/null
+++ b/intern/itasc/kdl/jntarray.cpp
@@ -0,0 +1,152 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "jntarray.hpp"
+
+namespace KDL
+{
+ JntArray::JntArray():
+ size(0),
+ data(NULL)
+ {
+ }
+
+ JntArray::JntArray(unsigned int _size):
+ size(_size)
+ {
+ assert(0 < size);
+ data = new double[size];
+ SetToZero(*this);
+ }
+
+
+ JntArray::JntArray(const JntArray& arg):
+ size(arg.size)
+ {
+ data = ((0 < size) ? new double[size] : NULL);
+ for(unsigned int i=0;i<size;i++)
+ data[i]=arg.data[i];
+ }
+
+ JntArray& JntArray::operator = (const JntArray& arg)
+ {
+ assert(size==arg.size);
+ for(unsigned int i=0;i<size;i++)
+ data[i]=arg.data[i];
+ return *this;
+ }
+
+
+ JntArray::~JntArray()
+ {
+ delete [] data;
+ }
+
+ void JntArray::resize(unsigned int newSize)
+ {
+ delete [] data;
+ size = newSize;
+ data = new double[size];
+ SetToZero(*this);
+ }
+
+ double JntArray::operator()(unsigned int i,unsigned int j)const
+ {
+ assert(i<size&&j==0);
+ assert(0 != size); // found JntArray containing no data
+ return data[i];
+ }
+
+ double& JntArray::operator()(unsigned int i,unsigned int j)
+ {
+ assert(i<size&&j==0);
+ assert(0 != size); // found JntArray containing no data
+ return data[i];
+ }
+
+ unsigned int JntArray::rows()const
+ {
+ return size;
+ }
+
+ unsigned int JntArray::columns()const
+ {
+ return 0;
+ }
+
+ void Add(const JntArray& src1,const JntArray& src2,JntArray& dest)
+ {
+ assert(src1.size==src2.size&&src1.size==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=src1.data[i]+src2.data[i];
+ }
+
+ void Subtract(const JntArray& src1,const JntArray& src2,JntArray& dest)
+ {
+ assert(src1.size==src2.size&&src1.size==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=src1.data[i]-src2.data[i];
+ }
+
+ void Multiply(const JntArray& src,const double& factor,JntArray& dest)
+ {
+ assert(src.size==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=factor*src.data[i];
+ }
+
+ void Divide(const JntArray& src,const double& factor,JntArray& dest)
+ {
+ assert(src.rows()==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=src.data[i]/factor;
+ }
+
+ void MultiplyJacobian(const Jacobian& jac, const JntArray& src, Twist& dest)
+ {
+ assert(jac.columns()==src.size);
+ SetToZero(dest);
+ for(unsigned int i=0;i<6;i++)
+ for(unsigned int j=0;j<src.size;j++)
+ dest(i)+=jac(i,j)*src.data[j];
+ }
+
+ void SetToZero(JntArray& array)
+ {
+ for(unsigned int i=0;i<array.size;i++)
+ array.data[i]=0;
+ }
+
+ bool Equal(const JntArray& src1, const JntArray& src2,double eps)
+ {
+ assert(src1.size==src2.size);
+ bool ret = true;
+ for(unsigned int i=0;i<src1.size;i++)
+ ret = ret && Equal(src1.data[i],src2.data[i],eps);
+ return ret;
+ }
+
+ bool operator==(const JntArray& src1,const JntArray& src2){return Equal(src1,src2);};
+ //bool operator!=(const JntArray& src1,const JntArray& src2){return Equal(src1,src2);};
+
+}
+
+
diff --git a/intern/itasc/kdl/jntarray.hpp b/intern/itasc/kdl/jntarray.hpp
new file mode 100644
index 00000000000..19ffa4343e3
--- /dev/null
+++ b/intern/itasc/kdl/jntarray.hpp
@@ -0,0 +1,217 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JNTARRAY_HPP
+#define KDL_JNTARRAY_HPP
+
+#include "frames.hpp"
+#include "jacobian.hpp"
+
+namespace KDL
+{
+ /**
+ * @brief This class represents an fixed size array containing
+ * joint values of a KDL::Chain.
+ *
+ * \warning An object constructed with the default constructor provides
+ * a valid, but inert, object. Many of the member functions will do
+ * the correct thing and have no affect on this object, but some
+ * member functions can _NOT_ deal with an inert/empty object. These
+ * functions will assert() and exit the program instead. The intended use
+ * case for the default constructor (in an RTT/OCL setting) is outlined in
+ * code below - the default constructor plus the resize() function allow
+ * use of JntArray objects whose size is set within a configureHook() call
+ * (typically based on a size determined from a property).
+
+\code
+class MyTask : public RTT::TaskContext
+{
+ JntArray j;
+ MyTask()
+ {} // invokes j's default constructor
+
+ bool configureHook()
+ {
+ unsigned int size = some_property.rvalue();
+ j.resize(size)
+ ...
+ }
+
+ void updateHook()
+ {
+ ** use j here
+ }
+};
+/endcode
+
+ */
+
+ class JntArray
+ {
+ private:
+ unsigned int size;
+ double* data;
+ public:
+ /** Construct with _no_ data array
+ * @post NULL == data
+ * @post 0 == rows()
+ * @warning use of an object constructed like this, without
+ * a resize() first, may result in program exit! See class
+ * documentation.
+ */
+ JntArray();
+ /**
+ * Constructor of the joint array
+ *
+ * @param size size of the array, this cannot be changed
+ * afterwards.
+ * @pre 0 < size
+ * @post NULL != data
+ * @post 0 < rows()
+ * @post all elements in data have 0 value
+ */
+ JntArray(unsigned int size);
+ /** Copy constructor
+ * @note Will correctly copy an empty object
+ */
+ JntArray(const JntArray& arg);
+ ~JntArray();
+ /** Resize the array
+ * @warning This causes a dynamic allocation (and potentially
+ * also a dynamic deallocation). This _will_ negatively affect
+ * real-time performance!
+ *
+ * @post newSize == rows()
+ * @post NULL != data
+ * @post all elements in data have 0 value
+ */
+ void resize(unsigned int newSize);
+
+ JntArray& operator = ( const JntArray& arg);
+ /**
+ * get_item operator for the joint array, if a second value is
+ * given it should be zero, since a JntArray resembles a column.
+ *
+ *
+ * @return the joint value at position i, starting from 0
+ * @pre 0 != size (ie non-default constructor or resize() called)
+ */
+ double operator()(unsigned int i,unsigned int j=0)const;
+ /**
+ * set_item operator, again if a second value is given it
+ *should be zero.
+ *
+ * @return reference to the joint value at position i,starting
+ *from zero.
+ * @pre 0 != size (ie non-default constructor or resize() called)
+ */
+ double& operator()(unsigned int i,unsigned int j=0);
+ /**
+ * Returns the number of rows (size) of the array
+ *
+ */
+ unsigned int rows()const;
+ /**
+ * Returns the number of columns of the array, always 1.
+ */
+ unsigned int columns()const;
+
+ /**
+ * Function to add two joint arrays, all the arguments must
+ * have the same size: A + B = C. This function is
+ * aliasing-safe, A or B can be the same array as C.
+ *
+ * @param src1 A
+ * @param src2 B
+ * @param dest C
+ */
+ friend void Add(const JntArray& src1,const JntArray& src2,JntArray& dest);
+ /**
+ * Function to subtract two joint arrays, all the arguments must
+ * have the same size: A - B = C. This function is
+ * aliasing-safe, A or B can be the same array as C.
+ *
+ * @param src1 A
+ * @param src2 B
+ * @param dest C
+ */
+ friend void Subtract(const JntArray& src1,const JntArray& src2,JntArray& dest);
+ /**
+ * Function to multiply all the array values with a scalar
+ * factor: A*b=C. This function is aliasing-safe, A can be the
+ * same array as C.
+ *
+ * @param src A
+ * @param factor b
+ * @param dest C
+ */
+ friend void Multiply(const JntArray& src,const double& factor,JntArray& dest);
+ /**
+ * Function to divide all the array values with a scalar
+ * factor: A/b=C. This function is aliasing-safe, A can be the
+ * same array as C.
+ *
+ * @param src A
+ * @param factor b
+ * @param dest C
+ */
+ friend void Divide(const JntArray& src,const double& factor,JntArray& dest);
+ /**
+ * Function to multiply a KDL::Jacobian with a KDL::JntArray
+ * to get a KDL::Twist, it should not be used to calculate the
+ * forward velocity kinematics, the solver classes are built
+ * for this purpose.
+ * J*q = t
+ *
+ * @param jac J
+ * @param src q
+ * @param dest t
+ * @post dest==Twist::Zero() if 0==src.rows() (ie src is empty)
+ */
+ friend void MultiplyJacobian(const Jacobian& jac, const JntArray& src, Twist& dest);
+ /**
+ * Function to set all the values of the array to 0
+ *
+ * @param array
+ */
+ friend void SetToZero(JntArray& array);
+ /**
+ * Function to check if two arrays are the same with a
+ *precision of eps
+ *
+ * @param src1
+ * @param src2
+ * @param eps default: epsilon
+ * @return true if each element of src1 is within eps of the same
+ * element in src2, or if both src1 and src2 have no data (ie 0==rows())
+ */
+ friend bool Equal(const JntArray& src1,const JntArray& src2,double eps=epsilon);
+
+ friend bool operator==(const JntArray& src1,const JntArray& src2);
+ //friend bool operator!=(const JntArray& src1,const JntArray& src2);
+ };
+
+ bool operator==(const JntArray& src1,const JntArray& src2);
+ //bool operator!=(const JntArray& src1,const JntArray& src2);
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/jntarrayacc.cpp b/intern/itasc/kdl/jntarrayacc.cpp
new file mode 100644
index 00000000000..3c9c67d9ef9
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayacc.cpp
@@ -0,0 +1,170 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "jntarrayacc.hpp"
+
+namespace KDL
+{
+ JntArrayAcc::JntArrayAcc(unsigned int size):
+ q(size),qdot(size),qdotdot(size)
+ {
+ }
+ JntArrayAcc::JntArrayAcc(const JntArray& qin, const JntArray& qdotin,const JntArray& qdotdotin):
+ q(qin),qdot(qdotin),qdotdot(qdotdotin)
+ {
+ assert(q.rows()==qdot.rows()&&qdot.rows()==qdotdot.rows());
+ }
+ JntArrayAcc::JntArrayAcc(const JntArray& qin, const JntArray& qdotin):
+ q(qin),qdot(qdotin),qdotdot(q.rows())
+ {
+ assert(q.rows()==qdot.rows());
+ }
+ JntArrayAcc::JntArrayAcc(const JntArray& qin):
+ q(qin),qdot(q.rows()),qdotdot(q.rows())
+ {
+ }
+
+ JntArray JntArrayAcc::value()const
+ {
+ return q;
+ }
+
+ JntArray JntArrayAcc::deriv()const
+ {
+ return qdot;
+ }
+ JntArray JntArrayAcc::dderiv()const
+ {
+ return qdotdot;
+ }
+
+ void Add(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest)
+ {
+ Add(src1.q,src2.q,dest.q);
+ Add(src1.qdot,src2.qdot,dest.qdot);
+ Add(src1.qdotdot,src2.qdotdot,dest.qdotdot);
+ }
+ void Add(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest)
+ {
+ Add(src1.q,src2.q,dest.q);
+ Add(src1.qdot,src2.qdot,dest.qdot);
+ dest.qdotdot=src1.qdotdot;
+ }
+ void Add(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest)
+ {
+ Add(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ dest.qdotdot=src1.qdotdot;
+ }
+
+ void Subtract(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest)
+ {
+ Subtract(src1.q,src2.q,dest.q);
+ Subtract(src1.qdot,src2.qdot,dest.qdot);
+ Subtract(src1.qdotdot,src2.qdotdot,dest.qdotdot);
+ }
+ void Subtract(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest)
+ {
+ Subtract(src1.q,src2.q,dest.q);
+ Subtract(src1.qdot,src2.qdot,dest.qdot);
+ dest.qdotdot=src1.qdotdot;
+ }
+ void Subtract(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest)
+ {
+ Subtract(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ dest.qdotdot=src1.qdotdot;
+ }
+
+ void Multiply(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,factor,dest.q);
+ Multiply(src.qdot,factor,dest.qdot);
+ Multiply(src.qdotdot,factor,dest.qdotdot);
+ }
+ void Multiply(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.qdot,factor.grad*2,dest.qdot);
+ Multiply(src.qdotdot,factor.t,dest.qdotdot);
+ Add(dest.qdot,dest.qdotdot,dest.qdotdot);
+ Multiply(src.q,factor.grad,dest.q);
+ Multiply(src.qdot,factor.t,dest.qdot);
+ Add(dest.qdot,dest.q,dest.qdot);
+ Multiply(src.q,factor.t,dest.q);
+ }
+ void Multiply(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,factor.dd,dest.q);
+ Multiply(src.qdot,factor.d*2,dest.qdot);
+ Multiply(src.qdotdot,factor.t,dest.qdotdot);
+ Add(dest.qdotdot,dest.qdot,dest.qdotdot);
+ Add(dest.qdotdot,dest.q,dest.qdotdot);
+ Multiply(src.q,factor.d,dest.q);
+ Multiply(src.qdot,factor.t,dest.qdot);
+ Add(dest.qdot,dest.q,dest.qdot);
+ Multiply(src.q,factor.t,dest.q);
+ }
+
+ void Divide(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest)
+ {
+ Divide(src.q,factor,dest.q);
+ Divide(src.qdot,factor,dest.qdot);
+ Divide(src.qdotdot,factor,dest.qdotdot);
+ }
+ void Divide(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,(2*factor.grad*factor.grad)/(factor.t*factor.t*factor.t),dest.q);
+ Multiply(src.qdot,(2*factor.grad)/(factor.t*factor.t),dest.qdot);
+ Divide(src.qdotdot,factor.t,dest.qdotdot);
+ Subtract(dest.qdotdot,dest.qdot,dest.qdotdot);
+ Add(dest.qdotdot,dest.q,dest.qdotdot);
+ Multiply(src.q,factor.grad/(factor.t*factor.t),dest.q);
+ Divide(src.qdot,factor.t,dest.qdot);
+ Subtract(dest.qdot,dest.q,dest.qdot);
+ Divide(src.q,factor.t,dest.q);
+ }
+ void Divide(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,(2*factor.d*factor.d)/(factor.t*factor.t*factor.t)-factor.dd/(factor.t*factor.t),dest.q);
+ Multiply(src.qdot,(2*factor.d)/(factor.t*factor.t),dest.qdot);
+ Divide(src.qdotdot,factor.t,dest.qdotdot);
+ Subtract(dest.qdotdot,dest.qdot,dest.qdotdot);
+ Add(dest.qdotdot,dest.q,dest.qdotdot);
+ Multiply(src.q,factor.d/(factor.t*factor.t),dest.q);
+ Divide(src.qdot,factor.t,dest.qdot);
+ Subtract(dest.qdot,dest.q,dest.qdot);
+ Divide(src.q,factor.t,dest.q);
+ }
+
+ void SetToZero(JntArrayAcc& array)
+ {
+ SetToZero(array.q);
+ SetToZero(array.qdot);
+ SetToZero(array.qdotdot);
+ }
+
+ bool Equal(const JntArrayAcc& src1,const JntArrayAcc& src2,double eps)
+ {
+ return (Equal(src1.q,src2.q,eps)&&Equal(src1.qdot,src2.qdot,eps)&&Equal(src1.qdotdot,src2.qdotdot,eps));
+ }
+}
+
+
diff --git a/intern/itasc/kdl/jntarrayacc.hpp b/intern/itasc/kdl/jntarrayacc.hpp
new file mode 100644
index 00000000000..275aa58f21e
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayacc.hpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JNTARRAYACC_HPP
+#define KDL_JNTARRAYACC_HPP
+
+#include "utilities/utility.h"
+#include "jntarray.hpp"
+#include "jntarrayvel.hpp"
+#include "frameacc.hpp"
+
+namespace KDL
+{
+ class JntArrayAcc
+ {
+ public:
+ JntArray q;
+ JntArray qdot;
+ JntArray qdotdot;
+ public:
+ JntArrayAcc(unsigned int size);
+ JntArrayAcc(const JntArray& q,const JntArray& qdot,const JntArray& qdotdot);
+ JntArrayAcc(const JntArray& q,const JntArray& qdot);
+ JntArrayAcc(const JntArray& q);
+
+ JntArray value()const;
+ JntArray deriv()const;
+ JntArray dderiv()const;
+
+ friend void Add(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest);
+ friend void Add(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest);
+ friend void Add(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest);
+ friend void Subtract(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest);
+ friend void Subtract(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest);
+ friend void Subtract(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest);
+ friend void Multiply(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest);
+ friend void Multiply(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest);
+ friend void Multiply(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest);
+ friend void Divide(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest);
+ friend void Divide(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest);
+ friend void Divide(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest);
+ friend void SetToZero(JntArrayAcc& array);
+ friend bool Equal(const JntArrayAcc& src1,const JntArrayAcc& src2,double eps=epsilon);
+
+ };
+}
+
+#endif
diff --git a/intern/itasc/kdl/jntarrayvel.cpp b/intern/itasc/kdl/jntarrayvel.cpp
new file mode 100644
index 00000000000..df5c7fb0fb3
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayvel.cpp
@@ -0,0 +1,111 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#include "jntarrayacc.hpp"
+
+namespace KDL
+{
+ JntArrayVel::JntArrayVel(unsigned int size):
+ q(size),qdot(size)
+ {
+ }
+ JntArrayVel::JntArrayVel(const JntArray& qin, const JntArray& qdotin):
+ q(qin),qdot(qdotin)
+ {
+ assert(q.rows()==qdot.rows());
+ }
+ JntArrayVel::JntArrayVel(const JntArray& qin):
+ q(qin),qdot(q.rows())
+ {
+ }
+
+ JntArray JntArrayVel::value()const
+ {
+ return q;
+ }
+
+ JntArray JntArrayVel::deriv()const
+ {
+ return qdot;
+ }
+
+ void Add(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest)
+ {
+ Add(src1.q,src2.q,dest.q);
+ Add(src1.qdot,src2.qdot,dest.qdot);
+ }
+ void Add(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest)
+ {
+ Add(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ }
+
+ void Subtract(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest)
+ {
+ Subtract(src1.q,src2.q,dest.q);
+ Subtract(src1.qdot,src2.qdot,dest.qdot);
+ }
+ void Subtract(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest)
+ {
+ Subtract(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ }
+
+ void Multiply(const JntArrayVel& src,const double& factor,JntArrayVel& dest)
+ {
+ Multiply(src.q,factor,dest.q);
+ Multiply(src.qdot,factor,dest.qdot);
+ }
+ void Multiply(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest)
+ {
+ Multiply(src.q,factor.grad,dest.q);
+ Multiply(src.qdot,factor.t,dest.qdot);
+ Add(dest.qdot,dest.q,dest.qdot);
+ Multiply(src.q,factor.t,dest.q);
+ }
+
+ void Divide(const JntArrayVel& src,const double& factor,JntArrayVel& dest)
+ {
+ Divide(src.q,factor,dest.q);
+ Divide(src.qdot,factor,dest.qdot);
+ }
+ void Divide(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest)
+ {
+ Multiply(src.q,(factor.grad/factor.t/factor.t),dest.q);
+ Divide(src.qdot,factor.t,dest.qdot);
+ Subtract(dest.qdot,dest.q,dest.qdot);
+ Divide(src.q,factor.t,dest.q);
+ }
+
+ void SetToZero(JntArrayVel& array)
+ {
+ SetToZero(array.q);
+ SetToZero(array.qdot);
+ }
+
+ bool Equal(const JntArrayVel& src1,const JntArrayVel& src2,double eps)
+ {
+ return Equal(src1.q,src2.q,eps)&&Equal(src1.qdot,src2.qdot,eps);
+ }
+}
+
+
diff --git a/intern/itasc/kdl/jntarrayvel.hpp b/intern/itasc/kdl/jntarrayvel.hpp
new file mode 100644
index 00000000000..faa82076ebb
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayvel.hpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JNTARRAYVEL_HPP
+#define KDL_JNTARRAYVEL_HPP
+
+#include "utilities/utility.h"
+#include "jntarray.hpp"
+#include "framevel.hpp"
+
+namespace KDL
+{
+
+ class JntArrayVel
+ {
+ public:
+ JntArray q;
+ JntArray qdot;
+ public:
+ JntArrayVel(unsigned int size);
+ JntArrayVel(const JntArray& q,const JntArray& qdot);
+ JntArrayVel(const JntArray& q);
+
+ JntArray value()const;
+ JntArray deriv()const;
+
+ friend void Add(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest);
+ friend void Add(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest);
+ friend void Subtract(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest);
+ friend void Subtract(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest);
+ friend void Multiply(const JntArrayVel& src,const double& factor,JntArrayVel& dest);
+ friend void Multiply(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest);
+ friend void Divide(const JntArrayVel& src,const double& factor,JntArrayVel& dest);
+ friend void Divide(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest);
+ friend void SetToZero(JntArrayVel& array);
+ friend bool Equal(const JntArrayVel& src1,const JntArrayVel& src2,double eps=epsilon);
+
+ };
+}
+
+#endif
diff --git a/intern/itasc/kdl/joint.cpp b/intern/itasc/kdl/joint.cpp
new file mode 100644
index 00000000000..dc5f17e5bf7
--- /dev/null
+++ b/intern/itasc/kdl/joint.cpp
@@ -0,0 +1,153 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "joint.hpp"
+
+namespace KDL {
+
+ Joint::Joint(const JointType& _type, const double& _scale, const double& _offset,
+ const double& _inertia, const double& _damping, const double& _stiffness):
+ type(_type),scale(_scale),offset(_offset),inertia(_inertia),damping(_damping),stiffness(_stiffness)
+ {
+ // for sphere and swing, offset is not used, assume no offset
+ }
+
+ Joint::Joint(const Joint& in):
+ type(in.type),scale(in.scale),offset(in.offset),
+ inertia(in.inertia),damping(in.damping),stiffness(in.stiffness)
+ {
+ }
+
+ Joint& Joint::operator=(const Joint& in)
+ {
+ type=in.type;
+ scale=in.scale;
+ offset=in.offset;
+ inertia=in.inertia;
+ damping=in.damping;
+ stiffness=in.stiffness;
+ return *this;
+ }
+
+
+ Joint::~Joint()
+ {
+ }
+
+ Frame Joint::pose(const double& q)const
+ {
+
+ switch(type){
+ case RotX:
+ return Frame(Rotation::RotX(scale*q+offset));
+ break;
+ case RotY:
+ return Frame(Rotation::RotY(scale*q+offset));
+ break;
+ case RotZ:
+ return Frame(Rotation::RotZ(scale*q+offset));
+ break;
+ case TransX:
+ return Frame(Vector(scale*q+offset,0.0,0.0));
+ break;
+ case TransY:
+ return Frame(Vector(0.0,scale*q+offset,0.0));
+ break;
+ case TransZ:
+ return Frame(Vector(0.0,0.0,scale*q+offset));
+ break;
+ case Sphere:
+ // the joint angles represent a rotation vector expressed in the base frame of the joint
+ // (= the frame you get when there is no offset nor rotation)
+ return Frame(Rot(Vector((&q)[0], (&q)[1], (&q)[2])));
+ break;
+ case Swing:
+ // the joint angles represent a 2D rotation vector in the XZ planee of the base frame of the joint
+ // (= the frame you get when there is no offset nor rotation)
+ return Frame(Rot(Vector((&q)[0], 0.0, (&q)[1])));
+ break;
+ default:
+ return Frame::Identity();
+ break;
+ }
+ }
+
+ Twist Joint::twist(const double& qdot, int dof)const
+ {
+ switch(type){
+ case RotX:
+ return Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+ break;
+ case RotY:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,scale*qdot,0.0));
+ break;
+ case RotZ:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+ break;
+ case TransX:
+ return Twist(Vector(scale*qdot,0.0,0.0),Vector(0.0,0.0,0.0));
+ break;
+ case TransY:
+ return Twist(Vector(0.0,scale*qdot,0.0),Vector(0.0,0.0,0.0));
+ break;
+ case TransZ:
+ return Twist(Vector(0.0,0.0,scale*qdot),Vector(0.0,0.0,0.0));
+ break;
+ case Swing:
+ switch (dof) {
+ case 0:
+ return Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+ case 1:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+ }
+ return Twist::Zero();
+ case Sphere:
+ switch (dof) {
+ case 0:
+ return Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+ case 1:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,scale*qdot,0.0));
+ case 2:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+ }
+ return Twist::Zero();
+ default:
+ return Twist::Zero();
+ break;
+ }
+ }
+
+ unsigned int Joint::getNDof() const
+ {
+ switch (type) {
+ case Sphere:
+ return 3;
+ case Swing:
+ return 2;
+ case None:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+
+} // end of namespace KDL
+
diff --git a/intern/itasc/kdl/joint.hpp b/intern/itasc/kdl/joint.hpp
new file mode 100644
index 00000000000..a1291509f0f
--- /dev/null
+++ b/intern/itasc/kdl/joint.hpp
@@ -0,0 +1,138 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JOINT_HPP
+#define KDL_JOINT_HPP
+
+#include "frames.hpp"
+#include <string>
+
+namespace KDL {
+
+ /**
+ * \brief This class encapsulates a simple joint, that is with one
+ * parameterized degree of freedom and with scalar dynamic properties.
+ *
+ * A simple joint is described by the following properties :
+ * - scale: ratio between motion input and motion output
+ * - offset: between the "physical" and the "logical" zero position.
+ * - type: revolute or translational, along one of the basic frame axes
+ * - inertia, stiffness and damping: scalars representing the physical
+ * effects along/about the joint axis only.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Joint {
+ public:
+ typedef enum { RotX,RotY,RotZ,TransX,TransY,TransZ,Sphere,Swing,None} JointType;
+ /**
+ * Constructor of a joint.
+ *
+ * @param type type of the joint, default: Joint::None
+ * @param scale scale between joint input and actual geometric
+ * movement, default: 1
+ * @param offset offset between joint input and actual
+ * geometric input, default: 0
+ * @param inertia 1D inertia along the joint axis, default: 0
+ * @param damping 1D damping along the joint axis, default: 0
+ * @param stiffness 1D stiffness along the joint axis,
+ * default: 0
+ */
+ Joint(const JointType& type=None,const double& scale=1,const double& offset=0,
+ const double& inertia=0,const double& damping=0,const double& stiffness=0);
+ Joint(const Joint& in);
+
+ Joint& operator=(const Joint& arg);
+
+ /**
+ * Request the 6D-pose between the beginning and the end of
+ * the joint at joint position q
+ *
+ * @param q the 1D joint position
+ *
+ * @return the resulting 6D-pose
+ */
+ Frame pose(const double& q)const;
+ /**
+ * Request the resulting 6D-velocity with a joint velocity qdot
+ *
+ * @param qdot the 1D joint velocity
+ *
+ * @return the resulting 6D-velocity
+ */
+ Twist twist(const double& qdot, int dof=0)const;
+
+ /**
+ * Request the type of the joint.
+ *
+ * @return const reference to the type
+ */
+ const JointType& getType() const
+ {
+ return type;
+ };
+
+ /**
+ * Request the stringified type of the joint.
+ *
+ * @return const string
+ */
+ const std::string getTypeName() const
+ {
+ switch (type) {
+ case RotX:
+ return "RotX";
+ case RotY:
+ return "RotY";
+ case RotZ:
+ return "RotZ";
+ case TransX:
+ return "TransX";
+ case TransY:
+ return "TransY";
+ case TransZ:
+ return "TransZ";
+ case Sphere:
+ return "Sphere";
+ case Swing:
+ return "Swing";
+ case None:
+ return "None";
+ default:
+ return "None";
+ }
+ };
+ unsigned int getNDof() const;
+
+ virtual ~Joint();
+
+ private:
+ Joint::JointType type;
+ double scale;
+ double offset;
+ double inertia;
+ double damping;
+ double stiffness;
+ };
+
+} // end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/kinfam_io.cpp b/intern/itasc/kdl/kinfam_io.cpp
new file mode 100644
index 00000000000..900e2e101a9
--- /dev/null
+++ b/intern/itasc/kdl/kinfam_io.cpp
@@ -0,0 +1,101 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "kinfam_io.hpp"
+#include "frames_io.hpp"
+
+namespace KDL {
+std::ostream& operator <<(std::ostream& os, const Joint& joint) {
+ return os << joint.getTypeName();
+}
+
+std::istream& operator >>(std::istream& is, Joint& joint) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Segment& segment) {
+ os << "[" << segment.getJoint() << ",\n" << segment.getFrameToTip() << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, Segment& segment) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Chain& chain) {
+ os << "[";
+ for (unsigned int i = 0; i < chain.getNrOfSegments(); i++)
+ os << chain.getSegment(i) << "\n";
+ os << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, Chain& chain) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Tree& tree) {
+ SegmentMap::const_iterator root = tree.getSegment("root");
+ return os << root;
+}
+
+std::ostream& operator <<(std::ostream& os, SegmentMap::const_iterator root) {
+ //os<<root->first<<": "<<root->second.segment<<"\n";
+ os << root->first<<"(q_nr: "<<root->second.q_nr<<")"<<"\n \t";
+ for (unsigned int i = 0; i < root->second.children.size(); i++) {
+ os <<(root->second.children[i])<<"\t";
+ }
+ return os << "\n";
+}
+
+std::istream& operator >>(std::istream& is, Tree& tree) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const JntArray& array) {
+ os << "[";
+ for (unsigned int i = 0; i < array.rows(); i++)
+ os << std::setw(KDL_FRAME_WIDTH) << array(i);
+ os << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, JntArray& array) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Jacobian& jac) {
+ os << "[";
+ for (unsigned int i = 0; i < jac.rows(); i++) {
+ for (unsigned int j = 0; j < jac.columns(); j++)
+ os << std::setw(KDL_FRAME_WIDTH) << jac(i, j);
+ os << std::endl;
+ }
+ os << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, Jacobian& jac) {
+ return is;
+}
+
+}
+
diff --git a/intern/itasc/kdl/kinfam_io.hpp b/intern/itasc/kdl/kinfam_io.hpp
new file mode 100644
index 00000000000..a8dbfd1c5dc
--- /dev/null
+++ b/intern/itasc/kdl/kinfam_io.hpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_KINFAM_IO_HPP
+#define KDL_KINFAM_IO_HPP
+
+#include <iostream>
+#include <fstream>
+
+#include "joint.hpp"
+#include "segment.hpp"
+#include "chain.hpp"
+#include "jntarray.hpp"
+#include "jacobian.hpp"
+#include "tree.hpp"
+
+namespace KDL {
+std::ostream& operator <<(std::ostream& os, const Joint& joint);
+std::istream& operator >>(std::istream& is, Joint& joint);
+std::ostream& operator <<(std::ostream& os, const Segment& segment);
+std::istream& operator >>(std::istream& is, Segment& segment);
+std::ostream& operator <<(std::ostream& os, const Chain& chain);
+std::istream& operator >>(std::istream& is, Chain& chain);
+
+std::ostream& operator <<(std::ostream& os, const Tree& tree);
+std::istream& operator >>(std::istream& is, Tree& tree);
+
+std::ostream& operator <<(std::ostream& os, SegmentMap::const_iterator it);
+
+std::ostream& operator <<(std::ostream& os, const JntArray& array);
+std::istream& operator >>(std::istream& is, JntArray& array);
+std::ostream& operator <<(std::ostream& os, const Jacobian& jac);
+std::istream& operator >>(std::istream& is, Jacobian& jac);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
+ os << "[";
+ for (unsigned int i = 0; i < vec.size(); i++)
+ os << vec[i] << " ";
+ os << "]";
+ return os;
+}
+;
+
+template<typename T>
+std::istream& operator >>(std::istream& is, std::vector<T>& vec) {
+ return is;
+}
+;
+}
+#endif
+
diff --git a/intern/itasc/kdl/segment.cpp b/intern/itasc/kdl/segment.cpp
new file mode 100644
index 00000000000..02f71d5e9f1
--- /dev/null
+++ b/intern/itasc/kdl/segment.cpp
@@ -0,0 +1,68 @@
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "segment.hpp"
+
+namespace KDL {
+
+ Segment::Segment(const Joint& _joint, const Frame& _f_tip, const Inertia& _M):
+ joint(_joint),M(_M),
+ f_tip(_f_tip)
+ {
+ }
+
+ Segment::Segment(const Segment& in):
+ joint(in.joint),M(in.M),
+ f_tip(in.f_tip)
+ {
+ }
+
+ Segment& Segment::operator=(const Segment& arg)
+ {
+ joint=arg.joint;
+ M=arg.M;
+ f_tip=arg.f_tip;
+ return *this;
+ }
+
+ Segment::~Segment()
+ {
+ }
+
+ Frame Segment::pose(const double& q)const
+ {
+ return joint.pose(q)*f_tip;
+ }
+
+ Twist Segment::twist(const double& q, const double& qdot, int dof)const
+ {
+ return joint.twist(qdot, dof).RefPoint(pose(q).p);
+ }
+
+ Twist Segment::twist(const Vector& p, const double& qdot, int dof)const
+ {
+ return joint.twist(qdot, dof).RefPoint(p);
+ }
+
+ Twist Segment::twist(const Frame& f, const double& qdot, int dof)const
+ {
+ return (f.M*joint.twist(qdot, dof)).RefPoint(f.p);
+ }
+}//end of namespace KDL
+
diff --git a/intern/itasc/kdl/segment.hpp b/intern/itasc/kdl/segment.hpp
new file mode 100644
index 00000000000..7c82ab418fa
--- /dev/null
+++ b/intern/itasc/kdl/segment.hpp
@@ -0,0 +1,149 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#ifndef KDL_SEGMENT_HPP
+#define KDL_SEGMENT_HPP
+
+#include "frames.hpp"
+#include "inertia.hpp"
+#include "joint.hpp"
+#include <vector>
+
+namespace KDL {
+
+ /**
+ * \brief This class encapsulates a simple segment, that is a "rigid
+ * body" (i.e., a frame and an inertia) with a joint and with
+ * "handles", root and tip to connect to other segments.
+ *
+ * A simple segment is described by the following properties :
+ * - Joint
+ * - inertia: of the rigid body part of the Segment
+ * - Offset from the end of the joint to the tip of the segment:
+ * the joint is located at the root of the segment.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Segment {
+ friend class Chain;
+ private:
+ Joint joint;
+ Inertia M;
+ Frame f_tip;
+
+ public:
+ /**
+ * Constructor of the segment
+ *
+ * @param joint joint of the segment, default:
+ * Joint(Joint::None)
+ * @param f_tip frame from the end of the joint to the tip of
+ * the segment, default: Frame::Identity()
+ * @param M rigid body inertia of the segment, default: Inertia::Zero()
+ */
+ Segment(const Joint& joint=Joint(), const Frame& f_tip=Frame::Identity(),const Inertia& M = Inertia::Zero());
+ Segment(const Segment& in);
+ Segment& operator=(const Segment& arg);
+
+ virtual ~Segment();
+
+ /**
+ * Request the pose of the segment, given the joint position q.
+ *
+ * @param q 1D position of the joint
+ *
+ * @return pose from the root to the tip of the segment
+ */
+ Frame pose(const double& q)const;
+ /**
+ * Request the 6D-velocity of the tip of the segment, given
+ * the joint position q and the joint velocity qdot.
+ *
+ * @param q ND position of the joint
+ * @param qdot ND velocity of the joint
+ *
+ * @return 6D-velocity of the tip of the segment, expressed
+ *in the base-frame of the segment(root) and with the tip of
+ *the segment as reference point.
+ */
+ Twist twist(const double& q,const double& qdot, int dof=0)const;
+
+ /**
+ * Request the 6D-velocity at a given point p, relative to base frame of the segment
+ * givven the joint velocity qdot.
+ *
+ * @param p reference point
+ * @param qdot ND velocity of the joint
+ *
+ * @return 6D-velocity at a given point p, expressed
+ * in the base-frame of the segment(root)
+ */
+ Twist twist(const Vector& p, const double& qdot, int dof=0)const;
+
+ /**
+ * Request the 6D-velocity at a given frame origin, relative to base frame of the segment
+ * assuming the frame rotation is the rotation of the joint.
+ *
+ * @param f joint pose frame + reference point
+ * @param qdot ND velocity of the joint
+ *
+ * @return 6D-velocity at frame reference point, expressed
+ * in the base-frame of the segment(root)
+ */
+ Twist twist(const Frame& f, const double& qdot, int dof)const;
+
+ /**
+ * Request the joint of the segment
+ *
+ *
+ * @return const reference to the joint of the segment
+ */
+ const Joint& getJoint()const
+ {
+ return joint;
+ }
+ /**
+ * Request the inertia of the segment
+ *
+ *
+ * @return const reference to the inertia of the segment
+ */
+ const Inertia& getInertia()const
+ {
+ return M;
+ }
+
+ /**
+ * Request the pose from the joint end to the tip of the
+ *segment.
+ *
+ * @return const reference to the joint end - segment tip pose.
+ */
+ const Frame& getFrameToTip()const
+ {
+ return f_tip;
+ }
+
+ };
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/tree.cpp b/intern/itasc/kdl/tree.cpp
new file mode 100644
index 00000000000..f117e54959b
--- /dev/null
+++ b/intern/itasc/kdl/tree.cpp
@@ -0,0 +1,117 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "tree.hpp"
+#include <sstream>
+namespace KDL {
+using namespace std;
+
+Tree::Tree() :
+ nrOfJoints(0), nrOfSegments(0) {
+ segments.insert(make_pair("root", TreeElement::Root()));
+}
+
+Tree::Tree(const Tree& in) {
+ segments.clear();
+ nrOfSegments = 0;
+ nrOfJoints = 0;
+
+ segments.insert(make_pair("root", TreeElement::Root()));
+ this->addTree(in, "", "root");
+
+}
+
+Tree& Tree::operator=(const Tree& in) {
+ segments.clear();
+ nrOfSegments = 0;
+ nrOfJoints = 0;
+
+ segments.insert(make_pair("root", TreeElement::Root()));
+ this->addTree(in, "", "root");
+ return *this;
+}
+
+bool Tree::addSegment(const Segment& segment, const std::string& segment_name,
+ const std::string& hook_name) {
+ SegmentMap::iterator parent = segments.find(hook_name);
+ //check if parent exists
+ if (parent == segments.end())
+ return false;
+ pair<SegmentMap::iterator, bool> retval;
+ //insert new element
+ retval = segments.insert(make_pair(segment_name, TreeElement(segment,
+ parent, nrOfJoints)));
+ //check if insertion succeeded
+ if (!retval.second)
+ return false;
+ //add iterator to new element in parents children list
+ parent->second.children.push_back(retval.first);
+ //increase number of segments
+ nrOfSegments++;
+ //increase number of joints
+ nrOfJoints += segment.getJoint().getNDof();
+ return true;
+}
+
+bool Tree::addChain(const Chain& chain, const std::string& chain_name,
+ const std::string& hook_name) {
+ string parent_name = hook_name;
+ for (unsigned int i = 0; i < chain.getNrOfSegments(); i++) {
+ ostringstream segment_name;
+ segment_name << chain_name << "Segment" << i;
+ if (this->addSegment(chain.getSegment(i), segment_name.str(),
+ parent_name))
+ parent_name = segment_name.str();
+ else
+ return false;
+ }
+ return true;
+}
+
+bool Tree::addTree(const Tree& tree, const std::string& tree_name,
+ const std::string& hook_name) {
+ return this->addTreeRecursive(tree.getSegment("root"), tree_name, hook_name);
+}
+
+bool Tree::addTreeRecursive(SegmentMap::const_iterator root,
+ const std::string& tree_name, const std::string& hook_name) {
+ //get iterator for root-segment
+ SegmentMap::const_iterator child;
+ //try to add all of root's children
+ for (unsigned int i = 0; i < root->second.children.size(); i++) {
+ child = root->second.children[i];
+ //Try to add the child
+ if (this->addSegment(child->second.segment, tree_name + child->first,
+ hook_name)) {
+ //if child is added, add all the child's children
+ if (!(this->addTreeRecursive(child, tree_name, tree_name
+ + child->first)))
+ //if it didn't work, return false
+ return false;
+ } else
+ //If the child could not be added, return false
+ return false;
+ }
+ return true;
+}
+
+}
+
diff --git a/intern/itasc/kdl/tree.hpp b/intern/itasc/kdl/tree.hpp
new file mode 100644
index 00000000000..bdd3aa94572
--- /dev/null
+++ b/intern/itasc/kdl/tree.hpp
@@ -0,0 +1,167 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_TREE_HPP
+#define KDL_TREE_HPP
+
+#include "segment.hpp"
+#include "chain.hpp"
+
+#include <string>
+#include <map>
+
+namespace KDL
+{
+ //Forward declaration
+ class TreeElement;
+ typedef std::map<std::string,TreeElement> SegmentMap;
+
+ class TreeElement
+ {
+ private:
+ TreeElement():q_nr(0)
+ {};
+ public:
+ Segment segment;
+ unsigned int q_nr;
+ SegmentMap::const_iterator parent;
+ std::vector<SegmentMap::const_iterator > children;
+ TreeElement(const Segment& segment_in,const SegmentMap::const_iterator& parent_in,unsigned int q_nr_in)
+ {
+ q_nr=q_nr_in;
+ segment=segment_in;
+ parent=parent_in;
+ };
+ static TreeElement Root()
+ {
+ return TreeElement();
+ };
+ };
+
+ /**
+ * \brief This class encapsulates a <strong>tree</strong>
+ * kinematic interconnection structure. It is build out of segments.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Tree
+ {
+ private:
+ SegmentMap segments;
+ unsigned int nrOfJoints;
+ unsigned int nrOfSegments;
+
+ bool addTreeRecursive(SegmentMap::const_iterator root, const std::string& tree_name, const std::string& hook_name);
+
+ public:
+ /**
+ * The constructor of a tree, a new tree is always empty
+ */
+ Tree();
+ Tree(const Tree& in);
+ Tree& operator= (const Tree& arg);
+
+ /**
+ * Adds a new segment to the end of the segment with
+ * hook_name as segment_name
+ *
+ * @param segment new segment to add
+ * @param segment_name name of the new segment
+ * @param hook_name name of the segment to connect this
+ * segment with.
+ *
+ * @return false if hook_name could not be found.
+ */
+ bool addSegment(const Segment& segment, const std::string& segment_name, const std::string& hook_name);
+
+ /**
+ * Adds a complete chain to the end of the segment with
+ * hook_name as segment_name. Segment i of
+ * the chain will get chain_name+".Segment"+i as segment_name.
+ *
+ * @param chain Chain to add
+ * @param chain_name name of the chain
+ * @param hook_name name of the segment to connect the chain with.
+ *
+ * @return false if hook_name could not be found.
+ */
+ bool addChain(const Chain& chain, const std::string& chain_name, const std::string& hook_name);
+
+ /**
+ * Adds a complete tree to the end of the segment with
+ * hookname as segment_name. The segments of the tree will get
+ * tree_name+segment_name as segment_name.
+ *
+ * @param tree Tree to add
+ * @param tree_name name of the tree
+ * @param hook_name name of the segment to connect the tree with
+ *
+ * @return false if hook_name could not be found
+ */
+ bool addTree(const Tree& tree, const std::string& tree_name,const std::string& hook_name);
+
+ /**
+ * Request the total number of joints in the tree.\n
+ * <strong> Important:</strong> It is not the same as the
+ * total number of segments since a segment does not need to have
+ * a joint.
+ *
+ * @return total nr of joints
+ */
+ unsigned int getNrOfJoints()const
+ {
+ return nrOfJoints;
+ };
+
+ /**
+ * Request the total number of segments in the tree.
+ * @return total number of segments
+ */
+ unsigned int getNrOfSegments()const {return nrOfSegments;};
+
+ /**
+ * Request the segment of the tree with name segment_name.
+ *
+ * @param segment_name the name of the requested segment
+ *
+ * @return constant iterator pointing to the requested segment
+ */
+ SegmentMap::const_iterator getSegment(const std::string& segment_name)const
+ {
+ return segments.find(segment_name);
+ };
+
+
+
+ const SegmentMap& getSegments()const
+ {
+ return segments;
+ }
+
+ virtual ~Tree(){};
+ };
+}
+#endif
+
+
+
+
+
diff --git a/intern/itasc/kdl/treefksolver.hpp b/intern/itasc/kdl/treefksolver.hpp
new file mode 100644
index 00000000000..22d5400ab0a
--- /dev/null
+++ b/intern/itasc/kdl/treefksolver.hpp
@@ -0,0 +1,110 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Copyright (C) 2008 Julia Jesse
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_TREE_FKSOLVER_HPP
+#define KDL_TREE_FKSOLVER_HPP
+
+#include <string>
+
+#include "tree.hpp"
+//#include "framevel.hpp"
+//#include "frameacc.hpp"
+#include "jntarray.hpp"
+//#include "jntarrayvel.hpp"
+//#include "jntarrayacc.hpp"
+
+namespace KDL {
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a
+ * solver for the forward position kinematics for a KDL::Tree.
+ *
+ * @ingroup KinematicFamily
+ */
+
+ //Forward definition
+ class TreeFkSolverPos {
+ public:
+ /**
+ * Calculate forward position kinematics for a KDL::Tree,
+ * from joint coordinates to cartesian pose.
+ *
+ * @param q_in input joint coordinates
+ * @param p_out reference to output cartesian pose
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out, const std::string& segmentName, const std::string& baseName)=0;
+ virtual ~TreeFkSolverPos(){};
+ };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward velocity kinematics for a KDL::Tree.
+ *
+ * @ingroup KinematicFamily
+ */
+// class TreeFkSolverVel {
+// public:
+ /**
+ * Calculate forward position and velocity kinematics, from
+ * joint coordinates to cartesian coordinates.
+ *
+ * @param q_in input joint coordinates (position and velocity)
+ * @param out output cartesian coordinates (position and velocity)
+ *
+ * @return if < 0 something went wrong
+ */
+// virtual int JntToCart(const JntArrayVel& q_in, FrameVel& out,int segmentNr=-1)=0;
+
+// virtual ~TreeFkSolverVel(){};
+// };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward acceleration kinematics for a KDL::Tree.
+ *
+ * @ingroup KinematicFamily
+ */
+
+// class TreeFkSolverAcc {
+// public:
+ /**
+ * Calculate forward position, velocity and accelaration
+ * kinematics, from joint coordinates to cartesian coordinates
+ *
+ * @param q_in input joint coordinates (position, velocity and
+ * acceleration
+ @param out output cartesian coordinates (position, velocity
+ * and acceleration
+ *
+ * @return if < 0 something went wrong
+ */
+// virtual int JntToCart(const JntArrayAcc& q_in, FrameAcc& out,int segmentNr=-1)=0;
+
+// virtual ~TreeFkSolverAcc()=0;
+// };
+
+
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/treefksolverpos_recursive.cpp b/intern/itasc/kdl/treefksolverpos_recursive.cpp
new file mode 100644
index 00000000000..f9dcb336d5d
--- /dev/null
+++ b/intern/itasc/kdl/treefksolverpos_recursive.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Copyright (C) 2008 Julia Jesse
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "treefksolverpos_recursive.hpp"
+#include <iostream>
+
+namespace KDL {
+
+ TreeFkSolverPos_recursive::TreeFkSolverPos_recursive(const Tree& _tree):
+ tree(_tree)
+ {
+ }
+
+ int TreeFkSolverPos_recursive::JntToCart(const JntArray& q_in, Frame& p_out, const std::string& segmentName, const std::string& baseName)
+ {
+ SegmentMap::const_iterator it = tree.getSegment(segmentName);
+ SegmentMap::const_iterator baseit = tree.getSegment(baseName);
+
+ if(q_in.rows() != tree.getNrOfJoints())
+ return -1;
+ else if(it == tree.getSegments().end()) //if the segment name is not found
+ return -2;
+ else if(baseit == tree.getSegments().end()) //if the base segment name is not found
+ return -3;
+ else{
+ p_out = recursiveFk(q_in, it, baseit);
+ return 0;
+ }
+ }
+
+ Frame TreeFkSolverPos_recursive::recursiveFk(const JntArray& q_in, const SegmentMap::const_iterator& it, const SegmentMap::const_iterator& baseit)
+ {
+ //gets the frame for the current element (segment)
+ const TreeElement& currentElement = it->second;
+
+ if(it == baseit){
+ return KDL::Frame::Identity();
+ }
+ else{
+ Frame currentFrame = currentElement.segment.pose(((JntArray&)q_in)(currentElement.q_nr));
+ SegmentMap::const_iterator parentIt = currentElement.parent;
+ return recursiveFk(q_in, parentIt, baseit) * currentFrame;
+ }
+ }
+
+ TreeFkSolverPos_recursive::~TreeFkSolverPos_recursive()
+ {
+ }
+
+
+}
diff --git a/intern/itasc/kdl/treefksolverpos_recursive.hpp b/intern/itasc/kdl/treefksolverpos_recursive.hpp
new file mode 100644
index 00000000000..c22fe4af75b
--- /dev/null
+++ b/intern/itasc/kdl/treefksolverpos_recursive.hpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Copyright (C) 2008 Julia Jesse
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDLTREEFKSOLVERPOS_RECURSIVE_HPP
+#define KDLTREEFKSOLVERPOS_RECURSIVE_HPP
+
+#include "treefksolver.hpp"
+
+namespace KDL {
+
+ /**
+ * Implementation of a recursive forward position kinematics
+ * algorithm to calculate the position transformation from joint
+ * space to Cartesian space of a general kinematic tree (KDL::Tree).
+ *
+ * @ingroup KinematicFamily
+ */
+ class TreeFkSolverPos_recursive : public TreeFkSolverPos
+ {
+ public:
+ TreeFkSolverPos_recursive(const Tree& tree);
+ ~TreeFkSolverPos_recursive();
+
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out, const std::string& segmentName, const std::string& baseName);
+
+ private:
+ const Tree tree;
+
+ Frame recursiveFk(const JntArray& q_in, const SegmentMap::const_iterator& it, const SegmentMap::const_iterator& baseit);
+ };
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/treejnttojacsolver.cpp b/intern/itasc/kdl/treejnttojacsolver.cpp
new file mode 100644
index 00000000000..194f18eb959
--- /dev/null
+++ b/intern/itasc/kdl/treejnttojacsolver.cpp
@@ -0,0 +1,78 @@
+/*
+ * TreeJntToJacSolver.cpp
+ *
+ * Created on: Nov 27, 2008
+ * Author: rubensmits
+ */
+
+#include "treejnttojacsolver.hpp"
+#include <iostream>
+
+namespace KDL {
+
+TreeJntToJacSolver::TreeJntToJacSolver(const Tree& tree_in) :
+ tree(tree_in) {
+}
+
+TreeJntToJacSolver::~TreeJntToJacSolver() {
+}
+
+int TreeJntToJacSolver::JntToJac(const JntArray& q_in, Jacobian& jac,
+ const std::string& segmentname) {
+ //First we check all the sizes:
+ if (q_in.rows() != tree.getNrOfJoints() || jac.columns()
+ != tree.getNrOfJoints())
+ return -1;
+
+ //Lets search the tree-element
+ SegmentMap::const_iterator it = tree.getSegments().find(segmentname);
+
+ //If segmentname is not inside the tree, back out:
+ if (it == tree.getSegments().end())
+ return -2;
+
+ //Let's make the jacobian zero:
+ SetToZero(jac);
+
+ SegmentMap::const_iterator root = tree.getSegments().find("root");
+
+ Frame T_total = Frame::Identity();
+ Frame T_local, T_joint;
+ Twist t_local;
+ //Lets recursively iterate until we are in the root segment
+ while (it != root) {
+ //get the corresponding q_nr for this TreeElement:
+ unsigned int q_nr = it->second.q_nr;
+
+ //get the pose of the joint.
+ T_joint = it->second.segment.getJoint().pose(((JntArray&)q_in)(q_nr));
+ // combine with the tip to have the tip pose
+ T_local = T_joint*it->second.segment.getFrameToTip();
+ //calculate new T_end:
+ T_total = T_local * T_total;
+
+ //get the twist of the segment:
+ int ndof = it->second.segment.getJoint().getNDof();
+ for (int dof=0; dof<ndof; dof++) {
+ // combine joint rotation with tip position to get a reference frame for the joint
+ T_joint.p = T_local.p;
+ // in which the twist can be computed (needed for NDof joint)
+ t_local = it->second.segment.twist(T_joint, 1.0, dof);
+ //transform the endpoint of the local twist to the global endpoint:
+ t_local = t_local.RefPoint(T_total.p - T_local.p);
+ //transform the base of the twist to the endpoint
+ t_local = T_total.M.Inverse(t_local);
+ //store the twist in the jacobian:
+ jac.twists[q_nr+dof] = t_local;
+ }
+ //goto the parent
+ it = it->second.parent;
+ }//endwhile
+ //Change the base of the complete jacobian from the endpoint to the base
+ changeBase(jac, T_total.M, jac);
+
+ return 0;
+
+}//end JntToJac
+}//end namespace
+
diff --git a/intern/itasc/kdl/treejnttojacsolver.hpp b/intern/itasc/kdl/treejnttojacsolver.hpp
new file mode 100644
index 00000000000..40977dcd577
--- /dev/null
+++ b/intern/itasc/kdl/treejnttojacsolver.hpp
@@ -0,0 +1,38 @@
+/*
+ * TreeJntToJacSolver.hpp
+ *
+ * Created on: Nov 27, 2008
+ * Author: rubensmits
+ */
+
+#ifndef TREEJNTTOJACSOLVER_HPP_
+#define TREEJNTTOJACSOLVER_HPP_
+
+#include "tree.hpp"
+#include "jacobian.hpp"
+#include "jntarray.hpp"
+
+namespace KDL {
+
+class TreeJntToJacSolver {
+public:
+ TreeJntToJacSolver(const Tree& tree);
+
+ virtual ~TreeJntToJacSolver();
+
+ /*
+ * Calculate the jacobian for a part of the tree: from a certain segment, given by segmentname to the root.
+ * The resulting jacobian is expressed in the baseframe of the tree ("root"), the reference point is in the end-segment
+ */
+
+ int JntToJac(const JntArray& q_in, Jacobian& jac,
+ const std::string& segmentname);
+
+private:
+ KDL::Tree tree;
+
+};
+
+}//End of namespace
+
+#endif /* TREEJNTTOJACSOLVER_H_ */
diff --git a/intern/itasc/kdl/utilities/Makefile b/intern/itasc/kdl/utilities/Makefile
new file mode 100644
index 00000000000..8ee08089e10
--- /dev/null
+++ b/intern/itasc/kdl/utilities/Makefile
@@ -0,0 +1,40 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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): Hans Lambermont
+#
+# ***** END GPL LICENSE BLOCK *****
+# iksolver main makefile.
+#
+
+include nan_definitions.mk
+
+LIBNAME = itasc_kdl_util
+# Same dir than parent (itasc instead of $(LIBNAME))
+DIR = $(OCGDIR)/intern/itasc
+
+include nan_compile.mk
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../../../../extern/Eigen2
diff --git a/intern/itasc/kdl/utilities/error.h b/intern/itasc/kdl/utilities/error.h
new file mode 100644
index 00000000000..868daef3db3
--- /dev/null
+++ b/intern/itasc/kdl/utilities/error.h
@@ -0,0 +1,245 @@
+/***************************************************************************
+ tag: Erwin Aertbelien Mon Jan 10 16:38:38 CET 2005 error.h
+
+ error.h - description
+ -------------------
+ begin : Mon January 10 2005
+ copyright : (C) 2005 Erwin Aertbelien
+ email : erwin.aertbelien@mech.kuleuven.ac.be
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+
+/*****************************************************************************
+ * \file
+ * Defines the exception classes that can be thrown
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ ****************************************************************************/
+#ifndef ERROR_H_84822 // to make it unique, a random number
+#define ERROR_H_84822
+
+#include "utility.h"
+#include <string>
+
+namespace KDL {
+
+/**
+ * Base class for errors generated by ORO_Geometry
+ */
+class Error {
+public:
+ /** Returns a description string describing the error.
+ * the returned pointer only garanteed to exists as long as
+ * the Error object exists.
+ */
+ virtual ~Error() {}
+ virtual const char* Description() const {return "Unspecified Error\n";}
+
+ virtual int GetType() const {return 0;}
+};
+
+
+class Error_IO : public Error {
+ std::string msg;
+ int typenr;
+public:
+ Error_IO(const std::string& _msg="Unspecified I/O Error",int typenr=0):msg(_msg) {}
+ virtual const char* Description() const {return msg.c_str();}
+ virtual int GetType() const {return typenr;}
+};
+class Error_BasicIO : public Error_IO {};
+class Error_BasicIO_File : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Error while reading stream";}
+ virtual int GetType() const {return 1;}
+};
+class Error_BasicIO_Exp_Delim : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Expected Delimiter not encountered";}
+ virtual int GetType() const {return 2;}
+};
+class Error_BasicIO_Not_A_Space : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Expected space,tab or newline not encountered";}
+ virtual int GetType() const {return 3;}
+};
+class Error_BasicIO_Unexpected : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Unexpected character";}
+ virtual int GetType() const {return 4;}
+};
+
+class Error_BasicIO_ToBig : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Word that is read out of stream is bigger than maxsize";}
+ virtual int GetType() const {return 5;}
+};
+
+class Error_BasicIO_Not_Opened : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "File cannot be opened";}
+ virtual int GetType() const {return 6;}
+};
+class Error_FrameIO : public Error_IO {};
+class Error_Frame_Vector_Unexpected_id : public Error_FrameIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting a vector (explicit or ZERO)";}
+ virtual int GetType() const {return 101;}
+};
+class Error_Frame_Frame_Unexpected_id : public Error_FrameIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting a Frame (explicit or DH)";}
+ virtual int GetType() const {return 102;}
+};
+class Error_Frame_Rotation_Unexpected_id : public Error_FrameIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting a Rotation (explicit or EULERZYX, EULERZYZ, RPY,ROT,IDENTITY)";}
+ virtual int GetType() const {return 103;}
+};
+class Error_ChainIO : public Error {};
+class Error_Chain_Unexpected_id : public Error_ChainIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting TRANS or ROT";}
+ virtual int GetType() const {return 201;}
+};
+//! Error_Redundancy indicates an error that occured during solving for redundancy.
+class Error_RedundancyIO:public Error_IO {};
+class Error_Redundancy_Illegal_Resolutiontype : public Error_RedundancyIO {
+public:
+ virtual const char* Description() const {return "Illegal Resolutiontype is used in I/O with ResolutionTask";}
+ virtual int GetType() const {return 301;}
+};
+class Error_Redundancy:public Error {};
+class Error_Redundancy_Unavoidable : public Error_Redundancy {
+public:
+ virtual const char* Description() const {return "Joint limits cannot be avoided";}
+ virtual int GetType() const {return 1002;}
+};
+class Error_Redundancy_Low_Manip: public Error_Redundancy {
+public:
+ virtual const char* Description() const {return "Manipulability is very low";}
+ virtual int GetType() const {return 1003;}
+};
+class Error_MotionIO : public Error {};
+class Error_MotionIO_Unexpected_MotProf : public Error_MotionIO {
+public:
+ virtual const char* Description() const { return "Wrong keyword while reading motion profile";}
+ virtual int GetType() const {return 2001;}
+};
+class Error_MotionIO_Unexpected_Traj : public Error_MotionIO {
+public:
+ virtual const char* Description() const { return "Trajectory type keyword not known";}
+ virtual int GetType() const {return 2002;}
+};
+
+class Error_MotionPlanning : public Error {};
+
+class Error_MotionPlanning_Circle_ToSmall : public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Circle : radius is to small";}
+ virtual int GetType() const {return 3001;}
+};
+
+class Error_MotionPlanning_Circle_No_Plane : public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Circle : Plane for motion is not properly defined";}
+ virtual int GetType() const {return 3002;}
+};
+
+class Error_MotionPlanning_Incompatible: public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Acceleration of a rectangular velocityprofile cannot be used";}
+ virtual int GetType() const {return 3003;}
+};
+
+class Error_MotionPlanning_Not_Feasible: public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Motion Profile with requested parameters is not feasible";}
+ virtual int GetType() const {return 3004;}
+};
+
+class Error_MotionPlanning_Not_Applicable: public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Method is not applicable for this derived object";}
+ virtual int GetType() const {return 3004;}
+};
+//! Abstract subclass of all errors that can be thrown by Adaptive_Integrator
+class Error_Integrator : public Error {};
+
+//! Error_Stepsize_Underflow is thrown if the stepsize becomes to small
+class Error_Stepsize_Underflow : public Error_Integrator {
+public:
+ virtual const char* Description() const { return "Stepsize Underflow";}
+ virtual int GetType() const {return 4001;}
+};
+
+//! Error_To_Many_Steps is thrown if the number of steps needed to
+//! integrate to the desired accuracy becomes to big.
+class Error_To_Many_Steps : public Error_Integrator {
+public:
+ virtual const char* Description() const { return "To many steps"; }
+ virtual int GetType() const {return 4002;}
+};
+
+//! Error_Stepsize_To_Small is thrown if the stepsize becomes to small
+class Error_Stepsize_To_Small : public Error_Integrator {
+public:
+ virtual const char* Description() const { return "Stepsize to small"; }
+ virtual int GetType() const {return 4003;}
+};
+
+class Error_Criterium : public Error {};
+
+class Error_Criterium_Unexpected_id: public Error_Criterium {
+public:
+ virtual const char* Description() const { return "Unexpected identifier while reading a criterium"; }
+ virtual int GetType() const {return 5001;}
+};
+
+class Error_Limits : public Error {};
+
+class Error_Limits_Unexpected_id: public Error_Limits {
+public:
+ virtual const char* Description() const { return "Unexpected identifier while reading a jointlimits"; }
+ virtual int GetType() const {return 6001;}
+};
+
+
+class Error_Not_Implemented: public Error {
+public:
+ virtual const char* Description() const { return "The requested object/method/function is not implemented"; }
+ virtual int GetType() const {return 7000;}
+};
+
+
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/utilities/error_stack.cpp b/intern/itasc/kdl/utilities/error_stack.cpp
new file mode 100644
index 00000000000..d55308c7346
--- /dev/null
+++ b/intern/itasc/kdl/utilities/error_stack.cpp
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ ****************************************************************************/
+
+
+#include "error_stack.h"
+#include <stack>
+#include <vector>
+#include <string>
+#include <cstring>
+
+namespace KDL {
+
+// Trace of the call stack of the I/O routines to help user
+// interprete error messages from I/O
+typedef std::stack<std::string> ErrorStack;
+
+ErrorStack errorstack;
+// should be in Thread Local Storage if this gets multithreaded one day...
+
+
+void IOTrace(const std::string& description) {
+ errorstack.push(description);
+}
+
+
+void IOTracePop() {
+ errorstack.pop();
+}
+
+void IOTraceOutput(std::ostream& os) {
+ while (!errorstack.empty()) {
+ os << errorstack.top().c_str() << std::endl;
+ errorstack.pop();
+ }
+}
+
+
+void IOTracePopStr(char* buffer,int size) {
+ if (errorstack.empty()) {
+ *buffer = 0;
+ return;
+ }
+ strncpy(buffer,errorstack.top().c_str(),size);
+ errorstack.pop();
+}
+
+}
diff --git a/intern/itasc/kdl/utilities/error_stack.h b/intern/itasc/kdl/utilities/error_stack.h
new file mode 100644
index 00000000000..918bc0786a6
--- /dev/null
+++ b/intern/itasc/kdl/utilities/error_stack.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ tag: Erwin Aertbelien Mon Jan 10 16:38:39 CET 2005 error_stack.h
+
+ error_stack.h - description
+ -------------------
+ begin : Mon January 10 2005
+ copyright : (C) 2005 Erwin Aertbelien
+ email : erwin.aertbelien@mech.kuleuven.ac.be
+
+ ***************************************************************************
+ * This library 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that 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 this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+
+/**
+ * \file
+ * \author Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par history
+ * - changed layout of the comments to accomodate doxygen
+ */
+#ifndef ERROR_STACK_H
+#define ERROR_STACK_H
+
+#include "utility.h"
+#include "utility_io.h"
+#include <string>
+
+
+namespace KDL {
+
+/*
+ * \todo
+ * IOTrace-routines store in static memory, should be in thread-local memory.
+ * pushes a description of the current routine on the IO-stack trace
+ */
+void IOTrace(const std::string& description);
+
+//! pops a description of the IO-stack
+void IOTracePop();
+
+
+//! outputs the IO-stack to a stream to provide a better errormessage.
+void IOTraceOutput(std::ostream& os);
+
+//! outputs one element of the IO-stack to the buffer (maximally size chars)
+//! returns empty string if no elements on the stack.
+void IOTracePopStr(char* buffer,int size);
+
+
+}
+
+#endif
+
diff --git a/intern/itasc/kdl/utilities/kdl-config.h b/intern/itasc/kdl/utilities/kdl-config.h
new file mode 100644
index 00000000000..4d2df2df6c5
--- /dev/null
+++ b/intern/itasc/kdl/utilities/kdl-config.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be> */
+
+/* Version: 1.0 */
+/* Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be> */
+/* Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be> */
+/* URL: http://www.orocos.org/kdl */
+
+/* This library 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 2.1 of the License, or (at your option) any later version. */
+
+/* This library is distributed in the hope that 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 this library; if not, write to the Free Software */
+/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+
+/* Methods are inlined */
+#define KDL_INLINE 1
+
+/* Column width that is used form printing frames */
+#define KDL_FRAME_WIDTH 12
+
+/* Indices are checked when accessing members of the objects */
+#define KDL_INDEX_CHECK 1
+
+/* use KDL implementation for == operator */
+#define KDL_USE_EQUAL 1
diff --git a/intern/itasc/kdl/utilities/rall1d.h b/intern/itasc/kdl/utilities/rall1d.h
new file mode 100644
index 00000000000..98bd4385d1e
--- /dev/null
+++ b/intern/itasc/kdl/utilities/rall1d.h
@@ -0,0 +1,478 @@
+
+/*****************************************************************************
+ * \file
+ * class for automatic differentiation on scalar values and 1st
+ * derivatives .
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par Note
+ * VC6++ contains a bug, concerning the use of inlined friend functions
+ * in combination with namespaces. So, try to avoid inlined friend
+ * functions !
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef Rall1D_H
+#define Rall1D_H
+#include <assert.h>
+#include "utility.h"
+
+namespace KDL {
+/**
+ * Rall1d contains a value, and its gradient, and defines an algebraic structure on this pair.
+ * This template class has 3 template parameters :
+ * - T contains the type of the value.
+ * - V contains the type of the gradient (can be a vector-like type).
+ * - S defines a scalar type that can operate on Rall1d. This is the type that
+ * is used to give back values of Norm() etc.
+ *
+ * S is usefull when you recurse a Rall1d object into itself to create a 2nd, 3th, 4th,..
+ * derivatives. (e.g. Rall1d< Rall1d<double>, Rall1d<double>, double> ).
+ *
+ * S is always passed by value.
+ *
+ * \par Class Type
+ * Concrete implementation
+ */
+template <typename T,typename V=T,typename S=T>
+class Rall1d
+ {
+ public:
+ typedef T valuetype;
+ typedef V gradienttype;
+ typedef S scalartype;
+ public :
+ T t; //!< value
+ V grad; //!< gradient
+ public :
+ INLINE Rall1d() {}
+
+ T value() const {
+ return t;
+ }
+ V deriv() const {
+ return grad;
+ }
+
+ explicit INLINE Rall1d(typename TI<T>::Arg c)
+ {t=T(c);SetToZero(grad);}
+
+ INLINE Rall1d(typename TI<T>::Arg tn, typename TI<V>::Arg afg):t(tn),grad(afg) {}
+
+ INLINE Rall1d(const Rall1d<T,V,S>& r):t(r.t),grad(r.grad) {}
+ //if one defines this constructor, it's better optimized then the
+ //automatically generated one ( this one set's up a loop to copy
+ // word by word.
+
+ INLINE T& Value() {
+ return t;
+ }
+
+ INLINE V& Gradient() {
+ return grad;
+ }
+
+ INLINE static Rall1d<T,V,S> Zero() {
+ Rall1d<T,V,S> tmp;
+ SetToZero(tmp);
+ return tmp;
+ }
+ INLINE static Rall1d<T,V,S> Identity() {
+ Rall1d<T,V,S> tmp;
+ SetToIdentity(tmp);
+ return tmp;
+ }
+
+ INLINE Rall1d<T,V,S>& operator =(S c)
+ {t=c;SetToZero(grad);return *this;}
+
+ INLINE Rall1d<T,V,S>& operator =(const Rall1d<T,V,S>& r)
+ {t=r.t;grad=r.grad;return *this;}
+
+ INLINE Rall1d<T,V,S>& operator /=(const Rall1d<T,V,S>& rhs)
+ {
+ grad = LinComb(rhs.t,grad,-t,rhs.grad) / (rhs.t*rhs.t);
+ t /= rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator *=(const Rall1d<T,V,S>& rhs)
+ {
+ LinCombR(rhs.t,grad,t,rhs.grad,grad);
+ t *= rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator +=(const Rall1d<T,V,S>& rhs)
+ {
+ grad +=rhs.grad;
+ t +=rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator -=(const Rall1d<T,V,S>& rhs)
+ {
+ grad -= rhs.grad;
+ t -= rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator /=(S rhs)
+ {
+ grad /= rhs;
+ t /= rhs;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator *=(S rhs)
+ {
+ grad *= rhs;
+ t *= rhs;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator +=(S rhs)
+ {
+ t += rhs;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator -=(S rhs)
+ {
+ t -= rhs;
+ return *this;
+ }
+
+
+
+ // = operators
+ /* gives warnings on cygwin
+
+ template <class T2,class V2,class S2>
+ friend INLINE Rall1d<T2,V2,S2> operator /(const Rall1d<T2,V2,S2>& lhs,const Rall1d<T2,V2,S2>& rhs);
+
+ friend INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs);
+ friend INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs);
+ friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs);
+ friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> operator *(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& v,S s);
+ friend INLINE Rall1d<T,V,S> operator +(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& v,S s);
+ friend INLINE Rall1d<T,V,S> operator -(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& v,S s);
+ friend INLINE Rall1d<T,V,S> operator /(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& v,S s);
+
+ // = Mathematical functions that operate on Rall1d objects
+ friend INLINE Rall1d<T,V,S> exp(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> log(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> sin(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> cos(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> tan(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> sinh(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> cosh(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> sqr(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> pow(const Rall1d<T,V,S>& arg,double m) ;
+ friend INLINE Rall1d<T,V,S> sqrt(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> atan(const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> hypot(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> asin(const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> acos(const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> abs(const Rall1d<T,V,S>& x);
+ friend INLINE S Norm(const Rall1d<T,V,S>& value) ;
+ friend INLINE Rall1d<T,V,S> tanh(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> atan2(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x);
+
+ // = Utility functions to improve performance
+
+ friend INLINE Rall1d<T,V,S> LinComb(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b );
+
+ friend INLINE void LinCombR(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b,Rall1d<T,V,S>& result );
+
+ // = Setting value of a Rall1d object to 0 or 1
+
+ friend INLINE void SetToZero(Rall1d<T,V,S>& value);
+ friend INLINE void SetToOne(Rall1d<T,V,S>& value);
+ // = Equality in an eps-interval
+ friend INLINE bool Equal(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x,double eps);
+ */
+ };
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t/rhs.t,(lhs.grad*rhs.t-lhs.t*rhs.grad)/(rhs.t*rhs.t));
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t*rhs.t,rhs.t*lhs.grad+lhs.t*rhs.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t+rhs.t,lhs.grad+rhs.grad);
+ }
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t-rhs.t,lhs.grad-rhs.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& arg)
+ {
+ return Rall1d<T,V,S>(-arg.t,-arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator *(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s*v.t,s*v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t*s,v.grad*s);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator +(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s+v.t,v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t+s,v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s-v.t,-v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t-s,v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator /(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s/v.t,(-s*v.grad)/(v.t*v.t));
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t/s,v.grad/s);
+ }
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> exp(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v= (exp(arg.t));
+ return Rall1d<T,V,S>(v,v*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> log(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(log(arg.t));
+ return Rall1d<T,V,S>(v,arg.grad/arg.t);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sin(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(sin(arg.t));
+ return Rall1d<T,V,S>(v,cos(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> cos(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(cos(arg.t));
+ return Rall1d<T,V,S>(v,-sin(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> tan(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(tan(arg.t));
+ return Rall1d<T,V,S>(v,arg.grad/sqr(cos(arg.t)));
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sinh(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(sinh(arg.t));
+ return Rall1d<T,V,S>(v,cosh(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> cosh(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(cosh(arg.t));
+ return Rall1d<T,V,S>(v,sinh(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sqr(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(arg.t*arg.t);
+ return Rall1d<T,V,S>(v,(2.0*arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> pow(const Rall1d<T,V,S>& arg,double m)
+ {
+ T v;
+ v=(pow(arg.t,m));
+ return Rall1d<T,V,S>(v,(m*v/arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sqrt(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=sqrt(arg.t);
+ return Rall1d<T,V,S>(v, (0.5/v)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> atan(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(atan(x.t));
+ return Rall1d<T,V,S>(v,x.grad/(1.0+sqr(x.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> hypot(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(hypot(y.t,x.t));
+ return Rall1d<T,V,S>(v,(x.t/v)*x.grad+(y.t/v)*y.grad);
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> asin(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(asin(x.t));
+ return Rall1d<T,V,S>(v,x.grad/sqrt(1.0-sqr(x.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> acos(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(acos(x.t));
+ return Rall1d<T,V,S>(v,-x.grad/sqrt(1.0-sqr(x.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> abs(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(Sign(x));
+ return Rall1d<T,V,S>(v*x,v*x.grad);
+}
+
+
+template <class T,class V,class S>
+INLINE S Norm(const Rall1d<T,V,S>& value)
+{
+ return Norm(value.t);
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> tanh(const Rall1d<T,V,S>& arg)
+{
+ T v(tanh(arg.t));
+ return Rall1d<T,V,S>(v,arg.grad/sqr(cosh(arg.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> atan2(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x)
+{
+ T v(x.t*x.t+y.t*y.t);
+ return Rall1d<T,V,S>(atan2(y.t,x.t),(x.t*y.grad-y.t*x.grad)/v);
+}
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> LinComb(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b ) {
+ return Rall1d<T,V,S>(
+ LinComb(alfa,a.t,beta,b.t),
+ LinComb(alfa,a.grad,beta,b.grad)
+ );
+}
+
+template <class T,class V,class S>
+INLINE void LinCombR(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b,Rall1d<T,V,S>& result ) {
+ LinCombR(alfa, a.t, beta, b.t, result.t);
+ LinCombR(alfa, a.grad, beta, b.grad, result.grad);
+}
+
+
+template <class T,class V,class S>
+INLINE void SetToZero(Rall1d<T,V,S>& value)
+ {
+ SetToZero(value.grad);
+ SetToZero(value.t);
+ }
+template <class T,class V,class S>
+INLINE void SetToIdentity(Rall1d<T,V,S>& value)
+ {
+ SetToIdentity(value.t);
+ SetToZero(value.grad);
+ }
+
+template <class T,class V,class S>
+INLINE bool Equal(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x,double eps=epsilon)
+{
+ return (Equal(x.t,y.t,eps)&&Equal(x.grad,y.grad,eps));
+}
+
+}
+
+
+
+#endif
diff --git a/intern/itasc/kdl/utilities/rall2d.h b/intern/itasc/kdl/utilities/rall2d.h
new file mode 100644
index 00000000000..cbd9e70b04f
--- /dev/null
+++ b/intern/itasc/kdl/utilities/rall2d.h
@@ -0,0 +1,538 @@
+
+/*****************************************************************************
+ * \file
+ * class for automatic differentiation on scalar values and 1st
+ * derivatives and 2nd derivative.
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par Note
+ * VC6++ contains a bug, concerning the use of inlined friend functions
+ * in combination with namespaces. So, try to avoid inlined friend
+ * functions !
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef Rall2D_H
+#define Rall2D_H
+
+#include <math.h>
+#include <assert.h>
+#include "utility.h"
+
+
+namespace KDL {
+
+/**
+ * Rall2d contains a value, and its gradient and its 2nd derivative, and defines an algebraic
+ * structure on this pair.
+ * This template class has 3 template parameters :
+ * - T contains the type of the value.
+ * - V contains the type of the gradient (can be a vector-like type).
+ * - S defines a scalar type that can operate on Rall1d. This is the type that
+ * is used to give back values of Norm() etc.
+ *
+ * S is usefull when you recurse a Rall1d object into itself to create a 2nd, 3th, 4th,..
+ * derivatives. (e.g. Rall1d< Rall1d<double>, Rall1d<double>, double> ).
+ *
+ * S is always passed by value.
+ *
+ * \par Class Type
+ * Concrete implementation
+ */
+template <class T,class V=T,class S=T>
+class Rall2d
+ {
+ public :
+ T t; //!< value
+ V d; //!< 1st derivative
+ V dd; //!< 2nd derivative
+ public :
+ // = Constructors
+ INLINE Rall2d() {}
+
+ explicit INLINE Rall2d(typename TI<T>::Arg c)
+ {t=c;SetToZero(d);SetToZero(dd);}
+
+ INLINE Rall2d(typename TI<T>::Arg tn,const V& afg):t(tn),d(afg) {SetToZero(dd);}
+
+ INLINE Rall2d(typename TI<T>::Arg tn,const V& afg,const V& afg2):t(tn),d(afg),dd(afg2) {}
+
+ // = Copy Constructor
+ INLINE Rall2d(const Rall2d<T,V,S>& r):t(r.t),d(r.d),dd(r.dd) {}
+ //if one defines this constructor, it's better optimized then the
+ //automatically generated one ( that one set's up a loop to copy
+ // word by word.
+
+ // = Member functions to access internal structures :
+ INLINE T& Value() {
+ return t;
+ }
+
+ INLINE V& D() {
+ return d;
+ }
+
+ INLINE V& DD() {
+ return dd;
+ }
+ INLINE static Rall2d<T,V,S> Zero() {
+ Rall2d<T,V,S> tmp;
+ SetToZero(tmp);
+ return tmp;
+ }
+ INLINE static Rall2d<T,V,S> Identity() {
+ Rall2d<T,V,S> tmp;
+ SetToIdentity(tmp);
+ return tmp;
+ }
+
+ // = assignment operators
+ INLINE Rall2d<T,V,S>& operator =(S c)
+ {t=c;SetToZero(d);SetToZero(dd);return *this;}
+
+ INLINE Rall2d<T,V,S>& operator =(const Rall2d<T,V,S>& r)
+ {t=r.t;d=r.d;dd=r.dd;return *this;}
+
+ INLINE Rall2d<T,V,S>& operator /=(const Rall2d<T,V,S>& rhs)
+ {
+ t /= rhs.t;
+ d = (d-t*rhs.d)/rhs.t;
+ dd= (dd - S(2)*d*rhs.d-t*rhs.dd)/rhs.t;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator *=(const Rall2d<T,V,S>& rhs)
+ {
+ t *= rhs.t;
+ d = (d*rhs.t+t*rhs.d);
+ dd = (dd*rhs.t+S(2)*d*rhs.d+t*rhs.dd);
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator +=(const Rall2d<T,V,S>& rhs)
+ {
+ t +=rhs.t;
+ d +=rhs.d;
+ dd+=rhs.dd;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator -=(const Rall2d<T,V,S>& rhs)
+ {
+ t -= rhs.t;
+ d -= rhs.d;
+ dd -= rhs.dd;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator /=(S rhs)
+ {
+ t /= rhs;
+ d /= rhs;
+ dd /= rhs;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator *=(S rhs)
+ {
+ t *= rhs;
+ d *= rhs;
+ dd *= rhs;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator -=(S rhs)
+ {
+ t -= rhs;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator +=(S rhs)
+ {
+ t += rhs;
+ return *this;
+ }
+
+ // = Operators between Rall2d objects
+/*
+ friend INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> operator *(S s,const Rall2d<T,V,S>& v);
+ friend INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& v,S s);
+ friend INLINE Rall2d<T,V,S> operator +(S s,const Rall2d<T,V,S>& v);
+ friend INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& v,S s);
+ friend INLINE Rall2d<T,V,S> operator -(S s,const Rall2d<T,V,S>& v);
+ friend INLINE INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& v,S s);
+ friend INLINE Rall2d<T,V,S> operator /(S s,const Rall2d<T,V,S>& v);
+ friend INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& v,S s);
+
+ // = Mathematical functions that operate on Rall2d objects
+
+ friend INLINE Rall2d<T,V,S> exp(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> log(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> sin(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> cos(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> tan(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> sinh(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> cosh(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> tanh(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> sqr(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> pow(const Rall2d<T,V,S>& arg,double m) ;
+ friend INLINE Rall2d<T,V,S> sqrt(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> asin(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> acos(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> atan(const Rall2d<T,V,S>& x);
+ friend INLINE Rall2d<T,V,S> atan2(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x);
+ friend INLINE Rall2d<T,V,S> abs(const Rall2d<T,V,S>& x);
+ friend INLINE Rall2d<T,V,S> hypot(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x);
+ // returns sqrt(y*y+x*x), but is optimized for accuracy and speed.
+ friend INLINE S Norm(const Rall2d<T,V,S>& value) ;
+ // returns Norm( value.Value() ).
+
+ // = Some utility functions to improve performance
+ // (should also be declared on primitive types to improve uniformity
+ friend INLINE Rall2d<T,V,S> LinComb(S alfa,const Rall2d<T,V,S>& a,
+ TI<T>::Arg beta,const Rall2d<T,V,S>& b );
+ friend INLINE void LinCombR(S alfa,const Rall2d<T,V,S>& a,
+ TI<T>::Arg beta,const Rall2d<T,V,S>& b,Rall2d<T,V,S>& result );
+ // = Setting value of a Rall2d object to 0 or 1
+ friend INLINE void SetToZero(Rall2d<T,V,S>& value);
+ friend INLINE void SetToOne(Rall2d<T,V,S>& value);
+ // = Equality in an eps-interval
+ friend INLINE bool Equal(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x,double eps);
+ */
+ };
+
+
+
+
+
+// = Operators between Rall2d objects
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = lhs.t/rhs.t;
+ tmp.d = (lhs.d-tmp.t*rhs.d)/rhs.t;
+ tmp.dd= (lhs.dd-S(2)*tmp.d*rhs.d-tmp.t*rhs.dd)/rhs.t;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = lhs.t*rhs.t;
+ tmp.d = (lhs.d*rhs.t+lhs.t*rhs.d);
+ tmp.dd = (lhs.dd*rhs.t+S(2)*lhs.d*rhs.d+lhs.t*rhs.dd);
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ return Rall2d<T,V,S>(lhs.t+rhs.t,lhs.d+rhs.d,lhs.dd+rhs.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ return Rall2d<T,V,S>(lhs.t-rhs.t,lhs.d-rhs.d,lhs.dd-rhs.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& arg)
+ {
+ return Rall2d<T,V,S>(-arg.t,-arg.d,-arg.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator *(S s,const Rall2d<T,V,S>& v)
+ {
+ return Rall2d<T,V,S>(s*v.t,s*v.d,s*v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t*s,v.d*s,v.dd*s);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator +(S s,const Rall2d<T,V,S>& v)
+ {
+ return Rall2d<T,V,S>(s+v.t,v.d,v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t+s,v.d,v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(S s,const Rall2d<T,V,S>& v)
+ {
+ return Rall2d<T,V,S>(s-v.t,-v.d,-v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t-s,v.d,v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator /(S s,const Rall2d<T,V,S>& rhs)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = s/rhs.t;
+ tmp.d = (-tmp.t*rhs.d)/rhs.t;
+ tmp.dd= (-S(2)*tmp.d*rhs.d-tmp.t*rhs.dd)/rhs.t;
+ return tmp;
+}
+
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t/s,v.d/s,v.dd/s);
+ }
+
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> exp(const Rall2d<T,V,S>& arg)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = exp(arg.t);
+ tmp.d = tmp.t*arg.d;
+ tmp.dd = tmp.d*arg.d+tmp.t*arg.dd;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> log(const Rall2d<T,V,S>& arg)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = log(arg.t);
+ tmp.d = arg.d/arg.t;
+ tmp.dd = (arg.dd-tmp.d*arg.d)/arg.t;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sin(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = sin(arg.t);
+ T v2 = cos(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d,v2*arg.dd - (v1*arg.d)*arg.d );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> cos(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = cos(arg.t);
+ T v2 = -sin(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d, v2*arg.dd - (v1*arg.d)*arg.d);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> tan(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = tan(arg.t);
+ T v2 = S(1)+sqr(v1);
+ return Rall2d<T,V,S>(v1,v2*arg.d, v2*(arg.dd+(S(2)*v1*sqr(arg.d))));
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sinh(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = sinh(arg.t);
+ T v2 = cosh(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d,v2*arg.dd + (v1*arg.d)*arg.d );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> cosh(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = cosh(arg.t);
+ T v2 = sinh(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d,v2*arg.dd + (v1*arg.d)*arg.d );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> tanh(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = tanh(arg.t);
+ T v2 = S(1)-sqr(v1);
+ return Rall2d<T,V,S>(v1,v2*arg.d, v2*(arg.dd-(S(2)*v1*sqr(arg.d))));
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sqr(const Rall2d<T,V,S>& arg)
+ {
+ return Rall2d<T,V,S>(arg.t*arg.t,
+ (S(2)*arg.t)*arg.d,
+ S(2)*(sqr(arg.d)+arg.t*arg.dd)
+ );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> pow(const Rall2d<T,V,S>& arg,double m)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = pow(arg.t,m);
+ T v2 = (m/arg.t)*tmp.t;
+ tmp.d = v2*arg.d;
+ tmp.dd = (S((m-1))/arg.t)*tmp.d*arg.d + v2*arg.dd;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sqrt(const Rall2d<T,V,S>& arg)
+ {
+ /* By inversion of sqr(x) :*/
+ Rall2d<T,V,S> tmp;
+ tmp.t = sqrt(arg.t);
+ tmp.d = (S(0.5)/tmp.t)*arg.d;
+ tmp.dd = (S(0.5)*arg.dd-sqr(tmp.d))/tmp.t;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> asin(const Rall2d<T,V,S>& arg)
+{
+ /* By inversion of sin(x) */
+ Rall2d<T,V,S> tmp;
+ tmp.t = asin(arg.t);
+ T v = cos(tmp.t);
+ tmp.d = arg.d/v;
+ tmp.dd = (arg.dd+arg.t*sqr(tmp.d))/v;
+ return tmp;
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> acos(const Rall2d<T,V,S>& arg)
+{
+ /* By inversion of cos(x) */
+ Rall2d<T,V,S> tmp;
+ tmp.t = acos(arg.t);
+ T v = -sin(tmp.t);
+ tmp.d = arg.d/v;
+ tmp.dd = (arg.dd+arg.t*sqr(tmp.d))/v;
+ return tmp;
+
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> atan(const Rall2d<T,V,S>& x)
+{
+ /* By inversion of tan(x) */
+ Rall2d<T,V,S> tmp;
+ tmp.t = atan(x.t);
+ T v = S(1)+sqr(x.t);
+ tmp.d = x.d/v;
+ tmp.dd = x.dd/v-(S(2)*x.t)*sqr(tmp.d);
+ return tmp;
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> atan2(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x)
+{
+ Rall2d<T,V,S> tmp;
+ tmp.t = atan2(y.t,x.t);
+ T v = sqr(y.t)+sqr(x.t);
+ tmp.d = (x.t*y.d-x.d*y.t)/v;
+ tmp.dd = ( x.t*y.dd-x.dd*y.t-S(2)*(x.t*x.d+y.t*y.d)*tmp.d ) / v;
+ return tmp;
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> abs(const Rall2d<T,V,S>& x)
+{
+ T v(Sign(x));
+ return Rall2d<T,V,S>(v*x,v*x.d,v*x.dd);
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> hypot(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x)
+{
+ Rall2d<T,V,S> tmp;
+ tmp.t = hypot(y.t,x.t);
+ tmp.d = (x.t*x.d+y.t*y.d)/tmp.t;
+ tmp.dd = (sqr(x.d)+x.t*x.dd+sqr(y.d)+y.t*y.dd-sqr(tmp.d))/tmp.t;
+ return tmp;
+}
+// returns sqrt(y*y+x*x), but is optimized for accuracy and speed.
+
+template <class T,class V,class S>
+INLINE S Norm(const Rall2d<T,V,S>& value)
+{
+ return Norm(value.t);
+}
+// returns Norm( value.Value() ).
+
+
+// (should also be declared on primitive types to improve uniformity
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> LinComb(S alfa,const Rall2d<T,V,S>& a,
+ const T& beta,const Rall2d<T,V,S>& b ) {
+ return Rall2d<T,V,S>(
+ LinComb(alfa,a.t,beta,b.t),
+ LinComb(alfa,a.d,beta,b.d),
+ LinComb(alfa,a.dd,beta,b.dd)
+ );
+}
+
+template <class T,class V,class S>
+INLINE void LinCombR(S alfa,const Rall2d<T,V,S>& a,
+ const T& beta,const Rall2d<T,V,S>& b,Rall2d<T,V,S>& result ) {
+ LinCombR(alfa, a.t, beta, b.t, result.t);
+ LinCombR(alfa, a.d, beta, b.d, result.d);
+ LinCombR(alfa, a.dd, beta, b.dd, result.dd);
+}
+
+template <class T,class V,class S>
+INLINE void SetToZero(Rall2d<T,V,S>& value)
+ {
+ SetToZero(value.t);
+ SetToZero(value.d);
+ SetToZero(value.dd);
+ }
+
+template <class T,class V,class S>
+INLINE void SetToIdentity(Rall2d<T,V,S>& value)
+ {
+ SetToZero(value.d);
+ SetToIdentity(value.t);
+ SetToZero(value.dd);
+ }
+
+template <class T,class V,class S>
+INLINE bool Equal(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x,double eps=epsilon)
+{
+ return (Equal(x.t,y.t,eps)&&
+ Equal(x.d,y.d,eps)&&
+ Equal(x.dd,y.dd,eps)
+ );
+}
+
+
+}
+
+
+#endif
diff --git a/intern/itasc/kdl/utilities/svd_eigen_HH.hpp b/intern/itasc/kdl/utilities/svd_eigen_HH.hpp
new file mode 100644
index 00000000000..2bbb8df521f
--- /dev/null
+++ b/intern/itasc/kdl/utilities/svd_eigen_HH.hpp
@@ -0,0 +1,309 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library 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 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that 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 this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+//Based on the svd of the KDL-0.2 library by Erwin Aertbelien
+#ifndef SVD_EIGEN_HH_HPP
+#define SVD_EIGEN_HH_HPP
+
+
+#include <Eigen/Array>
+#include <algorithm>
+
+namespace KDL
+{
+ template<typename Scalar> inline Scalar PYTHAG(Scalar a,Scalar b) {
+ double at,bt,ct;
+ at = fabs(a);
+ bt = fabs(b);
+ if (at > bt ) {
+ ct=bt/at;
+ return Scalar(at*sqrt(1.0+ct*ct));
+ } else {
+ if (bt==0)
+ return Scalar(0.0);
+ else {
+ ct=at/bt;
+ return Scalar(bt*sqrt(1.0+ct*ct));
+ }
+ }
+ }
+
+
+ template<typename Scalar> inline Scalar SIGN(Scalar a,Scalar b) {
+ return ((b) >= Scalar(0.0) ? fabs(a) : -fabs(a));
+ }
+
+ /**
+ * svd calculation of boost ublas matrices
+ *
+ * @param A matrix<double>(mxn)
+ * @param U matrix<double>(mxn)
+ * @param S vector<double> n
+ * @param V matrix<double>(nxn)
+ * @param tmp vector<double> n
+ * @param maxiter defaults to 150
+ *
+ * @return -2 if maxiter exceeded, 0 otherwise
+ */
+ template<typename MatrixA, typename MatrixUV, typename VectorS>
+ int svd_eigen_HH(
+ const Eigen::MatrixBase<MatrixA>& A,
+ Eigen::MatrixBase<MatrixUV>& U,
+ Eigen::MatrixBase<VectorS>& S,
+ Eigen::MatrixBase<MatrixUV>& V,
+ Eigen::MatrixBase<VectorS>& tmp,
+ int maxiter=150)
+ {
+ //get the rows/columns of the matrix
+ const int rows = A.rows();
+ const int cols = A.cols();
+
+ U = A;
+
+ int i(-1),its(-1),j(-1),jj(-1),k(-1),nm=0;
+ int ppi(0);
+ bool flag;
+ e_scalar maxarg1,maxarg2,anorm(0),c(0),f(0),h(0),s(0),scale(0),x(0),y(0),z(0),g(0);
+
+ g=scale=anorm=e_scalar(0.0);
+
+ /* Householder reduction to bidiagonal form. */
+ for (i=0;i<cols;i++) {
+ ppi=i+1;
+ tmp(i)=scale*g;
+ g=s=scale=e_scalar(0.0);
+ if (i<rows) {
+ // compute the sum of the i-th column, starting from the i-th row
+ for (k=i;k<rows;k++) scale += fabs(U(k,i));
+ if (scale!=0) {
+ // multiply the i-th column by 1.0/scale, start from the i-th element
+ // sum of squares of column i, start from the i-th element
+ for (k=i;k<rows;k++) {
+ U(k,i) /= scale;
+ s += U(k,i)*U(k,i);
+ }
+ f=U(i,i); // f is the diag elem
+ g = -SIGN(e_scalar(sqrt(s)),f);
+ h=f*g-s;
+ U(i,i)=f-g;
+ for (j=ppi;j<cols;j++) {
+ // dot product of columns i and j, starting from the i-th row
+ for (s=0.0,k=i;k<rows;k++) s += U(k,i)*U(k,j);
+ f=s/h;
+ // copy the scaled i-th column into the j-th column
+ for (k=i;k<rows;k++) U(k,j) += f*U(k,i);
+ }
+ for (k=i;k<rows;k++) U(k,i) *= scale;
+ }
+ }
+ // save singular value
+ S(i)=scale*g;
+ g=s=scale=e_scalar(0.0);
+ if ((i <rows) && (i+1 != cols)) {
+ // sum of row i, start from columns i+1
+ for (k=ppi;k<cols;k++) scale += fabs(U(i,k));
+ if (scale!=0) {
+ for (k=ppi;k<cols;k++) {
+ U(i,k) /= scale;
+ s += U(i,k)*U(i,k);
+ }
+ f=U(i,ppi);
+ g = -SIGN(e_scalar(sqrt(s)),f);
+ h=f*g-s;
+ U(i,ppi)=f-g;
+ for (k=ppi;k<cols;k++) tmp(k)=U(i,k)/h;
+ for (j=ppi;j<rows;j++) {
+ for (s=0.0,k=ppi;k<cols;k++) s += U(j,k)*U(i,k);
+ for (k=ppi;k<cols;k++) U(j,k) += s*tmp(k);
+ }
+ for (k=ppi;k<cols;k++) U(i,k) *= scale;
+ }
+ }
+ maxarg1=anorm;
+ maxarg2=(fabs(S(i))+fabs(tmp(i)));
+ anorm = maxarg1 > maxarg2 ? maxarg1 : maxarg2;
+ }
+ /* Accumulation of right-hand transformations. */
+ for (i=cols-1;i>=0;i--) {
+ if (i<cols-1) {
+ if (g) {
+ for (j=ppi;j<cols;j++) V(j,i)=(U(i,j)/U(i,ppi))/g;
+ for (j=ppi;j<cols;j++) {
+ for (s=0.0,k=ppi;k<cols;k++) s += U(i,k)*V(k,j);
+ for (k=ppi;k<cols;k++) V(k,j) += s*V(k,i);
+ }
+ }
+ for (j=ppi;j<cols;j++) V(i,j)=V(j,i)=0.0;
+ }
+ V(i,i)=1.0;
+ g=tmp(i);
+ ppi=i;
+ }
+ /* Accumulation of left-hand transformations. */
+ for (i=cols-1<rows-1 ? cols-1:rows-1;i>=0;i--) {
+ ppi=i+1;
+ g=S(i);
+ for (j=ppi;j<cols;j++) U(i,j)=0.0;
+ if (g) {
+ g=e_scalar(1.0)/g;
+ for (j=ppi;j<cols;j++) {
+ for (s=0.0,k=ppi;k<rows;k++) s += U(k,i)*U(k,j);
+ f=(s/U(i,i))*g;
+ for (k=i;k<rows;k++) U(k,j) += f*U(k,i);
+ }
+ for (j=i;j<rows;j++) U(j,i) *= g;
+ } else {
+ for (j=i;j<rows;j++) U(j,i)=0.0;
+ }
+ ++U(i,i);
+ }
+
+ /* Diagonalization of the bidiagonal form. */
+ for (k=cols-1;k>=0;k--) { /* Loop over singular values. */
+ for (its=1;its<=maxiter;its++) { /* Loop over allowed iterations. */
+ flag=true;
+ for (ppi=k;ppi>=0;ppi--) { /* Test for splitting. */
+ nm=ppi-1; /* Note that tmp(1) is always zero. */
+ if ((fabs(tmp(ppi))+anorm) == anorm) {
+ flag=false;
+ break;
+ }
+ if ((fabs(S(nm)+anorm) == anorm)) break;
+ }
+ if (flag) {
+ c=e_scalar(0.0); /* Cancellation of tmp(l), if l>1: */
+ s=e_scalar(1.);
+ for (i=ppi;i<=k;i++) {
+ f=s*tmp(i);
+ tmp(i)=c*tmp(i);
+ if ((fabs(f)+anorm) == anorm) break;
+ g=S(i);
+ h=PYTHAG(f,g);
+ S(i)=h;
+ h=e_scalar(1.0)/h;
+ c=g*h;
+ s=(-f*h);
+ for (j=0;j<rows;j++) {
+ y=U(j,nm);
+ z=U(j,i);
+ U(j,nm)=y*c+z*s;
+ U(j,i)=z*c-y*s;
+ }
+ }
+ }
+ z=S(k);
+
+ if (ppi == k) { /* Convergence. */
+ if (z < e_scalar(0.0)) { /* Singular value is made nonnegative. */
+ S(k) = -z;
+ for (j=0;j<cols;j++) V(j,k)=-V(j,k);
+ }
+ break;
+ }
+
+ x=S(ppi); /* Shift from bottom 2-by-2 minor: */
+ nm=k-1;
+ y=S(nm);
+ g=tmp(nm);
+ h=tmp(k);
+ f=((y-z)*(y+z)+(g-h)*(g+h))/(e_scalar(2.0)*h*y);
+
+ g=PYTHAG(f,e_scalar(1.0));
+ f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
+
+ /* Next QR transformation: */
+ c=s=1.0;
+ for (j=ppi;j<=nm;j++) {
+ i=j+1;
+ g=tmp(i);
+ y=S(i);
+ h=s*g;
+ g=c*g;
+ z=PYTHAG(f,h);
+ tmp(j)=z;
+ c=f/z;
+ s=h/z;
+ f=x*c+g*s;
+ g=g*c-x*s;
+ h=y*s;
+ y=y*c;
+ for (jj=0;jj<cols;jj++) {
+ x=V(jj,j);
+ z=V(jj,i);
+ V(jj,j)=x*c+z*s;
+ V(jj,i)=z*c-x*s;
+ }
+ z=PYTHAG(f,h);
+ S(j)=z;
+ if (z) {
+ z=e_scalar(1.0)/z;
+ c=f*z;
+ s=h*z;
+ }
+ f=(c*g)+(s*y);
+ x=(c*y)-(s*g);
+ for (jj=0;jj<rows;jj++) {
+ y=U(jj,j);
+ z=U(jj,i);
+ U(jj,j)=y*c+z*s;
+ U(jj,i)=z*c-y*s;
+ }
+ }
+ tmp(ppi)=0.0;
+ tmp(k)=f;
+ S(k)=x;
+ }
+ }
+
+ //Sort eigen values:
+ for (i=0; i<cols; i++){
+
+ double S_max = S(i);
+ int i_max = i;
+ for (j=i+1; j<cols; j++){
+ double Sj = S(j);
+ if (Sj > S_max){
+ S_max = Sj;
+ i_max = j;
+ }
+ }
+ if (i_max != i){
+ /* swap eigenvalues */
+ e_scalar tmp = S(i);
+ S(i)=S(i_max);
+ S(i_max)=tmp;
+
+ /* swap eigenvectors */
+ U.col(i).swap(U.col(i_max));
+ V.col(i).swap(V.col(i_max));
+ }
+ }
+
+
+ if (its == maxiter)
+ return (-2);
+ else
+ return (0);
+ }
+
+}
+#endif
diff --git a/intern/itasc/kdl/utilities/traits.h b/intern/itasc/kdl/utilities/traits.h
new file mode 100644
index 00000000000..2656d633653
--- /dev/null
+++ b/intern/itasc/kdl/utilities/traits.h
@@ -0,0 +1,111 @@
+#ifndef KDLPV_TRAITS_H
+#define KDLPV_TRAITS_H
+
+#include "utility.h"
+
+
+// forwards declarations :
+namespace KDL {
+ class Frame;
+ class Rotation;
+ class Vector;
+ class Twist;
+ class Wrench;
+ class FrameVel;
+ class RotationVel;
+ class VectorVel;
+ class TwistVel;
+}
+
+
+/**
+ * @brief Traits are traits classes to determine the type of a derivative of another type.
+ *
+ * For geometric objects the "geometric" derivative is chosen. For example the derivative of a Rotation
+ * matrix is NOT a 3x3 matrix containing the derivative of the elements of a rotation matrix. The derivative
+ * of the rotation matrix is a Vector corresponding the rotational velocity. Mostly used in template classes
+ * and routines to derive a correct type when needed.
+ *
+ * You can see this as a compile-time lookuptable to find the type of the derivative.
+ *
+ * Example
+ * \verbatim
+ Rotation R;
+ Traits<Rotation> dR;
+ \endverbatim
+ */
+template <typename T>
+struct Traits {
+ typedef T valueType;
+ typedef T derivType;
+};
+
+template <>
+struct Traits<KDL::Frame> {
+ typedef KDL::Frame valueType;
+ typedef KDL::Twist derivType;
+};
+template <>
+struct Traits<KDL::Twist> {
+ typedef KDL::Twist valueType;
+ typedef KDL::Twist derivType;
+};
+template <>
+struct Traits<KDL::Wrench> {
+ typedef KDL::Wrench valueType;
+ typedef KDL::Wrench derivType;
+};
+
+template <>
+struct Traits<KDL::Rotation> {
+ typedef KDL::Rotation valueType;
+ typedef KDL::Vector derivType;
+};
+
+template <>
+struct Traits<KDL::Vector> {
+ typedef KDL::Vector valueType;
+ typedef KDL::Vector derivType;
+};
+
+template <>
+struct Traits<double> {
+ typedef double valueType;
+ typedef double derivType;
+};
+
+template <>
+struct Traits<float> {
+ typedef float valueType;
+ typedef float derivType;
+};
+
+template <>
+struct Traits<KDL::FrameVel> {
+ typedef KDL::Frame valueType;
+ typedef KDL::TwistVel derivType;
+};
+template <>
+struct Traits<KDL::TwistVel> {
+ typedef KDL::Twist valueType;
+ typedef KDL::TwistVel derivType;
+};
+
+template <>
+struct Traits<KDL::RotationVel> {
+ typedef KDL::Rotation valueType;
+ typedef KDL::VectorVel derivType;
+};
+
+template <>
+struct Traits<KDL::VectorVel> {
+ typedef KDL::Vector valueType;
+ typedef KDL::VectorVel derivType;
+};
+
+
+
+#endif
+
+
+
diff --git a/intern/itasc/kdl/utilities/utility.cpp b/intern/itasc/kdl/utilities/utility.cpp
new file mode 100644
index 00000000000..1ab9cb6f83d
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility.cpp
@@ -0,0 +1,21 @@
+/** @file utility.cpp
+ * @author Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ * @version
+ * ORO_Geometry V0.2
+ *
+ * @par history
+ * - changed layout of the comments to accomodate doxygen
+ */
+
+#include "utility.h"
+
+namespace KDL {
+
+int STREAMBUFFERSIZE=10000;
+int MAXLENFILENAME = 255;
+const double PI= 3.1415926535897932384626433832795;
+const double deg2rad = 0.01745329251994329576923690768488;
+const double rad2deg = 57.2957795130823208767981548141052;
+double epsilon = 0.000001;
+double epsilon2 = 0.000001*0.000001;
+}
diff --git a/intern/itasc/kdl/utilities/utility.h b/intern/itasc/kdl/utilities/utility.h
new file mode 100644
index 00000000000..7151792536e
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility.h
@@ -0,0 +1,299 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ * \file
+ * Included by most lrl-files to provide some general
+ * functions and macro definitions.
+ *
+ * \par history
+ * - changed layout of the comments to accomodate doxygen
+ */
+
+
+#ifndef KDL_UTILITY_H
+#define KDL_UTILITY_H
+
+#include "kdl-config.h"
+#include <cstdlib>
+#include <cassert>
+#include <cmath>
+
+
+/////////////////////////////////////////////////////////////
+// configurable options for the frames library.
+
+#ifdef KDL_INLINE
+ #ifdef _MSC_VER
+ // Microsoft Visual C
+ #define IMETHOD __forceinline
+ #else
+ // Some other compiler, e.g. gcc
+ #define IMETHOD inline
+ #endif
+#else
+ #define IMETHOD
+#endif
+
+
+
+//! turn on or off frames bounds checking. If turned on, assert() can still
+//! be turned off with -DNDEBUG.
+#ifdef KDL_INDEX_CHECK
+ #define FRAMES_CHECKI(a) assert(a)
+#else
+ #define FRAMES_CHECKI(a)
+#endif
+
+
+namespace KDL {
+
+#ifdef __GNUC__
+ // so that sin,cos can be overloaded and complete
+ // resolution of overloaded functions work.
+ using ::sin;
+ using ::cos;
+ using ::exp;
+ using ::log;
+ using ::sin;
+ using ::cos;
+ using ::tan;
+ using ::sinh;
+ using ::cosh;
+ using ::pow;
+ using ::sqrt;
+ using ::atan;
+ using ::hypot;
+ using ::asin;
+ using ::acos;
+ using ::tanh;
+ using ::atan2;
+#endif
+#ifndef __GNUC__
+ //only real solution : get Rall1d and varia out of namespaces.
+ #pragma warning (disable:4786)
+
+ inline double sin(double a) {
+ return ::sin(a);
+ }
+
+ inline double cos(double a) {
+ return ::cos(a);
+ }
+ inline double exp(double a) {
+ return ::exp(a);
+ }
+ inline double log(double a) {
+ return ::log(a);
+ }
+ inline double tan(double a) {
+ return ::tan(a);
+ }
+ inline double cosh(double a) {
+ return ::cosh(a);
+ }
+ inline double sinh(double a) {
+ return ::sinh(a);
+ }
+ inline double sqrt(double a) {
+ return ::sqrt(a);
+ }
+ inline double atan(double a) {
+ return ::atan(a);
+ }
+ inline double acos(double a) {
+ return ::acos(a);
+ }
+ inline double asin(double a) {
+ return ::asin(a);
+ }
+ inline double tanh(double a) {
+ return ::tanh(a);
+ }
+ inline double pow(double a,double b) {
+ return ::pow(a,b);
+ }
+ inline double atan2(double a,double b) {
+ return ::atan2(a,b);
+ }
+#endif
+
+
+
+
+
+/**
+ * Auxiliary class for argument types (Trait-template class )
+ *
+ * Is used to pass doubles by value, and arbitrary objects by const reference.
+ * This is TWICE as fast (2 x less memory access) and avoids bugs in VC6++ concerning
+ * the assignment of the result of intrinsic functions to const double&-typed variables,
+ * and optimization on.
+ */
+template <class T>
+class TI
+{
+ public:
+ typedef const T& Arg; //!< Arg is used for passing the element to a function.
+};
+
+template <>
+class TI<double> {
+public:
+ typedef double Arg;
+};
+
+template <>
+class TI<int> {
+public:
+ typedef int Arg;
+};
+
+
+
+
+
+/**
+ * /note linkage
+ * Something fishy about the difference between C++ and C
+ * in C++ const values default to INTERNAL linkage, in C they default
+ * to EXTERNAL linkage. Here the constants should have EXTERNAL linkage
+ * because they, for at least some of them, can be changed by the user.
+ * If you want to explicitly declare internal linkage, use "static".
+ */
+//!
+extern int STREAMBUFFERSIZE;
+
+//! maximal length of a file name
+extern int MAXLENFILENAME;
+
+//! the value of pi
+extern const double PI;
+
+//! the value pi/180
+extern const double deg2rad;
+
+//! the value 180/pi
+extern const double rad2deg;
+
+//! default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
+extern double epsilon;
+
+//! power or 2 of epsilon
+extern double epsilon2;
+
+//! the number of derivatives used in the RN-... objects.
+extern int VSIZE;
+
+
+
+#ifndef _MFC_VER
+#undef max
+inline double max(double a,double b) {
+ if (b<a)
+ return a;
+ else
+ return b;
+}
+
+#undef min
+inline double min(double a,double b) {
+ if (b<a)
+ return b;
+ else
+ return a;
+}
+#endif
+
+
+#ifdef _MSC_VER
+ //#pragma inline_depth( 255 )
+ //#pragma inline_recursion( on )
+ #define INLINE __forceinline
+ //#define INLINE inline
+#else
+ #define INLINE inline
+#endif
+
+
+inline double LinComb(double alfa,double a,
+ double beta,double b ) {
+ return alfa*a+beta*b;
+}
+
+inline void LinCombR(double alfa,double a,
+ double beta,double b,double& result ) {
+ result=alfa*a+beta*b;
+ }
+
+//! to uniformly set double, RNDouble,Vector,... objects to zero in template-classes
+inline void SetToZero(double& arg) {
+ arg=0;
+}
+
+//! to uniformly set double, RNDouble,Vector,... objects to the identity element in template-classes
+inline void SetToIdentity(double& arg) {
+ arg=1;
+}
+
+inline double sign(double arg) {
+ return (arg<0)?(-1):(1);
+}
+
+inline double sqr(double arg) { return arg*arg;}
+inline double Norm(double arg) {
+ return fabs( (double)arg );
+}
+
+
+#if defined(__WIN32__) && !defined(__GNUC__)
+inline double hypot(double y,double x) { return ::_hypot(y,x);}
+inline double abs(double x) { return ::fabs(x);}
+#endif
+
+// compares whether 2 doubles are equal in an eps-interval.
+// Does not check whether a or b represents numbers
+// On VC6, if a/b is -INF, it returns false;
+inline bool Equal(double a,double b,double eps=epsilon)
+{
+ double tmp=(a-b);
+ return ((eps>tmp)&& (tmp>-eps) );
+}
+
+inline void random(double& a) {
+ a = 1.98*rand()/(double)RAND_MAX -0.99;
+}
+
+inline void posrandom(double& a) {
+ a = 0.001+0.99*rand()/(double)RAND_MAX;
+}
+
+inline double diff(double a,double b,double dt) {
+ return (b-a)/dt;
+}
+//inline float diff(float a,float b,double dt) {
+//return (b-a)/dt;
+//}
+inline double addDelta(double a,double da,double dt) {
+ return a+da*dt;
+}
+
+//inline float addDelta(float a,float da,double dt) {
+// return a+da*dt;
+//}
+
+
+}
+
+
+
+#endif
diff --git a/intern/itasc/kdl/utilities/utility_io.cpp b/intern/itasc/kdl/utilities/utility_io.cpp
new file mode 100644
index 00000000000..994567dfdfc
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility_io.cpp
@@ -0,0 +1,208 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ * \todo
+ * make IO routines more robust against the differences between DOS/UNIX end-of-line style.
+ ****************************************************************************/
+
+
+#include "utility_io.h"
+#include "error.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+namespace KDL {
+
+//
+// _functions are private functions
+//
+
+ void _check_istream(std::istream& is)
+ {
+ if ((!is.good())&&(is.eof()) )
+ {
+ throw Error_BasicIO_File();
+ }
+ }
+// Eats until the end of the line
+ int _EatUntilEndOfLine( std::istream& is, int* countp=NULL) {
+ int ch;
+ int count;
+ count = 0;
+ do {
+ ch = is.get();
+ count++;
+ _check_istream(is);
+ } while (ch!='\n');
+ if (countp!=NULL) *countp = count;
+ return ch;
+}
+
+// Eats until the end of the comment
+ int _EatUntilEndOfComment( std::istream& is, int* countp=NULL) {
+ int ch;
+ int count;
+ count = 0;
+ int prevch;
+ ch = 0;
+ do {
+ prevch = ch;
+ ch = is.get();
+ count++;
+ _check_istream(is);
+ if ((prevch=='*')&&(ch=='/')) {
+ break;
+ }
+ } while (true);
+ if (countp!=NULL) *countp = count;
+ ch = is.get();
+ return ch;
+}
+
+// Eats space-like characters and comments
+// possibly returns the number of space-like characters eaten.
+int _EatSpace( std::istream& is,int* countp=NULL) {
+ int ch;
+ int count;
+ count=-1;
+ do {
+ _check_istream(is);
+
+ ch = is.get();
+ count++;
+ if (ch == '#') {
+ ch = _EatUntilEndOfLine(is,&count);
+ }
+ if (ch == '/') {
+ ch = is.get();
+ if (ch == '/') {
+ ch = _EatUntilEndOfLine(is,&count);
+ } else if (ch == '*') {
+ ch = _EatUntilEndOfComment(is,&count);
+ } else {
+ is.putback(ch);
+ ch = '/';
+ }
+ }
+ } while ((ch==' ')||(ch=='\n')||(ch=='\t'));
+ if (countp!=NULL) *countp = count;
+ return ch;
+}
+
+
+
+// Eats whites, returns, tabs and the delim character
+// Checks wether delim char. is encountered.
+void Eat( std::istream& is, int delim )
+{
+ int ch;
+ ch=_EatSpace(is);
+ if (ch != delim) {
+ throw Error_BasicIO_Exp_Delim();
+ }
+ ch=_EatSpace(is);
+ is.putback(ch);
+}
+
+// Eats whites, returns, tabs and the delim character
+// Checks wether delim char. is encountered.
+// EatEnd does not eat all space-like char's at the end.
+void EatEnd( std::istream& is, int delim )
+{
+ int ch;
+ ch=_EatSpace(is);
+ if (ch != delim) {
+ throw Error_BasicIO_Exp_Delim();
+ }
+}
+
+
+
+// For each space in descript, this routine eats whites,tabs, and newlines (at least one)
+// There should be no consecutive spaces in the description.
+// for each letter in descript, its reads the corresponding letter in the output
+// the routine is case insensitive.
+
+
+// Simple routine, enough for our purposes.
+// works with ASCII chars
+inline char Upper(char ch)
+{
+ /*if (('a'<=ch)&&(ch<='z'))
+ return (ch-'a'+'A');
+ else
+ return ch;
+ */
+ return toupper(ch);
+}
+
+void Eat(std::istream& is,const char* descript)
+{
+ // eats whites before word
+ char ch;
+ char chdescr;
+ ch=_EatSpace(is);
+ is.putback(ch);
+ const char* p;
+ p = descript;
+ while ((*p)!=0) {
+ chdescr = (char)Upper(*p);
+ if (chdescr==' ') {
+ int count=0;
+ ch=_EatSpace(is,&count);
+ is.putback(ch);
+ if (count==0) {
+ throw Error_BasicIO_Not_A_Space();
+ }
+ } else {
+ ch=(char)is.get();
+ if (chdescr!=Upper(ch)) {
+ throw Error_BasicIO_Unexpected();
+ }
+ }
+ p++;
+ }
+
+}
+
+
+
+void EatWord(std::istream& is,const char* delim,char* storage,int maxsize)
+{
+ int ch;
+ char* p;
+ int size;
+ // eat white before word
+ ch=_EatSpace(is);
+ p = storage;
+ size=0;
+ int count = 0;
+ while ((count==0)&&(strchr(delim,ch)==NULL)) {
+ *p = (char) toupper(ch);
+ ++p;
+ if (size==maxsize) {
+ throw Error_BasicIO_ToBig();
+ }
+ _check_istream(is);
+ ++size;
+ //ch = is.get();
+ ch =_EatSpace(is,&count);
+ }
+ *p=0;
+ is.putback(ch);
+}
+
+
+}
diff --git a/intern/itasc/kdl/utilities/utility_io.h b/intern/itasc/kdl/utilities/utility_io.h
new file mode 100644
index 00000000000..2a71ce870a3
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility_io.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id$
+ * $Name: $
+ *
+ * \file utility_io.h
+ * Included by most lrl-files to provide some general
+ * functions and macro definitions related to file/stream I/O.
+ */
+
+#ifndef KDL_UTILITY_IO_H_84822
+#define KDL_UTILITY_IO_H_84822
+
+//#include <kdl/kdl-config.h>
+
+
+// Standard includes
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+
+namespace KDL {
+
+
+/**
+ * checks validity of basic io of is
+ */
+void _check_istream(std::istream& is);
+
+
+/**
+ * Eats characters of the stream until the character delim is encountered
+ * @param is a stream
+ * @param delim eat until this character is encountered
+ */
+void Eat(std::istream& is, int delim );
+
+/**
+ * Eats characters of the stream as long as they satisfy the description in descript
+ * @param is a stream
+ * @param descript description string. A sequence of spaces, tabs,
+ * new-lines and comments is regarded as 1 space in the description string.
+ */
+void Eat(std::istream& is,const char* descript);
+
+/**
+ * Eats a word of the stream delimited by the letters in delim or space(tabs...)
+ * @param is a stream
+ * @param delim a string containing the delimmiting characters
+ * @param storage for returning the word
+ * @param maxsize a word can be maximally maxsize-1 long.
+ */
+void EatWord(std::istream& is,const char* delim,char* storage,int maxsize);
+
+/**
+ * Eats characters of the stream until the character delim is encountered
+ * similar to Eat(is,delim) but spaces at the end are not read.
+ * @param is a stream
+ * @param delim eat until this character is encountered
+ */
+void EatEnd( std::istream& is, int delim );
+
+
+
+
+}
+
+
+#endif
diff --git a/intern/itasc/make/msvc_9_0/itasc.vcproj b/intern/itasc/make/msvc_9_0/itasc.vcproj
new file mode 100644
index 00000000000..f4a81079da0
--- /dev/null
+++ b/intern/itasc/make/msvc_9_0/itasc.vcproj
@@ -0,0 +1,539 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="INT_itasc"
+ ProjectGUID="{59567A5B-F63A-4A5C-B33A-0A45C300F4DC}"
+ RootNamespace="itasc"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Blender Debug|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\itasc\debug"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\itasc\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\..\extern\Eigen2"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="0"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\itasc\debug\itasc.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\itasc\debug\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\itasc\debug\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\itasc\debug\"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\debug\libitasc.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Blender Release|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\itasc"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\itasc"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\..\..\..\extern\Eigen2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\libitasc.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="kdl"
+ >
+ <Filter
+ Name="Header Files"
+ >
+ <File
+ RelativePath="..\..\kdl\chain.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainfksolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainfksolverpos_recursive.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainjnttojacsolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frameacc.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frameacc.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames_io.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\framevel.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\framevel.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\inertia.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jacobian.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarray.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayacc.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayvel.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\joint.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\kinfam_io.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\segment.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\tree.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treefksolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treefksolverpos_recursive.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treejnttojacsolver.hpp"
+ >
+ </File>
+ <Filter
+ Name="Utilities"
+ >
+ <File
+ RelativePath="..\..\kdl\utilities\error.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\error_stack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\kdl-config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\rall1d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\rall2d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\svd_eigen_HH.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\traits.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility_io.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ >
+ <File
+ RelativePath="..\..\kdl\chain.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainfksolverpos_recursive.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainjnttojacsolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frameacc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames_io.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\framevel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\inertia.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jacobian.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarray.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayacc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayvel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\joint.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\kinfam_io.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\segment.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\tree.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treefksolverpos_recursive.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treejnttojacsolver.cpp"
+ >
+ </File>
+ <Filter
+ Name="Utilities"
+ >
+ <File
+ RelativePath="..\..\kdl\utilities\error_stack.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility_io.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="itasc"
+ >
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\Armature.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Cache.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ConstraintSet.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ControlledObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\CopyPose.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Distance.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\eigen_types.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FixedObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\MovingFrame.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Object.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Scene.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Solver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\UncontrolledObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WDLSSolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WorldObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WSDLSSolver.hpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\Armature.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Cache.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ConstraintSet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ControlledObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\CopyPose.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Distance.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\eigen_types.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FixedObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\MovingFrame.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Scene.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\UncontrolledObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WDLSSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WorldObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WSDLSSolver.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/intern/itasc/ublas_types.hpp b/intern/itasc/ublas_types.hpp
new file mode 100644
index 00000000000..bf9bdcc26f2
--- /dev/null
+++ b/intern/itasc/ublas_types.hpp
@@ -0,0 +1,82 @@
+/*
+ * ublas_types.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef UBLAS_TYPES_HPP_
+#define UBLAS_TYPES_HPP_
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include "kdl/frames.hpp"
+#include "kdl/tree.hpp"
+#include "kdl/chain.hpp"
+#include "kdl/jacobian.hpp"
+#include "kdl/jntarray.hpp"
+
+
+namespace iTaSC{
+
+namespace ublas = boost::numeric::ublas;
+using KDL::Twist;
+using KDL::Frame;
+using KDL::Joint;
+using KDL::Inertia;
+using KDL::SegmentMap;
+using KDL::Tree;
+using KDL::JntArray;
+using KDL::Jacobian;
+using KDL::Segment;
+using KDL::Rotation;
+using KDL::Vector;
+using KDL::Chain;
+
+#define u_scalar double
+#define u_vector ublas::vector<u_scalar>
+#define u_zero_vector ublas::zero_vector<u_scalar>
+#define u_matrix ublas::matrix<u_scalar>
+#define u_matrix6 ublas::matrix<u_scalar,6,6>
+#define u_identity_matrix ublas::identity_matrix<u_scalar>
+#define u_scalar_vector ublas::scalar_vector<u_scalar>
+#define u_zero_matrix ublas::zero_matrix<u_scalar>
+#define u_vector6 ublas::bounded_vector<u_scalar,6>
+
+inline static int changeBase(const u_matrix& J_in, const Frame& T, u_matrix& J_out) {
+
+ if (J_out.size1() != 6 || J_in.size1() != 6 || J_in.size2() != J_out.size2())
+ return -1;
+ for (unsigned int j = 0; j < J_in.size2(); ++j) {
+ ublas::matrix_column<const u_matrix > Jj_in = column(J_in,j);
+ ublas::matrix_column<u_matrix > Jj_out = column(J_out,j);
+ Twist arg;
+ for(unsigned int i=0;i<6;++i)
+ arg(i)=Jj_in(i);
+ Twist tmp(T*arg);
+ for(unsigned int i=0;i<6;++i)
+ Jj_out(i)=tmp(i);
+ }
+ return 0;
+}
+inline static int changeBase(const ublas::matrix_range<u_matrix >& J_in, const Frame& T, ublas::matrix_range<u_matrix >& J_out) {
+
+ if (J_out.size1() != 6 || J_in.size1() != 6 || J_in.size2() != J_out.size2())
+ return -1;
+ for (unsigned int j = 0; j < J_in.size2(); ++j) {
+ ublas::matrix_column<const ublas::matrix_range<u_matrix > > Jj_in = column(J_in,j);
+ ublas::matrix_column<ublas::matrix_range<u_matrix > > Jj_out = column(J_out,j);
+ Twist arg;
+ for(unsigned int i=0;i<6;++i)
+ arg(i)=Jj_in(i);
+ Twist tmp(T*arg);
+ for(unsigned int i=0;i<6;++i)
+ Jj_out(i)=tmp(i);
+ }
+ return 0;
+}
+
+}
+#endif /* UBLAS_TYPES_HPP_ */
diff --git a/intern/memutil/make/msvc_9_0/memutil.vcproj b/intern/memutil/make/msvc_9_0/memutil.vcproj
index 6f642fb16bc..0b8251f0d7e 100644
--- a/intern/memutil/make/msvc_9_0/memutil.vcproj
+++ b/intern/memutil/make/msvc_9_0/memutil.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\..\..\intern;..\..\..\memutil"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/moto/make/msvc_9_0/moto.vcproj b/intern/moto/make/msvc_9_0/moto.vcproj
index b33bb165a75..34c5705e2f2 100644
--- a/intern/moto/make/msvc_9_0/moto.vcproj
+++ b/intern/moto/make/msvc_9_0/moto.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\include\"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
index 7574a0ec16e..8a32eaa2e68 100644
--- a/intern/smoke/intern/FLUID_3D.cpp
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -182,6 +182,9 @@ void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
//////////////////////////////////////////////////////////////////////
void FLUID_3D::step()
{
+ // addSmokeTestCase(_density, _res);
+ // addSmokeTestCase(_heat, _res);
+
// wipe forces
for (int i = 0; i < _totalCells; i++)
{
diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h
index 9d9e7318204..a7be7f58335 100644
--- a/intern/smoke/intern/FLUID_3D.h
+++ b/intern/smoke/intern/FLUID_3D.h
@@ -47,7 +47,7 @@ class FLUID_3D
void initVectorNoise(int amplify);
void addSmokeColumn();
- static void addSmokeTestCase(float* field, Vec3Int res, float value);
+ static void addSmokeTestCase(float* field, Vec3Int res);
void step();
void addObstacle(OBSTACLE* obstacle);
diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp
index 4909c071c3d..0215dfc417f 100644
--- a/intern/smoke/intern/FLUID_3D_STATIC.cpp
+++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp
@@ -44,8 +44,8 @@ void FLUID_3D::addSmokeColumn() {
// generic static version, so that it can be applied to the
// WTURBULENCE grid as well
//////////////////////////////////////////////////////////////////////
-/*
-void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
+
+void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res)
{
const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res);
float dx = 1.0f / (float)maxRes;
@@ -54,25 +54,23 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
float yTotal = dx * res[1];
float zTotal = dx * res[2];
- float heighMin = 0.05;
- float heighMax = 0.10;
-
- for (int y = 0; y < res[1]; y++)
- for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[1]); z++)
- for (int x = 0; x < res[0]; x++)
- {
- float xLength = x * dx - xTotal * 0.4f;
- float yLength = y * dx - zTotal * 0.5f;
- float radius = sqrtf(xLength * xLength + yLength * yLength);
-
- if (radius < 0.075f * xTotal)
- {
- int index = x + y * res[0] + z * slabSize;
- field[index] = value;
- }
- }
+ float heighMin = 0.05;
+ float heighMax = 0.10;
+
+ for (int y = 0; y < res[2]; y++)
+ for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++)
+ for (int x = 0; x < res[0]; x++) {
+ float xLength = x * dx - xTotal * 0.4f;
+ float yLength = y * dx - yTotal * 0.5f;
+ float radius = sqrtf(xLength * xLength + yLength * yLength);
+
+ if (radius < 0.075f * xTotal) {
+ int index = x + y * res[0] + z * slabSize;
+ field[index] = 1.0f;
+ }
+ }
}
-*/
+
//////////////////////////////////////////////////////////////////////
// set x direction to Neumann boundary conditions
@@ -98,7 +96,7 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res)
for (int z = 0; z < res[2]; z++)
{
// top slab
- int index = y * res[0] + z * slabSize;
+ index = y * res[0] + z * slabSize;
index += res[0] - 1;
if(field[index]<0.) field[index] = 0.;
index -= 1;
@@ -130,7 +128,7 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res)
for (int x = 0; x < res[0]; x++)
{
// top slab
- int index = x + z * slabSize;
+ index = x + z * slabSize;
index += slabSize - res[0];
if(field[index]<0.) field[index] = 0.;
index -= res[0];
@@ -164,7 +162,7 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res)
for (int x = 0; x < res[0]; x++)
{
// top slab
- int index = x + y * res[0];
+ index = x + y * res[0];
index += totalCells - slabSize;
if(field[index]<0.) field[index] = 0.;
index -= slabSize;
@@ -295,12 +293,10 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
const int xres = res[0];
const int yres = res[1];
const int zres = res[2];
- static int hits = 0;
- static int total = 0;
const int slabSize = res[0] * res[1];
// scale dt up to grid resolution
-#if PARALLEL==1 && !_WIN32
+#if PARALLEL==1
#pragma omp parallel
#pragma omp for schedule(static)
#endif
diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp
index a1b2aaf30f2..bcfc61856af 100644
--- a/intern/smoke/intern/WTURBULENCE.cpp
+++ b/intern/smoke/intern/WTURBULENCE.cpp
@@ -986,4 +986,3 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
_totalStepsBig++;
}
-
diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp
index 058831dddbb..67df6e805d8 100644
--- a/intern/smoke/intern/smoke_API.cpp
+++ b/intern/smoke/intern/smoke_API.cpp
@@ -81,8 +81,7 @@ extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
{
- if(wt)
- wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
+ wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
}
extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta)
diff --git a/intern/smoke/make/msvc_9_0/smoke.vcproj b/intern/smoke/make/msvc_9_0/smoke.vcproj
index aa3779031f0..38a761d5d82 100644
--- a/intern/smoke/make/msvc_9_0/smoke.vcproj
+++ b/intern/smoke/make/msvc_9_0/smoke.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\intern;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/string/make/msvc_9_0/string.vcproj b/intern/string/make/msvc_9_0/string.vcproj
index 16df974ff9c..512d67623b6 100644
--- a/intern/string/make/msvc_9_0/string.vcproj
+++ b/intern/string/make/msvc_9_0/string.vcproj
@@ -118,6 +118,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\.."
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/po/Makefile b/po/Makefile
index 425efbc08b3..b656a00fb38 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -50,9 +50,11 @@ LINGUAS_DEST= $(foreach LINGUA, $(LINGUAS),$(DIR)$(LINGUA)/LC_MESSAGES/blender.m
$(DIR)%/LC_MESSAGES/blender.mo: %.po
mkdir -p $(@D)
msgfmt -o $@ $<
+ifeq ($(BF_VERIFY_MO_FILES), true)
@cmp $@ $(NANBLENDERHOME)/bin/.blender/locale/$(basename $<)/LC_MESSAGES/blender.mo \
|| ( echo Mismatch between generated and commited $(basename $<).mo catalog && \
rm -f $@ && false )
+endif
all debug:: $(LINGUAS_DEST)
# Just trigger the deps
diff --git a/projectfiles_vc9/blender/BLO_readblenfile/BLO_readblenfile.vcproj b/projectfiles_vc9/blender/BLO_readblenfile/BLO_readblenfile.vcproj
index 07afe8c5b30..4d3b086cc7a 100644
--- a/projectfiles_vc9/blender/BLO_readblenfile/BLO_readblenfile.vcproj
+++ b/projectfiles_vc9/blender/BLO_readblenfile/BLO_readblenfile.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="BLO_readblenfile"
ProjectGUID="{DB6BE55D-B6D9-494D-856A-8764FF7BA91D}"
+ RootNamespace="BLO_readblenfile"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -264,6 +265,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\inflate;..\..\..\source\blender\deflate;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\blender\readblenfile;..\..\..\source\blender\readstreamglue;..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
index 7f1eff21e6f..6137696fc59 100644
--- a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
+++ b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\img;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesrna;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenloader;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/projectfiles_vc9/blender/avi/BL_avi.vcproj b/projectfiles_vc9/blender/avi/BL_avi.vcproj
index f9700ab85c2..e45cb1944a2 100644
--- a/projectfiles_vc9/blender/avi/BL_avi.vcproj
+++ b/projectfiles_vc9/blender/avi/BL_avi.vcproj
@@ -192,6 +192,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern\openexr"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,DWORDS_LITTLEENDIAN"
diff --git a/projectfiles_vc9/blender/blender.sln b/projectfiles_vc9/blender/blender.sln
index 51103efe20b..002e2b6a7c5 100644
--- a/projectfiles_vc9/blender/blender.sln
+++ b/projectfiles_vc9/blender/blender.sln
@@ -2,6 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj", "{F78B7FC9-DE32-465E-9F26-BB0B6B7A2EAF}"
ProjectSection(ProjectDependencies) = postProject
+ {02110D03-59DB-4571-8787-72B3C03B2F2D} = {02110D03-59DB-4571-8787-72B3C03B2F2D}
{E5F2F004-C704-4DCC-A08F-6EB1E38EAB9F} = {E5F2F004-C704-4DCC-A08F-6EB1E38EAB9F}
{6E24BF09-9653-4166-A871-F65CC9E98A9B} = {6E24BF09-9653-4166-A871-F65CC9E98A9B}
{A90C4918-4B21-4277-93BD-AF65F30951D9} = {A90C4918-4B21-4277-93BD-AF65F30951D9}
@@ -17,6 +18,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj",
{FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
{31628053-825D-4C06-8A21-D13883489718} = {31628053-825D-4C06-8A21-D13883489718}
{EADC3C5A-6C51-4F03-8038-1553E7D7F740} = {EADC3C5A-6C51-4F03-8038-1553E7D7F740}
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC} = {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}
{B093415D-C0F6-4E76-8F5A-6BC1917BCE9E} = {B093415D-C0F6-4E76-8F5A-6BC1917BCE9E}
{DB6BE55D-B6D9-494D-856A-8764FF7BA91D} = {DB6BE55D-B6D9-494D-856A-8764FF7BA91D}
{0A73055E-4DED-40CD-9F72-9093ED3EEC7E} = {0A73055E-4DED-40CD-9F72-9093ED3EEC7E}
@@ -43,6 +45,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj",
{E90C7BC2-CF30-4A60-A8F2-0050D592E358} = {E90C7BC2-CF30-4A60-A8F2-0050D592E358}
{8B8D4FC3-3234-4E54-8376-5AB83D00D164} = {8B8D4FC3-3234-4E54-8376-5AB83D00D164}
{4B6AFCC5-968C-424A-8F20-76E41B3BEF74} = {4B6AFCC5-968C-424A-8F20-76E41B3BEF74}
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3} = {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}
{87032FD2-9BA0-6B43-BE33-8902BA8F9172} = {87032FD2-9BA0-6B43-BE33-8902BA8F9172}
{EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9} = {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}
{5A2EA6DC-1A53-4E87-9166-52870CE3B4EA} = {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}
@@ -136,6 +139,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blenderplayer", "..\gameeng
{FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
{31628053-825D-4C06-8A21-D13883489718} = {31628053-825D-4C06-8A21-D13883489718}
{EADC3C5A-6C51-4F03-8038-1553E7D7F740} = {EADC3C5A-6C51-4F03-8038-1553E7D7F740}
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC} = {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}
{DB6BE55D-B6D9-494D-856A-8764FF7BA91D} = {DB6BE55D-B6D9-494D-856A-8764FF7BA91D}
{0A73055E-4DED-40CD-9F72-9093ED3EEC7E} = {0A73055E-4DED-40CD-9F72-9093ED3EEC7E}
{09222F5E-1625-4FF3-A89A-384D16875EE5} = {09222F5E-1625-4FF3-A89A-384D16875EE5}
@@ -160,6 +164,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blenderplayer", "..\gameeng
{E90C7BC2-CF30-4A60-A8F2-0050D592E358} = {E90C7BC2-CF30-4A60-A8F2-0050D592E358}
{8B8D4FC3-3234-4E54-8376-5AB83D00D164} = {8B8D4FC3-3234-4E54-8376-5AB83D00D164}
{4B6AFCC5-968C-424A-8F20-76E41B3BEF74} = {4B6AFCC5-968C-424A-8F20-76E41B3BEF74}
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3} = {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}
{87032FD2-9BA0-6B43-BE33-8902BA8F9172} = {87032FD2-9BA0-6B43-BE33-8902BA8F9172}
{5A2EA6DC-1A53-4E87-9166-52870CE3B4EA} = {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}
{E86B7BDE-C33C-4E55-9433-E74C141D7538} = {E86B7BDE-C33C-4E55-9433-E74C141D7538}
@@ -225,6 +230,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EXT_build_install_all", "..
ProjectSection(ProjectDependencies) = postProject
{79D0B232-208C-F208-DA71-79B4AC088602} = {79D0B232-208C-F208-DA71-79B4AC088602}
{FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400}
+ {EADC3C5A-6C51-4F03-8038-1553E7D7F740} = {EADC3C5A-6C51-4F03-8038-1553E7D7F740}
+ {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}
{8BFA4082-773B-D100-BC24-659083BA023F} = {8BFA4082-773B-D100-BC24-659083BA023F}
{BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}
EndProjectSection
@@ -268,6 +275,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "INT_build_install_all", "..
ProjectSection(ProjectDependencies) = postProject
{A90C4918-4B21-4277-93BD-AF65F30951D9} = {A90C4918-4B21-4277-93BD-AF65F30951D9}
{C66F722C-46BE-40C9-ABAE-2EAC7A697EB8} = {C66F722C-46BE-40C9-ABAE-2EAC7A697EB8}
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC} = {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}
{B093415D-C0F6-4E76-8F5A-6BC1917BCE9E} = {B093415D-C0F6-4E76-8F5A-6BC1917BCE9E}
{76D90B92-ECC7-409C-9F98-A8814B90F3C0} = {76D90B92-ECC7-409C-9F98-A8814B90F3C0}
{542A9FA1-B7FF-441C-AE15-054DB31D3488} = {542A9FA1-B7FF-441C-AE15-054DB31D3488}
@@ -292,6 +300,8 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RNA_makesrna", "makesrna\RNA_makesrna.vcproj", "{8C2BCCF8-4D9E-46D3-BABF-C1545A332CE6}"
ProjectSection(ProjectDependencies) = postProject
{7495FE37-933A-4AC1-BB2A-B3FDB4DE4284} = {7495FE37-933A-4AC1-BB2A-B3FDB4DE4284}
+ {31628053-825D-4C06-8A21-D13883489718} = {31628053-825D-4C06-8A21-D13883489718}
+ {1CC733F1-6AB5-4904-8F63-C08C46B79DD9} = {1CC733F1-6AB5-4904-8F63-C08C46B79DD9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RNA_rna", "makesrna\RNA_rna.vcproj", "{DFE7F3E3-E62A-4677-B666-DF0DDF70C359}"
@@ -306,6 +316,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNA_dna", "makesdna\DNA_dna
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BLF_blenfont", "blenfont\BLF_blenfont.vcproj", "{D1A9312F-4557-4982-A0F4-4D08508235F4}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "INT_itasc", "..\..\intern\itasc\make\msvc_9_0\itasc.vcproj", "{59567A5B-F63A-4A5C-B33A-0A45C300F4DC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BIK_ikplugin", "ikplugin\BIK_ikplugin.vcproj", "{9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "INT_smoke", "..\..\intern\smoke\make\msvc_9_0\smoke.vcproj", "{E8904FB3-F8F7-BC21-87A6-029A57B901F4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "INT_audaspace", "..\..\intern\audaspace\make\msvc_9_0\audaspace.vcproj", "{87032FD2-9BA0-6B43-BE33-8902BA8F9172}"
@@ -557,7 +571,6 @@ Global
{DF25E6F2-780C-438B-8AAD-D10CF8B3820A}.BlenderPlayer Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
{DF25E6F2-780C-438B-8AAD-D10CF8B3820A}.BlenderPlayer Release|Win32.ActiveCfg = 3D Plugin Release|Win32
{DF25E6F2-780C-438B-8AAD-D10CF8B3820A}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
- {DF25E6F2-780C-438B-8AAD-D10CF8B3820A}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32
{DF25E6F2-780C-438B-8AAD-D10CF8B3820A}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32
{DF25E6F2-780C-438B-8AAD-D10CF8B3820A}.Release|Win32.Build.0 = 3D Plugin Release|Win32
{D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.3D Plugin Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
@@ -575,7 +588,6 @@ Global
{D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.BlenderPlayer Release|Win32.ActiveCfg = BlenderPlayer Release|Win32
{D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.BlenderPlayer Release|Win32.Build.0 = BlenderPlayer Release|Win32
{D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.Debug|Win32.ActiveCfg = BlenderPlayer Debug|Win32
- {D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.Debug|Win32.Build.0 = BlenderPlayer Debug|Win32
{D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.Release|Win32.ActiveCfg = BlenderPlayer Release|Win32
{D8ABD6A5-1B36-4D62-934E-B5C6801130B0}.Release|Win32.Build.0 = BlenderPlayer Release|Win32
{3D310C60-6771-48E4-BCCA-D2718CDED898}.3D Plugin Debug|Win32.ActiveCfg = BlenderPlayer Release|Win32
@@ -593,7 +605,6 @@ Global
{3D310C60-6771-48E4-BCCA-D2718CDED898}.BlenderPlayer Release|Win32.ActiveCfg = BlenderPlayer Release|Win32
{3D310C60-6771-48E4-BCCA-D2718CDED898}.BlenderPlayer Release|Win32.Build.0 = BlenderPlayer Release|Win32
{3D310C60-6771-48E4-BCCA-D2718CDED898}.Debug|Win32.ActiveCfg = BlenderPlayer Debug|Win32
- {3D310C60-6771-48E4-BCCA-D2718CDED898}.Debug|Win32.Build.0 = BlenderPlayer Debug|Win32
{3D310C60-6771-48E4-BCCA-D2718CDED898}.Release|Win32.ActiveCfg = BlenderPlayer Release|Win32
{3D310C60-6771-48E4-BCCA-D2718CDED898}.Release|Win32.Build.0 = BlenderPlayer Release|Win32
{8154A59A-CAED-403D-AB94-BC4E7C032666}.3D Plugin Debug|Win32.ActiveCfg = Blender Release|Win32
@@ -1039,6 +1050,7 @@ Global
{9C71A793-C177-4CAB-8EC5-923D500B39F8}.3DPlugin Release|Win32.ActiveCfg = 3D Plugin Debug|Win32
{9C71A793-C177-4CAB-8EC5-923D500B39F8}.3DPlugin Release|Win32.Build.0 = 3D Plugin Debug|Win32
{9C71A793-C177-4CAB-8EC5-923D500B39F8}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {9C71A793-C177-4CAB-8EC5-923D500B39F8}.Blender Debug|Win32.Build.0 = Blender Debug|Win32
{9C71A793-C177-4CAB-8EC5-923D500B39F8}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{9C71A793-C177-4CAB-8EC5-923D500B39F8}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
{9C71A793-C177-4CAB-8EC5-923D500B39F8}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
@@ -1289,6 +1301,7 @@ Global
{02110D03-59DB-4571-8787-72B3C03B2F2D}.3DPlugin Release|Win32.ActiveCfg = 3DPlugin Release|Win32
{02110D03-59DB-4571-8787-72B3C03B2F2D}.3DPlugin Release|Win32.Build.0 = 3DPlugin Release|Win32
{02110D03-59DB-4571-8787-72B3C03B2F2D}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {02110D03-59DB-4571-8787-72B3C03B2F2D}.Blender Debug|Win32.Build.0 = Blender Debug|Win32
{02110D03-59DB-4571-8787-72B3C03B2F2D}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{02110D03-59DB-4571-8787-72B3C03B2F2D}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
{02110D03-59DB-4571-8787-72B3C03B2F2D}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
@@ -1416,6 +1429,42 @@ Global
{D1A9312F-4557-4982-A0F4-4D08508235F4}.Debug|Win32.Build.0 = Blender Debug|Win32
{D1A9312F-4557-4982-A0F4-4D08508235F4}.Release|Win32.ActiveCfg = Blender Release|Win32
{D1A9312F-4557-4982-A0F4-4D08508235F4}.Release|Win32.Build.0 = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.3D Plugin Debug|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.3D Plugin Debug|Win32.Build.0 = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.3D Plugin Release|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.3D Plugin Release|Win32.Build.0 = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.3DPlugin Debug|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.3DPlugin Release|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Blender Debug|Win32.Build.0 = Blender Debug|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Blender Release|Win32.Build.0 = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.BlenderPlayer Debug|Win32.Build.0 = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Debug|Win32.Build.0 = Blender Debug|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Release|Win32.ActiveCfg = Blender Release|Win32
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}.Release|Win32.Build.0 = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.3D Plugin Debug|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.3D Plugin Debug|Win32.Build.0 = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.3D Plugin Release|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.3D Plugin Release|Win32.Build.0 = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.3DPlugin Debug|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.3DPlugin Release|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Blender Debug|Win32.Build.0 = Blender Debug|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Blender Release|Win32.Build.0 = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.BlenderPlayer Debug|Win32.Build.0 = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Debug|Win32.Build.0 = Blender Debug|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Release|Win32.ActiveCfg = Blender Release|Win32
+ {9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}.Release|Win32.Build.0 = Blender Release|Win32
{E8904FB3-F8F7-BC21-87A6-029A57B901F4}.3D Plugin Debug|Win32.ActiveCfg = 3DPlugin Debug|Win32
{E8904FB3-F8F7-BC21-87A6-029A57B901F4}.3D Plugin Debug|Win32.Build.0 = 3DPlugin Debug|Win32
{E8904FB3-F8F7-BC21-87A6-029A57B901F4}.3D Plugin Release|Win32.ActiveCfg = 3DPlugin Debug|Win32
diff --git a/projectfiles_vc9/blender/blender.vcproj b/projectfiles_vc9/blender/blender.vcproj
index e6a5c483f7a..d6f29788f9d 100644
--- a/projectfiles_vc9/blender/blender.vcproj
+++ b/projectfiles_vc9/blender/blender.vcproj
@@ -43,6 +43,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\source\blender;..\..\source\blender\imbuf;..\..\source\blender\misc;..\..\source\blender\blenlib;..\..\source\blender\editors\include;..\..\source\blender\python;..\..\source\blender\windowmanager;..\..\source\blender\renderui;..\..\source\blender\makesdna;..\..\source\blender\makesrna;..\..\source\blender\blenkernel;..\..\source\blender\blenloader;..\..\source\blender\renderconverter;..\..\source\blender\render\extern\include;..\..\source\blender\radiosity\extern\include;..\..\source\kernel\gen_system;..\..\source\kernel\gen_messaging;..\..\..\build\msvc_9\extern\glew\include;..\..\source\blender\gpu"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;WITH_QUICKTIME;GAMEBLENDER=1;USE_SUMO_SOLID;FTGL_LIBRARY_STATIC"
diff --git a/projectfiles_vc9/blender/blenfont/BLF_blenfont.vcproj b/projectfiles_vc9/blender/blenfont/BLF_blenfont.vcproj
index 7b92276d4b8..07cddc10fc5 100644
--- a/projectfiles_vc9/blender/blenfont/BLF_blenfont.vcproj
+++ b/projectfiles_vc9/blender/blenfont/BLF_blenfont.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\intern\guardedalloc;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\ftfont;..\..\..\..\lib\windows\freetype\include;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\extern\glew\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WITH_BF_INTERNATIONAL"
diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
index 87f10346726..3f17da1ddab 100644
--- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -118,7 +118,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_OPENEXR;WITH_DDS;WITH_BULLET;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -192,8 +192,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;UNWRAPPER;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
StringPooling="true"
RuntimeLibrary="0"
@@ -268,7 +269,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
StringPooling="true"
RuntimeLibrary="2"
@@ -343,7 +344,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -418,7 +419,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\extern\lzo\minilzo;..\..\..\extern\lzma;..\..\..\source\blender\blenfont;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;UNWRAPPER;WITH_FFMPEG"
StringPooling="true"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj
index a6630c81aca..b883d8bf2b2 100644
--- a/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj
+++ b/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj
@@ -194,6 +194,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\freetype\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB"
@@ -483,6 +484,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\intern\BLI_bfile.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_dynstr.c"
>
</File>
@@ -620,6 +625,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\BLI_bfile.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\BLI_blenlib.h"
>
</File>
diff --git a/projectfiles_vc9/blender/blenpluginapi/blenpluginapi/blenpluginapi.vcproj b/projectfiles_vc9/blender/blenpluginapi/blenpluginapi/blenpluginapi.vcproj
index 02ea370e34a..c8e8dffbb24 100644
--- a/projectfiles_vc9/blender/blenpluginapi/blenpluginapi/blenpluginapi.vcproj
+++ b/projectfiles_vc9/blender/blenpluginapi/blenpluginapi/blenpluginapi.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="blenpluginapi"
ProjectGUID="{BB6AA598-B336-4F8B-9DF9-8CAE7BE71C23}"
+ RootNamespace="blenpluginapi"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -42,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -115,8 +116,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
RuntimeLibrary="0"
@@ -191,7 +193,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
RuntimeLibrary="2"
@@ -266,7 +268,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -340,7 +342,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
RuntimeLibrary="0"
@@ -415,7 +417,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj
index 5a6519d3d35..c49e817196e 100644
--- a/projectfiles_vc9/blender/editors/ED_editors.vcproj
+++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj
@@ -42,8 +42,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_FREETYPE2;WITH_INTERNATIONAL;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
StringPooling="true"
RuntimeLibrary="0"
@@ -118,7 +119,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_BF_INTERNATIONAL;WITH_FREETYPE2;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -270,7 +271,7 @@
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\include\ED_previewrender.h"
+ RelativePath="..\..\..\source\blender\editors\include\ED_render.h"
>
</File>
<File
@@ -379,7 +380,7 @@
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\datafiles\splash.jpg.c"
+ RelativePath="..\..\..\source\blender\editors\datafiles\splash.png.c"
>
</File>
</Filter>
@@ -1215,11 +1216,15 @@
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\mesh\mesh_intern.h"
+ RelativePath="..\..\..\source\blender\editors\mesh\loopcut.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\mesh\mesh_data.c"
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\mesh\mesh_layers.c"
+ RelativePath="..\..\..\source\blender\editors\mesh\mesh_intern.h"
>
</File>
<File
@@ -1283,6 +1288,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\armature\poseSlide.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\armature\reeb.c"
>
</File>
@@ -1412,38 +1421,34 @@
</File>
</Filter>
<Filter
- Name="preview"
+ Name="physics"
>
<File
- RelativePath="..\..\..\source\blender\editors\preview\previewrender.c"
+ RelativePath="..\..\..\source\blender\editors\physics\particle_boids.c"
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\preview\previewrender_intern.h"
+ RelativePath="..\..\..\source\blender\editors\physics\particle_edit.c"
>
</File>
- </Filter>
- <Filter
- Name="physics"
- >
<File
- RelativePath="..\..\..\source\blender\editors\physics\ed_fluidsim.c"
+ RelativePath="..\..\..\source\blender\editors\physics\particle_object.c"
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\physics\ed_pointcache.c"
+ RelativePath="..\..\..\source\blender\editors\physics\physics_fluid.c"
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\physics\editparticle.c"
+ RelativePath="..\..\..\source\blender\editors\physics\physics_intern.h"
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\physics\physics_boids.c"
+ RelativePath="..\..\..\source\blender\editors\physics\physics_ops.c"
>
</File>
<File
- RelativePath="..\..\..\source\blender\editors\physics\physics_intern.h"
+ RelativePath="..\..\..\source\blender\editors\physics\physics_pointcache.c"
>
</File>
</Filter>
@@ -1539,6 +1544,26 @@
>
</File>
</Filter>
+ <Filter
+ Name="render"
+ >
+ <File
+ RelativePath="..\..\..\source\blender\editors\render\render_intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\render\render_ops.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\render\render_preview.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\render\render_shading.c"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
diff --git a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj
index a185c8a7b18..af0b90796d1 100644
--- a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj
+++ b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj
@@ -192,6 +192,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\gpu"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,DWORDS_LITTLEENDIAN"
diff --git a/projectfiles_vc9/blender/ikplugin/BIK_ikplugin.vcproj b/projectfiles_vc9/blender/ikplugin/BIK_ikplugin.vcproj
new file mode 100644
index 00000000000..48693942798
--- /dev/null
+++ b/projectfiles_vc9/blender/ikplugin/BIK_ikplugin.vcproj
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="BIK_ikplugin"
+ ProjectGUID="{9951A8C9-84FE-4CFE-9E18-9D01CB8E09F3}"
+ RootNamespace="BRE_ikplugin"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Blender Debug|Win32"
+ OutputDirectory="..\..\..\..\build\msvc_9\source\blender\ikplugin\debug"
+ IntermediateDirectory="..\..\..\..\build\msvc_9\source\blender\ikplugin\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\ikplugin;..\..\..\intern\itasc;..\..\..\extern\Eigen2"
+ PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ DefaultCharIsUnsigned="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\build\msvc_9\source\blender\ikplugin\debug\BRE_yafray.pch"
+ AssemblerListingLocation="..\..\..\..\build\msvc_9\source\blender\ikplugin\debug\"
+ ObjectFile="..\..\..\..\build\msvc_9\source\blender\ikplugin\debug\"
+ ProgramDataBaseFileName="..\..\..\..\build\msvc_9\source\blender\ikplugin\debug\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\build\msvc_9\libs\debug\BRE_ikplugin.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Blender Release|Win32"
+ OutputDirectory="..\..\..\..\build\msvc_9\source\blender\ikplugin"
+ IntermediateDirectory="..\..\..\..\build\msvc_9\source\blender\ikplugin"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\ikplugin;..\..\..\intern\itasc;..\..\..\extern\Eigen2"
+ PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ DefaultCharIsUnsigned="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\build\msvc_9\source\blender\yafray\BIK_ikplugin.pch"
+ AssemblerListingLocation="..\..\..\..\build\msvc_9\source\blender\ikplugin\"
+ ObjectFile="..\..\..\..\build\msvc_9\source\blender\ikplugin\"
+ ProgramDataBaseFileName="..\..\..\..\build\msvc_9\source\blender\ikplugin\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\build\msvc_9\libs\BIK_ikplugin.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\intern\ikplugin_api.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\intern\iksolver_plugin.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\intern\itasc_plugin.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\intern\ikplugin_api.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\intern\iksolver_plugin.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\intern\itasc_plugin.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\..\source\blender\ikplugin\BIK_api.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj b/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj
index 0e25b26831b..b0ba1133393 100644
--- a/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj
+++ b/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj
@@ -266,6 +266,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\tiff\include;..\..\..\..\lib\windows\openexr\include;..\..\..\..\lib\windows\openexr\include\Iex;..\..\..\..\lib\windows\openexr\include\Imath;..\..\..\..\lib\windows\openexr\include\IlmImf;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\imbuf\intern\openexr;..\..\..\source\blender\imbuf\intern\dds"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;WITH_DDS;WITH_FFMPEG"
diff --git a/projectfiles_vc9/blender/loader/BLO_loader.vcproj b/projectfiles_vc9/blender/loader/BLO_loader.vcproj
index a8cec5ecf76..0ddb02afad1 100644
--- a/projectfiles_vc9/blender/loader/BLO_loader.vcproj
+++ b/projectfiles_vc9/blender/loader/BLO_loader.vcproj
@@ -267,6 +267,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\zlib\include;..\..\..\source\blender\inflate;..\..\..\source\blender\deflate;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\streamglue;..\..\..\source\blender\readblenfile;..\..\..\source\blender\writeblenfile;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\writestreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel\gen_messaging;..\..\..\..\build\msvc_9\extern\verse\include"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB"
@@ -470,123 +471,6 @@
</References>
<Files>
<Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"
- >
- </File>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"
- >
- <FileConfiguration
- Name="Blender Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Blender Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"
- >
- </File>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"
- >
- <FileConfiguration
- Name="Blender Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Blender Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
@@ -606,6 +490,123 @@
RelativePath="..\..\..\source\blender\blenloader\BLO_undofile.h"
>
</File>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"
+ >
+ <FileConfiguration
+ Name="Blender Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Blender Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"
+ >
+ <FileConfiguration
+ Name="Blender Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Blender Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
</Filter>
</Files>
<Globals>
diff --git a/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj b/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj
index 77fbe72dede..631c5dc2693 100644
--- a/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj
+++ b/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj
@@ -137,6 +137,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include"
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
index 8dd1982deca..f52dd193150 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
@@ -74,11 +74,10 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="libguardedalloc.lib BLI_blenlib.lib odbc32.lib odbccp32.lib"
OutputFile="..\..\..\source\blender\makesrna\intern\RNA_makesrna.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\build\msvc_9\libs\intern\mtdll\debug;..\..\..\..\build\msvc_9\libs\mtdll\debug"
+ AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames=" libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\..\..\..\build\msvc_9\libs\debug\DNA_makesrna.pdb"
@@ -139,6 +138,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager;..\..\..\source\blender\imbuf"
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
@@ -169,11 +169,10 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="libguardedalloc.lib BLI_blenlib.lib"
OutputFile="..\..\..\source\blender\makesrna\intern\RNA_makesrna.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\build\msvc_9\libs\intern;..\..\..\..\build\msvc_9\libs"
+ AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="libc.lib"
ProgramDatabaseFile="..\..\..\..\build\msvc_9\libs\DNA_makesrna.pdb"
SubSystem="1"
@@ -263,11 +262,10 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="libguardedalloc.lib BLI_blenlib.lib odbc32.lib odbccp32.lib"
OutputFile="..\..\..\source\blender\makesrna\intern\RNA_makesrna.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\build\msvc_9\libs\intern\mtdll;..\..\..\..\build\msvc_9\libs\mtdll"
+ AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames=" libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib"
ProgramDatabaseFile="..\..\..\..\build\msvc_9\libs\DNA_makesrna.pdb"
SubSystem="1"
@@ -358,11 +356,10 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386&#x0D;&#x0A;"
- AdditionalDependencies="libguardedalloc.lib BLI_blenlib.lib DNA_dna.lib"
OutputFile="..\..\..\source\blender\makesrna\intern\RNA_makesrna.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\build\msvc_9\libs\intern\debug;..\..\..\..\build\msvc_9\libs\debug"
+ AdditionalLibraryDirectories=""
IgnoreAllDefaultLibraries="false"
IgnoreDefaultLibraryNames="libc.lib, libcd.lib"
GenerateDebugInformation="true"
@@ -455,11 +452,10 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386&#x0D;&#x0A;"
- AdditionalDependencies="libguardedalloc.lib BLI_blenlib.lib odbc32.lib odbccp32.lib"
OutputFile="..\..\..\source\blender\makesrna\intern\RNA_makesrna.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\build\msvc_9\libs\intern\debug;..\..\..\..\build\msvc_9\libs\debug"
+ AdditionalLibraryDirectories=""
IgnoreAllDefaultLibraries="false"
IgnoreDefaultLibraryNames="libc.lib, libcd.lib"
GenerateDebugInformation="true"
@@ -551,11 +547,10 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="libguardedalloc.lib BLI_blenlib.lib odbc32.lib odbccp32.lib"
OutputFile="..\..\..\source\blender\makesrna\intern\RNA_makesrna.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\build\msvc_9\libs\intern;..\..\..\..\build\msvc_9\libs"
+ AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="libc.lib"
ProgramDatabaseFile="..\..\..\..\build\msvc_9\libs\DNA_makesrna.pdb"
SubSystem="1"
@@ -603,6 +598,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna_action_api.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna_actuator.c"
>
</File>
@@ -683,6 +682,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna_image_api.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna_key.c"
>
</File>
@@ -707,6 +710,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna_material_api.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna_mesh.c"
>
</File>
@@ -755,6 +762,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna_pose_api.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna_property.c"
>
</File>
@@ -811,6 +822,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna_text_api.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna_texture.c"
>
</File>
@@ -851,6 +866,22 @@
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
+ <File
+ RelativePath="..\..\..\source\blender\makesrna\RNA_access.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\makesrna\RNA_define.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\makesrna\RNA_enum_types.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\makesrna\RNA_types.h"
+ >
+ </File>
</Filter>
<Filter
Name="Resource Files"
diff --git a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
index 84359390f41..66449b01f81 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\ikplugin;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -114,7 +114,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\ikplugin;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/blender/nodes/nodes.vcproj b/projectfiles_vc9/blender/nodes/nodes.vcproj
index ca997306f04..e9cb51b5cff 100644
--- a/projectfiles_vc9/blender/nodes/nodes.vcproj
+++ b/projectfiles_vc9/blender/nodes/nodes.vcproj
@@ -42,7 +42,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
MinimalRebuild="false"
BasicRuntimeChecks="3"
@@ -112,7 +112,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
@@ -182,7 +182,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_OPENEXR"
MinimalRebuild="false"
BasicRuntimeChecks="3"
@@ -252,7 +252,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
+ Optimization="2"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_OPENEXR"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/blender/render/BRE_render.vcproj b/projectfiles_vc9/blender/render/BRE_render.vcproj
index 4e354c6dde3..4b223ddcdc3 100644
--- a/projectfiles_vc9/blender/render/BRE_render.vcproj
+++ b/projectfiles_vc9/blender/render/BRE_render.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="BRE_render"
ProjectGUID="{106AE171-0083-41D6-A949-20DB0E8DC251}"
+ RootNamespace="BRE_render"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -41,8 +42,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR"
StringPooling="true"
RuntimeLibrary="0"
@@ -117,7 +119,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;_USE_MATH_DEFINES"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
diff --git a/projectfiles_vc9/blender/windowmanager/windowmanager.vcproj b/projectfiles_vc9/blender/windowmanager/windowmanager.vcproj
index a074f66327d..805ad1f1cf3 100644
--- a/projectfiles_vc9/blender/windowmanager/windowmanager.vcproj
+++ b/projectfiles_vc9/blender/windowmanager/windowmanager.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -113,7 +113,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj b/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj
index ea387c4e976..ab959de31c7 100644
--- a/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj
+++ b/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenfont;..\..\..\intern\audaspace\intern"
PreprocessorDefinitions="WIN32;_LIB;_DEBUG;WITH_GLEXT;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -118,8 +118,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenfont"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenfont;..\..\..\intern\audaspace\intern"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT;WITH_FFMPEG"
StringPooling="true"
BasicRuntimeChecks="0"
diff --git a/projectfiles_vc9/gameengine/converter/KX_converter.vcproj b/projectfiles_vc9/gameengine/converter/KX_converter.vcproj
index d179fe03dc7..48b7f81b2aa 100644
--- a/projectfiles_vc9/gameengine/converter/KX_converter.vcproj
+++ b/projectfiles_vc9/gameengine/converter/KX_converter.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="WIN32,_LIB,_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -117,8 +117,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,USE_SUMO_SOLID"
StringPooling="true"
RuntimeLibrary="0"
@@ -194,7 +195,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="WIN32,_LIB,_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -269,7 +270,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,USE_SUMO_SOLID"
StringPooling="true"
RuntimeLibrary="2"
@@ -345,7 +346,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="WIN32,_LIB,_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -420,7 +421,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\ode;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\gameengine\soundsystem\snd_blenderwavecache;..\..\..\source\sumo\include;..\..\..\source\sumo\Fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\gpu;..\..\..\source\blender\windowmanager;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,USE_SUMO_SOLID"
StringPooling="true"
RuntimeLibrary="0"
@@ -481,6 +482,22 @@
>
</File>
<File
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureActuator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureChannel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureConstraint.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureObject.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Converter\BL_BlenderDataConversion.cpp"
>
</File>
@@ -554,7 +571,15 @@
>
</File>
<File
- RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureObject.cpp"
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureActuator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureChannel.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureConstraint.h"
>
</File>
<File
diff --git a/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj b/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj
index 9aeb9584b35..1ee2fe7eb52 100644
--- a/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj
+++ b/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -118,7 +118,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
PreprocessorDefinitions="WIN32,_LIB,EXP_PYTHON_EMBEDDING,_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -193,7 +193,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
StringPooling="true"
RuntimeLibrary="2"
@@ -267,8 +267,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
StringPooling="true"
RuntimeLibrary="0"
@@ -343,7 +344,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -418,7 +419,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph;..\..\..\source\blender\blenloader"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
StringPooling="true"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj b/projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj
index 61e589213c0..72150cb7752 100644
--- a/projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj
+++ b/projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj
@@ -117,6 +117,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
@@ -498,6 +499,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_BasicEventManager.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_DelaySensor.cpp"
>
</File>
@@ -659,6 +664,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_BasicEventManager.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_DelaySensor.h"
>
</File>
diff --git a/projectfiles_vc9/gameengine/gameplayer/axctl/GP_axctl.vcproj b/projectfiles_vc9/gameengine/gameplayer/axctl/GP_axctl.vcproj
index ed2dad65374..5bcfe1aabd1 100644
--- a/projectfiles_vc9/gameengine/gameplayer/axctl/GP_axctl.vcproj
+++ b/projectfiles_vc9/gameengine/gameplayer/axctl/GP_axctl.vcproj
@@ -161,6 +161,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\openal\include;..\..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\include;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenloader;..\..\..\..\source\blender\render\extern\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\kernel\gen_messaging;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\network;..\..\..\..\source\gameengine\rasterizer;..\..\..\..\source\gameengine\converter;..\..\..\..\source\gameengine\gamelogic;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\scenegraph;..\..\..\..\source\gameengine\soundsystem;..\..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\..\source\gameengine\gameplayer\common;..\..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\..\source\gameengine\GamePlayer\common;..\..\..\..\source\gameengine\GamePlayer\common\windows;..\..\..\..\source\sumo\include;..\..\..\..\source\sumo\fuzzics\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
diff --git a/projectfiles_vc9/gameengine/gameplayer/common/GP_common.vcproj b/projectfiles_vc9/gameengine/gameplayer/common/GP_common.vcproj
index 87d9683a25e..ad8f3338594 100644
--- a/projectfiles_vc9/gameengine/gameplayer/common/GP_common.vcproj
+++ b/projectfiles_vc9/gameengine/gameplayer/common/GP_common.vcproj
@@ -265,6 +265,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\..\build\msvc_9\intern\openal\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenloader;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\render\extern\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\network;..\..\..\..\source\gameengine\rasterizer;..\..\..\..\source\gameengine\Converter;..\..\..\..\source\gameengine\gamelogic;..\..\..\..\source\gameengine\scenegraph;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\soundsystem;..\..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\..\source\gameengine\GamePlayer\common;..\..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\source\gameengine\soundsystem\snd_dummy;..\..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\..\source\gameengine\Physics\Sumo;..\..\..\..\source\gameengine\Physics\common;..\..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\..\source\sumo\include;..\..\..\..\source\sumo\fuzzics\include;..\..\..\..\source\blender\gpu"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
index e29a65264e9..4d6b7a4cd8a 100644
--- a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
+++ b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
@@ -136,6 +136,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\openal\include;..\..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\source\blender\include;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenloader;..\..\..\..\source\blender\readblenfile;..\..\..\..\source\blender\render\extern\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\kernel\gen_messaging;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Physics;..\..\..\..\source\gameengine\network;..\..\..\..\source\gameengine\rasterizer;..\..\..\..\source\gameengine\converter;..\..\..\..\source\gameengine\gamelogic;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\scenegraph;..\..\..\..\source\gameengine\Physics\Ode;..\..\..\..\source\gameengine\soundsystem;..\..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\..\source\gameengine\gameplayer\common;..\..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\..\source\gameengine\gameplayer\common\windows;..\..\..\..\source\sumo\include;..\..\..\..\source\sumo\fuzzics\include;..\..\..\..\source\blender\gpu;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE;WITH_FFMPEG"
diff --git a/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
index f709e0b7d29..b552b87e820 100644
--- a/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
+++ b/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
@@ -269,6 +269,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\sdl\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\python\generic;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT"
@@ -718,6 +719,10 @@
Name="SensorsImp"
>
<File
+ RelativePath="..\..\..\source\gameengine\Ketsji\KX_ArmatureSensor.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_MouseFocusSensor.cpp"
>
</File>
@@ -1027,6 +1032,10 @@
Name="Sensors"
>
<File
+ RelativePath="..\..\..\source\gameengine\Ketsji\KX_ArmatureSensor.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_MouseFocusSensor.h"
>
</File>
diff --git a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
index 36c8218b803..92cde144652 100644
--- a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
+++ b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/projectfiles_vc9/gameengine/network/loopbacknetwork/NG_loopbacknetwork.vcproj b/projectfiles_vc9/gameengine/network/loopbacknetwork/NG_loopbacknetwork.vcproj
index bbb8cc5ec25..ca5e0ddaf94 100644
--- a/projectfiles_vc9/gameengine/network/loopbacknetwork/NG_loopbacknetwork.vcproj
+++ b/projectfiles_vc9/gameengine/network/loopbacknetwork/NG_loopbacknetwork.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="NG_loopbacknetwork"
ProjectGUID="{6B801390-5F95-4F07-81A7-97FBA046AACC}"
+ RootNamespace="NG_loopbacknetwork"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -116,6 +117,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Network"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/projectfiles_vc9/gameengine/network/network/NG_network.vcproj b/projectfiles_vc9/gameengine/network/network/NG_network.vcproj
index a9e0ce1acd2..b7a8ab77e26 100644
--- a/projectfiles_vc9/gameengine/network/network/NG_network.vcproj
+++ b/projectfiles_vc9/gameengine/network/network/NG_network.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="NG_network"
ProjectGUID="{0A73055E-4DED-40CD-9F72-9093ED3EEC7E}"
+ RootNamespace="NG_network"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -191,6 +192,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\source\kernel\gen_system"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
index d4e29e0774a..128b902754c 100644
--- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
+++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
@@ -176,6 +176,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna;..\..\..\..\..\source\blender\blenkernel;..\..\..\..\..\source\blender\blenlib"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Dummy/PHY_Dummy.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Dummy/PHY_Dummy.vcproj
index 5c0159d5aa9..bd39d14895f 100644
--- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Dummy/PHY_Dummy.vcproj
+++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Dummy/PHY_Dummy.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="PHY_Dummy"
ProjectGUID="{3648FB9A-C36F-43AB-AED0-1F1361E67FC7}"
+ RootNamespace="PHY_Dummy"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -264,6 +265,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\source\gameengine\physics\common"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Ode/PHY_Ode.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Ode/PHY_Ode.vcproj
index e9773ecf683..d5b3f657f11 100644
--- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Ode/PHY_Ode.vcproj
+++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Ode/PHY_Ode.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="PHY_Ode"
ProjectGUID="{EC405272-28E3-4840-AAC2-53D6DE4E163D}"
+ RootNamespace="PHY_Ode"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -264,6 +265,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\ode\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\source\gameengine\physics\common"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj
index 5441c5bd4f1..7158da47f3b 100644
--- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj
+++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj
@@ -116,6 +116,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\moto\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_SUMO_SOLID"
diff --git a/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj b/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj
index 43c8d4100bf..f82b46413c9 100644
--- a/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj
+++ b/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj
@@ -192,6 +192,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
diff --git a/projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj b/projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
index 09b87f41ddf..4d55bd0da37 100644
--- a/projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
+++ b/projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
@@ -267,6 +267,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
diff --git a/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj b/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj
index 95e61cc4af8..043a934758c 100644
--- a/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj
+++ b/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
index 94e09303a1b..4eb37259785 100644
--- a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
+++ b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
@@ -112,6 +112,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WITH_FFMPEG;__STDC_CONSTANT_MACROS"
diff --git a/projectfiles_vc9/kernel/gen_messaging/gen_messaging.vcproj b/projectfiles_vc9/kernel/gen_messaging/gen_messaging.vcproj
index ac958a10f54..8dfe63b67a4 100644
--- a/projectfiles_vc9/kernel/gen_messaging/gen_messaging.vcproj
+++ b/projectfiles_vc9/kernel/gen_messaging/gen_messaging.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="gen_messaging"
ProjectGUID="{727F90AC-ABE6-40BF-8937-C2F2F1D13DEA}"
+ RootNamespace="gen_messaging"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -189,6 +190,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/projectfiles_vc9/kernel/system/SYS_system.vcproj b/projectfiles_vc9/kernel/system/SYS_system.vcproj
index c667a6050e8..36ec0001d8b 100644
--- a/projectfiles_vc9/kernel/system/SYS_system.vcproj
+++ b/projectfiles_vc9/kernel/system/SYS_system.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="SYS_system"
ProjectGUID="{BAAE3F2B-BCF8-4E84-B8BA-CFB2D64945FE}"
+ RootNamespace="SYS_system"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -266,6 +267,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
diff --git a/release/Makefile b/release/Makefile
index 94bb902646d..9fe83ef3494 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -153,9 +153,6 @@ endif
@echo "----> Copy python infrastructure"
@[ ! -d scripts ] || cp -r scripts $(CONFDIR)/scripts
-
- @echo "----> Copy python UI files"
- @[ ! -d ui ] || cp -r ui $(CONFDIR)/ui
ifeq ($(OS),darwin)
@echo "----> Copy python modules"
diff --git a/release/datafiles/splash.jpg b/release/datafiles/splash.png
index e35a26a2c23..e35a26a2c23 100644
--- a/release/datafiles/splash.jpg
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py
deleted file mode 100644
index c12c846231d..00000000000
--- a/release/io/netrender/slave.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import sys, os
-import http, http.client, http.server, urllib
-import subprocess, time
-
-from netrender.utils import *
-import netrender.model
-
-CANCEL_POLL_SPEED = 2
-MAX_TIMEOUT = 10
-INCREMENT_TIMEOUT = 1
-
-def slave_Info():
- sysname, nodename, release, version, machine = os.uname()
- slave = netrender.model.RenderSlave()
- slave.name = nodename
- slave.stats = sysname + " " + release + " " + machine
- return slave
-
-def testCancel(conn, job_id):
- conn.request("HEAD", "status", headers={"job-id":job_id})
- response = conn.getresponse()
-
- # cancelled if job isn't found anymore
- if response.status == http.client.NO_CONTENT:
- return True
- else:
- return False
-
-def testFile(conn, JOB_PREFIX, file_path, main_path = None):
- job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
-
- if not os.path.exists(job_full_path):
- temp_path = JOB_PREFIX + "slave.temp.blend"
- conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id, "job-file":file_path})
- response = conn.getresponse()
-
- if response.status != http.client.OK:
- return None # file for job not returned by server, need to return an error code to server
-
- f = open(temp_path, "wb")
- buf = response.read(1024)
-
- while buf:
- f.write(buf)
- buf = response.read(1024)
-
- f.close()
-
- os.renames(temp_path, job_full_path)
-
- return job_full_path
-
-
-def render_slave(engine, scene):
- netsettings = scene.network_render
- timeout = 1
-
- engine.update_stats("", "Network render node initiation")
-
- conn = clientConnection(scene)
-
- if conn:
- conn.request("POST", "slave", repr(slave_Info().serialize()))
- response = conn.getresponse()
-
- slave_id = response.getheader("slave-id")
-
- NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
- if not os.path.exists(NODE_PREFIX):
- os.mkdir(NODE_PREFIX)
-
- while not engine.test_break():
-
- conn.request("GET", "job", headers={"slave-id":slave_id})
- response = conn.getresponse()
-
- if response.status == http.client.OK:
- timeout = 1 # reset timeout on new job
-
- job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
-
- JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
- if not os.path.exists(JOB_PREFIX):
- os.mkdir(JOB_PREFIX)
-
- job_path = job.files[0][0] # data in files have format (path, start, end)
- main_path, main_file = os.path.split(job_path)
-
- job_full_path = testFile(conn, JOB_PREFIX, job_path)
- print("Fullpath", job_full_path)
- print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
- engine.update_stats("", "Render File", main_file, "for job", job.id)
-
- for file_path, start, end in job.files[1:]:
- print("\t", file_path)
- testFile(conn, JOB_PREFIX, file_path, main_path)
-
- frame_args = []
-
- for frame in job.frames:
- print("frame", frame.number)
- frame_args += ["-f", str(frame.number)]
-
- start_t = time.time()
-
- process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
- cancelled = False
- stdout = bytes()
- run_t = time.time()
- while process.poll() == None and not cancelled:
- stdout += process.stdout.read(32)
- current_t = time.time()
- cancelled = engine.test_break()
- if current_t - run_t > CANCEL_POLL_SPEED:
- if testCancel(conn, job.id):
- cancelled = True
- else:
- run_t = current_t
-
- if cancelled:
- # kill process if needed
- if process.poll() == None:
- process.terminate()
- continue # to next frame
-
- total_t = time.time() - start_t
-
- avg_t = total_t / len(job.frames)
-
- status = process.returncode
-
- print("status", status)
-
- headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
-
- if status == 0: # non zero status is error
- headers["job-result"] = str(DONE)
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send result back to server
- f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
- conn.request("PUT", "render", f, headers=headers)
- f.close()
- response = conn.getresponse()
- else:
- headers["job-result"] = str(ERROR)
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send error result back to server
- conn.request("PUT", "render", headers=headers)
- response = conn.getresponse()
-
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send log in any case
- conn.request("PUT", "log", stdout, headers=headers)
- response = conn.getresponse()
- else:
- if timeout < MAX_TIMEOUT:
- timeout += INCREMENT_TIMEOUT
-
- for i in range(timeout):
- time.sleep(1)
- if engine.test_break():
- conn.close()
- return
-
- conn.close()
diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py
deleted file mode 100644
index bcde82c4869..00000000000
--- a/release/scripts/3ds_import.py
+++ /dev/null
@@ -1,1007 +0,0 @@
-#!BPY
-"""
-Name: '3D Studio (.3ds)...'
-Blender: 244
-Group: 'Import'
-Tooltip: 'Import from 3DS file format (.3ds)'
-"""
-
-__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin']
-__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
-__version__= '0.996'
-__bpydoc__= '''\
-
-3ds Importer
-
-This script imports a 3ds file and the materials into Blender for editing.
-
-Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen).
-
-0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200 <br>
- - Implemented workaround to correct association between name, geometry and materials of
- imported meshes.
-
- Without this patch, version 0.995 of this importer would associate to each mesh object the
- geometry and the materials of the previously parsed mesh object. By so, the name of the
- first mesh object would be thrown away, and the name of the last mesh object would be
- automatically merged with a '.001' at the end. No object would desappear, however object's
- names and materials would be completely jumbled.
-
-0.995 by Campbell Barton<br>
-- workaround for buggy mesh vert delete
-- minor tweaks
-
-0.99 by Bob Holcomb<br>
-- added support for floating point color values that previously broke on import.
-
-0.98 by Campbell Barton<br>
-- import faces and verts to lists instead of a mesh, convert to a mesh later
-- use new index mapping feature of mesh to re-map faces that were not added.
-
-0.97 by Campbell Barton<br>
-- Strip material names of spaces
-- Added import as instance to import the 3ds into its own
- scene and add a group instance to the current scene
-- New option to scale down imported objects so they are within a limited bounding area.
-
-0.96 by Campbell Barton<br>
-- Added workaround for bug in setting UV's for Zero vert index UV faces.
-- Removed unique name function, let blender make the names unique.
-
-0.95 by Campbell Barton<br>
-- Removed workarounds for Blender 2.41
-- Mesh objects split by material- many 3ds objects used more then 16 per mesh.
-- Removed a lot of unneeded variable creation.
-
-0.94 by Campbell Barton<br>
-- Face import tested to be about overall 16x speedup over 0.93.
-- Material importing speedup.
-- Tested with more models.
-- Support some corrupt models.
-
-0.93 by Campbell Barton<br>
-- Tested with 400 3ds files from turbosquid and samples.
-- Tactfully ignore faces that used the same verts twice.
-- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading.
-- Converted from NMesh to Mesh.
-- Faster and cleaner new names.
-- Use external comprehensive image loader.
-- Re intergrated 0.92 and 0.9 changes
-- Fixes for 2.41 compat.
-- Non textured faces do not use a texture flag.
-
-0.92<br>
-- Added support for diffuse, alpha, spec, bump maps in a single material
-
-0.9<br>
-- Reorganized code into object/material block functions<br>
-- Use of Matrix() to copy matrix data<br>
-- added support for material transparency<br>
-
-0.83 2005-08-07: Campell Barton
-- Aggressive image finding and case insensitivy for posisx systems.
-
-0.82a 2005-07-22
-- image texture loading (both for face uv and renderer)
-
-0.82 - image texture loading (for face uv)
-
-0.81a (fork- not 0.9) Campbell Barton 2005-06-08
-- Simplified import code
-- Never overwrite data
-- Faster list handling
-- Leaves import selected
-
-0.81 Damien McGinnes 2005-01-09
-- handle missing images better
-
-0.8 Damien McGinnes 2005-01-08
-- copies sticky UV coords to face ones
-- handles images better
-- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
-
-'''
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Bob Holcomb
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-# Importing modules
-
-import Blender
-import bpy
-from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils
-from Blender.Mathutils import Vector
-import BPyImage
-
-import BPyMessages
-
-try:
- from struct import calcsize, unpack
-except:
- calcsize= unpack= None
-
-
-
-# If python version is less than 2.4, try to get set stuff from module
-try:
- set
-except:
- from sets import Set as set
-
-BOUNDS_3DS= []
-
-
-#this script imports uvcoords as sticky vertex coords
-#this parameter enables copying these to face uv coords
-#which shold be more useful.
-
-def createBlenderTexture(material, name, image):
- texture= bpy.data.textures.new(name)
- texture.setType('Image')
- texture.image= image
- material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
-
-
-
-######################################################
-# Data Structures
-######################################################
-
-#Some of the chunks that we will see
-#----- Primary Chunk, at the beginning of each file
-PRIMARY= long('0x4D4D',16)
-
-#------ Main Chunks
-OBJECTINFO = long('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information
-VERSION = long('0x0002',16); #This gives the version of the .3ds file
-EDITKEYFRAME= long('0xB000',16); #This is the header for all of the key frame info
-
-#------ sub defines of OBJECTINFO
-MATERIAL=45055 #0xAFFF // This stored the texture info
-OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
-
-#>------ sub defines of MATERIAL
-#------ sub defines of MATERIAL_BLOCK
-MAT_NAME = long('0xA000',16) # This holds the material name
-MAT_AMBIENT = long('0xA010',16) # Ambient color of the object/material
-MAT_DIFFUSE = long('0xA020',16) # This holds the color of the object/material
-MAT_SPECULAR = long('0xA030',16) # SPecular color of the object/material
-MAT_SHINESS = long('0xA040',16) # ??
-MAT_TRANSPARENCY= long('0xA050',16) # Transparency value of material
-MAT_SELF_ILLUM = long('0xA080',16) # Self Illumination value of material
-MAT_WIRE = long('0xA085',16) # Only render's wireframe
-
-MAT_TEXTURE_MAP = long('0xA200',16) # This is a header for a new texture map
-MAT_SPECULAR_MAP= long('0xA204',16) # This is a header for a new specular map
-MAT_OPACITY_MAP = long('0xA210',16) # This is a header for a new opacity map
-MAT_REFLECTION_MAP= long('0xA220',16) # This is a header for a new reflection map
-MAT_BUMP_MAP = long('0xA230',16) # This is a header for a new bump map
-MAT_MAP_FILENAME = long('0xA300',16) # This holds the file name of the texture
-
-MAT_FLOAT_COLOR = long ('0x0010', 16) #color defined as 3 floats
-MAT_24BIT_COLOR = long ('0x0011', 16) #color defined as 3 bytes
-
-#>------ sub defines of OBJECT
-OBJECT_MESH = long('0x4100',16); # This lets us know that we are reading a new object
-OBJECT_LAMP = long('0x4600',16); # This lets un know we are reading a light object
-OBJECT_LAMP_SPOT = long('0x4610',16); # The light is a spotloght.
-OBJECT_LAMP_OFF = long('0x4620',16); # The light off.
-OBJECT_LAMP_ATTENUATE = long('0x4625',16);
-OBJECT_LAMP_RAYSHADE = long('0x4627',16);
-OBJECT_LAMP_SHADOWED = long('0x4630',16);
-OBJECT_LAMP_LOCAL_SHADOW = long('0x4640',16);
-OBJECT_LAMP_LOCAL_SHADOW2 = long('0x4641',16);
-OBJECT_LAMP_SEE_CONE = long('0x4650',16);
-OBJECT_LAMP_SPOT_RECTANGULAR= long('0x4651',16);
-OBJECT_LAMP_SPOT_OVERSHOOT= long('0x4652',16);
-OBJECT_LAMP_SPOT_PROJECTOR= long('0x4653',16);
-OBJECT_LAMP_EXCLUDE= long('0x4654',16);
-OBJECT_LAMP_RANGE= long('0x4655',16);
-OBJECT_LAMP_ROLL= long('0x4656',16);
-OBJECT_LAMP_SPOT_ASPECT= long('0x4657',16);
-OBJECT_LAMP_RAY_BIAS= long('0x4658',16);
-OBJECT_LAMP_INNER_RANGE= long('0x4659',16);
-OBJECT_LAMP_OUTER_RANGE= long('0x465A',16);
-OBJECT_LAMP_MULTIPLIER = long('0x465B',16);
-OBJECT_LAMP_AMBIENT_LIGHT = long('0x4680',16);
-
-
-
-OBJECT_CAMERA= long('0x4700',16); # This lets un know we are reading a camera object
-
-#>------ sub defines of CAMERA
-OBJECT_CAM_RANGES= long('0x4720',16); # The camera range values
-
-#>------ sub defines of OBJECT_MESH
-OBJECT_VERTICES = long('0x4110',16); # The objects vertices
-OBJECT_FACES = long('0x4120',16); # The objects faces
-OBJECT_MATERIAL = long('0x4130',16); # This is found if the object has a material, either texture map or color
-OBJECT_UV = long('0x4140',16); # The UV texture coordinates
-OBJECT_TRANS_MATRIX = long('0x4160',16); # The Object Matrix
-
-global scn
-scn= None
-
-#the chunk class
-class chunk:
- ID=0
- length=0
- bytes_read=0
-
- #we don't read in the bytes_read, we compute that
- binary_format='<HI'
-
- def __init__(self):
- self.ID=0
- self.length=0
- self.bytes_read=0
-
- def dump(self):
- print 'ID: ', self.ID
- print 'ID in hex: ', hex(self.ID)
- print 'length: ', self.length
- print 'bytes_read: ', self.bytes_read
-
-def read_chunk(file, chunk):
- temp_data=file.read(calcsize(chunk.binary_format))
- data=unpack(chunk.binary_format, temp_data)
- chunk.ID=data[0]
- chunk.length=data[1]
- #update the bytes read function
- chunk.bytes_read=6
-
- #if debugging
- #chunk.dump()
-
-def read_string(file):
- #read in the characters till we get a null character
- s=''
- while not s.endswith('\x00'):
- s+=unpack( '<c', file.read(1) )[0]
- #print 'string: ',s
-
- #remove the null character from the string
- return s[:-1]
-
-######################################################
-# IMPORT
-######################################################
-def process_next_object_chunk(file, previous_chunk):
- new_chunk=chunk()
- temp_chunk=chunk()
-
- while (previous_chunk.bytes_read<previous_chunk.length):
- #read the next chunk
- read_chunk(file, new_chunk)
-
-def skip_to_end(file, skip_chunk):
- buffer_size=skip_chunk.length-skip_chunk.bytes_read
- binary_format='%ic' % buffer_size
- temp_data=file.read(calcsize(binary_format))
- skip_chunk.bytes_read+=buffer_size
-
-
-def add_texture_to_material(image, texture, material, mapto):
- if mapto=='DIFFUSE':
- map=Texture.MapTo.COL
- elif mapto=='SPECULAR':
- map=Texture.MapTo.SPEC
- elif mapto=='OPACITY':
- map=Texture.MapTo.ALPHA
- elif mapto=='BUMP':
- map=Texture.MapTo.NOR
- else:
- print '/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name)
- map=Texture.MapTo.COL
-
- if image: texture.setImage(image) # double check its an image.
- free_tex_slots= [i for i, tex in enumerate( material.getTextures() ) if tex==None]
- if not free_tex_slots:
- print '/tError: Cannot add "%s" map. 10 Texture slots alredy used.' % mapto
- else:
- material.setTexture(free_tex_slots[0],texture,Texture.TexCo.UV,map)
-
-
-def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
- #print previous_chunk.bytes_read, 'BYTES READ'
- contextObName= None
- contextLamp= [None, None] # object, Data
- contextMaterial= None
- contextMatrix_rot= None # Blender.Mathutils.Matrix(); contextMatrix.identity()
- #contextMatrix_tx= None # Blender.Mathutils.Matrix(); contextMatrix.identity()
- contextMesh_vertls= None
- contextMesh_facels= None
- contextMeshMaterials= {} # matname:[face_idxs]
- contextMeshUV= None
-
- TEXTURE_DICT={}
- MATDICT={}
- TEXMODE= Mesh.FaceModes['TEX']
-
- # Localspace variable names, faster.
- STRUCT_SIZE_1CHAR= calcsize('c')
- STRUCT_SIZE_2FLOAT= calcsize('2f')
- STRUCT_SIZE_3FLOAT= calcsize('3f')
- STRUCT_SIZE_UNSIGNED_SHORT= calcsize('H')
- STRUCT_SIZE_4UNSIGNED_SHORT= calcsize('4H')
- STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff')
- _STRUCT_SIZE_4x3MAT= calcsize('fffffffffffff')
- # STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff')
- # print STRUCT_SIZE_4x3MAT, ' STRUCT_SIZE_4x3MAT'
-
- def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
-
- materialFaces= set() # faces that have a material. Can optimize?
-
- # Now make copies with assigned materils.
-
- def makeMeshMaterialCopy(matName, faces):
- '''
- Make a new mesh with only face the faces that use this material.
- faces can be any iterable object - containing ints.
- '''
-
- faceVertUsers = [False] * len(myContextMesh_vertls)
- ok=0
- for fIdx in faces:
- for vindex in myContextMesh_facels[fIdx]:
- faceVertUsers[vindex] = True
- if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces.
- materialFaces.add(fIdx)
- ok=1
-
- if not ok:
- return
-
- myVertMapping = {}
- vertMappingIndex = 0
-
- vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]]
- myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
-
- tempName= '%s_%s' % (contextObName, matName) # matName may be None.
- bmesh = bpy.data.meshes.new(tempName)
-
- if matName == None:
- img= None
- else:
- bmat = MATDICT[matName][1]
- bmesh.materials= [bmat]
- try: img= TEXTURE_DICT[bmat.name]
- except: img= None
-
- bmesh_verts = bmesh.verts
- bmesh_verts.extend( [Vector()] )
- bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
- # +1 because of DUMMYVERT
- face_mapping= bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
-
- if bmesh.faces and (contextMeshUV or img):
- bmesh.faceUV= 1
- for ii, i in enumerate(faces):
-
- # Mapped index- faces may have not been added- if so, then map to the correct index
- # BUGGY API - face_mapping is not always the right length
- map_index= face_mapping[ii]
-
- if map_index != None:
- targetFace= bmesh.faces[map_index]
- if contextMeshUV:
- # v.index-1 because of the DUMMYVERT
- targetFace.uv= [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
- if img:
- targetFace.image= img
-
- # bmesh.transform(contextMatrix)
- ob = SCN_OBJECTS.new(bmesh, tempName)
- '''
- if contextMatrix_tx:
- ob.setMatrix(contextMatrix_tx)
- '''
-
- if contextMatrix_rot:
- ob.setMatrix(contextMatrix_rot)
-
- importedObjects.append(ob)
- bmesh.calcNormals()
-
- for matName, faces in myContextMeshMaterials.iteritems():
- makeMeshMaterialCopy(matName, faces)
-
- if len(materialFaces)!=len(myContextMesh_facels):
- # Invert material faces.
- makeMeshMaterialCopy(None, set(range(len( myContextMesh_facels ))) - materialFaces)
- #raise 'Some UnMaterialed faces', len(contextMesh.faces)
-
- #a spare chunk
- new_chunk= chunk()
- temp_chunk= chunk()
-
- CreateBlenderObject = False
-
- #loop through all the data for this chunk (previous chunk) and see what it is
- while (previous_chunk.bytes_read<previous_chunk.length):
- #print '\t', previous_chunk.bytes_read, 'keep going'
- #read the next chunk
- #print 'reading a chunk'
- read_chunk(file, new_chunk)
-
- #is it a Version chunk?
- if (new_chunk.ID==VERSION):
- #print 'if (new_chunk.ID==VERSION):'
- #print 'found a VERSION chunk'
- #read in the version of the file
- #it's an unsigned short (H)
- temp_data= file.read(calcsize('I'))
- version = unpack('<I', temp_data)[0]
- new_chunk.bytes_read+= 4 #read the 4 bytes for the version number
- #this loader works with version 3 and below, but may not with 4 and above
- if (version>3):
- print '\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version
-
- #is it an object info chunk?
- elif (new_chunk.ID==OBJECTINFO):
- #print 'elif (new_chunk.ID==OBJECTINFO):'
- # print 'found an OBJECTINFO chunk'
- process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH)
-
- #keep track of how much we read in the main chunk
- new_chunk.bytes_read+=temp_chunk.bytes_read
-
- #is it an object chunk?
- elif (new_chunk.ID==OBJECT):
-
- if CreateBlenderObject:
- putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
- contextMesh_vertls= []; contextMesh_facels= []
-
- ## preparando para receber o proximo objeto
- contextMeshMaterials= {} # matname:[face_idxs]
- contextMeshUV= None
- #contextMesh.vertexUV= 1 # Make sticky coords.
- # Reset matrix
- contextMatrix_rot= None
- #contextMatrix_tx= None
-
- CreateBlenderObject= True
- tempName= read_string(file)
- contextObName= tempName
- new_chunk.bytes_read += len(tempName)+1
-
- #is it a material chunk?
- elif (new_chunk.ID==MATERIAL):
- #print 'elif (new_chunk.ID==MATERIAL):'
- contextMaterial= bpy.data.materials.new('Material')
-
- elif (new_chunk.ID==MAT_NAME):
- #print 'elif (new_chunk.ID==MAT_NAME):'
- material_name= read_string(file)
-
- #plus one for the null character that ended the string
- new_chunk.bytes_read+= len(material_name)+1
-
- contextMaterial.name= material_name.rstrip() # remove trailing whitespace
- MATDICT[material_name]= (contextMaterial.name, contextMaterial)
-
- elif (new_chunk.ID==MAT_AMBIENT):
- #print 'elif (new_chunk.ID==MAT_AMBIENT):'
- read_chunk(file, temp_chunk)
- if (temp_chunk.ID==MAT_FLOAT_COLOR):
- temp_data=file.read(calcsize('3f'))
- temp_chunk.bytes_read+=12
- contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)]
- elif (temp_chunk.ID==MAT_24BIT_COLOR):
- temp_data=file.read(calcsize('3B'))
- temp_chunk.bytes_read+= 3
- contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
- else:
- skip_to_end(file, temp_chunk)
- new_chunk.bytes_read+= temp_chunk.bytes_read
-
- elif (new_chunk.ID==MAT_DIFFUSE):
- #print 'elif (new_chunk.ID==MAT_DIFFUSE):'
- read_chunk(file, temp_chunk)
- if (temp_chunk.ID==MAT_FLOAT_COLOR):
- temp_data=file.read(calcsize('3f'))
- temp_chunk.bytes_read+=12
- contextMaterial.rgbCol=[float(col) for col in unpack('<3f', temp_data)]
- elif (temp_chunk.ID==MAT_24BIT_COLOR):
- temp_data=file.read(calcsize('3B'))
- temp_chunk.bytes_read+= 3
- contextMaterial.rgbCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
- else:
- skip_to_end(file, temp_chunk)
- new_chunk.bytes_read+= temp_chunk.bytes_read
-
- elif (new_chunk.ID==MAT_SPECULAR):
- #print 'elif (new_chunk.ID==MAT_SPECULAR):'
- read_chunk(file, temp_chunk)
- if (temp_chunk.ID==MAT_FLOAT_COLOR):
- temp_data=file.read(calcsize('3f'))
- temp_chunk.bytes_read+=12
- contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)]
- elif (temp_chunk.ID==MAT_24BIT_COLOR):
- temp_data=file.read(calcsize('3B'))
- temp_chunk.bytes_read+= 3
- contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
- else:
- skip_to_end(file, temp_chunk)
- new_chunk.bytes_read+= temp_chunk.bytes_read
-
- elif (new_chunk.ID==MAT_TEXTURE_MAP):
- #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):'
- new_texture= bpy.data.textures.new('Diffuse')
- new_texture.setType('Image')
- img = None
- while (new_chunk.bytes_read<new_chunk.length):
- #print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
- read_chunk(file, temp_chunk)
-
- if (temp_chunk.ID==MAT_MAP_FILENAME):
- texture_name=read_string(file)
- #img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
- img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
- new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
-
- else:
- skip_to_end(file, temp_chunk)
-
- new_chunk.bytes_read+= temp_chunk.bytes_read
-
- #add the map to the material in the right channel
- if img:
- add_texture_to_material(img, new_texture, contextMaterial, 'DIFFUSE')
-
- elif (new_chunk.ID==MAT_SPECULAR_MAP):
- #print 'elif (new_chunk.ID==MAT_SPECULAR_MAP):'
- new_texture= bpy.data.textures.new('Specular')
- new_texture.setType('Image')
- img = None
- while (new_chunk.bytes_read<new_chunk.length):
- read_chunk(file, temp_chunk)
-
- if (temp_chunk.ID==MAT_MAP_FILENAME):
- texture_name= read_string(file)
- #img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
- img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
- new_chunk.bytes_read+= (len(texture_name)+1) #plus one for the null character that gets removed
- else:
- skip_to_end(file, temp_chunk)
-
- new_chunk.bytes_read+= temp_chunk.bytes_read
-
- #add the map to the material in the right channel
- if img:
- add_texture_to_material(img, new_texture, contextMaterial, 'SPECULAR')
-
- elif (new_chunk.ID==MAT_OPACITY_MAP):
- #print 'new_texture=Blender.Texture.New('Opacity')'
- new_texture= bpy.data.textures.new('Opacity')
- new_texture.setType('Image')
- img = None
- while (new_chunk.bytes_read<new_chunk.length):
- read_chunk(file, temp_chunk)
-
- if (temp_chunk.ID==MAT_MAP_FILENAME):
- texture_name= read_string(file)
- #img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
- img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
- new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
- else:
- skip_to_end(file, temp_chunk)
-
- new_chunk.bytes_read+= temp_chunk.bytes_read
- #add the map to the material in the right channel
- if img:
- add_texture_to_material(img, new_texture, contextMaterial, 'OPACITY')
-
- elif (new_chunk.ID==MAT_BUMP_MAP):
- #print 'elif (new_chunk.ID==MAT_BUMP_MAP):'
- new_texture= bpy.data.textures.new('Bump')
- new_texture.setType('Image')
- img = None
- while (new_chunk.bytes_read<new_chunk.length):
- read_chunk(file, temp_chunk)
-
- if (temp_chunk.ID==MAT_MAP_FILENAME):
- texture_name= read_string(file)
- #img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
- img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
- new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
- else:
- skip_to_end(file, temp_chunk)
-
- new_chunk.bytes_read+=temp_chunk.bytes_read
-
- #add the map to the material in the right channel
- if img:
- add_texture_to_material(img, new_texture, contextMaterial, 'BUMP')
-
- elif (new_chunk.ID==MAT_TRANSPARENCY):
- #print 'elif (new_chunk.ID==MAT_TRANSPARENCY):'
- read_chunk(file, temp_chunk)
- temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
-
- temp_chunk.bytes_read+=2
- contextMaterial.alpha= 1-(float(unpack('<H', temp_data)[0])/100)
- new_chunk.bytes_read+=temp_chunk.bytes_read
-
-
- elif (new_chunk.ID==OBJECT_LAMP): # Basic lamp support.
-
- temp_data=file.read(STRUCT_SIZE_3FLOAT)
-
- x,y,z=unpack('<3f', temp_data)
- new_chunk.bytes_read+=STRUCT_SIZE_3FLOAT
-
- contextLamp[1]= bpy.data.lamps.new()
- contextLamp[0]= SCN_OBJECTS.new(contextLamp[1])
- importedObjects.append(contextLamp[0])
-
- #print 'number of faces: ', num_faces
- #print x,y,z
- contextLamp[0].setLocation(x,y,z)
-
- # Reset matrix
- contextMatrix_rot= None
- #contextMatrix_tx= None
- #print contextLamp.name,
-
- elif (new_chunk.ID==OBJECT_MESH):
- # print 'Found an OBJECT_MESH chunk'
- pass
- elif (new_chunk.ID==OBJECT_VERTICES):
- '''
- Worldspace vertex locations
- '''
- # print 'elif (new_chunk.ID==OBJECT_VERTICES):'
- temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
- num_verts=unpack('<H', temp_data)[0]
- new_chunk.bytes_read+=2
-
- # print 'number of verts: ', num_verts
- def getvert():
- temp_data= unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
- new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
- return temp_data
-
- #contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed.
- contextMesh_vertls= [getvert() for i in xrange(num_verts)]
-
- #print 'object verts: bytes read: ', new_chunk.bytes_read
-
- elif (new_chunk.ID==OBJECT_FACES):
- # print 'elif (new_chunk.ID==OBJECT_FACES):'
- temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
- num_faces= unpack('<H', temp_data)[0]
- new_chunk.bytes_read+= 2
- #print 'number of faces: ', num_faces
-
- def getface():
- # print '\ngetting a face'
- temp_data= file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
- new_chunk.bytes_read+= STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
- v1,v2,v3,dummy= unpack('<4H', temp_data)
- return v1, v2, v3
-
- contextMesh_facels= [ getface() for i in xrange(num_faces) ]
-
-
- elif (new_chunk.ID==OBJECT_MATERIAL):
- # print 'elif (new_chunk.ID==OBJECT_MATERIAL):'
- material_name= read_string(file)
- new_chunk.bytes_read += len(material_name)+1 # remove 1 null character.
-
- temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
- num_faces_using_mat = unpack('<H', temp_data)[0]
- new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
-
- def getmat():
- temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
- new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT
- return unpack('<H', temp_data)[0]
-
- contextMeshMaterials[material_name]= [ getmat() for i in xrange(num_faces_using_mat) ]
-
- #look up the material in all the materials
-
- elif (new_chunk.ID==OBJECT_UV):
- temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
- num_uv=unpack('<H', temp_data)[0]
- new_chunk.bytes_read+= 2
-
- def getuv():
- temp_data=file.read(STRUCT_SIZE_2FLOAT)
- new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
- return Vector( unpack('<2f', temp_data) )
-
- contextMeshUV= [ getuv() for i in xrange(num_uv) ]
-
- elif (new_chunk.ID== OBJECT_TRANS_MATRIX):
- # How do we know the matrix size? 54 == 4x4 48 == 4x3
- temp_data=file.read(STRUCT_SIZE_4x3MAT)
- data= list( unpack('<ffffffffffff', temp_data) )
- new_chunk.bytes_read += STRUCT_SIZE_4x3MAT
-
- contextMatrix_rot= Blender.Mathutils.Matrix(\
- data[:3] + [0],\
- data[3:6] + [0],\
- data[6:9] + [0],\
- data[9:] + [1])
-
-
- '''
- contextMatrix_rot= Blender.Mathutils.Matrix(\
- data[:3] + [0],\
- data[3:6] + [0],\
- data[6:9] + [0],\
- [0,0,0,1])
- '''
-
- '''
- contextMatrix_rot= Blender.Mathutils.Matrix(\
- data[:3] ,\
- data[3:6],\
- data[6:9])
- '''
-
- '''
- contextMatrix_rot = Blender.Mathutils.Matrix()
- m = 0
- for j in xrange(4):
- for i in xrange(3):
- contextMatrix_rot[j][i] = data[m]
- m+=1
-
- contextMatrix_rot[0][3]=0;
- contextMatrix_rot[1][3]=0;
- contextMatrix_rot[2][3]=0;
- contextMatrix_rot[3][3]=1;
- '''
-
- #contextMatrix_rot.resize4x4()
- #print "MTX"
- #print contextMatrix_rot
- contextMatrix_rot.invert()
- #print contextMatrix_rot
- #contextMatrix_tx = Blender.Mathutils.TranslationMatrix(0.5 * Blender.Mathutils.Vector(data[9:]))
- #contextMatrix_tx.invert()
-
- #tx.invert()
-
- #contextMatrix = contextMatrix * tx
- #contextMatrix = contextMatrix *tx
-
- elif (new_chunk.ID==MAT_MAP_FILENAME):
- texture_name=read_string(file)
- try:
- TEXTURE_DICT[contextMaterial.name]
- except:
- #img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
- img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
-
- new_chunk.bytes_read+= len(texture_name)+1 #plus one for the null character that gets removed
-
- else: #(new_chunk.ID!=VERSION or new_chunk.ID!=OBJECTINFO or new_chunk.ID!=OBJECT or new_chunk.ID!=MATERIAL):
- # print 'skipping to end of this chunk'
- buffer_size=new_chunk.length-new_chunk.bytes_read
- binary_format='%ic' % buffer_size
- temp_data=file.read(calcsize(binary_format))
- new_chunk.bytes_read+=buffer_size
-
-
- #update the previous chunk bytes read
- # print 'previous_chunk.bytes_read += new_chunk.bytes_read'
- # print previous_chunk.bytes_read, new_chunk.bytes_read
- previous_chunk.bytes_read += new_chunk.bytes_read
- ## print 'Bytes left in this chunk: ', previous_chunk.length-previous_chunk.bytes_read
-
- # FINISHED LOOP
- # There will be a number of objects still not added
- if contextMesh_facels != None:
- putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
-
-def load_3ds(filename, PREF_UI= True):
- global FILENAME, SCN_OBJECTS
-
- if BPyMessages.Error_NoFile(filename):
- return
-
- print '\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename))
-
- time1= Blender.sys.time()
-
- FILENAME=filename
- current_chunk=chunk()
-
- file=open(filename,'rb')
-
- #here we go!
- # print 'reading the first chunk'
- read_chunk(file, current_chunk)
- if (current_chunk.ID!=PRIMARY):
- print '\tFatal Error: Not a valid 3ds file: ', filename
- file.close()
- return
-
-
- # IMPORT_AS_INSTANCE= Blender.Draw.Create(0)
- IMPORT_CONSTRAIN_BOUNDS= Blender.Draw.Create(10.0)
- IMAGE_SEARCH= Blender.Draw.Create(1)
- APPLY_MATRIX= Blender.Draw.Create(0)
-
- # Get USER Options
- pup_block= [\
- ('Size Constraint:', IMPORT_CONSTRAIN_BOUNDS, 0.0, 1000.0, 'Scale the model by 10 until it reacehs the size constraint. Zero Disables.'),\
- ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\
- ('Transform Fix', APPLY_MATRIX, 'Workaround for object transformations importing incorrectly'),\
- #('Group Instance', IMPORT_AS_INSTANCE, 'Import objects into a new scene and group, creating an instance in the current scene.'),\
- ]
-
- if PREF_UI:
- if not Blender.Draw.PupBlock('Import 3DS...', pup_block):
- return
-
- Blender.Window.WaitCursor(1)
-
- IMPORT_CONSTRAIN_BOUNDS= IMPORT_CONSTRAIN_BOUNDS.val
- # IMPORT_AS_INSTANCE= IMPORT_AS_INSTANCE.val
- IMAGE_SEARCH = IMAGE_SEARCH.val
- APPLY_MATRIX = APPLY_MATRIX.val
-
- if IMPORT_CONSTRAIN_BOUNDS:
- BOUNDS_3DS[:]= [1<<30, 1<<30, 1<<30, -1<<30, -1<<30, -1<<30]
- else:
- BOUNDS_3DS[:]= []
-
- ##IMAGE_SEARCH
-
- scn= bpy.data.scenes.active
- SCN_OBJECTS = scn.objects
- SCN_OBJECTS.selected = [] # de select all
-
- importedObjects= [] # Fill this list with objects
- process_next_chunk(file, current_chunk, importedObjects, IMAGE_SEARCH)
-
-
- # Link the objects into this scene.
- # Layers= scn.Layers
-
- # REMOVE DUMMYVERT, - remove this in the next release when blenders internal are fixed.
-
-
- for ob in importedObjects:
- if ob.type=='Mesh':
- me= ob.getData(mesh=1)
- me.verts.delete([me.verts[0],])
- if not APPLY_MATRIX:
- me.transform(ob.matrixWorld.copy().invert())
-
- # Done DUMMYVERT
- """
- if IMPORT_AS_INSTANCE:
- name= filename.split('\\')[-1].split('/')[-1]
- # Create a group for this import.
- group_scn= Scene.New(name)
- for ob in importedObjects:
- group_scn.link(ob) # dont worry about the layers
-
- grp= Blender.Group.New(name)
- grp.objects= importedObjects
-
- grp_ob= Object.New('Empty', name)
- grp_ob.enableDupGroup= True
- grp_ob.DupGroup= grp
- scn.link(grp_ob)
- grp_ob.Layers= Layers
- grp_ob.sel= 1
- else:
- # Select all imported objects.
- for ob in importedObjects:
- scn.link(ob)
- ob.Layers= Layers
- ob.sel= 1
- """
-
- if IMPORT_CONSTRAIN_BOUNDS!=0.0:
- # Set bounds from objecyt bounding box
- for ob in importedObjects:
- if ob.type=='Mesh':
- ob.makeDisplayList() # Why dosnt this update the bounds?
- for v in ob.getBoundBox():
- for i in (0,1,2):
- if v[i] < BOUNDS_3DS[i]:
- BOUNDS_3DS[i]= v[i] # min
-
- if v[i] > BOUNDS_3DS[i+3]:
- BOUNDS_3DS[i+3]= v[i] # min
-
- # Get the max axis x/y/z
- max_axis= max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2])
- # print max_axis
- if max_axis < 1<<30: # Should never be false but just make sure.
-
- # Get a new scale factor if set as an option
- SCALE=1.0
- while (max_axis*SCALE) > IMPORT_CONSTRAIN_BOUNDS:
- SCALE/=10
-
- # SCALE Matrix
- SCALE_MAT= Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1])
-
- for ob in importedObjects:
- ob.setMatrix(ob.matrixWorld*SCALE_MAT)
-
- # Done constraining to bounds.
-
- # Select all new objects.
- print 'finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1))
- file.close()
- Blender.Window.WaitCursor(0)
-
-
-DEBUG= False
-if __name__=='__main__' and not DEBUG:
- if calcsize==None:
- Blender.Draw.PupMenu('Error%t|a full python installation not found')
- else:
- Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds')
-
-# For testing compatibility
-#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False)
-#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False)
-'''
-
-else:
- import os
- # DEBUG ONLY
- TIME= Blender.sys.time()
- import os
- print 'Searching for files'
- os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list')
- # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list')
- print '...Done'
- file= open('/tmp/temp3ds_list', 'r')
- lines= file.readlines()
- file.close()
- # sort by filesize for faster testing
- lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
- lines_size.sort()
- lines = [f[1] for f in lines_size]
-
-
- def between(v,a,b):
- if v <= max(a,b) and v >= min(a,b):
- return True
- return False
-
- for i, _3ds in enumerate(lines):
- if between(i, 650,800):
- #_3ds= _3ds[:-1]
- print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines)
- _3ds_file= _3ds.split('/')[-1].split('\\')[-1]
- newScn= Blender.Scene.New(_3ds_file)
- newScn.makeCurrent()
- load_3ds(_3ds, False)
-
- print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
-
-'''
diff --git a/release/scripts/Axiscopy.py b/release/scripts/Axiscopy.py
deleted file mode 100644
index 6a31432edb6..00000000000
--- a/release/scripts/Axiscopy.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Axis Orientation Copy'
-Blender: 242
-Group: 'Object'
-Tip: 'Copy local axis orientation of active object to all selected meshes (changes mesh data)'
-"""
-
-__author__ = "A Vanpoucke (xand)"
-__url__ = ("blenderartists.org", "www.blender.org",
-"French Blender support forum, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "2 17/12/05"
-
-__bpydoc__ = """\
-This script copies the axis orientation -- X, Y and Z rotations -- of the
-active object to all selected meshes.
-
-It's useful to align the orientations of all meshes of a structure, a human
-skeleton, for example.
-
-Usage:
-
-Select all mesh objects that need to have their orientations changed
-(reminder: keep SHIFT pressed after the first, to add each new one to the
-selection), then select the object whose orientation will be copied from and
-finally run this script to update the angles.
-
-Notes:<br>
- This script changes mesh data: the vertices are transformed.<br>
- Before copying the orientation to each object, the script stores its
-transformation matrix. Then the angles are copied and after that the object's
-vertices are transformed "back" so that they still have the same positions as
-before. In other words, the rotations are updated, but you won't notice that
-just from looking at the objects.<br>
- Checking their X, Y and Z rotation values with "Transform Properties" in
-the 3D View's Object menu shows the angles are now the same of the active
-object. Or simply look at the transform manipulator handles in local transform
-orientation.
-"""
-
-
-# $Id$
-#
-#----------------------------------------------
-# A Vanpoucke (xand)
-#from the previous script realignaxis
-#----------------------------------------------
-# Communiquer les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2003, 2004: A Vanpoucke
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import *
-from Blender import Mathutils
-from Blender.Mathutils import *
-import BPyMessages
-
-def realusers(data):
- users = data.users
- if data.fakeUser: users -= 1
- return users
-
-
-
-def main():
-
- scn_obs= Scene.GetCurrent().objects
- ob_act = scn_obs.active
- scn_obs = scn_obs.context
-
- if not ob_act:
- BPyMessages.Error_NoActive()
-
- obs = [(ob, ob.getData(mesh=1)) for ob in scn_obs if ob != ob_act]
-
- for ob, me in obs:
-
- if ob.type != 'Mesh':
- Draw.PupMenu("Error%t|Selection must be made up of mesh objects only")
- return
-
- if realusers(me) != 1:
- Draw.PupMenu("Error%t|Meshes must be single user")
- return
-
- if len(obs) < 1:
- Draw.PupMenu("Error: you must select at least 2 objects")
- return
-
- result = Draw.PupMenu("Copy axis orientation from: " + ob_act.name + " ?%t|OK")
- if result == -1:
- return
-
- for ob_target, me_target in obs:
- if ob_act.rot != ob_target.rot:
- rot_target = ob_target.matrixWorld.rotationPart().toEuler().toMatrix()
- rot_source = ob_act.matrixWorld.rotationPart().toEuler().toMatrix()
- rot_source_inv = rot_source.copy().invert()
- tx_mat = rot_target * rot_source_inv
- tx_mat.resize4x4()
- me_target.transform(tx_mat)
- ob_target.rot=ob_act.rot
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py
deleted file mode 100644
index 8a0ecaf0eb7..00000000000
--- a/release/scripts/DirectX8Exporter.py
+++ /dev/null
@@ -1,1196 +0,0 @@
-#!BPY
-
-"""
-# Name: 'DirectX (.x)...'
-# Blender: 242
-# Group: 'Export'
-# Tooltip: 'Export to DirectX text file format format for XNA Animation Component Library.'
-"""
-__author__ = "vertex color exporting feature is added by mnemoto (original:minahito (original:Arben (Ben) Omari))"
-__url__ = ("blender.org", "blenderartists.org", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it","Adjuster's site http://ex.homeunix.net/")
-__version__ = "3.1"
-
-__bpydoc__ = """\
-This script exports a Blender mesh with armature to DirectX 8's text file
-format.
-
-Notes:<br>
- Check author's site or the elYsiun forum for a new beta version of the
-DX exporter.
-"""
-# DirectXExporter.py version 3.0
-# Copyright (C) 2006 Arben OMARI -- omariarben@everyday.com
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# This script export meshes created with Blender in DirectX8 file format
-# it exports meshes,armatures,materials,normals,texturecoords and animations
-
-# Grab the latest version here :www.omariben.too.it
-
-# [Notice]
-# This script is the custom version of Mr.Arben Omari's great work.
-# If you have a question about the adjusted part, visit http://sunday-lab.blogspot.com/.
-
-import Blender
-from Blender import Types, Object, NMesh, Material,Armature,Mesh
-from Blender.Mathutils import *
-from Blender import Draw, BGL
-from Blender.BGL import *
-try: import math
-except: math = None
-
-global mat_flip,index_list,space,bone_list,mat_dict
-global anim,flip_norm,swap_zy,flip_z,speed,ticks,no_light,recalc_norm,Bl_norm
-bone_list =[]
-index_list = []
-mat_dict = {}
-space = 0;flip_z = 1;anim=0;swap_yz=0;flip_norm=0;speed=0;ticks= 25
-Bl_norm = 1;recalc_norm = 0;no_light = 0
-
-toggle_val = 0
-toggle1_val = 0
-toggle2_val = 0
-toggle3_val = 1
-toggle4_val = 0
-toggle5_val = 1
-toggle6_val = 0
-toggle7_val = 0
-anim_tick = Draw.Create(25)
-
-#***********************************************
-# DirectX file spec only allows letters, digits, and
-# underscore in Names.
-#***********************************************
-def make_legal_name(starting_name):
- new_name = starting_name.replace('.','_')
- new_name = new_name.replace(' ','_')
- if new_name[0].isdigit():
- new_name = '_' + new_name
- return new_name
-
-#***********************************************
-# MAIN
-#***********************************************
-
-def my_callback(filename):
- if filename.find('.x', -2) <= 0: filename += '.x'
- xexport = xExport(filename)
- xexport.SelectObjs()
-
-def my_callback_sel(filename):
- if filename.find('.x', -2) <= 0: filename += '.x'
- xexport = xExport(filename)
- xexport.exportSelMesh()
-def event(evt, val):
- if evt == Draw.ESCKEY:
- Draw.Exit()
- return
-
-def button_event(evt):
- global toggle_val,toggle1_val,toggle2_val,toggle3_val,toggle4_val,toggle5_val,toggle6_val,toggle7_val
- global flip_z,swap_yz,flip_norm,anim,ticks,speed,no_light,Bl_norm,recalc_norm
- arg = __script__['arg']
- if evt == 1:
- toggle_val = 1 - toggle_val
- anim = toggle_val
- Draw.Redraw(1)
- if evt == 2:
- toggle1_val = 1 - toggle1_val
- flip_norm = toggle1_val
- Draw.Redraw(1)
- if evt == 3:
- toggle2_val = 1 - toggle2_val
- swap_yz = toggle2_val
- Draw.Redraw(1)
- if evt == 4:
- toggle3_val = 1 - toggle3_val
- flip_z = toggle3_val
- Draw.Redraw(1)
- if evt == 5:
- toggle4_val = 1 - toggle4_val
- speed = toggle4_val
- Draw.Redraw(1)
- if evt == 10:
- toggle5_val = 1 - toggle5_val
- if toggle5_val==1:
- toggle6_val = 0
- toggle7_val = 0
- else :
- toggle6_val = 1
- toggle7_val = 1
- no_light = toggle7_val
- recalc_norm = toggle6_val
- Bl_norm = toggle5_val
- Draw.Redraw(1)
- if evt == 11:
- toggle6_val = 1 - toggle6_val
- if toggle6_val==1:
- toggle5_val = 0
- toggle7_val = 0
- else :
- toggle5_val = 1
- toggle7_val = 1
- no_light = toggle7_val
- recalc_norm = toggle6_val
- Bl_norm = toggle5_val
- Draw.Redraw(1)
- if evt == 12:
- toggle7_val = 1 - toggle7_val
- if toggle7_val==1:
- toggle6_val = 0
- toggle5_val = 0
- else :
- toggle6_val = 1
- toggle5_val = 1
- no_light = toggle7_val
- recalc_norm = toggle6_val
- Bl_norm = toggle5_val
- Draw.Redraw(1)
- if evt == 6:
- ticks = anim_tick.val
- if evt == 7:
- fname = Blender.sys.makename(ext = ".x")
- Blender.Window.FileSelector(my_callback, "Export DirectX", fname)
- if evt == 8:
- fname = Blender.sys.makename(ext = ".x")
- Blender.Window.FileSelector(my_callback_sel, "Export DirectX", fname)
- if evt == 9:
- Draw.Exit()
-
-
-def draw():
- global animsg,flipmsg,swapmsg,anim_tick
- global flip_z,swap_yz,flip_norm,anim,ticks,speed,recalc_norm,Bl_norm,no_light
- glClearColor(0.55,0.6,0.6,1)
- glClear(BGL.GL_COLOR_BUFFER_BIT)
- #external box
- glColor3f(0.2,0.3,0.3)
- rect(10,402,300,382)
- #--
- #glColor3f(0.3,0.4,0.4)
- #rect(11,399,298,398)
- #--
- glColor3f(0.5,0.75,0.65)
- rect(14,398,292,30)
- #--
- glColor3f(0.5,0.75,0.65)
- rect(14,366,292,160)
- #--
- glColor3f(0.5,0.75,0.65)
- rect(14,202,292,60)
- #--
- glColor3f(0.5,0.75,0.65)
- rect(14,138,292,40)
- #--
- glColor3f(0.5,0.75,0.65)
- rect(14,94,292,70)
-
- glColor3f(0.8,.8,0.6)
- glRasterPos2i(20, 380)
- Draw.Text("DirectX Exporter ",'large')
- Draw.Text("(for Blender 2.41)", 'small')
- #-------Aniamtion toggle---------------------------------------------
- Draw.Toggle("Anim", 1, 20, 330, 55, 20, toggle_val,"export animations")
- if toggle_val :
- anim = 1
- animsg = "animation will be exported"
- else:
- anim = 0
- animsg = "animation will be not exported"
- glRasterPos2i(100,335)
- Draw.Text(animsg)
- #---Flip normals toggle-----------------------------------------------
- Draw.Toggle("Flip norm", 2, 20, 300, 55, 20, toggle1_val,"invert normals")
- if toggle1_val :
- flip_norm = 1
- flipmsg = "flipped normals"
- else:
- flip_norm = 0
- flipmsg = "not flipped normals"
- glRasterPos2i(100,305)
- Draw.Text(flipmsg)
- #------Swap yz toggle----------------------------------------------------------------
- Draw.Toggle("Swap zy", 3, 20, 270, 55, 20, toggle2_val,"swap z,y axis(y up)")
- if toggle2_val :
- swap_yz = 1
- swapmsg = "Y-axis up"
- else:
- swap_yz = 0
- swapmsg = "Z-axis up"
- glRasterPos2i(100,275)
- Draw.Text(swapmsg)
- #------Flip z toggle----------------------------------------------------------------
- Draw.Toggle("Flip z", 4, 20, 240, 55, 20, toggle3_val,"flip z axis")
- if toggle3_val :
- flip_z = 1
- zmsg = "left handed system"
- else:
- flip_z = 0
- zmsg = "right handed system"
- glRasterPos2i(100,245)
- Draw.Text(zmsg)
- #------Speed toggle----------------------------------------------------------------
- Draw.Toggle("Speed", 5, 20, 210, 55, 20, toggle4_val,"Animation speed")
- if toggle4_val :
- speed = 1
- spedmsg = "set speed"
- anim_tick = Draw.Number("", 6,200, 210, 85, 20, anim_tick.val,1,100000,"ticks per second")
- else:
- speed = 0
- spedmsg = ""
- glRasterPos2i(100,215)
- Draw.Text(spedmsg)
- #------Blender Normals toggle----------------------------------------------------------------
- Draw.Toggle("Bl.normals", 10, 20, 105, 75, 25, toggle5_val,"export normals as in Blender")
- if toggle5_val :
- Bl_norm = 1
- #------Recalculute Normals toggle----------------------------------------------------------------
- Draw.Toggle("recalc.no", 11, 120, 105, 75, 25, toggle6_val,"export recalculated normals")
- if toggle6_val :
- recalc_norm = 1
- #------Recalculute Normals toggle----------------------------------------------------------------
- Draw.Toggle("no smooth", 12, 220, 105, 75, 25, toggle7_val,"every vertex has the face normal,no smoothing")
- if toggle7_val :
- no_light = 1
- #------Draw Button export----------------------------------------------------------------
- exp_butt = Draw.Button("Export All",7,20, 155, 75, 30, "export all the scene objects")
- sel_butt = Draw.Button("Export Sel",8,120, 155, 75, 30, "export the selected object")
- exit_butt = Draw.Button("Exit",9,220, 155, 75, 30, "exit")
- glRasterPos2i(20,75)
- Draw.Text("(C) 2006 Arben OMARI ")
- glRasterPos2i(20,55)
- Draw.Text("http://www.omariben.too.it")
- glRasterPos2i(20,35)
- Draw.Text("aromar@tin.it")
-
-def rect(x,y,width,height):
- glBegin(GL_LINE_LOOP)
- glVertex2i(x,y)
- glVertex2i(x+width,y)
- glVertex2i(x+width,y-height)
- glVertex2i(x,y-height)
- glEnd()
-
-def rectFill(x,y,width,height):
- glBegin(GL_POLYGON)
- glVertex2i(x,y)
- glVertex2i(x+width,y)
- glVertex2i(x+width,y-height)
- glVertex2i(x,y-height)
- glEnd()
-
-
-
-Draw.Register(draw, event, button_event)
-
-
-#***********************************************
-#***********************************************
-# EXPORTER
-#***********************************************
-#***********************************************
-
-class xExport:
- def __init__(self, filename):
- self.file = open(filename, "w")
-
-#*********************************************************************************************************************************************
- #***********************************************
- #Select Scene objects
- #***********************************************
- def analyzeScene(self):
- parent_list = []
- for obj in Blender.Scene.GetCurrent().objects:
- if obj.type in ('Mesh', 'Armature', 'Empty'):
- if obj.parent == None :
- parent_list.append(obj)
-
- return parent_list
-
- def getChildren(self,obj):
- obs = Blender.Scene.GetCurrent().objects
- return [ ob for ob in obs if ob.parent == obj ]
-
- def getArmChildren(self,obj):
- for ob in Blender.Scene.GetCurrent().objects: #Object.Get():
- if ob.parent == obj :
- return ob
-
- def getLocMat(self, obj):
- pare = obj.parent
- mat = obj.matrixWorld
- mat_id = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
- if pare:
- mat_p = pare.matrixWorld
- mat_c = Matrix(mat_p)
- mat_c.invert()
- mat_f = mat * mat_c
- else :
- mat_id.invert()
- mat_f = mat * mat_id
- return mat_f
-
- def writeObjFrames(self,obj):
- global space,chld_obj,ch_list
- mesh = obj.getData()
- if obj.type == "Empty" :
- mat = self.getLocMat(obj)
- mat_c = Matrix(mat)
- self.writeArmFrames(mat_c, make_legal_name(obj.name))
- if type(mesh) == Types.ArmatureType :
- Child_obj = self.getArmChildren(obj)
- chld_obj = obj
- ch_list.append(Child_obj)
- self.writeRootBone(obj, Child_obj)
- if obj.type == 'Mesh' and obj not in ch_list:
- self.exportMesh(obj)
-
-
- def writeChildObj(self,obj):
- global space,ch_list
- space += 1
- if obj :
- for ob in obj:
- if ob not in ch_list:
- self.writeObjFrames(ob)
- ch_list.append(ob)
- ch_ob = self.getChildren(ob)
- self.writeChildObj(ch_ob)
- self.closeBrackets()
- self.file.write(" // End of the Object %s \n" % (ob.name))
-
-
- def writeRootFrame(self):
- global flip_z,swap_yz,speed
- if speed:
- self.writeAnimTicks()
- if flip_z:
- mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1])
- else :
- mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
- if swap_yz :
- mat_rot = RotationMatrix(-90, 4, 'x')
- mat_flip = mat_rot * mat_flip
- self.writeArmFrames(mat_flip, "RootFrame")
-
- ##################################################################
- def SelectObjs(self):
- global space,chld_obj,ch_list,flip_z,swap_yz,speed
- print "exporting..."
- self.writeHeader()
- self.writeRootFrame()
- obj_list = self.analyzeScene()
- space += 1
- ch_list = []
- for obj in obj_list:
- self.writeObjFrames(obj)
- ch_l = self.getChildren(obj)
- for ch in ch_l:
-
-
- if ch and ch.type == "Armature":
- ch_list.append(ch)
- self.writeObjFrames(ch)
- else :
- self.writeChildObj(ch_l)
- if obj.type != "Armature":
- self.file.write(" } // SI End of the Object %s \n" % (obj.name))
-
-
-
- self.file.write("} // End of the Root Frame\n")
- if anim :
- self.file.write("AnimationSet AnimationSet0 {\n")
- for obj in Blender.Scene.GetCurrent().objects:
- if obj.type in ('Mesh', 'Empty'):
- ip_list = obj.ipo
- if ip_list != None :
- self.writeAnimationObj(obj)
- elif obj.type == 'Armature':
- act_list = obj.getAction()
- if act_list != None :
- self.writeAnimation(obj)
- #ip_list = obj.ipo
- #if ip_list != None :
- # self.writeAnimationObj(obj)
-
- self.file.write("} // End of Animation Set\n")
- self.writeEnd()
- #######################################################
-
-
- def writeAnimTicks(self):
- global ticks
- self.file.write("AnimTicksPerSecond {\n")
- self.file.write("%d; \n" % (ticks))
- self.file.write("}\n")
-
- #***********************************************
- #Export Mesh without Armature
- #***********************************************
- def exportMesh(self, obj):
- tex = []
- mesh = obj.getData()
- self.writeTextures(obj, tex)
- self.writeMeshcoordArm(obj, arm_ob = None)
- self.writeMeshMaterialList(obj, mesh, tex)
- self.writeMeshNormals(obj, mesh)
- self.writeMeshTextureCoords(obj, mesh)
- self.writeMeshVertexColors(obj, mesh)
- self.file.write(" } // End of the Mesh %s \n" % (obj.name))
-
-
- #***********************************************
- #Export the Selected Mesh
- #***********************************************
- def exportSelMesh(self):
- print "exporting ..."
- self.writeHeader()
- self.writeRootFrame()
- tex = []
- objs = Object.GetSelected()
- for obj in objs:
- if obj.type == 'Mesh':
- mesh = obj.data
- self.writeTextures(obj, tex)
- self.writeMeshcoordArm(obj, arm_ob = None)
- self.writeMeshMaterialList(obj, mesh, tex)
- self.writeMeshNormals(obj, mesh)
- self.writeMeshTextureCoords(obj, mesh)
- self.writeMeshVertexColors(obj, mesh)
- self.file.write(" }\n")
- self.file.write("}\n")
- ind = objs.index(obj)
- if ind == len(objs)-1:
- self.file.write("}\n")
- ip_list = obj.ipo
- if ip_list != None :
- self.file.write("AnimationSet AnimationSet0 {\n")
- self.writeAnimationObj(obj)
- self.file.write("}\n")
- else :
- print "The selected object is not a mesh"
- print "...finished"
- #***********************************************
- #Export Mesh with Armature
- #***********************************************
- def exportMeshArm(self,arm,arm_ob,ch_obj):
- tex = []
- mesh = ch_obj.getData()
- self.writeTextures(ch_obj, tex)
- self.writeMeshcoordArm(ch_obj ,arm_ob)
- self.writeMeshMaterialList(ch_obj, mesh, tex)
- self.writeMeshNormals(ch_obj, mesh)
- self.writeMeshTextureCoords(ch_obj, mesh)
- self.writeSkinWeights(arm,mesh)
- #self.file.write(" } // End of the Frame %s \n" % (ch_obj.name))
- self.file.write(" } // End of the Object %s \n" % (ch_obj.name))
-
- #***********************************************
- #Export Root Bone
- #***********************************************
- def writeRootBone(self, chld_obj, child_obj):
- global space,root_bon
- arms = chld_obj.getData()
- mat_arm = self.getLocMat(chld_obj)
- for bon in arms.bones.values():
- if bon.hasParent():
- pass
- else:
- root_bon = bon
- space += 1
- mat_r = self.writeAnimCombineMatrix(root_bon,1)
- self.writeArmFrames(mat_r, make_legal_name(root_bon.name))
-
- bon_c = root_bon.children
- self.writeChildren(bon_c)
- self.file.write(" } // End of the Bone %s \n" % (root_bon.name))
- self.exportMeshArm(arms, chld_obj ,child_obj)
-
- #***********************************************
- #Create Children structure
- #***********************************************
- def writeBon(self,bon):
- global space
- mat_r = self.writeAnimCombineMatrix(bon,1)
- self.writeArmFrames(mat_r, make_legal_name(bon.name))
-
-
- def writeChildren(self,bon_c):
- global space,bone_list
- space += 1
- if bon_c:
- for bo in bon_c:
- if bo.name not in bone_list:
- self.writeBon(bo)
- bone_list.append(bo.name)
- bo_c = bo.children
- self.writeChildren(bo_c)
- self.closeBrackets()
-
-
-
- def closeBrackets(self):
- global space
- space = space-1
- tab = " "
- self.file.write("%s" % (tab * space))
- self.file.write("}\n")
-
-
-
- #***********************************************
- #Offset Matrix
- #***********************************************
- def writeMatrixOffset(self,bon):
- global chld_obj
- Blender.Set('curframe', 1)
- pose = chld_obj.getPose()
- pos_b = pose.bones[bon.name]
- mat_b = pos_b.poseMatrix
- mat_c = Matrix(mat_b)
- mat_c.invert()
- return mat_c
-
-
- #***********************************************
- #Combine Matrix
- #***********************************************
- def writeCombineMatrix(self,bon):
- global chld_obj
-
- Blender.Set('curframe', 1)
- pose = chld_obj.getPose()
- pos_b = pose.bones[bon.name]
- mat_b = pos_b.poseMatrix
- if bon.hasParent():
- pare = bon.parent
- pos_p = pose.bones[pare.name]
- mat_p = pos_p.poseMatrix
-
- else:
- mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
- mat_c = Matrix(mat_p)
- mat_c.invert()
- mat_f = mat_b * mat_c
-
- return mat_f
- #***********************************************
- #Combine Matrix
- #***********************************************
- def writeAnimCombineMatrix(self,bon,fre):
- global chld_obj
- Blender.Set('curframe', fre)
- pose = chld_obj.getPose()
- pos_b = pose.bones[bon.name]
- mat_b = pos_b.poseMatrix
- if bon.hasParent():
- pare = bon.parent
- pos_p = pose.bones[pare.name]
- mat_p = pos_p.poseMatrix
-
- else:
- mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
- mat_c = Matrix(mat_p)
- mat_c.invert()
- mat_f = mat_b * mat_c
-
- return mat_f
-
-
-#*********************************************************************************************************************************************
- #***********************************************
- #Write SkinWeights
- #***********************************************
- def writeSkinWeights(self, arm, mesh):
- global index_list
- v_dict = {}
- Blender.Set('curframe',1)
- self.file.write(" XSkinMeshHeader {\n")
- max_infl = 0
- for bo in arm.bones.values() :
- name = bo.name
- try :
- vertx_list = mesh.getVertsFromGroup(name,1)
- for inde in vertx_list :
- vert_infl = mesh.getVertexInfluences(inde[0])
- ln_infl = len(vert_infl)
- if ln_infl > max_infl :
- max_infl = ln_infl
-
- except:
- pass
-
- self.file.write(" %d; \n" % (max_infl))
- self.file.write(" %d; \n" % (max_infl * 3))
- self.file.write(" %d; \n" % (len(arm.bones.values())))
- self.file.write(" }\n")
-
- for bo in arm.bones.values() :
- bo_list = []
- weight_list = []
- name = bo.name
- f_name = make_legal_name(name)
- try :
- vert_list = mesh.getVertsFromGroup(name,1)
- le = 0
- for indx in vert_list:
- ver_infl = mesh.getVertexInfluences(indx[0])
- infl = 0.0
- if len(ver_infl) != 0:
- sum = 0.0
- for bone_n, weight in ver_infl:
- if bone_n == name:
- infl = weight
- sum += weight
- infl /= sum
-
- i = -1
- for el in index_list :
- i += 1
- if el == indx[0] :
- le +=1
- bo_list.append(i)
- weight_list.append(infl)
-
-
- self.file.write(" SkinWeights {\n")
- self.file.write(' "%s"; \n' % (f_name))
- self.file.write(' %d; \n' % (le))
- count = 0
- for ind in bo_list :
- count += 1
- if count == len(bo_list):
- self.file.write(" %d; \n" % (ind))
- else :
- self.file.write(" %d, \n" % (ind))
- cou = 0
- for wegh in weight_list :
- cou += 1
-
- if cou == len(weight_list):
- self.file.write(" %f; \n" % (round(wegh,6)))
- else :
- self.file.write(" %f, \n" % (round(wegh,6)))
-
-
- matx = self.writeMatrixOffset(bo)
- self.writeOffsFrames(matx, name)
- except :
- pass
- self.file.write(" } // End of XSkinMeshHeader\n")
-
-
- #***********************************************
- # Write Matrices
- #***********************************************
- def writeArmFrames(self, matx, name):
- global space
- tab = " "
- self.file.write("%s" % (tab * space))
- self.file.write("Frame ")
- self.file.write("%s {\n\n" % (name))
- self.file.write("%s" % (tab * space))
- self.file.write(" FrameTransformMatrix {\n")
- self.writeFrame(matx)
-
- #***********************************************
- # Write Frames
- #***********************************************
- def writeOffsFrames(self, matx, name):
- space = 1
- self.writeFrame(matx)
-
- #***********************************************
- # Write Frames
- #***********************************************
- def writeFrame(self, matx):
- tab = " "
- self.file.write("%s" % (tab * space))
- self.file.write(" %f,%f,%f,%f,\n" %
- (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4)))
- self.file.write("%s" % (tab * space))
- self.file.write(" %f,%f,%f,%f,\n" %
- (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4)))
- self.file.write("%s" % (tab * space))
- self.file.write(" %f,%f,%f,%f,\n" %
- (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4)))
- self.file.write("%s" % (tab * space))
- self.file.write(" %f,%f,%f,%f;;\n" %
- (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4)))
- self.file.write("%s" % (tab * space))
- self.file.write(" }\n")
-#*********************************************************************************************************************************************
-
- #***********************************************
- #HEADER
- #***********************************************
- def writeHeader(self):
- self.file.write("xof 0303txt 0032\n\n\n")
- self.file.write("template VertexDuplicationIndices { \n\
- <b8d65549-d7c9-4995-89cf-53a9a8b031e3>\n\
- DWORD nIndices;\n\
- DWORD nOriginalVertices;\n\
- array DWORD indices[nIndices];\n\
-}\n\
-template XSkinMeshHeader {\n\
- <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\n\
- WORD nMaxSkinWeightsPerVertex;\n\
- WORD nMaxSkinWeightsPerFace;\n\
- WORD nBones;\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")
-
- #***********************************************
- #CLOSE FILE
- #***********************************************
- def writeEnd(self):
- self.file.close()
- print "... finished"
-
-
- #***********************************************
- #EXPORT TEXTURES
- #***********************************************
- def writeTextures(self,name, tex):
- mesh = name.data
- for face in mesh.faces:
- if face.image and face.image.name not in tex:
- tex.append(face.image.name)
-
-
-
- #***********************************************
- #EXPORT MESH DATA with Armature
- #***********************************************
- def writeMeshcoordArm(self, obj ,arm_ob):
- global index_list,flip_z
- #TransformMatrix
- mat = self.getLocMat(obj)
- self.writeArmFrames(mat, make_legal_name(obj.name))
- mesh = NMesh.GetRawFromObject(obj.name)
- self.file.write("Mesh {\n")
- numface=len(mesh.faces)
- #VERTICES NUMBER
- numvert = 0
- for face in mesh.faces:
- numvert = numvert + len(face.v)
- self.file.write("%d;\n" % (numvert))
- if numvert == 0:
- print "Mesh named",mesh.name,"has no vertices.Problems may occur using the .x file"
- #VERTICES COORDINATES
- counter = 0
- for face in mesh.faces:
- counter += 1
- for n in range(len(face.v)):
- index_list.append(face.v[n].index)
- vec_vert = Vector([(face.v[n].co[0]), face.v[n].co[1], face.v[n].co[2], 1])
- if arm_ob :
- f_vec_vert = vec_vert * mat
- else :
- f_vec_vert = vec_vert
- self.file.write("%f; %f; %f;" % (round(f_vec_vert[0],4), round(f_vec_vert[1],4), round(f_vec_vert[2],4)))
- if counter == numface :
- if n == len(face.v)-1 :
- self.file.write(";\n")
- else :
- self.file.write(",\n")
- else :
- self.file.write(",\n")
- if flip_z:
- a3 = 0;b3 = 2;c3 = 1
- a4 = 0;b4 = 3;c4 = 2;d4 = 1
- else:
- a3 = 0;b3 = 1;c3 = 2
- a4 = 0;b4 = 1;c4 = 2;d4 = 3
-
- #FACES NUMBER
- self.file.write("%s;\n" % (numface))
- coun,counter = 0, 0
- for face in mesh.faces :
- coun += 1
- separator = ','
- if coun == numface:
- separator = ';'
- if len(face.v) == 3:
- self.file.write("3; %d, %d, %d;%c\n" % (counter + a3, counter + b3, counter + c3, separator))
- counter += 3
- elif len(face.v) == 4:
- self.file.write("4; %d, %d, %d, %d;%c\n" % (counter + a4, counter + b4, counter + c4, counter + d4, separator))
- counter += 4
- elif len(face.v) < 3:
- print "WARNING:the mesh has faces with less then 3 vertices"
- print " It my be not exported correctly."
-
-
- #***********************************************
- #MESH MATERIAL LIST
- #***********************************************
- def writeMeshMaterialList(self, obj, mesh, tex):
- self.file.write(" MeshMaterialList {\n")
- #HOW MANY MATERIALS ARE USED
- count = 0
- for mat in mesh.getMaterials():
- count+=1
- self.file.write(" %d;\n" % (len(tex) + count))
- #HOW MANY FACES IT HAS
- numfaces=len(mesh.faces)
- self.file.write(" %d;\n" % (numfaces))
- ##MATERIALS INDEX FOR EVERY FACE
- counter = 0
- for face in mesh.faces :
- counter += 1
- mater = face.materialIndex
- if counter == numfaces:
- if face.image and face.image.name in tex :
- self.file.write(" %d;;\n" % (tex.index(face.image.name) + count))
- else :
- self.file.write(" %d;;\n" % (mater))
- else :
- if face.image and face.image.name in tex :
- self.file.write(" %d,\n" % (tex.index(face.image.name) + count))
- else :
- self.file.write(" %d,\n" % (mater))
-
- ##MATERIAL NAME
- for mat in mesh.getMaterials():
- self.file.write(" Material")
- self.file.write(" %s "% (make_legal_name(mat.name)))
- self.file.write("{\n")
- self.file.write(" %f; %f; %f;" % (mat.R, mat.G, mat.B))
- self.file.write("%s;;\n" % (mat.alpha))
- self.file.write(" %f;\n" % (mat.spec))
- self.file.write(" %f; %f; %f;;\n" % (mat.specR, mat.specG, mat.specB))
- self.file.write(" 0.0; 0.0; 0.0;;\n")
- self.file.write(" } //End of Material\n")
-
- for mat in tex:
- self.file.write(" Material Mat")
- self.file.write("%s "% (len(tex)))
- self.file.write("{\n")
- self.file.write(" 1.0; 1.0; 1.0; 1.0;;\n")
- self.file.write(" 1.0;\n")
- self.file.write(" 1.0; 1.0; 1.0;;\n")
- self.file.write(" 0.0; 0.0; 0.0;;\n")
- self.file.write(" TextureFilename {")
- self.file.write(' "%s";'% (mat))
- self.file.write(" }\n")
- self.file.write(" } // End of Material\n")
- self.file.write(" } //End of MeshMaterialList\n")
-
- #***********************************************
- #MESH NORMALS
- #***********************************************
- def writeMeshNormals(self,name,mesh):
- global flip_norm,flip_z,no_light,recalc_norm,Bl_norm
-
- self.file.write(" MeshNormals {\n")
- #VERTICES NUMBER
- numvert = 0
- for face in mesh.faces:
- numvert = numvert + len(face.v)
- self.file.write("%d;\n" % (numvert))
- numfaces=len(mesh.faces)
- if flip_norm :
- fl = -1
- else :
- fl = 1
- #VERTICES NORMAL
- if Bl_norm:
- self.writeBlenderNormals(mesh,fl)
- if recalc_norm:
- self.writeRecalcNormals(mesh,fl)
- if no_light:
- self.writeNoSmothing(mesh,fl)
-
-
-
- if flip_z:
- a3 = 0;b3 = 2;c3 = 1
- a4 = 0;b4 = 3;c4 = 2;d4 = 1
- else:
- a3 = 0;b3 = 1;c3 = 2
- a4 = 0;b4 = 1;c4 = 2;d4 = 3
-
- #FACES NUMBER
- self.file.write("%s;\n" % (numfaces))
- coun,counter = 0, 0
- for face in mesh.faces :
- coun += 1
- if coun == numfaces:
- if len(face.v) == 3:
- self.file.write("3; %d, %d, %d;;\n" % (counter + a3, counter + b3, counter + c3))
- counter += 3
- else :
- self.file.write("4; %d, %d, %d, %d;;\n" % (counter + a4, counter + b4, counter + c4, counter + d4))
- counter += 4
- else:
-
- if len(face.v) == 3:
- self.file.write("3; %d, %d, %d;,\n" % (counter + a3, counter + b3, counter + c3))
- counter += 3
- else :
- self.file.write("4; %d, %d, %d, %d;,\n" % (counter + a4, counter + b4, counter + c4, counter + d4))
- counter += 4
- self.file.write("} //End of MeshNormals\n")
-
- def writeBlenderNormals(self,mesh,fl):
- numfaces=len(mesh.faces)
- #VERTICES NORMAL
- counter = 0
- for face in mesh.faces:
- counter += 1
- for n in range(len(face.v)):
- self.file.write(" %f; %f; %f;" % (
- (round(face.v[n].no[0],6)*fl),(round(face.v[n].no[1],6)*fl),(round(face.v[n].no[2],6)*fl)))
- if counter == numfaces :
- if n == len(face.v)-1 :
- self.file.write(";\n")
- else :
- self.file.write(",\n")
- else :
- self.file.write(",\n")
-
- def writeRecalcNormals(self,mesh,fl):
- numfaces=len(mesh.faces)
- normal_list = {}
- idx = 0
- for vertex in mesh.verts:
- v_norm = Vector([0, 0, 0])
- normal_list[idx] = v_norm
- idx += 1
- for face in mesh.faces:
- for verts in face.v:
- if verts.index == vertex.index :
- v_norm[0] += face.no[0]
- v_norm[1] += face.no[1]
- v_norm[2] += face.no[2]
-
- v_norm.normalize()
-
- counter = 0
- for face in mesh.faces:
- counter += 1
- n = 0
- for vert in face.v:
- n += 1
- norm = normal_list[vert.index]
-
- self.file.write(" %f; %f; %f;" % (
- (round(norm[0],6)*fl),(round(norm[1],6)*fl),(round(norm[2],6)*fl)))
- if counter == numfaces :
- if n == len(face.v) :
- self.file.write(";\n")
- else :
- self.file.write(",\n")
- else :
- self.file.write(",\n")
-
- def writeNoSmothing(self,mesh,fl):
- numfaces=len(mesh.faces)
- counter = 0
- for face in mesh.faces:
- counter += 1
- n = 0
- for n in range(len(face.v)):
- n += 1
- self.file.write(" %f; %f; %f;" % (
- (round(face.no[0],6)*fl),(round(face.no[1],6)*fl),(round(face.no[2],6)*fl)))
-
-
- if counter == numfaces :
- if n == len(face.v) :
- self.file.write(";\n")
- else :
- self.file.write(",\n")
- else :
- self.file.write(",\n")
- #***********************************************
- #MESH TEXTURE COORDS
- #***********************************************
- def writeMeshTextureCoords(self, name, mesh):
- if mesh.hasFaceUV():
- self.file.write("MeshTextureCoords {\n")
- #VERTICES NUMBER
- numvert = 0
- for face in mesh.faces:
- numvert += len(face.v)
- self.file.write("%d;\n" % (numvert))
- #UV COORDS
- numfaces = len(mesh.faces)
- counter = -1
- co = 0
- for face in mesh.faces:
- counter += 1
- co += 1
- for n in range(len(face.v)):
- self.file.write("%f;%f;" % (mesh.faces[counter].uv[n][0], -mesh.faces[counter].uv[n][1]))
- if co == numfaces :
- if n == len(face.v) - 1 :
- self.file.write(";\n")
- else :
- self.file.write(",\n")
- else :
- self.file.write(",\n")
-
- self.file.write("} //End of MeshTextureCoords\n")
-
- #***********************************************
- #MESH VORTEX COLORS
- #***********************************************
- def writeMeshVertexColors(self, name, mesh):
- if mesh.hasVertexColours():
- self.file.write("MeshVertexColors {\n")
- #VERTICES NUMBER
- numvert = reduce( lambda i,f: len(f)+i, mesh.faces, 0)
- self.file.write("%d;\n" % (numvert))
- #VERTEX COLORS
-
- vcounter =0
- for f in mesh.faces:
- col = f.col
- for i,c in enumerate(col):
- # Note vcol alpha has no meaning
- self.file.write("%d;%f;%f;%f;%f;" % (vcounter,c.r/255.0, c.g/255.0, c.b/255.0, 1.0)) # c.a/255.0))
- vcounter+=1
- if vcounter == numvert :
- self.file.write(";\n")
- else :
- self.file.write(",\n")
-
- self.file.write("} //End of MeshVertexColors\n")
-
-#***********************************************#***********************************************#***********************************************
- #***********************************************
- #FRAMES
- #***********************************************
- def writeFrames(self, matx):
-
- self.file.write("%f,%f,%f,%f," %
- (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4)))
- self.file.write("%f,%f,%f,%f," %
- (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4)))
- self.file.write("%f,%f,%f,%f," %
- (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4)))
- self.file.write("%f,%f,%f,%f;;" %
- (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4)))
-
-
-
-
-
- #***********************************************
- #WRITE ANIMATION KEYS
- #***********************************************
- def writeAnimation(self,arm_ob):
- global mat_dict, root_bon
- arm = arm_ob.getData()
- act_list = arm_ob.getAction()
- ip = act_list.getAllChannelIpos()
- for bon in arm.bones.values() :
- point_list = []
- name = bon.name
- name_f = make_legal_name(name)
- try :
- ip_bon_channel = ip[bon.name]
- ip_bon_name = ip_bon_channel.getName()
-
- ip_bon = Blender.Ipo.Get(ip_bon_name)
- poi = ip_bon.getCurves()
-
- for po in poi[3].getPoints():
- a = po.getPoints()
- point_list.append(int(a[0]))
- #point_list.pop(0)
-
- self.file.write(" Animation { \n")
- self.file.write(" { %s }\n" %(name_f))
- self.file.write(" AnimationKey { \n")
- self.file.write(" 4;\n")
- self.file.write(" %d; \n" % (len(point_list)))
-
- for fr in point_list:
-
- if name == root_bon.name :
-
-
- mat_b = self.writeAnimCombineMatrix(bon,fr)
- mat_arm = self.getLocMat(arm_ob)
- mat = mat_b * mat_arm
- else:
- mat = self.writeAnimCombineMatrix(bon,fr)
-
- self.file.write(" %d;" % (fr))
- self.file.write("16;")
-
- self.writeFrames(mat)
-
- if fr == point_list[len(point_list)-1]:
- self.file.write(";\n")
- else:
- self.file.write(",\n")
- self.file.write(" }\n")
- self.file.write(" }\n")
- self.file.write("\n")
- except:
- pass
-
-
-
- #***********************************************
- #WRITE ANIMATION KEYS
- #***********************************************
- def writeAnimationObj(self, obj):
- point_list = []
- ip = obj.ipo
- poi = ip.getCurves()
- for po in poi[0].getPoints():
- a = po.getPoints()
- point_list.append(int(a[0]))
-
- self.file.write(" Animation {\n")
- self.file.write(" { ")
- self.file.write("%s }\n" % (make_legal_name(obj.name)))
- self.file.write(" AnimationKey { \n")
- self.file.write(" 4;\n")
- self.file.write(" %d; \n" % (len(point_list)))
- for fr in point_list:
- self.file.write(" %d;" % (fr))
- self.file.write("16;")
- Blender.Set('curframe',fr)
-
- #mat_new = self.getLocMat(obj)
- mat_new = obj.matrixLocal
- self.writeFrames(mat_new)
-
- if fr == point_list[len(point_list)-1]:
- self.file.write(";\n")
- else:
- self.file.write(",\n")
- self.file.write(" }\n")
- self.file.write(" }\n")
-
-
-
-#***********************************************#***********************************************#***********************************************
-
-
-
-
-
diff --git a/release/scripts/DirectX8Importer.py b/release/scripts/DirectX8Importer.py
deleted file mode 100644
index 0dda654944d..00000000000
--- a/release/scripts/DirectX8Importer.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus:
-Name: 'DirectX(.x)...'
-Blender: 244
-Group: 'Import'
-
-Tip: 'Import from DirectX text file format format.'
-"""
-# DirectXImporter.py version 1.2
-# Copyright (C) 2005 Arben OMARI -- omariarben@everyday.com
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# This script import meshes from DirectX text file format
-
-# Grab the latest version here :www.omariben.too.it
-import bpy
-import Blender
-from Blender import Mesh,Object,Material,Texture,Image,Draw
-
-
-class xImport:
- def __init__(self, filename):
- global my_path
- self.file = open(filename, "r")
- my_path = Blender.sys.dirname(filename)
-
- #
- self.lines = [l_split for l in self.file.readlines() for l_split in (' '.join(l.split()),) if l_split]
-
- def Import(self):
- lines = self.lines
- print "importing into Blender ..."
- scene = bpy.data.scenes.active
-
- mesh_indicies = {} # the index of each 'Mesh' is used as the key for those meshes indicies
- context_indicies = None # will raise an error if used!
-
-
- #Get the line of Texture Coords
- nr_uv_ind = 0
-
- #Get Materials
- nr_fac_mat = 0
- i = -1
- mat_list = []
- tex_list = []
- mesh_line_indicies = []
- for j, line in enumerate(lines):
- l = line.strip()
- words = line.split()
- if words[0] == "Material" :
- #context_indicies["Material"] = j
- self.loadMaterials(j, mat_list, tex_list)
- elif words[0] == "MeshTextureCoords" :
- context_indicies["MeshTextureCoords"] = j
- #nr_uv_ind = j
- elif words[0] == "MeshMaterialList" :
- context_indicies["MeshMaterialList"] = j+2
- #nr_fac_mat = j + 2
- elif words[0] == "Mesh": # Avoid a second loop
- context_indicies = mesh_indicies[j] = {'MeshTextureCoords':0, 'MeshMaterialList':0}
-
- for mesh_index, value in mesh_indicies.iteritems():
- mesh = Mesh.New()
- self.loadVertices(mesh_index, mesh, value['MeshTextureCoords'], value['MeshMaterialList'], tex_list)
-
- mesh.materials = mat_list[:16]
- if value['MeshMaterialList']:
- self.loadMeshMaterials(value['MeshMaterialList'], mesh)
- scene.objects.new(mesh)
-
- self.file.close()
- print "... finished"
-
- #------------------------------------------------------------------------------
- # CREATE THE MESH
- #------------------------------------------------------------------------------
- def loadVertices(self, nr_vr_ind, mesh, nr_uv, nr_fac_mat, tex_list):
- v_ind = nr_vr_ind + 1
- lin = self.lines[v_ind]
- if lin :
- lin_c = self.CleanLine(lin)
- nr_vert = int((lin_c.split()[0]))
- else :
- v_ind = nr_vr_ind + 2
- lin = self.lines[v_ind]
- lin_c = self.CleanLine(lin)
- nr_vert = int((lin_c.split()[0]))
-
- #--------------------------------------------------
- nr_fac_li = v_ind + nr_vert +1
- lin_f = self.lines[nr_fac_li]
- if lin_f :
- lin_fc = self.CleanLine(lin_f)
- nr_face = int((lin_fc.split()[0]))
- else :
- nr_fac_li = v_ind + nr_vert +1
- lin_f = self.lines[nr_fac_li]
- lin_fc = self.CleanLine(lin_f)
- nr_face = int((lin_fc.split()[0]))
-
- #Get Coordinates
- verts_list = [(0,0,0)] # WARNING - DUMMY VERT - solves EEKADOODLE ERROR
- for l in xrange(v_ind + 1, (v_ind + nr_vert +1)):
- line_v = self.lines[l]
- lin_v = self.CleanLine(line_v)
- words = lin_v.split()
- if len(words)==3:
- verts_list.append((float(words[0]),float(words[1]),float(words[2])))
-
- mesh.verts.extend(verts_list)
- del verts_list
-
- face_list = []
- #Make Faces
- i = 0
- mesh_verts = mesh.verts
- for f in xrange(nr_fac_li + 1, (nr_fac_li + nr_face + 1)):
- i += 1
- line_f = self.lines[f]
- lin_f = self.CleanLine(line_f)
-
- # +1 for dummy vert only!
- words = lin_f.split()
- if len(words) == 5:
- face_list.append((1+int(words[1]), 1+int(words[2]), 1+int(words[3]), 1+int(words[4])))
- elif len(words) == 4:
- face_list.append((1+int(words[1]), 1+int(words[2]), 1+int(words[3])))
-
- mesh.faces.extend(face_list)
- del face_list
-
- if nr_uv :
- mesh.faceUV = True
- for f in mesh.faces:
- fuv = f.uv
- for ii, v in enumerate(f):
- # _u, _v = self.CleanLine(self.lines[nr_uv + 2 + v.index]).split()
-
- # Use a dummy vert
- _u, _v = self.CleanLine(self.lines[nr_uv + 1 + v.index]).split()
-
- fuv[ii].x = float(_u)
- fuv[ii].y = float(_v)
-
- if nr_fac_mat :
- fac_line = self.lines[nr_fac_mat + i]
- fixed_fac = self.CleanLine(fac_line)
- w_tex = int(fixed_fac.split()[0])
- f.image = tex_list[w_tex]
-
- # remove dummy vert
- mesh.verts.delete([0,])
-
- def CleanLine(self,line):
- return line.replace(\
- ";", " ").replace(\
- '"', ' ').replace(\
- "{", " ").replace(\
- "}", " ").replace(\
- ",", " ").replace(\
- "'", " ")
-
- #------------------------------------------------------------------
- # CREATE MATERIALS
- #------------------------------------------------------------------
- def loadMaterials(self, nr_mat, mat_list, tex_list):
-
- def load_image(name):
- try:
- return Image.Load(Blender.sys.join(my_path,name))
- except:
- return None
-
- mat = bpy.data.materials.new()
- line = self.lines[nr_mat + 1]
- fixed_line = self.CleanLine(line)
- words = fixed_line.split()
- mat.rgbCol = [float(words[0]),float(words[1]),float(words[2])]
- mat.setAlpha(float(words[3]))
- mat_list.append(mat)
- l = self.lines[nr_mat + 5]
- fix_3_line = self.CleanLine(l)
- tex_n = fix_3_line.split()
-
- if tex_n and tex_n[0] == "TextureFilename" :
-
- if len(tex_n) > 1:
- tex_list.append(load_image(tex_n[1]))
-
- if len(tex_n) <= 1 :
-
- l_succ = self.lines[nr_mat + 6]
- fix_3_succ = self.CleanLine(l_succ)
- tex_n_succ = fix_3_succ.split()
- tex_list.append(load_image(tex_n_succ[0]))
- else :
- tex_list.append(None) # no texture for this index
-
- return mat_list, tex_list
- #------------------------------------------------------------------
- # SET MATERIALS
- #------------------------------------------------------------------
- def loadMeshMaterials(self, nr_fc_mat, mesh):
- for face in mesh.faces:
- nr_fc_mat += 1
- line = self.lines[nr_fc_mat]
- fixed_line = self.CleanLine(line)
- wrd = fixed_line.split()
- mat_idx = int(wrd[0])
- face.mat = mat_idx
-
-#------------------------------------------------------------------
-# MAIN
-#------------------------------------------------------------------
-def my_callback(filename):
- if not filename.lower().endswith('.x'): print "Not an .x file"
- ximport = xImport(filename)
- ximport.Import()
-
-arg = __script__['arg']
-
-if __name__ == '__main__':
- Blender.Window.FileSelector(my_callback, "Import DirectX", "*.x")
-
-#my_callback('/fe/x/directxterrain.x')
-#my_callback('/fe/x/Male_Normal_MAX.X')
-#my_callback('/fe/x/male_ms3d.x')
diff --git a/release/scripts/IDPropBrowser.py b/release/scripts/IDPropBrowser.py
deleted file mode 100644
index 2a14760270a..00000000000
--- a/release/scripts/IDPropBrowser.py
+++ /dev/null
@@ -1,523 +0,0 @@
-#!BPY
-
-"""
-Name: 'ID Property Browser'
-Blender: 242
-Group: 'Help'
-Tooltip: 'Browse ID properties'
-"""
-
-__author__ = "Joe Eagar"
-__version__ = "0.3.108"
-__email__ = "joeedh@gmail.com"
-__bpydoc__ = """\
-
-Allows browsing, creating and editing of ID Properties
-for various ID block types such as mesh, scene, object,
-etc.
-"""
-
-# --------------------------------------------------------------------------
-# ID Property Browser.
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import *
-from Blender.BGL import *
-from Blender.Types import IDGroupType, IDArrayType
-import Blender
-
-def IsInRectWH(mx, my, x, y, wid, hgt):
- if mx >= x and mx <= x + wid:
- if my >= y and my <= y + hgt:
- return 1
- return 0
-
-Button_Back = 1
-Button_New = 2
-Button_MatMenu = 3
-Button_TypeMenu = 4
-
-ButStart = 55
-
-IDP_String = 0
-IDP_Int = 1
-IDP_Float = 2
-IDP_Array = 5
-IDP_Group = 6
-
-ButDelStart = 255
-#max limit for string input button
-strmax = 100
-
-State_Normal = 0
-State_InArray = 1
-
-#IDTypeModules entries are of form [module, active_object_index, module_name]
-IDTypeModules = [[Scene, 0, "Scenes"], [Object, 0, "Objects"], [Mesh, 0, "Meshes"]]
-IDTypeModules += [[Material, 0, "Materials"], [Texture, 0, "Textures"]]
-IDTypeModules += [[Image, 0, "Images"]]
-
-class IDArrayBrowser:
- array = 0
- parentbrowser = 0
- buts = 0
-
- def __init__(self):
- self.buts = []
-
- def Draw(self):
- pb = self.parentbrowser
- x = pb.x
- y = pb.y
- width = pb.width
- height = pb.height
- pad = pb.pad
- itemhgt = pb.itemhgt
- cellwid = 65
- y = y + height - itemhgt - pad
-
- Draw.PushButton("Back", Button_Back, x, y, 40, 20)
- y -= itemhgt + pad
-
- self.buts = []
- Draw.BeginAlign()
- for i in xrange(len(self.array)):
- st = ""
- if type(self.array[0]) == float:
- st = "%.5f" % self.array[i]
- else: st = str(self.array[i])
-
- b = Draw.String("", ButStart+i, x, y, cellwid, itemhgt, st, 30)
- self.buts.append(b)
- x += cellwid + pad
- if x + cellwid + pad > width:
- x = 0
- y -= itemhgt + pad
- Draw.EndAlign()
- def Button(self, bval):
- if bval == Button_Back:
- self.parentbrowser.state = State_Normal
- self.parentbrowser.array = 0
- self.buts = []
- Draw.Draw()
- self.array = 0
- elif bval >= ButStart:
- i = bval - ButStart
- st = self.buts[i].val
- n = 0
- if type(self.array[0]) == float:
- try:
- n = int(st)
- except:
- return
- elif type(self.array[0]) == int:
- try:
- n = float(st)
- except:
- return
-
- self.array[i] = n
- Draw.Draw()
-
- def Evt(self, evt, val):
- if evt == Draw.ESCKEY:
- Draw.Exit()
-
-class IDPropertyBrowser:
- width = 0
- height = 0
- x = 0
- y = 0
- scrollx = 0
- scrolly = 0
- itemhgt = 22
- pad = 2
-
- group = 0
- parents = 0 #list stack of parent groups
- active_item = -1
- mousecursor = 0
- _i = 0
- buts = []
-
- state = 0
- array = 0
- prop = 0
-
- IDList = 0
- idindex = 0
- idblock = 0
-
- type = 0 # attach buildin type() method to class
- # since oddly it's not available to button
- # callbacks! EEK! :(
-
- def __init__(self, idgroup, mat, x, y, wid, hgt):
- self.group = idgroup
- self.prop = idgroup
- self.x = x
- self.y = y
- self.width = wid
- self.height = hgt
- self.mousecursor = [0, 0]
- self.parents = []
- self.idblock = mat
- self.type = type
-
- def DrawBox(self, glmode, x, y, width, height):
- glBegin(glmode)
- glVertex2f(x, y)
- glVertex2f(x+width, y)
- glVertex2f(x+width, y+height)
- glVertex2f(x, y+height)
- glEnd()
-
- def Draw(self):
- global IDTypeModules
-
- #first draw outlining box :)
- glColor3f(0, 0, 0)
- self.DrawBox(GL_LINE_LOOP, self.x, self.y, self.width, self.height)
-
- itemhgt = self.itemhgt
- pad = self.pad
- x = self.x
- y = self.y + self.height - itemhgt - pad
-
- if self.state == State_InArray:
- self.array.Draw()
- return
-
- plist = []
- self.buts = []
- for p in self.group.iteritems():
- plist.append(p)
-
- #-------do top buttons----------#
- Draw.BeginAlign()
- Draw.PushButton("New", Button_New, x, y, 40, 20)
- x += 40 + pad
- #do the menu button for all materials
- st = ""
-
- blocks = IDTypeModules[self.IDList][0].Get()
- i = 1
- mi = 0
- for m in blocks:
- if m.name == self.idblock.name:
- mi = i
- st += m.name + " %x" + str(i) + "|"
- i += 1
-
- self.menubut = Draw.Menu(st, Button_MatMenu, x, y, 100, 20, mi)
-
- x += 100 + pad
-
- st = ""
- i = 0
- for e in IDTypeModules:
- st += e[2] + " %x" + str(i+1) + "|"
- i += 1
-
- cur = self.IDList + 1
- self.idmenu = Draw.Menu(st, Button_TypeMenu, x, y, 100, 20, cur)
- x = self.x
- y -= self.itemhgt + self.pad
- Draw.EndAlign()
-
-
- #-----------do property items---------#
- i = 0
- while y > self.y - 20 - pad and i < len(plist):
- k = plist[i][0]
- p = plist[i][1]
- if i == self.active_item:
- glColor3f(0.5, 0.4, 0.3)
- self.DrawBox(GL_POLYGON, x+pad, y, self.width-pad*2, itemhgt)
-
- glColor3f(0, 0, 0)
- self.DrawBox(GL_LINE_LOOP, x+pad, y, self.width-pad*2, itemhgt)
-
- glRasterPos2f(x+pad*2, y+5)
- Draw.Text(str(k)) #str(self.mousecursor) + " " + str(self.active_item)) #p.name)
- tlen = Draw.GetStringWidth(str(k))
-
- type_p = type(p)
- if type_p == str:
- b = Draw.String("", ButStart+i, x+pad*5+tlen, y, 200, itemhgt, p, strmax)
- self.buts.append(b)
- elif type_p in [int, float]:
- #only do precision to 5 points on floats
- st = ""
- if type_p == float:
- st = "%.5f" % p
- else: st = str(p)
- b = Draw.String("", ButStart+i, x+pad*5+tlen, y, 75, itemhgt, st, strmax)
- self.buts.append(b)
- else:
- glRasterPos2f(x+pad*2 +tlen+10, y+5)
- if type_p == Types.IDArrayType:
- Draw.Text('(array, click to edit)')
- elif type_p == Types.IDGroupType:
- Draw.Text('(group, click to edit)')
-
-
- self.buts.append(None)
-
- Draw.PushButton("Del", ButDelStart+i, x+self.width-35, y, 30, 20)
-
- i += 1
- y -= self.itemhgt + self.pad
-
- if len(self.parents) != 0:
- Draw.PushButton("Back", Button_Back, x, y, 40, 20)
- x = x + 40 + pad
-
- def SetActive(self):
- m = self.mousecursor
- itemhgt = self.itemhgt
- pad = self.pad
-
- x = self.x + pad
- y = self.y + self.height - itemhgt - pad - itemhgt
-
- plist = []
- for p in self.group.iteritems():
- plist.append(p)
-
- self.active_item = -1
- i = 0
- while y > self.y and i < len(plist):
- p = plist[i]
- if IsInRectWH(m[0], m[1], x, y, self.width-pad, itemhgt):
- self.active_item = i
-
- i += 1
- y -= self.itemhgt + self.pad
-
- def EventIn(self, evt, val):
- if self.state == State_InArray:
- self.array.Evt(evt, val)
-
- if evt == Draw.ESCKEY:
- Draw.Exit()
- if evt == Draw.MOUSEX or evt == Draw.MOUSEY:
- size = Buffer(GL_FLOAT, 4)
- glGetFloatv(GL_SCISSOR_BOX, size)
- if evt == Draw.MOUSEX:
- self.mousecursor[0] = val - size[0]
- else:
- self.mousecursor[1] = val - size[1]
- del size
-
- self.SetActive()
- self._i += 1
- if self._i == 5:
- Draw.Draw()
- self._i = 0
-
-
- if evt == Draw.LEFTMOUSE and val == 1:
- plist = list(self.group.iteritems())
- a = self.active_item
- if a >= 0 and a < len(plist):
- p = plist[a]
-
- basictypes = [IDGroupType, float, str, int]
- if type(p[1]) == IDGroupType:
- self.parents.append(self.group)
- self.group = p[1]
- self.active_item = -1
- Draw.Draw()
- elif type(p[1]) == IDArrayType:
- self.array = IDArrayBrowser()
- self.array.array = p[1]
- self.array.parentbrowser = self
- self.state = State_InArray
- Draw.Draw()
-
- if evt == Draw.TKEY and val == 1:
- try:
- self.prop['float'] = 0.0
- self.prop['int'] = 1
- self.prop['string'] = "hi!"
- self.prop['float array'] = [0, 0, 1.0, 0]
- self.prop['int array'] = [0, 0, 0, 0]
- self.prop.data['a subgroup'] = {"int": 0, "float": 0.0, "anothergroup": {"a": 0.0, "intarr": [0, 0, 0, 0]}}
- Draw.Draw()
- except:
- Draw.PupMenu("Can only do T once per block, the test names are already taken!")
-
-
- def Button(self, bval):
- global IDTypeModules
- if self.state == State_InArray:
- self.array.Button(bval)
- return
-
- if bval == Button_MatMenu:
- global IDTypeModules
-
- val = self.idindex = self.menubut.val - 1
- i = self.IDList
- block = IDTypeModules[i][0].Get()[val]
- self.idblock = block
- self.prop = block.properties
- self.group = self.prop
- self.active_item = -1
- self.parents = []
- Draw.Draw()
-
- if bval == Button_TypeMenu:
- i = IDTypeModules[self.idmenu.val-1]
- if len(i[0].Get()) == 0:
- Draw.PupMenu("Error%t|There are no " + i[2] + "!")
- return
-
- IDTypeModules[self.IDList][1] = self.idindex
- self.IDList = self.idmenu.val-1
- val = self.idindex = IDTypeModules[self.IDList][1]
- i = self.IDList
- block = IDTypeModules[i][0].Get()[val]
- self.idblock = block
- self.prop = block.properties
- self.group = self.prop
- self.active_item = -1
- self.parents = []
- Draw.Draw()
-
- if bval >= ButDelStart:
- plist = [p for p in self.group]
- prop = plist[bval - ButDelStart]
- del self.group[prop]
- Draw.Draw()
-
- elif bval >= ButStart:
- plist = list(self.group.iteritems())
-
- prop = plist[bval - ButStart]
- print prop
-
- if self.type(prop[1]) == str:
- self.group[prop[0]] = self.buts[bval - ButStart].val
- elif self.type(prop[1]) == int:
- i = self.buts[bval - ButStart].val
- try:
- i = int(i)
- self.group[prop[0]] = i
- except:
- Draw.Draw()
- return
- Draw.Draw()
- elif self.type(prop[1]) == float:
- f = self.buts[bval - ButStart].val
- try:
- f = float(f)
- self.group[prop[0]] = f
- except:
- Draw.Draw()
- return
- Draw.Draw()
-
- elif bval == Button_Back:
- self.group = self.parents[len(self.parents)-1]
- self.parents.pop(len(self.parents)-1)
- Draw.Draw()
-
- elif bval == Button_New:
- name = Draw.Create("untitled")
- stype = Draw.Create(0)
- gtype = Draw.Create(0)
- ftype = Draw.Create(0)
- itype = Draw.Create(0)
- atype = Draw.Create(0)
-
- block = []
- block.append(("Name: ", name, 0, 30, "Click to type in the name of the new ID property"))
- block.append("Type")
- block.append(("String", stype))
- block.append(("Subgroup", gtype))
- block.append(("Float", ftype))
- block.append(("Int", itype))
- block.append(("Array", atype))
-
- retval = Blender.Draw.PupBlock("New IDProperty", block)
- if retval == 0: return
-
- name = name.val
- i = 1
- stop = 0
- while stop == 0:
- stop = 1
- for p in self.group:
- if p == name:
- d = name.rfind(".")
- if d != -1:
- name = name[:d]
- name = name + "." + str(i).zfill(3)
- i += 1
- stop = 0
-
- type = "String"
- if stype.val:
- self.group[name] = ""
- elif gtype.val:
- self.group[name] = {}
- elif ftype.val:
- self.group[name] = 0.0
- elif itype.val:
- self.group[name] = 0 #newProperty("Int", name, 0)
- elif atype.val:
- arrfloat = Draw.Create(1)
- arrint = Draw.Create(0)
- arrlen = Draw.Create(3)
- block = []
- block.append("Type")
- block.append(("Float", arrfloat, "Make a float array"))
- block.append(("Int", arrint, "Make an integer array"))
- block.append(("Len", arrlen, 2, 200))
-
- if Blender.Draw.PupBlock("Array Properties", block):
- if arrfloat.val:
- tmpl = 0.0
- elif arrint.val:
- tmpl = 0
- else:
- return
-
- self.group[name] = [tmpl] * arrlen.val
-
-
- def Go(self):
- Draw.Register(self.Draw, self.EventIn, self.Button)
-
-scenes = Scene.Get()
-
-size = Window.GetAreaSize()
-browser = IDPropertyBrowser(scenes[0].properties, scenes[0], 2, 2, size[0], size[1])
-browser.Go()
-
-#a = prop.newProperty("String", "hwello!", "bleh")
-#b = prop.newProperty("Group", "subgroup")
-
-#for p in prop:
- #print p.name
diff --git a/release/scripts/ac3d_export.py b/release/scripts/ac3d_export.py
deleted file mode 100644
index 57f27c7e3a2..00000000000
--- a/release/scripts/ac3d_export.py
+++ /dev/null
@@ -1,828 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus:
-Name: 'AC3D (.ac)...'
-Blender: 243
-Group: 'Export'
-Tip: 'Export selected meshes to AC3D (.ac) format'
-"""
-
-__author__ = "Willian P. Germano"
-__url__ = ("blender", "blenderartists.org", "AC3D's homepage, http://www.ac3d.org",
- "PLib 3d gaming lib, http://plib.sf.net")
-__version__ = "2.44 2007-05-05"
-
-__bpydoc__ = """\
-This script exports selected Blender meshes to AC3D's .ac file format.
-
-AC3D is a simple commercial 3d modeller also built with OpenGL.
-The .ac file format is an easy to parse text format well supported,
-for example, by the PLib 3d gaming library (AC3D 3.x).
-
-Supported:<br>
- UV-textured meshes with hierarchy (grouping) information.
-
-Missing:<br>
- The 'url' tag, specific to AC3D. It is easy to add by hand to the exported
-file, if needed.
-
-Known issues:<br>
- The ambient and emit data we can retrieve from Blender are single values,
-that this script copies to R, G, B, giving shades of gray.<br>
- Loose edges (lines) receive the first material found in the mesh, if any, or a default white material.<br>
- In AC3D 4 "compatibility mode":<br>
- - shininess of materials is taken from the shader specularity value in Blender, mapped from [0.0, 2.0] to [0, 128];<br>
- - crease angle is exported, but in Blender it is limited to [1, 80], since there are other more powerful ways to control surface smoothing. In AC3D 4.0 crease's range is [0.0, 180.0];
-
-Config Options:<br>
- toggle:<br>
- - AC3D 4 mode: unset it to export without the 'crease' tag that was
-introduced with AC3D 4.0 and with the old material handling;<br>
- - global coords: transform all vertices of all meshes to global coordinates;<br>
- - skip data: set it if you don't want mesh names (ME:, not OB: field)
-to be exported as strings for AC's "data" tags (19 chars max);<br>
- - rgb mirror color can be exported as ambient and/or emissive if needed,
-since Blender handles these differently;<br>
- - default mat: a default (white) material is added if some mesh was
-left without mats -- it's better to always add your own materials;<br>
- - no split: don't split meshes (see above);<br>
- - set texture dir: override the actual textures path with a given default
-path (or simply export the texture names, without dir info, if the path is
-empty);<br>
- - per face 1 or 2 sided: override the "Double Sided" button that defines this behavior per whole mesh in favor of the UV Face Select mode "twosided" per face atribute;<br>
- - only selected: only consider selected objects when looking for meshes
-to export (read notes below about tokens, too);<br>
- strings:<br>
- - export dir: default dir to export to;<br>
- - texture dir: override textures path with this path if 'set texture dir'
-toggle is "on".
-
-Notes:<br>
- This version updates:<br>
- - modified meshes are correctly exported, no need to apply the modifiers in Blender;<br>
- - correctly export each used material, be it assigned to the object or to its mesh data;<br>
- - exporting lines (edges) is again supported; color comes from first material found in the mesh, if any, or a default white one.<br>
- - there's a new option to choose between exporting meshes with transformed (global) coordinates or local ones;<br>
- Multiple textures per mesh are supported (mesh gets split);<br>
- Parents are exported as a group containing both the parent and its children;<br>
- Start mesh object names (OB: field) with "!" or "#" if you don't want them to be exported;<br>
- Start mesh object names (OB: field) with "=" or "$" to prevent them from being split (meshes with multiple textures or both textured and non textured faces are split unless this trick is used or the "no split" option is set.
-"""
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# AC3DExport version 2.44
-# Program versions: Blender 2.42+ and AC3Db files (means version 0xb)
-# new: updated for new Blender version and Mesh module; supports lines (edges) again;
-# option to export vertices transformed to global coordinates or not; now the modified
-# (by existing mesh modifiers) mesh is exported; materials are properly exported, no
-# matter if each of them is linked to the mesh or to the object. New (2.43.1): loose
-# edges use color of first material found in the mesh, if any.
-# --------------------------------------------------------------------------
-# Thanks: Steve Baker for discussions and inspiration; for testing, bug
-# reports, suggestions, patches: David Megginson, Filippo di Natale,
-# Franz Melchior, Campbell Barton, Josh Babcock, Ralf Gerlich, Stewart Andreason.
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004-2007: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Object, Mesh, Material, Image, Mathutils, Registry
-from Blender import sys as bsys
-
-# Globals
-REPORT_DATA = {
- 'main': [],
- 'errors': [],
- 'warns': [],
- 'nosplit': [],
- 'noexport': []
-}
-TOKENS_DONT_EXPORT = ['!', '#']
-TOKENS_DONT_SPLIT = ['=', '$']
-
-MATIDX_ERROR = 0
-
-# flags:
-LOOSE = Mesh.EdgeFlags['LOOSE']
-FACE_TWOSIDED = Mesh.FaceModes['TWOSIDE']
-MESH_TWOSIDED = Mesh.Modes['TWOSIDED']
-
-REG_KEY = 'ac3d_export'
-
-# config options:
-GLOBAL_COORDS = True
-SKIP_DATA = False
-MIRCOL_AS_AMB = False
-MIRCOL_AS_EMIS = False
-ADD_DEFAULT_MAT = True
-SET_TEX_DIR = True
-TEX_DIR = ''
-AC3D_4 = True # export crease value, compatible with AC3D 4 loaders
-NO_SPLIT = False
-ONLY_SELECTED = True
-EXPORT_DIR = ''
-PER_FACE_1_OR_2_SIDED = True
-
-tooltips = {
- 'GLOBAL_COORDS': "transform all vertices of all meshes to global coordinates",
- 'SKIP_DATA': "don't export mesh names as data fields",
- 'MIRCOL_AS_AMB': "export mirror color as ambient color",
- 'MIRCOL_AS_EMIS': "export mirror color as emissive color",
- 'ADD_DEFAULT_MAT': "always add a default white material",
- 'SET_TEX_DIR': "don't export default texture paths (edit also \"tex dir\")",
- 'EXPORT_DIR': "default / last folder used to export .ac files to",
- 'TEX_DIR': "(see \"set tex dir\") dir to prepend to all exported texture names (leave empty for no dir)",
- 'AC3D_4': "compatibility mode, adds 'crease' tag and slightly better material support",
- 'NO_SPLIT': "don't split meshes with multiple textures (or both textured and non textured polygons)",
- 'ONLY_SELECTED': "export only selected objects",
- 'PER_FACE_1_OR_2_SIDED': "override \"Double Sided\" button in favor of per face \"twosided\" attribute (UV Face Select mode)"
-}
-
-def update_RegistryInfo():
- d = {}
- d['SKIP_DATA'] = SKIP_DATA
- d['MIRCOL_AS_AMB'] = MIRCOL_AS_AMB
- d['MIRCOL_AS_EMIS'] = MIRCOL_AS_EMIS
- d['ADD_DEFAULT_MAT'] = ADD_DEFAULT_MAT
- d['SET_TEX_DIR'] = SET_TEX_DIR
- d['TEX_DIR'] = TEX_DIR
- d['AC3D_4'] = AC3D_4
- d['NO_SPLIT'] = NO_SPLIT
- d['EXPORT_DIR'] = EXPORT_DIR
- d['ONLY_SELECTED'] = ONLY_SELECTED
- d['PER_FACE_1_OR_2_SIDED'] = PER_FACE_1_OR_2_SIDED
- d['tooltips'] = tooltips
- d['GLOBAL_COORDS'] = GLOBAL_COORDS
- Registry.SetKey(REG_KEY, d, True)
-
-# Looking for a saved key in Blender.Registry dict:
-rd = Registry.GetKey(REG_KEY, True)
-
-if rd:
- try:
- AC3D_4 = rd['AC3D_4']
- SKIP_DATA = rd['SKIP_DATA']
- MIRCOL_AS_AMB = rd['MIRCOL_AS_AMB']
- MIRCOL_AS_EMIS = rd['MIRCOL_AS_EMIS']
- ADD_DEFAULT_MAT = rd['ADD_DEFAULT_MAT']
- SET_TEX_DIR = rd['SET_TEX_DIR']
- TEX_DIR = rd['TEX_DIR']
- EXPORT_DIR = rd['EXPORT_DIR']
- ONLY_SELECTED = rd['ONLY_SELECTED']
- NO_SPLIT = rd['NO_SPLIT']
- PER_FACE_1_OR_2_SIDED = rd['PER_FACE_1_OR_2_SIDED']
- GLOBAL_COORDS = rd['GLOBAL_COORDS']
- except KeyError: update_RegistryInfo()
-
-else:
- update_RegistryInfo()
-
-VERBOSE = True
-CONFIRM_OVERWRITE = True
-
-# check General scripts config key for default behaviors
-rd = Registry.GetKey('General', True)
-if rd:
- try:
- VERBOSE = rd['verbose']
- CONFIRM_OVERWRITE = rd['confirm_overwrite']
- except: pass
-
-
-# The default material to be used when necessary (see ADD_DEFAULT_MAT)
-DEFAULT_MAT = \
-'MATERIAL "DefaultWhite" rgb 1 1 1 amb 1 1 1 emis 0 0 0 \
-spec 0.5 0.5 0.5 shi 64 trans 0'
-
-# This transformation aligns Blender and AC3D coordinate systems:
-BLEND_TO_AC3D_MATRIX = Mathutils.Matrix([1,0,0,0], [0,0,-1,0], [0,1,0,0], [0,0,0,1])
-
-def Round_s(f):
- "Round to default precision and turn value to a string"
- r = round(f,6) # precision set to 10e-06
- if r == int(r):
- return str(int(r))
- else:
- return str(r)
-
-def transform_verts(verts, m):
- vecs = []
- for v in verts:
- x, y, z = v.co
- vec = Mathutils.Vector([x, y, z, 1])
- vecs.append(vec*m)
- return vecs
-
-def get_loose_edges(mesh):
- loose = LOOSE
- return [e for e in mesh.edges if e.flag & loose]
-
-# ---
-
-# meshes with more than one texture assigned
-# are split and saved as these foomeshes
-class FooMesh:
-
- class FooVert:
- def __init__(self, v):
- self.v = v
- self.index = 0
-
- class FooFace:
- def __init__(self, foomesh, f):
- self.f = f
- foov = foomesh.FooVert
- self.v = [foov(f.v[0]), foov(f.v[1])]
- len_fv = len(f.v)
- if len_fv > 2 and f.v[2]:
- self.v.append(foov(f.v[2]))
- if len_fv > 3 and f.v[3]: self.v.append(foov(f.v[3]))
-
- def __getattr__(self, attr):
- if attr == 'v': return self.v
- return getattr(self.f, attr)
-
- def __len__(self):
- return len(self.f)
-
- def __init__(self, tex, faces, mesh):
- self.name = mesh.name
- self.mesh = mesh
- self.looseEdges = []
- self.faceUV = mesh.faceUV
- self.degr = mesh.degr
- vidxs = [0]*len(mesh.verts)
- foofaces = []
- for f in faces:
- foofaces.append(self.FooFace(self, f))
- for v in f.v:
- if v: vidxs[v.index] = 1
- i = 0
- fooverts = []
- for v in mesh.verts:
- if vidxs[v.index]:
- fooverts.append(v)
- vidxs[v.index] = i
- i += 1
- for f in foofaces:
- for v in f.v:
- if v: v.index = vidxs[v.v.index]
- self.faces = foofaces
- self.verts = fooverts
-
-
-class AC3DExport: # the ac3d exporter part
-
- def __init__(self, scene_objects, file):
-
- global ARG, SKIP_DATA, ADD_DEFAULT_MAT, DEFAULT_MAT
-
- header = 'AC3Db'
- self.file = file
- self.buf = ''
- self.mbuf = []
- self.mlist = []
- world_kids = 0
- parents_list = self.parents_list = []
- kids_dict = self.kids_dict = {}
- objs = []
- exp_objs = self.exp_objs = []
- tree = {}
-
- file.write(header+'\n')
-
- objs = \
- [o for o in scene_objects if o.type in ['Mesh', 'Empty']]
-
- # create a tree from parents to children objects
-
- for obj in objs[:]:
- parent = obj.parent
- lineage = [obj]
-
- while parent:
- parents_list.append(parent.name)
- obj = parent
- parent = parent.getParent()
- lineage.insert(0, obj)
-
- d = tree
- for i in xrange(len(lineage)):
- lname = lineage[i].getType()[:2] + lineage[i].name
- if lname not in d.keys():
- d[lname] = {}
- d = d[lname]
-
- # traverse the tree to get an ordered list of names of objects to export
- self.traverse_dict(tree)
-
- world_kids = len(tree.keys())
-
- # get list of objects to export, start writing the .ac file
-
- objlist = [Object.Get(name) for name in exp_objs]
-
- meshlist = [o for o in objlist if o.type == 'Mesh']
-
- # create a temporary mesh to hold actual (modified) mesh data
- TMP_mesh = Mesh.New('tmp_for_ac_export')
-
- # write materials
-
- self.MATERIALS(meshlist, TMP_mesh)
- mbuf = self.mbuf
- if not mbuf or ADD_DEFAULT_MAT:
- mbuf.insert(0, "%s\n" % DEFAULT_MAT)
- mbuf = "".join(mbuf)
- file.write(mbuf)
-
- file.write('OBJECT world\nkids %s\n' % world_kids)
-
- # write the objects
-
- for obj in objlist:
- self.obj = obj
-
- objtype = obj.type
- objname = obj.name
- kidsnum = kids_dict[objname]
-
- # A parent plus its children are exported as a group.
- # If the parent is a mesh, its rot and loc are exported as the
- # group rot and loc and the mesh (w/o rot and loc) is added to the group.
- if kidsnum:
- self.OBJECT('group')
- self.name(objname)
- if objtype == 'Mesh':
- kidsnum += 1
- if not GLOBAL_COORDS:
- localmatrix = obj.getMatrix('localspace')
- if not obj.getParent():
- localmatrix *= BLEND_TO_AC3D_MATRIX
- self.rot(localmatrix.rotationPart())
- self.loc(localmatrix.translationPart())
- self.kids(kidsnum)
-
- if objtype == 'Mesh':
- mesh = TMP_mesh # temporary mesh to hold actual (modified) mesh data
- mesh.getFromObject(objname)
- self.mesh = mesh
- if mesh.faceUV:
- meshes = self.split_mesh(mesh)
- else:
- meshes = [mesh]
- if len(meshes) > 1:
- if NO_SPLIT or self.dont_split(objname):
- self.export_mesh(mesh, ob)
- REPORT_DATA['nosplit'].append(objname)
- else:
- self.OBJECT('group')
- self.name(objname)
- self.kids(len(meshes))
- counter = 0
- for me in meshes:
- self.export_mesh(me, obj,
- name = '%s_%s' % (obj.name, counter), foomesh = True)
- self.kids()
- counter += 1
- else:
- self.export_mesh(mesh, obj)
- self.kids()
-
-
- def traverse_dict(self, d):
- kids_dict = self.kids_dict
- exp_objs = self.exp_objs
- keys = d.keys()
- keys.sort() # sort for predictable output
- keys.reverse()
- for k in keys:
- objname = k[2:]
- klen = len(d[k])
- kids_dict[objname] = klen
- if self.dont_export(objname):
- d.pop(k)
- parent = Object.Get(objname).getParent()
- if parent: kids_dict[parent.name] -= 1
- REPORT_DATA['noexport'].append(objname)
- continue
- if klen:
- self.traverse_dict(d[k])
- exp_objs.insert(0, objname)
- else:
- if k.find('Em', 0) == 0: # Empty w/o children
- d.pop(k)
- parent = Object.Get(objname).getParent()
- if parent: kids_dict[parent.name] -= 1
- else:
- exp_objs.insert(0, objname)
-
- def dont_export(self, name): # if name starts with '!' or '#'
- length = len(name)
- if length >= 1:
- if name[0] in TOKENS_DONT_EXPORT: # '!' or '#' doubled (escaped): export
- if length > 1 and name[1] == name[0]:
- return 0
- return 1
-
- def dont_split(self, name): # if name starts with '=' or '$'
- length = len(name)
- if length >= 1:
- if name[0] in TOKENS_DONT_SPLIT: # '=' or '$' doubled (escaped): split
- if length > 1 and name[1] == name[0]:
- return 0
- return 1
-
- def split_mesh(self, mesh):
- tex_dict = {0:[]}
- for f in mesh.faces:
- if f.image:
- if not f.image.name in tex_dict: tex_dict[f.image.name] = []
- tex_dict[f.image.name].append(f)
- else: tex_dict[0].append(f)
- keys = tex_dict.keys()
- len_keys = len(keys)
- if not tex_dict[0]:
- len_keys -= 1
- tex_dict.pop(0)
- keys.remove(0)
- elif len_keys > 1:
- lines = []
- anyimgkey = [k for k in keys if k != 0][0]
- for f in tex_dict[0]:
- if len(f.v) < 3:
- lines.append(f)
- if len(tex_dict[0]) == len(lines):
- for l in lines:
- tex_dict[anyimgkey].append(l)
- len_keys -= 1
- tex_dict.pop(0)
- if len_keys > 1:
- foo_meshes = []
- for k in keys:
- faces = tex_dict[k]
- foo_meshes.append(FooMesh(k, faces, mesh))
- foo_meshes[0].edges = get_loose_edges(mesh)
- return foo_meshes
- return [mesh]
-
- def export_mesh(self, mesh, obj, name = None, foomesh = False):
- file = self.file
- self.OBJECT('poly')
- if not name: name = obj.name
- self.name(name)
- if not SKIP_DATA:
- meshname = obj.getData(name_only = True)
- self.data(len(meshname), meshname)
- if mesh.faceUV:
- texline = self.texture(mesh.faces)
- if texline: file.write(texline)
- if AC3D_4:
- self.crease(mesh.degr)
-
- # If exporting using local coordinates, children object coordinates should not be
- # transformed to ac3d's coordinate system, since that will be accounted for in
- # their topmost parents (the parents w/o parents) transformations.
- if not GLOBAL_COORDS:
- # We hold parents in a list, so they also don't get transformed,
- # because for each parent we create an ac3d group to hold both the
- # parent and its children.
- if obj.name not in self.parents_list:
- localmatrix = obj.getMatrix('localspace')
- if not obj.getParent():
- localmatrix *= BLEND_TO_AC3D_MATRIX
- self.rot(localmatrix.rotationPart())
- self.loc(localmatrix.translationPart())
- matrix = None
- else:
- matrix = obj.getMatrix() * BLEND_TO_AC3D_MATRIX
-
- self.numvert(mesh.verts, matrix)
- self.numsurf(mesh, foomesh)
-
- def MATERIALS(self, meshlist, me):
- for meobj in meshlist:
- me.getFromObject(meobj)
- mats = me.materials
- mbuf = []
- mlist = self.mlist
- for m in mats:
- if not m: continue
- name = m.name
- if name not in mlist:
- mlist.append(name)
- M = Material.Get(name)
- material = 'MATERIAL "%s"' % name
- mirCol = "%s %s %s" % (Round_s(M.mirCol[0]), Round_s(M.mirCol[1]),
- Round_s(M.mirCol[2]))
- rgb = "rgb %s %s %s" % (Round_s(M.R), Round_s(M.G), Round_s(M.B))
- ambval = Round_s(M.amb)
- amb = "amb %s %s %s" % (ambval, ambval, ambval)
- spec = "spec %s %s %s" % (Round_s(M.specCol[0]),
- Round_s(M.specCol[1]), Round_s(M.specCol[2]))
- if AC3D_4:
- emit = Round_s(M.emit)
- emis = "emis %s %s %s" % (emit, emit, emit)
- shival = int(M.spec * 64)
- else:
- emis = "emis 0 0 0"
- shival = 72
- shi = "shi %s" % shival
- trans = "trans %s" % (Round_s(1 - M.alpha))
- if MIRCOL_AS_AMB:
- amb = "amb %s" % mirCol
- if MIRCOL_AS_EMIS:
- emis = "emis %s" % mirCol
- mbuf.append("%s %s %s %s %s %s %s\n" \
- % (material, rgb, amb, emis, spec, shi, trans))
- self.mlist = mlist
- self.mbuf.append("".join(mbuf))
-
- def OBJECT(self, type):
- self.file.write('OBJECT %s\n' % type)
-
- def name(self, name):
- if name[0] in TOKENS_DONT_EXPORT or name[0] in TOKENS_DONT_SPLIT:
- if len(name) > 1: name = name[1:]
- self.file.write('name "%s"\n' % name)
-
- def kids(self, num = 0):
- self.file.write('kids %s\n' % num)
-
- def data(self, num, str):
- self.file.write('data %s\n%s\n' % (num, str))
-
- def texture(self, faces):
- tex = ""
- for f in faces:
- if f.image:
- tex = f.image.name
- break
- if tex:
- image = Image.Get(tex)
- texfname = image.filename
- if SET_TEX_DIR:
- texfname = bsys.basename(texfname)
- if TEX_DIR:
- texfname = bsys.join(TEX_DIR, texfname)
- buf = 'texture "%s"\n' % texfname
- xrep = image.xrep
- yrep = image.yrep
- buf += 'texrep %s %s\n' % (xrep, yrep)
- self.file.write(buf)
-
- def rot(self, matrix):
- rot = ''
- not_I = 0 # not identity
- matstr = []
- for i in [0, 1, 2]:
- r = map(Round_s, matrix[i])
- not_I += (r[0] != '0')+(r[1] != '0')+(r[2] != '0')
- not_I -= (r[i] == '1')
- for j in [0, 1, 2]:
- matstr.append(' %s' % r[j])
- if not_I: # no need to write identity
- self.file.write('rot%s\n' % "".join(matstr))
-
- def loc(self, loc):
- loc = map(Round_s, loc)
- if loc != ['0', '0', '0']: # no need to write default
- self.file.write('loc %s %s %s\n' % (loc[0], loc[1], loc[2]))
-
- def crease(self, crease):
- self.file.write('crease %f\n' % crease)
-
- def numvert(self, verts, matrix):
- file = self.file
- nvstr = []
- nvstr.append("numvert %s\n" % len(verts))
-
- if matrix:
- verts = transform_verts(verts, matrix)
- for v in verts:
- v = map (Round_s, v)
- nvstr.append("%s %s %s\n" % (v[0], v[1], v[2]))
- else:
- for v in verts:
- v = map(Round_s, v.co)
- nvstr.append("%s %s %s\n" % (v[0], v[1], v[2]))
-
- file.write("".join(nvstr))
-
- def numsurf(self, mesh, foomesh = False):
-
- global MATIDX_ERROR
-
- # local vars are faster and so better in tight loops
- lc_ADD_DEFAULT_MAT = ADD_DEFAULT_MAT
- lc_MATIDX_ERROR = MATIDX_ERROR
- lc_PER_FACE_1_OR_2_SIDED = PER_FACE_1_OR_2_SIDED
- lc_FACE_TWOSIDED = FACE_TWOSIDED
- lc_MESH_TWOSIDED = MESH_TWOSIDED
-
- faces = mesh.faces
- hasFaceUV = mesh.faceUV
- if foomesh:
- looseEdges = mesh.looseEdges
- else:
- looseEdges = get_loose_edges(mesh)
-
- file = self.file
-
- file.write("numsurf %s\n" % (len(faces) + len(looseEdges)))
-
- if not foomesh: verts = list(self.mesh.verts)
-
- materials = self.mesh.materials
- mlist = self.mlist
- matidx_error_reported = False
- objmats = []
- for omat in materials:
- if omat: objmats.append(omat.name)
- else: objmats.append(None)
- for f in faces:
- if not objmats:
- m_idx = 0
- elif objmats[f.mat] in mlist:
- m_idx = mlist.index(objmats[f.mat])
- else:
- if not lc_MATIDX_ERROR:
- rdat = REPORT_DATA['warns']
- rdat.append("Object %s" % self.obj.name)
- rdat.append("has at least one material *index* assigned but not")
- rdat.append("defined (not linked to an existing material).")
- rdat.append("Result: some faces may be exported with a wrong color.")
- rdat.append("You can assign materials in the Edit Buttons window (F9).")
- elif not matidx_error_reported:
- midxmsg = "- Same for object %s." % self.obj.name
- REPORT_DATA['warns'].append(midxmsg)
- lc_MATIDX_ERROR += 1
- matidx_error_reported = True
- m_idx = 0
- if lc_ADD_DEFAULT_MAT: m_idx -= 1
- refs = len(f)
- flaglow = 0 # polygon
- if lc_PER_FACE_1_OR_2_SIDED and hasFaceUV: # per face attribute
- two_side = f.mode & lc_FACE_TWOSIDED
- else: # global, for the whole mesh
- two_side = self.mesh.mode & lc_MESH_TWOSIDED
- two_side = (two_side > 0) << 1
- flaghigh = f.smooth | two_side
- surfstr = "SURF 0x%d%d\n" % (flaghigh, flaglow)
- if lc_ADD_DEFAULT_MAT and objmats: m_idx += 1
- matstr = "mat %s\n" % m_idx
- refstr = "refs %s\n" % refs
- u, v, vi = 0, 0, 0
- fvstr = []
- if foomesh:
- for vert in f.v:
- fvstr.append(str(vert.index))
- if hasFaceUV:
- u = f.uv[vi][0]
- v = f.uv[vi][1]
- vi += 1
- fvstr.append(" %s %s\n" % (u, v))
- else:
- for vert in f.v:
- fvstr.append(str(verts.index(vert)))
- if hasFaceUV:
- u = f.uv[vi][0]
- v = f.uv[vi][1]
- vi += 1
- fvstr.append(" %s %s\n" % (u, v))
-
- fvstr = "".join(fvstr)
-
- file.write("%s%s%s%s" % (surfstr, matstr, refstr, fvstr))
-
- # material for loose edges
- edges_mat = 0 # default to first material
- for omat in objmats: # but look for a material from this mesh
- if omat in mlist:
- edges_mat = mlist.index(omat)
- if lc_ADD_DEFAULT_MAT: edges_mat += 1
- break
-
- for e in looseEdges:
- fvstr = []
- #flaglow = 2 # 1 = closed line, 2 = line
- #flaghigh = 0
- #surfstr = "SURF 0x%d%d\n" % (flaghigh, flaglow)
- surfstr = "SURF 0x02\n"
-
- fvstr.append("%d 0 0\n" % verts.index(e.v1))
- fvstr.append("%d 0 0\n" % verts.index(e.v2))
- fvstr = "".join(fvstr)
-
- matstr = "mat %d\n" % edges_mat # for now, use first material
- refstr = "refs 2\n" # 2 verts
-
- file.write("%s%s%s%s" % (surfstr, matstr, refstr, fvstr))
-
- MATIDX_ERROR = lc_MATIDX_ERROR
-
-# End of Class AC3DExport
-
-from Blender.Window import FileSelector
-
-def report_data():
- global VERBOSE
-
- if not VERBOSE: return
-
- d = REPORT_DATA
- msgs = {
- '0main': '%s\nExporting meshes to AC3D format' % str(19*'-'),
- '1warns': 'Warnings',
- '2errors': 'Errors',
- '3nosplit': 'Not split (because name starts with "=" or "$")',
- '4noexport': 'Not exported (because name starts with "!" or "#")'
- }
- if NO_SPLIT:
- l = msgs['3nosplit']
- l = "%s (because OPTION NO_SPLIT is set)" % l.split('(')[0]
- msgs['3nosplit'] = l
- keys = msgs.keys()
- keys.sort()
- for k in keys:
- msgk = msgs[k]
- msg = '\n'.join(d[k[1:]])
- if msg:
- print '\n-%s:' % msgk
- print msg
-
-# File Selector callback:
-def fs_callback(filename):
- global EXPORT_DIR, OBJS, CONFIRM_OVERWRITE, VERBOSE
-
- if not filename.endswith('.ac'): filename = '%s.ac' % filename
-
- if bsys.exists(filename) and CONFIRM_OVERWRITE:
- if Blender.Draw.PupMenu('OVERWRITE?%t|File exists') != 1:
- return
-
- Blender.Window.WaitCursor(1)
- starttime = bsys.time()
-
- export_dir = bsys.dirname(filename)
- if export_dir != EXPORT_DIR:
- EXPORT_DIR = export_dir
- update_RegistryInfo()
-
- try:
- file = open(filename, 'w')
- except IOError, (errno, strerror):
- error = "IOError #%s: %s" % (errno, strerror)
- REPORT_DATA['errors'].append("Saving failed - %s." % error)
- error_msg = "Couldn't save file!%%t|%s" % error
- Blender.Draw.PupMenu(error_msg)
- return
-
- try:
- test = AC3DExport(OBJS, file)
- except:
- file.close()
- raise
- else:
- file.close()
- endtime = bsys.time() - starttime
- REPORT_DATA['main'].append("Done. Saved to: %s" % filename)
- REPORT_DATA['main'].append("Data exported in %.3f seconds." % endtime)
-
- if VERBOSE: report_data()
- Blender.Window.WaitCursor(0)
-
-
-# -- End of definitions
-
-scn = Blender.Scene.GetCurrent()
-
-if ONLY_SELECTED:
- OBJS = list(scn.objects.context)
-else:
- OBJS = list(scn.objects)
-
-if not OBJS:
- Blender.Draw.PupMenu('ERROR: no objects selected')
-else:
- fname = bsys.makename(ext=".ac")
- if EXPORT_DIR:
- fname = bsys.join(EXPORT_DIR, bsys.basename(fname))
- FileSelector(fs_callback, "Export AC3D", fname)
diff --git a/release/scripts/ac3d_import.py b/release/scripts/ac3d_import.py
deleted file mode 100644
index 2f5512e7150..00000000000
--- a/release/scripts/ac3d_import.py
+++ /dev/null
@@ -1,783 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus:
-Name: 'AC3D (.ac)...'
-Blender: 243
-Group: 'Import'
-Tip: 'Import an AC3D (.ac) file.'
-"""
-
-__author__ = "Willian P. Germano"
-__url__ = ("blender", "blenderartists.org", "AC3D's homepage, http://www.ac3d.org",
- "PLib 3d gaming lib, http://plib.sf.net")
-__version__ = "2.48.1 2009-01-11"
-
-__bpydoc__ = """\
-This script imports AC3D models into Blender.
-
-AC3D is a simple and affordable commercial 3d modeller also built with OpenGL.
-The .ac file format is an easy to parse text format well supported,
-for example, by the PLib 3d gaming library.
-
-Supported:<br>
- UV-textured meshes with hierarchy (grouping) information.
-
-Missing:<br>
- The url tag is irrelevant for Blender.
-
-Known issues:<br>
- - Some objects may be imported with wrong normals due to wrong information in the model itself. This can be noticed by strange shading, like darker than expected parts in the model. To fix this, select the mesh with wrong normals, enter edit mode and tell Blender to recalculate the normals, either to make them point outside (the usual case) or inside.<br>
-
-Config Options:<br>
- - display transp (toggle): if "on", objects that have materials with alpha < 1.0 are shown with translucency (transparency) in the 3D View.<br>
- - subdiv (toggle): if "on", ac3d objects meant to be subdivided receive a SUBSURF modifier in Blender.<br>
- - emis as mircol: store the emissive rgb color from AC3D as mirror color in Blender -- this is a hack to preserve the values and be able to export them using the equivalent option in the exporter.<br>
- - textures dir (string): if non blank, when imported texture paths are
-wrong in the .ac file, Blender will also look for them at this dir.
-
-Notes:<br>
- - When looking for assigned textures, Blender tries in order: the actual
-paths from the .ac file, the .ac file's dir and the default textures dir path
-users can configure (see config options above).
-"""
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# AC3DImport version 2.43.1 Feb 21, 2007
-# Program versions: Blender 2.43 and AC3Db files (means version 0xb)
-# changed: better triangulation of ngons, more fixes to support bad .ac files,
-# option to display transp mats in 3d view, support "subdiv" tag (via SUBSURF modifier)
-# --------------------------------------------------------------------------
-# Thanks: Melchior Franz for extensive bug testing and reporting, making this
-# version cope much better with old or bad .ac files, among other improvements;
-# Stewart Andreason for reporting a serious crash; Francesco Brisa for the
-# emis as mircol functionality (w/ patch).
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004-2009: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-from math import radians
-
-import Blender
-from Blender import Scene, Object, Mesh, Lamp, Registry, sys as bsys, Window, Image, Material, Modifier
-from Blender.sys import dirsep
-from Blender.Mathutils import Vector, Matrix, Euler
-from Blender.Geometry import PolyFill
-
-# Default folder for AC3D textures, to override wrong paths, change to your
-# liking or leave as "":
-TEXTURES_DIR = ""
-
-DISPLAY_TRANSP = True
-
-SUBDIV = True
-
-EMIS_AS_MIRCOL = False
-
-
-tooltips = {
- 'DISPLAY_TRANSP': 'Turn transparency on in the 3d View for objects using materials with alpha < 1.0.',
- 'SUBDIV': 'Apply a SUBSURF modifier to objects meant to appear subdivided.',
- 'TEXTURES_DIR': 'Additional folder to look for missing textures.',
- 'EMIS_AS_MIRCOL': 'Store emis color as mirror color in Blender.'
-}
-
-def update_registry():
- global TEXTURES_DIR, DISPLAY_TRANSP, EMIS_AS_MIRCOL
- rd = dict([('tooltips', tooltips), ('TEXTURES_DIR', TEXTURES_DIR), ('DISPLAY_TRANSP', DISPLAY_TRANSP), ('SUBDIV', SUBDIV), ('EMIS_AS_MIRCOL', EMIS_AS_MIRCOL)])
- Registry.SetKey('ac3d_import', rd, True)
-
-rd = Registry.GetKey('ac3d_import', True)
-
-if rd:
- if 'GROUP' in rd:
- update_registry()
- try:
- TEXTURES_DIR = rd['TEXTURES_DIR']
- DISPLAY_TRANSP = rd['DISPLAY_TRANSP']
- SUBDIV = rd['SUBDIV']
- EMIS_AS_MIRCOL = rd['EMIS_AS_MIRCOL']
- except:
- update_registry()
-else: update_registry()
-
-if TEXTURES_DIR:
- oldtexdir = TEXTURES_DIR
- if dirsep == '/': TEXTURES_DIR = TEXTURES_DIR.replace('\\', '/')
- if TEXTURES_DIR[-1] != dirsep: TEXTURES_DIR = "%s%s" % (TEXTURES_DIR, dirsep)
- if oldtexdir != TEXTURES_DIR: update_registry()
-
-
-VERBOSE = True
-rd = Registry.GetKey('General', True)
-if rd:
- if rd.has_key('verbose'):
- VERBOSE = rd['verbose']
-
-
-errmsg = ""
-
-# Matrix to align ac3d's coordinate system with Blender's one,
-# it's a -90 degrees rotation around the x axis:
-AC_TO_BLEND_MATRIX = Matrix([1, 0, 0], [0, 0, 1], [0, -1, 0])
-
-AC_WORLD = 0
-AC_GROUP = 1
-AC_POLY = 2
-AC_LIGHT = 3
-AC_OB_TYPES = {
- 'world': AC_WORLD,
- 'group': AC_GROUP,
- 'poly': AC_POLY,
- 'light': AC_LIGHT
- }
-
-AC_OB_BAD_TYPES_LIST = [] # to hold references to unknown (wrong) ob types
-
-def inform(msg):
- global VERBOSE
- if VERBOSE: print msg
-
-def euler_in_radians(eul):
- "Used while there's a bug in the BPY API"
- eul.x = radians(eul.x)
- eul.y = radians(eul.y)
- eul.z = radians(eul.z)
- return eul
-
-class Obj:
-
- def __init__(self, type):
- self.type = type
- self.dad = None
- self.name = ''
- self.data = ''
- self.tex = ''
- self.texrep = [1,1]
- self.texoff = None
- self.loc = []
- self.rot = []
- self.size = []
- self.crease = 30
- self.subdiv = 0
- self.vlist = []
- self.flist_cfg = []
- self.flist_v = []
- self.flist_uv = []
- self.elist = []
- self.matlist = []
- self.kids = 0
-
- self.bl_obj = None # the actual Blender object created from this data
-
-class AC3DImport:
-
- def __init__(self, filename):
-
- global errmsg
-
- self.scene = Scene.GetCurrent()
-
- self.i = 0
- errmsg = ''
- self.importdir = bsys.dirname(filename)
- try:
- file = open(filename, 'r')
- except IOError, (errno, strerror):
- errmsg = "IOError #%s: %s" % (errno, strerror)
- Blender.Draw.PupMenu('ERROR: %s' % errmsg)
- inform(errmsg)
- return None
- header = file.read(5)
- header, version = header[:4], header[-1]
- if header != 'AC3D':
- file.close()
- errmsg = 'AC3D header not found (invalid file)'
- Blender.Draw.PupMenu('ERROR: %s' % errmsg)
- inform(errmsg)
- return None
- elif version != 'b':
- inform('AC3D file version 0x%s.' % version)
- inform('This importer is for version 0xb, so it may fail.')
-
- self.token = {'OBJECT': self.parse_obj,
- 'numvert': self.parse_vert,
- 'numsurf': self.parse_surf,
- 'name': self.parse_name,
- 'data': self.parse_data,
- 'kids': self.parse_kids,
- 'loc': self.parse_loc,
- 'rot': self.parse_rot,
- 'MATERIAL': self.parse_mat,
- 'texture': self.parse_tex,
- 'texrep': self.parse_texrep,
- 'texoff': self.parse_texoff,
- 'subdiv': self.parse_subdiv,
- 'crease': self.parse_crease}
-
- self.objlist = []
- self.mlist = []
- self.kidsnumlist = []
- self.dad = None
-
- self.lines = file.readlines()
- self.lines.append('')
- self.parse_file()
- file.close()
-
- self.testAC3DImport()
-
- def parse_obj(self, value):
- kidsnumlist = self.kidsnumlist
- if kidsnumlist:
- while not kidsnumlist[-1]:
- kidsnumlist.pop()
- if kidsnumlist:
- self.dad = self.dad.dad
- else:
- inform('Ignoring unexpected data at end of file.')
- return -1 # bad file with more objects than reported
- kidsnumlist[-1] -= 1
- if value in AC_OB_TYPES:
- new = Obj(AC_OB_TYPES[value])
- else:
- if value not in AC_OB_BAD_TYPES_LIST:
- AC_OB_BAD_TYPES_LIST.append(value)
- inform('Unexpected object type keyword: "%s". Assuming it is of type: "poly".' % value)
- new = Obj(AC_OB_TYPES['poly'])
- new.dad = self.dad
- new.name = value
- self.objlist.append(new)
-
- def parse_kids(self, value):
- kids = int(value)
- if kids:
- self.kidsnumlist.append(kids)
- self.dad = self.objlist[-1]
- self.objlist[-1].kids = kids
-
- def parse_name(self, value):
- name = value.split('"')[1]
- self.objlist[-1].name = name
-
- def parse_data(self, value):
- data = self.lines[self.i].strip()
- self.objlist[-1].data = data
-
- def parse_tex(self, value):
- line = self.lines[self.i - 1] # parse again to properly get paths with spaces
- texture = line.split('"')[1]
- self.objlist[-1].tex = texture
-
- def parse_texrep(self, trash):
- trep = self.lines[self.i - 1]
- trep = trep.split()
- trep = [float(trep[1]), float(trep[2])]
- self.objlist[-1].texrep = trep
- self.objlist[-1].texoff = [0, 0]
-
- def parse_texoff(self, trash):
- toff = self.lines[self.i - 1]
- toff = toff.split()
- toff = [float(toff[1]), float(toff[2])]
- self.objlist[-1].texoff = toff
-
- def parse_mat(self, value):
- i = self.i - 1
- lines = self.lines
- line = lines[i].split()
- mat_name = ''
- mat_col = mat_amb = mat_emit = mat_spec_col = mat_mir_col = [0,0,0]
- mat_alpha = 1
- mat_spec = 1.0
-
- while line[0] == 'MATERIAL':
- mat_name = line[1].split('"')[1]
- mat_col = map(float,[line[3],line[4],line[5]])
- v = map(float,[line[7],line[8],line[9]])
- mat_amb = (v[0]+v[1]+v[2]) / 3.0
- v = map(float,[line[11],line[12],line[13]])
- mat_emit = (v[0]+v[1]+v[2]) / 3.0
- if EMIS_AS_MIRCOL:
- mat_emit = 0
- mat_mir_col = map(float,[line[11],line[12],line[13]])
-
- mat_spec_col = map(float,[line[15],line[16],line[17]])
- mat_spec = float(line[19]) / 64.0
- mat_alpha = float(line[-1])
- mat_alpha = 1 - mat_alpha
- self.mlist.append([mat_name, mat_col, mat_amb, mat_emit, mat_spec_col, mat_spec, mat_mir_col, mat_alpha])
- i += 1
- line = lines[i].split()
-
- self.i = i
-
- def parse_rot(self, trash):
- i = self.i - 1
- ob = self.objlist[-1]
- rot = self.lines[i].split(' ', 1)[1]
- rot = map(float, rot.split())
- matrix = Matrix(rot[:3], rot[3:6], rot[6:])
- ob.rot = matrix
- size = matrix.scalePart() # vector
- ob.size = size
-
- def parse_loc(self, trash):
- i = self.i - 1
- loc = self.lines[i].split(' ', 1)[1]
- loc = map(float, loc.split())
- self.objlist[-1].loc = Vector(loc)
-
- def parse_crease(self, value):
- # AC3D: range is [0.0, 180.0]; Blender: [1, 80]
- value = float(value)
- self.objlist[-1].crease = int(value)
-
- def parse_subdiv(self, value):
- self.objlist[-1].subdiv = int(value)
-
- def parse_vert(self, value):
- i = self.i
- lines = self.lines
- obj = self.objlist[-1]
- vlist = obj.vlist
- n = int(value)
-
- while n:
- line = lines[i].split()
- line = map(float, line)
- vlist.append(line)
- n -= 1
- i += 1
-
- if vlist: # prepend a vertex at 1st position to deal with vindex 0 issues
- vlist.insert(0, line)
-
- self.i = i
-
- def parse_surf(self, value):
- i = self.i
- is_smooth = 0
- double_sided = 0
- lines = self.lines
- obj = self.objlist[-1]
- vlist = obj.vlist
- matlist = obj.matlist
- numsurf = int(value)
- NUMSURF = numsurf
-
- badface_notpoly = badface_multirefs = 0
-
- while numsurf:
- flags = lines[i].split()[1][2:]
- if len(flags) > 1:
- flaghigh = int(flags[0])
- flaglow = int(flags[1])
- else:
- flaghigh = 0
- flaglow = int(flags[0])
-
- is_smooth = flaghigh & 1
- twoside = flaghigh & 2
- nextline = lines[i+1].split()
- if nextline[0] != 'mat': # the "mat" line may be missing (found in one buggy .ac file)
- matid = 0
- if not matid in matlist: matlist.append(matid)
- i += 2
- else:
- matid = int(nextline[1])
- if not matid in matlist: matlist.append(matid)
- nextline = lines[i+2].split()
- i += 3
- refs = int(nextline[1])
- face = []
- faces = []
- edges = []
- fuv = []
- fuvs = []
- rfs = refs
-
- while rfs:
- line = lines[i].split()
- v = int(line[0]) + 1 # + 1 to avoid vindex == 0
- uv = [float(line[1]), float(line[2])]
- face.append(v)
- fuv.append(Vector(uv))
- rfs -= 1
- i += 1
-
- if flaglow: # it's a line or closed line, not a polygon
- while len(face) >= 2:
- cut = face[:2]
- edges.append(cut)
- face = face[1:]
-
- if flaglow == 1 and edges: # closed line
- face = [edges[-1][-1], edges[0][0]]
- edges.append(face)
-
- else: # polygon
-
- # check for bad face, that references same vertex more than once
- lenface = len(face)
- if lenface < 3:
- # less than 3 vertices, not a face
- badface_notpoly += 1
- elif sum(map(face.count, face)) != lenface:
- # multiple references to the same vertex
- badface_multirefs += 1
- else: # ok, seems fine
- if len(face) > 4: # ngon, triangulate it
- polyline = []
- for vi in face:
- polyline.append(Vector(vlist[vi]))
- tris = PolyFill([polyline])
- for t in tris:
- tri = [face[t[0]], face[t[1]], face[t[2]]]
- triuvs = [fuv[t[0]], fuv[t[1]], fuv[t[2]]]
- faces.append(tri)
- fuvs.append(triuvs)
- else: # tri or quad
- faces.append(face)
- fuvs.append(fuv)
-
- obj.flist_cfg.extend([[matid, is_smooth, twoside]] * len(faces))
- obj.flist_v.extend(faces)
- obj.flist_uv.extend(fuvs)
- obj.elist.extend(edges) # loose edges
-
- numsurf -= 1
-
- if badface_notpoly or badface_multirefs:
- inform('Object "%s" - ignoring bad faces:' % obj.name)
- if badface_notpoly:
- inform('\t%d face(s) with less than 3 vertices.' % badface_notpoly)
- if badface_multirefs:
- inform('\t%d face(s) with multiple references to a same vertex.' % badface_multirefs)
-
- self.i = i
-
- def parse_file(self):
- i = 1
- lines = self.lines
- line = lines[i].split()
-
- while line:
- kw = ''
- for k in self.token.keys():
- if line[0] == k:
- kw = k
- break
- i += 1
- if kw:
- self.i = i
- result = self.token[kw](line[1])
- if result:
- break # bad .ac file, stop parsing
- i = self.i
- line = lines[i].split()
-
- # for each group of meshes we try to find one that can be used as
- # parent of the group in Blender.
- # If not found, we can use an Empty as parent.
- def found_parent(self, groupname, olist):
- l = [o for o in olist if o.type == AC_POLY \
- and not o.kids and not o.rot and not o.loc]
- if l:
- for o in l:
- if o.name == groupname:
- return o
- #return l[0]
- return None
-
- def build_hierarchy(self):
- blmatrix = AC_TO_BLEND_MATRIX
-
- olist = self.objlist[1:]
- olist.reverse()
-
- scene = self.scene
-
- newlist = []
-
- for o in olist:
- kids = o.kids
- if kids:
- children = newlist[-kids:]
- newlist = newlist[:-kids]
- if o.type == AC_GROUP:
- parent = self.found_parent(o.name, children)
- if parent:
- children.remove(parent)
- o.bl_obj = parent.bl_obj
- else: # not found, use an empty
- empty = scene.objects.new('Empty', o.name)
- o.bl_obj = empty
-
- bl_children = [c.bl_obj for c in children if c.bl_obj != None]
-
- o.bl_obj.makeParent(bl_children, 0, 1)
- for child in children:
- blob = child.bl_obj
- if not blob: continue
- if child.rot:
- eul = euler_in_radians(child.rot.toEuler())
- blob.setEuler(eul)
- if child.size:
- blob.size = child.size
- if not child.loc:
- child.loc = Vector(0.0, 0.0, 0.0)
- blob.setLocation(child.loc)
-
- newlist.append(o)
-
- for o in newlist: # newlist now only has objs w/o parents
- blob = o.bl_obj
- if not blob:
- continue
- if o.size:
- o.bl_obj.size = o.size
- if not o.rot:
- blob.setEuler([1.5707963267948966, 0, 0])
- else:
- matrix = o.rot * blmatrix
- eul = euler_in_radians(matrix.toEuler())
- blob.setEuler(eul)
- if o.loc:
- o.loc *= blmatrix
- else:
- o.loc = Vector(0.0, 0.0, 0.0)
- blob.setLocation(o.loc) # forces DAG update, so we do it even for 0, 0, 0
-
- # XXX important: until we fix the BPy API so it doesn't increase user count
- # when wrapping a Blender object, this piece of code is needed for proper
- # object (+ obdata) deletion in Blender:
- for o in self.objlist:
- if o.bl_obj:
- o.bl_obj = None
-
- def testAC3DImport(self):
-
- FACE_TWOSIDE = Mesh.FaceModes['TWOSIDE']
- FACE_TEX = Mesh.FaceModes['TEX']
- MESH_AUTOSMOOTH = Mesh.Modes['AUTOSMOOTH']
-
- MAT_MODE_ZTRANSP = Material.Modes['ZTRANSP']
- MAT_MODE_TRANSPSHADOW = Material.Modes['TRANSPSHADOW']
-
- scene = self.scene
-
- bl_images = {} # loaded texture images
- missing_textures = [] # textures we couldn't find
-
- objlist = self.objlist[1:] # skip 'world'
-
- bmat = []
- has_transp_mats = False
- for mat in self.mlist:
- name = mat[0]
- m = Material.New(name)
- m.rgbCol = (mat[1][0], mat[1][1], mat[1][2])
- m.amb = mat[2]
- m.emit = mat[3]
- m.specCol = (mat[4][0], mat[4][1], mat[4][2])
- m.spec = mat[5]
- m.mirCol = (mat[6][0], mat[6][1], mat[6][2])
- m.alpha = mat[7]
- if m.alpha < 1.0:
- m.mode |= MAT_MODE_ZTRANSP
- has_transp_mats = True
- bmat.append(m)
-
- if has_transp_mats:
- for mat in bmat:
- mat.mode |= MAT_MODE_TRANSPSHADOW
-
- obj_idx = 0 # index of current obj in loop
- for obj in objlist:
- if obj.type == AC_GROUP:
- continue
- elif obj.type == AC_LIGHT:
- light = Lamp.New('Lamp')
- object = scene.objects.new(light, obj.name)
- #object.select(True)
- obj.bl_obj = object
- if obj.data:
- light.name = obj.data
- continue
-
- # type AC_POLY:
-
- # old .ac files used empty meshes as groups, convert to a real ac group
- if not obj.vlist and obj.kids:
- obj.type = AC_GROUP
- continue
-
- mesh = Mesh.New()
- object = scene.objects.new(mesh, obj.name)
- #object.select(True)
- obj.bl_obj = object
- if obj.data: mesh.name = obj.data
- mesh.degr = obj.crease # will auto clamp to [1, 80]
-
- if not obj.vlist: # no vertices? nothing more to do
- continue
-
- mesh.verts.extend(obj.vlist)
-
- objmat_indices = []
- for mat in bmat:
- if bmat.index(mat) in obj.matlist:
- objmat_indices.append(bmat.index(mat))
- mesh.materials += [mat]
- if DISPLAY_TRANSP and mat.alpha < 1.0:
- object.transp = True
-
- for e in obj.elist:
- mesh.edges.extend(e)
-
- if obj.flist_v:
- mesh.faces.extend(obj.flist_v)
-
- facesnum = len(mesh.faces)
-
- if facesnum == 0: # shouldn't happen, of course
- continue
-
- mesh.faceUV = True
-
- # checking if the .ac file had duplicate faces (Blender ignores them)
- if facesnum != len(obj.flist_v):
- # it has, ugh. Let's clean the uv list:
- lenfl = len(obj.flist_v)
- flist = obj.flist_v
- uvlist = obj.flist_uv
- cfglist = obj.flist_cfg
- for f in flist:
- f.sort()
- fi = lenfl
- while fi > 0: # remove data related to duplicates
- fi -= 1
- if flist[fi] in flist[:fi]:
- uvlist.pop(fi)
- cfglist.pop(fi)
-
- img = None
- if obj.tex != '':
- if obj.tex in bl_images.keys():
- img = bl_images[obj.tex]
- elif obj.tex not in missing_textures:
- texfname = None
- objtex = obj.tex
- baseimgname = bsys.basename(objtex)
- if bsys.exists(objtex) == 1:
- texfname = objtex
- elif bsys.exists(bsys.join(self.importdir, objtex)):
- texfname = bsys.join(self.importdir, objtex)
- else:
- if baseimgname.find('\\') > 0:
- baseimgname = bsys.basename(objtex.replace('\\','/'))
- objtex = bsys.join(self.importdir, baseimgname)
- if bsys.exists(objtex) == 1:
- texfname = objtex
- else:
- objtex = bsys.join(TEXTURES_DIR, baseimgname)
- if bsys.exists(objtex):
- texfname = objtex
- if texfname:
- try:
- img = Image.Load(texfname)
- # Commented because it's unnecessary:
- #img.xrep = int(obj.texrep[0])
- #img.yrep = int(obj.texrep[1])
- if img:
- bl_images[obj.tex] = img
- except:
- inform("Couldn't load texture: %s" % baseimgname)
- else:
- missing_textures.append(obj.tex)
- inform("Couldn't find texture: %s" % baseimgname)
-
- for i in range(facesnum):
- f = obj.flist_cfg[i]
- fmat = f[0]
- is_smooth = f[1]
- twoside = f[2]
- bface = mesh.faces[i]
- bface.smooth = is_smooth
- if twoside: bface.mode |= FACE_TWOSIDE
- if img:
- bface.mode |= FACE_TEX
- bface.image = img
- bface.mat = objmat_indices.index(fmat)
- fuv = obj.flist_uv[i]
- if obj.texoff:
- uoff = obj.texoff[0]
- voff = obj.texoff[1]
- urep = obj.texrep[0]
- vrep = obj.texrep[1]
- for uv in fuv:
- uv[0] *= urep
- uv[1] *= vrep
- uv[0] += uoff
- uv[1] += voff
-
- mesh.faces[i].uv = fuv
-
- # finally, delete the 1st vertex we added to prevent vindices == 0
- mesh.verts.delete(0)
-
- mesh.calcNormals()
-
- mesh.mode = MESH_AUTOSMOOTH
-
- # subdiv: create SUBSURF modifier in Blender
- if SUBDIV and obj.subdiv > 0:
- subdiv = obj.subdiv
- subdiv_render = subdiv
- # just to be safe:
- if subdiv_render > 6: subdiv_render = 6
- if subdiv > 3: subdiv = 3
- modif = object.modifiers.append(Modifier.Types.SUBSURF)
- modif[Modifier.Settings.LEVELS] = subdiv
- modif[Modifier.Settings.RENDLEVELS] = subdiv_render
-
- obj_idx += 1
-
- self.build_hierarchy()
- scene.update()
-
-# End of class AC3DImport
-
-def filesel_callback(filename):
-
- inform("\nTrying to import AC3D model(s) from:\n%s ..." % filename)
- Window.WaitCursor(1)
- starttime = bsys.time()
- test = AC3DImport(filename)
- Window.WaitCursor(0)
- endtime = bsys.time() - starttime
- inform('Done! Data imported in %.3f seconds.\n' % endtime)
-
-Window.EditMode(0)
-
-Window.FileSelector(filesel_callback, "Import AC3D", "*.ac")
diff --git a/release/scripts/add_mesh_empty.py b/release/scripts/add_mesh_empty.py
deleted file mode 100644
index 537bd1e2c3d..00000000000
--- a/release/scripts/add_mesh_empty.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#!BPY
-"""
-Name: 'Empty mesh'
-Blender: 243
-Group: 'AddMesh'
-"""
-import BPyAddMesh
-import Blender
-
-def main():
- BPyAddMesh.add_mesh_simple('EmptyMesh', [], [], [])
-
-main() \ No newline at end of file
diff --git a/release/scripts/add_mesh_torus.py b/release/scripts/add_mesh_torus.py
deleted file mode 100644
index 2941c56420e..00000000000
--- a/release/scripts/add_mesh_torus.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!BPY
-"""
-Name: 'Torus'
-Blender: 243
-Group: 'AddMesh'
-"""
-import BPyAddMesh
-import Blender
-try: from math import cos, sin, pi
-except: math = None
-
-def add_torus(PREF_MAJOR_RAD, PREF_MINOR_RAD, PREF_MAJOR_SEG, PREF_MINOR_SEG):
- Vector = Blender.Mathutils.Vector
- RotationMatrix = Blender.Mathutils.RotationMatrix
- verts = []
- faces = []
- i1 = 0
- tot_verts = PREF_MAJOR_SEG * PREF_MINOR_SEG
- for major_index in xrange(PREF_MAJOR_SEG):
- verts_tmp = []
- mtx = RotationMatrix( 360 * float(major_index)/PREF_MAJOR_SEG, 3, 'z' )
-
- for minor_index in xrange(PREF_MINOR_SEG):
- angle = 2*pi*minor_index/PREF_MINOR_SEG
-
- verts.append( Vector(PREF_MAJOR_RAD+(cos(angle)*PREF_MINOR_RAD), 0, (sin(angle)*PREF_MINOR_RAD)) * mtx )
- if minor_index+1==PREF_MINOR_SEG:
- i2 = (major_index)*PREF_MINOR_SEG
- i3 = i1 + PREF_MINOR_SEG
- i4 = i2 + PREF_MINOR_SEG
-
- else:
- i2 = i1 + 1
- i3 = i1 + PREF_MINOR_SEG
- i4 = i3 + 1
-
- if i2>=tot_verts: i2 = i2-tot_verts
- if i3>=tot_verts: i3 = i3-tot_verts
- if i4>=tot_verts: i4 = i4-tot_verts
-
- faces.append( (i3,i4,i2,i1) )
- i1+=1
-
- return verts, faces
-
-def main():
- Draw = Blender.Draw
- PREF_MAJOR_RAD = Draw.Create(1.0)
- PREF_MINOR_RAD = Draw.Create(0.25)
- PREF_MAJOR_SEG = Draw.Create(48)
- PREF_MINOR_SEG = Draw.Create(16)
-
- if not Draw.PupBlock('Add Torus', [\
- ('Major Radius:', PREF_MAJOR_RAD, 0.01, 100, 'Radius for the main ring of the torus'),\
- ('Minor Radius:', PREF_MINOR_RAD, 0.01, 100, 'Radius for the minor ring of the torus setting the thickness of the ring'),\
- ('Major Segments:', PREF_MAJOR_SEG, 3, 256, 'Number of segments for the main ring of the torus'),\
- ('Minor Segments:', PREF_MINOR_SEG, 3, 256, 'Number of segments for the minor ring of the torus'),\
- ]):
- return
-
- verts, faces = add_torus(PREF_MAJOR_RAD.val, PREF_MINOR_RAD.val, PREF_MAJOR_SEG.val, PREF_MINOR_SEG.val)
-
- BPyAddMesh.add_mesh_simple('Torus', verts, [], faces)
-
-if cos and sin and pi:
- main()
-else:
- Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
-
diff --git a/release/scripts/animation_bake_constraints.py b/release/scripts/animation_bake_constraints.py
deleted file mode 100644
index 16855828460..00000000000
--- a/release/scripts/animation_bake_constraints.py
+++ /dev/null
@@ -1,792 +0,0 @@
-#!BPY
-
-"""
-Name: 'Bake Constraints'
-Blender: 246
-Group: 'Animation'
-Tooltip: 'Bake a Constrained object/rig to IPOs'
-Fillename: 'Bake_Constraint.py'
-"""
-
-__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)"
-__script__ = "Animation Bake Constraints"
-__version__ = "0.7"
-__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"]
-__email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"]
-__bpydoc__ = """\
-
-bake_constraints
-
-This script bakes the real-world LocRot of an object (the net effect of any constraints -
-(Copy, Limit, Track, Follow, - that affect Location, Rotation)
-(usually one constrained to match another's location and/or Tracked to another)
-and creates a clone with a set of Ipo Curves named Ipo<objname>
-These curves control a non-constrained object and thus make it mimic the constrained object
-Actions can be then be edited without the need for the drivers/constraining objects
-
-Developed for use with MoCap data, where a bone is constrained to point at an empty
-moving through space and time. This records the actual locrot of the armature
-so that the motion can be edited, reoriented, scaled, and used as NLA Actions
-
-see also wiki Scripts/Manual/ Tutorial/Motion Capture <br>
-
-Usage: <br>
- - Select the reference Object(s) you want to bake <br>
- - Set the frame range to bake in the Anim Panel <br>
- - Set the test code (if you want a self-test) in the RT field in the Anim Panel <br>
- -- Set RT:1 to create a test armature <br>
- -- Set RT: up to 100 for more debug messages and status updates <br>
-<br>
- - Run the script <br>
- - The clone copy of the object is created and it has an IPO curve assigned to it. <br>
- - The clone shadows the object by an offset locrot (see usrDelta) <br>
- - That Object has Ipo Location and Rotation curves that make the clone mimic the movement <br>
- of the selected object, but without using constraints. <br>
- - If the object was an Armature, the clone's bones move identically in relation to the <br>
- original armature, and an Action is created that drives the bone movements. <br>
-
-Version History:
- 0.1: bakes Loc Rot for a constrained object
- 0.2: bakes Loc and Rot for the bones within Armature object
- 0.3: UI for setting options
- 0.3.1 add manual to script library
- 0.4: bake multiple objects
- 0.5: root bone worldspace rotation
- 0.6: re-integration with BPyArmature
- 0.7: bakes parents and leaves clones selected
-
-License, Copyright, and Attribution:
- by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain
- feel free to add to any Blender Python Scripts Bundle.
- Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton), Basil_Fawlty/Cage_drei (Andrew Cruse)
- much lifted/learned from blender.org/documentation/245PytonDoc and wiki
- some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter
-
-Pseudocode:
- Initialize
- If at least one object is selected
- For each selected object,
- create a cloned object
- remove any constraints on the clone
- create or reset an ipo curve named like the object
- for each frame
- set the clone's locrot key based on the reference object
- if it's an armature,
- create an action (which is an Ipo for each bone)
- for each frame of the animation
- for each bone in the armature
- set the key
- Else you're a smurf
-
-Test Conditions and Regressions:
- 1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level
- 2. armatures, with ipo curve and constraints at the object level
- 3. armatures, with bones that have ipo curves and constraints
- 4. objects without parents, children with unselected parents, select children first.
-
-Naming conventions:
- arm = a specific objec type armature
- bone = bones that make up the skeleton of an armature
-
- ob = object, an instance of an object type
- ebone = edit bone, a bone in edit mode
- pbone = pose bone, a posed bone in an object
- tst = testing, self-test routines
- usr = user-entered or designated stuff
-"""
-########################################
-
-import Blender
-from Blender import *
-from Blender.Mathutils import *
-import struct
-import string
-import bpy
-import BPyMessages
-import BPyArmature
-# reload(BPyArmature)
-from BPyArmature import getBakedPoseData
-
-Vector= Blender.Mathutils.Vector
-Euler= Blender.Mathutils.Euler
-Matrix= Blender.Mathutils.Matrix #invert() function at least
-RotationMatrix = Blender.Mathutils.RotationMatrix
-TranslationMatrix= Blender.Mathutils.TranslationMatrix
-Quaternion = Blender.Mathutils.Quaternion
-Vector = Blender.Mathutils.Vector
-POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT]
-
-#=================
-# Global Variables
-#=================
-
-# set senstitivity for displaying debug/console messages. 0=none, 100=max
-# then call debug(num,string) to conditionally display status/info in console window
-MODE=Blender.Get('rt') #execution mode: 0=run normal, 1=make test armature
-DEBUG=Blender.Get('rt') #how much detail on internal processing for user to see. range 0-100
-BATCH=False #called from command line? is someone there? Would you like some cake?
-
-#there are two coordinate systems, the real, or absolute 3D space,
-# and the local relative to a parent.
-COORDINATE_SYSTEMS = ['local','real']
-COORD_LOCAL = 0
-COORD_REAL = 1
-
-# User Settings - Change these options manually or via GUI (future TODO)
-usrCoord = COORD_REAL # what the user wants
-usrParent = False # True=clone keeps original parent, False = clone's parent is the clone of the original parent (if cloned)
-usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin
-# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant
-usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz
-usrACTION = True # Offset baked Action frames to start at frame 1
-
-CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on
-ARMATURE = 'Armature' #en anglais
-BONE_SPACES = ['ARMATURESPACE','BONESPACE']
- # 'ARMATURESPACE' - this matrix of the bone in relation to the armature
- # 'BONESPACE' - the matrix of the bone in relation to itself
-
-#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name
-#bakedArmName = "b." #used for both the armature class and object instance
-usrObjectNamePrefix= ""
-#ipoBoneNamePrefix = ""
-# for example, if on entry an armature named Man was selected, and the object prefix was "a."
-# on exit an armature and an IPO curve named a.Man exists for the object as a whole
-# if that armature had bones (spine, neck, arm) and the bone prefix was "a."
-# the bones and IPO curves will be (a.spine, a.neck, a.arm)
-
-R2D = 18/3.141592653589793 # radian to grad
-BLENDER_VERSION = Blender.Get('version')
-
-# Gets the current scene, there can be many scenes in 1 blend file.
-scn = Blender.Scene.GetCurrent()
-
-#=================
-# Methods
-#=================
-########################################
-def debug(num,msg): #use log4j or just console here.
- if DEBUG >= num:
- if BATCH == False:
- print 'debug: '[:num/10+7]+msg
- #TODO: else write out to file (runs faster if it doesnt have to display details)
- return
-
-########################################
-def error(str):
- debug(0,'ERROR: '+str)
- if BATCH == False:
- Draw.PupMenu('ERROR%t|'+str)
- return
-
-########################################
-def getRenderInfo():
- context=scn.getRenderingContext()
- staframe = context.startFrame()
- endframe = context.endFrame()
- if endframe<staframe: endframe=staframe
- curframe = Blender.Get(CURFRAME)
- debug(90,'Scene is on frame %i and frame range is %i to %i' % (curframe,staframe,endframe))
- return (staframe,endframe,curframe)
-
-########################################
-def sortObjects(obs): #returns a list of objects sorted based on parent dependency
- obClones= []
- while len(obClones) < len(obs):
- for ob in obs:
- if not ob in obClones:
- par= ob.getParent()
- #if no parent, or the parent is not scheduled to be cloned
- if par==None:
- obClones.append(ob) # add the independent
- elif par not in obs: # parent will not be cloned
- obClones.append(ob) # add the child
- elif par in obClones: # is it on the list?
- obClones.append(ob) # add the child
- # parent may be a child, so it will be caught next time thru
- debug(100,'clone object order: \n%s' % obClones)
- return obClones # ordered list of (ob, par) tuples
-
-########################################
-def sortBones(xbones): #returns a sorted list of bones that should be added,sorted based on parent dependency
-# while there are bones to add,
-# look thru the list of bones we need to add
-# if we have not already added this bone
-# if it does not have a parent
-# add it
-# else, it has a parent
-# if we already added it's parent
-# add it now.
-# else #we need to keep cycling and catch its parent
-# else it is a root bone
-# add it
-# else skip it, it's already in there
-# endfor
-# endwhile
- xboneNames=[]
- for xbone in xbones: xboneNames.append(xbone.name)
- debug (80,'reference bone order: \n%s' % xboneNames)
- eboneNames=[]
- while len(eboneNames) < len(xboneNames):
- for xbone in xbones:
- if not xbone.name in eboneNames:
- if not xbone.parent:
- eboneNames.append(xbone.name)
- else:
- if xbone.parent.name in eboneNames:
- eboneNames.append(xbone.name)
- #else skip it
- #endif
- #else prego
- #endfor
- #endwhile
- debug (80,'clone bone order: \n%s' % eboneNames)
- return eboneNames
-
-########################################
-def dupliArmature(ob): #makes a copy in current scn of the armature used by ob and its bones
- ob_mat = ob.matrixWorld
- ob_data = ob.getData()
- debug(49,'Reference object uses %s' % ob_data)
- arm_ob = Armature.Get(ob_data.name) #the armature used by the passed object
-
- arm = Blender.Armature.New()
- debug(20,'Cloning Armature %s to create %s' % (arm_ob.name, arm.name))
- arm.drawType = Armature.STICK #set the draw type
-
- arm.makeEditable() #enter editmode
-
- # for each bone in the object's armature,
- xbones=ob.data.bones.values()
- usrSpace = 0 #0=armature, 1=local
- space=[BONE_SPACES[usrSpace]][0]
-
- #we have to make a list of bones, then figure out our parents, then add to the arm
- #when creating a child, we cannot link to a parent if it does not yet exist in our armature
- ebones = [] #list of the bones I want to create for my arm
-
- eboneNames = sortBones(xbones)
-
- i=0
- # error('bones sorted. continue?')
- for abone in eboneNames: #set all editable attributes to fully define the bone.
- for bone in xbones:
- if bone.name == abone: break # get the reference bone
- ebone = Armature.Editbone() #throw me a bone, bone-man!
- ebones.append(ebone) #you're on my list, buddy
-
- ebone.name = bone.name
- ebone.headRadius = bone.headRadius
- ebone.tailRadius = bone.tailRadius
- ebone.weight = bone.weight
- ebone.options = bone.options
-
- ebone.head = bone.head[space] #dictionary lookups
- ebone.tail = bone.tail[space]
- ebone.matrix = bone.matrix[space]
- ebone.roll = bone.roll[space]
-
- debug(30,'Generating new %s as child of %s' % (bone,bone.parent))
- if bone.hasParent():
-# parent=bone.parent.name
-# debug(100,'looking for %s' % parent)
-# for parbone in xbones: if parbone.name == parent: break # get the parent bone
-# ebone.parent = arm.bones[ebones[j].name]
- ebone.parent = arm.bones[bone.parent.name]
-# else:
-# ebone.parent = None
- debug(30,'Generating new editbone %s as child of %s' % (ebone,ebone.parent))
- arm.bones[ebone.name] = ebone # i would have expected an append or add function, but this works
-
- debug (100,'arm.bones: \n%s' % arm.bones)
- debug (20,'Cloned %i bones now in armature %s' %(len(arm.bones),arm.name))
-
- myob = scn.objects.new(arm) #interestingly, object must be created before
- arm.update() #armature can be saved
- debug(40,'dupArm finished %s instanced as object %s' % (arm.name,myob.getName()))
- print ob.matrix
- print myob.matrix
-
- return myob
-########################################
-def scrub(): # scrubs to startframe
- staFrame,endFrame,curFrame = getRenderInfo()
-
- # eye-candy, go from current to start, fwd or back
- if not BATCH:
- debug(100, "Positioning to start...")
- frameinc=(staFrame-curFrame)/10
- if abs(frameinc) >= 1:
- for i in range(10):
- curFrame+=frameinc
- Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects
- Blender.Redraw()
- Blender.Set(CURFRAME, staFrame)
- return
-
-########################################
-def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
- scrub()
- staFrame,endFrame,curFrame = getRenderInfo()
- act = getBakedPoseData(ref_ob, staFrame, endFrame, ACTION_BAKE = True, ACTION_BAKE_FIRST_FRAME = usrACTION) # bake the pose positions of the reference ob to the armature ob
- arm_ob.action = act
- scrub()
-
- # user comprehension feature - change action name and channel ipo names to match the names of the bone they drive
- debug (80,'Renaming each action ipo to match the bone they pose')
- act.name = arm_ob.name
- arm_channels = act.getAllChannelIpos()
- pose= arm_ob.getPose()
- pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup
- for pbone in pbones:
- debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] ))
- ipo=arm_channels[pbone.name]
- ipo.name = pbone.name # since bone names are unique within an armature, the pose names can be the same since they are within an Action
-
- return
-
-########################################
-def getOrCreateCurve(ipo, curvename):
- """
- Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
- Either an ipo curve named C{curvename} exists before the call then this curve is returned,
- Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned
- """
- try:
- mycurve = ipo.getCurve(curvename)
- if mycurve != None:
- pass
- else:
- mycurve = ipo.addCurve(curvename)
- except:
- mycurve = ipo.addCurve(curvename)
- return mycurve
-
-########################################
-def eraseCurve(ipo,numCurves):
- debug(90,'Erasing %i curves for %' % (numCurves,ipo.GetName()))
- for i in range(numCurves):
- nbBezPoints= ipo.getNBezPoints(i)
- for j in range(nbBezPoints):
- ipo.delBezPoint(i)
- return
-
-########################################
-def resetIPO(ipo):
- debug(60,'Resetting ipo curve named %s' %ipo.name)
- numCurves = ipo.getNcurves() #like LocX, LocY, etc
- if numCurves > 0:
- eraseCurve(ipo, numCurves) #erase data if one exists
- return
-
-########################################
-def resetIPOs(ob): #resets all IPO curvess assocated with an object and its bones
- debug(30,'Resetting any ipo curves linked to %s' %ob.getName())
- ipo = ob.getIpo() #may be None
- ipoName = ipo.getName() #name of the IPO that guides/controls this object
- debug(70,'Object IPO is %s' %ipoName)
- try:
- ipo = Ipo.Get(ipoName)
- except:
- ipo = Ipo.New('Object', ipoName)
- resetIPO(ipo)
- if ob.getType() == ARMATURE:
- arm_data=ob.getData()
- bones=arm_data.bones.values()
- for bone in bones:
- #for each bone: get the name and check for a Pose IPO
- debug(10,'Processing '+ bone.name)
- return
-
-########################################
-def parse(string,delim):
- index = string.find(delim) # -1 if not found, else pointer to delim
- if index+1: return string[:index]
- return string
-
-########################################
-def newIpo(ipoName): #add a new Ipo object to the Blender scene
- ipo=Blender.Ipo.New('Object',ipoName)
-
- ipo.addCurve('LocX')
- ipo.addCurve('LocY')
- ipo.addCurve('LocZ')
- ipo.addCurve('RotX')
- ipo.addCurve('RotY')
- ipo.addCurve('RotZ')
- return ipo
-
-########################################
-def makeUpaName(type,name): #i know this exists in Blender somewhere...
- debug(90,'Making up a new %s name using %s as a basis.' % (type,name))
- name = (parse(name,'.'))
- if type == 'Ipo':
- ipoName = name # maybe we get lucky today
- ext = 0
- extlen = 3 # 3 digit extensions, like hello.002
- success = False
- while not(success):
- try:
- debug(100,'Trying %s' % ipoName)
- ipo = Ipo.Get(ipoName)
- #that one exists if we get here. add on extension and keep trying
- ext +=1
- if ext>=10**extlen: extlen +=1 # go to more digits if 999 not found
- ipoName = '%s.%s' % (name, str(ext).zfill(extlen))
- except: # could not find it
- success = True
- name=ipoName
- else:
- debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob))
- return None
- return name
-
-########################################
-def createIpo(ob): #create an Ipo and curves and link them to this object
- #first, we have to create a unique name
- #try first with just the name of the object to keep things simple.
- ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name
- debug(20,'Ipo and LocRot curves called %s' % ipoName)
- ipo=newIpo(ipoName)
- ob.setIpo(ipo) #link them
- return ipo
-
-########################################
-def getLocLocal(ob):
- key = [
- ob.LocX,
- ob.LocY,
- ob.LocZ,
- ob.RotX*R2D, #get the curves in this order
- ob.RotY*R2D,
- ob.RotZ*R2D
- ]
- return key
-
-########################################
-def getLocReal(ob):
- obMatrix = ob.matrixWorld #Thank you IdeasMan42
- loc = obMatrix.translationPart()
- rot = obMatrix.toEuler()
- key = [
- loc.x,
- loc.y,
- loc.z,
- rot.x/10,
- rot.y/10,
- rot.z/10
- ]
- return key
-
-########################################
-def getLocRot(ob,space):
- if space in xrange(len(COORDINATE_SYSTEMS)):
- if space == COORD_LOCAL:
- key = getLocLocal(ob)
- return key
- elif space == COORD_REAL:
- key = getLocReal(ob)
- return key
- else: #hey, programmers make mistakes too.
- debug(0,'Fatal Error: getLoc called with %i' % space)
- return
-
-########################################
-def getCurves(ipo):
- ipos = [
- ipo[Ipo.OB_LOCX],
- ipo[Ipo.OB_LOCY],
- ipo[Ipo.OB_LOCZ],
- ipo[Ipo.OB_ROTX], #get the curves in this order
- ipo[Ipo.OB_ROTY],
- ipo[Ipo.OB_ROTZ]
- ]
- return ipos
-
-########################################
-def addPoint(time,keyLocRot,ipos):
- if BLENDER_VERSION < 245:
- debug(0,'WARNING: addPoint uses BezTriple')
- for i in range(len(ipos)):
- point = BezTriple.New() #this was new with Blender 2.45 API
- point.pt = (time, keyLocRot[i])
- point.handleTypes = [1,1]
-
- ipos[i].append(point)
- return ipos
-
-########################################
-def bakeFrames(ob,myipo): #bakes an object in a scene, returning the IPO containing the curves
- myipoName = myipo.getName()
- debug(20,'Baking frames for scene %s object %s to ipo %s' % (scn.getName(),ob.getName(),myipoName))
- ipos = getCurves(myipo)
- #TODO: Gui setup idea: myOffset
- # reset action to start at frame 1 or at location
- myOffset=0 #=1-staframe
- #loop through frames in the animation. Often, there is rollup and the mocap starts late
- staframe,endframe,curframe = getRenderInfo()
- for frame in range(staframe, endframe+1):
- debug(80,'Baking Frame %i' % frame)
- #tell Blender to advace to frame
- Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
- if not BATCH: Blender.Redraw() # no secrets, let user see what we are doing
-
- #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen
- key = getLocRot(ob,usrCoord) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame
- key = [a+b for a,b in zip(key, usrDelta)] #offset to the new location
-
- myframe= frame+myOffset
- Blender.Set(CURFRAME,myframe)
-
- time = Blender.Get('curtime') #for BezTriple
- ipos = addPoint(time,key,ipos) #add this data at this time to the ipos
- debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5]))
- # eye-candy - smoothly rewind the animation, showing now how the clone match moves
- if endframe-staframe <400 and not BATCH:
- for frame in range (endframe,staframe,-1): #rewind
- Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
- Blender.Redraw()
- Blender.Set(CURFRAME,staframe)
- Blender.Redraw()
-
- return ipos
-
-########################################
-def duplicateLinked(ob):
- obType = ob.type
- debug(10,'Duplicating %s Object named %s' % (obType,ob.getName()))
- scn.objects.selected = [ob]
-## rdw: simplified by just duplicating armature. kept code as reference for creating armatures
-## disadvantage is that you cant have clone as stick and original as octahedron
-## since they share the same Armature. User can click Make Single User button.
-## if obType == ARMATURE: #build a copy from scratch
-## myob= dupliArmature(ob)
-## else:
- Blender.Object.Duplicate() # Duplicate linked, including pose constraints.
- myobs = Object.GetSelected() #duplicate is top on the list
- myob = myobs[0]
- if usrParent == False:
- myob.clrParent(usrFreeze)
- debug(20,'=myob= was created as %s' % myob.getName())
- return myob
-
-########################################
-def removeConstraints(ob):
- for const in ob.constraints:
- debug(90,'removed %s => %s' % (ob.name, const))
- ob.constraints.remove(const)
- return
-
-########################################
-def removeConstraintsOb(ob): # from object or armature
- debug(40,'Removing constraints from '+ob.getName())
- if BLENDER_VERSION > 241: #constraints module not available before 242
- removeConstraints(ob)
- if ob.getType() == ARMATURE:
- pose = ob.getPose()
- for pbone in pose.bones.values():
- #bone = pose.bones[bonename]
- removeConstraints(pbone)
- #should also check if it is a deflector?
- return
-
-########################################
-def deLinkOb(type,ob): #remove linkages
- if type == 'Ipo':
- success = ob.clearIpo() #true=there was one
- if success: debug(80,'deLinked Ipo curve to %s' % ob.getName())
- return
-
-########################################
-def bakeObject(ob): #bakes the core object locrot and assigns the Ipo to a Clone
- if ob != None:
- # Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone
- myob = duplicateLinked(ob) #clone it
- myob.setName(usrObjectNamePrefix + ob.getName())
- removeConstraintsOb(myob) #my object is a free man
- deLinkOb('Ipo',myob) #kids, it's not nice to share. you've been lied to
- if ob.getType() != ARMATURE: # baking armatures is based on bones, not object
- myipo = createIpo(myob) #create own IPO and curves for the clone object
- ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames
- return myob
-
-########################################
-def bake(ob,par): #bakes an object of any type, linking it to parent
- debug(0,'Baking %s object %s' % (ob.getType(), ob))
- clone = bakeObject(ob) #creates and bakes the object motion
- if par!= None:
- par.makeParent([clone])
- debug(20,"assigned object to parent %s" % par)
- if ob.getType() == ARMATURE:
-## error('Object baked. Continue with bones?')
- bakeBones(ob,clone) #go into the bones and copy from -> to in frame range
- #future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...)
- return clone
-
-########################################
-def tstCreateArm(): #create a test armature in scene
- # rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you!
-
- debug(0,'Making Test Armature')
- # New Armature
- arm_data= Armature.New('myArmature')
- print arm_data
- arm_ob = scn.objects.new(arm_data)
- arm_data.makeEditable()
-
- # Add 4 bones
- ebones = [Armature.Editbone(), Armature.Editbone(), Armature.Editbone(), Armature.Editbone()]
-
- # Name the editbones
- ebones[0].name = 'Bone.001'
- ebones[1].name = 'Bone.002'
- ebones[2].name = 'Bone.003'
- ebones[3].name = 'Bone.004'
-
- # Assign the editbones to the armature
- for eb in ebones:
- arm_data.bones[eb.name]= eb
-
- # Set the locations of the bones
- ebones[0].head= Mathutils.Vector(0,0,0)
- ebones[0].tail= Mathutils.Vector(0,0,1) #tip
- ebones[1].head= Mathutils.Vector(0,0,1)
- ebones[1].tail= Mathutils.Vector(0,0,2)
- ebones[2].head= Mathutils.Vector(0,0,2)
- ebones[2].tail= Mathutils.Vector(0,0,3)
- ebones[3].head= Mathutils.Vector(0,0,3)
- ebones[3].tail= Mathutils.Vector(0,0,4)
-
- ebones[1].parent= ebones[0]
- ebones[2].parent= ebones[1]
- ebones[3].parent= ebones[2]
-
- arm_data.update()
- # Done with editing the armature
-
- # Assign the pose animation
- arm_pose = arm_ob.getPose()
-
- act = arm_ob.getAction()
- if not act: # Add a pose action if we dont have one
- act = Armature.NLA.NewAction()
- act.setActive(arm_ob)
-
- xbones=arm_ob.data.bones.values()
- pbones = arm_pose.bones.values()
-
- frame = 1
- for pbone in pbones: # set bones to no rotation
- pbone.quat[:] = 1.000,0.000,0.000,0.0000
- pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
-
- # Set a different rotation at frame 25
- pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000
- pbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000
- pbones[2].quat[:] = 1.000,0.1000,0.3000,0.40000
- pbones[3].quat[:] = 1.000,-0.2000,-0.3000,0.30000
-
- frame = 25
- for i in xrange(4):
- pbones[i].insertKey(arm_ob, frame, Object.Pose.ROT)
-
- pbones[0].quat[:] = 1.000,0.000,0.000,0.0000
- pbones[1].quat[:] = 1.000,0.000,0.000,0.0000
- pbones[2].quat[:] = 1.000,0.000,0.000,0.0000
- pbones[3].quat[:] = 1.000,0.000,0.000,0.0000
-
- frame = 50
- for pbone in pbones: # set bones to no rotation
- pbone.quat[:] = 1.000,0.000,0.000,0.0000
- pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
-
- return arm_ob
-
-########################################
-def tstMoveOb(ob): # makes a simple LocRot animation of object in the scene
- anim = [
- #Loc Rot/10
- #
- ( 0,0,0, 0, 0, 0), #frame 1 origin
- ( 1,0,0, 0, 0, 0), #frame 2
- ( 1,1,0, 0, 0, 0),
- ( 1,1,1, 0, 0, 0),
- ( 1,1,1,4.5, 0, 0),
- ( 1,1,1,4.5,4.5, 0),
- ( 1,1,1,4.5,4.5,4.5)
- ]
- space = COORD_LOCAL
- ipo = createIpo(ob) #create an Ipo and curves for this object
- ipos = getCurves(ipo)
-
- # span this motion over the currently set anim range
- # to set points, i need time but do not know how it is computed, so will have to advance the animation
- staframe,endframe,curframe = getRenderInfo()
-
- frame = staframe #x position of new ipo datapoint. set to staframe if you want a match
- frameDelta=(endframe-staframe)/(len(anim)) #accomplish the animation in frame range
- for key in anim: #effectively does a getLocRot()
- #tell Blender to advace to frame
- Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects
- time = Blender.Get('curtime')
-
- ipos = addPoint(time,key,ipos) #add this data at this time to the ipos
-
- debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5]))
- frame += frameDelta
- Blender.Set(CURFRAME,curframe) # reset back to where we started
- return
-#=================
-# Program Template
-#=================
-########################################
-def main():
- # return code set via rt button in Blender Buttons Scene Context Anim panel
- if MODE == 1: #create test armature #1
- ob = tstCreateArm() # make test arm and select it
- tstMoveOb(ob)
- scn.objects.selected = [ob]
-
- obs= Blender.Object.GetSelected() #scn.objects.selected
- obs= sortObjects(obs)
- debug(0,'Baking %i objects' % len(obs))
-
- if len(obs) >= 1: # user might have multiple objects selected
- i= 0
- clones=[] # my clone army
- for ob in obs:
- par= ob.getParent()
- if not usrParent:
- if par in obs:
- par= clones[obs.index(par)]
- clones.append(bake(ob,par))
- scn.objects.selected = clones
- else:
- error('Please select at least one object')
- return
-
-########################################
-def benchmark(): # This lets you benchmark (time) the script's running duration
- Window.WaitCursor(1)
- t = sys.time()
- debug(60,'%s began at %.0f' %(__script__,sys.time()))
-
- # Run the function on the active scene
- in_editmode = Window.EditMode()
- if in_editmode: Window.EditMode(0)
-
- main()
-
- if in_editmode: Window.EditMode(1)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- debug(0,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) )
- Window.WaitCursor(0)
- return
-
-########################################
-# This lets you can import the script without running it
-if __name__ == '__main__':
- debug(0, "------------------------------------")
- debug(0, "%s %s Script begins with mode=%i debug=%i batch=%s" % (__script__,__version__,MODE,DEBUG,BATCH))
- benchmark()
diff --git a/release/scripts/animation_clean.py b/release/scripts/animation_clean.py
deleted file mode 100644
index fc44f264ac1..00000000000
--- a/release/scripts/animation_clean.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!BPY
-
-"""
-Name: 'Clean Animation Curves'
-Blender: 249
-Group: 'Animation'
-Tooltip: 'Remove unused keyframes for ipo curves'
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2008-2009: 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,
-# --------------------------------------------------------------------------
-
-import bpy
-from Blender import IpoCurve, Draw, Window
-
-def clean_ipos(ipos):
- eul = 0.001
-
- def isflat(vec):
- prev_y = vec[0][1]
- mid_y = vec[1][1]
- next_y = vec[2][1]
-
- # flat status for prev and next
- return abs(mid_y-prev_y) < eul, abs(mid_y-next_y) < eul
-
-
-
- X=0
- Y=1
- PREV=0
- MID=1
- NEXT=2
-
- LEFT = 0
- RIGHT = 1
-
- TOT = 0
- TOTBEZ = 0
- # for ipo in bpy.data.ipos:
- for ipo in ipos:
- if ipo.lib:
- continue
- # print ipo
- for icu in ipo:
- interp = icu.interpolation
- extend = icu.extend
-
- bezierPoints = icu.bezierPoints
- bezierVecs = [bez.vec for bez in bezierPoints]
-
- l = len(bezierPoints)
-
- TOTBEZ += l
-
- # our aim is to simplify this ipo as much as possible!
- if interp == IpoCurve.InterpTypes.BEZIER or interp == interp == IpoCurve.InterpTypes.LINEAR:
- #print "Not yet supported"
-
- if interp == IpoCurve.InterpTypes.BEZIER:
- flats = [isflat(bez) for bez in bezierVecs]
- else:
- # A bit of a waste but fake the locations for these so they will always be flats
- # IS better then too much duplicate code.
- flats = [(True, True)] * l
- for v in bezierVecs:
- v[PREV][Y] = v[NEXT][Y] = v[MID][Y]
-
-
- # remove middle points
- if l>2:
- done_nothing = False
-
- while not done_nothing and len(bezierVecs) > 2:
- done_nothing = True
- i = l-2
-
- while i > 0:
- #print i
- #print i, len(bezierVecs)
- if flats[i]==(True,True) and flats[i-1][RIGHT] and flats[i+1][LEFT]:
-
- if abs(bezierVecs[i][MID][Y] - bezierVecs[i-1][MID][Y]) < eul and abs(bezierVecs[i][MID][Y] - bezierVecs[i+1][MID][Y]) < eul:
- done_nothing = False
-
- del flats[i]
- del bezierVecs[i]
- icu.delBezier(i)
- TOT += 1
- l-=1
- i-=1
-
- # remove endpoints
- if extend == IpoCurve.ExtendTypes.CONST and len(bezierVecs) > 1:
- #print l, len(bezierVecs)
- # start
-
- while l > 2 and (flats[0][RIGHT] and flats[1][LEFT] and (abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul)):
- print "\tremoving 1 point from start of the curve"
- del flats[0]
- del bezierVecs[0]
- icu.delBezier(0)
- TOT += 1
- l-=1
-
-
- # End
- while l > 2 and flats[-2][RIGHT] and flats[-1][LEFT] and (abs(bezierVecs[-2][MID][Y] - bezierVecs[-1][MID][Y]) < eul):
- print "\tremoving 1 point from end of the curve", l
- del flats[l-1]
- del bezierVecs[l-1]
- icu.delBezier(l-1)
- TOT += 1
- l-=1
-
-
-
- if l==2:
- if isflat( bezierVecs[0] )[RIGHT] and isflat( bezierVecs[1] )[LEFT] and abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul:
- # remove the second point
- print "\tremoving 1 point from 2 point bez curve"
- # remove the second point
- del flats[1]
- del bezierVecs[1]
- icu.delBezier(1)
- TOT+=1
- l-=1
-
- # Change to linear for faster evaluation
- '''
- if l==1:
- print 'Linear'
- icu.interpolation = IpoCurve.InterpTypes.LINEAR
- '''
-
-
-
-
- if interp== IpoCurve.InterpTypes.CONST:
- print "Not yet supported"
-
- print 'total', TOT, TOTBEZ
- return TOT, TOTBEZ
-
-def main():
- ret = Draw.PupMenu('Clean Selected Objects Ipos%t|Object IPO%x1|Object Action%x2|%l|All IPOs (be careful!)%x3')
-
- sce = bpy.data.scenes.active
- ipos = []
-
- if ret == 3:
- ipos.extend(list(bpy.data.ipos))
- else:
- for ob in sce.objects.context:
- if ret == 1:
- ipo = ob.ipo
- if ipo:
- ipos.append(ipo)
-
- elif ret == 2:
- action = ob.action
- if action:
- ipos.extend([ipo for ipo in action.getAllChannelIpos().values() if ipo])
-
-
-
- if not ipos:
- Draw.PupMenu('Error%t|No ipos found')
- else:
- total_removed, total = clean_ipos(ipos)
- Draw.PupMenu('Done!%t|Removed ' + str(total_removed) + ' of ' + str(total) + ' points')
-
- Window.RedrawAll()
-
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/animation_trajectory.py b/release/scripts/animation_trajectory.py
deleted file mode 100644
index 55a670b66b1..00000000000
--- a/release/scripts/animation_trajectory.py
+++ /dev/null
@@ -1,575 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Trajectory'
-Blender: 243
-Group: 'Animation'
-Tip: 'See Trajectory of selected object'
-"""
-
-__author__ = '3R - R3gis'
-__version__ = '2.43'
-__url__ = ["Script's site , http://blenderfrance.free.fr/python/Trajectory_en.htm","Author's site , http://cybercreator.free.fr", "French Blender support forum, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender"]
-__email__=["3R, r3gis@free.fr"]
-
-
-__bpydoc__ = """
-
-Usage:
-
-* Launch with alt+P (or put it in .script folder)
-
-Allow to see in real time trajectory of selected object.
-
-On first run, it ask you
-- If you want that actually selected object have they trajectory always shown
-- If you want to use Space Handler or a Scriptlink in Redraw mode
-- Future and Past : it is the frame in past and future
-of the beggining and the end of the path
-- Width of line that represent the trajectory
-
-Then the object's trajectory will be shown in all 3D areas.
-When trajectory is red, you can modifiy it by moving object.
-When trajectory is blue and you want to be able to modify it, inser a Key (I-Key)
-
-Points appears on trajectory :
-- Left Clic to modify position
-- Right Clic to go to the frame it represents
-
-Notes:<br>
-In scriptlink mode, it create one script link so make sure that 'Enable Script Link' toogle is on
-In SpaceHandler mode, you have to go in View>>SpaceHandlerScript menu to activate Trajectory
-
-
-"""
-
-
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004-2006: Regis Montoya
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-#################################
-# by 3R - 26/08/05
-# for any problem :
-# r3gis@free.fr
-# ou sur le newsgroup:
-# http://zoo-logique.org/3D.Blender/
-#################################
-#Many thanks to cambo for his fixes
-#################################
-
-
-
-import Blender
-
-
-scene= Blender.Scene.GetCurrent()
-
-
-#Writing
-def write_script(name, script):
- global scene
- #List texts and their name
- #write : type of writing : 1->New, 2->Overwrite
- scripting= None
- for text in Blender.Text.Get():
- if text.name==name and text.asLines()[1] != "#"+str(__version__):
- scripting = text
- scripting.clear()
- scripting.write(script)
- break
-
- if not scripting:
- scripting= Blender.Text.New(name)
- scripting.write(script)
-
-def link_script(name, type):
- global scene
- scriptlinks = scene.getScriptLinks(type) # none or list
- if not scriptlinks or name not in scriptlinks:
- scene.addScriptLink(name, type)
-
-
-#Deleting of a text
-def text_remove(name):
- global scene
- #try to delete text if already linked
- try:
- text= Blender.Text.Get(name)
- # Texte.clear()
- scene.clearScriptLinks([name])
- Blender.Text.unlink(text)
- except:
- print('---Initialisation of Trajectory_'+str(__version__)+'.py---')
-
-#Whether is already running, also check if it's the last version of the script : second line contain the version fo the script
-ask_modif= 0 # Default
-for text in Blender.Text.Get():
- if text.name == 'Trajectory' and text.asLines()[1] == "#"+str(__version__):
- #We ask if script modify his seetings, keep it or stop script
- ask_modif= Blender.Draw.PupMenu("Script already launch %t|Modify settings%x0|Keep settings%x1|Stop script%x2|")
- if ask_modif==-1: # user canceled.
- ask_modif= 1
- break
-
-selection_mode= 0
-future= 35
-past= 20
-width= 2
-
-#In modify case
-if ask_modif==0:
- handle_mode= Blender.Draw.Create(0)
- selection_mode= Blender.Draw.Create(0)
- future= Blender.Draw.Create(35)
- past= Blender.Draw.Create(20)
- width= Blender.Draw.Create(2)
-
- block= []
- block.append(("Space Handlers", handle_mode, "You have to activate for each area by View>>SpaceHandler")) #You can delete this option...
- block.append(("Always Draw", selection_mode, "Selected object will have their trajectory always shown"))
- block.append(("Past :", past, 1, 900))
- block.append(("Futur:", future, 1, 900))
- block.append(("Width:", width, 1,5))
-
- if not Blender.Draw.PupBlock("Trajectory seetings", block):
- ask_modif=1
-
- handle_mode= handle_mode.val
- selection_mode= selection_mode.val
- future= future.val
- past= past.val
- width= width.val
-
-
-#put names of selected objects in objects_select if option choosen by user
-if selection_mode==1:
- objects_select= [ob.name for ob in scene.objects.context]
-else:
- objects_select= []
-
-
-try:
- if handle_mode==1:
- DrawPart="#SPACEHANDLER.VIEW3D.DRAW\n"
- else:
- DrawPart="#!BPY\n"
-except:DrawPart="#BadlyMade"
-
-
-#Here is the script to write in Blender and to link, options are also written now
-DrawPart=DrawPart+"#"+str(__version__)+"""
-#This script is a part of Trajectory.py and have to be linked to the scene in Redraw if not in HANDLER mode.
-#Author : 3R - Regis Montoya
-#It's better to use the Trajectory_"version_number".py
-#You can modify the two following value to change the path settings
-future="""+str(future)+"""
-past="""+str(past)+"""
-object_init_names="""+str(objects_select)+"""
-
-
-import Blender, math
-from Blender import BGL, Draw, Ipo
-from Blender.BGL import *
-from Blender.Draw import *
-from math import *
-
-from Blender.Mathutils import Vector
-
-#take actual frame
-frameC=Blender.Get('curframe')
-scene = Blender.Scene.GetCurrent()
-render_context=scene.getRenderingContext()
-#ajust number of frames with NewMap and OldMapvalue values
-k=1.00*render_context.oldMapValue()/render_context.newMapValue()
-if k<1:
- tr=-1*int(log(k*0.1, 10))
-else:
- tr=-1*int(log(k, 10))
-#The real and integer frame to compare to ipos keys frames
-frameCtr=round(frameC*k, tr)
-frameCr=frameC*k
-frameC=int(round(frameC*k, 0))
-
-
-#List objects that we have to show trajectory in $objects
-# In this case, using a dict for unique objects is the fastest way.
-object_dict= dict([(ob.name, ob) for ob in scene.objects.context])
-for obname in object_init_names:
- if not object_dict.has_key(obname):
- try: # Object may be removed.
- object_dict[obname]= Blender.Object.Get(obname)
- except:
- pass # object was removed.
-
-#This fonction give the resulting matrix of all parents at a given frame
-#parent_list is the list of all parents [object, matrix, locX_ipo, locY, Z, rotX, Y, Z, sizeX, Y, Z] of current object
-def matrixForTraj(frame, parent_list):
- DecMatC=Blender.Mathutils.Matrix([1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1])
-
- for parent_data in parent_list:
- parent_ob= parent_data[0]
-
- try: X= parent_data[5][frame]*pi/18
- except: X= parent_ob.RotX
- try: Y= parent_data[6][frame]*pi/18
- except: Y= parent_ob.RotY
- try: Z= parent_data[7][frame]*pi/18
- except: Z= parent_ob.RotZ
- try: LX= parent_data[2][frame]
- except: LX= parent_ob.LocX
- try: LY= parent_data[3][frame]
- except: LY= parent_ob.LocY
- try: LZ= parent_data[4][frame]
- except: LZ= parent_ob.LocZ
- try: SX= parent_data[8][frame]
- except: SX= parent_ob.SizeX
- try: SY= parent_data[9][frame]
- except: SY= parent_ob.SizeY
- try: SZ= parent_data[10][frame]
- except: SZ= parent_ob.SizeZ
-
- NMat=Blender.Mathutils.Matrix([cos(Y)*cos(Z)*SX,SX*cos(Y)*sin(Z),-SX*sin(Y),0],
- [(-cos(X)*sin(Z)+sin(Y)*sin(X)*cos(Z))*SY,(sin(X)*sin(Y)*sin(Z)+cos(X)*cos(Z))*SY,sin(X)*cos(Y)*SY,0],
- [(cos(X)*sin(Y)*cos(Z)+sin(X)*sin(Z))*SZ,(cos(X)*sin(Y)*sin(Z)-sin(X)*cos(Z))*SZ,SZ*cos(X)*cos(Y),0],
- [LX,LY,LZ,1])
- DecMatC=DecMatC*parent_data[1]*NMat
- return DecMatC
-
-#####
-TestLIST=[]
-matview=Blender.Window.GetPerspMatrix()
-###########
-#Fonction to draw trajectories
-###########
-
-def Trace_Traj(ob):
- global TestLIST, matview
- #we draw trajectories for all objects in list
-
- LocX=[]
- LocY=[]
- LocZ=[]
- #List with trajectories' vertexs
- vertexX=[]
-
- contextIpo= ob.ipo
- if contextIpo:
- ipoLocX=contextIpo[Ipo.OB_LOCX]
- ipoLocY=contextIpo[Ipo.OB_LOCY]
- ipoLocZ=contextIpo[Ipo.OB_LOCZ]
- ipoTime=contextIpo[Ipo.OB_TIME]
- else: # only do if there is no IPO (if no ipo curves : return None object and don't go in this except)
- ipoLocX= ipoLocY= ipoLocZ= ipoTime= None
-
- if ipoTime:
- return 0
-
- #Get all parents of ob
- parent=ob.parent
- backup_ob= ob
- child= ob
- parent_list= []
-
- #Get parents's infos :
- #list of [name, initial matrix at make parent, ipo in X,Y,Z,rotX,rotY,rotZ,sizeX,Y,Z]
- while parent:
- Init_Mat=Blender.Mathutils.Matrix(child.getMatrix('worldspace')) #must be done like it (it isn't a matrix otherwise)
- Init_Mat.invert()
- Init_Mat=Init_Mat*child.getMatrix('localspace')
- Init_Mat=parent.getMatrix()*Init_Mat
- Init_Mat.invert()
-
- contextIpo= parent.ipo # None or IPO
- if contextIpo:
- ipo_Parent_LocX=contextIpo[Ipo.OB_LOCX]
- ipo_Parent_LocY=contextIpo[Ipo.OB_LOCY]
- ipo_Parent_LocZ=contextIpo[Ipo.OB_LOCZ]
- ipo_Parent_RotX=contextIpo[Ipo.OB_ROTX]
- ipo_Parent_RotY=contextIpo[Ipo.OB_ROTY]
- ipo_Parent_RotZ=contextIpo[Ipo.OB_ROTZ]
- ipo_Parent_SizeX=contextIpo[Ipo.OB_SIZEX]
- ipo_Parent_SizeY=contextIpo[Ipo.OB_SIZEY]
- ipo_Parent_SizeZ=contextIpo[Ipo.OB_SIZEZ]
- else:
- ipo_Parent_LocX=ipo_Parent_LocY=ipo_Parent_LocZ=\
- ipo_Parent_RotX=ipo_Parent_RotY=ipo_Parent_RotZ=\
- ipo_Parent_SizeX=ipo_Parent_SizeY=ipo_Parent_SizeZ= None
-
- parent_list.append([parent, Init_Mat, ipo_Parent_LocX, ipo_Parent_LocY, ipo_Parent_LocZ, ipo_Parent_RotX, ipo_Parent_RotY, ipo_Parent_RotZ, ipo_Parent_SizeX, ipo_Parent_SizeY, ipo_Parent_SizeZ])
-
- child=parent
- parent=parent.parent
-
- #security : if one of parents object are a path>>follow : trajectory don't work properly so it have to draw nothing
- for parent in parent_list:
- if parent[0].type == 'Curve':
- if parent[0].data.flag & 1<<4: # Follow path, 4th bit
- return 1
-
- #ob >> re-assign obj and not parent
- ob= backup_ob
- ob= backup_ob
-
-
- if ipoLocX: LXC= ipoLocX[frameC]
- else: LXC= ob.LocX
- if ipoLocY: LYC= ipoLocY[frameC]
- else: LYC= ob.LocY
- if ipoLocZ: LZC= ipoLocZ[frameC]
- else: LZC= ob.LocZ
-
- vect= Vector([ob.LocX, ob.LocY, ob.LocZ, 1])
- color=[0, 1]
-
- #If trajectory is being modified and we are at a frame where a ipo key already exist
- if round(ob.LocX, 5)!=round(LXC, 5):
- for bez in ipoLocX.bezierPoints:
- if round(bez.pt[0], tr)==frameCtr:
- bez.pt = [frameCr, vect[0]]
- ipoLocX.recalc()
- if round(ob.LocY, 5)!=round(LYC, 5):
- for bez in ipoLocY.bezierPoints:
- if round(bez.pt[0], tr)==frameCtr:
- bez.pt = [frameCr, vect[1]]
- ipoLocY.recalc()
- if round(ob.LocZ, 5)!=round(LZC, 5):
- for bez in ipoLocZ.bezierPoints:
- if round(bez.pt[0], tr)==frameCtr:
- bez.pt = [frameCr, vect[2]]
- ipoLocZ.recalc()
-
- #change trajectory color if at an ipoKey
- VertexFrame=[]
- bezier_Coord=0
- if ipoLocX: # FIXED like others it was just in case ipoLocX==None
- for bez in ipoLocX.bezierPoints:
- bezier_Coord=round(bez.pt[0], tr)
- if bezier_Coord not in VertexFrame:
- VertexFrame.append(bezier_Coord)
- if bezier_Coord==frameCtr:
- color=[1, color[1]-0.3]
- if ipoLocY: # FIXED
- for bez in ipoLocY.bezierPoints:
- bezier_Coord=round(bez.pt[0], tr)
- if bezier_Coord not in VertexFrame:
- VertexFrame.append(bezier_Coord)
- if round(bez.pt[0], tr)==frameCtr:
- color=[1, color[1]-0.3]
- if ipoLocZ: # FIXED
- for bez in ipoLocZ.bezierPoints:
- bezier_Coord=round(bez.pt[0], tr)
- if bezier_Coord not in VertexFrame:
- VertexFrame.append(bezier_Coord)
- if round(bez.pt[0], tr)==frameCtr:
- color=[1, color[1]-0.3]
-
-
- #put in LocX, LocY and LocZ all points of trajectory
- for frame in xrange(frameC-past, frameC+future):
- DecMat=matrixForTraj(frame, parent_list)
-
- if ipoLocX: LX= ipoLocX[frame]
- else: LX= ob.LocX
- if ipoLocY: LY= ipoLocY[frame]
- else: LY= ob.LocY
- if ipoLocZ: LZ= ipoLocZ[frame]
- else: LZ= ob.LocZ
-
- vect=Vector(LX, LY, LZ)*DecMat
- LocX.append(vect[0])
- LocY.append(vect[1])
- LocZ.append(vect[2])
-
-
- #draw part : get current view
- MatPreBuff= [matview[i][j] for i in xrange(4) for j in xrange(4)]
-
- MatBuff=BGL.Buffer(GL_FLOAT, 16, MatPreBuff)
-
- glLoadIdentity()
- glMatrixMode(GL_PROJECTION)
- glPushMatrix()
- glLoadMatrixf(MatBuff)
-
- #draw trajectory line
- glLineWidth("""+str(width)+""")
-
- glBegin(GL_LINE_STRIP)
- for i in xrange(len(LocX)):
- glColor3f((i+1)*1.00/len(LocX)*color[0], 0, (i+1)*1.00/len(LocX)*color[1])
- glVertex3f(LocX[i], LocY[i], LocZ[i])
-
- glEnd()
-
- #draw trajectory's "vertexs"
- if not Blender.Window.EditMode():
- glPointSize(5)
- glBegin(GL_POINTS)
- TestPOINTS=[]
- TestFRAME=[]
- i=0
- for frame in VertexFrame:
- ix=int(frame)-frameC+past
- if ix>=0 and ix<len(LocX):
- glColor3f(1, 0.7, 0.2)
- glVertex3f(LocX[ix], LocY[ix], LocZ[ix])
- TestPOINTS.append(Vector([LocX[ix], LocY[ix], LocZ[ix], 1]))
- TestFRAME.append(int(frame))
- i+=1
- glEnd()
- #this list contains info about where to check if we click over a "vertex" in 3D view
- TestLIST.append((ob, TestPOINTS, TestFRAME))
-
- glLineWidth(1)
- return 0
-
-
-for ob in object_dict.itervalues():
- Trace_Traj(ob)
-
-###########
-#Fonction to handle trajectories
-###########
-
-def Manip():
- #use TestLIST and matview defined by Trace_Traj
- global TestLIST, matview
- for screen in Blender.Window.GetScreenInfo(Blender.Window.Types.VIEW3D):
- if screen['id']==Blender.Window.GetAreaID():
- x0, y0, x1, y1= screen['vertices']
- break
-
- #Projection of GL matrix in 3D view
- glPushMatrix()
- glMatrixMode(GL_PROJECTION)
- glPushMatrix()
- glLoadIdentity()
- #Global coordinates' matrix
- glOrtho(x0, x1, y0, y1, -1, 0)
- glMatrixMode(GL_MODELVIEW)
- glLoadIdentity()
- #Test mouse clics and other events
-
-
- if Blender.Window.QTest():
- evt, val= Blender.Window.QRead()
- if (evt==LEFTMOUSE or evt==RIGHTMOUSE) and not Blender.Window.EditMode():
- mouse_co=Blender.Window.GetMouseCoords()
- #if click on trajectory "vertexs"...
- for ob, TestPOINTS, TestFRAME in TestLIST: # ob is now used, line 552 to know what object it had to select
- for k, Vect in enumerate(TestPOINTS):
- proj=Vect*matview
-
- pt=[(proj[0]/proj[3])*(x1-x0)/2+(x1+x0)/2, (proj[1]/proj[3])*(y1-y0)/2+(y1+y0)/2]
-
- if mouse_co[0]<pt[0]+4 and mouse_co[0]>pt[0]-4 and mouse_co[1]>pt[1]-4 and mouse_co[1]<pt[1]+4:
- if evt==LEFTMOUSE:
- #remember current selected object
- object_names=[obj.name for obj in Blender.Object.GetSelected()]
- #this script allow to simulate a GKey, but I have to write a script
- #another way would made a infinit redraw or don't allow to move object
- #it auto unlink and delete itself
- script=\"\"\"
-import Blender
-from Blender import Draw, Window
-from Blender.Window import *
-from Blender.Draw import *
-
-from Blender.Mathutils import Vector
-
-# The following code is a bit of a hack, it allows clicking on the points and dragging directly
-#It simulate user press GKey
-#It also set the cursor position at center (because user have previously clic on area and moved the cursor):
-#And I can't get previous cursor position : redraw appear after it has been moved
-#If there is no better way you can remove this comments
-f= GetAreaID()
-SetCursorPos(0,0,0)
-#SetKeyQualifiers(1) #FIXED : the bug in older versions seems to have been fixed
-SetKeyQualifiers(0)
-QAdd(f, Blender.Draw.GKEY, 1, 0)
-QHandle(f)
-Blender.Redraw()
-done=0
-while not done:
- while Blender.Window.QTest():
- ev=Blender.Window.QRead()[0]
- if ev not in (4, 5, 18, 112, 213): #all event needed to move object
- #SetKeyQualifiers(1) #FIXED too, same reason that above
- #SetKeyQualifiers(0)
- SetKeyQualifiers(Blender.Window.GetKeyQualifiers())
- QAdd(f, ev, 1, 0)
- QHandle(f)
- Blender.Redraw()
- if ev in (RIGHTMOUSE, LEFTMOUSE, ESCKEY):
- done=1
-Blender.Set('curframe',\"\"\"+str(Blender.Get('curframe'))+\"\"\")
-Blender.Object.GetSelected()[0].sel= False
-for obname in \"\"\"+str(object_names)+\"\"\":
- ob=Blender.Object.Get(obname)
- ob.sel= True
-SetCursorPos(0,0,0)
-scripting=Blender.Text.Get('Edit_Trajectory')
-scripting.clear()
-Blender.Text.unlink(scripting)
- \"\"\"
-
- #FIXED Edit_Trajectory was longer : all SetKeyQualifiers removed
- scene=Blender.Scene.GetCurrent()
- try:
- scripting=Blender.Text.Get('Edit_Trajectory')
- scripting.clear()
- except:
- scripting=Blender.Text.New('Edit_Trajectory')
-
- scripting.write(script)
- #script= scripting #FIXED seems not needed anymore
-
- #Go to frame that correspond to selected "vertex"
- Blender.Set('curframe', TestFRAME[k])
-
- scene.objects.selected = [] #un select all objects
-
- #FIXED TestLIST[j][0].sel=0, but no j. So ob.sel and above variable changed in obj
- ob.sel= True
- Blender.Run('Edit_Trajectory')
-
- #work well now !!!
- if evt==RIGHTMOUSE :
- Blender.Set('curframe', TestFRAME[k])
-
-Manip()
-#retrieve a normal matrix
-glPopMatrix()
-glMatrixMode(GL_PROJECTION)
-glPopMatrix()
-glMatrixMode(GL_MODELVIEW)
-"""
-
-if ask_modif==0:
- text_remove('Trajectory')
- write_script('Trajectory', DrawPart)
- if handle_mode==1:
- Blender.UpdateMenus()
- else:
- link_script('Trajectory', 'Redraw')
-if ask_modif==2:
- text_remove('Trajectory')
- print("---End of Trajectory_"+str(__version__)+".py---\n--- Thanks for use ---")
diff --git a/release/scripts/armature_symmetry.py b/release/scripts/armature_symmetry.py
deleted file mode 100644
index 5ee4e086fb0..00000000000
--- a/release/scripts/armature_symmetry.py
+++ /dev/null
@@ -1,325 +0,0 @@
-#!BPY
-
-"""
-Name: 'Armature Symmetry'
-Blender: 242
-Group: 'Armature'
-Tooltip: 'Make an Armature symmetrical'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartist")
-__version__ = "1.0 2006-7-26"
-
-__doc__ = """\
-This script creates perfectly symmetrical armatures,
-based on the best fit when comparing the mirrored locations of 2 bones.
-Hidden bones are ignored, and optionally only operate on selected bones.
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell J Barton 2006
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-Vector= Blender.Mathutils.Vector
-
-
-def VecXFlip(vec):
- '''
- Return a copy of this vector x flipped.
- '''
- x,y,z= vec
- return Vector(-x,y,z)
-
-def editbone_mirror_diff(editbone1, editbone2):
- '''
- X Mirror bone compare
- return a float representing the difference between the 2 bones
- the smaller the better the match
- '''
- h1= editbone1.head
- h2= editbone2.head
-
- t1= editbone1.tail
- t2= editbone2.tail
-
- # Mirror bone2's location
- h2= VecXFlip(h2)
- t2= VecXFlip(t2)
-
- #return (h1-h2).length + (t1-t2).length # returns the length only
-
- # For this function its easier to return the bones also
- return ((h1-h2).length + (t1-t2).length)/2, editbone1, editbone2
-
-def editbone_mirror_merge(editbone1, editbone2, PREF_MODE_L2R, PREF_MODE_R2L):
- '''
- Merge these 2 bones to their mirrored locations
- '''
- h1= editbone1.head
- h2= editbone2.head
-
- t1= editbone1.tail
- t2= editbone2.tail
-
- if PREF_MODE_L2R and PREF_MODE_R2L:
- # Median, flip bone2's locations and average, then apply to editbone1, flip and apply to editbone2
- h2_f= VecXFlip(h2)
- t2_f= VecXFlip(t2)
-
- h_med= (h1+h2_f)*0.5 # middle between t1 and flipped t2
- t_med= (t1+t2_f)*0.5 # middle between h1 and flipped h2
-
- # Apply the median to editbone1
- editbone1.head= h_med
- editbone1.tail= t_med
-
- # Flip in place for editbone2
- h_med.x= -h_med.x
- t_med.x= -t_med.x
-
- # Apply the median to editbone2
- editbone2.head= h_med
- editbone2.tail= t_med
-
- # Average the roll, this might need some logical work, but looks good for now.
- r1= editbone1.roll
- r2= -editbone2.roll
- # print 'rolls are', r1,r2
- r_med= (r1+r2)/2
- # print 'new roll is', r_med
- editbone1.roll= r_med
- editbone2.roll= -r_med # mirror roll
-
- else: # Copy from 1 side to another
-
- # Crafty function we can use so L>R and R>L can use the same code
- def IS_XMIRROR_SOURCE(xval):
- '''Source means is this the value we want to copy from'''
-
- if PREF_MODE_L2R:
- if xval<0: return True
- else: return False
- else: # PREF_MODE_R2L
- if xval<0: return False
- else: return True
-
- if IS_XMIRROR_SOURCE( h1.x ):# head bone 1s negative, so copy it to h2
- editbone2.head= VecXFlip(h1)
- else:
- '''
- assume h2.x<0 - not a big deal if were wrong,
- its unlikely to ever happen because the bones would both be on the same side.
- '''
-
- # head bone 2s negative, so copy it to h1
- editbone1.head= VecXFlip(h2)
-
- # Same as above for tail
- if IS_XMIRROR_SOURCE(t1.x):
- editbone2.tail= VecXFlip(t1)
- else:
- editbone1.tail= VecXFlip(t2)
-
- # Copy roll from 1 bone to another, use the head's location to decide which side it's on.
- if IS_XMIRROR_SOURCE(editbone1.head):
- editbone2.roll= -editbone1.roll
- else:
- editbone1.roll= -editbone2.roll
-
-
-def armature_symetry(\
- arm_ob,\
- PREF_MAX_DIST,\
- PREF_XMID_SNAP,\
- PREF_XZERO_THRESH,\
- PREF_MODE_L2R,\
- PREF_MODE_R2L,\
- PREF_SEL_ONLY):
-
- '''
- Main function that does all the work,
- return the number of
- '''
- arm_data= arm_ob.data
- arm_data.makeEditable()
-
- # Get the bones
- bones= []
- HIDDEN_EDIT= Blender.Armature.HIDDEN_EDIT
- BONE_SELECTED= Blender.Armature.BONE_SELECTED
-
- if PREF_SEL_ONLY:
- for eb in arm_data.bones.values():
- options= eb.options
- if HIDDEN_EDIT not in options and BONE_SELECTED in options:
- bones.append(eb)
- else:
- # All non hidden bones
- for eb in arm_data.bones.values():
- options= eb.options
- if HIDDEN_EDIT not in options:
- bones.append(eb)
-
- del HIDDEN_EDIT # remove temp variables
- del BONE_SELECTED
-
- # Store the numder of bones we have modified for a message
- tot_editbones= len(bones)
- tot_editbones_modified= 0
-
- if PREF_XMID_SNAP:
- # Remove bones that are in the middle (X Zero)
- # reverse loop so we can remove items in the list.
- for eb_idx in xrange(len(bones)-1, -1, -1):
- edit_bone= bones[eb_idx]
- if abs(edit_bone.head.x) + abs(edit_bone.tail.x) <= PREF_XZERO_THRESH/2:
-
- # This is a center bone, clamp and remove from the bone list so we dont use again.
- if edit_bone.tail.x or edit_bone.head.x:
- tot_editbones_modified += 1
-
- edit_bone.tail.x= edit_bone.head.x= 0
- del bones[eb_idx]
-
-
-
-
- bone_comparisons= []
-
- # Compare every bone with every other bone, shouldn't be too slow.
- # These 2 "for" loops only compare once
- for eb_idx_a in xrange(len(bones)-1, -1, -1):
- edit_bone_a= bones[eb_idx_a]
- for eb_idx_b in xrange(eb_idx_a-1, -1, -1):
- edit_bone_b= bones[eb_idx_b]
- # Error float the first value from editbone_mirror_diff() so we can sort the resulting list.
- bone_comparisons.append(editbone_mirror_diff(edit_bone_a, edit_bone_b))
-
-
- bone_comparisons.sort() # best matches first
-
- # Make a dict() of bone names that have been used so we dont mirror more then once
- bone_mirrored= {}
-
- for error, editbone1, editbone2 in bone_comparisons:
- # print 'Trying to merge at error %.3f' % error
- if error > PREF_MAX_DIST:
- # print 'breaking, max error limit reached PREF_MAX_DIST: %.3f' % PREF_MAX_DIST
- break
-
- if not bone_mirrored.has_key(editbone1.name) and not bone_mirrored.has_key(editbone2.name):
- # Were not used, execute the mirror
- editbone_mirror_merge(editbone1, editbone2, PREF_MODE_L2R, PREF_MODE_R2L)
- # print 'Merging bones'
-
- # Add ourselves so we aren't touched again
- bone_mirrored[editbone1.name] = None # dummy value, would use sets in python 2.4
- bone_mirrored[editbone2.name] = None
-
- # If both options are enabled, then we have changed 2 bones
- tot_editbones_modified+= PREF_MODE_L2R + PREF_MODE_R2L
-
- arm_data.update() # get out of armature editmode
- return tot_editbones, tot_editbones_modified
-
-
-def main():
- '''
- User interface function that gets the options and calls armature_symetry()
- '''
-
- scn= bpy.data.scenes.active
- arm_ob= scn.objects.active
-
- if not arm_ob or arm_ob.type!='Armature':
- Blender.Draw.PupMenu('No Armature object selected.')
- return
-
- # Cant be in editmode for armature.makeEditable()
- is_editmode= Blender.Window.EditMode()
- if is_editmode: Blender.Window.EditMode(0)
- Draw= Blender.Draw
-
- # Defaults for the user input
- PREF_XMID_SNAP= Draw.Create(1)
- PREF_MAX_DIST= Draw.Create(0.4)
- PREF_XZERO_THRESH= Draw.Create(0.02)
-
- PREF_MODE_L2R= Draw.Create(1)
- PREF_MODE_R2L= Draw.Create(0)
- PREF_SEL_ONLY= Draw.Create(1)
-
- pup_block = [\
- 'Left (-), Right (+)',\
- ('Left > Right', PREF_MODE_L2R, 'Copy from the Left to Right of the mesh. Enable Both for a mid loc.'),\
- ('Right > Left', PREF_MODE_R2L, 'Copy from the Right to Left of the mesh. Enable Both for a mid loc.'),\
- '',\
- ('MaxDist:', PREF_MAX_DIST, 0.0, 4.0, 'Maximum difference in mirror bones to match up pairs.'),\
- ('XZero limit:', PREF_XZERO_THRESH, 0.0, 2.0, 'Tolerance for locking bones into the middle (X/zero).'),\
- ('XMidSnap Bones', PREF_XMID_SNAP, 'Snap middle verts to X Zero (uses XZero limit)'),\
- ('Selected Only', PREF_SEL_ONLY, 'Only xmirror selected bones.'),\
- ]
-
- # Popup, exit if the user doesn't click OK
- if not Draw.PupBlock("X Mirror mesh tool", pup_block):
- return
-
- # Replace the variables with their button values.
- PREF_XMID_SNAP= PREF_XMID_SNAP.val
- PREF_MAX_DIST= PREF_MAX_DIST.val
- PREF_MODE_L2R= PREF_MODE_L2R.val
- PREF_MODE_R2L= PREF_MODE_R2L.val
- PREF_XZERO_THRESH= PREF_XZERO_THRESH.val
- PREF_SEL_ONLY= PREF_SEL_ONLY.val
-
- # If both are off assume mid-point and enable both
- if not PREF_MODE_R2L and not PREF_MODE_L2R:
- PREF_MODE_R2L= PREF_MODE_L2R= True
-
-
- tot_editbones, tot_editbones_modified = armature_symetry(\
- arm_ob,\
- PREF_MAX_DIST,\
- PREF_XMID_SNAP,\
- PREF_XZERO_THRESH,\
- PREF_MODE_L2R,\
- PREF_MODE_R2L,\
- PREF_SEL_ONLY)
-
- if is_editmode: Blender.Window.EditMode(1)
-
- # Redraw all views before popup
- Blender.Window.RedrawAll()
-
- # Print results
- if PREF_SEL_ONLY:
- msg= 'moved %i bones of %i selected' % (tot_editbones_modified, tot_editbones)
- else:
- msg= 'moved %i bones of %i visible' % (tot_editbones_modified, tot_editbones)
-
-
- Blender.Draw.PupMenu(msg)
-
-# Check for __main__ so this function can be imported by other scripts without running the script.
-if __name__=='__main__':
- main()
diff --git a/release/scripts/bevel_center.py b/release/scripts/bevel_center.py
deleted file mode 100644
index 637ed08127f..00000000000
--- a/release/scripts/bevel_center.py
+++ /dev/null
@@ -1,474 +0,0 @@
-#!BPY
-# -*- coding: utf-8 -*-
-""" Registration info for Blender menus
-Name: 'Bevel Center'
-Blender: 243
-Group: 'Mesh'
-Tip: 'Bevel selected faces, edges, and vertices'
-"""
-
-__author__ = "Loic BERTHE"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "2.0"
-
-__bpydoc__ = """\
-This script implements vertex and edges bevelling in Blender.
-
-Usage:
-
-Select the mesh you want to work on, enter Edit Mode and select the edges
-to bevel. Then run this script from the 3d View's Mesh->Scripts menu.
-
-You can control the thickness of the bevel with the slider -- redefine the
-end points for bigger or smaller ranges. The thickness can be changed even
-after applying the bevel, as many times as needed.
-
-For an extra smoothing after or instead of direct bevel, set the level of
-recursiveness and use the "Recursive" button.
-
-This "Recursive" Button, won't work in face select mode, unless you choose
-"faces" in the select mode menu.
-
-Notes:<br>
- You can undo and redo your steps just like with normal mesh operations in
-Blender.
-"""
-
-######################################################################
-# Bevel Center v2.0 for Blender
-
-# This script lets you bevel the selected vertices or edges and control the
-# thickness of the bevel
-
-# (c) 2004-2006 Loïc Berthe (loic+blender@lilotux.net)
-# released under Blender Artistic License
-
-######################################################################
-
-import Blender
-from Blender import NMesh, Window, Scene
-from Blender.Draw import *
-from Blender.Mathutils import *
-from Blender.BGL import *
-import BPyMessages
-#PY23 NO SETS#
-'''
-try:
- set()
-except:
- from sets import set
-'''
-
-######################################################################
-# Functions to handle the global structures of the script NF, NE and NC
-# which contain informations about faces and corners to be created
-
-global E_selected
-E_selected = NMesh.EdgeFlags['SELECT']
-
-old_dist = None
-
-def act_mesh_ob():
- scn = Scene.GetCurrent()
- ob = scn.objects.active
- if ob == None or ob.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- if ob.getData(mesh=1).multires:
- BPyMessages.Error_NoMeshMultiresEdit()
- return
-
- return ob
-
-def make_sel_vert(*co):
- v= NMesh.Vert(*co)
- v.sel = 1
- me.verts.append(v)
- return v
-
-def make_sel_face(verts):
- f = NMesh.Face(verts)
- f.sel = 1
- me.addFace(f)
-
-def add_to_NV(old,dir,new):
- try:
- NV[old][dir] = new
- except:
- NV[old] = {dir:new}
-
-def get_v(old, *neighbors):
- # compute the direction of the new vert
- if len(neighbors) == 1: dir = (neighbors[0].co - old.co).normalize()
- #dir
- else: dir = (neighbors[0].co - old.co).normalize() + (neighbors[1].co-old.co).normalize()
-
- # look in NV if this vert already exists
- key = tuple(dir)
- if old in NV and key in NV[old] : return NV[old][key]
-
- # else, create it
- new = old.co + dist.val*dir
- v = make_sel_vert(new.x,new.y,new.z)
- add_to_NV(old,key,v)
- return v
-
-def make_faces():
- """ Analyse the mesh, make the faces corresponding to selected faces and
- fill the structures NE and NC """
-
- # make the differents flags consistent
- for e in me.edges:
- if e.flag & E_selected :
- e.v1.sel = 1
- e.v2.sel = 1
-
- NF =[] # NF : New faces
- for f in me.faces:
- V = f.v
- nV = len(V)
- enumV = range(nV)
- E = [me.findEdge(V[i],V[(i+1) % nV]) for i in enumV]
- Esel = [x.flag & E_selected for x in E]
-
- # look for selected vertices and creates a list containing the new vertices
- newV = V[:]
- changes = False
- for (i,v) in enumerate(V):
- if v.sel :
- changes = True
- if Esel[i-1] == 0 and Esel[i] == 1 : newV[i] = get_v(v,V[i-1])
- elif Esel[i-1] == 1 and Esel[i] == 0 : newV[i] = get_v(v,V[(i+1) % nV])
- elif Esel[i-1] == 1 and Esel[i] == 1 : newV[i] = get_v(v,V[i-1],V[(i+1) % nV])
- else : newV[i] = [get_v(v,V[i-1]),get_v(v,V[(i+1) % nV])]
-
- if changes:
- # determine and store the face to be created
-
- lenV = [len(x) for x in newV]
- if 2 not in lenV :
- new_f = NMesh.Face(newV)
- if sum(Esel) == nV : new_f.sel = 1
- NF.append(new_f)
-
- else :
- nb2 = lenV.count(2)
-
- if nV == 4 : # f is a quad
- if nb2 == 1 :
- ind2 = lenV.index(2)
- NF.append(NMesh.Face([newV[ind2-1],newV[ind2][0],newV[ind2][1],newV[ind2-3]]))
- NF.append(NMesh.Face([newV[ind2-1],newV[ind2-2],newV[ind2-3]]))
-
- elif nb2 == 2 :
- # We must know if the tuples are neighbours
- ind2 = ''.join([str(x) for x in lenV+lenV[:1]]).find('22')
-
- if ind2 != -1 : # They are
- NF.append(NMesh.Face([newV[ind2][0],newV[ind2][1],newV[ind2-3][0],newV[ind2-3][1]]))
- NF.append(NMesh.Face([newV[ind2][0],newV[ind2-1],newV[ind2-2],newV[ind2-3][1]]))
-
- else: # They aren't
- ind2 = lenV.index(2)
- NF.append(NMesh.Face([newV[ind2][0],newV[ind2][1],newV[ind2-2][0],newV[ind2-2][1]]))
- NF.append(NMesh.Face([newV[ind2][1],newV[ind2-3],newV[ind2-2][0]]))
- NF.append(NMesh.Face([newV[ind2][0],newV[ind2-1],newV[ind2-2][1]]))
-
- elif nb2 == 3 :
- ind2 = lenV.index(3)
- NF.append(NMesh.Face([newV[ind2-1][1],newV[ind2],newV[ind2-3][0]]))
- NF.append(NMesh.Face([newV[ind2-1][0],newV[ind2-1][1],newV[ind2-3][0],newV[ind2-3][1]]))
- NF.append(NMesh.Face([newV[ind2-3][1],newV[ind2-2][0],newV[ind2-2][1],newV[ind2-1][0]]))
-
- else:
- if (newV[0][1].co-newV[3][0].co).length + (newV[1][0].co-newV[2][1].co).length \
- < (newV[0][0].co-newV[1][1].co).length + (newV[2][0].co-newV[3][1].co).length :
- ind2 = 0
- else :
- ind2 = 1
- NF.append(NMesh.Face([newV[ind2-1][0],newV[ind2-1][1],newV[ind2][0],newV[ind2][1]]))
- NF.append(NMesh.Face([newV[ind2][1],newV[ind2-3][0],newV[ind2-2][1],newV[ind2-1][0]]))
- NF.append(NMesh.Face([newV[ind2-3][0],newV[ind2-3][1],newV[ind2-2][0],newV[ind2-2][1]]))
-
- else : # f is a tri
- if nb2 == 1:
- ind2 = lenV.index(2)
- NF.append(NMesh.Face([newV[ind2-2],newV[ind2-1],newV[ind2][0],newV[ind2][1]]))
-
- elif nb2 == 2:
- ind2 = lenV.index(3)
- NF.append(NMesh.Face([newV[ind2-1][1],newV[ind2],newV[ind2-2][0]]))
- NF.append(NMesh.Face([newV[ind2-2][0],newV[ind2-2][1],newV[ind2-1][0],newV[ind2-1][1]]))
-
- else:
- ind2 = min( [((newV[i][1].co-newV[i-1][0].co).length, i) for i in enumV] )[1]
- NF.append(NMesh.Face([newV[ind2-1][1],newV[ind2][0],newV[ind2][1],newV[ind2-2][0]]))
- NF.append(NMesh.Face([newV[ind2-2][0],newV[ind2-2][1],newV[ind2-1][0],newV[ind2-1][1]]))
-
- # Preparing the corners
- for i in enumV:
- if lenV[i] == 2 : NC.setdefault(V[i],[]).append(newV[i])
-
-
- old_faces.append(f)
-
- # Preparing the Edges
- for i in enumV:
- if Esel[i]:
- verts = [newV[i],newV[(i+1) % nV]]
- if V[i].index > V[(i+1) % nV].index : verts.reverse()
- NE.setdefault(E[i],[]).append(verts)
-
- # Create the faces
- for f in NF: me.addFace(f)
-
-def make_edges():
- """ Make the faces corresponding to selected edges """
-
- for old,new in NE.iteritems() :
- if len(new) == 1 : # This edge was on a border
- oldv = [old.v1, old.v2]
- if old.v1.index < old.v2.index : oldv.reverse()
-
- make_sel_face(oldv+new[0])
-
- me.findEdge(*oldv).flag |= E_selected
- me.findEdge(*new[0]).flag |= E_selected
-
- #PY23 NO SETS# for v in oldv : NV_ext.add(v)
- for v in oldv : NV_ext[v]= None
-
- else:
- make_sel_face(new[0] + new[1][::-1])
-
- me.findEdge(*new[0]).flag |= E_selected
- me.findEdge(*new[1]).flag |= E_selected
-
-def make_corners():
- """ Make the faces corresponding to corners """
-
- for v in NV.iterkeys():
- V = NV[v].values()
- nV = len(V)
-
- if nV == 1: pass
-
- elif nV == 2 :
- #PY23 NO SETS# if v in NV_ext:
- if v in NV_ext.iterkeys():
- make_sel_face(V+[v])
- me.findEdge(*V).flag |= E_selected
-
- else:
- #PY23 NO SETS# if nV == 3 and v not in NV_ext : make_sel_face(V)
- if nV == 3 and v not in NV_ext.iterkeys() : make_sel_face(V)
-
-
- else :
-
- # We need to know which are the edges around the corner.
- # First, we look for the quads surrounding the corner.
- eed = []
- for old, new in NE.iteritems():
- if v in (old.v1,old.v2) :
- if v.index == min(old.v1.index,old.v2.index) : ind = 0
- else : ind = 1
-
- if len(new) == 1: eed.append([v,new[0][ind]])
- else : eed.append([new[0][ind],new[1][ind]])
-
- # We will add the edges coming from faces where only one vertice is selected.
- # They are stored in NC.
- if v in NC: eed = eed+NC[v]
-
- # Now we have to sort these vertices
- hc = {}
- for (a,b) in eed :
- hc.setdefault(a,[]).append(b)
- hc.setdefault(b,[]).append(a)
-
- for x0,edges in hc.iteritems():
- if len(edges) == 1 : break
-
- b = [x0] # b will contain the sorted list of vertices
-
- for i in xrange(len(hc)-1):
- for x in hc[x0] :
- if x not in b : break
- b.append(x)
- x0 = x
-
- b.append(b[0])
-
- # Now we can create the faces
- if len(b) == 5: make_sel_face(b[:4])
-
- else:
- New_V = Vector(0.0, 0.0,0.0)
- New_d = [0.0, 0.0,0.0]
-
- for x in hc.iterkeys(): New_V += x.co
- for dir in NV[v] :
- for i in xrange(3): New_d[i] += dir[i]
-
- New_V *= 1./len(hc)
- for i in xrange(3) : New_d[i] /= nV
-
- center = make_sel_vert(New_V.x,New_V.y,New_V.z)
- add_to_NV(v,tuple(New_d),center)
-
- for k in xrange(len(b)-1): make_sel_face([center, b[k], b[k+1]])
-
- if 2 < nV and v in NC :
- for edge in NC[v] : me.findEdge(*edge).flag |= E_selected
-
-def clear_old():
- """ Erase old faces and vertices """
-
- for f in old_faces: me.removeFace(f)
-
- for v in NV.iterkeys():
- #PY23 NO SETS# if v not in NV_ext : me.verts.remove(v)
- if v not in NV_ext.iterkeys() : me.verts.remove(v)
-
- for e in me.edges:
- if e.flag & E_selected :
- e.v1.sel = 1
- e.v2.sel = 1
-
-
-######################################################################
-# Interface
-
-global dist
-
-dist = Create(0.2)
-left = Create(0.0)
-right = Create(1.0)
-num = Create(2)
-
-# Events
-EVENT_NOEVENT = 1
-EVENT_BEVEL = 2
-EVENT_UPDATE = 3
-EVENT_RECURS = 4
-EVENT_EXIT = 5
-
-def draw():
- global dist, left, right, num, old_dist
- global EVENT_NOEVENT, EVENT_BEVEL, EVENT_UPDATE, EVENT_RECURS, EVENT_EXIT
-
- glClear(GL_COLOR_BUFFER_BIT)
- Button("Bevel",EVENT_BEVEL,10,100,280,25)
-
- BeginAlign()
- left=Number('', EVENT_NOEVENT,10,70,45, 20,left.val,0,right.val,'Set the minimum of the slider')
- dist=Slider("Thickness ",EVENT_UPDATE,60,70,180,20,dist.val,left.val,right.val,0, \
- "Thickness of the bevel, can be changed even after bevelling")
- right = Number("",EVENT_NOEVENT,245,70,45,20,right.val,left.val,200,"Set the maximum of the slider")
-
- EndAlign()
- glRasterPos2d(8,40)
- Text('To finish, you can use recursive bevel to smooth it')
-
-
- if old_dist != None:
- num=Number('', EVENT_NOEVENT,10,10,40, 16,num.val,1,100,'Recursion level')
- Button("Recursive",EVENT_RECURS,55,10,100,16)
-
- Button("Exit",EVENT_EXIT,210,10,80,20)
-
-def event(evt, val):
- if ((evt == QKEY or evt == ESCKEY) and not val): Exit()
-
-def bevent(evt):
- if evt == EVENT_EXIT : Exit()
- elif evt == EVENT_BEVEL : bevel()
- elif evt == EVENT_UPDATE :
- try: bevel_update()
- except NameError : pass
- elif evt == EVENT_RECURS : recursive()
-
-Register(draw, event, bevent)
-
-######################################################################
-def bevel():
- """ The main function, which creates the bevel """
- global me,NV,NV_ext,NE,NC, old_faces,old_dist
-
- ob = act_mesh_ob()
- if not ob: return
-
- Window.WaitCursor(1) # Change the Cursor
- t= Blender.sys.time()
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
-
- me = ob.data
-
- NV = {}
- #PY23 NO SETS# NV_ext = set()
- NV_ext= {}
- NE = {}
- NC = {}
- old_faces = []
-
- make_faces()
- make_edges()
- make_corners()
- clear_old()
-
- old_dist = dist.val
- print '\tbevel in %.6f sec' % (Blender.sys.time()-t)
- me.update(1)
- if is_editmode: Window.EditMode(1)
- Window.WaitCursor(0)
- Blender.Redraw()
-
-def bevel_update():
- """ Use NV to update the bevel """
- global dist, old_dist
-
- if old_dist == None:
- # PupMenu('Error%t|Must bevel first.')
- return
-
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
-
- fac = dist.val - old_dist
- old_dist = dist.val
-
- for old_v in NV.iterkeys():
- for dir in NV[old_v].iterkeys():
- for i in xrange(3):
- NV[old_v][dir].co[i] += fac*dir[i]
-
- me.update(1)
- if is_editmode: Window.EditMode(1)
- Blender.Redraw()
-
-def recursive():
- """ Make a recursive bevel... still experimental """
- global dist
- from math import pi, sin
-
- if num.val > 1:
- a = pi/4
- ang = []
- for k in xrange(num.val):
- ang.append(a)
- a = (pi+2*a)/4
-
- l = [2*(1-sin(x))/sin(2*x) for x in ang]
- R = dist.val/sum(l)
- l = [x*R for x in l]
-
- dist.val = l[0]
- bevel_update()
-
- for x in l[1:]:
- dist.val = x
- bevel()
-
diff --git a/release/scripts/blenderLipSynchro.py b/release/scripts/blenderLipSynchro.py
deleted file mode 100644
index c4815811512..00000000000
--- a/release/scripts/blenderLipSynchro.py
+++ /dev/null
@@ -1,729 +0,0 @@
-#!BPY
-# coding: utf-8
-"""
-Name: 'BlenderLipSynchro'
-Blender: 242
-Group: 'Animation'
-Tooltip: 'Import phonemes from Papagayo or JLipSync for lip synchronization'
-"""
-
-__author__ = "Dienben: Benoit Foucque dienben_mail@yahoo.fr"
-__url__ = ["blenderLipSynchro Blog, http://blenderlipsynchro.blogspot.com/",
-"Papagayo (Python), http://www.lostmarble.com/papagayo/index.shtml",
-"JLipSync (Java), http://jlipsync.sourceforge.net/"]
-__version__ = "2.0"
-__bpydoc__ = """\
-Description:
-
-This script imports Voice Export made by Papagayo or JLipSync and maps the export with your shapes.
-
-Usage:
-
-Import a Papagayo or JLipSync voice export file and link it with your shapes.
-
-Note:<br>
-- Naturally, you need files exported from one of the supported lip synching
-programs. Check their sites to learn more and download them.
-
-"""
-
-# --------------------------------------------------------------------------
-# BlenderLipSynchro
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-
-#il y a 3 etapes
-#la deuxieme on charge le dictionnaire de correspondance
-#la troisieme on fait le choix des correpondance
-#la quatrieme on construit les cles a partir du fichiers frame
-
-#there are 3 stages
-#the second one load the mapping dictionnary
-#the tird make the mapping
-#the fourth make the key in the IPO Curve
-
-#voici mes differents imports
-#the imports
-import os
-import Blender
-
-from Blender import Ipo
-from Blender.Draw import *
-from Blender.BGL import *
-from Blender.sys import basename
-
-
-
-#ici commencent mes fonctions
-#here begin my functions
-#cette fonction trace l'interface graphique
-#this functions draw the User interface
-def trace():
- #voici mes variables pouvant etre modifie
- #my variables
- global nbr_phoneme, mon_fichier_dico
- global let01, let02, let03, let04,let05, let06, let07, let08, let09, let10
- global let11, let12, let13, let14,let15, let16, let17, let18, let19, let20
- global let21, let22, let23, let24
-
- global let01selectkey,let02selectkey,let03selectkey,let04selectkey,let05selectkey
- global let06selectkey,let07selectkey,let08selectkey,let09selectkey,let10selectkey,let11selectkey
- global let12selectkey,let13selectkey,let14selectkey,let15selectkey,let16selectkey,let17selectkey
- global let18selectkey,let19selectkey,let20selectkey,let21selectkey,let22selectkey,let23selectkey
- global let24selectkey
-
- glClearColor(0.4,0.5,0.6 ,0.0)
- glClear(GL_COLOR_BUFFER_BIT)
-
- glColor3d(1,1,1)
- glRasterPos2i(87, 375)
- Text("Blendersynchro V 2.0")
- glColor3d(1,1,1)
- glRasterPos2i(84, 360)
- Text("Programming: Dienben")
-
- glColor3d(0,0,0)
- glRasterPos2i(13, 342)
- Text("Lip Synchronization Tool")
- glColor3d(0,0,0)
- glRasterPos2i(13, 326)
- Text("Thanks to Chris Clawson and Liubomir Kovatchev")
-
- glColor3d(1,1,1)
- glRasterPos2i(5, 320)
- Text("_______________________________________________________")
- glColor3d(0,0,0)
- glRasterPos2i(6, 318)
- Text("_______________________________________________________")
-
-
- if (etape==1):
- #cette etape permet de choisi la correspondance entre les phonemes et les cles
- #this stage offer the possibility to choose the mapping between phonems and shapes
-
- glColor3d(1,1,1)
- glRasterPos2i(140, 300)
- Text("Objet: "+Blender.Object.GetSelected()[0].getName() )
-
- glColor3d(1,1,1)
- glRasterPos2i(5, 215)
- Text("Assign phonems to shapes:")
-
- #on mesure la taille de la liste de phonemes
- #this is the lenght of the phonem list
- nbr_phoneme=len(liste_phoneme)
-
- #on dessine les listes de choix
- #we draw the choice list
-
- #
- if (nbr_phoneme > 0):
- let01 = String(" ", 4, 5, 185, 30, 16, liste_phoneme[0], 3)
- glColor3d(0,0,0)
- glRasterPos2i(40, 188)
- Text("=")
- let01selectkey = Menu(key_menu, 50, 50, 185, 70, 16, let01selectkey.val)
-
- #
- if (nbr_phoneme > 1):
- let02 = String(" ", 4, 150, 185, 30, 16, liste_phoneme[1], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 188)
- Text("=")
- let02selectkey = Menu(key_menu, 51, 195, 185, 70, 16, let02selectkey.val)
-
- #
- if (nbr_phoneme > 2):
- let03 = String(" ", 4, 5, 165, 30, 16, liste_phoneme[2], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 168)
- Text("=")
- let03selectkey = Menu(key_menu, 52, 50, 165, 70, 16, let03selectkey.val)
-
- #
- if (nbr_phoneme > 3):
- let04 = String(" ", 4, 150, 165, 30, 16, liste_phoneme[3], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 168)
- Text("=")
- let04selectkey = Menu(key_menu, 53, 195, 165, 70, 16, let04selectkey.val)
-
- #
- if (nbr_phoneme > 4):
- let05 = String(" ", 4, 5, 145, 30, 16, liste_phoneme[4], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 148)
- Text("=")
- let05selectkey = Menu(key_menu, 54, 50, 145, 70, 16, let05selectkey.val)
-
- #
- if (nbr_phoneme > 5):
- let06 = String(" ", 4, 150, 145, 30, 16, liste_phoneme[5], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 148)
- Text("=")
- let06selectkey = Menu(key_menu, 55, 195, 145, 70, 16, let06selectkey.val)
-
- #
- if (nbr_phoneme > 6):
- let07 = String(" ", 4, 5, 125, 30, 16, liste_phoneme[6], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 128)
- Text("=")
- let07selectkey = Menu(key_menu, 56, 50, 125, 70, 16, let07selectkey.val)
-
- #
- if (nbr_phoneme > 7):
- let08 = String(" ", 4, 150, 125, 30, 16, liste_phoneme[7], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 128)
- Text("=")
- let08selectkey = Menu(key_menu, 57, 195, 125, 70, 16,let08selectkey.val)
-
- #
- if (nbr_phoneme > 8):
- let09 = String(" ", 4, 5, 105, 30, 16, liste_phoneme[8], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 108)
- Text("=")
- let09selectkey = Menu(key_menu, 58, 50, 105, 70, 16,let09selectkey.val)
-
- #
- if (nbr_phoneme > 9):
- let10 = String(" ", 4, 150, 105, 30, 16, liste_phoneme[9], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 108)
- Text("=")
- let10selectkey = Menu(key_menu, 59, 195, 105, 70, 16, let10selectkey.val)
-
- #
- if (nbr_phoneme > 10):
- let11 = String(" ", 4, 5, 85, 30, 16, liste_phoneme[10], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 88)
- Text("=")
- let11selectkey = Menu(key_menu, 60, 50, 85, 70, 16, let11selectkey.val)
-
- #
- if (nbr_phoneme > 11):
- let12 = String(" ", 4, 150, 85, 30, 16, liste_phoneme[11], 2)
- glColor3d(0,0,0)
- Text("=")
- let12selectkey = Menu(key_menu, 61, 195, 85, 70, 16, let12selectkey.val)
-
- #
- if (nbr_phoneme > 12):
- let13 = String(" ", 4, 5, 65, 30, 16, liste_phoneme[12], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 68)
- Text("=")
- let13selectkey = Menu(key_menu, 62, 50, 65, 70, 16, let13selectkey.val)
-
- #
- if (nbr_phoneme > 13):
- let14 = String(" ", 4, 150, 65, 30, 16, liste_phoneme[13], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 68)
- Text("=")
- let14selectkey = Menu(key_menu, 63, 195, 65, 70, 16, let14selectkey.val)
-
- #
- if (nbr_phoneme > 14):
- let15 = String(" ", 4, 5, 45, 30, 16, liste_phoneme[14], 2)
- glColor3d(0,0,0)
- glRasterPos2i(40, 48)
- Text("=")
- let15selectkey = Menu(key_menu, 64, 50, 45, 70, 16, let15selectkey.val)
-
- #
- if (nbr_phoneme > 15):
- let16 = String(" ", 4, 150, 45, 30, 16, liste_phoneme[15], 2)
- glColor3d(0,0,0)
- glRasterPos2i(185, 48)
- Text("=")
- let16selectkey = Menu(key_menu, 65, 195, 45, 70, 16, let16selectkey.val)
-
- #
- if (nbr_phoneme > 16):
- let17 = String(" ", 4, 295, 185, 30, 16, liste_phoneme[16], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 188)
- Text("=")
- let17selectkey = Menu(key_menu, 66, 340, 185, 70, 16, let17selectkey.val)
-
- #
- if (nbr_phoneme > 17):
- let18 = String(" ", 4, 440, 185, 70, 16, liste_phoneme[17], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 188)
- Text("=")
- let18selectkey = Menu(key_menu, 67, 525, 185, 70, 16, let18selectkey.val)
-
- #
- if (nbr_phoneme > 18):
- let19 = String(" ", 4, 295, 165, 30, 16, liste_phoneme[18], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 168)
- Text("=")
- let19selectkey = Menu(key_menu, 68, 340, 165, 70, 16, let19selectkey.val)
-
- #
- if (nbr_phoneme > 19):
- let20 = String(" ", 4, 440, 165, 70, 16, liste_phoneme[19], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 168)
- Text("=")
- let20selectkey = Menu(key_menu, 69, 525, 165, 70, 16, let20selectkey.val)
-
- #
- if (nbr_phoneme > 20):
- let21 = String(" ", 4, 295, 145, 30, 16, liste_phoneme[20], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 148)
- Text("=")
- let21selectkey = Menu(key_menu, 70, 340, 145, 70, 16, let21selectkey.val)
-
- #
- if (nbr_phoneme > 21):
- let22 = String(" ", 4, 440, 145, 70, 16, liste_phoneme[21], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 148)
- Text("=")
- let22selectkey = Menu(key_menu, 71, 525, 145, 70, 16, let22selectkey.val)
-
- #
- if (nbr_phoneme > 22):
- let23 = String(" ", 4, 295, 125, 30, 16, liste_phoneme[22], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 128)
- Text("=")
- let23selectkey = Menu(key_menu, 72, 340, 125, 70, 16,let23selectkey.val)
-
- #
- if (nbr_phoneme > 23):
- let24 = String(" ", 4, 440, 125, 70, 16, liste_phoneme[23], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 128)
- Text("=")
- let24selectkey = Menu(key_menu, 73, 525, 125, 70, 16, let24selectkey.val)
-
- #
- if (nbr_phoneme > 24):
- let25 = String(" ", 4, 295, 105, 30, 16, liste_phoneme[24], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 108)
- Text("=")
- let25selectkey = Menu(key_menu, 74, 340, 105, 70, 16, let25selectkey.val)
-
- #
- if (nbr_phoneme > 25):
- let26 = String(" ", 4, 440, 105, 70, 16, liste_phoneme[25], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 108)
- Text("=")
- let26selectkey = Menu(key_menu, 75, 525, 105, 70, 16,let26selectkey.val)
-
- #
- if (nbr_phoneme > 26):
- let27 = String(" ", 4, 295, 85, 30, 16, liste_phoneme[26], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 88)
- Text("=")
- let27selectkey = Menu(key_menu, 76, 340, 85, 70, 16, let27selectkey.val)
-
- #
- if (nbr_phoneme > 27):
- let28 = String(" ", 4, 440, 85, 70, 16, liste_phoneme[27], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 88)
- Text("=")
- let28selectkey = Menu(key_menu, 77, 525, 85, 70, 16,let28selectkey.val)
-
- #
- if (nbr_phoneme > 28):
- let29 = String(" ", 4, 295, 65, 30, 16, liste_phoneme[28], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 68)
- Text("=")
- let29selectkey = Menu(key_menu, 78, 340, 65, 70, 16, let29selectkey.val)
-
- #
- if (nbr_phoneme > 29):
- let30 = String(" ", 4, 440, 65, 70, 16, liste_phoneme[29], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 68)
- Text("=")
- let30selectkey = Menu(key_menu, 79, 525, 65, 70, 16, let30selectkey.val)
-
- #
- if (nbr_phoneme > 30):
- let31 = String(" ", 4, 295, 45, 30, 16, liste_phoneme[30], 2)
- glColor3d(0,0,0)
- glRasterPos2i(330, 48)
- Text("=")
- let31selectkey = Menu(key_menu, 80, 340, 45, 70, 16, let31selectkey.val)
-
- #
- if (nbr_phoneme > 31):
- let32 = String(" ", 4, 440, 45, 70, 16, liste_phoneme[31], 8)
- glColor3d(0,0,0)
- glRasterPos2i(515, 48)
- Text("=")
- let32selectkey = Menu(key_menu, 81, 525, 45, 70, 16, let32selectkey.val)
-
- Button("Go", 3, 155, 5, 145, 22)
-
- if (etape==2):
- glColor3d(1,1,1)
- glRasterPos2i(125, 200)
- Text("Operation Completed")
-
- if (etape==0):
- glColor3d(1,1,1)
- glRasterPos2i(125, 200)
- Text("Please select a Mesh'Object and Create all the IPO Curves for your Shapes")
-
- if (etape==3):
- #this stage permits to load a custom dictionnary
- load_file_text = "Load File"
- if mon_fichier_dico:
- Button("Import Loaded File", 2, 5, 5, 145, 22)
- glColor3d(1,1,1)
- glRasterPos2i(6, 50)
- Text("loaded file: %s" % basename(mon_fichier_dico))
- load_file_text = "Choose Another File"
- Button(load_file_text, 8, 125, 180, 145, 22)
-
- glRasterPos2i(6, 40)
- Text("_______________________________________________________")
- glColor3d(0,0,0)
- glRasterPos2i(6, 38)
- Text("_______________________________________________________")
-
- Button("Exit", 1, 305, 5, 80, 22)
-
-
-
-#cette fonction sur evenement quite en cas d'ESC
-#this functions catch the ESC event and quit
-def event(evt,val):
- if (evt == ESCKEY and not val): Exit()
-
-#cette fonction gere les evenements
-#the event functions
-def bevent(evt):
- global etape,soft_type,liste_phoneme,dico_phoneme_export
-
- if (evt == 1):
- Exit()
-
- elif (evt == 2):
- #c'est l'import du dictionnaire
- #we create and import the dictionnary
- lecture_chaine(mon_fichier_dico,dico_phoneme_export)
- construction_dictionnaire_phoneme()
- #we change the stage
- etape=1
-
- elif (evt == 3):
- #c'est l'import
- #we import
- lecture_chaine(mon_fichier_export,dico_phoneme_export)
- construction_dico_correspondance()
- construction_lipsynchro()
- #on change d'etape
- #we change the stage
- etape=2
-
- elif (evt == 8):
- #we choose the file
- Blender.Window.FileSelector(selectionner_fichier,"Select File")
-
- Blender.Redraw()
-
-#cette fonction recupere le nom et le chemin du fichier dictionnaire
-#we catch the name and the path of the dictionnary
-def selectionner_fichier(filename):
- global mon_fichier_dico,mon_fichier_export
- mon_fichier_dico=filename
- mon_fichier_export=filename
-
-#fonction de lecture de la liste frame phoneme
-#we read the frame and phonems
-def lecture_chaine(fichier,liste):
- mon_fichier=open(fichier)
- #je lis la premiere ligne qui contiens la version de moho
- #first, we read the moho version
- mon_fichier.readline()
-
- #je lis jusqu'a la fin
- #then we read until the end of the file
- while 1:
- ma_ligne=mon_fichier.readline()
- if ma_ligne=='':
- break
- decoup=ma_ligne.split()
- liste[decoup[0]]=decoup[1]
- print liste
-
-
-
-
-#fonction qui construit la liste dictionnaire simple
-#we make the dictionnary
-def construction_dictionnaire_phoneme():
- global liste_phoneme
- index_liste=0
- #je transforme mon dictionnaire en list de tulpes
- #we transform the list in tulpes
- ma_liste=dico_phoneme_export.items()
- #je parcours ma liste a la recherche d'elements non existant
- #we read the list to find non existing elements
- print dico_phoneme
- for index in range(len(ma_liste)):
- if ma_liste[index][1] not in liste_phoneme:
- liste_phoneme[index_liste:index_liste]=[ma_liste[index][1]]
- index_liste=index_liste+1
- print liste_phoneme
-
-
-#cette fonction recupere les courbes cible
-#this functon catch the IPO curve
-def recuperation_courbe():
- global key_menu,dico_key
-
- #on recupere le nom des shapes
- #we catch the shapes
- key=Blender.Object.GetSelected()[0].getData().getKey().getBlocks()
- for n in range(len(key)):
- #on vire la première cle (en effet basic n'est pas une cle en tant que telle)
- #we threw away the basic shapes
- if (n>0):
- key_menu=key_menu+key[n].name + " %x" + str(n-1) + "|"
- dico_key[str(n-1)]=Blender.Object.GetSelected()[0].getData().getKey().getIpo().getCurves()[n-1]
-
-
- print "dico_key"
- print dico_key
- print 'end dico_key'
-
-#cette fonction construit un dictionnaire de correspondance entre les phonemes prononces et les cles a utiliser
-#we make the dictionnary for the mapping between shapes and phonems
-def construction_dico_correspondance():
- global dico_correspondance
- #je parcours les phonemes
- #we read the phonems
- if (nbr_phoneme>0):
- dico_correspondance[liste_phoneme[0]]=dico_key[str(let01selectkey.val)]
- if (nbr_phoneme>1):
- dico_correspondance[liste_phoneme[1]]=dico_key[str(let02selectkey.val)]
- if (nbr_phoneme>2):
- dico_correspondance[liste_phoneme[2]]=dico_key[str(let03selectkey.val)]
- if (nbr_phoneme>3):
- dico_correspondance[liste_phoneme[3]]=dico_key[str(let04selectkey.val)]
- if (nbr_phoneme>4):
- dico_correspondance[liste_phoneme[4]]=dico_key[str(let05selectkey.val)]
- if (nbr_phoneme>5):
- dico_correspondance[liste_phoneme[5]]=dico_key[str(let06selectkey.val)]
- if (nbr_phoneme>6):
- dico_correspondance[liste_phoneme[6]]=dico_key[str(let07selectkey.val)]
- if (nbr_phoneme>7):
- dico_correspondance[liste_phoneme[7]]=dico_key[str(let08selectkey.val)]
- if (nbr_phoneme>8):
- dico_correspondance[liste_phoneme[8]]=dico_key[str(let09selectkey.val)]
- if (nbr_phoneme>9):
- dico_correspondance[liste_phoneme[9]]=dico_key[str(let10selectkey.val)]
- if (nbr_phoneme>10):
- dico_correspondance[liste_phoneme[10]]=dico_key[str(let11selectkey.val)]
- if (nbr_phoneme>11):
- dico_correspondance[liste_phoneme[11]]=dico_key[str(let12selectkey.val)]
- if (nbr_phoneme>12):
- dico_correspondance[liste_phoneme[12]]=dico_key[str(let13selectkey.val)]
- if (nbr_phoneme>13):
- dico_correspondance[liste_phoneme[13]]=dico_key[str(let14selectkey.val)]
- if (nbr_phoneme>14):
- dico_correspondance[liste_phoneme[14]]=dico_key[str(let15selectkey.val)]
- if (nbr_phoneme>15):
- dico_correspondance[liste_phoneme[15]]=dico_key[str(let16selectkey.val)]
- if (nbr_phoneme>16):
- dico_correspondance[liste_phoneme[16]]=dico_key[str(let17selectkey.val)]
- if (nbr_phoneme>17):
- dico_correspondance[liste_phoneme[17]]=dico_key[str(let18selectkey.val)]
- if (nbr_phoneme>18):
- dico_correspondance[liste_phoneme[18]]=dico_key[str(let19selectkey.val)]
- if (nbr_phoneme>19):
- dico_correspondance[liste_phoneme[19]]=dico_key[str(let20selectkey.val)]
- if (nbr_phoneme>20):
- dico_correspondance[liste_phoneme[20]]=dico_key[str(let21selectkey.val)]
- if (nbr_phoneme>21):
- dico_correspondance[liste_phoneme[21]]=dico_key[str(let22selectkey.val)]
- if (nbr_phoneme>22):
- dico_correspondance[liste_phoneme[22]]=dico_key[str(let23selectkey.val)]
- if (nbr_phoneme>23):
- dico_correspondance[liste_phoneme[23]]=dico_key[str(let24selectkey.val)]
- if (nbr_phoneme>24):
- dico_correspondance[liste_phoneme[24]]=dico_key[str(let25selectkey.val)]
- if (nbr_phoneme>25):
- dico_correspondance[liste_phoneme[25]]=dico_key[str(let26selectkey.val)]
- if (nbr_phoneme>26):
- dico_correspondance[liste_phoneme[26]]=dico_key[str(let27selectkey.val)]
- if (nbr_phoneme>27):
- dico_correspondance[liste_phoneme[27]]=dico_key[str(let28selectkey.val)]
- if (nbr_phoneme>28):
- dico_correspondance[liste_phoneme[28]]=dico_key[str(let29selectkey.val)]
- if (nbr_phoneme>29):
- dico_correspondance[liste_phoneme[29]]=dico_key[str(let30selectkey.val)]
- if (nbr_phoneme>30):
- dico_correspondance[liste_phoneme[30]]=dico_key[str(let31selectkey.val)]
- if (nbr_phoneme>31):
- dico_correspondance[liste_phoneme[31]]=dico_key[str(let32selectkey.val)]
-
- print dico_correspondance
-
-
-#cette fonction ajoute un points a la cle donnee a la frame donnee
-#we add a point to the IPO curve Target
-def ajoute_point(cle,frame,valeur):
- cle.setInterpolation('Linear')
- cle.append((frame,valeur))
- cle.Recalc()
-
-#cette fonction parcours le dictionnaire des frame à ajouter et construit les points
-#we add all the point to the IPO Curve
-def construction_lipsynchro():
- print "je construit"
- doublet_old=""
- #construction de la liste des frame
- cpt=0
- liste_frame=[]
- for frame in dico_phoneme_export:
- liste_frame.append(int(frame))
- cpt=cpt+1
- liste_frame.sort()
- print "listeframe"
- print liste_frame
- print "fini"
-
- for doublet in liste_frame:
- ajoute_point(dico_correspondance[dico_phoneme_export[str(doublet)]],doublet,1)
- if (doublet_old==""):
- ajoute_point(dico_correspondance[dico_phoneme_export[str(doublet)]],(doublet-2),0)
- if (doublet_old!=''):
- if (dico_correspondance[dico_phoneme_export[str(doublet)]]!=dico_correspondance[dico_phoneme_export[doublet_old]]):
- print "doublet:"+str(doublet)
- print "doublet old:"+doublet_old
- ajoute_point(dico_correspondance[dico_phoneme_export[doublet_old]],(int(doublet_old)+2),0)
- ajoute_point(dico_correspondance[dico_phoneme_export[str(doublet)]],(doublet-2),0)
- doublet_old=str(doublet)
-
-
-#end of my functions we begin the execution
-#je commence l execution-----------------------------------------------------------------------------------------------
-#voici mes variables
-
-#declaration et instanciation
-#decleration and instanciation
-
-
-#voici mon objet de travail
-objet_travail=Create(0)
-
-#my soft type
-soft_type=1
-
-#voici la liste des phoneme effectivement utilise
-#the phonems'list
-#liste_phoneme_papagayo=['AI','E','O','U','FV','L','WQ','MBP','etc','rest']
-#liste_phoneme_jlipsinch=['A','B','C','Closed','D','E','F','G','I','K','L','M','N','O','P','Q','R','S','SH','T','TH','U','V','W']
-
-liste_phoneme=[]
-#voici mon dictionnaire des frames o
-dico_phoneme_export = Create(0)
-dico_phoneme_export={}
-dico_phoneme={}
-
-
-#voici mes cle
-key_menu=""
-dico_key={}
-
-#voici mes ipo
-dico_bloc={}
-iponame = Create(0)
-
-#voici mon dictionnaire de correspondance
-dico_correspondance={}
-
-try:
- #on verifie est bien une mesh et qu'il a des courbes
- if ((Blender.Object.GetSelected()[0].getType()=='Mesh')):
- #on verifie que l'objet a bien toute ses Courbes
- if (len(Blender.Object.GetSelected()[0].getData().getKey().getBlocks())-1==Blender.Object.GetSelected()[0].getData().getKey().getIpo().getNcurves()):
- etape=3
- #on lance la creation du dictionnaire
- recuperation_courbe()
- else:
- print "not the good number of IPO Curve"
- etape = 0
- else:
- print "error: bad object Type:"
- print Blender.Object.GetSelected()[0].getType()
- etape = 0
-except:
- print 'error: exception'
- etape = 0
-
-
-#voici le fichier dictionnaire
-mon_fichier_dico=""
-
-#voici le fichier export pamela
-mon_fichier_export=""
-
-
-let01selectkey = Create(0)
-let02selectkey = Create(0)
-let03selectkey = Create(0)
-let04selectkey = Create(0)
-let05selectkey = Create(0)
-let06selectkey = Create(0)
-let07selectkey = Create(0)
-let08selectkey = Create(0)
-let09selectkey = Create(0)
-let10selectkey = Create(0)
-let11selectkey = Create(0)
-let12selectkey = Create(0)
-let13selectkey = Create(0)
-let14selectkey = Create(0)
-let15selectkey = Create(0)
-let16selectkey = Create(0)
-let17selectkey = Create(0)
-let18selectkey = Create(0)
-let19selectkey = Create(0)
-let20selectkey = Create(0)
-let21selectkey = Create(0)
-let22selectkey = Create(0)
-let23selectkey = Create(0)
-let24selectkey = Create(0)
-
-
-Register (trace,event,bevent)
diff --git a/release/scripts/bpydata/KUlang.txt b/release/scripts/bpydata/KUlang.txt
deleted file mode 100644
index 38605d69c9f..00000000000
--- a/release/scripts/bpydata/KUlang.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-Version 3.233-2004
-******************
-Espanol
-Sale del programa
-Utilidades de...%t|Alinea objetos%x1|Creacion%x2|Edita mallas%x3|Edita objetos%x4
-11
-Mov
-Esc
-Encaja
-Abarca
-Separa
-Alinea
-Rota
-Incr.
-Crea nuevos objetos
-Es+
-Es*
-Separar entre:%t|Origenes%x1|Centros geometricos%x2|Minimos%x3|Maximos%x4|Baricentro%x5|Objetos%x6
-Crear%t|Arco (3 ptos.)%x1|Arco (interactivo)%x2|Circunferencia (3 ptos.)%x3
-12
-Puntos
-Centro
-Orden
-Objeto
-AngIni:
-AngFin:
-Angulo:
-Radio:
-Puntos:
-Centro
-Nombre:
-Puntos
-Modifica vertices%t|Subdivide%x1|Envia a un plano%x2|Aplica LocRotSize%x3
-Partes
-Proyectar en el plano:%t|Coordenado global...%x1|Coordenado local...%x2
-Actuar sobre el plano%t|Yz%x1|Zx%x2|Xy%x3
-En la dirección%t|X%x1|Y%x2|Z%x3|Ortogonal al plano%x4
-Captura
-Buffer%t|Copia vector diferencia%x1|Copia distancia%x2|Copia diferencia de rotacion%x3|Copia media LocRotSiz%x4|Ver buffer en consola%x5
-Transformar LocRotSize%t|Hacia el obj. activo%x1|Aleatoriamente%x2
-Poner a distancia fija%x1|Sumar (desp. absoluto)%x2|Multiplicar (desp. relativo)%x3
-********************
-English
-Exit program
-Utils about:%t|Align Objects%x1|Create%x2|Edit Meshes%x3|Edit Objects%x4
-11
-Mov
-Sca
-Fit
-Embrace
-Separate
-Align
-Rota
-Incr.
-Create new objects
-Sc+
-Sc*
-Separate between:%t|Origins%x1|Geometric centers%x2|Minimum%x3|Maximum%x4|Baricenter%x5|Objects%x6
-Create what%t|Arc (3 pts.)%x1|Arc (interactive)%x2|Circunference (3 pts.)%x3
-12
-Points
-Centre
-Sort
-Object
-AngIni:
-AngEnd:
-Angle:
-Radius:
-Points:
-Centre
-ObjName:
-Points
-Modify vertices%t|Subdivide edges%x1|Send to a plane%x2|Set LocRotSize%x3
-Parts
-Project onto the plane:%t|Global coordinated...%x1|Local coordinated...%x2
-Act on plane%t|Yz%x1|Zx%x2|Xy%x3
-In direction%t|X%x1|Y%x2|Z%x3|Ortogonal to plane%x4
-Get
-Buffer%t|Copy diference vector%x1|Copy distance%x2|Copy rot diference%x3|Copy LocRotSiz average%x4|Show Buffer in Console%x5
-Transform LocRotSize%t|Close to active%x1|Randomly%x2
-Set at fixed distance%x1|Add (absolute displ.)%x2|Multiply (relative displ.)%x3
-********************
-Catala
-Surt del programa
-Utilitats de...%t|Alinea objectes%x1|Creacio%x2|Edita malles%x3|Edita objetes%x4
-11
-Mov
-Esc
-Encaixa
-Abarca
-Separa
-Alinea
-Rotacio
-Incr.
-Crea objectes nous
-Es+
-Es*
-Separa entra:%t|Origens%x1|Centres geometrics%x2|Minims%x3|Maxims%x4|Baricentre%x5|Objectes%x6
-Crear%t|Arc (3 pts.)%x1|Arc (interactiu)%x2|Circumferencia (3 pts.)%x3
-12
-Punts
-Centre
-Ordre
-Objecte
-AngIni:
-AngFi:
-Angle:
-Radi:
-Punts:
-Centre
-Nom:
-Punts
-Modifica vertex%t|Subdivideix%x1|Envia a un pla%x2|Aplica LocRotSize%x3
-Parts
-Projectar en el pla:%t|Coordenacio global...%x1|Coordenacio local...%x2
-Actuar sobre el pla%t|Yz%x1|Zx%x2|Xy%x3
-En la direccio%t|X%x1|Y%x2|Z%x3|Ortogonal al pla%x4
-Captura
-Buffer%t|Copia vector diferencia%x1|Copia distancia%x2|Copia diferencia de rotacio%x3|Copia mitjana LocRotSiz%x4|Veure buffer en consola%x5
-Transformar LocRotSize%t|Cap al obj. actiu%x1|Aleatoriamente%x2
-Posar a distancia fixa%x1|Sumar (desp. absolut)%x2|Multiplicar (desp. relatiu)%x3
diff --git a/release/scripts/bpydata/config/readme.txt b/release/scripts/bpydata/config/readme.txt
deleted file mode 100644
index 4b5cb61b063..00000000000
--- a/release/scripts/bpydata/config/readme.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This folder is for automatically saved scripts configuration data.
-
-To use this feature scripts just need to set a proper Blender.Registry key.
-
-To know more, check the API Reference doc (specifically the API_related and
-Registry parts) and the documentation for the "Scripts Config Editor" script.
diff --git a/release/scripts/bpydata/readme.txt b/release/scripts/bpydata/readme.txt
deleted file mode 100644
index 3e640e27c4b..00000000000
--- a/release/scripts/bpydata/readme.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This directory is the default place for scripts to put their data,
-like internal files needed by the script and its saved configuration.
-
-Scripts can find the path to this dir using Blender.Get("datadir").
-Ex:
-
-import Blender
-print Blender.Get("datadir")
-
diff --git a/release/scripts/bpymodules/BPyAddMesh.py b/release/scripts/bpymodules/BPyAddMesh.py
deleted file mode 100644
index 901e68866cc..00000000000
--- a/release/scripts/bpymodules/BPyAddMesh.py
+++ /dev/null
@@ -1,159 +0,0 @@
-import Blender
-from Blender.Window import EditMode, GetCursorPos, GetViewQuat
-import bpy
-import BPyMessages
-
-def add_mesh_simple(name, verts, edges, faces):
- '''
- Adds a mesh from verts, edges and faces
-
- name - new object/mesh name
- verts - list of 3d vectors
- edges - list of int pairs
- faces - list of int triplets/quads
- '''
-
- scn = bpy.data.scenes.active
- if scn.lib: return
- ob_act = scn.objects.active
-
- is_editmode = EditMode()
-
- cursor = GetCursorPos()
- quat = None
- if is_editmode or Blender.Get('add_view_align'): # Aligning seems odd for editmode, but blender does it, oh well
- try: quat = Blender.Mathutils.Quaternion(GetViewQuat())
- except: pass
-
- # Exist editmode for non mesh types
- if ob_act and ob_act.type != 'Mesh' and is_editmode:
- EditMode(0)
-
- # We are in mesh editmode
- if EditMode():
- me = ob_act.getData(mesh=1)
-
- if me.multires:
- BPyMessages.Error_NoMeshMultiresEdit()
- return
-
- # Add to existing mesh
- # must exit editmode to modify mesh
- EditMode(0)
-
- me.sel = False
-
- vert_offset = len(me.verts)
- edge_offset = len(me.edges)
- face_offset = len(me.faces)
-
- # transform the verts
- txmat = Blender.Mathutils.TranslationMatrix(Blender.Mathutils.Vector(cursor))
- if quat:
- mat = quat.toMatrix()
- mat.invert()
- mat.resize4x4()
- txmat = mat * txmat
-
- txmat = txmat * ob_act.matrixWorld.copy().invert()
-
-
- me.verts.extend(verts)
- # Transform the verts by the cursor and view rotation
- me.transform(txmat, selected_only=True)
-
- if vert_offset:
- me.edges.extend([[i+vert_offset for i in e] for e in edges])
- me.faces.extend([[i+vert_offset for i in f] for f in faces])
- else:
- # Mesh with no data, unlikely
- me.edges.extend(edges)
- me.faces.extend(faces)
- else:
-
- # Object mode add new
-
- me = bpy.data.meshes.new(name)
- me.verts.extend(verts)
- me.edges.extend(edges)
- me.faces.extend(faces)
- me.sel = True
-
- # Object creation and location
- scn.objects.selected = []
- ob_act = scn.objects.new(me, name)
- scn.objects.active = ob_act
-
- if quat:
- mat = quat.toMatrix()
- mat.invert()
- mat.resize4x4()
- ob_act.setMatrix(mat)
-
- ob_act.loc = cursor
-
- me.calcNormals()
-
- if is_editmode or Blender.Get('add_editmode'):
- EditMode(1)
-
-
-
-
-
-def write_mesh_script(filepath, me):
- '''
- filepath - path to py file
- me - mesh to write
- '''
-
- name = me.name
- file = open(filepath, 'w')
-
- file.write('#!BPY\n')
- file.write('"""\n')
- file.write('Name: \'%s\'\n' % name)
- file.write('Blender: 245\n')
- file.write('Group: \'AddMesh\'\n')
- file.write('"""\n\n')
- file.write('import BPyAddMesh\n')
- file.write('from Blender.Mathutils import Vector\n\n')
-
- file.write('verts = [\\\n')
- for v in me.verts:
- file.write('Vector(%f,%f,%f),\\\n' % tuple(v.co))
- file.write(']\n')
-
- file.write('edges = []\n') # TODO, write loose edges
-
- file.write('faces = [\\\n')
- for f in me.faces:
- file.write('%s,\\\n' % str(tuple([v.index for v in f])))
- file.write(']\n')
-
- file.write('BPyAddMesh.add_mesh_simple("%s", verts, edges, faces)\n' % name)
-
-# The script below can make a file from a mesh with teh above function...
-'''
-#!BPY
-"""
-Name: 'Mesh as AddMesh Script'
-Blender: 242
-Group: 'Mesh'
-Tip: ''
-"""
-import BPyAddMesh
-reload(BPyAddMesh)
-
-import bpy
-
-def main():
- # Add error checking
- scn = bpy.data.scenes.active
- ob = scn.objects.active
- me = ob.getData(mesh=1)
-
- BPyAddMesh.write_mesh_script('/test.py', me)
-
-main()
-'''
diff --git a/release/scripts/bpymodules/BPyArmature.py b/release/scripts/bpymodules/BPyArmature.py
deleted file mode 100644
index 63df02d080c..00000000000
--- a/release/scripts/bpymodules/BPyArmature.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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
-# Version History:
-# 1.0 original release bakes an armature into a matrix
-# 1.1 optional params (ACTION_BAKE, ACTION_BAKE_FIRST_FRAME, direct function to key and return the Action
-
-import Blender
-from Blender import sys
-import bpy
-def getBakedPoseData(ob_arm, start_frame, end_frame, ACTION_BAKE = False, ACTION_BAKE_FIRST_FRAME = True):
- '''
- If you are currently getting IPO's this function can be used to
- ACTION_BAKE==False: return a list of frame aligned bone dictionary's
- ACTION_BAKE==True: return an action with keys aligned to bone constrained movement
- if ACTION_BAKE_FIRST_FRAME is not supplied or is true: keys begin at frame 1
-
- The data in these can be swaped in for the IPO loc and quat
-
- If you want to bake an action, this is not as hard and the ipo hack can be removed.
- '''
-
- # --------------------------------- Dummy Action! Only for this functon
- backup_action = ob_arm.action
- backup_frame = Blender.Get('curframe')
-
- DUMMY_ACTION_NAME = '~DONT_USE~'
- # Get the dummy action if it has no users
- try:
- new_action = bpy.data.actions[DUMMY_ACTION_NAME]
- if new_action.users:
- new_action = None
- except:
- new_action = None
-
- if not new_action:
- new_action = bpy.data.actions.new(DUMMY_ACTION_NAME)
- new_action.fakeUser = False
- # ---------------------------------- Done
-
- Matrix = Blender.Mathutils.Matrix
- Quaternion = Blender.Mathutils.Quaternion
- Vector = Blender.Mathutils.Vector
- POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT]
-
- # Each dict a frame
- bake_data = [{} for i in xrange(1+end_frame-start_frame)]
-
- pose= ob_arm.getPose()
- armature_data= ob_arm.getData();
- pose_bones= pose.bones
-
- # --------------------------------- Build a list of arma data for reuse
- armature_bone_data = []
- bones_index = {}
- for bone_name, rest_bone in armature_data.bones.items():
- pose_bone = pose_bones[bone_name]
- rest_matrix = rest_bone.matrix['ARMATURESPACE']
- rest_matrix_inv = rest_matrix.copy().invert()
- armature_bone_data.append( [len(bones_index), -1, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, None ])
- bones_index[bone_name] = len(bones_index)
-
- # Set the parent ID's
- for bone_name, pose_bone in pose_bones.items():
- parent = pose_bone.parent
- if parent:
- bone_index= bones_index[bone_name]
- parent_index= bones_index[parent.name]
- armature_bone_data[ bone_index ][1]= parent_index
- # ---------------------------------- Done
-
-
-
- # --------------------------------- Main loop to collect IPO data
- frame_index = 0
- NvideoFrames= end_frame-start_frame
- for current_frame in xrange(start_frame, end_frame+1):
- if frame_index==0: start=sys.time()
- elif frame_index==15: print NvideoFrames*(sys.time()-start),"seconds estimated..." #slows as it grows *3
- elif frame_index >15:
- percom= frame_index*100/NvideoFrames
- print "Frame %i Overall %i percent complete\r" % (current_frame, percom),
- ob_arm.action = backup_action
- #pose.update() # not needed
- Blender.Set('curframe', current_frame)
- #Blender.Window.RedrawAll()
- #frame_data = bake_data[frame_index]
- ob_arm.action = new_action
- ###for i,pose_bone in enumerate(pose_bones):
-
- for index, parent_index, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, ipo in armature_bone_data:
- matrix= pose_bone.poseMatrix
- parent_bone= rest_bone.parent
- if parent_index != -1:
- parent_pose_matrix = armature_bone_data[parent_index][6].poseMatrix
- parent_bone_matrix_inv = armature_bone_data[parent_index][5]
- matrix= matrix * parent_pose_matrix.copy().invert()
- rest_matrix= rest_matrix * parent_bone_matrix_inv
-
- matrix=matrix * rest_matrix.copy().invert()
- pose_bone.quat= matrix.toQuat()
- pose_bone.loc= matrix.translationPart()
- if ACTION_BAKE==False:
- pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1
-
- # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE
- # - use a temp action and bake into that, always at the same frame
- # so as not to make big IPO's, then collect the result from the IPOs
-
- # Now get the data from the IPOs
- if not ipo: ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name)
-
- loc = Vector()
- quat = Quaternion()
-
- for curve in ipo:
- val = curve.evaluate(1)
- curve_name= curve.name
- if curve_name == 'LocX': loc[0] = val
- elif curve_name == 'LocY': loc[1] = val
- elif curve_name == 'LocZ': loc[2] = val
- elif curve_name == 'QuatW': quat[3] = val
- elif curve_name == 'QuatX': quat[0] = val
- elif curve_name == 'QuatY': quat[1] = val
- elif curve_name == 'QuatZ': quat[2] = val
-
- bake_data[frame_index][bone_name] = loc, quat
- else:
- if ACTION_BAKE_FIRST_FRAME: pose_bone.insertKey(ob_arm, frame_index+1, POSE_XFORM)
- else: pose_bone.insertKey(ob_arm, current_frame , POSE_XFORM)
- frame_index+=1
- print "\nBaking Complete."
- ob_arm.action = backup_action
- if ACTION_BAKE==False:
- Blender.Set('curframe', backup_frame)
- return bake_data
- elif ACTION_BAKE==True:
- return new_action
- else: print "ERROR: Invalid ACTION_BAKE %i sent to BPyArmature" % ACTION_BAKE
-
-
-
diff --git a/release/scripts/bpymodules/BPyBlender.py b/release/scripts/bpymodules/BPyBlender.py
deleted file mode 100644
index 681dff63cf8..00000000000
--- a/release/scripts/bpymodules/BPyBlender.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# $Id$
-#
-# --------------------------------------------------------------------------
-# BPyBlender.py version 0.3 Mar 20, 2005
-# --------------------------------------------------------------------------
-# helper functions to be used by other scripts
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-# Basic set of modules Blender should have in all supported platforms.
-# The second and third lines are the contents of the Python23.zip file
-# included with Windows Blender binaries along with zlib.pyd.
-# Other platforms are assumed to have Python installed.
-basic_modules = [
-'Blender',
-'chunk','colorsys','copy','copy_reg','gzip','os','random','repr','stat',
-'string','StringIO','types','UserDict','webbrowser', 'zlib', 'math',
-'BPyBlender', 'BPyRegistry'
-]
diff --git a/release/scripts/bpymodules/BPyCurve.py b/release/scripts/bpymodules/BPyCurve.py
deleted file mode 100644
index 3dd5f1784f2..00000000000
--- a/release/scripts/bpymodules/BPyCurve.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# --------------------------------------------------------------------------
-# BPyImage.py version 0.15
-# --------------------------------------------------------------------------
-# helper functions to be used by other scripts
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import *
-
-def curve2vecs(ob, WORLDSPACE= True):
- '''
- Takes a curve object and retuirns a list of vec lists (polylines)
- one list per curve
-
- This is usefull as a way to get a polyline per curve
- so as not to have to deal with the spline types directly
- '''
- if ob.type != 'Curve':
- raise 'must be a curve object'
-
- me_dummy = Mesh.New()
- me_dummy.getFromObject(ob)
-
- if WORLDSPACE:
- me_dummy.transform(ob.matrixWorld)
-
- # build an edge dict
- edges = {} # should be a set
-
- def sort_pair(i1, i2):
- if i1 > i2: return i2, i1
- else: return i1, i2
-
- for ed in me_dummy.edges:
- edges[sort_pair(ed.v1.index,ed.v2.index)] = None # dummy value
-
- # now set the curves
- first_time = True
-
- current_vecs = []
- vec_list = [current_vecs]
-
- for v in me_dummy.verts:
- if first_time:
- first_time = False
- current_vecs.append(v.co.copy())
- last_index = v.index
- else:
- index = v.index
- if edges.has_key(sort_pair(index, last_index)):
- current_vecs.append( v.co.copy() )
- else:
- current_vecs = []
- vec_list.append(current_vecs)
-
- last_index = index
-
- me_dummy.verts = None
-
- return vec_list
-
-
diff --git a/release/scripts/bpymodules/BPyImage.py b/release/scripts/bpymodules/BPyImage.py
deleted file mode 100644
index 504e4ee29ba..00000000000
--- a/release/scripts/bpymodules/BPyImage.py
+++ /dev/null
@@ -1,318 +0,0 @@
-# --------------------------------------------------------------------------
-# BPyImage.py version 0.15
-# --------------------------------------------------------------------------
-# helper functions to be used by other scripts
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-#===========================================================================#
-# Comprehensive image loader, will search and find the image #
-# Will return a blender image or a new image if the image is missing #
-#===========================================================================#
-import bpy
-from Blender import sys
-try:
- import os
-except:
- os=None
-
-#==============================================#
-# Return directory, where the file is #
-#==============================================#
-def stripFile(path):
- lastSlash = max(path.rfind('\\'), path.rfind('/'))
- if lastSlash != -1:
- path = path[:lastSlash]
- newpath= '%s%s' % (path, sys.sep)
- else:
- newpath= path
- return newpath
-
-#==============================================#
-# Strips the slashes from the back of a string #
-#==============================================#
-def stripPath(path):
- return path.split('/')[-1].split('\\')[-1]
-
-#====================================================#
-# Strips the prefix off the name before writing #
-#====================================================#
-def stripExt(name): # name is a string
- index = name.rfind('.')
- if index != -1:
- return name[ : index ]
- else:
- return name
-
-def getExt(name):
- index = name.rfind('.')
- if index != -1:
- return name[index+1:]
- return name
-
-#====================================================#
-# Adds a slash to the end of a path if its not there #
-#====================================================#
-def addSlash(path):
- if not path:
- return ''
-
- elif path.endswith('\\') or path.endswith('/'):
- return path
- return path + sys.sep
-
-
-def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False, CONVERT_CALLBACK=None):
- '''
- imagePath: The image filename
- If a path precedes it, this will be searched as well.
-
- filePath: is the directory where the image may be located - any file at teh end will be ignored.
-
- PLACE_HOLDER: if True a new place holder image will be created.
- this is usefull so later you can relink the image to its original data.
-
- VERBOSE: If True debug info will be printed.
-
- RECURSIVE: If True, directories will be recursivly searched.
- Be carefull with this if you have files in your root directory because it may take a long time.
-
- CASE_INSENSITIVE: for non win32 systems, find the correct case for the file.
-
- CONVERT_CALLBACK: a function that takes an existing path and returns a new one.
- Use this when loading image formats blender may not support, the CONVERT_CALLBACK
- can take the path for a GIF (for example), convert it to a PNG and return the PNG's path.
- For formats blender can read, simply return the path that is given.
- '''
-
- # VERBOSE = True
-
- if VERBOSE: print 'img:', imagePath, 'file:', filePath
-
- if os == None and CASE_INSENSITIVE:
- CASE_INSENSITIVE = True
-
- # When we have the file load it with this. try/except niceness.
- def imageLoad(path):
- #if path.endswith('\\') or path.endswith('/'):
- # raise 'INVALID PATH'
-
- if CONVERT_CALLBACK:
- path = CONVERT_CALLBACK(path)
-
- try:
- img = bpy.data.images.new(filename=path)
- if VERBOSE: print '\t\tImage loaded "%s"' % path
- return img
- except:
- if VERBOSE:
- if sys.exists(path): print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path)
- else: print '\t\tImage not found, making a place holder "%s"' % (path)
- if PLACE_HOLDER:
- img= bpy.data.images.new(stripPath(path),4,4)
- img.filename= path
- return img #blank image
- else:
- return None
-
- # Image formats blender can read
- IMAGE_EXT = ['jpg', 'jpeg', 'png', 'tga', 'bmp', 'rgb', 'sgi', 'bw', 'iff', 'lbm', # Blender Internal
- 'gif', 'psd', 'tif', 'tiff', 'pct', 'pict', 'pntg', 'qtif'] # Quacktime, worth a try.
-
- imageFileName = stripPath(imagePath) # image path only
- imageFileName_lower = imageFileName.lower() # image path only
-
- if VERBOSE: print '\tSearchingExisting Images for "%s"' % imagePath
- for i in bpy.data.images:
- if stripPath(i.filename.lower()) == imageFileName_lower:
- if VERBOSE: print '\t\tUsing existing image.'
- return i
-
-
- if VERBOSE: print '\tAttempting to load "%s"' % imagePath
- if sys.exists(imagePath):
- if VERBOSE: print '\t\tFile found where expected "%s".' % imagePath
- return imageLoad(imagePath)
-
-
-
- imageFileName_noext = stripExt(imageFileName) # With no extension.
- imageFileName_noext_lower = stripExt(imageFileName_lower) # With no extension.
- imageFilePath = stripFile(imagePath)
-
- # Remove relative path from image path
- if imageFilePath.startswith('./') or imageFilePath.startswith('.\\'):
- imageFilePath = imageFilePath[2:]
-
-
- # Attempt to load from obj path.
- tmpPath = stripFile(filePath) + stripPath(imageFileName)
- if sys.exists(tmpPath):
- if VERBOSE: print '\t\tFile found in path (1)"%s".' % tmpPath
- return imageLoad(tmpPath)
-
-
- # os needed if we go any further.
- if not os:
- if VERBOSE: print '\t\tCreating a placeholder with a face path: "%s".' % imagePath
- return imageLoad(imagePath) # Will jus treturn a placeholder.
-
-
- # We have os.
- # GATHER PATHS.
- paths = {} # Store possible paths we may use, dict for no doubles.
- tmpPath = addSlash(sys.expandpath('//')) # Blenders path
- if sys.exists(tmpPath):
- if VERBOSE: print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
- else:
- if VERBOSE: print '\tNo Path: "%s"' % tmpPath
-
- tmpPath = imageFilePath
- if sys.exists(tmpPath):
- if VERBOSE: print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
- else:
- if VERBOSE: print '\tNo Path: "%s"' % tmpPath
-
- tmpPath = stripFile(filePath)
- if sys.exists(tmpPath):
- if VERBOSE: print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
- else:
- if VERBOSE: print '\tNo Path: "%s"' % tmpPath
-
- tmpPath = addSlash(bpy.config.textureDir)
- if tmpPath and sys.exists(tmpPath):
- if VERBOSE: print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
- else:
- if VERBOSE: print '\tNo Path: "%s"' % tmpPath
-
- # Add path if relative image patrh was given.
- tmp_paths= paths.keys()
- for k in tmp_paths:
- tmpPath = k + imageFilePath
- if sys.exists(tmpPath):
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
- else:
- if VERBOSE: print '\tNo Path: "%s"' % tmpPath
- # DONE
- #
- for path, files in paths.iteritems():
- if sys.exists(path + imageFileName):
- if VERBOSE: print '\tFound image at path: "%s" file" "%s"' % (path, imageFileName)
- return imageLoad(path + imageFileName)
-
- # If the files not there then well do a case insensitive seek.
- filesOrigCase = files[0]
- filesLower = files[1]
- filesLowerNoExt = files[2]
-
- # We are going to try in index the file directly, if its not there just keep on
-
- index = None
- try:
- # Is it just a case mismatch?
- index = filesLower.index(imageFileName_lower)
- except:
- try:
- # Have the extensions changed?
- index = filesLowerNoExt.index(imageFileName_noext_lower)
-
- ext = getExt( filesLower[index] ) # Get the extension of the file that matches all but ext.
-
- # Check that the ext is useable eg- not a 3ds file :)
- if ext.lower() not in IMAGE_EXT:
- index = None
-
- except:
- index = None
-
- if index != None:
- tmpPath = path + filesOrigCase[index]
- img = imageLoad( tmpPath )
- if img != None:
- if VERBOSE: print '\t\tImage Found "%s"' % tmpPath
- return img
-
- if RECURSIVE:
- # IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH.
- if VERBOSE: print '\t\tImage Not Found in any of the dirs, doing a recusrive search'
- for path in paths.iterkeys():
- # Were not going to use files
- if path == '/' or len(path) == 3 and path[1:] == ':\\':
- continue
-
- # print path , 'ASS'
-
- #------------------
- # finds the file starting at the root.
- # def findImage(findRoot, imagePath):
- #W---------------
-
- # ROOT, DIRS, FILES
- pathWalk = os.walk(path)
- pathList = [True]
-
- matchList = [] # Store a list of (match, size), choose the biggest.
- while True:
- try:
- pathList = pathWalk.next()
- except:
- break
-
- for file in pathList[2]:
- file_lower = file.lower()
- # FOUND A MATCH
- if (file_lower == imageFileName_lower) or\
- (stripExt(file_lower) == imageFileName_noext_lower and getExt(file_lower) in IMAGE_EXT):
- name = pathList[0] + sys.sep + file
- size = os.path.getsize(name)
- if VERBOSE: print '\t\t\tfound:', name
- matchList.append( (name, size) )
-
- if matchList:
- # Sort by file size
- matchList.sort(lambda A, B: cmp(B[1], A[1]) )
-
- if VERBOSE: print '\t\tFound "%s"' % matchList[0][0]
-
- # Loop through all we have found
- img = None
- for match in matchList:
- img = imageLoad(match[0]) # 0 - first, 0 - pathname
- if img != None:
- break
- return img
-
- # No go.
- if VERBOSE: print '\t\tImage Not Found after looking everywhere! "%s"' % imagePath
- return imageLoad(imagePath) # Will jus treturn a placeholder.
diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py
deleted file mode 100644
index 4882e9aaf21..00000000000
--- a/release/scripts/bpymodules/BPyMathutils.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# $Id$
-#
-# --------------------------------------------------------------------------
-# helper functions to be used by other scripts
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender.Mathutils import *
-
-# ------ Mersenne Twister - start
-
-# Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura.
-# Any feedback is very welcome. For any question, comments,
-# see http://www.math.keio.ac.jp/matumoto/emt.html or email
-# matumoto@math.keio.ac.jp
-
-# The link above is dead, this is the new one:
-# http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/emt.html
-# And here the license info, from Mr. Matsumoto's site:
-# Until 2001/4/6, MT had been distributed under GNU Public License,
-# but after 2001/4/6, we decided to let MT be used for any purpose, including
-# commercial use. 2002-versions mt19937ar.c, mt19937ar-cok.c are considered
-# to be usable freely.
-#
-# So from the year above (1997), this code is under GPL.
-
-# Period parameters
-N = 624
-M = 397
-MATRIX_A = 0x9908b0dfL # constant vector a
-UPPER_MASK = 0x80000000L # most significant w-r bits
-LOWER_MASK = 0x7fffffffL # least significant r bits
-
-# Tempering parameters
-TEMPERING_MASK_B = 0x9d2c5680L
-TEMPERING_MASK_C = 0xefc60000L
-
-def TEMPERING_SHIFT_U(y):
- return (y >> 11)
-
-def TEMPERING_SHIFT_S(y):
- return (y << 7)
-
-def TEMPERING_SHIFT_T(y):
- return (y << 15)
-
-def TEMPERING_SHIFT_L(y):
- return (y >> 18)
-
-mt = [] # the array for the state vector
-mti = N+1 # mti==N+1 means mt[N] is not initialized
-
-# initializing the array with a NONZERO seed
-def sgenrand(seed):
- # setting initial seeds to mt[N] using
- # the generator Line 25 of Table 1 in
- # [KNUTH 1981, The Art of Computer Programming
- # Vol. 2 (2nd Ed.), pp102]
-
- global mt, mti
-
- mt = []
-
- mt.append(seed & 0xffffffffL)
- for i in xrange(1, N + 1):
- mt.append((69069 * mt[i-1]) & 0xffffffffL)
-
- mti = i
-# end sgenrand
-
-
-def genrand():
- global mt, mti
-
- mag01 = [0x0L, MATRIX_A]
- # mag01[x] = x * MATRIX_A for x=0,1
- y = 0
-
- if mti >= N: # generate N words at one time
- if mti == N+1: # if sgenrand() has not been called,
- sgenrand(4357) # a default initial seed is used
-
- for kk in xrange((N-M) + 1):
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]
-
- for kk in xrange(kk, N):
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)
- mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]
-
- y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK)
- mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]
-
- mti = 0
-
- y = mt[mti]
- mti += 1
- y ^= TEMPERING_SHIFT_U(y)
- y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B
- y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C
- y ^= TEMPERING_SHIFT_L(y)
-
- return ( float(y) / 0xffffffffL ) # reals
-
-#------ Mersenne Twister -- end
-
-
-
-
-""" 2d convexhull
-Based from Dinu C. Gherman's work,
-modified for Blender/Mathutils by Campell Barton
-"""
-######################################################################
-# Public interface
-######################################################################
-def convexHull(point_list_2d):
- """Calculate the convex hull of a set of vectors
- The vectors can be 3 or 4d but only the Xand Y are used.
- returns a list of convex hull indicies to the given point list
- """
-
- ######################################################################
- # Helpers
- ######################################################################
-
- def _myDet(p, q, r):
- """Calc. determinant of a special matrix with three 2D points.
-
- The sign, "-" or "+", determines the side, right or left,
- respectivly, on which the point r lies, when measured against
- a directed vector from p to q.
- """
- return (q.x*r.y + p.x*q.y + r.x*p.y) - (q.x*p.y + r.x*q.y + p.x*r.y)
-
- def _isRightTurn((p, q, r)):
- "Do the vectors pq:qr form a right turn, or not?"
- #assert p[0] != q[0] and q[0] != r[0] and p[0] != r[0]
- if _myDet(p[0], q[0], r[0]) < 0:
- return 1
- else:
- return 0
-
- # Get a local list copy of the points and sort them lexically.
- points = [(p, i) for i, p in enumerate(point_list_2d)]
-
- try: points.sort(key = lambda a: (a[0].x, a[0].y))
- except: points.sort(lambda a,b: cmp((a[0].x, a[0].y), (b[0].x, b[0].y)))
-
- # Build upper half of the hull.
- upper = [points[0], points[1]] # cant remove these.
- for i in xrange(len(points)-2):
- upper.append(points[i+2])
- while len(upper) > 2 and not _isRightTurn(upper[-3:]):
- del upper[-2]
-
- # Build lower half of the hull.
- points.reverse()
- lower = [points.pop(0), points.pop(1)]
- for p in points:
- lower.append(p)
- while len(lower) > 2 and not _isRightTurn(lower[-3:]):
- del lower[-2]
-
- # Concatenate both halfs and return.
- return [p[1] for ls in (upper, lower) for p in ls]
-
-
-def plane2mat(plane, normalize= False):
- '''
- Takes a plane and converts to a matrix
- points between 0 and 1 are up
- 1 and 2 are right
- assumes the plane has 90d corners
- '''
- cent= (plane[0]+plane[1]+plane[2]+plane[3] ) /4.0
-
-
- up= cent - ((plane[0]+plane[1])/2.0)
- right= cent - ((plane[1]+plane[2])/2.0)
- z= up.cross(right)
-
- if normalize:
- up.normalize()
- right.normalize()
- z.normalize()
-
- mat= Matrix(up, right, z)
-
- # translate
- mat.resize4x4()
- tmat= Blender.Mathutils.TranslationMatrix(cent)
- return mat * tmat
-
-
-# Used for mesh_solidify.py and mesh_wire.py
-
-# returns a length from an angle
-# Imaging a 2d space.
-# there is a hoz line at Y1 going to inf on both X ends, never moves (LINEA)
-# down at Y0 is a unit length line point up at (angle) from X0,Y0 (LINEB)
-# This function returns the length of LINEB at the point it would intersect LINEA
-# - Use this for working out how long to make the vector - differencing it from surrounding faces,
-# import math
-from math import pi, sin, cos, sqrt
-
-def angleToLength(angle):
- # Alredy accounted for
- if angle < 0.000001: return 1.0
- else: return abs(1.0 / cos(pi*angle/180));
diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py
deleted file mode 100644
index 292f7a4b91e..00000000000
--- a/release/scripts/bpymodules/BPyMesh.py
+++ /dev/null
@@ -1,1326 +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-
-import Blender
-import bpy
-import BPyMesh_redux # seperated because of its size.
-# reload(BPyMesh_redux)
-redux= BPyMesh_redux.redux
-
-# python 2.3 has no reversed() iterator. this will only work on lists and tuples
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-
-# If python version is less than 2.4, try to get set stuff from module
-try:
- set
-except:
- try:
- from sets import Set as set
- except:
- set= None
-
-
-
-
-
-def meshWeight2List(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= me.getVertGroupNames()
- len_groupNames= len(groupNames)
-
- if not len_groupNames:
- # no verts? return a vert aligned empty list
- return [[] for i in xrange(len(me.verts))], []
-
- else:
- vWeightList= [[0.0]*len_groupNames for i in xrange(len(me.verts))]
-
- for group_index, group in enumerate(groupNames):
- for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples.
- vWeightList[vert_index][group_index]= weight
-
- # removed this because me may be copying teh vertex groups.
- #for group in groupNames:
- # me.removeVertGroup(group)
-
- return groupNames, vWeightList
-
-
-def list2MeshWeight(me, groupNames, vWeightList):
- ''' Takes a list of groups and a list of vertex Weight lists as created by meshWeight2List
- and applys it to the mesh.'''
-
- if len(vWeightList) != len(me.verts):
- raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights'
-
- act_group = me.activeGroup
-
- # Clear the vert group.
- currentGroupNames= me.getVertGroupNames()
- for group in currentGroupNames:
- me.removeVertGroup(group) # messes up the active group.
-
- # Add clean unused vert groupNames back
- currentGroupNames= me.getVertGroupNames()
- for group in groupNames:
- me.addVertGroup(group)
-
- add_ = Blender.Mesh.AssignModes.ADD
-
- vertList= [None]
- for i, v in enumerate(me.verts):
- vertList[0]= i
- for group_index, weight in enumerate(vWeightList[i]):
- if weight:
- try:
- me.assignVertsToGroup(groupNames[group_index], vertList, min(1, max(0, weight)), add_)
- except:
- pass # vert group is not used anymore.
-
- try: me.activeGroup = act_group
- except: pass
-
- me.update()
-
-
-
-
-def meshWeight2Dict(me):
- ''' Takes a mesh and return its group names and a list of dicts, one dict per vertex.
- using the group as a key and a float value for the weight.
- These 2 lists can be modified and then used with dict2MeshWeight to apply the changes.
- '''
-
- vWeightDict= [dict() for i in xrange(len(me.verts))] # Sync with vertlist.
-
- # Clear the vert group.
- groupNames= me.getVertGroupNames()
-
- for group in groupNames:
- for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples.
- vWeightDict[vert_index][group]= weight
-
- # removed this because me may be copying teh vertex groups.
- #for group in groupNames:
- # me.removeVertGroup(group)
-
- return groupNames, vWeightDict
-
-
-def dict2MeshWeight(me, groupNames, vWeightDict):
- ''' Takes a list of groups and a list of vertex Weight dicts as created by meshWeight2Dict
- and applys it to the mesh.'''
-
- if len(vWeightDict) != len(me.verts):
- raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights'
-
- act_group = me.activeGroup
-
- # Clear the vert group.
- currentGroupNames= me.getVertGroupNames()
- for group in currentGroupNames:
- if group not in groupNames:
- me.removeVertGroup(group) # messes up the active group.
- else:
- me.removeVertsFromGroup(group)
-
- # Add clean unused vert groupNames back
- currentGroupNames= me.getVertGroupNames()
- for group in groupNames:
- if group not in currentGroupNames:
- me.addVertGroup(group)
-
- add_ = Blender.Mesh.AssignModes.ADD
-
- vertList= [None]
- for i, v in enumerate(me.verts):
- vertList[0]= i
- for group, weight in vWeightDict[i].iteritems():
- try:
- me.assignVertsToGroup(group, vertList, min(1, max(0, weight)), add_)
- except:
- pass # vert group is not used anymore.
-
- try: me.activeGroup = act_group
- except: pass
-
- me.update()
-
-def dictWeightMerge(dict_weights):
- '''
- Takes dict weight list and merges into 1 weight dict item and returns it
- '''
-
- if not dict_weights:
- return {}
-
- keys= []
- for weight in dict_weights:
- keys.extend([ (k, 0.0) for k in weight.iterkeys() ])
-
- new_wdict = dict(keys)
-
- len_dict_weights= len(dict_weights)
-
- for weight in dict_weights:
- for group, value in weight.iteritems():
- new_wdict[group] += value/len_dict_weights
-
- return new_wdict
-
-
-FLIPNAMES=[\
-('Left','Right'),\
-('_L','_R'),\
-('-L','-R'),\
-('.L','.R'),\
-]
-
-def dictWeightFlipGroups(dict_weight, groupNames, createNewGroups):
- '''
- Returns a weight with flip names
- dict_weight - 1 vert weight.
- groupNames - because we may need to add new group names.
- dict_weight - Weather to make new groups where needed.
- '''
-
- def flipName(name):
- for n1,n2 in FLIPNAMES:
- for nA, nB in ( (n1,n2), (n1.lower(),n2.lower()), (n1.upper(),n2.upper()) ):
- if createNewGroups:
- newName= name.replace(nA,nB)
- if newName!=name:
- if newName not in groupNames:
- groupNames.append(newName)
- return newName
-
- newName= name.replace(nB,nA)
- if newName!=name:
- if newName not in groupNames:
- groupNames.append(newName)
- return newName
-
- else:
- newName= name.replace(nA,nB)
- if newName!=name and newName in groupNames:
- return newName
-
- newName= name.replace(nB,nA)
- if newName!=name and newName in groupNames:
- return newName
-
- return name
-
- if not dict_weight:
- return dict_weight, groupNames
-
-
- new_wdict = {}
- for group, weight in dict_weight.iteritems():
- flipname= flipName(group)
- new_wdict[flipname]= weight
-
- return new_wdict, groupNames
-
-
-def mesh2linkedFaces(me):
- '''
- Splits the mesh into connected parts,
- these parts are returned as lists of faces.
- used for seperating cubes from other mesh elements in the 1 mesh
- '''
-
- # Build vert face connectivity
- vert_faces= [[] for i in xrange(len(me.verts))]
- for f in me.faces:
- for v in f:
- vert_faces[v.index].append(f)
-
- # sort faces into connectivity groups
- face_groups= [[f] for f in me.faces]
- face_mapping = range(len(me.faces)) # map old, new face location
-
- # Now clump faces iterativly
- ok= True
- while ok:
- ok= False
-
- for i, f in enumerate(me.faces):
- mapped_index= face_mapping[f.index]
- mapped_group= face_groups[mapped_index]
-
- for v in f:
- for nxt_f in vert_faces[v.index]:
- if nxt_f != f:
- nxt_mapped_index= face_mapping[nxt_f.index]
-
- # We are not a part of the same group
- if mapped_index != nxt_mapped_index:
-
- ok= True
-
- # Assign mapping to this group so they all map to this group
- for grp_f in face_groups[nxt_mapped_index]:
- face_mapping[grp_f.index] = mapped_index
-
- # Move faces into this group
- mapped_group.extend(face_groups[nxt_mapped_index])
-
- # remove reference to the list
- face_groups[nxt_mapped_index]= None
-
-
- # return all face groups that are not null
- # this is all the faces that are connected in their own lists.
- return [fg for fg in face_groups if fg]
-
-
-def getFaceLoopEdges(faces, seams=[]):
- '''
- Takes me.faces or a list of faces and returns the edge loops
- These edge loops are the edges that sit between quads, so they dont touch
- 1 quad, not not connected will make 2 edge loops, both only containing 2 edges.
-
- return a list of edge key lists
- [ [(0,1), (4, 8), (3,8)], ...]
-
- optionaly, seams are edge keys that will be removed
- '''
-
- OTHER_INDEX = 2,3,0,1 # opposite face index
-
- edges = {}
-
- for f in faces:
- if len(f) == 4:
- edge_keys = f.edge_keys
- for i, edkey in enumerate(f.edge_keys):
- edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]])
-
- for edkey in seams:
- edges[edkey] = []
-
- # Collect edge loops here
- edge_loops = []
-
- for edkey, ed_adj in edges.iteritems():
- if 0 <len(ed_adj) < 3: # 1 or 2
- # Seek the first edge
- context_loop = [edkey, ed_adj[0]]
- edge_loops.append(context_loop)
- if len(ed_adj) == 2:
- other_dir = ed_adj[1]
- else:
- other_dir = None
-
- ed_adj[:] = []
-
- flipped = False
-
- while 1:
- # from knowing the last 2, look for th next.
- ed_adj = edges[context_loop[-1]]
- if len(ed_adj) != 2:
-
- if other_dir and flipped==False: # the original edge had 2 other edges
- flipped = True # only flip the list once
- context_loop.reverse()
- ed_adj[:] = []
- context_loop.append(other_dir) # save 1 lookiup
-
- ed_adj = edges[context_loop[-1]]
- if len(ed_adj) != 2:
- ed_adj[:] = []
- break
- else:
- ed_adj[:] = []
- break
-
- i = ed_adj.index(context_loop[-2])
- context_loop.append( ed_adj[ not i] )
-
- # Dont look at this again
- ed_adj[:] = []
-
-
- return edge_loops
-
-
-
-def getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None):
- '''
- ob - the object that you want to get the mesh from
- container_mesh - a Blender.Mesh type mesh that is reused to avoid a new datablock per call to getMeshFromObject
- apply_modifiers - if enabled, subsurf bones etc. will be applied to the returned mesh. disable to get a copy of the mesh.
- vgroup - For mesh objects only, apply the vgroup to the the copied mesh. (slower)
- scn - Scene type. avoids getting the current scene each time getMeshFromObject is called.
-
- Returns Mesh or None
- '''
-
- if not scn:
- scn= bpy.data.scenes.active
- if not container_mesh:
- mesh = bpy.data.meshes.new(ob.name)
- else:
- mesh= container_mesh
- mesh.verts= None
-
- ob_type = ob.type
- dataname = ob.getData(1)
- tempob= None
- if apply_modifiers or ob_type != 'Mesh':
- try:
- mesh.getFromObject(ob)
- except:
- return None
-
- else:
- '''
- Dont apply modifiers, copy the mesh.
- So we can transform the data. its easiest just to get a copy of the mesh.
- '''
- tempob= scn.objects.new(ob.getData(mesh=1))
- mesh.getFromObject(tempob)
- scn.objects.unlink(tempob)
-
- if ob_type == 'Mesh':
- if vgroups:
- if tempob==None:
- tempob= Blender.Object.New('Mesh')
-
- tempob.link(mesh)
- try:
- # Copy the influences if possible.
- groupNames, vWeightDict= meshWeight2Dict(ob.getData(mesh=1))
- dict2MeshWeight(mesh, groupNames, vWeightDict)
- except:
- # if the modifier changes the vert count then it messes it up for us.
- pass
-
- return mesh
-
-
-def faceRayIntersect(f, orig, rdir):
- '''
- Returns face, side
- Side is the side of a quad we intersect.
- side 0 == 0,1,2
- side 1 == 0,2,3
- '''
- f_v= f.v
- isect= Blender.Mathutils.Intersect(f_v[0].co, f_v[1].co, f_v[2].co, rdir, orig, 1) # 1==clip
-
- if isect:
- return isect, 0
-
- if len(f_v)==4:
- isect= Blender.Mathutils.Intersect(f_v[0].co, f_v[2].co, f_v[3].co, rdir, orig, 1) # 1==clip
- if isect:
- return isect, 1
- return False, 0
-
-
-def pickMeshRayFace(me, orig, rdir):
- best_dist= 1000000
- best_isect= best_side= best_face= None
- for f in me.faces:
- isect, side= faceRayIntersect(f, orig, rdir)
- if isect:
- dist= (isect-orig).length
- if dist<best_dist:
- best_dist= dist
- best_face= f
- best_side= side
- best_isect= isect
-
- return best_face, best_isect, best_side
-
-
-def pickMeshRayFaceWeight(me, orig, rdir):
- f, isect, side = pickMeshRayFace(me, orig, rdir)
-
- if f==None:
- return None, None, None, None, None
-
- f_v= [v.co for v in f]
- if side==1: # we can leave side 0 without changes.
- f_v = f_v[0], f_v[2], f_v[3]
-
- l0= (f_v[0]-isect).length
- l1= (f_v[1]-isect).length
- l2= (f_v[2]-isect).length
-
- w0 = (l1+l2)
- w1 = (l0+l2)
- w2 = (l1+l0)
-
- totw= w0 + w1 + w2
- w0=w0/totw
- w1=w1/totw
- w2=w2/totw
-
- return f, side, w0, w1, w2
-
-
-
-def pickMeshGroupWeight(me, act_group, orig, rdir):
- f, side, w0, w1, w2= pickMeshRayFaceWeight(me, orig, rdir)
-
- if f==None:
- return None
-
- f_v= f.v
- if side==0:
- f_vi= (f_v[0].index, f_v[1].index, f_v[2].index)
- else:
- f_vi= (f_v[0].index, f_v[2].index, f_v[3].index)
-
- vws= [0.0,0.0,0.0]
- for i in xrange(3):
- try: vws[i]= me.getVertsFromGroup(act_group, 1, [f_vi[i],])[0][1]
- except: pass
-
- return w0*vws[0] + w1*vws[1] + w2*vws[2]
-
-def pickMeshGroupVCol(me, orig, rdir):
- Vector= Blender.Mathutils.Vector
- f, side, w0, w1, w2= pickMeshRayFaceWeight(me, orig, rdir)
-
- if f==None:
- return None
-
- def col2vec(c):
- return Vector(c.r, c.g, c.b)
-
- if side==0:
- idxs= 0,1,2
- else:
- idxs= 0,2,3
- f_c= f.col
- f_colvecs= [col2vec(f_c[i]) for i in idxs]
- return f_colvecs[0]*w0 + f_colvecs[1]*w1 + f_colvecs[2]*w2
-
-def edge_face_users(me):
- '''
- Takes a mesh and returns a list aligned with the meshes edges.
- Each item is a list of the faces that use the edge
- would be the equiv for having ed.face_users as a property
- '''
-
- face_edges_dict= dict([(ed.key, (ed.index, [])) for ed in me.edges])
- for f in me.faces:
- fvi= [v.index for v in f]# face vert idx's
- for edkey in f.edge_keys:
- face_edges_dict[edkey][1].append(f)
-
- face_edges= [None] * len(me.edges)
- for ed_index, ed_faces in face_edges_dict.itervalues():
- face_edges[ed_index]= ed_faces
-
- return face_edges
-
-
-def face_edges(me):
- '''
- Returns a list alligned to the meshes faces.
- each item is a list of lists: that is
- face_edges -> face indicies
- face_edges[i] -> list referencs local faces v indicies 1,2,3 &| 4
- face_edges[i][j] -> list of faces that this edge uses.
- crap this is tricky to explain :/
- '''
- face_edges= [ [-1] * len(f) for f in me.faces ]
-
- face_edges_dict= dict([(ed.key, []) for ed in me.edges])
- for fidx, f in enumerate(me.faces):
- for i, edkey in enumerate(f.edge_keys):
- edge_face_users= face_edges_dict[edkey]
- edge_face_users.append(f)
- face_edges[fidx][i]= edge_face_users
-
- return face_edges
-
-
-def facesPlanerIslands(me):
-
- def roundvec(v):
- return round(v[0], 4), round(v[1], 4), round(v[2], 4)
-
- face_props= [(cent, no, roundvec(no), cent.dot(no)) for f in me.faces for no, cent in ((f.no, f.cent),)]
-
- face_edge_users= face_edges(me)
- islands= []
-
- used_faces= [0] * len(me.faces)
- while True:
- new_island= False
- for i, used_val in enumerate(used_faces):
- if used_val==0:
- island= [i]
- new_island= True
- used_faces[i]= 1
- break
-
- if not new_island:
- break
-
- island_growing= True
- while island_growing:
- island_growing= False
- for fidx1 in island[:]:
- if used_faces[fidx1]==1:
- used_faces[fidx1]= 2
- face_prop1= face_props[fidx1]
- for ed in face_edge_users[fidx1]:
- for f2 in ed:
- fidx2= f2.index
- if fidx1 != fidx2 and used_faces[fidx2]==0:
- island_growing= True
- face_prop2= face_props[fidx2]
- # normals are the same?
- if face_prop1[2]==face_prop2[2]:
- if abs(face_prop1[3] - face_prop1[1].dot(face_prop2[0])) < 0.000001:
- used_faces[fidx2]= 1
- island.append(fidx2)
- islands.append([me.faces[i] for i in island])
- return islands
-
-
-
-def facesUvIslands(me, PREF_IMAGE_DELIMIT=True):
- def roundvec(v):
- return round(v[0], 4), round(v[1], 4)
-
- if not me.faceUV:
- return [ list(me.faces), ]
-
- # make a list of uv dicts
- face_uvs= [ [roundvec(uv) for uv in f.uv] for f in me.faces]
-
- # key - face uv || value - list of face idxs
- uv_connect_dict= dict([ (uv, [] ) for f_uvs in face_uvs for uv in f_uvs])
-
- for i, f_uvs in enumerate(face_uvs):
- for uv in f_uvs: # loops through rounded uv values
- uv_connect_dict[uv].append(i)
- islands= []
-
- used_faces= [0] * len(me.faces)
- while True:
- new_island= False
- for i, used_val in enumerate(used_faces):
- if used_val==0:
- island= [i]
- new_island= True
- used_faces[i]= 1
- break
-
- if not new_island:
- break
-
- island_growing= True
- while island_growing:
- island_growing= False
- for fidx1 in island[:]:
- if used_faces[fidx1]==1:
- used_faces[fidx1]= 2
- for uv in face_uvs[fidx1]:
- for fidx2 in uv_connect_dict[uv]:
- if fidx1 != fidx2 and used_faces[fidx2]==0:
- if not PREF_IMAGE_DELIMIT or me.faces[fidx1].image==me.faces[fidx2].image:
- island_growing= True
- used_faces[fidx2]= 1
- island.append(fidx2)
-
- islands.append([me.faces[i] for i in island])
- return islands
-
-#def faceUvBounds(me, faces= None):
-
-
-def facesUvRotate(me, deg, faces= None, pivot= (0,0)):
- '''
- Faces can be None an all faces will be used
- pivot is just the x/y well rotated about
-
- positive deg value for clockwise rotation
- '''
- if faces==None: faces= me.faces
- pivot= Blender.Mathutils.Vector(pivot)
-
- rotmat= Blender.Mathutils.RotationMatrix(-deg, 2)
-
- for f in faces:
- f.uv= [((uv-pivot)*rotmat)+pivot for uv in f.uv]
-
-def facesUvScale(me, sca, faces= None, pivot= (0,0)):
- '''
- Faces can be None an all faces will be used
- pivot is just the x/y well rotated about
- sca can be wither an int/float or a vector if you want to
- scale x/y seperately.
- a sca or (1.0, 1.0) will do nothing.
- '''
- def vecmulti(v1,v2):
- '''V2 is unchanged'''
- v1[:]= (v1.x*v2.x, v1.y*v2.y)
- return v1
-
- sca= Blender.Mathutils.Vector(sca)
- if faces==None: faces= me.faces
- pivot= Blender.Mathutils.Vector(pivot)
-
- for f in faces:
- f.uv= [vecmulti(uv-pivot, sca)+pivot for uv in f.uv]
-
-
-def facesUvTranslate(me, tra, faces= None, pivot= (0,0)):
- '''
- Faces can be None an all faces will be used
- pivot is just the x/y well rotated about
- '''
- if faces==None: faces= me.faces
- tra= Blender.Mathutils.Vector(tra)
-
- for f in faces:
- f.uv= [uv+tra for uv in f.uv]
-
-
-
-def edgeFaceUserCount(me, faces= None):
- '''
- Return an edge aligned list with the count for all the faces that use that edge. -
- can spesify a subset of the faces, so only those will be counted.
- '''
- if faces==None:
- faces= me.faces
- max_vert= len(me.verts)
- else:
- # find the lighest vert index
- pass
-
- edge_users= [0] * len(me.edges)
-
- edges_idx_dict= dict([(ed.key, ed.index) for ed in me.edges])
-
- for f in faces:
- for edkey in f.edge_keys:
- edge_users[edges_idx_dict[edkey]] += 1
-
- return edge_users
-
-
-#============================================================================#
-# Takes a face, and a pixel x/y on the image and returns a worldspace x/y/z #
-# will return none if the pixel is not inside the faces UV #
-#============================================================================#
-def getUvPixelLoc(face, pxLoc, img_size = None, uvArea = None):
- TriangleArea= Blender.Mathutils.TriangleArea
- Vector= Blender.Mathutils.Vector
-
- if not img_size:
- w,h = face.image.size
- else:
- w,h= img_size
-
- scaled_uvs= [Vector(uv.x*w, uv.y*h) for uv in f.uv]
-
- if len(scaled_uvs)==3:
- indicies= ((0,1,2),)
- else:
- indicies= ((0,1,2), (0,2,3))
-
- for fidxs in indicies:
- for i1,i2,i3 in fidxs:
- # IS a point inside our triangle?
- # UVArea could be cached?
- uv_area = TriangleArea(scaled_uvs[i1], scaled_uvs[i2], scaled_uvs[i3])
- area0 = TriangleArea(pxLoc, scaled_uvs[i2], scaled_uvs[i3])
- area1 = TriangleArea(pxLoc, scaled_uvs[i1], scaled_uvs[i3])
- area2 = TriangleArea(pxLoc, scaled_uvs[i1], scaled_uvs[i2])
- if area0 + area1 + area2 > uv_area + 1: # 1 px bleed/error margin.
- pass # if were a quad the other side may contain the pixel so keep looking.
- else:
- # We know the point is in the tri
- area0 /= uv_area
- area1 /= uv_area
- area2 /= uv_area
-
- # New location
- return Vector(\
- face.v[i1].co[0]*area0 + face.v[i2].co[0]*area1 + face.v[i3].co[0]*area2,\
- face.v[i1].co[1]*area0 + face.v[i2].co[1]*area1 + face.v[i3].co[1]*area2,\
- face.v[i1].co[2]*area0 + face.v[i2].co[2]*area1 + face.v[i3].co[2]*area2\
- )
-
- return None
-
-
-# Used for debugging ngon
-"""
-def draw_loops(loops):
-
- me= Blender.Mesh.New()
- for l in loops:
- #~ me= Blender.Mesh.New()
-
-
- i= len(me.verts)
- me.verts.extend([v[0] for v in l])
- try:
- me.verts[0].sel= 1
- except:
- pass
- me.edges.extend([ (j-1, j) for j in xrange(i+1, len(me.verts)) ])
- # Close the edge?
- me.edges.extend((i, len(me.verts)-1))
-
-
- #~ ob= Blender.Object.New('Mesh')
- #~ ob.link(me)
- #~ scn= Blender.Scene.GetCurrent()
- #~ scn.link(ob)
- #~ ob.Layers= scn.Layers
- #~ ob.sel= 1
-
-
-
- # Fill
- #fill= Blender.Mathutils.PolyFill(loops)
- #me.faces.extend(fill)
-
-
- ob= Blender.Object.New('Mesh')
- ob.link(me)
- scn= Blender.Scene.GetCurrent()
- scn.link(ob)
- ob.Layers= scn.Layers
- ob.sel= 1
- Blender.Window.RedrawAll()
-"""
-
-def ngon(from_data, indices, PREF_FIX_LOOPS= True):
- '''
- Takes a polyline of indices (fgon)
- and returns a list of face indicie lists.
- Designed to be used for importers that need indices for an fgon to create from existing verts.
-
- from_data: either a mesh, or a list/tuple of vectors.
- indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given.
- PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly.
- '''
-
- if not set: # Need sets for this, otherwise do a normal fill.
- PREF_FIX_LOOPS= False
-
- Vector= Blender.Mathutils.Vector
- if not indices:
- return []
-
- # return []
- def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6)
- def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length
-
- def vert_treplet(v, i):
- return v, rvec(v), i, mlen(v)
-
- def ed_key_mlen(v1, v2):
- if v1[3] > v2[3]:
- return v2[1], v1[1]
- else:
- return v1[1], v2[1]
-
-
- if not PREF_FIX_LOOPS:
- '''
- Normal single concave loop filling
- '''
- if type(from_data) in (tuple, list):
- verts= [Vector(from_data[i]) for ii, i in enumerate(indices)]
- else:
- verts= [from_data.verts[i].co for ii, i in enumerate(indices)]
-
- for i in xrange(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))):
- if verts[i][1]==verts[i-1][0]:
- verts.pop(i-1)
-
- fill= Blender.Geometry.PolyFill([verts])
-
- else:
- '''
- Seperate this loop into multiple loops be finding edges that are used twice
- This is used by lightwave LWO files a lot
- '''
-
- if type(from_data) in (tuple, list):
- verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)]
- else:
- verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)]
-
- edges= [(i, i-1) for i in xrange(len(verts))]
- if edges:
- edges[0]= (0,len(verts)-1)
-
- if not verts:
- return []
-
-
- edges_used= set()
- edges_doubles= set()
- # We need to check if any edges are used twice location based.
- for ed in edges:
- edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]])
- if edkey in edges_used:
- edges_doubles.add(edkey)
- else:
- edges_used.add(edkey)
-
- # Store a list of unconnected loop segments split by double edges.
- # will join later
- loop_segments= []
-
- v_prev= verts[0]
- context_loop= [v_prev]
- loop_segments= [context_loop]
-
- for v in verts:
- if v!=v_prev:
- # Are we crossing an edge we removed?
- if ed_key_mlen(v, v_prev) in edges_doubles:
- context_loop= [v]
- loop_segments.append(context_loop)
- else:
- if context_loop and context_loop[-1][1]==v[1]:
- #raise "as"
- pass
- else:
- context_loop.append(v)
-
- v_prev= v
- # Now join loop segments
-
- def join_seg(s1,s2):
- if s2[-1][1]==s1[0][1]: #
- s1,s2= s2,s1
- elif s1[-1][1]==s2[0][1]:
- pass
- else:
- return False
-
- # If were stuill here s1 and s2 are 2 segments in the same polyline
- s1.pop() # remove the last vert from s1
- s1.extend(s2) # add segment 2 to segment 1
-
- if s1[0][1]==s1[-1][1]: # remove endpoints double
- s1.pop()
-
- s2[:]= [] # Empty this segment s2 so we dont use it again.
- return True
-
- joining_segments= True
- while joining_segments:
- joining_segments= False
- segcount= len(loop_segments)
-
- for j in xrange(segcount-1, -1, -1): #reversed(xrange(segcount)):
- seg_j= loop_segments[j]
- if seg_j:
- for k in xrange(j-1, -1, -1): # reversed(xrange(j)):
- if not seg_j:
- break
- seg_k= loop_segments[k]
-
- if seg_k and join_seg(seg_j, seg_k):
- joining_segments= True
-
- loop_list= loop_segments
-
- for verts in loop_list:
- while verts and verts[0][1]==verts[-1][1]:
- verts.pop()
-
- loop_list= [verts for verts in loop_list if len(verts)>2]
- # DONE DEALING WITH LOOP FIXING
-
-
- # vert mapping
- vert_map= [None]*len(indices)
- ii=0
- for verts in loop_list:
- if len(verts)>2:
- for i, vert in enumerate(verts):
- vert_map[i+ii]= vert[2]
- ii+=len(verts)
-
- fill= Blender.Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ])
- #draw_loops(loop_list)
- #raise 'done loop'
- # map to original indicies
- fill= [[vert_map[i] for i in reversed(f)] for f in fill]
-
-
- if not fill:
- print 'Warning Cannot scanfill, fallback on a triangle fan.'
- fill= [ [0, i-1, i] for i in xrange(2, len(indices)) ]
- else:
- # Use real scanfill.
- # See if its flipped the wrong way.
- flip= None
- for fi in fill:
- if flip != None:
- break
- for i, vi in enumerate(fi):
- if vi==0 and fi[i-1]==1:
- flip= False
- break
- elif vi==1 and fi[i-1]==0:
- flip= True
- break
-
- if not flip:
- for i, fi in enumerate(fill):
- fill[i]= tuple([ii for ii in reversed(fi)])
-
-
-
-
- return fill
-
-
-
-# EG
-'''
-scn= Scene.GetCurrent()
-me = scn.getActiveObject().getData(mesh=1)
-ind= [v.index for v in me.verts if v.sel] # Get indices
-
-indices = ngon(me, ind) # fill the ngon.
-
-# Extand the faces to show what the scanfill looked like.
-print len(indices)
-me.faces.extend([[me.verts[ii] for ii in i] for i in indices])
-'''
-
-def meshCalcNormals(me, vertNormals=None):
- '''
- takes a mesh and returns very high quality normals 1 normal per vertex.
- The normals should be correct, indipendant of topology
-
- vertNormals - a list of vectors at least as long as the number of verts in the mesh
- '''
- Ang= Blender.Mathutils.AngleBetweenVecs
- Vector= Blender.Mathutils.Vector
- SMALL_NUM=0.000001
- # Weight the edge normals by total angle difference
- # EDGE METHOD
-
- if not vertNormals:
- vertNormals= [ Vector() for v in xrange(len(me.verts)) ]
- else:
- for v in vertNormals:
- v.zero()
-
- edges={}
- for f in me.faces:
- f_v = f.v
- for edkey in f.edge_keys:
- edges.setdefault(edkey, []).append(f.no)
-
- # Weight the edge normals by total angle difference
- for fnos in edges.itervalues():
-
- len_fnos= len(fnos)
- if len_fnos>1:
- totAngDiff=0
- for j in xrange(len_fnos-1, -1, -1): # same as reversed(xrange(...))
- for k in xrange(j-1, -1, -1): # same as reversed(xrange(...))
- #print j,k
- try:
- totAngDiff+= (Ang(fnos[j], fnos[k])) # /180 isnt needed, just to keeop the vert small.
- except:
- pass # Zero length face
-
- # print totAngDiff
- if totAngDiff > SMALL_NUM:
- '''
- average_no= Vector()
- for no in fnos:
- average_no+=no
- '''
- average_no= reduce(lambda a,b: a+b, fnos, Vector())
- fnos.append(average_no*totAngDiff) # average no * total angle diff
- #else:
- # fnos[0]
- else:
- fnos.append(fnos[0])
-
- for ed, v in edges.iteritems():
- vertNormals[ed[0]]+= v[-1]
- vertNormals[ed[1]]+= v[-1]
- for i, v in enumerate(me.verts):
- v.no= vertNormals[i]
-
-
-
-
-def pointInsideMesh(ob, pt):
- Intersect = Blender.Mathutils.Intersect # 2 less dict lookups.
- Vector = Blender.Mathutils.Vector
-
- def ptInFaceXYBounds(f, pt):
- f_v = f.v
- co= f_v[0].co
- xmax= xmin= co.x
- ymax= ymin= co.y
-
- co= f_v[1].co
- xmax= max(xmax, co.x)
- xmin= min(xmin, co.x)
- ymax= max(ymax, co.y)
- ymin= min(ymin, co.y)
-
- co= f_v[2].co
- xmax= max(xmax, co.x)
- xmin= min(xmin, co.x)
- ymax= max(ymax, co.y)
- ymin= min(ymin, co.y)
-
- if len(f_v)==4:
- co= f_v[3].co
- xmax= max(xmax, co.x)
- xmin= min(xmin, co.x)
- ymax= max(ymax, co.y)
- ymin= min(ymin, co.y)
-
- # Now we have the bounds, see if the point is in it.
- if\
- pt.x < xmin or\
- pt.y < ymin or\
- pt.x > xmax or\
- pt.y > ymax:
- return False # point is outside face bounds
- else:
- return True # point inside.
- #return xmax, ymax, xmin, ymin
-
- def faceIntersect(f):
- f_v = f.v
- isect = Intersect(f_v[0].co, f_v[1].co, f_v[2].co, ray, obSpacePt, 1) # Clipped.
- if not isect and len(f) == 4:
- isect = Intersect(f_v[0].co, f_v[2].co, f_v[3].co, ray, obSpacePt, 1) # Clipped.
-
- if isect and isect.z > obSpacePt.z: # This is so the ray only counts if its above the point.
- return True
- else:
- return False
-
- obSpacePt = pt*ob.matrixWorld.copy().invert()
- ray = Vector(0,0,-1)
- me= ob.getData(mesh=1)
-
- # Here we find the number on intersecting faces, return true if an odd number (inside), false (outside) if its true.
- return len([None for f in me.faces if ptInFaceXYBounds(f, obSpacePt) if faceIntersect(f)]) % 2
-
-
-def faceAngles(f):
- '''
- Returns the angle between all corners in a tri or a quad
-
- '''
- AngleBetweenVecs = Blender.Mathutils.AngleBetweenVecs
- def Ang(a1,a2):
- try: return AngleBetweenVecs(a1,a2)
- except: return 180
-
- if len(f) == 3:
- if type(f) in (tuple, list): v1,v2,v3 = f
- else: v1,v2,v3 = [v.co for v in f]
- a1= Ang(v2-v1,v3-v1)
- a2= Ang(v1-v2,v3-v2)
- a3 = 180 - (a1+a2) # a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3)
- return a1,a2,a3
-
- else:
- if type(f) in (tuple, list): v1,v2,v3,v4 = f
- else: v1,v2,v3,v4 = [v.co for v in f]
- a1= Ang(v2-v1,v4-v1)
- a2= Ang(v1-v2,v3-v2)
- a3= Ang(v2-v3,v4-v3)
- a4= Ang(v3-v4,v1-v4)
- return a1,a2,a3,a4
-
-# NMesh wrapper
-Vector= Blender.Mathutils.Vector
-class NMesh(object):
- __slots__= 'verts', 'faces', 'edges', 'faceUV', 'materials', 'realmesh'
- def __init__(self, mesh):
- '''
- This is an NMesh wrapper that
- mesh is an Mesh as returned by Blender.Mesh.New()
- This class wraps NMesh like access into Mesh
-
- Running NMesh.update() - with this wrapper,
- Will update the realmesh.
- '''
- self.verts= []
- self.faces= []
- self.edges= []
- self.faceUV= False
- self.materials= []
- self.realmesh= mesh
-
- def addFace(self, nmf):
- self.faces.append(nmf)
-
- def Face(self, v=[]):
- return NMFace(v)
- def Vert(self, x,y,z):
- return NMVert(x,y,z)
-
- def hasFaceUV(self, flag):
- if flag:
- self.faceUV= True
- else:
- self.faceUV= False
-
- def addMaterial(self, mat):
- self.materials.append(mat)
-
- def update(self, recalc_normals=False): # recalc_normals is dummy
- mesh= self.realmesh
- mesh.verts= None # Clears the
-
- # Add in any verts from faces we may have not added.
- for nmf in self.faces:
- for nmv in nmf.v:
- if nmv.index==-1:
- nmv.index= len(self.verts)
- self.verts.append(nmv)
-
-
- mesh.verts.extend([nmv.co for nmv in self.verts])
- for i, nmv in enumerate(self.verts):
- nmv.index= i
- mv= mesh.verts[i]
- mv.sel= nmv.sel
-
- good_faces= [nmf for nmf in self.faces if len(nmf.v) in (3,4)]
- #print len(good_faces), 'AAA'
-
-
- #mesh.faces.extend([nmf.v for nmf in self.faces])
- mesh.faces.extend([[mesh.verts[nmv.index] for nmv in nmf.v] for nmf in good_faces])
- if len(mesh.faces):
- if self.faceUV:
- mesh.faceUV= 1
-
- #for i, nmf in enumerate(self.faces):
- for i, nmf in enumerate(good_faces):
- mf= mesh.faces[i]
- if self.faceUV:
- if len(nmf.uv) == len(mf.v):
- mf.uv= [Vector(uv[0], uv[1]) for uv in nmf.uv]
- if len(nmf.col) == len(mf.v):
- for c, i in enumerate(mf.col):
- c.r, c.g, c.b= nmf.col[i].r, nmf.col[i].g, nmf.col[i].b
- if nmf.image:
- mf.image= nmf.image
-
- mesh.materials= self.materials[:16]
-
-class NMVert(object):
- __slots__= 'co', 'index', 'no', 'sel', 'uvco'
- def __init__(self, x,y,z):
- self.co= Vector(x,y,z)
- self.index= None # set on appending.
- self.no= Vector(0,0,1) # dummy
- self.sel= 0
- self.uvco= None
-class NMFace(object):
- __slots__= 'col', 'flag', 'hide', 'image', 'mat', 'materialIndex', 'mode', 'normal',\
- 'sel', 'smooth', 'transp', 'uv', 'v'
-
- def __init__(self, v=[]):
- self.col= []
- self.flag= 0
- self.hide= 0
- self.image= None
- self.mat= 0 # materialIndex needs support too.
- self.mode= 0
- self.normal= Vector(0,0,1)
- self.uv= []
- self.sel= 0
- self.smooth= 0
- self.transp= 0
- self.uv= []
- self.v= [] # a list of nmverts.
-
-class NMCol(object):
- __slots__ = 'r', 'g', 'b', 'a'
- def __init__(self):
- self.r= 255
- self.g= 255
- self.b= 255
- self.a= 255
-
-
-'''
-#
-verts_split= [dict() for i in xrange(len(me.verts))]
-
-tot_verts= 0
-for f in me.faces:
- f_uv= f.uv
- for i, v in enumerate(f.v):
- vert_index= v.index # mesh index
- vert_dict= verts_split[vert_index] # get the dict for this vert
-
- uv= f_uv[i]
- # now we have the vert and the face uv well make a unique dict.
-
- vert_key= v.x, v.y, v.x, uv.x, uv.y # ADD IMAGE NAME HETR IF YOU WANT TO SPLIT BY THAT TOO
- value= vert_index, tot_verts # ADD WEIGHT HERE IF YOU NEED.
- try:
- vert_dict[vert_key] # if this is missing it will fail.
- except:
- # this stores a mapping between the split and orig vert indicies
- vert_dict[vert_key]= value
- tot_verts+= 1
-
-# a flat list of split verts - can add custom weight data here too if you need
-split_verts= [None]*tot_verts
-
-for vert_split_dict in verts_split:
- for key, value in vert_split_dict.iteritems():
- local_index, split_index= value
- split_verts[split_index]= key
-
-# split_verts - Now you have a list of verts split by their UV.
-'''
diff --git a/release/scripts/bpymodules/BPyMesh_redux.py b/release/scripts/bpymodules/BPyMesh_redux.py
deleted file mode 100644
index 5955d696fbd..00000000000
--- a/release/scripts/bpymodules/BPyMesh_redux.py
+++ /dev/null
@@ -1,652 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# (C) Copyright 2006 MetaVR, Inc.
-# http://www.metavr.com
-# Written by Campbell 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-Vector= Blender.Mathutils.Vector
-Ang= Blender.Mathutils.AngleBetweenVecs
-MidpointVecs= Blender.Mathutils.MidpointVecs
-import BPyMesh
-
-# If python version is less than 2.4, try to get set stuff from module
-
-try:
- set
-except:
- try:
- from sets import Set as set
- except:
- set= None
-
-def uv_key(uv):
- return round(uv.x, 5), round(uv.y, 5)
-
-def uv_key_mix(uv1, uv2, w1, w2):
- # Weighted mix. w1+w2==1.0
- return w1*uv1[0]+w2*uv2[0], w1*uv1[1]+w2*uv2[1]
-
-def col_key(col):
- return col.r, col.g, col.b
-
-def col_key_mix(col1, col2, w1, w2):
- # Weighted mix. w1+w2==1.0
- return int(w1*col1[0] + w2*col2[0]), int(w1*col1[1] + w2*col2[1]), int(w1*col1[2]+col2[2]*w2)
-
-
-def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=2.0, REMOVE_DOUBLES=False, FACE_AREA_WEIGHT=1.0, FACE_TRIANGULATE=True, DO_UV=True, DO_VCOL=True, DO_WEIGHTS=True, VGROUP_INF_REDUX= None, VGROUP_INF_WEIGHT=0.5):
- """
- BOUNDRY_WEIGHT - 0 is no boundry weighting. 2.0 will make them twice as unlikely to collapse.
- FACE_AREA_WEIGHT - 0 is no weight. 1 is normal, 2.0 is higher.
- """
-
- if REDUX<0 or REDUX>1.0:
- raise 'Error, factor must be between 0 and 1.0'
- elif not set:
- raise 'Error, this function requires Python 2.4 or a full install of Python 2.3'
-
- BOUNDRY_WEIGHT= 1+BOUNDRY_WEIGHT
-
- """ # DEBUG!
- if Blender.Get('rt') == 1000:
- DEBUG=True
- else:
- DEBUG= False
- """
-
- me= ob.getData(mesh=1)
- me.hide= False # unhide all data,.
- if len(me.faces)<5:
- return
-
-
-
- if FACE_TRIANGULATE or REMOVE_DOUBLES:
- me.sel= True
-
- if FACE_TRIANGULATE:
- me.quadToTriangle()
-
- if REMOVE_DOUBLES:
- me.remDoubles(0.0001)
-
- vgroups= me.getVertGroupNames()
-
- if not me.getVertGroupNames():
- DO_WEIGHTS= False
-
- if (VGROUP_INF_REDUX!= None and VGROUP_INF_REDUX not in vgroups) or\
- VGROUP_INF_WEIGHT==0.0:
- VGROUP_INF_REDUX= None
-
- try:
- VGROUP_INF_REDUX_INDEX= vgroups.index(VGROUP_INF_REDUX)
- except:
- VGROUP_INF_REDUX_INDEX= -1
-
- # del vgroups
- len_vgroups= len(vgroups)
-
-
-
- OLD_MESH_MODE= Blender.Mesh.Mode()
- Blender.Mesh.Mode(Blender.Mesh.SelectModes.VERTEX)
-
- if DO_UV and not me.faceUV:
- DO_UV= False
-
- if DO_VCOL and not me.vertexColors:
- DO_VCOL = False
-
- current_face_count= len(me.faces)
- target_face_count= int(current_face_count * REDUX)
- # % of the collapseable faces to collapse per pass.
- #collapse_per_pass= 0.333 # between 0.1 - lots of small nibbles, slow but high q. and 0.9 - big passes and faster.
- collapse_per_pass= 0.333 # between 0.1 - lots of small nibbles, slow but high q. and 0.9 - big passes and faster.
-
- """# DEBUG!
- if DEBUG:
- COUNT= [0]
- def rd():
- if COUNT[0]< 330:
- COUNT[0]+=1
- return
- me.update()
- Blender.Window.RedrawAll()
- print 'Press key for next, count "%s"' % COUNT[0]
- try: input()
- except KeyboardInterrupt:
- raise "Error"
- except:
- pass
-
- COUNT[0]+=1
- """
-
- class collapseEdge(object):
- __slots__ = 'length', 'key', 'faces', 'collapse_loc', 'v1', 'v2','uv1', 'uv2', 'col1', 'col2', 'collapse_weight'
- def __init__(self, ed):
- self.init_from_edge(ed) # So we can re-use the classes without using more memory.
-
- def init_from_edge(self, ed):
- self.key= ed.key
- self.length= ed.length
- self.faces= []
- self.v1= ed.v1
- self.v2= ed.v2
- if DO_UV or DO_VCOL:
- self.uv1= []
- self.uv2= []
- self.col1= []
- self.col2= []
-
- # self.collapse_loc= None # new collapse location.
- # Basic weighting.
- #self.collapse_weight= self.length * (1+ ((ed.v1.no-ed.v2.no).length**2))
- self.collapse_weight= 1.0
-
- def collapse_locations(self, w1, w2):
- '''
- Generate a smart location for this edge to collapse to
- w1 and w2 are vertex location bias
- '''
-
- v1co= self.v1.co
- v2co= self.v2.co
- v1no= self.v1.no
- v2no= self.v2.no
-
- # Basic operation, works fine but not as good as predicting the best place.
- #between= ((v1co*w1) + (v2co*w2))
- #self.collapse_loc= between
-
- # normalize the weights of each vert - se we can use them as scalers.
- wscale= w1+w2
- if not wscale: # no scale?
- w1=w2= 0.5
- else:
- w1/=wscale
- w2/=wscale
-
- length= self.length
- between= MidpointVecs(v1co, v2co)
-
- # Collapse
- # new_location = between # Replace tricky code below. this code predicts the best collapse location.
-
- # Make lines at right angles to the normals- these 2 lines will intersect and be
- # the point of collapsing.
-
- # Enlarge so we know they intersect: self.length*2
- cv1= v1no.cross(v1no.cross(v1co-v2co))
- cv2= v2no.cross(v2no.cross(v2co-v1co))
-
- # Scale to be less then the edge lengths.
- cv2.length = cv1.length = 1
-
- cv1 = cv1 * (length* 0.4)
- cv2 = cv2 * (length* 0.4)
-
- smart_offset_loc= between + (cv1 + cv2)
-
- # Now we need to blend between smart_offset_loc and w1/w2
- # you see were blending between a vert and the edges midpoint, so we cant use a normal weighted blend.
- if w1 > 0.5: # between v1 and smart_offset_loc
- #self.collapse_loc= v1co*(w2+0.5) + smart_offset_loc*(w1-0.5)
- w2*=2
- w1= 1-w2
- new_loc_smart= v1co*w1 + smart_offset_loc*w2
- else: # w between v2 and smart_offset_loc
- w1*=2
- w2= 1-w1
- new_loc_smart= v2co*w2 + smart_offset_loc*w1
-
- if new_loc_smart.x != new_loc_smart.x: # NAN LOCATION, revert to between
- new_loc_smart= None
-
- return new_loc_smart, between, v1co*0.99999 + v2co*0.00001, v1co*0.00001 + v2co*0.99999
-
-
- class collapseFace(object):
- __slots__ = 'verts', 'normal', 'area', 'index', 'orig_uv', 'orig_col', 'uv', 'col' # , 'collapse_edge_count'
- def __init__(self, f):
- self.init_from_face(f)
-
- def init_from_face(self, f):
- self.verts= f.v
- self.normal= f.no
- self.area= f.area
- self.index= f.index
- if DO_UV:
- self.orig_uv= [uv_key(uv) for uv in f.uv]
- self.uv= f.uv
- if DO_VCOL:
- self.orig_col= [col_key(col) for col in f.col]
- self.col= f.col
-
- collapse_edges= collapse_faces= None
-
- # So meshCalcNormals can avoid making a new list all the time.
- reuse_vertNormals= [ Vector() for v in xrange(len(me.verts)) ]
-
- while target_face_count <= len(me.faces):
- BPyMesh.meshCalcNormals(me, reuse_vertNormals)
-
- if DO_WEIGHTS:
- #groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
- groupNames, vWeightList= BPyMesh.meshWeight2List(me)
-
- # THIS CRASHES? Not anymore.
- verts= list(me.verts)
- edges= list(me.edges)
- faces= list(me.faces)
-
- # THIS WORKS
- #verts= me.verts
- #edges= me.edges
- #faces= me.faces
-
- # if DEBUG: DOUBLE_CHECK= [0]*len(verts)
- me.sel= False
-
- if not collapse_faces: # Initialize the list.
- collapse_faces= [collapseFace(f) for f in faces]
- collapse_edges= [collapseEdge(ed) for ed in edges]
- else:
- for i, ed in enumerate(edges):
- collapse_edges[i].init_from_edge(ed)
-
- # Strip the unneeded end off the list
- collapse_edges[i+1:]= []
-
- for i, f in enumerate(faces):
- collapse_faces[i].init_from_face(f)
-
- # Strip the unneeded end off the list
- collapse_faces[i+1:]= []
-
-
- collapse_edges_dict= dict( [(ced.key, ced) for ced in collapse_edges] )
-
- # Store verts edges.
- vert_ed_users= [[] for i in xrange(len(verts))]
- for ced in collapse_edges:
- vert_ed_users[ced.key[0]].append(ced)
- vert_ed_users[ced.key[1]].append(ced)
-
- # Store face users
- vert_face_users= [[] for i in xrange(len(verts))]
-
- # Have decieded not to use this. area is better.
- #face_perim= [0.0]* len(me.faces)
-
- for ii, cfa in enumerate(collapse_faces):
- for i, v1 in enumerate(cfa.verts):
- vert_face_users[v1.index].append( (i,cfa) )
-
- # add the uv coord to the vert
- v2 = cfa.verts[i-1]
- i1= v1.index
- i2= v2.index
-
- if i1>i2: ced= collapse_edges_dict[i2,i1]
- else: ced= collapse_edges_dict[i1,i2]
-
- ced.faces.append(cfa)
- if DO_UV or DO_VCOL:
- # if the edge is flipped from its order in the face then we need to flip the order indicies.
- if cfa.verts[i]==ced.v1: i1,i2 = i, i-1
- else: i1,i2 = i-1, i
-
- if DO_UV:
- ced.uv1.append( cfa.orig_uv[i1] )
- ced.uv2.append( cfa.orig_uv[i2] )
-
- if DO_VCOL:
- ced.col1.append( cfa.orig_col[i1] )
- ced.col2.append( cfa.orig_col[i2] )
-
-
- # PERIMITER
- #face_perim[ii]+= ced.length
-
-
-
- # How weight the verts by the area of their faces * the normal difference.
- # when the edge collapses, to vert weights are taken into account
-
- vert_weights= [0.5] * len(verts)
-
- for ii, vert_faces in enumerate(vert_face_users):
- for f in vert_faces:
- try:
- no_ang= (Ang(verts[ii].no, f[1].normal)/180) * f[1].area
- except:
- no_ang= 1.0
-
- vert_weights[ii] += no_ang
-
- # Use a vertex group as a weighting.
- if VGROUP_INF_REDUX!=None:
-
- # Get Weights from a vgroup.
- """
- vert_weights_map= [1.0] * len(verts)
- for i, wd in enumerate(vWeightDict):
- try: vert_weights_map[i]= 1+(wd[VGROUP_INF_REDUX] * VGROUP_INF_WEIGHT)
- except: pass
- """
- vert_weights_map= [1+(wl[VGROUP_INF_REDUX_INDEX]*VGROUP_INF_WEIGHT) for wl in vWeightList ]
-
-
- # BOUNDRY CHECKING AND WEIGHT EDGES. CAN REMOVE
- # Now we know how many faces link to an edge. lets get all the boundry verts
- if BOUNDRY_WEIGHT > 0:
- verts_boundry= [1] * len(verts)
- #for ed_idxs, faces_and_uvs in edge_faces_and_uvs.iteritems():
- for ced in collapse_edges:
- if len(ced.faces) < 2:
- for key in ced.key: # only ever 2 key indicies.
- verts_boundry[key]= 2
-
- for ced in collapse_edges:
- b1= verts_boundry[ced.key[0]]
- b2= verts_boundry[ced.key[1]]
- if b1 != b2:
- # Edge has 1 boundry and 1 non boundry vert. weight higher
- ced.collapse_weight= BOUNDRY_WEIGHT
- #elif b1==b2==2: # if both are on a seam then weigh half as bad.
- # ced.collapse_weight= ((BOUNDRY_WEIGHT-1)/2) +1
- # weight the verts by their boundry status
- del b1
- del b2
-
- for ii, boundry in enumerate(verts_boundry):
- if boundry==2:
- vert_weights[ii] *= BOUNDRY_WEIGHT
-
- vert_collapsed= verts_boundry
- del verts_boundry
- else:
- vert_collapsed= [1] * len(verts)
-
-
-
-
- # Best method, no quick hacks here, Correction. Should be the best but needs tweaks.
- def ed_set_collapse_error(ced):
- # Use the vertex weights to bias the new location.
- new_locs= ced.collapse_locations(vert_weights[ced.key[0]], vert_weights[ced.key[1]])
-
-
- # Find the connecting faces of the 2 verts.
- i1, i2= ced.key
- test_faces= set()
- for i in (i1,i2): # faster then LC's
- for f in vert_face_users[i]:
- test_faces.add(f[1].index)
- for f in ced.faces:
- test_faces.remove(f.index)
-
-
- v1_orig= Vector(ced.v1.co)
- v2_orig= Vector(ced.v2.co)
-
- def test_loc(new_loc):
- '''
- Takes a location and tests the error without changing anything
- '''
- new_weight= ced.collapse_weight
- ced.v1.co= ced.v2.co= new_loc
-
- new_nos= [faces[i].no for i in test_faces]
-
- # So we can compare the befire and after normals
- ced.v1.co= v1_orig
- ced.v2.co= v2_orig
-
- # now see how bad the normals are effected
- angle_diff= 1.0
-
- for ii, i in enumerate(test_faces): # local face index, global face index
- cfa= collapse_faces[i] # this collapse face
- try:
- # can use perim, but area looks better.
- if FACE_AREA_WEIGHT:
- # Psudo code for wrighting
- # angle_diff= The before and after angle difference between the collapsed and un-collapsed face.
- # ... devide by 180 so the value will be between 0 and 1.0
- # ... add 1 so we can use it as a multiplyer and not make the area have no eefect (below)
- # area_weight= The faces original area * the area weight
- # ... add 1.0 so a small area face dosent make the angle_diff have no effect.
- #
- # Now multiply - (angle_diff * area_weight)
- # ... The weight will be a minimum of 1.0 - we need to subtract this so more faces done give the collapse an uneven weighting.
-
- angle_diff+= ((1+(Ang(cfa.normal, new_nos[ii])/180)) * (1+(cfa.area * FACE_AREA_WEIGHT))) -1 # 4 is how much to influence area
- else:
- angle_diff+= (Ang(cfa.normal), new_nos[ii])/180
-
- except:
- pass
-
-
- # This is very arbirary, feel free to modify
- try: no_ang= (Ang(ced.v1.no, ced.v2.no)/180) + 1
- except: no_ang= 2.0
-
- # do *= because we face the boundry weight to initialize the weight. 1.0 default.
- new_weight *= ((no_ang * ced.length) * (1-(1/angle_diff)))# / max(len(test_faces), 1)
- return new_weight
- # End testloc
-
-
- # Test the collapse locatons
- collapse_loc_best= None
- collapse_weight_best= 1000000000
- ii= 0
- for collapse_loc in new_locs:
- if collapse_loc: # will only ever fail if smart loc is NAN
- test_weight= test_loc(collapse_loc)
- if test_weight < collapse_weight_best:
- iii= ii
- collapse_weight_best = test_weight
- collapse_loc_best= collapse_loc
- ii+=1
-
- ced.collapse_loc= collapse_loc_best
- ced.collapse_weight= collapse_weight_best
-
-
- # are we using a weight map
- if VGROUP_INF_REDUX:
- v= vert_weights_map[i1]+vert_weights_map[i2]
- ced.collapse_weight*= v
- # End collapse Error
-
- # We can calculate the weights on __init__ but this is higher qualuity.
- for ced in collapse_edges:
- if ced.faces: # dont collapse faceless edges.
- ed_set_collapse_error(ced)
-
- # Wont use the function again.
- del ed_set_collapse_error
- # END BOUNDRY. Can remove
-
- # sort by collapse weight
- try: collapse_edges.sort(key = lambda ced: ced.collapse_weight) # edges will be used for sorting
- except: collapse_edges.sort(lambda ced1, ced2: cmp(ced1.collapse_weight, ced2.collapse_weight)) # edges will be used for sorting
-
-
- vert_collapsed= [0]*len(verts)
-
- collapse_edges_to_collapse= []
-
- # Make a list of the first half edges we can collapse,
- # these will better edges to remove.
- collapse_count=0
- for ced in collapse_edges:
- if ced.faces:
- i1, i2= ced.key
- # Use vert selections
- if vert_collapsed[i1] or vert_collapsed[i2]:
- pass
- else:
- # Now we know the verts havnyt been collapsed.
- vert_collapsed[i2]= vert_collapsed[i1]= 1 # Dont collapse again.
- collapse_count+=1
- collapse_edges_to_collapse.append(ced)
-
- # Get a subset of the entire list- the first "collapse_per_pass", that are best to collapse.
- if collapse_count > 4:
- collapse_count = int(collapse_count*collapse_per_pass)
- else:
- collapse_count = len(collapse_edges)
- # We know edge_container_list_collapse can be removed.
- for ced in collapse_edges_to_collapse:
- """# DEBUG!
- if DEBUG:
- if DOUBLE_CHECK[ced.v1.index] or\
- DOUBLE_CHECK[ced.v2.index]:
- raise 'Error'
- else:
- DOUBLE_CHECK[ced.v1.index]=1
- DOUBLE_CHECK[ced.v2.index]=1
-
- tmp= (ced.v1.co+ced.v2.co)*0.5
- Blender.Window.SetCursorPos(tmp.x, tmp.y, tmp.z)
- Blender.Window.RedrawAll()
- """
-
- # Chech if we have collapsed our quota.
- collapse_count-=1
- if not collapse_count:
- break
-
- current_face_count -= len(ced.faces)
-
- # Find and assign the real weights based on collapse loc.
-
- # Find the weights from the collapse error
- if DO_WEIGHTS or DO_UV or DO_VCOL:
- i1, i2= ced.key
- # Dont use these weights since they may not have been used to make the collapse loc.
- #w1= vert_weights[i1]
- #w2= vert_weights[i2]
- w1= (ced.v2.co-ced.collapse_loc).length
- w2= (ced.v1.co-ced.collapse_loc).length
-
- # Normalize weights
- wscale= w1+w2
- if not wscale: # no scale?
- w1=w2= 0.5
- else:
- w1/= wscale
- w2/= wscale
-
-
- # Interpolate the bone weights.
- if DO_WEIGHTS:
-
- # add verts vgroups to eachother
- wl1= vWeightList[i1] # v1 weight dict
- wl2= vWeightList[i2] # v2 weight dict
- for group_index in xrange(len_vgroups):
- wl1[group_index]= wl2[group_index]= (wl1[group_index]*w1) + (wl2[group_index]*w2)
- # Done finding weights.
-
-
-
- if DO_UV or DO_VCOL:
- # Handel UV's and vert Colors!
- for v, my_weight, other_weight, edge_my_uvs, edge_other_uvs, edge_my_cols, edge_other_cols in (\
- (ced.v1, w1, w2, ced.uv1, ced.uv2, ced.col1, ced.col2),\
- (ced.v2, w2, w1, ced.uv2, ced.uv1, ced.col2, ced.col1)\
- ):
- uvs_mixed= [ uv_key_mix(edge_my_uvs[iii], edge_other_uvs[iii], my_weight, other_weight) for iii in xrange(len(edge_my_uvs)) ]
- cols_mixed= [ col_key_mix(edge_my_cols[iii], edge_other_cols[iii], my_weight, other_weight) for iii in xrange(len(edge_my_cols)) ]
-
- for face_vert_index, cfa in vert_face_users[v.index]:
- if len(cfa.verts)==3 and cfa not in ced.faces: # if the face is apart of this edge then dont bother finding the uvs since the face will be removed anyway.
-
- if DO_UV:
- # UV COORDS
- uvk= cfa.orig_uv[face_vert_index]
- try:
- tex_index= edge_my_uvs.index(uvk)
- except:
- tex_index= None
- """ # DEBUG!
- if DEBUG:
- print 'not found', uvk, 'in', edge_my_uvs, 'ed index', ii, '\nwhat about', edge_other_uvs
- """
- if tex_index != None: # This face uses a uv in the collapsing face. - do a merge
- other_uv= edge_other_uvs[tex_index]
- uv_vec= cfa.uv[face_vert_index]
- uv_vec.x, uv_vec.y= uvs_mixed[tex_index]
-
- # TEXFACE COLORS
- if DO_VCOL:
- colk= cfa.orig_col[face_vert_index]
- try: tex_index= edge_my_cols.index(colk)
- except: pass
- if tex_index != None:
- other_col= edge_other_cols[tex_index]
- col_ob= cfa.col[face_vert_index]
- col_ob.r, col_ob.g, col_ob.b= cols_mixed[tex_index]
-
- # DEBUG! if DEBUG: rd()
-
- # Execute the collapse
- ced.v1.sel= ced.v2.sel= True # Select so remove doubles removed the edges and faces that use it
- ced.v1.co= ced.v2.co= ced.collapse_loc
-
- # DEBUG! if DEBUG: rd()
- if current_face_count <= target_face_count:
- break
-
- # Copy weights back to the mesh before we remove doubles.
- if DO_WEIGHTS:
- #BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
- BPyMesh.list2MeshWeight(me, groupNames, vWeightList)
-
- doubles= me.remDoubles(0.0001)
- current_face_count= len(me.faces)
-
- if current_face_count <= target_face_count or not doubles: # not doubles shoule never happen.
- break
-
- me.update()
- Blender.Mesh.Mode(OLD_MESH_MODE)
-
-
-# Example usage
-def main():
- Blender.Window.EditMode(0)
- scn= bpy.data.scenes.active
- active_ob= scn.objects.active
- t= Blender.sys.time()
- redux(active_ob, 0.5)
- print '%.4f' % (Blender.sys.time()-t)
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/bpymodules/BPyMessages.py b/release/scripts/bpymodules/BPyMessages.py
deleted file mode 100644
index 8ee1aa6c707..00000000000
--- a/release/scripts/bpymodules/BPyMessages.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from Blender import Draw, sys
-def Error_NoMeshSelected():
- Draw.PupMenu('Error%t|No mesh objects selected')
-def Error_NoActive():
- Draw.PupMenu('Error%t|No active object')
-def Error_NoMeshActive():
- Draw.PupMenu('Error%t|Active object is not a mesh')
-def Error_NoMeshUvSelected():
- Draw.PupMenu('Error%t|No mesh objects with texface selected')
-def Error_NoMeshUvActive():
- Draw.PupMenu('Error%t|Active object is not a mesh with texface')
-def Error_NoMeshMultiresEdit():
- Draw.PupMenu('Error%t|Unable to complete action with multires enabled')
-def Error_NoMeshFaces():
- Draw.PupMenu('Error%t|Mesh has no faces')
-
-# File I/O messages
-def Error_NoFile(path):
- '''True if file missing, False if files there
-
- Use simply by doing...
- if Error_NoFile(path): return
- '''
- if not sys.exists(sys.expandpath(path)):
- Draw.PupMenu("Error%t|Can't open file: " + path)
- return True
- return False
-
-def Error_NoDir(path):
- '''True if dirs missing, False if dirs there
-
- Use simply by doing...
- if Error_NoDir(path): return
- '''
- if not sys.exists(sys.expandpath(path)):
- Draw.PupMenu("Error%t|Path does not exist: " + path)
- return True
- return False
-
-
-def Warning_MeshDistroyLayers(mesh):
- '''Returns true if we can continue to edit the mesh, warn when using NMesh'''
- if len(mesh.getUVLayerNames()) >1 and len(mesh.getColorLayerNames()) >1:
- return True
-
- ret = Draw.PupMenu('Warning%t|This script will distroy inactive UV and Color layers, OK?')
- if ret == -1:
- return False
-
- return True
-
-def Warning_SaveOver(path):
- '''Returns - True to save, False dont save'''
- if sys.exists(sys.expandpath(path)):
- ret= Draw.PupMenu('Save over%t|' + path)
- if ret == -1:
- return False
-
- return True
-
-
diff --git a/release/scripts/bpymodules/BPyNMesh.py b/release/scripts/bpymodules/BPyNMesh.py
deleted file mode 100644
index 043d8514db9..00000000000
--- a/release/scripts/bpymodules/BPyNMesh.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# $Id$
-#
-# --------------------------------------------------------------------------
-# BPyNMesh.py version 0.1
-# --------------------------------------------------------------------------
-# helper functions to be used by other scripts
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-# --------------------------------------------------------------------------
-# "Apply size and rotation" function by Jonas Petersen
-# --------------------------------------------------------------------------
-# This function does (hopefully) exactly what the
-# "Apply size and rotation" command does (CTRL-A in Object Mode).
-def ApplySizeAndRotation(obj):
- if obj.getType() != "Mesh": return
- if obj.SizeX==1.0 and obj.SizeY==1.0 and obj.SizeZ==1.0 and obj.RotX == 0.0 and obj.RotY == 0.0 and obj.RotZ == 0.0: return
- mesh = obj.getData()
- matrix = obj.matrix
- v = [0,0,0]
- for vert in mesh.verts:
- co = vert.co
- v[0] = co[0]*matrix[0][0] + co[1]*matrix[1][0] + co[2]*matrix[2][0]
- v[1] = co[0]*matrix[0][1] + co[1]*matrix[1][1] + co[2]*matrix[2][1]
- v[2] = co[0]*matrix[0][2] + co[1]*matrix[1][2] + co[2]*matrix[2][2]
- co[0], co[1], co[2] = v
- obj.SizeX = obj.SizeY = obj.SizeZ = 1.0
- obj.RotX = obj.RotY = obj.RotZ = 0.0
- mesh.update()
-
diff --git a/release/scripts/bpymodules/BPyObject.py b/release/scripts/bpymodules/BPyObject.py
deleted file mode 100644
index 54ff949218d..00000000000
--- a/release/scripts/bpymodules/BPyObject.py
+++ /dev/null
@@ -1,108 +0,0 @@
-import Blender
-
-def getObjectArmature(ob):
- '''
- This returns the first armature the mesh uses.
- remember there can be more then 1 armature but most people dont do that.
- '''
- if ob.type != 'Mesh':
- return None
-
- arm = ob.parent
- if arm and arm.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.ARMATURE:
- return arm
-
- for m in ob.modifiers:
- if m.type== Blender.Modifier.Types.ARMATURE:
- arm = m[Blender.Modifier.Settings.OBJECT]
- if arm:
- return arm
-
- return None
-
-
-def getDerivedObjects(ob, PARTICLES= True):
- '''
- Takes an objects and returnes a list of (ob, maxrix4x4) pairs
- that are derived from this object -
- This will include the object its self if it would be rendered.
- all dupli's for eg are not rendered themselves.
-
- currently supports
- * dupligroups
- * dupliverts
- * dupliframes
- * static particles as a mesh
-
- it is possible this function will return an empty list.
- '''
-
- ob_mtx_pairs = ob.DupObjects
- effects= ob.effects
-
- # Ignore self if were a dupli* or our parent is a duplivert.
- if ob.enableDupFrames or ob.enableDupGroup or ob.enableDupVerts:
- pass
- else:
- parent= ob.parent
- if parent and parent.enableDupVerts:
- pass
- else:
- if effects and (not effects[0].flag & Blender.Effect.Flags.EMESH):
- # Particles mesh wont render
- pass
- else:
- ob_mtx_pairs.append((ob, ob.matrixWorld))
-
-
- if PARTICLES:
- type_vec= type(Blender.Mathutils.Vector())
- type_tp= type((0,0))
- type_ls= type([])
-
- # TODO, particles per child object.
- # TODO Support materials
- me= Blender.Mesh.New()
- for eff in effects:
- par= eff.getParticlesLoc()
-
- if par:
- type_par= type(par[0])
-
- if type_par == type_vec:
- # point particles
- me.verts.extend(par)
-
- elif type_par == type_tp:
- # edge pairs
- start_index= len(me.verts)
- me.verts.extend([v for p in par for v in p])
- me.edges.extend( [(i, i+1) for i in xrange(start_index, start_index + len(par) - 1 )] )
-
- elif type_par == type_ls:
- # lines of edges
- start_index= len(me.verts)
- me.verts.extend([v for line in par for v in line])
-
- edges= []
- for line in par:
- edges.extend( [(i,i+1) for i in xrange(start_index, start_index+len(line)-1) ] )
- start_index+= len(line)
-
- me.edges.extend(edges)
-
- if me.verts:
- # If we have verts, then add the mesh
- ob_par = Blender.Object.New('Mesh')
- ob_par.link( me )
-
- LOOSE= Blender.Mesh.EdgeFlags.LOOSE
- for ed in me.edges:
- ed.flag |= LOOSE
-
- # Particle's are in worldspace so an identity matrix is fine.
- ob_mtx_pairs.append( (ob_par, Blender.Mathutils.Matrix()) )
-
- return ob_mtx_pairs
-
-
diff --git a/release/scripts/bpymodules/BPyRegistry.py b/release/scripts/bpymodules/BPyRegistry.py
deleted file mode 100644
index 4d681e15937..00000000000
--- a/release/scripts/bpymodules/BPyRegistry.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# --------------------------------------------------------------------------
-# Module BPyRegistry version 0.1
-# Helper functions to store / restore configuration data.
-# --------------------------------------------------------------------------
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# --------------------------------------------------------------------------
-
-# The Registry is a Python dictionary that is kept in Blender for as long as
-# the program is running, where scripts can store / restore persistent data
-# (data that is not lost when the script exits). This module provides
-# functions to save and restore Registry entries as config data in the
-# bpydata/config folder. Scripts just need to give an extra parameter to
-# the Blender.Registry.Get/Set() functions to have their data automatically
-# saved and restored when needed.
-#
-# Note: entries starting with an underscore are not saved, so script authors
-# can use that fact to define data that is not meant to be stored in a
-# config file. Example: data to be passed to another script and references to
-# invalid data, like Blender objects and any function or method.
-#
-# Check the Blender.Registry documentation for more information.
-
-import Blender
-from Blender import Registry, sys as bsys
-
-_EXT = '.cfg' # file extension for saved config data
-
-# limits:
-#MAX_ITEMS_NUM = 60 # max number of keys per dict and itens per list and tuple
-#MAX_STR_LEN = 300 # max string length (remember this is just for config data)
-
-_CFG_DIR = ''
-if Blender.Get('udatadir'):
- _CFG_DIR = Blender.sys.join(Blender.Get('udatadir'), 'config')
-if not _CFG_DIR or not bsys.exists(_CFG_DIR):
- _CFG_DIR = Blender.sys.join(Blender.Get('datadir'), 'config')
-if not bsys.exists(_CFG_DIR):
- _CFG_DIR = ''
-
-# to compare against, so we don't write to a cvs tree:
-_CVS_SUBPATH = 'release/scripts/bpydata/config/'
-if bsys.dirsep == '\\':
- _CVS_SUBPATH = _CVS_SUBPATH.replace('/', '\\')
-
-_KEYS = [k for k in Registry.Keys() if k[0] != '_']
-
-# _ITEMS_NUM = 0
-
-def _sanitize(o):
- "Check recursively that all objects are valid, set invalid ones to None"
-
- # global MAX_ITEMS_NUM, MAX_STR_LEN, _ITEMS_NUM
-
- valid_types = [int, float, bool, long, type]
- valid_checked_types = [str, unicode]
- # Only very simple types are considered valid for configuration data,
- # functions, methods and Blender objects (use their names instead) aren't.
-
- t = type(o)
-
- if t == dict:
- '''
- _ITEMS_NUM += len(o)
- if _ITEMS_NUM > MAX_ITEMS_NUM:
- return None
- '''
- for k, v in o.iteritems():
- o[k] = _sanitize(v)
- elif t in [list, tuple]:
- '''
- _ITEMS_NUM += len(o)
- if _ITEMS_NUM > MAX_ITEMS_NUM:
- return None
- '''
- return [_sanitize(i) for i in o]
- elif t in valid_types:
- return o
- elif t in valid_checked_types:
- '''
- if len(o) > MAX_STR_LEN:
- o = o[:MAX_STR_LEN]
- '''
- return o
- else: return None
-
- return o
-
-
-def _dict_to_str(name, d):
- "Return a pretty-print version of the passed dictionary"
- if not d: return 'None' # d can be None if there was no config to pass
-
- if name: l = ['%s = {' % name]
- else: l = ['{']
- #keys = d.keys()
- for k,v in d.iteritems(): # .keys()
- if type(v) == dict:
- l.append("'%s': %s" % (k, _dict_to_str(None, v)))
- else:
- l.append("'%s': %s," % (k, repr(v)))
- if name: l.append('}')
- else: l.append('},')
- return "\n".join(l)
-
-_HELP_MSG = """
-Please create a valid scripts config dir tree either by
-copying release/scripts/ tree to your <blenderhome> dir
-or by copying release/scripts/bpydata/ tree to a user
-defined scripts dir that you can set in the
-User Preferences -> Paths tab -> Python path input box.
-"""
-
-def _check_dir():
- global _CFG_DIR, _CVS_SUBPATH, _HELP_MSG
-
- if not _CFG_DIR:
- errmsg = "scripts config dir not found!\n%s" % _HELP_MSG
- raise IOError, errmsg
- elif _CFG_DIR.find(_CVS_SUBPATH) > 0:
- errmsg = """
-Your scripts config dir:\n%s
-seems to reside in your local Blender's cvs tree.\n%s""" % (_CFG_DIR, _HELP_MSG)
- raise SystemError, errmsg
- else: return
-
-
-# API:
-
-BPY_KEY_MISSING = 0
-BPY_KEY_IN_REGISTRY = 1
-BPY_KEY_IN_FILE = 2
-
-def HasConfigData (key):
- """
- Check if the given key exists, either already loaded in the Registry dict or
- as a file in the script data config dir.
- @type key: string
- @param key: a given key name.
- @returns:
- - 0: key does not exist;
- - 1: key exists in the Registry dict only;
- - 2: key exists as a file only;
- - 3: key exists in the Registry dict and also as a file.
- @note: for readability it's better to check against the constant bitmasks
- BPY_KEY_MISSING = 0, BPY_KEY_IN_REGISTRY = 1 and BPY_KEY_IN_FILE = 2.
- """
-
- fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
-
- result = BPY_KEY_MISSING
- if key in Registry.Keys(): result |= BPY_KEY_IN_REGISTRY
- if bsys.exists(fname): result |= BPY_KEY_IN_FILE
-
- return result
-
-
-def LoadConfigData (key = None):
- """
- Load config data from file(s) to the Registry dictionary.
- @type key: string
- @param key: a given key name. If None (default), all available keys are
- loaded.
- @returns: None
- """
-
- _check_dir()
-
- import os
-
- if not key:
- files = \
- [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)]
- else:
- files = []
- fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
- if bsys.exists(fname): files.append(fname)
-
- for p in files:
- try:
- f = file(p, 'r')
- lines = f.readlines()
- f.close()
- if lines: # Lines may be blank
- mainkey = lines[0].split('=')[0].strip()
- pysrc = "\n".join(lines)
- exec(pysrc)
- exec("Registry.SetKey('%s', %s)" % (str(mainkey), mainkey))
- except Exception, e:
- raise Warning(e) # Resend exception as warning
-
-
-def RemoveConfigData (key = None):
- """
- Remove this key's config file from the <(u)datadir>/config/ folder.
- @type key: string
- @param key: the name of the key to be removed. If None (default) all
- available config files are deleted.
- """
-
- _check_dir()
-
- if not key:
- files = \
- [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)]
- else:
- files = []
- fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
- if bsys.exists(fname): files.append(fname)
-
- import os
-
- try:
- for p in files:
- os.remove(p) # remove the file(s)
- except Exception, e:
- raise Warning(e) # Resend exception as warning
-
-
-def SaveConfigData (key = None):
- """
- Save Registry key(s) as file(s) in the <(u)datadir>/config/ folder.
- @type key: string
- @param key: the name of the key to be saved. If None (default) all
- available keys are saved.
- """
-
- global _KEYS, _CFG_DIR
-
- _check_dir()
-
- if key: keys = [key]
- else: keys = _KEYS
-
- for mainkey in keys:
- cfgdict = Registry.GetKey(mainkey).copy()
- for k in cfgdict: # .keys()
- if not k or k[0] == '_':
- del cfgdict[k]
-
- if not cfgdict: continue
-
- try:
- filename = bsys.join(_CFG_DIR, "%s%s" % (mainkey, _EXT))
- f = file(filename, 'w')
- output = _dict_to_str(mainkey, _sanitize(cfgdict))
- if output!='None':
- f.write(output)
- f.close()
- except Exception, e:
- raise Warning(e) # Resend exception as warning
diff --git a/release/scripts/bpymodules/BPyRender.py b/release/scripts/bpymodules/BPyRender.py
deleted file mode 100644
index 951e1ae6300..00000000000
--- a/release/scripts/bpymodules/BPyRender.py
+++ /dev/null
@@ -1,633 +0,0 @@
-import Blender
-from Blender import Scene, sys, Camera, Object, Image
-from Blender.Scene import Render
-Vector= Blender.Mathutils.Vector
-
-
-def extFromFormat(format):
- if format == Render.TARGA: return 'tga'
- if format == Render.RAWTGA: return 'tga'
- if format == Render.HDR: return 'hdr'
- if format == Render.PNG: return 'png'
- if format == Render.BMP: return 'bmp'
- if format == Render.JPEG: return 'jpg'
- if format == Render.HAMX: return 'ham'
- if format == Render.TIFF: return 'tif'
- if format == Render.CINEON: return 'cine'
- if format == Render.DPX: return 'tif'
- if format == Render.OPENEXR: return 'exr'
- if format == Render.IRIS: return 'rgb'
- return ''
-
-
-
-def imageFromObjectsOrtho(objects, path, width, height, smooth, alpha= True, camera_matrix= None, format=Render.PNG):
- '''
- Takes any number of objects and renders them on the z axis, between x:y-0 and x:y-1
- Usefull for making images from a mesh without per pixel operations
- - objects must be alredy placed
- - smooth, anti alias True/False
- - path renders to a PNG image
- - alpha weather to render background as alpha
-
- returns the blender image
- '''
- ext = '.' + extFromFormat(format)
- print ext
- # remove an extension if its alredy there
- if path.lower().endswith(ext):
- path= path[:-4]
-
- path_expand= sys.expandpath(path) + ext
-
- print path_expand, 'path'
-
- # Touch the path
- try:
- f= open(path_expand, 'w')
- f.close()
- except:
- raise 'Error, could not write to path:' + path_expand
-
-
- # RENDER THE FACES.
- scn= Scene.GetCurrent()
- render_scn= Scene.New()
- render_scn.makeCurrent()
- render_scn.Layers |= (1<<20)-1 # all layers enabled
-
- # Add objects into the current scene
- for ob in objects:
- render_scn.link(ob)
-
- render_context= render_scn.getRenderingContext()
- render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path.
-
-
- render_context.imageSizeX(width)
- render_context.imageSizeY(height)
-
- if smooth:
- render_context.enableOversampling(True)
- render_context.setOversamplingLevel(16)
- else:
- render_context.enableOversampling(False)
-
- render_context.setRenderWinSize(100)
- render_context.setImageType(format)
- render_context.enableExtensions(True)
- #render_context.enableSky() # No alpha needed.
- if alpha:
- render_context.alphaMode= 1
- render_context.enableRGBAColor()
- else:
- render_context.alphaMode= 0
- render_context.enableRGBColor()
-
- render_context.displayMode= 0 # fullscreen
-
- # New camera and object
- render_cam_data= Camera.New('ortho')
- render_cam_ob= Object.New('Camera')
- render_cam_ob.link(render_cam_data)
- render_scn.link(render_cam_ob)
- render_scn.objects.camera = render_cam_ob
-
- render_cam_data.type= 'ortho'
-
-
-
- # Position the camera
- if camera_matrix:
- render_cam_ob.setMatrix(camera_matrix)
- # We need to take into account the matrix scaling when setting the size
- # so we get the image bounds defined by the matrix
- # first get the x and y factors from the matrix.
- # To render the correct dimensions we must use the aspy and aspy to force the matrix scale to
- # override the aspect enforced by the width and weight.
- cent= Vector() * camera_matrix
- xvec= Vector(1,0,0) * camera_matrix
- yvec= Vector(0,1,0) * camera_matrix
- # zvec= Vector(0,0,1) * camera_matrix
- xlen = (cent-xvec).length # half height of the image
- ylen = (cent-yvec).length # half width of the image
- # zlen = (cent-zvec).length # dist to place the camera? - just use the loc for now.
-
-
- # less then 1.0 portrate, 1.0 or more is portrate
- asp_cam_mat= xlen/ylen # divide by zero? - possible but scripters fault.
- asp_image_res= float(width)/height
- #print 'asp quad', asp_cam_mat, 'asp_image', asp_image_res
- #print 'xylen', xlen, ylen, 'w/h', width, height
- # Setup the aspect
-
- if asp_cam_mat > asp_image_res:
- # camera is wider then image res.
- # to make the image wider, reduce the aspy
- asp_diff= asp_image_res/asp_cam_mat
- min_asp= asp_diff * 200
- #print 'X', min_asp
-
- elif asp_cam_mat < asp_image_res: # asp_cam_mat < asp_image_res
- # camera is narrower then image res
- # to make the image narrower, reduce the aspx
- asp_diff= asp_cam_mat/asp_image_res
- min_asp= asp_diff * 200
- #print 'Y', min_asp
- else:
- min_asp= 200
-
- # set the camera size
- if xlen > ylen:
- if asp_cam_mat > asp_image_res:
- render_context.aspectX= 200 # get the greatest range possible
- render_context.aspectY= min_asp # get the greatest range possible
- else:
- render_context.aspectY= 200 # get the greatest range possible
- render_context.aspectX= min_asp # get the greatest range possible
- #print "xlen bigger"
- render_cam_data.scale= xlen * 2
- elif xlen < ylen:# ylen is bigger
- if asp_cam_mat > asp_image_res:
- render_context.aspectX= 200 # get the greatest range possible
- render_context.aspectY= min_asp # get the greatest range possible
- else:
- render_context.aspectY= 200 # get the greatest range possible
- render_context.aspectX= min_asp # get the greatest range possible
- #print "ylen bigger"
- render_cam_data.scale= ylen *2
- else:
- # asppect 1:1
- #print 'NOLEN Bigger'
- render_cam_data.scale= xlen * 2
-
- #print xlen, ylen, 'xlen, ylen'
-
- else:
- if width > height:
- min_asp = int((float(height) / width) * 200)
- render_context.aspectX= min_asp
- render_context.aspectY= 200
- else:
- min_asp = int((float(width) / height) * 200)
- render_context.aspectX= 200
- render_context.aspectY= min_asp
-
-
- render_cam_data.scale= 1.0
- render_cam_ob.LocZ= 1.0
- render_cam_ob.LocX= 0.5
- render_cam_ob.LocY= 0.5
-
- Blender.Window.RedrawAll()
-
- render_context.render()
- render_context.saveRenderedImage(path)
- Render.CloseRenderWindow()
- #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND):
- # raise 'Error!!!'
-
- scn.makeCurrent()
- Scene.Unlink(render_scn)
-
- # NOW APPLY THE SAVED IMAGE TO THE FACES!
- #print PREF_IMAGE_PATH_EXPAND
- try:
- target_image= Image.Load(path_expand)
- return target_image
- except:
- raise 'Error: Could not render or load the image at path "%s"' % path_expand
- return
-
-
-
-#-----------------------------------------------------------------------------#
-# UV Baking functions, make a picture from mesh(es) uvs #
-#-----------------------------------------------------------------------------#
-
-def mesh2uv(me_s, PREF_SEL_FACES_ONLY=False):
- '''
- Converts a uv mapped mesh into a 2D Mesh from UV coords.
- returns a triple -
- (mesh2d, face_list, col_list)
- "mesh" is the new mesh and...
- "face_list" is the faces that were used to make the mesh,
- "material_list" is a list of materials used by each face
- These are in alligned with the meshes faces, so you can easerly copy data between them
-
- '''
- render_me= Blender.Mesh.New()
- render_me.verts.extend( [Vector(0,0,0),] ) # 0 vert uv bugm dummy vert
- face_list= []
- material_list= []
- for me in me_s:
- me_materials= me.materials
- if PREF_SEL_FACES_ONLY:
- me_faces= [f for f in me.faces if f.sel]
- else:
- me_faces= me.faces
-
- face_list.extend(me_faces)
-
- # Dittro
- if me_materials:
- material_list.extend([me_materials[f.mat] for f in me_faces])
- else:
- material_list.extend([None]*len(me_faces))
-
- # Now add the verts
- render_me.verts.extend( [ Vector(uv.x, uv.y, 0) for f in face_list for uv in f.uv ] )
-
- # Now add the faces
- tmp_faces= []
- vert_offset= 1
- for f in face_list:
- tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] )
- vert_offset+= len(f)
-
- render_me.faces.extend(tmp_faces)
- render_me.faceUV=1
- return render_me, face_list, material_list
-
-
-def uvmesh_apply_normals(render_me, face_list):
- '''Worldspace normals to vertex colors'''
- for i, f in enumerate(render_me.faces):
- face_orig= face_list[i]
- f_col= f.col
- for j, v in enumerate(face_orig):
- c= f_col[j]
- nx, ny, nz= v.no
- c.r= int((nx+1)*128)-1
- c.g= int((ny+1)*128)-1
- c.b= int((nz+1)*128)-1
-
-def uvmesh_apply_image(render_me, face_list):
- '''Copy the image and uvs from the original faces'''
- for i, f in enumerate(render_me.faces):
- f.uv= face_list[i].uv
- f.image= face_list[i].image
-
-
-def uvmesh_apply_vcol(render_me, face_list):
- '''Copy the vertex colors from the original faces'''
- for i, f in enumerate(render_me.faces):
- face_orig= face_list[i]
- f_col= f.col
- for j, c_orig in enumerate(face_orig.col):
- c= f_col[j]
- c.r= c_orig.r
- c.g= c_orig.g
- c.b= c_orig.b
-
-def uvmesh_apply_matcol(render_me, material_list):
- '''Get the vertex colors from the original materials'''
- for i, f in enumerate(render_me.faces):
- mat_orig= material_list[i]
- f_col= f.col
- if mat_orig:
- for c in f_col:
- c.r= int(mat_orig.R*255)
- c.g= int(mat_orig.G*255)
- c.b= int(mat_orig.B*255)
- else:
- for c in f_col:
- c.r= 255
- c.g= 255
- c.b= 255
-
-def uvmesh_apply_col(render_me, color):
- '''Get the vertex colors from the original materials'''
- r,g,b= color
- for i, f in enumerate(render_me.faces):
- f_col= f.col
- for c in f_col:
- c.r= r
- c.g= g
- c.b= b
-
-
-def vcol2image(me_s,\
- PREF_IMAGE_PATH,\
- PREF_IMAGE_SIZE,\
- PREF_IMAGE_BLEED,\
- PREF_IMAGE_SMOOTH,\
- PREF_IMAGE_WIRE,\
- PREF_IMAGE_WIRE_INVERT,\
- PREF_IMAGE_WIRE_UNDERLAY,\
- PREF_USE_IMAGE,\
- PREF_USE_VCOL,\
- PREF_USE_MATCOL,\
- PREF_USE_NORMAL,\
- PREF_USE_TEXTURE,\
- PREF_SEL_FACES_ONLY):
-
-
- def rnd_mat():
- render_mat= Blender.Material.New()
- mode= render_mat.mode
-
- # Dont use lights ever
- mode |= Blender.Material.Modes.SHADELESS
-
- if PREF_IMAGE_WIRE:
- # Set the wire color
- if PREF_IMAGE_WIRE_INVERT:
- render_mat.rgbCol= (1,1,1)
- else:
- render_mat.rgbCol= (0,0,0)
-
- mode |= Blender.Material.Modes.WIRE
- if PREF_USE_VCOL or PREF_USE_MATCOL or PREF_USE_NORMAL: # both vcol and material color use vertex cols to avoid the 16 max limit in materials
- mode |= Blender.Material.Modes.VCOL_PAINT
- if PREF_USE_IMAGE:
- mode |= Blender.Material.Modes.TEXFACE
-
- # Copy back the mode
- render_mat.mode |= mode
- return render_mat
-
-
- render_me, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY)
-
- # Normals exclude all others
- if PREF_USE_NORMAL:
- uvmesh_apply_normals(render_me, face_list)
- else:
- if PREF_USE_IMAGE:
- uvmesh_apply_image(render_me, face_list)
- uvmesh_apply_vcol(render_me, face_list)
-
- elif PREF_USE_VCOL:
- uvmesh_apply_vcol(render_me, face_list)
-
- elif PREF_USE_MATCOL:
- uvmesh_apply_matcol(render_me, material_list)
-
- elif PREF_USE_TEXTURE:
- # if we have more then 16 materials across all the mesh objects were stuffed :/
- # get unique materials
- tex_unique_materials= dict([(mat.name, mat) for mat in material_list]).values()[:16] # just incase we have more then 16
- tex_me= Blender.Mesh.New()
-
- # Backup the original shadless setting
- tex_unique_materials_shadeless= [ mat.mode & Blender.Material.Modes.SHADELESS for mat in tex_unique_materials ]
-
- # Turn shadeless on
- for mat in tex_unique_materials:
- mat.mode |= Blender.Material.Modes.SHADELESS
-
- # Assign materials
- render_me.materials= tex_unique_materials
-
-
-
- tex_material_indicies= dict([(mat.name, i) for i, mat in enumerate(tex_unique_materials)])
-
- tex_me.verts.extend([Vector(0,0,0),]) # dummy
- tex_me.verts.extend( [ Vector(v.co) for f in face_list for v in f ] )
-
- # Now add the faces
- tmp_faces= []
- vert_offset= 1
- for f in face_list:
- tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] )
- vert_offset+= len(f)
-
- tex_me.faces.extend(tmp_faces)
-
- # Now we have the faces, put materials and normal, uvs into the mesh
- if len(tex_me.faces) != len(face_list):
- # Should never happen
- raise "Error face length mismatch"
-
- # Copy data to the mesh that could be used as texture coords
- for i, tex_face in enumerate(tex_me.faces):
- orig_face= face_list[i]
-
- # Set the material index
- try:
- render_face.mat= tex_material_indicies[ material_list[i].name ]
- except:
- # more then 16 materials
- pass
-
-
- # set the uvs on the texmesh mesh
- tex_face.uv= orig_face.uv
-
- orig_face_v= orig_face.v
- # Set the normals
- for j, v in enumerate(tex_face):
- v.no= orig_face_v[j].no
-
- # Set the texmesh
- render_me.texMesh= tex_me
- # END TEXMESH
-
-
- # Handel adding objects
- render_ob= Blender.Object.New('Mesh')
- render_ob.link(render_me)
-
- if not PREF_USE_TEXTURE: # textures use the original materials
- render_me.materials= [rnd_mat()]
-
-
- obs= [render_ob]
-
-
- if PREF_IMAGE_WIRE_UNDERLAY:
- # Make another mesh with the material colors
- render_me_under, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY)
-
- uvmesh_apply_matcol(render_me_under, material_list)
-
- # Handel adding objects
- render_ob= Blender.Object.New('Mesh')
- render_ob.link(render_me_under)
- render_ob.LocZ= -0.01
-
- # Add material and disable wire
- mat= rnd_mat()
- mat.rgbCol= 1,1,1
- mat.alpha= 0.5
- mat.mode &= ~Blender.Material.Modes.WIRE
- mat.mode |= Blender.Material.Modes.VCOL_PAINT
-
- render_me_under.materials= [mat]
-
- obs.append(render_ob)
-
- elif PREF_IMAGE_BLEED and not PREF_IMAGE_WIRE:
- # EVIL BLEEDING CODE!! - Just do copys of the mesh and place behind. Crufty but better then many other methods I have seen. - Cam
- BLEED_PIXEL= 1.0/PREF_IMAGE_SIZE
- z_offset= 0.0
- for i in xrange(PREF_IMAGE_BLEED):
- for diag1, diag2 in ((-1,-1),(-1,1),(1,-1),(1,1), (1,0), (0,1), (-1,0), (0, -1)): # This line extends the object in 8 different directions, top avoid bleeding.
-
- render_ob= Blender.Object.New('Mesh')
- render_ob.link(render_me)
-
- render_ob.LocX= (i+1)*diag1*BLEED_PIXEL
- render_ob.LocY= (i+1)*diag2*BLEED_PIXEL
- render_ob.LocZ= -z_offset
-
- obs.append(render_ob)
- z_offset += 0.01
-
-
-
- image= imageFromObjectsOrtho(obs, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_IMAGE_SIZE, PREF_IMAGE_SMOOTH)
-
- # Clear from memory as best as we can
- render_me.verts= None
-
- if PREF_IMAGE_WIRE_UNDERLAY:
- render_me_under.verts= None
-
- if PREF_USE_TEXTURE:
- tex_me.verts= None
- # Restire Shadeless setting
- for i, mat in enumerate(tex_unique_materials):
- # we know there all on so turn it off of its not set
- if not tex_unique_materials_shadeless[i]:
- mat.mode &= ~Blender.Material.Modes.SHADELESS
-
- return image
-
-def bakeToPlane(sce, ob_from, width, height, bakemodes, axis='z', margin=0, depth=32):
- '''
- Bakes terrain onto a plane from one object
- sce - scene to bake with
- ob_from - mesh object
- width/height - image size
- bakemodes - list of baking modes to use, Blender.Scene.Render.BakeModes.NORMALS, Blender.Scene.Render.BakeModes.AO ... etc
- axis - axis to allign the plane to.
- margin - margin setting for baking.
- depth - bit depth for the images to bake into, (32 or 128 for floating point images)
- Example:
- import Blender
- from Blender import *
- import BPyRender
- sce = Scene.GetCurrent()
- ob = Object.Get('Plane')
- BPyRender.bakeToPlane(sce, ob, 512, 512, [Scene.Render.BakeModes.DISPLACEMENT, Scene.Render.BakeModes.NORMALS], 'z', 8 )
- '''
-
- # Backup bake settings
- rend = sce.render
- BACKUP_bakeDist = rend.bakeDist
- BACKUP_bakeBias = rend.bakeBias
- BACKUP_bakeMode = rend.bakeMode
- BACKUP_bakeClear = rend.bakeClear
- BACKUP_bakeMargin = rend.bakeMargin
- BACKUP_bakeToActive = rend.bakeToActive
- BACKUP_bakeNormalize = rend.bakeNormalize
-
- # Backup object selection
- BACKUP_obsel = list(sce.objects.selected)
- BACKUP_obact = sce.objects.active
-
- # New bake settings
- rend.bakeClear = True
- rend.bakeMargin = margin
- rend.bakeToActive = True
- rend.bakeNormalize = True
-
- # Assume a mesh
- me_from = ob_from.getData(mesh=1)
-
- xmin = ymin = zmin = 10000000000
- xmax = ymax = zmax =-10000000000
-
- # Dont trust bounding boxes :/
- #bounds = ob_from.boundingBox
- #for v in bounds:
- # x,y,z = tuple(v)
- mtx = ob_from.matrixWorld
- for v in me_from.verts:
- x,y,z = tuple(v.co*mtx)
-
- xmax = max(xmax, x)
- ymax = max(ymax, y)
- zmax = max(zmax, z)
-
- xmin = min(xmin, x)
- ymin = min(ymin, y)
- zmin = min(zmin, z)
-
- if axis=='x':
- xmed = (xmin+xmax)/2.0
- co1 = (xmed, ymin, zmin)
- co2 = (xmed, ymin, zmax)
- co3 = (xmed, ymax, zmax)
- co4 = (xmed, ymax, zmin)
- rend.bakeDist = ((xmax-xmin)/2.0) + 0.000001 # we need a euler value for this since it
- elif axis=='y':
- ymed = (ymin+ymax)/2.0
- co1 = (xmin, ymed, zmin)
- co2 = (xmin, ymed, zmax)
- co3 = (xmax, ymed, zmax)
- co4 = (xmax, ymed, zmin)
- rend.bakeDist = ((ymax-ymin)/2.0) + 0.000001
- elif axis=='z':
- zmed = (zmin+zmax)/2.0
- co1 = (xmin, ymin, zmed)
- co2 = (xmin, ymax, zmed)
- co3 = (xmax, ymax, zmed)
- co4 = (xmax, ymin, zmed)
- rend.bakeDist = ((zmax-zmin)/2.0) + 0.000001
- else:
- raise "invalid axis"
- me_plane = Blender.Mesh.New()
- ob_plane = Blender.Object.New('Mesh')
- ob_plane.link(me_plane)
- sce.objects.link(ob_plane)
- ob_plane.Layers = ob_from.Layers
-
- ob_from.sel = 1 # make active
- sce.objects.active = ob_plane
- ob_plane.sel = 1
-
- me_plane.verts.extend([co4, co3, co2, co1])
- me_plane.faces.extend([(0,1,2,3)])
- me_plane.faceUV = True
- me_plane_face = me_plane.faces[0]
- uvs = me_plane_face.uv
- uvs[0].x = 0.0; uvs[0].y = 0.0
- uvs[1].x = 0.0; uvs[1].y = 1.0
- uvs[2].x = 1.0; uvs[2].y = 1.0
- uvs[3].x = 1.0; uvs[3].y = 0.0
-
- images_return = []
-
- for mode in bakemodes:
- img = Blender.Image.New('bake', width, height, depth)
-
- me_plane_face.image = img
- rend.bakeMode = mode
- rend.bake()
- images_return.append( img )
-
- # Restore bake settings
- #'''
- rend.bakeDist = BACKUP_bakeDist
- rend.bakeBias = BACKUP_bakeBias
- rend.bakeMode = BACKUP_bakeMode
- rend.bakeClear = BACKUP_bakeClear
- rend.bakeMargin = BACKUP_bakeMargin
- rend.bakeToActive = BACKUP_bakeToActive
- rend.bakeNormalize = BACKUP_bakeNormalize
-
-
- # Restore obsel
- sce.objects.selected = BACKUP_obsel
- sce.objects.active = BACKUP_obact
-
- me_plane.verts = None
- sce.objects.unlink(ob_plane)
- #'''
-
- return images_return
-
diff --git a/release/scripts/bpymodules/BPySys.py b/release/scripts/bpymodules/BPySys.py
deleted file mode 100644
index a2d2120ebff..00000000000
--- a/release/scripts/bpymodules/BPySys.py
+++ /dev/null
@@ -1,74 +0,0 @@
-
-## This was used to make V, but faster not to do all that
-##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
-##v = range(255)
-##for c in valid: v.remove(ord(c))
-v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
-invalid = ''.join([chr(i) for i in v])
-## del v, c, i, valid
-del v, i
-
-def cleanName(name):
- for ch in invalid: name = name.replace(ch, '_')
- return name
-
-def caseInsensitivePath(path, RET_FOUND=False):
- '''
- Get a case insensitive path on a case sensitive system
-
- RET_FOUND is for internal use only, to avoid too many calls to os.path.exists
- # Example usage
- getCaseInsensitivePath('/hOmE/mE/sOmEpAtH.tXt')
- '''
- import os # todo, what happens with no os?
-
- if os==None:
- if RET_FOUND: ret = path, True
- else: ret = path
- return ret
-
- if path=='' or os.path.exists(path):
- if RET_FOUND: ret = path, True
- else: ret = path
- return ret
-
- f = os.path.basename(path) # f may be a directory or a file
- d = os.path.dirname(path)
-
- suffix = ''
- if not f: # dir ends with a slash?
- if len(d) < len(path):
- suffix = path[:len(path)-len(d)]
-
- f = os.path.basename(d)
- d = os.path.dirname(d)
-
- if not os.path.exists(d):
- d, found = caseInsensitivePath(d, True)
-
- if not found:
- if RET_FOUND: ret = path, False
- else: ret = path
- return ret
-
- # at this point, the directory exists but not the file
-
- try: # we are expecting 'd' to be a directory, but it could be a file
- files = os.listdir(d)
- except:
- if RET_FOUND: ret = path, False
- else: ret = path
-
- f_low = f.lower()
-
- try: f_nocase = [fl for fl in files if fl.lower() == f_low][0]
- except: f_nocase = None
-
- if f_nocase:
- if RET_FOUND: ret = os.path.join(d, f_nocase) + suffix, True
- else: ret = os.path.join(d, f_nocase) + suffix
- return ret
- else:
- if RET_FOUND: ret = path, False
- else: ret = path
- return ret # cant find the right one, just return the path as is. \ No newline at end of file
diff --git a/release/scripts/bpymodules/BPyTextPlugin.py b/release/scripts/bpymodules/BPyTextPlugin.py
deleted file mode 100644
index cd5a085de37..00000000000
--- a/release/scripts/bpymodules/BPyTextPlugin.py
+++ /dev/null
@@ -1,814 +0,0 @@
-"""The BPyTextPlugin Module
-
-Use get_cached_descriptor(txt) to retrieve information about the script held in
-the txt Text object.
-
-Use print_cache_for(txt) to print the information to the console.
-
-Use line, cursor = current_line(txt) to get the logical line and cursor position
-
-Use get_targets(line, cursor) to find out what precedes the cursor:
- aaa.bbb.cc|c.ddd -> ['aaa', 'bbb', 'cc']
-
-Use resolve_targets(txt, targets) to turn a target list into a usable object if
-one is found to match.
-"""
-
-import bpy, sys, os
-import __builtin__, tokenize
-from Blender.sys import time
-from tokenize import generate_tokens, TokenError, \
- COMMENT, DEDENT, INDENT, NAME, NEWLINE, NL, STRING, NUMBER
-
-class Definition:
- """Describes a definition or defined object through its name, line number
- and docstring. This is the base class for definition based descriptors.
- """
-
- def __init__(self, name, lineno, doc=''):
- self.name = name
- self.lineno = lineno
- self.doc = doc
-
-class ScriptDesc:
- """Describes a script through lists of further descriptor objects (classes,
- defs, vars) and dictionaries to built-in types (imports). If a script has
- not been fully parsed, its incomplete flag will be set. The time of the last
- parse is held by the time field and the name of the text object from which
- it was parsed, the name field.
- """
-
- def __init__(self, name, imports, classes, defs, vars, incomplete=False):
- self.name = name
- self.imports = imports
- self.classes = classes
- self.defs = defs
- self.vars = vars
- self.incomplete = incomplete
- self.parse_due = 0
-
- def set_delay(self, delay):
- self.parse_due = time() + delay
-
-class ClassDesc(Definition):
- """Describes a class through lists of further descriptor objects (defs and
- vars). The name of the class is held by the name field and the line on
- which it is defined is held in lineno.
- """
-
- def __init__(self, name, parents, defs, vars, lineno, doc=''):
- Definition.__init__(self, name, lineno, doc)
- self.parents = parents
- self.defs = defs
- self.vars = vars
-
-class FunctionDesc(Definition):
- """Describes a function through its name and list of parameters (name,
- params) and the line on which it is defined (lineno).
- """
-
- def __init__(self, name, params, lineno, doc=''):
- Definition.__init__(self, name, lineno, doc)
- self.params = params
-
-class VarDesc(Definition):
- """Describes a variable through its name and type (if ascertainable) and the
- line on which it is defined (lineno). If no type can be determined, type
- will equal None.
- """
-
- def __init__(self, name, type, lineno):
- Definition.__init__(self, name, lineno)
- self.type = type # None for unknown (supports: dict/list/str)
-
-# Context types
-CTX_UNSET = -1
-CTX_NORMAL = 0
-CTX_SINGLE_QUOTE = 1
-CTX_DOUBLE_QUOTE = 2
-CTX_COMMENT = 3
-
-# Python keywords
-KEYWORDS = ['and', 'del', 'from', 'not', 'while', 'as', 'elif', 'global',
- 'or', 'with', 'assert', 'else', 'if', 'pass', 'yield',
- 'break', 'except', 'import', 'print', 'class', 'exec', 'in',
- 'raise', 'continue', 'finally', 'is', 'return', 'def', 'for',
- 'lambda', 'try' ]
-
-# Module file extensions
-MODULE_EXTS = ['.py', '.pyc', '.pyo', '.pyw', '.pyd']
-
-ModuleType = type(__builtin__)
-NoneScriptDesc = ScriptDesc('', dict(), dict(), dict(), dict(), True)
-
-_modules = {}
-_modules_updated = 0
-_parse_cache = dict()
-
-def _load_module_names():
- """Searches the sys.path for module files and lists them, along with
- sys.builtin_module_names, in the global dict _modules.
- """
-
- global _modules
-
- for n in sys.builtin_module_names:
- _modules[n] = None
- for p in sys.path:
- if p == '': p = os.curdir
- if not os.path.isdir(p): continue
- for f in os.listdir(p):
- for ext in MODULE_EXTS:
- if f.endswith(ext):
- _modules[f[:-len(ext)]] = None
- break
-
-_load_module_names()
-
-def _trim_doc(doc):
- """Trims the quotes from a quoted STRING token (eg. "'''text'''" -> "text")
- """
-
- l = len(doc)
- i = 0
- while i < l/2 and (doc[i] == "'" or doc[i] == '"'):
- i += 1
- return doc[i:-i]
-
-def resolve_targets(txt, targets):
- """Attempts to return a useful object for the locally or externally defined
- entity described by targets. If the object is local (defined in txt), a
- Definition instance is returned. If the object is external (imported or
- built in), the object itself is returned. If no object can be found, None is
- returned.
- """
-
- count = len(targets)
- if count==0: return None
-
- obj = None
- local = None
- i = 1
-
- desc = get_cached_descriptor(txt)
- b = targets[0].find('(')
- if b==-1: b = None # Trick to let us use [:b] and get the whole string
-
- if desc.classes.has_key(targets[0][:b]):
- local = desc.classes[targets[0][:b]]
- elif desc.defs.has_key(targets[0]):
- local = desc.defs[targets[0]]
- elif desc.vars.has_key(targets[0]):
- obj = desc.vars[targets[0]].type
-
- if local:
- while i < count:
- b = targets[i].find('(')
- if b==-1: b = None
- if hasattr(local, 'classes') and local.classes.has_key(targets[i][:b]):
- local = local.classes[targets[i][:b]]
- elif hasattr(local, 'defs') and local.defs.has_key(targets[i]):
- local = local.defs[targets[i]]
- elif hasattr(local, 'vars') and local.vars.has_key(targets[i]):
- obj = local.vars[targets[i]].type
- local = None
- i += 1
- break
- else:
- local = None
- break
- i += 1
-
- if local: return local
-
- if not obj:
- if desc.imports.has_key(targets[0]):
- obj = desc.imports[targets[0]]
- else:
- builtins = get_builtins()
- if builtins.has_key(targets[0]):
- obj = builtins[targets[0]]
-
- while obj and i < count:
- if hasattr(obj, targets[i]):
- obj = getattr(obj, targets[i])
- else:
- obj = None
- break
- i += 1
-
- return obj
-
-def get_cached_descriptor(txt, force_parse=0):
- """Returns the cached ScriptDesc for the specified Text object 'txt'. If the
- script has not been parsed in the last 'period' seconds it will be reparsed
- to obtain this descriptor.
-
- Specifying TP_AUTO for the period (default) will choose a period based on the
- size of the Text object. Larger texts are parsed less often.
- """
-
- global _parse_cache
-
- parse = True
- key = hash(txt)
- if not force_parse and _parse_cache.has_key(key):
- desc = _parse_cache[key]
- if desc.parse_due > time():
- parse = desc.incomplete
-
- if parse:
- desc = parse_text(txt)
-
- return desc
-
-def parse_text(txt):
- """Parses an entire script's text and returns a ScriptDesc instance
- containing information about the script.
-
- If the text is not a valid Python script (for example if brackets are left
- open), parsing may fail to complete. However, if this occurs, no exception
- is thrown. Instead the returned ScriptDesc instance will have its incomplete
- flag set and information processed up to this point will still be accessible.
- """
-
- start_time = time()
- txt.reset()
- tokens = generate_tokens(txt.readline) # Throws TokenError
-
- curl, cursor = txt.getCursorPos()
- linen = curl + 1 # Token line numbers are one-based
-
- imports = dict()
- imp_step = 0
-
- classes = dict()
- cls_step = 0
-
- defs = dict()
- def_step = 0
-
- vars = dict()
- var1_step = 0
- var2_step = 0
- var3_step = 0
- var_accum = dict()
- var_forflag = False
-
- indent = 0
- prev_type = -1
- prev_text = ''
- incomplete = False
-
- while True:
- try:
- type, text, start, end, line = tokens.next()
- except StopIteration:
- break
- except (TokenError, IndentationError):
- incomplete = True
- break
-
- # Skip all comments and line joining characters
- if type == COMMENT or type == NL:
- continue
-
- #################
- ## Indentation ##
- #################
-
- if type == INDENT:
- indent += 1
- elif type == DEDENT:
- indent -= 1
-
- #########################
- ## Module importing... ##
- #########################
-
- imp_store = False
-
- # Default, look for 'from' or 'import' to start
- if imp_step == 0:
- if text == 'from':
- imp_tmp = []
- imp_step = 1
- elif text == 'import':
- imp_from = None
- imp_tmp = []
- imp_step = 2
-
- # Found a 'from', create imp_from in form '???.???...'
- elif imp_step == 1:
- if text == 'import':
- imp_from = '.'.join(imp_tmp)
- imp_tmp = []
- imp_step = 2
- elif type == NAME:
- imp_tmp.append(text)
- elif text != '.':
- imp_step = 0 # Invalid syntax
-
- # Found 'import', imp_from is populated or None, create imp_name
- elif imp_step == 2:
- if text == 'as':
- imp_name = '.'.join(imp_tmp)
- imp_step = 3
- elif type == NAME or text == '*':
- imp_tmp.append(text)
- elif text != '.':
- imp_name = '.'.join(imp_tmp)
- imp_symb = imp_name
- imp_store = True
-
- # Found 'as', change imp_symb to this value and go back to step 2
- elif imp_step == 3:
- if type == NAME:
- imp_symb = text
- else:
- imp_store = True
-
- # Both imp_name and imp_symb have now been populated so we can import
- if imp_store:
-
- # Handle special case of 'import *'
- if imp_name == '*':
- parent = get_module(imp_from)
- imports.update(parent.__dict__)
-
- else:
- # Try importing the name as a module
- try:
- if imp_from:
- module = get_module(imp_from +'.'+ imp_name)
- else:
- module = get_module(imp_name)
- except (ImportError, ValueError, AttributeError, TypeError):
- # Try importing name as an attribute of the parent
- try:
- module = __import__(imp_from, globals(), locals(), [imp_name])
- imports[imp_symb] = getattr(module, imp_name)
- except (ImportError, ValueError, AttributeError, TypeError):
- pass
- else:
- imports[imp_symb] = module
-
- # More to import from the same module?
- if text == ',':
- imp_tmp = []
- imp_step = 2
- else:
- imp_step = 0
-
- ###################
- ## Class parsing ##
- ###################
-
- # If we are inside a class then def and variable parsing should be done
- # for the class. Otherwise the definitions are considered global
-
- # Look for 'class'
- if cls_step == 0:
- if text == 'class':
- cls_name = None
- cls_lineno = start[0]
- cls_indent = indent
- cls_step = 1
-
- # Found 'class', look for cls_name followed by '(' parents ')'
- elif cls_step == 1:
- if not cls_name:
- if type == NAME:
- cls_name = text
- cls_sline = False
- cls_parents = dict()
- cls_defs = dict()
- cls_vars = dict()
- elif type == NAME:
- if classes.has_key(text):
- parent = classes[text]
- cls_parents[text] = parent
- cls_defs.update(parent.defs)
- cls_vars.update(parent.vars)
- elif text == ':':
- cls_step = 2
-
- # Found 'class' name ... ':', now check if it's a single line statement
- elif cls_step == 2:
- if type == NEWLINE:
- cls_sline = False
- else:
- cls_sline = True
- cls_doc = ''
- cls_step = 3
-
- elif cls_step == 3:
- if not cls_doc and type == STRING:
- cls_doc = _trim_doc(text)
- if cls_sline:
- if type == NEWLINE:
- classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc)
- cls_step = 0
- else:
- if type == DEDENT and indent <= cls_indent:
- classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc)
- cls_step = 0
-
- #################
- ## Def parsing ##
- #################
-
- # Look for 'def'
- if def_step == 0:
- if text == 'def':
- def_name = None
- def_lineno = start[0]
- def_step = 1
-
- # Found 'def', look for def_name followed by '('
- elif def_step == 1:
- if type == NAME:
- def_name = text
- def_params = []
- elif def_name and text == '(':
- def_step = 2
-
- # Found 'def' name '(', now identify the parameters upto ')'
- # TODO: Handle ellipsis '...'
- elif def_step == 2:
- if type == NAME:
- def_params.append(text)
- elif text == ':':
- def_step = 3
-
- # Found 'def' ... ':', now check if it's a single line statement
- elif def_step == 3:
- if type == NEWLINE:
- def_sline = False
- else:
- def_sline = True
- def_doc = ''
- def_step = 4
-
- elif def_step == 4:
- if type == STRING:
- def_doc = _trim_doc(text)
- newdef = None
- if def_sline:
- if type == NEWLINE:
- newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc)
- else:
- if type == NAME:
- newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc)
- if newdef:
- if cls_step > 0: # Parsing a class
- cls_defs[def_name] = newdef
- else:
- defs[def_name] = newdef
- def_step = 0
-
- ##########################
- ## Variable assignation ##
- ##########################
-
- if cls_step > 0: # Parsing a class
- # Look for 'self.???'
- if var1_step == 0:
- if text == 'self':
- var1_step = 1
- elif var1_step == 1:
- if text == '.':
- var_name = None
- var1_step = 2
- else:
- var1_step = 0
- elif var1_step == 2:
- if type == NAME:
- var_name = text
- if cls_vars.has_key(var_name):
- var_step = 0
- else:
- var1_step = 3
- elif var1_step == 3:
- if text == '=':
- var1_step = 4
- elif text != ',':
- var1_step = 0
- elif var1_step == 4:
- var_type = None
- if type == NUMBER:
- close = end[1]
- if text.find('.') != -1: var_type = float
- else: var_type = int
- elif type == STRING:
- close = end[1]
- var_type = str
- elif text == '[':
- close = line.find(']', end[1])
- var_type = list
- elif text == '(':
- close = line.find(')', end[1])
- var_type = tuple
- elif text == '{':
- close = line.find('}', end[1])
- var_type = dict
- elif text == 'dict':
- close = line.find(')', end[1])
- var_type = dict
- if var_type and close+1 < len(line):
- if line[close+1] != ' ' and line[close+1] != '\t':
- var_type = None
- cls_vars[var_name] = VarDesc(var_name, var_type, start[0])
- var1_step = 0
-
- elif def_step > 0: # Parsing a def
- # Look for 'global ???[,???]'
- if var2_step == 0:
- if text == 'global':
- var2_step = 1
- elif var2_step == 1:
- if type == NAME:
- if not vars.has_key(text):
- vars[text] = VarDesc(text, None, start[0])
- elif text != ',' and type != NL:
- var2_step == 0
-
- else: # In global scope
- if var3_step == 0:
- # Look for names
- if text == 'for':
- var_accum = dict()
- var_forflag = True
- elif text == '=' or (var_forflag and text == 'in'):
- var_forflag = False
- var3_step = 1
- elif type == NAME:
- if prev_text != '.' and not vars.has_key(text):
- var_accum[text] = VarDesc(text, None, start[0])
- elif not text in [',', '(', ')', '[', ']']:
- var_accum = dict()
- var_forflag = False
- elif var3_step == 1:
- if len(var_accum) != 1:
- var_type = None
- vars.update(var_accum)
- else:
- var_name = var_accum.keys()[0]
- var_type = None
- if type == NUMBER:
- if text.find('.') != -1: var_type = float
- else: var_type = int
- elif type == STRING: var_type = str
- elif text == '[': var_type = list
- elif text == '(': var_type = tuple
- elif text == '{': var_type = dict
- vars[var_name] = VarDesc(var_name, var_type, start[0])
- var3_step = 0
-
- #######################
- ## General utilities ##
- #######################
-
- prev_type = type
- prev_text = text
-
- desc = ScriptDesc(txt.name, imports, classes, defs, vars, incomplete)
- desc.set_delay(10 * (time()-start_time) + 0.05)
-
- global _parse_cache
- _parse_cache[hash(txt)] = desc
- return desc
-
-def get_modules(since=1):
- """Returns the set of built-in modules and any modules that have been
- imported into the system upto 'since' seconds ago.
- """
-
- global _modules, _modules_updated
-
- t = time()
- if _modules_updated < t - since:
- _modules.update(sys.modules)
- _modules_updated = t
- return _modules.keys()
-
-def suggest_cmp(x, y):
- """Use this method when sorting a list of suggestions.
- """
-
- return cmp(x[0].upper(), y[0].upper())
-
-def get_module(name):
- """Returns the module specified by its name. The module itself is imported
- by this method and, as such, any initialization code will be executed.
- """
-
- mod = __import__(name)
- components = name.split('.')
- for comp in components[1:]:
- mod = getattr(mod, comp)
- return mod
-
-def type_char(v):
- """Returns the character used to signify the type of a variable. Use this
- method to identify the type character for an item in a suggestion list.
-
- The following values are returned:
- 'm' if the parameter is a module
- 'f' if the parameter is callable
- 'v' if the parameter is variable or otherwise indeterminable
-
- """
-
- if isinstance(v, ModuleType):
- return 'm'
- elif callable(v):
- return 'f'
- else:
- return 'v'
-
-def get_context(txt):
- """Establishes the context of the cursor in the given Blender Text object
-
- Returns one of:
- CTX_NORMAL - Cursor is in a normal context
- CTX_SINGLE_QUOTE - Cursor is inside a single quoted string
- CTX_DOUBLE_QUOTE - Cursor is inside a double quoted string
- CTX_COMMENT - Cursor is inside a comment
-
- """
-
- l, cursor = txt.getCursorPos()
- lines = txt.asLines(0, l+1)
-
- # FIXME: This method is too slow in large files for it to be called as often
- # as it is. So for lines below the 1000th line we do this... (quorn)
- if l > 1000: return CTX_NORMAL
-
- # Detect context (in string or comment)
- in_str = CTX_NORMAL
- for line in lines:
- if l == 0:
- end = cursor
- else:
- end = len(line)
- l -= 1
-
- # Comments end at new lines
- if in_str == CTX_COMMENT:
- in_str = CTX_NORMAL
-
- for i in range(end):
- if in_str == 0:
- if line[i] == "'": in_str = CTX_SINGLE_QUOTE
- elif line[i] == '"': in_str = CTX_DOUBLE_QUOTE
- elif line[i] == '#': in_str = CTX_COMMENT
- else:
- if in_str == CTX_SINGLE_QUOTE:
- if line[i] == "'":
- in_str = CTX_NORMAL
- # In again if ' escaped, out again if \ escaped, and so on
- for a in range(i-1, -1, -1):
- if line[a] == '\\': in_str = 1-in_str
- else: break
- elif in_str == CTX_DOUBLE_QUOTE:
- if line[i] == '"':
- in_str = CTX_NORMAL
- # In again if " escaped, out again if \ escaped, and so on
- for a in range(i-1, -1, -1):
- if line[i-a] == '\\': in_str = 2-in_str
- else: break
-
- return in_str
-
-def current_line(txt):
- """Extracts the Python script line at the cursor in the Blender Text object
- provided and cursor position within this line as the tuple pair (line,
- cursor).
- """
-
- lineindex, cursor = txt.getCursorPos()
- lines = txt.asLines()
- line = lines[lineindex]
-
- # Join previous lines to this line if spanning
- i = lineindex - 1
- while i > 0:
- earlier = lines[i].rstrip()
- if earlier.endswith('\\'):
- line = earlier[:-1] + ' ' + line
- cursor += len(earlier)
- i -= 1
-
- # Join later lines while there is an explicit joining character
- i = lineindex
- while i < len(lines)-1 and lines[i].rstrip().endswith('\\'):
- later = lines[i+1].strip()
- line = line + ' ' + later[:-1]
- i += 1
-
- return line, cursor
-
-def get_targets(line, cursor):
- """Parses a period separated string of valid names preceding the cursor and
- returns them as a list in the same order.
- """
-
- brk = 0
- targets = []
- j = cursor
- i = j-1
- while i >= 0:
- if line[i] == ')': brk += 1
- elif brk:
- if line[i] == '(': brk -= 1
- else:
- if line[i] == '.':
- targets.insert(0, line[i+1:j]); j=i
- elif not (line[i].isalnum() or line[i] == '_' or line[i] == '.'):
- break
- i -= 1
- targets.insert(0, line[i+1:j])
- return targets
-
-def get_defs(txt):
- """Returns a dictionary which maps definition names in the source code to
- a list of their parameter names.
-
- The line 'def doit(one, two, three): print one' for example, results in the
- mapping 'doit' : [ 'one', 'two', 'three' ]
- """
-
- return get_cached_descriptor(txt).defs
-
-def get_vars(txt):
- """Returns a dictionary of variable names found in the specified Text
- object. This method locates all names followed directly by an equal sign:
- 'a = ???' or indirectly as part of a tuple/list assignment or inside a
- 'for ??? in ???:' block.
- """
-
- return get_cached_descriptor(txt).vars
-
-def get_imports(txt):
- """Returns a dictionary which maps symbol names in the source code to their
- respective modules.
-
- The line 'from Blender import Text as BText' for example, results in the
- mapping 'BText' : <module 'Blender.Text' (built-in)>
-
- Note that this method imports the modules to provide this mapping as as such
- will execute any initilization code found within.
- """
-
- return get_cached_descriptor(txt).imports
-
-def get_builtins():
- """Returns a dictionary of built-in modules, functions and variables."""
-
- return __builtin__.__dict__
-
-
-#################################
-## Debugging utility functions ##
-#################################
-
-def print_cache_for(txt, period=sys.maxint):
- """Prints out the data cached for a given Text object. If no period is
- given the text will not be reparsed and the cached version will be returned.
- Otherwise if the period has expired the text will be reparsed.
- """
-
- desc = get_cached_descriptor(txt, period)
- print '================================================'
- print 'Name:', desc.name, '('+str(hash(txt))+')'
- print '------------------------------------------------'
- print 'Defs:'
- for name, ddesc in desc.defs.items():
- print ' ', name, ddesc.params, ddesc.lineno
- print ' ', ddesc.doc
- print '------------------------------------------------'
- print 'Vars:'
- for name, vdesc in desc.vars.items():
- print ' ', name, vdesc.type, vdesc.lineno
- print '------------------------------------------------'
- print 'Imports:'
- for name, item in desc.imports.items():
- print ' ', name.ljust(15), item
- print '------------------------------------------------'
- print 'Classes:'
- for clsnme, clsdsc in desc.classes.items():
- print ' *********************************'
- print ' Name:', clsnme
- print ' ', clsdsc.doc
- print ' ---------------------------------'
- print ' Defs:'
- for name, ddesc in clsdsc.defs.items():
- print ' ', name, ddesc.params, ddesc.lineno
- print ' ', ddesc.doc
- print ' ---------------------------------'
- print ' Vars:'
- for name, vdesc in clsdsc.vars.items():
- print ' ', name, vdesc.type, vdesc.lineno
- print ' *********************************'
- print '================================================'
diff --git a/release/scripts/bpymodules/BPyWindow.py b/release/scripts/bpymodules/BPyWindow.py
deleted file mode 100644
index d3fd4fa88b5..00000000000
--- a/release/scripts/bpymodules/BPyWindow.py
+++ /dev/null
@@ -1,206 +0,0 @@
-import Blender
-from Blender import Mathutils, Window, Scene, Draw, Mesh
-from Blender.Mathutils import Matrix, Vector, Intersect
-
-# DESCRIPTION:
-# screen_x, screen_y the origin point of the pick ray
-# it is either the mouse location
-# localMatrix is used if you want to have the returned values in an objects localspace.
-# this is usefull when dealing with an objects data such as verts.
-# or if useMid is true, the midpoint of the current 3dview
-# returns
-# Origin - the origin point of the pick ray
-# Direction - the direction vector of the pick ray
-# in global coordinates
-epsilon = 1e-3 # just a small value to account for floating point errors
-
-def mouseViewRay(screen_x, screen_y, localMatrix=None, useMid = False):
-
- # Constant function variables
- p = mouseViewRay.p
- d = mouseViewRay.d
-
- for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example)
- win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices']
- # calculate a few geometric extents for this window
-
- win_mid_x = (win_max_x + win_min_x + 1.0) * 0.5
- win_mid_y = (win_max_y + win_min_y + 1.0) * 0.5
- win_size_x = (win_max_x - win_min_x + 1.0) * 0.5
- win_size_y = (win_max_y - win_min_y + 1.0) * 0.5
-
- #useMid is for projecting the coordinates when we subdivide the screen into bins
- if useMid: # == True
- screen_x = win_mid_x
- screen_y = win_mid_y
-
- # if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one...
- if (win_max_x > screen_x > win_min_x) and ( win_max_y > screen_y > win_min_y):
- # first we handle all pending events for this window (otherwise the matrices might come out wrong)
- Window.QHandle(win3d['id'])
-
- # now we get a few matrices for our window...
- # sorry - i cannot explain here what they all do
- # - if you're not familiar with all those matrices take a look at an introduction to OpenGL...
- pm = Window.GetPerspMatrix() # the prespective matrix
- pmi = Matrix(pm); pmi.invert() # the inverted perspective matrix
-
- if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon):
- # pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5)
- hms = mouseViewRay.hms
- ortho_d = mouseViewRay.ortho_d
-
- # ortho mode: is a bit strange - actually there's no definite location of the camera ...
- # but the camera could be displaced anywhere along the viewing direction.
-
- ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector()
- ortho_d.w = 0
-
- # all rays are parallel in ortho mode - so the direction vector is simply the viewing direction
- #hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0
- hms[:] = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0
-
- # these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1
- p=(hms*pmi) + (1000*ortho_d)
- p.resize3D()
- d[:] = ortho_d[:3]
-
-
- # Finally we shift the position infinitely far away in
- # the viewing direction to make sure the camera if outside the scene
- # (this is actually a hack because this function
- # is used in sculpt_mesh to initialize backface culling...)
- else:
- # PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location
- vmi = Matrix(Window.GetViewMatrix()); vmi.invert() # the inverse viewing matrix
- fp = mouseViewRay.fp
-
- dx = pm[3][3] * (((screen_x-win_min_x)/win_size_x)-1.0) - pm[3][0]
- dy = pm[3][3] * (((screen_y-win_min_y)/win_size_y)-1.0) - pm[3][1]
-
- fp[:] = \
- pmi[0][0]*dx+pmi[1][0]*dy,\
- pmi[0][1]*dx+pmi[1][1]*dy,\
- pmi[0][2]*dx+pmi[1][2]*dy
-
- # fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y)
- #- figuring out how to calculate this took me quite some time.
- # The calculation of dxy and fp are simplified versions of my original code
- #- so it's almost impossible to explain what's going on geometrically... sorry
-
- p[:] = vmi[3][:3]
-
- # the camera's location in global 3dcoords can be read directly from the inverted viewmatrix
- #d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp))
- d[:] = p.x-fp.x, p.y-fp.y, p.z-fp.z
-
- #print 'd', d, 'p', p, 'fp', fp
-
-
- # the direction vector is simply the difference vector from the virtual camera's position
- #to the unprojected (screenspace) point fp
-
- # Do we want to return a direction in object's localspace?
-
- if localMatrix:
- localInvMatrix = Matrix(localMatrix)
- localInvMatrix.invert()
- localInvMatrix_notrans = localInvMatrix.rotationPart()
- p = p * localInvMatrix
- d = d * localInvMatrix # normalize_v3
-
- # remove the translation from d
- d.x -= localInvMatrix[3][0]
- d.y -= localInvMatrix[3][1]
- d.z -= localInvMatrix[3][2]
-
-
- d.normalize()
- '''
- # Debugging
- me = Blender.Mesh.New()
- me.verts.extend([p[0:3]])
- me.verts.extend([(p-d)[0:3]])
- me.edges.extend([0,1])
- ob = Blender.Scene.GetCurrent().objects.new(me)
- '''
- return True, p, d # Origin, Direction
-
- # Mouse is not in any view, return None.
- return False, None, None
-
-# Constant function variables
-mouseViewRay.d = Vector(0,0,0) # Perspective, 3d
-mouseViewRay.p = Vector(0,0,0)
-mouseViewRay.fp = Vector(0,0,0)
-
-mouseViewRay.hms = Vector(0,0,0,0) # ortho only 4d
-mouseViewRay.ortho_d = Vector(0,0,0,0) # ortho only 4d
-
-
-LMB= Window.MButs['L']
-def mouseup():
- # Loop until click
- mouse_buttons = Window.GetMouseButtons()
- while not mouse_buttons & LMB:
- Blender.sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
- while mouse_buttons & LMB:
- Blender.sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
-
-
-if __name__=='__main__':
- mouseup()
- x,y= Window.GetMouseCoords()
- isect, point, dir= mouseViewRay(x,y)
- if isect:
- scn= Blender.Scene.GetCurrent()
- me = Blender.Mesh.New()
- ob= Blender.Object.New('Mesh')
- ob.link(me)
- scn.link(ob)
- ob.sel= 1
- me.verts.extend([point, dir])
- me.verts[0].sel= 1
-
- print isect, point, dir
-
-
-
-def spaceRect():
- '''
- Returns the space rect
- xmin,ymin,width,height
- '''
-
- __UI_RECT__ = Blender.BGL.Buffer(Blender.BGL.GL_FLOAT, 4)
- Blender.BGL.glGetFloatv(Blender.BGL.GL_SCISSOR_BOX, __UI_RECT__)
- __UI_RECT__ = __UI_RECT__.list
- __UI_RECT__ = int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2])-1, int(__UI_RECT__[3])
-
- return __UI_RECT__
-
-def mouseRelativeLoc2d(__UI_RECT__= None):
- if not __UI_RECT__:
- __UI_RECT__ = spaceRect()
-
- mco = Window.GetMouseCoords()
- if mco[0] > __UI_RECT__[0] and\
- mco[1] > __UI_RECT__[1] and\
- mco[0] < __UI_RECT__[0] + __UI_RECT__[2] and\
- mco[1] < __UI_RECT__[1] + __UI_RECT__[3]:
-
- return (mco[0] - __UI_RECT__[0], mco[1] - __UI_RECT__[1])
-
- else:
- return None
-
-
-
-
-
-
-
-
- \ No newline at end of file
diff --git a/release/scripts/bpymodules/blend2renderinfo.py b/release/scripts/bpymodules/blend2renderinfo.py
deleted file mode 100644
index 1b9dec58d55..00000000000
--- a/release/scripts/bpymodules/blend2renderinfo.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import struct
-
-# In Blender, selecting scenes in the databrowser (shift+f4) will tag for rendering.
-
-# This struct wont change according to ton.
-# Note that the size differs on 32/64bit
-'''
-typedef struct BHead {
- int code, len;
- void *old;
- int SDNAnr, nr;
-} BHead;
-'''
-
-
-def read_blend_rend_chunk(path):
- file = open(path, 'rb')
-
- if file.read(len('BLENDER')) != 'BLENDER':
- return []
-
- #
- if file.read(1) == '-':
- is64bit = True
- else: # '_'
- is64bit = False
-
- if file.read(1) == 'V':
- isBigEndian = True # ppc
- else: # 'V'
- isBigEndian = False # x86
-
-
- # Now read the bhead chunk!!!
- file.read(3) # skip the version
-
- scenes = []
-
- while file.read(4) == 'REND':
-
- if is64bit: sizeof_bhead = sizeof_bhead_left = 24 # 64bit
- else: sizeof_bhead = sizeof_bhead_left = 20 # 32bit
-
- sizeof_bhead_left -= 4
-
- if isBigEndian: rend_length = struct.unpack('>i', file.read(4))[0]
- else: rend_length = struct.unpack('<i', file.read(4))[0]
-
- sizeof_bhead_left -= 4
-
- # We dont care about the rest of the bhead struct
- file.read(sizeof_bhead_left)
-
- # Now we want the scene name, start and end frame. this is 32bites long
-
- if isBigEndian: start_frame, end_frame = struct.unpack('>2i', file.read(8))
- else: start_frame, end_frame = struct.unpack('<2i', file.read(8))
-
- scene_name = file.read(24)
- scene_name = scene_name[ : scene_name.index('\0') ]
-
- scenes.append( (start_frame, end_frame, scene_name) )
- return scenes
-
-def main():
- import sys
- for arg in sys.argv[1:]:
- if arg.lower().endswith('.blend'):
- print read_blend_rend_chunk(arg)
-
-if __name__ == '__main__':
- main()
-
diff --git a/release/scripts/bpymodules/defaultdoodads.py b/release/scripts/bpymodules/defaultdoodads.py
deleted file mode 100644
index 987b8b8ae71..00000000000
--- a/release/scripts/bpymodules/defaultdoodads.py
+++ /dev/null
@@ -1,941 +0,0 @@
-# Default Doodad Set for Discombobulator
-# by Evan J. Rosky, 2005
-# GPL- http://www.gnu.org/copyleft/gpl.html
-#
-# $Id$
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2005: Evan J. Rosky
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-#Run discombobulator.py, not this.
-
-import Blender
-from Blender import NMesh,Object,Material
-from Blender.NMesh import Vert,Face
-from Blender.Mathutils import *
-
-import BPyMathutils
-from BPyMathutils import genrand
-a = BPyMathutils.sgenrand(4859)
-
-#Create random numbers
-def randnum(low,high):
- num = genrand()
- num = num*(high-low)
- num = num+low
- return num
-
-face = Face()
-xmin = Vector([0,0,0])
-xmax = Vector([0,0,0])
-ymin = Vector([0,0,0])
-ymax = Vector([0,0,0])
-mxmin = Vector([0,0,0])
-mxmax = Vector([0,0,0])
-mymin = Vector([0,0,0])
-mymax = Vector([0,0,0])
-doodadCenter = Vector([0,0,0])
-orientation = 0
-center = Vector([0,0,0])
-tosel = 0
-seltopsonly = 0
-tempx = []
-doodadMesh = NMesh.GetRaw()
-
-global materialArray
-global reassignMats
-global thereAreMats
-global currmat
-global doodSideMat
-global doodTopMat
-
-#face is the face to add the doodad to.
-#sizeX and sizeY are values from 0.0 to 1.0 that represents a percentage the face that is covered by the doodad.
-#height is how tall the doodad is.
-
-def settings(seltops,matArr,reasMats,therMats,sidemat,topmat):
- global seltopsonly
- global materialArray
- global reassignMats
- global thereAreMats
- global currmat
- global doodSideMat
- global doodTopMat
- materialArray = matArr
- reassignMats = reasMats
- thereAreMats = therMats
- seltopsonly = seltops
- doodSideMat = sidemat
- doodTopMat = topmat
-
-def setCurrMat(curma):
- global currmat
- currmat = curma
-
-#Find center and orientation of doodad
-def findDoodadCenter(sizeX, sizeY):
- #globalizing junk
- global face
- global xmin
- global xmax
- global ymin
- global ymax
- global orientation
- global doodadCenter
- global center
- global tosel
- global mxmin
- global mxmax
- global mymin
- global mymax
- global tempx
- global seltopsonly
-
- #Find the center of the face
- center = Vector([0,0,0])
- for pt in face.v:
- center = center + pt.co
- center = divideVectorByInt(center,len(face.v))
-
- #Find Temp Location Range by looking at the sizes
- txmin = ((divideVectorByInt((face.v[0].co + face.v[3].co),2)) - center)*(1-sizeX) + center
- txmax = ((divideVectorByInt((face.v[1].co + face.v[2].co),2)) - center)*(1-sizeX) + center
- tymin = ((divideVectorByInt((face.v[0].co + face.v[1].co),2)) - center)*(1-sizeY) + center
- tymax = ((divideVectorByInt((face.v[2].co + face.v[3].co),2)) - center)*(1-sizeY) + center
-
- #Find Center of doodad
- amtx = randnum(0.0,1.0)
- amty = randnum(0.0,1.0)
- thepoint = (((((txmin - txmax)*amtx + txmax) - ((tymin - tymax)*amty + tymax))*.5 + ((tymin - tymax)*amty + tymax)) - center)*2 + center
- doodadCenter = Vector([thepoint[0],thepoint[1],thepoint[2]])
-
- #Find Main Range by looking at the sizes
- mxmin = divideVectorByInt((face.v[0].co + face.v[3].co),2)
- mxmax = divideVectorByInt((face.v[1].co + face.v[2].co),2)
- mymin = divideVectorByInt((face.v[0].co + face.v[1].co),2)
- mymax = divideVectorByInt((face.v[2].co + face.v[3].co),2)
-
- #Find x/y equivs for whole face
- ve1 = (txmin - txmax)*amtx + txmax
- ve1 = ve1 - mxmax
- nax = ve1.length
- ve1 = (mxmin - mxmax)
- nax = nax/ve1.length
-
- ve1 = (tymin - tymax)*amty + tymax
- ve1 = ve1 - mymax
- nay = ve1.length
- ve1 = (mymin - mymax)
- nay = nay/ve1.length
-
- #Find new box thing
- tempx = []
- amtx = nax-sizeX/2
- amty = nay-sizeY/2
- tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center)
-
- amtx = nax-sizeX/2
- amty = nay+sizeY/2
- tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center)
-
- amtx = nax+sizeX/2
- amty = nay+sizeY/2
- tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center)
-
- amtx = nax+sizeX/2
- amty = nay-sizeY/2
- tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center)
-
- #Find New Location Range by looking at the sizes
- xmin = divideVectorByInt((tempx[0] + tempx[3]),2)
- xmax = divideVectorByInt((tempx[1] + tempx[2]),2)
- ymin = divideVectorByInt((tempx[0] + tempx[1]),2)
- ymax = divideVectorByInt((tempx[2] + tempx[3]),2)
-
-#Make a point
-def makePoint(x,y,z=0):
- global xmin
- global xmax
- global ymin
- global ymax
- global doodadCenter
- global tosel
- global seltopsonly
- global face
-
- amtx = x
- amty = y
- thepoint = (((((xmin - xmax)*amtx + xmax) - ((ymin - ymax)*amty + ymax))*.5 + ((ymin - ymax)*amty + ymax)) - doodadCenter)*2 + doodadCenter
- thepoint = thepoint + z*Vector(face.no)
- tver = Vert(thepoint[0],thepoint[1],thepoint[2])
- if tosel == 1 and seltopsonly == 0 and z == 0:
- tver.sel = 1
- return tver
-
-#extrude ground-plane(s)
-def extrudedoodad(vArray,heig):
- global face
- global doodadMesh
- global tosel
-
- topVArray = []
-
- doodadMesh.verts.extend(vArray)
-
- #Create array for extruded verts
- for ind in range(0,(len(vArray))):
- point = vArray[ind].co + heig*Vector(face.no)
- ver = Vert(point[0],point[1],point[2])
- if tosel == 1:
- ver.sel = 1
- topVArray.append(ver)
- doodadMesh.verts.append(topVArray[ind])
-
- #make faces around sides
- for ind in range(0,(len(vArray) - 1)):
- face = Face()
- face.v.extend([vArray[ind],vArray[ind+1],topVArray[ind+1],topVArray[ind]])
- if tosel == 1 and seltopsonly == 0: face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodSideMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vArray[len(vArray) - 1],vArray[0],topVArray[0],topVArray[len(topVArray) - 1]])
- if tosel == 1 and seltopsonly == 0:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodSideMat-1
- doodadMesh.faces.append(face)
-
- return topVArray
-
-#For switching face vertices
-def fixvertindex(ind):
- if ind > 3:
- indx = ind - 4
- else:
- indx = ind
- return indx
-
-#runs doodads
-def createDoodad(indexArray,facec,minsi,maxsi,minhei,maxhei,selec,amtmin,amtmax,facpercent):
- global doodadMesh
- global seltopsonly
- global tosel
-
- doodadMesh = NMesh.GetRaw()
-
- theamt = round(randnum(amtmin,amtmax),0)
- theamt = int(theamt)
- tosel = selec
-
- for i in range(0,(theamt)):
- if randnum(0,1) <= facpercent:
- index = round(randnum(1,len(indexArray)),0)
- index = indexArray[(int(index) - 1)]
-
- Xsi = randnum(minsi,maxsi)
- Ysi = randnum(minsi,maxsi)
- hei = randnum(minhei,maxhei)
-
- #Determine orientation
- orient = int(round(randnum(0.0,3.0)))
-
- #face to use as range
- facer = Face()
- facer.v.extend([facec.v[orient],facec.v[fixvertindex(1+orient)],facec.v[fixvertindex(2+orient)],facec.v[fixvertindex(3+orient)]])
-
- if index == 1:
- singleBox(facer,Xsi,Ysi,hei)
- if index == 2:
- doubleBox(facer,Xsi,Ysi,hei)
- if index == 3:
- tripleBox(facer,Xsi,Ysi,hei)
- if index == 4:
- LShape(facer,Xsi,Ysi,hei)
- if index == 5:
- TShape(facer,Xsi,Ysi,hei)
- if index == 6:
- if randnum(0.0,1.0) > .5:
- SShape(facer,Xsi,Ysi,hei)
- else:
- ZShape(facer,Xsi,Ysi,hei)
-
- return doodadMesh
-
-def divideVectorByInt(thevect,theint):
- thevect.x = thevect.x/theint
- thevect.y = thevect.y/theint
- thevect.z = thevect.z/theint
- return thevect
-
-#Single Box Doodad
-def singleBox(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- vertArray = []
-
- #place four points
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,1))
- vertArray.append(makePoint(1,1))
- vertArray.append(makePoint(1,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- face = Face()
- face.v.extend(vertArray)
- face.v.reverse()
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend(topVertArray)
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
-#Double Box Doodad
-def doubleBox(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- vertArray = []
-
- #place first box
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,1))
- vertArray.append(makePoint(0.45,1))
- vertArray.append(makePoint(0.45,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- face = Face()
- face.v.extend(vertArray)
- face.v.reverse()
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend(topVertArray)
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- vertArray = []
-
- #place second box
- vertArray.append(makePoint(0.55,0))
- vertArray.append(makePoint(0.55,1))
- vertArray.append(makePoint(1,1))
- vertArray.append(makePoint(1,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- face = Face()
- face.v.extend(vertArray)
- face.v.reverse()
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend(topVertArray)
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
-#Triple Box Doodad
-def tripleBox(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- vertArray = []
-
- #place first box
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,1))
- vertArray.append(makePoint(0.3,1))
- vertArray.append(makePoint(0.3,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- face = Face()
- face.v.extend(vertArray)
- face.v.reverse()
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend(topVertArray)
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- vertArray = []
-
- #place second box
- vertArray.append(makePoint(0.35,0))
- vertArray.append(makePoint(0.35,1))
- vertArray.append(makePoint(0.65,1))
- vertArray.append(makePoint(0.65,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- face = Face()
- face.v.extend(vertArray)
- face.v.reverse()
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend(topVertArray)
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- vertArray = []
-
- #place third box
- vertArray.append(makePoint(0.7,0))
- vertArray.append(makePoint(0.7,1))
- vertArray.append(makePoint(1,1))
- vertArray.append(makePoint(1,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- face = Face()
- face.v.extend(vertArray)
- face.v.reverse()
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend(topVertArray)
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
-#The "L" Shape
-def LShape(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- rcon1 = randnum(0.2,0.8)
- rcon2 = randnum(0.2,0.8)
-
- vertArray = []
-
- #place L shape
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,rcon1))
- vertArray.append(makePoint(0,1))
- vertArray.append(makePoint(rcon2,1))
- vertArray.append(makePoint(rcon2,rcon1))
- vertArray.append(makePoint(1,rcon1))
- vertArray.append(makePoint(1,0))
- vertArray.append(makePoint(rcon2,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- #This fills in the bottom of doodad with faceness
- face = Face()
- face.v.extend([vertArray[0],vertArray[1],vertArray[4],vertArray[7]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[1],vertArray[2],vertArray[3],vertArray[4]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[4],vertArray[5],vertArray[6],vertArray[7]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- #This fills in the top with faceness
- face = Face()
- face.v.extend([topVertArray[0],topVertArray[1],topVertArray[4],topVertArray[7]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[1],topVertArray[2],topVertArray[3],topVertArray[4]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[4],topVertArray[5],topVertArray[6],topVertArray[7]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
-#The "T" Shape
-def TShape(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- rcony = randnum(0.25,0.75)
- rconx1 = randnum(0.1,0.49)
- rconx2 = randnum(0.51,0.9)
-
- vertArray = []
-
- #place T shape
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,rcony))
- vertArray.append(makePoint(rconx1,rcony))
- vertArray.append(makePoint(rconx1,1))
- vertArray.append(makePoint(rconx2,1))
- vertArray.append(makePoint(rconx2,rcony))
- vertArray.append(makePoint(1,rcony))
- vertArray.append(makePoint(1,0))
- vertArray.append(makePoint(rconx2,0))
- vertArray.append(makePoint(rconx1,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- #fills bottom with faceness
- face = Face()
- face.v.extend([vertArray[0],vertArray[1],vertArray[2],vertArray[9]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[2],vertArray[3],vertArray[4],vertArray[5]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[5],vertArray[6],vertArray[7],vertArray[8]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[8],vertArray[9],vertArray[2],vertArray[5]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- #fills top with faceness
- face = Face()
- face.v.extend([topVertArray[0],topVertArray[1],topVertArray[2],topVertArray[9]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[2],topVertArray[3],topVertArray[4],topVertArray[5]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[5],topVertArray[6],topVertArray[7],topVertArray[8]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[8],topVertArray[9],topVertArray[2],topVertArray[5]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
-#The "S" or "Z" Shapes
-def SShape(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- rcony1 = randnum(0.1,0.49)
- rcony2 = randnum(0.51,0.9)
- rconx1 = randnum(0.1,0.49)
- rconx2 = randnum(0.51,0.9)
-
- vertArray = []
-
- #place S shape
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,rcony1))
- vertArray.append(makePoint(rconx1,rcony1))
- vertArray.append(makePoint(rconx1,rcony2))
- vertArray.append(makePoint(rconx1,1))
- vertArray.append(makePoint(rconx2,1))
- vertArray.append(makePoint(1,1))
- vertArray.append(makePoint(1,rcony2))
- vertArray.append(makePoint(rconx2,rcony2))
- vertArray.append(makePoint(rconx2,rcony1))
- vertArray.append(makePoint(rconx2,0))
- vertArray.append(makePoint(rconx1,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- #fills bottom with faceness
- face = Face()
- face.v.extend([vertArray[0],vertArray[1],vertArray[2],vertArray[11]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[2],vertArray[9],vertArray[10],vertArray[11]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[2],vertArray[3],vertArray[8],vertArray[9]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[3],vertArray[4],vertArray[5],vertArray[8]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[5],vertArray[6],vertArray[7],vertArray[8]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- #fills top with faceness
- face = Face()
- face.v.extend([topVertArray[0],topVertArray[1],topVertArray[2],topVertArray[11]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[2],topVertArray[9],topVertArray[10],topVertArray[11]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[2],topVertArray[3],topVertArray[8],topVertArray[9]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[3],topVertArray[4],topVertArray[5],topVertArray[8]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[5],topVertArray[6],topVertArray[7],topVertArray[8]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
-def ZShape(facel, Xsize, Ysize, height):
- #globaling junk
- global face
- global tosel
- global doodadMesh
-
- face = Face()
- face = facel
-
- findDoodadCenter(Xsize, Ysize)
-
- rcony1 = randnum(0.1,0.49)
- rcony2 = randnum(0.51,0.9)
- rconx1 = randnum(0.1,0.49)
- rconx2 = randnum(0.51,0.9)
-
- vertArray = []
-
- #place Z shape
- vertArray.append(makePoint(0,0))
- vertArray.append(makePoint(0,rcony1))
- vertArray.append(makePoint(0,rcony2))
- vertArray.append(makePoint(rconx1,rcony2))
- vertArray.append(makePoint(rconx2,rcony2))
- vertArray.append(makePoint(rconx2,1))
- vertArray.append(makePoint(1,1))
- vertArray.append(makePoint(1,rcony2))
- vertArray.append(makePoint(1,rcony1))
- vertArray.append(makePoint(rconx2,rcony1))
- vertArray.append(makePoint(rconx1,rcony1))
- vertArray.append(makePoint(rconx1,0))
- topVertArray = extrudedoodad(vertArray,height)
-
- #fills bottom with faceness
- face = Face()
- face.v.extend([vertArray[0],vertArray[1],vertArray[10],vertArray[11]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[1],vertArray[2],vertArray[3],vertArray[10]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[3],vertArray[4],vertArray[9],vertArray[10]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[4],vertArray[7],vertArray[8],vertArray[9]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([vertArray[4],vertArray[5],vertArray[6],vertArray[7]])
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
- #fills top with faceness
- face = Face()
- face.v.extend([topVertArray[0],topVertArray[1],topVertArray[10],topVertArray[11]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[1],topVertArray[2],topVertArray[3],topVertArray[10]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[3],topVertArray[4],topVertArray[9],topVertArray[10]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[4],topVertArray[7],topVertArray[8],topVertArray[9]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
- face = Face()
- face.v.extend([topVertArray[4],topVertArray[5],topVertArray[6],topVertArray[7]])
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or doodTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = doodTopMat-1
- doodadMesh.faces.append(face)
-
diff --git a/release/scripts/bpymodules/dxfColorMap.py b/release/scripts/bpymodules/dxfColorMap.py
deleted file mode 100644
index 66c0bd4e9a2..00000000000
--- a/release/scripts/bpymodules/dxfColorMap.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# dictionary mapping AutoCAD color indexes with Blender colors
-
-# --------------------------------------------------------------------------
-# color_map.py Final by Ed Blake (AKA Kitsu)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-color_map = {
- 0:[0.0, 0.0, 0.0],
- 1:[0.99609375, 0.0, 0.0],
- 2:[0.99609375, 0.99609375, 0.0],
- 3:[0.0, 0.99609375, 0.0],
- 4:[0.0, 0.99609375, 0.99609375],
- 5:[0.0, 0.0, 0.99609375],
- 6:[0.99609375, 0.0, 0.99609375],
- 7:[0.99609375, 0.99609375, 0.99609375],
- 8:[0.25390625, 0.25390625, 0.25390625],
- 9:[0.5, 0.5, 0.5],
- 10:[0.99609375, 0.0, 0.0],
- 11:[0.99609375, 0.6640625, 0.6640625],
- 12:[0.73828125, 0.0, 0.0],
- 13:[0.73828125, 0.4921875, 0.4921875],
- 14:[0.50390625, 0.0, 0.0],
- 15:[0.50390625, 0.3359375, 0.3359375],
- 16:[0.40625, 0.0, 0.0],
- 17:[0.40625, 0.26953125, 0.26953125],
- 18:[0.30859375, 0.0, 0.0],
- 19:[0.30859375, 0.20703125, 0.20703125],
- 20:[0.99609375, 0.24609375, 0.0],
- 21:[0.99609375, 0.74609375, 0.6640625],
- 22:[0.73828125, 0.1796875, 0.0],
- 23:[0.73828125, 0.55078125, 0.4921875],
- 24:[0.50390625, 0.12109375, 0.0],
- 25:[0.50390625, 0.375, 0.3359375],
- 26:[0.40625, 0.09765625, 0.0],
- 27:[0.40625, 0.3046875, 0.26953125],
- 28:[0.30859375, 0.07421875, 0.0],
- 29:[0.30859375, 0.23046875, 0.20703125],
- 30:[0.99609375, 0.49609375, 0.0],
- 31:[0.99609375, 0.828125, 0.6640625],
- 32:[0.73828125, 0.3671875, 0.0],
- 33:[0.73828125, 0.61328125, 0.4921875],
- 34:[0.50390625, 0.25, 0.0],
- 35:[0.50390625, 0.41796875, 0.3359375],
- 36:[0.40625, 0.203125, 0.0],
- 37:[0.40625, 0.3359375, 0.26953125],
- 38:[0.30859375, 0.15234375, 0.0],
- 39:[0.30859375, 0.2578125, 0.20703125],
- 40:[0.99609375, 0.74609375, 0.0],
- 41:[0.99609375, 0.9140625, 0.6640625],
- 42:[0.73828125, 0.55078125, 0.0],
- 43:[0.73828125, 0.67578125, 0.4921875],
- 44:[0.50390625, 0.375, 0.0],
- 45:[0.50390625, 0.4609375, 0.3359375],
- 46:[0.40625, 0.3046875, 0.0],
- 47:[0.40625, 0.37109375, 0.26953125],
- 48:[0.30859375, 0.23046875, 0.0],
- 49:[0.30859375, 0.28515625, 0.20703125],
- 50:[0.99609375, 0.99609375, 0.0],
- 51:[0.99609375, 0.99609375, 0.6640625],
- 52:[0.73828125, 0.73828125, 0.0],
- 53:[0.73828125, 0.73828125, 0.4921875],
- 54:[0.50390625, 0.50390625, 0.0],
- 55:[0.50390625, 0.50390625, 0.3359375],
- 56:[0.40625, 0.40625, 0.0],
- 57:[0.40625, 0.40625, 0.26953125],
- 58:[0.30859375, 0.30859375, 0.0],
- 59:[0.30859375, 0.30859375, 0.20703125],
- 60:[0.74609375, 0.99609375, 0.0],
- 61:[0.9140625, 0.99609375, 0.6640625],
- 62:[0.55078125, 0.73828125, 0.0],
- 63:[0.67578125, 0.73828125, 0.4921875],
- 64:[0.375, 0.50390625, 0.0],
- 65:[0.4609375, 0.50390625, 0.3359375],
- 66:[0.3046875, 0.40625, 0.0],
- 67:[0.37109375, 0.40625, 0.26953125],
- 68:[0.23046875, 0.30859375, 0.0],
- 69:[0.28515625, 0.30859375, 0.20703125],
- 70:[0.49609375, 0.99609375, 0.0],
- 71:[0.828125, 0.99609375, 0.6640625],
- 72:[0.3671875, 0.73828125, 0.0],
- 73:[0.61328125, 0.73828125, 0.4921875],
- 74:[0.25, 0.50390625, 0.0],
- 75:[0.41796875, 0.50390625, 0.3359375],
- 76:[0.203125, 0.40625, 0.0],
- 77:[0.3359375, 0.40625, 0.26953125],
- 78:[0.15234375, 0.30859375, 0.0],
- 79:[0.2578125, 0.30859375, 0.20703125],
- 80:[0.24609375, 0.99609375, 0.0],
- 81:[0.74609375, 0.99609375, 0.6640625],
- 82:[0.1796875, 0.73828125, 0.0],
- 83:[0.55078125, 0.73828125, 0.4921875],
- 84:[0.12109375, 0.50390625, 0.0],
- 85:[0.375, 0.50390625, 0.3359375],
- 86:[0.09765625, 0.40625, 0.0],
- 87:[0.3046875, 0.40625, 0.26953125],
- 88:[0.07421875, 0.30859375, 0.0],
- 89:[0.23046875, 0.30859375, 0.20703125],
- 90:[0.0, 0.99609375, 0.0],
- 91:[0.6640625, 0.99609375, 0.6640625],
- 92:[0.0, 0.73828125, 0.0],
- 93:[0.4921875, 0.73828125, 0.4921875],
- 94:[0.0, 0.50390625, 0.0],
- 95:[0.3359375, 0.50390625, 0.3359375],
- 96:[0.0, 0.40625, 0.0],
- 97:[0.26953125, 0.40625, 0.26953125],
- 98:[0.0, 0.30859375, 0.0],
- 99:[0.20703125, 0.30859375, 0.20703125],
- 100:[0.0, 0.99609375, 0.24609375],
- 101:[0.6640625, 0.99609375, 0.74609375],
- 102:[0.0, 0.73828125, 0.1796875],
- 103:[0.4921875, 0.73828125, 0.55078125],
- 104:[0.0, 0.50390625, 0.12109375],
- 105:[0.3359375, 0.50390625, 0.375],
- 106:[0.0, 0.40625, 0.09765625],
- 107:[0.26953125, 0.40625, 0.3046875],
- 108:[0.0, 0.30859375, 0.07421875],
- 109:[0.20703125, 0.30859375, 0.23046875],
- 110:[0.0, 0.99609375, 0.49609375],
- 111:[0.6640625, 0.99609375, 0.828125],
- 112:[0.0, 0.73828125, 0.3671875],
- 113:[0.4921875, 0.73828125, 0.61328125],
- 114:[0.0, 0.50390625, 0.25],
- 115:[0.3359375, 0.50390625, 0.41796875],
- 116:[0.0, 0.40625, 0.203125],
- 117:[0.26953125, 0.40625, 0.3359375],
- 118:[0.0, 0.30859375, 0.15234375],
- 119:[0.20703125, 0.30859375, 0.2578125],
- 120:[0.0, 0.99609375, 0.74609375],
- 121:[0.6640625, 0.99609375, 0.9140625],
- 122:[0.0, 0.73828125, 0.55078125],
- 123:[0.4921875, 0.73828125, 0.67578125],
- 124:[0.0, 0.50390625, 0.375],
- 125:[0.3359375, 0.50390625, 0.4609375],
- 126:[0.0, 0.40625, 0.3046875],
- 127:[0.26953125, 0.40625, 0.37109375],
- 128:[0.0, 0.30859375, 0.23046875],
- 129:[0.20703125, 0.30859375, 0.28515625],
- 130:[0.0, 0.99609375, 0.99609375],
- 131:[0.6640625, 0.99609375, 0.99609375],
- 132:[0.0, 0.73828125, 0.73828125],
- 133:[0.4921875, 0.73828125, 0.73828125],
- 134:[0.0, 0.50390625, 0.50390625],
- 135:[0.3359375, 0.50390625, 0.50390625],
- 136:[0.0, 0.40625, 0.40625],
- 137:[0.26953125, 0.40625, 0.40625],
- 138:[0.0, 0.30859375, 0.30859375],
- 139:[0.20703125, 0.30859375, 0.30859375],
- 140:[0.0, 0.74609375, 0.99609375],
- 141:[0.6640625, 0.9140625, 0.99609375],
- 142:[0.0, 0.55078125, 0.73828125],
- 143:[0.4921875, 0.67578125, 0.73828125],
- 144:[0.0, 0.375, 0.50390625],
- 145:[0.3359375, 0.4609375, 0.50390625],
- 146:[0.0, 0.3046875, 0.40625],
- 147:[0.26953125, 0.37109375, 0.40625],
- 148:[0.0, 0.23046875, 0.30859375],
- 149:[0.20703125, 0.28515625, 0.30859375],
- 150:[0.0, 0.49609375, 0.99609375],
- 151:[0.6640625, 0.828125, 0.99609375],
- 152:[0.0, 0.3671875, 0.73828125],
- 153:[0.4921875, 0.61328125, 0.73828125],
- 154:[0.0, 0.25, 0.50390625],
- 155:[0.3359375, 0.41796875, 0.50390625],
- 156:[0.0, 0.203125, 0.40625],
- 157:[0.26953125, 0.3359375, 0.40625],
- 158:[0.0, 0.15234375, 0.30859375],
- 159:[0.20703125, 0.2578125, 0.30859375],
- 160:[0.0, 0.24609375, 0.99609375],
- 161:[0.6640625, 0.74609375, 0.99609375],
- 162:[0.0, 0.1796875, 0.73828125],
- 163:[0.4921875, 0.55078125, 0.73828125],
- 164:[0.0, 0.12109375, 0.50390625],
- 165:[0.3359375, 0.375, 0.50390625],
- 166:[0.0, 0.09765625, 0.40625],
- 167:[0.26953125, 0.3046875, 0.40625],
- 168:[0.0, 0.07421875, 0.30859375],
- 169:[0.20703125, 0.23046875, 0.30859375],
- 170:[0.0, 0.0, 0.99609375],
- 171:[0.6640625, 0.6640625, 0.99609375],
- 172:[0.0, 0.0, 0.73828125],
- 173:[0.4921875, 0.4921875, 0.73828125],
- 174:[0.0, 0.0, 0.50390625],
- 175:[0.3359375, 0.3359375, 0.50390625],
- 176:[0.0, 0.0, 0.40625],
- 177:[0.26953125, 0.26953125, 0.40625],
- 178:[0.0, 0.0, 0.30859375],
- 179:[0.20703125, 0.20703125, 0.30859375],
- 180:[0.24609375, 0.0, 0.99609375],
- 181:[0.74609375, 0.6640625, 0.99609375],
- 182:[0.1796875, 0.0, 0.73828125],
- 183:[0.55078125, 0.4921875, 0.73828125],
- 184:[0.12109375, 0.0, 0.50390625],
- 185:[0.375, 0.3359375, 0.50390625],
- 186:[0.09765625, 0.0, 0.40625],
- 187:[0.3046875, 0.26953125, 0.40625],
- 188:[0.07421875, 0.0, 0.30859375],
- 189:[0.23046875, 0.20703125, 0.30859375],
- 190:[0.49609375, 0.0, 0.99609375],
- 191:[0.828125, 0.6640625, 0.99609375],
- 192:[0.3671875, 0.0, 0.73828125],
- 193:[0.61328125, 0.4921875, 0.73828125],
- 194:[0.25, 0.0, 0.50390625],
- 195:[0.41796875, 0.3359375, 0.50390625],
- 196:[0.203125, 0.0, 0.40625],
- 197:[0.3359375, 0.26953125, 0.40625],
- 198:[0.15234375, 0.0, 0.30859375],
- 199:[0.2578125, 0.20703125, 0.30859375],
- 200:[0.74609375, 0.0, 0.99609375],
- 201:[0.9140625, 0.6640625, 0.99609375],
- 202:[0.55078125, 0.0, 0.73828125],
- 203:[0.67578125, 0.4921875, 0.73828125],
- 204:[0.375, 0.0, 0.50390625],
- 205:[0.4609375, 0.3359375, 0.50390625],
- 206:[0.3046875, 0.0, 0.40625],
- 207:[0.37109375, 0.26953125, 0.40625],
- 208:[0.23046875, 0.0, 0.30859375],
- 209:[0.28515625, 0.20703125, 0.30859375],
- 210:[0.99609375, 0.0, 0.99609375],
- 211:[0.99609375, 0.6640625, 0.99609375],
- 212:[0.73828125, 0.0, 0.73828125],
- 213:[0.73828125, 0.4921875, 0.73828125],
- 214:[0.50390625, 0.0, 0.50390625],
- 215:[0.50390625, 0.3359375, 0.50390625],
- 216:[0.40625, 0.0, 0.40625],
- 217:[0.40625, 0.26953125, 0.40625],
- 218:[0.30859375, 0.0, 0.30859375],
- 219:[0.30859375, 0.20703125, 0.30859375],
- 220:[0.99609375, 0.0, 0.74609375],
- 221:[0.99609375, 0.6640625, 0.9140625],
- 222:[0.73828125, 0.0, 0.55078125],
- 223:[0.73828125, 0.4921875, 0.67578125],
- 224:[0.50390625, 0.0, 0.375],
- 225:[0.50390625, 0.3359375, 0.4609375],
- 226:[0.40625, 0.0, 0.3046875],
- 227:[0.40625, 0.26953125, 0.37109375],
- 228:[0.30859375, 0.0, 0.23046875],
- 229:[0.30859375, 0.20703125, 0.28515625],
- 230:[0.99609375, 0.0, 0.49609375],
- 231:[0.99609375, 0.6640625, 0.828125],
- 232:[0.73828125, 0.0, 0.3671875],
- 233:[0.73828125, 0.4921875, 0.61328125],
- 234:[0.50390625, 0.0, 0.25],
- 235:[0.50390625, 0.3359375, 0.41796875],
- 236:[0.40625, 0.0, 0.203125],
- 237:[0.40625, 0.26953125, 0.3359375],
- 238:[0.30859375, 0.0, 0.15234375],
- 239:[0.30859375, 0.20703125, 0.2578125],
- 240:[0.99609375, 0.0, 0.24609375],
- 241:[0.99609375, 0.6640625, 0.74609375],
- 242:[0.73828125, 0.0, 0.1796875],
- 243:[0.73828125, 0.4921875, 0.55078125],
- 244:[0.50390625, 0.0, 0.12109375],
- 245:[0.50390625, 0.3359375, 0.375],
- 246:[0.40625, 0.0, 0.09765625],
- 247:[0.40625, 0.26953125, 0.3046875],
- 248:[0.30859375, 0.0, 0.07421875],
- 249:[0.30859375, 0.20703125, 0.23046875],
- 250:[0.19921875, 0.19921875, 0.19921875],
- 251:[0.3125, 0.3125, 0.3125],
- 252:[0.41015625, 0.41015625, 0.41015625],
- 253:[0.5078125, 0.5078125, 0.5078125],
- 254:[0.7421875, 0.7421875, 0.7421875],
- 255:[0.99609375, 0.99609375, 0.99609375],
-}
diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py
deleted file mode 100644
index ccd8ef9b625..00000000000
--- a/release/scripts/bpymodules/dxfLibrary.py
+++ /dev/null
@@ -1,880 +0,0 @@
-#dxfLibrary.py : provides functions for generating DXF files
-# --------------------------------------------------------------------------
-__version__ = "v1.33 - 2009.06.16"
-__author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)"
-__license__ = "GPL"
-__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf"
-__bpydoc__ ="""The library to export geometry data to DXF format r12 version.
-
-Copyright %s
-Version %s
-License %s
-Homepage %s
-
-See the homepage for documentation.
-Dedicated thread on BlenderArtists: http://blenderartists.org/forum/showthread.php?t=136439
-
-IDEAs:
--
-
-TODO:
-- add support for DXFr14 (needs extended file header)
-- add support for SPLINEs (possible first in DXFr14 version)
-- add user preset for floating point precision (3-16?)
-
-History
-v1.33 - 2009.06.16 by migius
- - modif _point(): converts all coords to floats
- - modif LineType class: implement elements
- - added VPORT class, incl. defaults
- - fix Insert class
-v1.32 - 2009.06.06 by migius
- - modif Style class: changed defaults to widthFactor=1.0, obliqueAngle=0.0
- - modif Text class: alignment parameter reactivated
-v1.31 - 2009.06.02 by migius
- - modif _Entity class: added paperspace,elevation
-v1.30 - 2009.05.28 by migius
- - bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0
-v1.29 - 2008.12.28 by Yorik
- - modif POLYLINE to support bulge segments
-v1.28 - 2008.12.13 by Steeve/BlenderArtists
- - bugfix for EXTMIN/EXTMAX to suit Cycas-CAD
-v1.27 - 2008.10.07 by migius
- - beautifying output code: keys whitespace prefix
- - refactoring DXF-strings format: NewLine moved to the end of
-v1.26 - 2008.10.05 by migius
- - modif POLYLINE to support POLYFACE
-v1.25 - 2008.09.28 by migius
- - modif FACE class for r12
-v1.24 - 2008.09.27 by migius
- - modif POLYLINE class for r12
- - changing output format from r9 to r12(AC1009)
-v1.1 (20/6/2005) by www.stani.be/python/sdxf
- - Python library to generate dxf drawings
-______________________________________________________________
-""" % (__author__,__version__,__license__,__url__)
-
-# --------------------------------------------------------------------------
-# DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani)
-# 2008/2009 modif by Remigiusz Fiedler (AKA migius)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-
-#import Blender
-#from Blender import Mathutils, Window, Scene, sys, Draw
-#import BPyMessages
-
-try:
- import copy
- #from struct import pack
-except:
- copy = None
-
-####1) Private (only for developpers)
-_HEADER_POINTS=['insbase','extmin','extmax']
-
-#---helper functions-----------------------------------
-def _point(x,index=0):
- """Convert tuple to a dxf point"""
- #print 'deb: _point=', x #-------------
- return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
-
-def _points(plist):
- """Convert a list of tuples to dxf points"""
- out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
- return out
-
-#---base classes----------------------------------------
-class _Call:
- """Makes a callable class."""
- def copy(self):
- """Returns a copy."""
- return copy.deepcopy(self)
-
- def __call__(self,**attrs):
- """Returns a copy with modified attributes."""
- copied=self.copy()
- for attr in attrs:setattr(copied,attr,attrs[attr])
- return copied
-
-#-------------------------------------------------------
-class _Entity(_Call):
- """Base class for _common group codes for entities."""
- def __init__(self,paperspace=None,color=None,layer='0',
- lineType=None,lineTypeScale=None,lineWeight=None,
- extrusion=None,elevation=None,thickness=None,
- parent=None):
- """None values will be omitted."""
- self.paperspace = paperspace
- self.color = color
- self.layer = layer
- self.lineType = lineType
- self.lineTypeScale = lineTypeScale
- self.lineWeight = lineWeight
- self.extrusion = extrusion
- self.elevation = elevation
- self.thickness = thickness
- #self.visible = visible
- self.parent = parent
-
- def _common(self):
- """Return common group codes as a string."""
- if self.parent:parent=self.parent
- else:parent=self
- result =''
- if parent.paperspace==1: result+=' 67\n1\n'
- if parent.layer!=None: result+=' 8\n%s\n'%parent.layer
- if parent.color!=None: result+=' 62\n%s\n'%parent.color
- if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType
- # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
- # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
- if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
- if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
- if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
- if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
- return result
-
-#--------------------------
-class _Entities:
- """Base class to deal with composed objects."""
- def __dxf__(self):
- return []
-
- def __str__(self):
- return ''.join([str(x) for x in self.__dxf__()])
-
-#--------------------------
-class _Collection(_Call):
- """Base class to expose entities methods to main object."""
- def __init__(self,entities=[]):
- self.entities=copy.copy(entities)
- #link entities methods to drawing
- for attr in dir(self.entities):
- if attr[0]!='_':
- attrObject=getattr(self.entities,attr)
- if callable(attrObject):
- setattr(self,attr,attrObject)
-
-####2) Constants
-#---color values
-BYBLOCK=0
-BYLAYER=256
-
-#---block-type flags (bit coded values, may be combined):
-ANONYMOUS =1 # This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application
-NON_CONSTANT_ATTRIBUTES =2 # This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all)
-XREF =4 # This block is an external reference (xref)
-XREF_OVERLAY =8 # This block is an xref overlay
-EXTERNAL =16 # This block is externally dependent
-RESOLVED =32 # This is a resolved external reference, or dependent of an external reference (ignored on input)
-REFERENCED =64 # This definition is a referenced external reference (ignored on input)
-
-#---mtext flags
-#attachment point
-TOP_LEFT = 1
-TOP_CENTER = 2
-TOP_RIGHT = 3
-MIDDLE_LEFT = 4
-MIDDLE_CENTER = 5
-MIDDLE_RIGHT = 6
-BOTTOM_LEFT = 7
-BOTTOM_CENTER = 8
-BOTTOM_RIGHT = 9
-#drawing direction
-LEFT_RIGHT = 1
-TOP_BOTTOM = 3
-BY_STYLE = 5 #the flow direction is inherited from the associated text style
-#line spacing style (optional):
-AT_LEAST = 1 #taller characters will override
-EXACT = 2 #taller characters will not override
-
-#---polyline flags
-CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction)
-CURVE_FIT =2 # Curve-fit vertices have been added
-SPLINE_FIT =4 # Spline-fit vertices have been added
-POLYLINE_3D =8 # This is a 3D polyline
-POLYGON_MESH =16 # This is a 3D polygon mesh
-CLOSED_N =32 # The polygon mesh is closed in the N direction
-POLYFACE_MESH =64 # The polyline is a polyface mesh
-CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline
-
-#---text flags
-#horizontal
-LEFT = 0
-CENTER = 1
-RIGHT = 2
-ALIGNED = 3 #if vertical alignment = 0
-MIDDLE = 4 #if vertical alignment = 0
-FIT = 5 #if vertical alignment = 0
-#vertical
-BASELINE = 0
-BOTTOM = 1
-MIDDLE = 2
-TOP = 3
-
-####3) Classes
-#---entitities -----------------------------------------------
-#--------------------------
-class Arc(_Entity):
- """Arc, angles in degrees."""
- def __init__(self,center=(0,0,0),radius=1,
- startAngle=0.0,endAngle=90,**common):
- """Angles in degrees."""
- _Entity.__init__(self,**common)
- self.center=center
- self.radius=radius
- self.startAngle=startAngle
- self.endAngle=endAngle
- def __str__(self):
- return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
- (self._common(),_point(self.center),
- self.radius,self.startAngle,self.endAngle)
-
-#-----------------------------------------------
-class Circle(_Entity):
- """Circle"""
- def __init__(self,center=(0,0,0),radius=1,**common):
- _Entity.__init__(self,**common)
- self.center=center
- self.radius=radius
- def __str__(self):
- return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\
- (self._common(),_point(self.center),self.radius)
-
-#-----------------------------------------------
-class Face(_Entity):
- """3dface"""
- def __init__(self,points,**common):
- _Entity.__init__(self,**common)
- while len(points)<4: #fix for r12 format
- points.append(points[-1])
- self.points=points
-
- def __str__(self):
- out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
- #print 'deb:out=', out #-------------------
- return out
-
-#-----------------------------------------------
-class Insert(_Entity):
- """Block instance."""
- def __init__(self,name,point=(0,0,0),
- xscale=None,yscale=None,zscale=None,
- cols=None,colspacing=None,rows=None,rowspacing=None,
- rotation=None,
- **common):
- _Entity.__init__(self,**common)
- self.name=name
- self.point=point
- self.xscale=xscale
- self.yscale=yscale
- self.zscale=zscale
- self.cols=cols
- self.colspacing=colspacing
- self.rows=rows
- self.rowspacing=rowspacing
- self.rotation=rotation
-
- def __str__(self):
- result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\
- (self.name,self._common(),_point(self.point))
- if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
- if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
- if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
- if self.rotation:result+=' 50\n%s\n'%self.rotation
- if self.cols!=None:result+=' 70\n%s\n'%self.cols
- if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
- if self.rows!=None:result+=' 71\n%s\n'%self.rows
- if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
- return result
-
-#-----------------------------------------------
-class Line(_Entity):
- """Line"""
- def __init__(self,points,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self):
- return ' 0\nLINE\n%s%s\n' %(
- self._common(), _points(self.points))
-
-
-#-----------------------------------------------
-class PolyLine(_Entity):
- def __init__(self,points,org_point=[0,0,0],flag=0,width=None,**common):
- #width = number, or width = list [width_start=None, width_end=None]
- #for 2d-polyline: points = [ [x, y, z, width_start=None, width_end=None, bulge=0 or None], ...]
- #for 3d-polyline: points = [ [x, y, z], ...]
- #for polyface: points = [points_list, faces_list]
- _Entity.__init__(self,**common)
- self.points=points
- self.org_point=org_point
- self.flag=flag
- self.polyface = False
- self.polyline2d = False
- self.faces = [] # dummy value
- self.width= None # dummy value
- if self.flag & POLYFACE_MESH:
- self.polyface=True
- self.points=points[0]
- self.faces=points[1]
- self.p_count=len(self.points)
- self.f_count=len(self.faces)
- elif not self.flag & POLYLINE_3D:
- self.polyline2d = True
- if width:
- if type(width)!='list':
- width=[width,width]
- self.width=width
-
- def __str__(self):
- result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag)
- result+=' 66\n1\n'
- result+='%s\n' %_point(self.org_point)
- if self.polyface:
- result+=' 71\n%s\n' %self.p_count
- result+=' 72\n%s\n' %self.f_count
- elif self.polyline2d:
- if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
- for point in self.points:
- result+=' 0\nVERTEX\n'
- result+=' 8\n%s\n' %self.layer
- if self.polyface:
- result+='%s\n' %_point(point[0:3])
- result+=' 70\n192\n'
- elif self.polyline2d:
- result+='%s\n' %_point(point[0:2])
- if len(point)>4:
- width1, width2 = point[3], point[4]
- if width1!=None: result+=' 40\n%s\n' %width1
- if width2!=None: result+=' 41\n%s\n' %width2
- if len(point)==6:
- bulge = point[5]
- if bulge: result+=' 42\n%s\n' %bulge
- else:
- result+='%s\n' %_point(point[0:3])
- for face in self.faces:
- result+=' 0\nVERTEX\n'
- result+=' 8\n%s\n' %self.layer
- result+='%s\n' %_point(self.org_point)
- result+=' 70\n128\n'
- result+=' 71\n%s\n' %face[0]
- result+=' 72\n%s\n' %face[1]
- result+=' 73\n%s\n' %face[2]
- if len(face)==4: result+=' 74\n%s\n' %face[3]
- result+=' 0\nSEQEND\n'
- result+=' 8\n%s\n' %self.layer
- return result
-
-#-----------------------------------------------
-class Point(_Entity):
- """Point."""
- def __init__(self,points=None,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self): # TODO:
- return ' 0\nPOINT\n%s%s\n' %(self._common(),
- _points(self.points)
- )
-
-#-----------------------------------------------
-class Solid(_Entity):
- """Colored solid fill."""
- def __init__(self,points=None,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self):
- return ' 0\nSOLID\n%s%s\n' %(self._common(),
- _points(self.points[:2]+[self.points[3],self.points[2]])
- )
-
-
-#-----------------------------------------------
-class Text(_Entity):
- """Single text line."""
- def __init__(self,text='',point=(0,0,0),alignment=None,
- flag=None,height=1,justifyhor=None,justifyver=None,
- rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
- _Entity.__init__(self,**common)
- self.text=text
- self.point=point
- self.alignment=alignment
- self.flag=flag
- self.height=height
- self.justifyhor=justifyhor
- self.justifyver=justifyver
- self.rotation=rotation
- self.obliqueAngle=obliqueAngle
- self.style=style
- self.xscale=xscale
- def __str__(self):
- result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\
- (self._common(),_point(self.point),self.height,self.text)
- if self.rotation: result+=' 50\n%s\n'%self.rotation
- if self.xscale: result+=' 41\n%s\n'%self.xscale
- if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
- if self.style: result+=' 7\n%s\n'%self.style
- if self.flag: result+=' 71\n%s\n'%self.flag
- if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
- if self.alignment: result+='%s\n'%_point(self.alignment,1)
- if self.justifyver: result+=' 73\n%s\n'%self.justifyver
- return result
-
-#-----------------------------------------------
-class Mtext(Text):
- """Surrogate for mtext, generates some Text instances."""
- def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
- Text.__init__(self,text=text,point=point,**options)
- if down:spacingFactor*=-1
- self.spacingFactor=spacingFactor
- self.spacingWidth=spacingWidth
- self.width=width
- self.down=down
- def __str__(self):
- texts=self.text.replace('\r\n','\n').split('\n')
- if not self.down:texts.reverse()
- result=''
- x=y=0
- if self.spacingWidth:spacingWidth=self.spacingWidth
- else:spacingWidth=self.height*self.spacingFactor
- for text in texts:
- while text:
- result+='%s\n'%Text(text[:self.width],
- point=(self.point[0]+x*spacingWidth,
- self.point[1]+y*spacingWidth,
- self.point[2]),
- alignment=self.alignment,flag=self.flag,height=self.height,
- justifyhor=self.justifyhor,justifyver=self.justifyver,
- rotation=self.rotation,obliqueAngle=self.obliqueAngle,
- style=self.style,xscale=self.xscale,parent=self
- )
- text=text[self.width:]
- if self.rotation:x+=1
- else:y+=1
- return result[1:]
-
-#-----------------------------------------------
-##class _Mtext(_Entity):
-## """Mtext not functioning for minimal dxf."""
-## def __init__(self,text='',point=(0,0,0),attachment=1,
-## charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
-## spacingStyle=None,spacingFactor=None,style=None,width=100,
-## xdirection=None,**common):
-## _Entity.__init__(self,**common)
-## self.text=text
-## self.point=point
-## self.attachment=attachment
-## self.charWidth=charWidth
-## self.charHeight=charHeight
-## self.direction=direction
-## self.height=height
-## self.rotation=rotation
-## self.spacingStyle=spacingStyle
-## self.spacingFactor=spacingFactor
-## self.style=style
-## self.width=width
-## self.xdirection=xdirection
-## def __str__(self):
-## input=self.text
-## text=''
-## while len(input)>250:
-## text+='3\n%s\n'%input[:250]
-## input=input[250:]
-## text+='1\n%s\n'%input
-## result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
-## (self._common(),_point(self.point),self.charHeight,self.width,
-## self.attachment,self.direction,text,
-## self.height,
-## self.rotation)
-## if self.style:result+='7\n%s\n'%self.style
-## if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
-## if self.charWidth:result+='42\n%s\n'%self.charWidth
-## if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
-## if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
-## return result
-
-#---tables ---------------------------------------------------
-#-----------------------------------------------
-class Block(_Collection):
- """Use list methods to add entities, eg append."""
- def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
- self.entities=copy.copy(entities)
- _Collection.__init__(self,entities)
- self.layer=layer
- self.name=name
- self.flag=0
- self.base=base
- def __str__(self): # TODO:
- e=''.join([str(x)for x in self.entities])
- return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\
- (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
-
-#-----------------------------------------------
-class Layer(_Call):
- """Layer"""
- def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
- self.name=name
- self.color=color
- self.lineType=lineType
- self.flag=flag
- def __str__(self):
- return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\
- (self.name.upper(),self.flag,self.color,self.lineType)
-
-#-----------------------------------------------
-class LineType(_Call):
- """Custom linetype"""
- def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
- self.name=name
- self.description=description
- self.elements=copy.copy(elements)
- self.flag=flag
- def __str__(self):
- result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\
- (self.name.upper(),self.flag,self.description)
- if self.elements:
- elements = ' 73\n%s\n' %(len(self.elements)-1)
- elements += ' 40\n%s\n' %(self.elements[0])
- for e in self.elements[1:]:
- elements += ' 49\n%s\n' %e
- result += elements
- return result
-
-
-#-----------------------------------------------
-class Style(_Call):
- """Text style"""
- def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
- mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
- self.name=name
- self.flag=flag
- self.height=height
- self.widthFactor=widthFactor
- self.obliqueAngle=obliqueAngle
- self.mirror=mirror
- self.lastHeight=lastHeight
- self.font=font
- self.bigFont=bigFont
- def __str__(self):
- return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
- (self.name.upper(),self.flag,self.flag,self.widthFactor,
- self.obliqueAngle,self.mirror,self.lastHeight,
- self.font.upper(),self.bigFont.upper())
-
-#-----------------------------------------------
-class VPort(_Call):
- def __init__(self,name,flag=0,
- leftBottom=(0.0,0.0),
- rightTop=(1.0,1.0),
- center=(0.5,0.5),
- snap_base=(0.0,0.0),
- snap_spacing=(0.1,0.1),
- grid_spacing=(0.1,0.1),
- direction=(0.0,0.0,1.0),
- target=(0.0,0.0,0.0),
- height=1.0,
- ratio=1.0,
- lens=50,
- frontClipping=0,
- backClipping=0,
- snap_rotation=0,
- twist=0,
- mode=0,
- circle_zoom=100,
- fast_zoom=1,
- ucsicon=1,
- snap_on=0,
- grid_on=0,
- snap_style=0,
- snap_isopair=0
- ):
- self.name=name
- self.flag=flag
- self.leftBottom=leftBottom
- self.rightTop=rightTop
- self.center=center
- self.snap_base=snap_base
- self.snap_spacing=snap_spacing
- self.grid_spacing=grid_spacing
- self.direction=direction
- self.target=target
- self.height=float(height)
- self.ratio=float(ratio)
- self.lens=float(lens)
- self.frontClipping=float(frontClipping)
- self.backClipping=float(backClipping)
- self.snap_rotation=float(snap_rotation)
- self.twist=float(twist)
- self.mode=mode
- self.circle_zoom=circle_zoom
- self.fast_zoom=fast_zoom
- self.ucsicon=ucsicon
- self.snap_on=snap_on
- self.grid_on=grid_on
- self.snap_style=snap_style
- self.snap_isopair=snap_isopair
- def __str__(self):
- output = [' 0', 'VPORT',
- ' 2', self.name,
- ' 70', self.flag,
- _point(self.leftBottom),
- _point(self.rightTop,1),
- _point(self.center,2), # View center point (in DCS)
- _point(self.snap_base,3),
- _point(self.snap_spacing,4),
- _point(self.grid_spacing,5),
- _point(self.direction,6), #view direction from target (in WCS)
- _point(self.target,7),
- ' 40', self.height,
- ' 41', self.ratio,
- ' 42', self.lens,
- ' 43', self.frontClipping,
- ' 44', self.backClipping,
- ' 50', self.snap_rotation,
- ' 51', self.twist,
- ' 71', self.mode,
- ' 72', self.circle_zoom,
- ' 73', self.fast_zoom,
- ' 74', self.ucsicon,
- ' 75', self.snap_on,
- ' 76', self.grid_on,
- ' 77', self.snap_style,
- ' 78', self.snap_isopair
- ]
-
- output_str = ''
- for s in output:
- output_str += '%s\n' %s
- return output_str
-
-
-
-#-----------------------------------------------
-class View(_Call):
- def __init__(self,name,flag=0,
- width=1,
- height=1,
- center=(0.5,0.5),
- direction=(0,0,1),
- target=(0,0,0),
- lens=50,
- frontClipping=0,
- backClipping=0,
- twist=0,mode=0
- ):
- self.name=name
- self.flag=flag
- self.width=float(width)
- self.height=float(height)
- self.center=center
- self.direction=direction
- self.target=target
- self.lens=float(lens)
- self.frontClipping=float(frontClipping)
- self.backClipping=float(backClipping)
- self.twist=float(twist)
- self.mode=mode
- def __str__(self):
- output = [' 0', 'VIEW',
- ' 2', self.name,
- ' 70', self.flag,
- ' 40', self.height,
- _point(self.center),
- ' 41', self.width,
- _point(self.direction,1),
- _point(self.target,2),
- ' 42', self.lens,
- ' 43', self.frontClipping,
- ' 44', self.backClipping,
- ' 50', self.twist,
- ' 71', self.mode
- ]
- output_str = ''
- for s in output:
- output_str += '%s\n' %s
- return output_str
-
-#-----------------------------------------------
-def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options):
- width=abs(rightTop[0]-leftBottom[0])
- height=abs(rightTop[1]-leftBottom[1])
- center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
- return View(name=name,width=width,height=height,center=center,**options)
-
-#---drawing
-#-----------------------------------------------
-class Drawing(_Collection):
- """Dxf drawing. Use append or any other list methods to add objects."""
- def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
- layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
- views=[],vports=[],entities=None,fileName='test.dxf'):
- # TODO: replace list with None,arial
- if not entities:
- entities=[]
- _Collection.__init__(self,entities)
- self.insbase=insbase
- self.extmin=extmin
- self.extmax=extmax
- self.layers=copy.copy(layers)
- self.linetypes=copy.copy(linetypes)
- self.styles=copy.copy(styles)
- self.views=copy.copy(views)
- self.vports=copy.copy(vports)
- self.blocks=copy.copy(blocks)
- self.fileName=fileName
- #private
- #self.acadver='9\n$ACADVER\n1\nAC1006\n'
- self.acadver=' 9\n$ACADVER\n 1\nAC1009\n'
- """DXF AutoCAD-Release format codes
- AC1021 2008, 2007
- AC1018 2006, 2005, 2004
- AC1015 2002, 2000i, 2000
- AC1014 R14,14.01
- AC1012 R13
- AC1009 R12,11
- AC1006 R10
- AC1004 R9
- AC1002 R2.6
- AC1.50 R2.05
- """
-
- def _name(self,x):
- """Helper function for self._point"""
- return ' 9\n$%s\n' %x.upper()
-
- def _point(self,name,x):
- """Point setting from drawing like extmin,extmax,..."""
- return '%s%s' %(self._name(name),_point(x))
-
- def _section(self,name,x):
- """Sections like tables,blocks,entities,..."""
- if x: xstr=''.join(x)
- else: xstr=''
- return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr)
-
- def _table(self,name,x):
- """Tables like ltype,layer,style,..."""
- if x: xstr=''.join(x)
- else: xstr=''
- return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr)
-
- def __str__(self):
- """Returns drawing as dxf string."""
- header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
- header=self._section('header',header)
-
- tables=[self._table('vport',[str(x) for x in self.vports]),
- self._table('ltype',[str(x) for x in self.linetypes]),
- self._table('layer',[str(x) for x in self.layers]),
- self._table('style',[str(x) for x in self.styles]),
- self._table('view',[str(x) for x in self.views]),
- ]
- tables=self._section('tables',tables)
-
- blocks=self._section('blocks',[str(x) for x in self.blocks])
-
- entities=self._section('entities',[str(x) for x in self.entities])
-
- all=''.join([header,tables,blocks,entities,' 0\nEOF\n'])
- return all
-
- def saveas(self,fileName):
- self.fileName=fileName
- self.save()
-
- def save(self):
- test=open(self.fileName,'w')
- test.write(str(self))
- test.close()
-
-
-#---extras
-#-----------------------------------------------
-class Rectangle(_Entity):
- """Rectangle, creates lines."""
- def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
- _Entity.__init__(self,**common)
- self.point=point
- self.width=width
- self.height=height
- self.solid=solid
- self.line=line
- def __str__(self):
- result=''
- points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
- (self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
- (self.point[0],self.point[1]+self.height,self.point[2]),self.point]
- if self.solid:
- result+= Solid(points=points[:-1],parent=self.solid)
- if self.line:
- for i in range(4):
- result+= Line(points=[points[i],points[i+1]],parent=self)
- return result[1:]
-
-#-----------------------------------------------
-class LineList(_Entity):
- """Like polyline, but built of individual lines."""
- def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
- _Entity.__init__(self,**common)
- self.closed=closed
- self.points=copy.copy(points)
- def __str__(self):
- if self.closed:points=self.points+[self.points[0]]
- else: points=self.points
- result=''
- for i in range(len(points)-1):
- result+= Line(points=[points[i],points[i+1]],parent=self)
- return result[1:]
-
-#-----------------------------------------------------
-def test():
- #Blocks
- b=Block('test')
- b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
- b.append(Arc(center=(1,0,0),color=2))
-
- #Drawing
- d=Drawing()
- #tables
- d.blocks.append(b) #table blocks
- d.styles.append(Style()) #table styles
- d.views.append(View('Normal')) #table view
- d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem
-
- #entities
- d.append(Circle(center=(1,1,0),color=3))
- d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
- d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
- d.append(Line(points=[(0,0,0),(1,1,1)]))
- d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
- d.append(Text('Please donate!',point=(3,0,1)))
- #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
- d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
- #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
-
- #d.saveas('c:\\test.dxf')
- d.saveas('test.dxf')
-
-#-----------------------------------------------------
-if __name__=='__main__':
- if not copy:
- Draw.PupMenu('Error%t|This script requires a full python install')
- else: test()
- \ No newline at end of file
diff --git a/release/scripts/bpymodules/dxfReader.py b/release/scripts/bpymodules/dxfReader.py
deleted file mode 100644
index df4ebc309e4..00000000000
--- a/release/scripts/bpymodules/dxfReader.py
+++ /dev/null
@@ -1,381 +0,0 @@
-"""This module provides a function for reading dxf files and parsing them into a useful tree of objects and data.
-
- The convert function is called by the readDXF fuction to convert dxf strings into the correct data based
- on their type code. readDXF expects a (full path) file name as input.
-"""
-
-# --------------------------------------------------------------------------
-# DXF Reader v0.9 by Ed Blake (AKA Kitsu)
-# 2008.05.08 modif.def convert() by Remigiusz Fiedler (AKA migius)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-#from dxfImportObjects import *
-
-class Object:
- """Empty container class for dxf objects"""
-
- def __init__(self, _type='', block=False):
- """_type expects a string value."""
- self.type = _type
- self.name = ''
- self.data = []
-
- def __str__(self):
- if self.name:
- return self.name
- else:
- return self.type
-
- def __repr__(self):
- return str(self.data)
-
- def get_type(self, kind=''):
- """Despite the name, this method actually returns all objects of type 'kind' from self.data."""
- if type:
- objects = []
- for item in self.data:
- if type(item) != list and item.type == kind:
- # we want this type of object
- objects.append(item)
- elif type(item) == list and item[0] == kind:
- # we want this type of data
- objects.append(item[1])
- return objects
-
-
-class InitializationError(Exception): pass
-
-class StateMachine:
- """(finite) State Machine from the great David Mertz's great Charming Python article."""
-
- def __init__(self):
- self.handlers = []
- self.startState = None
- self.endStates = []
-
- def add_state(self, handler, end_state=0):
- """All states and handlers are functions which return
- a state and a cargo."""
- self.handlers.append(handler)
- if end_state:
- self.endStates.append(handler)
- def set_start(self, handler):
- """Sets the starting handler function."""
- self.startState = handler
-
-
- def run(self, cargo=None):
- if not self.startState:
- raise InitializationError,\
- "must call .set_start() before .run()"
- if not self.endStates:
- raise InitializationError, \
- "at least one state must be an end_state"
- handler = self.startState
- while 1:
- (newState, cargo) = handler(cargo)
- #print cargo
- if newState in self.endStates:
- return newState(cargo)
- #break
- elif newState not in self.handlers:
- raise RuntimeError, "Invalid target %s" % newState
- else:
- handler = newState
-
-def get_name(data):
- """Get the name of an object from its object data.
-
- Returns a pair of (data_item, name) where data_item is the list entry where the name was found
- (the data_item can be used to remove the entry from the object data). Be sure to check
- name not None before using the returned values!
- """
- value = None
- for item in data:
- if item[0] == 2:
- value = item[1]
- break
- return item, value
-
-def get_layer(data):
- """Expects object data as input.
-
- Returns (entry, layer_name) where entry is the data item that provided the layer name.
- """
- value = None
- for item in data:
- if item[0] == 8:
- value = item[1]
- break
- return item, value
-
-
-def convert(code, value):
- """Convert a string to the correct Python type based on its dxf code.
- code types:
- ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070
- longs = 90-99, 420-429, 440-459, 1071
- floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059
- hex = 105, 310-379, 390-399
- strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009
- """
- if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071:
- value = int(float(value))
- elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071:
- value = long(float(value))
- elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060:
- value = float(value)
- elif code == 105 or 309 < code < 380 or 389 < code < 400:
- value = int(value, 16) # should be left as string?
- else: # it's already a string so do nothing
- pass
- return value
-
-
-def findObject(infile, kind=''):
- """Finds the next occurance of an object."""
- obj = False
- while 1:
- line = infile.readline()
- if not line: # readline returns '' at eof
- return False
- if not obj: # We're still looking for our object code
- if line.lower().strip() == '0':
- obj = True # found it
- else: # we are in an object definition
- if kind: # if we're looking for a particular kind
- if line.lower().strip() == kind:
- obj = Object(line.lower().strip())
- break
- else: # otherwise take anything non-numeric
- if line.lower().strip() not in string.digits:
- obj = Object(line.lower().strip())
- break
- obj = False # whether we found one or not it's time to start over
- return obj
-
-def handleObject(infile):
- """Add data to an object until end of object is found."""
- line = infile.readline()
- if line.lower().strip() == 'section':
- return 'section' # this would be a problem
- elif line.lower().strip() == 'endsec':
- return 'endsec' # this means we are done with a section
- else: # add data to the object until we find a new object
- obj = Object(line.lower().strip())
- obj.name = obj.type
- done = False
- data = []
- while not done:
- line = infile.readline()
- if not data:
- if line.lower().strip() == '0':
- #we've found an object, time to return
- return obj
- else:
- # first part is always an int
- data.append(int(line.lower().strip()))
- else:
- data.append(convert(data[0], line.strip()))
- obj.data.append(data)
- data = []
-
-def handleTable(table, infile):
- """Special handler for dealing with nested table objects."""
- item, name = get_name(table.data)
- if name: # We should always find a name
- table.data.remove(item)
- table.name = name.lower()
- # This next bit is from handleObject
- # handleObject should be generalized to work with any section like object
- while 1:
- obj = handleObject(infile)
- if obj.type == 'table':
- print "Warning: previous table not closed!"
- return table
- elif obj.type == 'endtab':
- return table # this means we are done with the table
- else: # add objects to the table until one of the above is found
- table.data.append(obj)
-
-
-
-
-def handleBlock(block, infile):
- """Special handler for dealing with nested table objects."""
- item, name = get_name(block.data)
- if name: # We should always find a name
- block.data.remove(item)
- block.name = name
- # This next bit is from handleObject
- # handleObject should be generalized to work with any section like object
- while 1:
- obj = handleObject(infile)
- if obj.type == 'block':
- print "Warning: previous block not closed!"
- return block
- elif obj.type == 'endblk':
- return block # this means we are done with the table
- else: # add objects to the table until one of the above is found
- block.data.append(obj)
-
-
-
-
-"""These are the states/functions used in the State Machine.
-states:
- start - find first section
- start_section - add data, find first object
- object - add obj-data, watch for next obj (called directly by start_section)
- end_section - look for next section or eof
- end - return results
-"""
-
-def start(cargo):
- """Expects the infile as cargo, initializes the cargo."""
- #print "Entering start state!"
- infile = cargo
- drawing = Object('drawing')
- section = findObject(infile, 'section')
- if section:
- return start_section, (infile, drawing, section)
- else:
- return error, (infile, "Failed to find any sections!")
-
-def start_section(cargo):
- """Expects [infile, drawing, section] as cargo, builds a nested section object."""
- #print "Entering start_section state!"
- infile = cargo[0]
- drawing = cargo[1]
- section = cargo[2]
- # read each line, if it is an object declaration go to object mode
- # otherwise create a [index, data] pair and add it to the sections data.
- done = False
- data = []
- while not done:
- line = infile.readline()
-
- if not data: # if we haven't found a dxf code yet
- if line.lower().strip() == '0':
- # we've found an object
- while 1: # no way out unless we find an end section or a new section
- obj = handleObject(infile)
- if obj == 'section': # shouldn't happen
- print "Warning: failed to close previous section!"
- return end_section, (infile, drawing)
- elif obj == 'endsec': # This section is over, look for the next
- drawing.data.append(section)
- return end_section, (infile, drawing)
- elif obj.type == 'table': # tables are collections of data
- obj = handleTable(obj, infile) # we need to find all there contents
- section.data.append(obj) # before moving on
- elif obj.type == 'block': # the same is true of blocks
- obj = handleBlock(obj, infile) # we need to find all there contents
- section.data.append(obj) # before moving on
- else: # found another sub-object
- section.data.append(obj)
- else:
- data.append(int(line.lower().strip()))
- else: # we have our code, now we just need to convert the data and add it to our list.
- data.append(convert(data[0], line.strip()))
- section.data.append(data)
- data = []
-def end_section(cargo):
- """Expects (infile, drawing) as cargo, searches for next section."""
- #print "Entering end_section state!"
- infile = cargo[0]
- drawing = cargo[1]
- section = findObject(infile, 'section')
- if section:
- return start_section, (infile, drawing, section)
- else:
- return end, (infile, drawing)
-
-def end(cargo):
- """Expects (infile, drawing) as cargo, called when eof has been reached."""
- #print "Entering end state!"
- infile = cargo[0]
- drawing = cargo[1]
- #infile.close()
- return drawing
-
-def error(cargo):
- """Expects a (infile, string) as cargo, called when there is an error during processing."""
- #print "Entering error state!"
- infile = cargo[0]
- err = cargo[1]
- infile.close()
- print "There has been an error:"
- print err
- return False
-
-def readDXF(filename, objectify):
- """Given a file name try to read it as a dxf file.
-
- Output is an object with the following structure
- drawing
- header
- header data
- classes
- class data
- tables
- table data
- blocks
- block data
- entities
- entity data
- objects
- object data
- where foo data is a list of sub-objects. True object data
- is of the form [code, data].
-"""
- infile = open(filename)
-
- sm = StateMachine()
- sm.add_state(error, True)
- sm.add_state(end, True)
- sm.add_state(start_section)
- sm.add_state(end_section)
- sm.add_state(start)
- sm.set_start(start)
- try:
- drawing = sm.run(infile)
- if drawing:
- drawing.name = filename
- for obj in drawing.data:
- item, name = get_name(obj.data)
- if name:
- obj.data.remove(item)
- obj.name = name.lower()
- setattr(drawing, name.lower(), obj)
- # Call the objectify function to cast
- # raw objects into the right types of object
- obj.data = objectify(obj.data)
- #print obj.name
- finally:
- infile.close()
- return drawing
-if __name__ == "__main__":
- filename = r".\examples\block-test.dxf"
- drawing = readDXF(filename)
- for item in drawing.entities.data:
- print item
diff --git a/release/scripts/bpymodules/mesh_gradient.py b/release/scripts/bpymodules/mesh_gradient.py
deleted file mode 100644
index e582a30152b..00000000000
--- a/release/scripts/bpymodules/mesh_gradient.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# This is not to be used directly, vertexGradientPick can be used externaly
-
-import Blender
-import BPyMesh
-import BPyWindow
-
-mouseViewRay= BPyWindow.mouseViewRay
-from Blender import Mathutils, Window, Scene, Draw, sys
-from Blender.Mathutils import Vector, Intersect, LineIntersect, AngleBetweenVecs
-LMB= Window.MButs['L']
-
-def mouseup():
- # Loop until click
- mouse_buttons = Window.GetMouseButtons()
- while not mouse_buttons & LMB:
- sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
- while mouse_buttons & LMB:
- sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
-
-def mousedown_wait():
- # If the menu has just been pressed dont use its mousedown,
- mouse_buttons = Window.GetMouseButtons()
- while mouse_buttons & LMB:
- mouse_buttons = Window.GetMouseButtons()
-
-eps= 0.0001
-def vertexGradientPick(ob, MODE):
- #MODE 0 == VWEIGHT, 1 == VCOL
-
- me= ob.getData(mesh=1)
- if not me.faceUV: me.faceUV= True
-
- Window.DrawProgressBar (0.0, '')
-
- mousedown_wait()
-
- if MODE==0:
- act_group= me.activeGroup
- if act_group == None:
- mousedown_wait()
- Draw.PupMenu('Error, mesh has no active group.')
- return
-
- # Loop until click
- Window.DrawProgressBar (0.25, 'Click to set gradient start')
- mouseup()
-
- obmat= ob.matrixWorld
- screen_x, screen_y = Window.GetMouseCoords()
- mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)
- if not mouseInView or not OriginA:
- return
-
- # get the mouse weight
-
- if MODE==0:
- pickValA= BPyMesh.pickMeshGroupWeight(me, act_group, OriginA, DirectionA)
- if MODE==1:
- pickValA= BPyMesh.pickMeshGroupVCol(me, OriginA, DirectionA)
-
- Window.DrawProgressBar (0.75, 'Click to set gradient end')
- mouseup()
-
- TOALPHA= Window.GetKeyQualifiers() & Window.Qual.SHIFT
-
- screen_x, screen_y = Window.GetMouseCoords()
- mouseInView, OriginB, DirectionB = mouseViewRay(screen_x, screen_y, obmat)
- if not mouseInView or not OriginB:
- return
-
- if not TOALPHA: # Only get a second opaque value if we are not blending to alpha
- if MODE==0: pickValB= BPyMesh.pickMeshGroupWeight(me, act_group, OriginB, DirectionB)
- else:
- pickValB= BPyMesh.pickMeshGroupVCol(me, OriginB, DirectionB)
- else:
- if MODE==0: pickValB= 0.0
- else: pickValB= [0.0, 0.0, 0.0] # Dummy value
-
- # Neither points touched a face
- if pickValA == pickValB == None:
- return
-
- # clicking on 1 non face is fine. just set the weight to 0.0
- if pickValA==None:
- pickValA= 0.0
-
- # swap A/B
- OriginA, OriginB= OriginB, OriginA
- DirectionA, DirectionB= DirectionB, DirectionA
- pickValA, pickValB= pickValA, pickValB
-
- TOALPHA= True
-
- if pickValB==None:
- pickValB= 0.0
- TOALPHA= True
-
- # set up 2 lines so we can measure their distances and calc the gradient
-
- # make a line 90d to the grad in screenspace.
- if (OriginA-OriginB).length <= eps: # Persp view. same origin different direction
- cross_grad= DirectionA.cross(DirectionB)
- ORTHO= False
-
- else: # Ortho - Same direction, different origin
- cross_grad= DirectionA.cross(OriginA-OriginB)
- ORTHO= True
-
- cross_grad.normalize()
- cross_grad= cross_grad * 100
-
- lineA= (OriginA, OriginA+(DirectionA*100))
- lineB= (OriginB, OriginB+(DirectionB*100))
-
- if not ORTHO:
- line_angle= AngleBetweenVecs(lineA[1], lineB[1])/2
- line_mid= (lineA[1]+lineB[1])*0.5
-
- VSEL= [False] * (len(me.verts))
-
- # Get the selected faces and apply the selection to the verts.
- for f in me.faces:
- if f.sel:
- for v in f.v:
- VSEL[v.index]= True
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
-
-
-
- def grad_weight_from_co(v):
- '''
- Takes a vert and retuens its gradient radio between A and B
- '''
-
- if not VSEL[v.index]: # Not bart of a selected face?
- return None, None
-
- v_co= v.co
- # make a line 90d to the 2 lines the user clicked.
- vert_line= (v_co - cross_grad, v_co + cross_grad)
-
- xA= LineIntersect(vert_line[0], vert_line[1], lineA[0], lineA[1])
- xB= LineIntersect(vert_line[0], vert_line[1], lineB[0], lineB[1])
-
- if not xA or not xB: # Should never happen but support it anyhow
- return None, None
-
- wA= (xA[0]-xA[1]).length
- wB= (xB[0]-xB[1]).length
-
- wTot= wA+wB
- if not wTot: # lines are on the same point.
- return None, None
-
- '''
- Get the length of the line between both intersections on the
- 2x view lines.
- if the dist between lineA+VertLine and lineB+VertLine is
- greater then the lenth between lineA and lineB intersection points, it means
- that the verts are not inbetween the 2 lines.
- '''
- lineAB_length= (xA[1]-xB[1]).length
-
- # normalzie
- wA= wA/wTot
- wB= wB/wTot
-
- if ORTHO: # Con only use line length method with parelelle lines
- if wTot > lineAB_length+eps:
- # vert is outside the range on 1 side. see what side of the grad
- if wA>wB: wA, wB= 1.0, 0.0
- else: wA, wB= 0.0, 1.0
- else:
- # PERSP, lineA[0] is the same origin as lineB[0]
-
- # Either xA[0] or xB[0] can be used instead of a possible x_mid between the 2
- # as long as the point is inbetween lineA and lineB it dosent matter.
- a= AngleBetweenVecs(lineA[0]-xA[0], line_mid)
- if a>line_angle:
- # vert is outside the range on 1 side. see what side of the grad
- if wA>wB: wA, wB= 1.0, 0.0
- else: wA, wB= 0.0, 1.0
-
- return wA, wB
-
-
- grad_weights= [grad_weight_from_co(v) for v in me.verts]
-
-
- if MODE==0:
- for v in me.verts:
- i= v.index
- if VSEL[i]:
- wA, wB = grad_weights[i]
- if wA != None: # and wB
- if TOALPHA:
- # Do alpha by using the exiting weight for
- try: pickValB= vWeightDict[i][act_group]
- except: pickValB= 0.0 # The weights not there? assume zero
- # Mix2 2 opaque weights
- vWeightDict[i][act_group]= pickValB*wA + pickValA*wB
-
- else: # MODE==1 VCol
- for f in me.faces:
- if f.sel:
- f_v= f.v
- for i in xrange(len(f_v)):
- v= f_v[i]
- wA, wB = grad_weights[v.index]
-
- c= f.col[i]
-
- if TOALPHA:
- pickValB= c.r, c.g, c.b
-
- c.r = int(pickValB[0]*wA + pickValA[0]*wB)
- c.g = int(pickValB[1]*wA + pickValA[1]*wB)
- c.b = int(pickValB[2]*wA + pickValA[2]*wB)
-
-
-
-
- # Copy weights back to the mesh.
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
- Window.DrawProgressBar (1.0, '')
-
-
diff --git a/release/scripts/bpymodules/meshtools.py b/release/scripts/bpymodules/meshtools.py
deleted file mode 100644
index 274a12ea6da..00000000000
--- a/release/scripts/bpymodules/meshtools.py
+++ /dev/null
@@ -1,355 +0,0 @@
-# $Id$
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2001 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | September 28, 2002 |
-# +---------------------------------------------------------+
-# | Common Functions & Global Variables For All IO Modules |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-import sys
-
-show_progress = 1 # Set to 0 for faster performance
-average_vcols = 1 # Off for per-face, On for per-vertex
-overwrite_mesh_name = 0 # Set to 0 to increment object-name version
-
-blender_version = Blender.Get('version')
-blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:]
-
-try:
- import operator
-except:
- msg = "Error: you need a full Python install to run this script."
- meshtools.print_boxed(msg)
- Blender.Draw.PupMenu("ERROR%t|"+msg)
-
-# =================================
-# === Append Faces To Face List ===
-# =================================
-def append_faces(mesh, faces, facesuv, uvcoords):
- for i in xrange(len(faces)):
- if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces")
- numfaceverts=len(faces[i])
- if numfaceverts == 2: #This is not a face is an edge
- if mesh.edges == None: #first run
- mesh.addEdgeData()
- #rev_face = revert(cur_face)
- i1 = faces[i][0]
- i2 = faces[i][1]
- ee = mesh.addEdge(mesh.verts[i1],mesh.verts[i2])
- ee.flag |= Blender.NMesh.EdgeFlags.EDGEDRAW
- ee.flag |= Blender.NMesh.EdgeFlags.EDGERENDER
- elif numfaceverts in [3,4]: # This face is a triangle or quad
- face = Blender.NMesh.Face()
- for j in xrange(numfaceverts):
- index = faces[i][j]
- face.v.append(mesh.verts[index])
- if len(uvcoords) > 1:
- uvidx = facesuv[i][j]
- face.uv.append(uvcoords[uvidx])
- face.mode = 0
- face.col = [Blender.NMesh.Col()]*4
- mesh.faces.append(face)
- else: # Triangulate n-sided convex polygon.
- a, b, c = 0, 1, 2 # Indices of first triangle.
- for j in xrange(numfaceverts-2): # Number of triangles in polygon.
- face = Blender.NMesh.Face()
- face.v.append(mesh.verts[faces[i][a]])
- face.v.append(mesh.verts[faces[i][b]])
- face.v.append(mesh.verts[faces[i][c]])
- b = c; c += 1
- mesh.faces.append(face)
- #face.smooth = 1
-
-# ===================================
-# === Append Verts to Vertex List ===
-# ===================================
-def append_verts(mesh, verts, normals):
- #print "Number of normals:", len(normals)
- #print "Number of verts :", len(verts)
- for i in xrange(len(verts)):
- if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts")
- x, y, z = verts[i]
- mesh.verts.append(Blender.NMesh.Vert(x, y, z))
- if normals:
- mesh.verts[i].no[0] = normals[i][0]
- mesh.verts[i].no[1] = normals[i][1]
- mesh.verts[i].no[2] = normals[i][2]
-
-# ===========================
-# === Create Blender Mesh ===
-# ===========================
-def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]):
- if normals: normal_flag = 0
- else: normal_flag = 1
- mesh = Blender.NMesh.GetRaw()
- append_verts(mesh, verts, normals)
- append_faces(mesh, faces, facesuv, uvcoords)
- if not overwrite_mesh_name:
- objname = versioned_name(objname)
- ob= Blender.NMesh.PutRaw(mesh, objname, normal_flag) # Name the Mesh
- ob.name= objname # Name the Object
- Blender.Redraw()
-
-# ==============================
-# === Increment Name Version ===
-# ==============================
-def versioned_name(objname):
- existing_names = []
- for object in Blender.Object.Get():
- existing_names.append(object.name)
- existing_names.append(object.getData(name_only=1))
- if objname in existing_names: # don't over-write other names
- try:
- name, ext = objname.split('.')
- except ValueError:
- name, ext = objname, ''
- try:
- num = int(ext)
- root = name
- except ValueError:
- root = objname
- for i in xrange(1, 1000):
- objname = "%s.%03d" % (root, i)
- if objname not in existing_names:
- break
- return objname
-
-# ===========================
-# === Print Text In A Box ===
-# ===========================
-def print_boxed(text):
- lines = text.splitlines()
- maxlinelen = max(map(len, lines))
- if sys.platform[:3] == "win":
- print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191)
- for line in lines:
- print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179)
- print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217)
- else:
- print '+-' + '-'*maxlinelen + '-+'
- for line in lines: print '| ' + line.ljust(maxlinelen) + ' |'
- print '+-' + '-'*maxlinelen + '-+'
- print '\a\r', # beep when done
-
-# ===============================================
-# === Get euler angles from a rotation matrix ===
-# ===============================================
-def mat2euler(mat):
- angle_y = -math.asin(mat[0][2])
- c = math.cos(angle_y)
- if math.fabs(c) > 0.005:
- angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c)
- angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c)
- else:
- angle_x = 0.0
- angle_z = -math.atan2(mat[1][0], mat[1][1])
- return (angle_x, angle_y, angle_z)
-
-# ==========================
-# === Transpose A Matrix ===
-# ==========================
-def transpose(A):
- S = len(A)
- T = len(A[0])
- B = [[None]*S for i in xrange(T)]
- for i in xrange(T):
- for j in xrange(S):
- B[i][j] = A[j][i]
- return B
-
-# =======================
-# === Apply Transform ===
-# =======================
-def apply_transform(vertex, matrix):
- x, y, z = vertex
- xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]
- xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc
- ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc
- zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc
- vertex = [xcomponent, ycomponent, zcomponent]
- return vertex
-
-# =========================
-# === Has Vertex Colors ===
-# =========================
-def has_vertex_colors(mesh):
- # My replacement/workaround for hasVertexColours()
- # The docs say:
- # "Warning: If a mesh has both vertex colours and textured faces,
- # this function will return False. This is due to the way Blender
- # deals internally with the vertex colours array (if there are
- # textured faces, it is copied to the textured face structure and
- # the original array is freed/deleted)."
- try:
- return mesh.faces[0].col[0]
- except:
- return 0
-
-# ===========================
-# === Generate Edge Table ===
-# ===========================
-def generate_edgetable(mesh):
- edge_table = {}
- numfaces = len(mesh.faces)
-
- for i in xrange(numfaces):
- if not i%100 and show_progress:
- Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table")
- if len(mesh.faces[i].v) == 4: # Process Quadrilaterals
- generate_entry_from_quad(mesh, i, edge_table)
- elif len(mesh.faces[i].v) == 3: # Process Triangles
- generate_entry_from_tri(mesh, i, edge_table)
- else: # Skip This Face
- print "Face #", i, "was skipped."
-
- # === Sort Edge_Table Keys & Add Edge Indices ===
- i = 0
- keys = edge_table.keys()
- keys.sort()
- for key in keys:
- edge_table[key][6] = i
- i += 1
-
- # === Replace Tuples With Indices ===
- for key in keys:
- for i in [2,3,4,5]:
- if edge_table.has_key(edge_table[key][i]):
- edge_table[key][i] = edge_table[edge_table[key][i]][6]
- else:
- keyrev = (edge_table[key][i][1], edge_table[key][i][0])
- edge_table[key][i] = edge_table[keyrev][6]
-
- return edge_table
-
-# ================================
-# === Generate Entry From Quad ===
-# ================================
-def generate_entry_from_quad(mesh, i, edge_table):
- vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v
-
- if has_vertex_colors(mesh):
- vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col
- Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
- Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
- Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
- Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0)
-
- # === verts are upper case, edges are lower case ===
- A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index
- a, b, c, d = (A, B), (B, C), (C, D), (D, A)
-
- if edge_table.has_key((B, A)):
- edge_table[(B, A)][1] = i
- edge_table[(B, A)][4] = d
- edge_table[(B, A)][5] = b
- if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
- else:
- if has_vertex_colors(mesh):
- edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None]
- else:
- edge_table[(A, B)] = [i, None, d, b, None, None, None]
-
- if edge_table.has_key((C, B)):
- edge_table[(C, B)][1] = i
- edge_table[(C, B)][4] = a
- edge_table[(C, B)][5] = c
- if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
- else:
- if has_vertex_colors(mesh):
- edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
- else:
- edge_table[(B, C)] = [i, None, a, c, None, None, None]
-
- if edge_table.has_key((D, C)):
- edge_table[(D, C)][1] = i
- edge_table[(D, C)][4] = b
- edge_table[(D, C)][5] = d
- if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol
- else:
- if has_vertex_colors(mesh):
- edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None]
- else:
- edge_table[(C, D)] = [i, None, b, d, None, None, None]
-
- if edge_table.has_key((A, D)):
- edge_table[(A, D)][1] = i
- edge_table[(A, D)][4] = c
- edge_table[(A, D)][5] = a
- if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol
- else:
- if has_vertex_colors(mesh):
- edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None]
- else:
- edge_table[(D, A)] = [i, None, c, a, None, None, None]
-
-# ====================================
-# === Generate Entry From Triangle ===
-# ====================================
-def generate_entry_from_tri(mesh, i, edge_table):
- vertex3, vertex2, vertex1 = mesh.faces[i].v
-
- if has_vertex_colors(mesh):
- vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col
- Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
- Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
- Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
-
- # === verts are upper case, edges are lower case ===
- A, B, C = vertex1.index, vertex2.index, vertex3.index
- a, b, c = (A, B), (B, C), (C, A)
-
- if edge_table.has_key((B, A)):
- edge_table[(B, A)][1] = i
- edge_table[(B, A)][4] = c
- edge_table[(B, A)][5] = b
- if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
- else:
- if has_vertex_colors(mesh):
- edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None]
- else:
- edge_table[(A, B)] = [i, None, c, b, None, None, None]
-
- if edge_table.has_key((C, B)):
- edge_table[(C, B)][1] = i
- edge_table[(C, B)][4] = a
- edge_table[(C, B)][5] = c
- if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
- else:
- if has_vertex_colors(mesh):
- edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
- else:
- edge_table[(B, C)] = [i, None, a, c, None, None, None]
-
- if edge_table.has_key((A, C)):
- edge_table[(A, C)][1] = i
- edge_table[(A, C)][4] = b
- edge_table[(A, C)][5] = a
- if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol
- else:
- if has_vertex_colors(mesh):
- edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None]
- else:
- edge_table[(C, A)] = [i, None, b, a, None, None, None]
-
diff --git a/release/scripts/bpymodules/paths_ai2obj.py b/release/scripts/bpymodules/paths_ai2obj.py
deleted file mode 100644
index 6eb5023a8d4..00000000000
--- a/release/scripts/bpymodules/paths_ai2obj.py
+++ /dev/null
@@ -1,506 +0,0 @@
-# -*- coding: latin-1 -*-
-"""
-paths_ai2obj.py
-# ---------------------------------------------------------------
-Copyright (c) jm soler juillet/novembre 2004-april 2007,
-# ---------------------------------------------------------------
- released under GNU Licence
- for the Blender 2.45 Python Scripts Bundle.
-Ce programme est libre, vous pouvez le redistribuer et/ou
-le modifier selon les termes de la Licence Publique Générale GNU
-publiée par la Free Software Foundation (version 2 ou bien toute
-autre version ultérieure choisie par vous).
-
-Ce programme est distribué car potentiellement utile, mais SANS
-AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties
-de commercialisation ou d'adaptation dans un but spécifique.
-Reportez-vous à la Licence Publique Générale GNU pour plus de détails.
-
-Vous devez avoir reçu une copie de la Licence Publique Générale GNU
-en même temps que ce programme ; si ce n'est pas le cas, écrivez à la
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307, États-Unis.
-
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# ---------------------------------------------------------------
-#----------------------------------------------
-#
-# Page officielle :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_ai_en.htm
-# Communiquer les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#----------------------------------------------
-
-#Changelog
-#----------------------------------------------
-# 0.1.1 : 2004/08/03, bug in boundingbox reading when Value are negative
-# 0.1.2 : 2005/06/12, gmove tranformation properties
-# 0.1.3 : 2005/06/25, added a __name__ test to use the script alone
-# 0.1.4 : 2005/06/25, closepath improvements
-# 0.1.5 : 2005/06/25, ...
-# 0.1.6 : 2005/06/26, warning for compacted file
- compatibility increased up to AI 10.0 plain text
-# 0.1.7 : 2005/06/25, two more closepath improvements
-#
-# 0.1.8 : 2006/07/03, two more closepath improvements
-# 0.1.9 : 2007/05/06, modif on the method that gets the last object on
- the list data
-# 2008/03/12, Added character encoding line so french text
-# does not break python interpreters.
-
-"""
-SHARP_IMPORT=0
-SCALE=1
-NOTHING_TODO=1
-AI_VERSION=''
-
-GSTACK = []
-GSCALE = []
-GTRANSLATE = []
-
-import sys
-#oldpath=sys.path
-import Blender
-BLversion=Blender.Get('version')
-
-try:
- import nt
- os=nt
- os.sep='\\'
-
-except:
- import posix
- os=posix
- os.sep='/'
-
-def isdir(path):
- try:
- st = os.stat(path)
- return 1
- except:
- return 0
-
-def split(pathname):
- if pathname.find(os.sep)!=-1:
- k0=pathname.split(os.sep)
- else:
- if os.sep=='/':
- k0=pathname.split('\\')
- else:
- k0=pathname.split('/')
-
- directory=pathname.replace(k0[len(k0)-1],'')
- Name=k0[len(k0)-1]
- return directory, Name
-
-def join(l0,l1):
- return l0+os.sep+l1
-
-os.isdir=isdir
-os.split=split
-os.join=join
-
-def filtreFICHIER(nom):
- f=open(nom,'rU')
- t=f.readlines()
- f.close()
-
- if len(t)>1 and t[0].find('EPSF')==-1:
- return t
- else:
- name = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1
- result = Blender.Draw.PupMenu(name)
-
- return 'false'
-
-#===============================
-# Data
-#===============================
-#===============================
-# Blender Curve Data
-#===============================
-objBEZIER=0
-objSURFACE=5
-typBEZIER3D=1 #3D
-typBEZIER2D=9 #2D
-
-class Bez:
- def __init__(self):
- self.co=[]
- self.ha=[0,0]
- self.tag=''
-
-class ITEM:
- def __init__(self):
- self.type = typBEZIER3D,
- self.pntsUV = [0,0]
- self.resolUV = [32,0]
- self.orderUV = [0,0]
- self.flagUV = [0,0]
- self.Origine = [0.0,0.0]
- self.beziers_knot = []
-
-class COURBE:
- def __init__(self):
- self.magic_number='3DG3'
- self.type = objBEZIER
- self.number_of_items = 0
- self.ext1_ext2 = [0,0]
- self.matrix = """0.0 0.0 1.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 """
- self.ITEM = {}
-
-courbes=COURBE()
-
-PATTERN={}
-
-BOUNDINGBOX={'rec':[],'coef':1.0}
-npat=0
-#=====================================================================
-#======== name of the curve in teh courbes dictionnary ===============
-#=====================================================================
-n0=0
-
-#=====================================================================
-#====================== current Point ================================
-#=====================================================================
-CP=[0.0,0.0] #currentPoint
-
-
-# modifs 12/06/2005
-#=====================================================================
-#====================== current transform ============================
-#=====================================================================
-class transform:
- def __init__(self,matrix=[1,0,01],x=0.0,y=0.0):
- self.matrix=matrix[:]
- self.xy=[x,y]
-
-def G_move(l,a):
- global GSCALE, GTRANSLATE, GSTACK
- #print GSCALE, GTRANSLATE, GSTACK
- return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a])
-# modifs 12/06/2005
-
-
-#=====================================================================
-#===== to compare last position to the original move to displacement =
-#===== needed for cyclic efinition =================================
-#=====================================================================
-def test_egalitedespositions(f1,f2):
- if f1[0]==f2[0] and f1[1]==f2[1]:
- return Blender.TRUE
- else:
- return Blender.FALSE
-
-
-def Open_GEOfile(dir,nom):
- if BLversion>=233:
- in_editmode = Blender.Window.EditMode()
- if in_editmode: Blender.Window.EditMode(0)
- Blender.Load(dir+nom+'OOO.obj', 1)
- BO=Blender.Scene.GetCurrent().objects.active
- BO.RotY=0.0
- BO.RotX=1.57
- BO.makeDisplayList()
- Blender.Window.RedrawAll()
- else:
- print "Not yet implemented"
-
-def create_GEOtext(courbes):
- global SCALE, B, BOUNDINGBOX
- r=BOUNDINGBOX['rec']
-
- if SCALE==1:
- SCALE=1.0
- elif SCALE==2:
- SCALE=r[2]-r[0]
- elif SCALE==3:
- SCALE=r[3]-r[1]
-
- t=[]
- t.append(courbes.magic_number+'\n')
- t.append(str(courbes.type)+'\n')
- t.append(str(courbes.number_of_items)+'\n')
- t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n')
- t.append(courbes.matrix+'\n')
-
- for k in courbes.ITEM.keys():
- if len(courbes.ITEM[k].beziers_knot)>1 :
- t.append("%s\n"%courbes.ITEM[k].type)
- t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1]))
-
- flag =courbes.ITEM[k].flagUV[0]
-
- for k2 in range(len(courbes.ITEM[k].beziers_knot)):
- #print k2
- k1 =courbes.ITEM[k].beziers_knot[k2]
- t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE))
- t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE))
- t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE))
-
- t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n')
- return t
-
-def save_GEOfile(dir,nom,t):
- f=open(dir+nom+'OOO.obj','w')
- f.writelines(t)
- f.close()
- #warning = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1"
- #result = Blender.Draw.PupMenu(warning)
-
-
-#=====================================================================
-#===== AI format : DEBUT =========================
-#=====================================================================
-def mouvement_vers(l,n0,CP):
- if n0 in courbes.ITEM.keys():
- n0+=1
-
- CP=[l[-3].replace('d',''),l[-2]]
- courbes.ITEM[n0]=ITEM()
- courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]]
-
- B=Bez()
- B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]]
- B.ha=[0,0]
- B.tag=l[-1]
-
- courbes.ITEM[n0].beziers_knot.append(B)
-
- return courbes,n0,CP
-
-def courbe_vers_c(l,l2, n0,CP): #c,C
-
- B=Bez()
- B.co=[l[4],l[5],l[2],l[3],l[4],l[5]]
- B.tag=l[-1]
- B.ha=[0,0]
-
- BP=courbes.ITEM[n0].beziers_knot[-1]
-
- BP.co[0]=l[0]
- BP.co[1]=l[1]
-
- courbes.ITEM[n0].beziers_knot.append(B)
-
- CP=[B.co[4],B.co[5]]
- return courbes,n0,CP
-
-
-def courbe_vers_v(l,n0,CP): #v-V
-
- B=Bez()
- B.tag=l[-1]
- B.co=[l[2],l[3],l[0],l[1],l[2],l[3]]
- B.ha=[0,0]
-
- courbes.ITEM[n0].beziers_knot.append(B)
-
- CP=[B.co[4],B.co[5]]
- return courbes,n0,CP
-
-def courbe_vers_y(l,n0,CP): #y
- B=Bez()
- B.tag=l[-1]
- B.co=[l[2],l[3],l[2],l[3],l[2],l[3]]
- B.ha=[0,0]
-
- BP=courbes.ITEM[n0].beziers_knot[-1]
- BP.co[0]=l[0]
- BP.co[1]=l[1]
-
- courbes.ITEM[n0].beziers_knot.append(B)
- CP=[B.co[4],B.co[5]]
- return courbes,n0,CP
-
-
-def ligne_tracee_l(l,n0,CP):
- B=Bez()
- B.tag=l[-1]
- B.co=[l[0],l[1],l[0],l[1],l[0],l[1]]
- B.ha=[0,0]
-
- BP=courbes.ITEM[n0].beziers_knot[-1]
-
- courbes.ITEM[n0].beziers_knot.append(B)
- CP=[B.co[4],B.co[5]]
- return courbes,n0,CP
-
-def ligne_fermee(l,n0,CP):
- courbes.ITEM[n0].flagUV[0]=1
-
- if len(courbes.ITEM[n0].beziers_knot)>1:
- BP=courbes.ITEM[n0].beziers_knot[-1]
- BP0=courbes.ITEM[n0].beziers_knot[0]
-
- if BP.tag not in ['l','L']:
- BP.co[0]=BP0.co[0] #4-5 point prec
- BP.co[1]=BP0.co[1]
-
- del courbes.ITEM[n0].beziers_knot[0]
- return courbes,n0,CP
-
-def passe(l,n0,CP):
- return courbes,n0,CP
-
-Actions= { "C" : courbe_vers_c,
- "c" : courbe_vers_c,
- "V" : courbe_vers_v,
- "v" : courbe_vers_v,
- "Y" : courbe_vers_y,
- "y" : courbe_vers_y,
- "m" : mouvement_vers,
- "l" : ligne_tracee_l,
- "L" : ligne_tracee_l,
- "F" : passe,
- "f" : ligne_fermee,
- "B" : passe,
- "b" : ligne_fermee,
- "S" : passe,
- "s" : ligne_fermee,
- "N" : ligne_fermee,
- "n" : passe,
- }
-
-TAGcourbe=Actions.keys()
-
-def pik_pattern(t,l):
- global npat, PATTERN, BOUNDINGBOX, AI_VERSION
- while t[l].find('%%EndSetup')!=0:
- if t[l].find('%%Creator: Adobe Illustrator(R)')!=-1:
- print t[l]
- AI_VERSION=t[l].split()[-1]
- print AI_VERSION
-
- if t[l].find('%%BoundingBox:')!=-1:
- t[l]=t[l][t[l].find(':')+1:]
- l0=t[l].split()
- BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])]
- r=BOUNDINGBOX['rec']
- BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0])
- #print l,
- if t[l].find('BeginPattern')!=-1:
- nomPattern=t[l][t[l].find('(')+1:t[l].find(')')]
- PATTERN[nomPattern]={}
-
- if t[l].find('BeginPatternLayer')!=-1:
- npat+=1
- PATTERN[nomPattern][npat]=[]
- while t[l].find('EndPatternLayer')==-1:
- #print t[l]
- PATTERN[nomPattern][npat].append(l)
- l+=1
- if l+1<len(t):
- l=l+1
- else:
- return 1,l
- return 1,l
-
-def scan_FILE(nom):
- global CP, courbes, SCALE, NOTHING_TODO
- dir,name=split(nom)
- name=name.split('.')
- n0=0
- result=0
- t=filtreFICHIER(nom)
-
- if nom.upper().find('.AI')!=-1 and t!='false':
- if not SHARP_IMPORT:
- warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3"
- SCALE = Blender.Draw.PupMenu(warning)
-
- npat=0
- l=0
- do=0
- while l <len(t)-1 :
- if not do:
- do,l=pik_pattern(t,l)
- #print 'len(t)',len(t)
- t[l].replace('\n','')
- if t[l].find('%%EOF')==0:
- break
- if t[l][0]!='%':
- l0=t[l].split()
- #print l0
- if l0[0][0] in ['F','f','N','n','B','b']:
- l3=l0[0][0]
- courbes,n0,CP=Actions[l3](l3,n0,CP)
- l0[0]=l0[1:]
-
- if l0[-1] in TAGcourbe:
- NOTHING_TODO=0
- if l0[-1] in ['C','c']:
- l2=t[l+1].split()
- courbes,n0,CP=Actions[l0[-1]](l0,l2,n0,CP)
- else:
- courbes,n0,CP=Actions[l0[-1]](l0,n0,CP)
- l=l+1; #print l
- t=[]
-
-
- courbes.number_of_items=len(courbes.ITEM.keys())
- for k in courbes.ITEM.keys():
- courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot)
-
-
- if courbes.number_of_items>0:
- if len(PATTERN.keys() )>0:
- #print len(PATTERN.keys() )
- warning = "Pattern list (for info not used): %t| "
- p0=1
- for P in PATTERN.keys():
- warning+="%s %%x%s|"%(P,p0)
- p0+=1
- Padd = Blender.Draw.PupMenu(warning)
-
- t=create_GEOtext(courbes)
- save_GEOfile(dir,name[0],t)
-
- # 0.1.8 ---------------------------------
- # [O.select(0) for O in Blender.Scene.getCurrent().getChildren()]
- # 0.1.8 ---------------------------------
-
- Open_GEOfile(dir,name[0])
-
- # 0.1.8 ---------------------------------
- Blender.Object.Get()[-1].setName(name[0])
- # 0.1.8 ---------------------------------
-
- else:
- pass
-#=====================================================================
-#====================== AI format mouvements =========================
-#=====================================================================
-#=========================================================
-# une sorte de contournement qui permet d'utiliser la fonction
-# et de documenter les variables Window.FileSelector
-#=========================================================
-def fonctionSELECT(nom):
- global NOTHING_TODO,AI_VERSION
- scan_FILE(nom)
- if NOTHING_TODO==1:
- warning = "AI %s compatible file "%AI_VERSION+" but nothing to do ? %t| Perhaps a compacted file ... "
- NOTHING = Blender.Draw.PupMenu(warning)
-
-if __name__=="__main__":
- Blender.Window.FileSelector (fonctionSELECT, 'SELECT AI FILE')
-#sys.path=oldpath
diff --git a/release/scripts/bpymodules/paths_eps2obj.py b/release/scripts/bpymodules/paths_eps2obj.py
deleted file mode 100644
index e1643c3bf40..00000000000
--- a/release/scripts/bpymodules/paths_eps2obj.py
+++ /dev/null
@@ -1,452 +0,0 @@
-#----------------------------------------------
-# (c) jm soler juillet 2004-juin 2005 , released under Blender Artistic Licence
-# for the Blender 2.34-2.37 Python Scripts Bundle.
-#
-# last update: 06/05/2007
-#----------------------------------------------
-# Page officielle :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_eps.htm
-# Communiquer les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#----------------------------------------------
-SHARP_IMPORT = 0
-SCALE = 1.0
-scale = 1
-
-import sys
-#oldpath=sys.path
-
-import Blender
-from Blender import Draw
-BLversion=Blender.Get('version')
-
-try:
- import nt
- os=nt
- os.sep='\\'
-
-except:
- import posix
- os=posix
- os.sep='/'
-
-def isdir(path):
- try:
- st = os.stat(path)
- return 1
- except:
- return 0
-
-def split(pathname):
- if pathname.find(os.sep)!=-1:
- k0=pathname.split(os.sep)
- else:
- if os.sep=='/':
- k0=pathname.split('\\')
- else:
- k0=pathname.split('/')
-
- directory=pathname.replace(k0[len(k0)-1],'')
- Name=k0[len(k0)-1]
- return directory, Name
-
-def join(l0,l1):
- return l0+os.sep+l1
-
-os.isdir=isdir
-os.split=split
-os.join=join
-
-def filtreFICHIER(nom):
- f=open(nom,'rU')
- t=f.readlines()
- f.close()
- if len(t)==1 and t[0].find('\r'):
- t=t[0].split('\r')
- if len(t)>1 and t[0].find('PS-Adobe-3.0')==-1 and t[0].find('EPSF')==-1:
- return t
- else:
- name = "OK?%t| Not a valid file or an empty file or... %x1| not a pure PS-Adobe-2.0 file %x2 "
- result = Blender.Draw.PupMenu(name)
- return 'false'
-
-#===============================
-# Data
-#===============================
-#===============================
-# Blender Curve Data
-#===============================
-objBEZIER=0
-objSURFACE=5
-typBEZIER3D=1 #3D
-typBEZIER2D=9 #2D
-
-class Bez:
- def __init__(self):
- self.co=[]
- self.ha=[0,0]
-
-class ITEM:
- def __init__(self):
- self.type = typBEZIER3D,
- self.pntsUV = [0,0]
- self.resolUV = [32,0]
- self.orderUV = [0,0]
- self.flagUV = [0,0]
- self.Origine = [0.0,0.0]
- self.beziers_knot = []
-
-class COURBE:
- def __init__(self):
- self.magic_number='3DG3'
- self.type = objBEZIER
- self.number_of_items = 0
- self.ext1_ext2 = [0,0]
- self.matrix = """0.0 0.0 1.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 """ #- right-handed object matrix. Used to determine position, rotation and size
- self.ITEM = {}
-
-courbes=COURBE()
-PATTERN={}
-BOUNDINGBOX={'rec':[],'coef':1.0}
-npat=0
-#=====================================================================
-#======== name of the curve in teh courbes dictionnary ===============
-#=====================================================================
-n0=0
-
-#=====================================================================
-#====================== current Point ================================
-#=====================================================================
-CP=[0.0,0.0] #currentPoint
-
-# modifs 12/06/2005
-#=====================================================================
-#====================== current transform ============================
-#=====================================================================
-class transform:
- def __init__(self,matrix=[1,0,01],x=0.0,y=0.0):
- self.matrix=matrix[:]
- self.xy=[x,y]
-
-GSTACK = []
-stack=transform()
-GSTACK.append(stack)
-
-GSCALE = [1.0,1.0]
-GTRANSLATE = [0.0,0.0]
-
-def G_move(l,a):
- global GSCALE, GTRANSLATE, GSTACK
- #print GSCALE, GTRANSLATE, GSTACK
- return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a])
-# modifs 12/06/2005
-
-#=====================================================================
-#===== to compare last position to the original move to displacement =
-#===== needed for cyclic efinition =================================
-#=====================================================================
-def test_egalitedespositions(f1,f2):
- if f1[0]==f2[0] and f1[1]==f2[1]:
- return Blender.TRUE
- else:
- return Blender.FALSE
-
-
-def Open_GEOfile(dir,nom):
- global SCALE,BOUNDINGBOX, scale
- if BLversion>=233:
- Blender.Load(dir+nom+'OOO.obj', 1)
- BO=Blender.Scene.GetCurrent().objects.active
- BO.RotY=3.1416
- BO.RotZ=3.1416
- BO.RotX=3.1416/2.0
- if scale==1:
- BO.LocY+=BOUNDINGBOX['rec'][3]
- else:
- BO.LocY+=BOUNDINGBOX['rec'][3]/SCALE
-
- BO.makeDisplayList()
- Blender.Window.RedrawAll()
- else:
- print "Not yet implemented"
-
-def create_GEOtext(courbes):
- global SCALE, B, BOUNDINGBOX,scale
- r=BOUNDINGBOX['rec']
-
- if scale==1:
- SCALE=1.0
- elif scale==2:
- SCALE=r[2]-r[0]
- elif scale==3:
- SCALE=r[3]-r[1]
-
- t=[]
- t.append(courbes.magic_number+'\n')
- t.append(str(courbes.type)+'\n')
- t.append(str(courbes.number_of_items)+'\n')
- t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n')
- t.append(courbes.matrix+'\n')
-
- for k in courbes.ITEM.keys():
- t.append("%s\n"%courbes.ITEM[k].type)
- t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1]))
-
- flag =courbes.ITEM[k].flagUV[0]
-
- for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)):
- k1 =courbes.ITEM[k].beziers_knot[k2]
- t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE))
- t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE))
- t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE))
- t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n')
- return t
-
-def save_GEOfile(dir,nom,t):
- f=open(dir+nom+'OOO.obj','w')
- f.writelines(t)
- f.close()
-
- #name = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1"
- #result = Blender.Draw.PupMenu(name)
-
-
-#=====================================================================
-#===== EPS format : DEBUT =========================
-#=====================================================================
-def mouvement_vers(l,n0,CP):
- if n0 in courbes.ITEM.keys():
- #if test_egalitedespositions(courbes.ITEM[n0].Origine,CP):
- # courbes.ITEM[n0].flagUV[0]=1
- n0+=1
- CP=[l[-3].replace('d',''),l[-2]]
- else:
- CP=[l[-3].replace('d',''),l[-2]]
- #i=
- courbes.ITEM[n0]=ITEM()
- courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]]
-
- B=Bez()
- B.co=[G_move(CP[0],0),
- G_move(CP[1],1),
- G_move(CP[0],0),
- G_move(CP[1],1),
- G_move(CP[0],0),
- G_move(CP[1],1)]
-
- B.ha=[0,0]
- courbes.ITEM[n0].beziers_knot.append(B)
-
- return courbes,n0,CP
-
-def rmouvement_vers(l,n0,CP):
- if n0 in courbes.ITEM.keys():
- #if test_egalitedespositions(courbes.ITEM[n0].Origine,CP):
- # courbes.ITEM[n0].flagUV[0]=1
- n0+=1
- CP=["%4f"%(float(l[-3])+float(CP[0])),"%4f"%(float(l[-2])+float(CP[1]))]
- else:
- CP=["%4f"%(float(l[-3])+float(CP[0])),"%4f"%(float(l[-2])+float(CP[1]))]
- #i=
- courbes.ITEM[n0]=ITEM()
- courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]]
-
- B=Bez()
- B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]]
- B.ha=[0,0]
- courbes.ITEM[n0].beziers_knot.append(B)
- return courbes,n0,CP
-
-def courbe_vers_c(l, l2, n0,CP): #c,C
- """
- B=Bez()
- B.co=[l[0],l[1],l[2],l[3],l[4],l[5]]
- B.ha=[0,0]
-
- courbes.ITEM[n0].beziers_knot.append(B)
- """
- B=Bez()
- B.co=[G_move(l[2],0),
- G_move(l[3],1),
- G_move(l[4],0),
- G_move(l[5],1),
- G_move(l[0],0),
- G_move(l[1],1)]
- if len(courbes.ITEM[n0].beziers_knot)==1:
- CP=[l[0],l[1]]
- courbes.ITEM[n0].Origine=[l[0],l[1]]
- if l[-1]=='C':
- B.ha=[2,2]
- else:
- B.ha=[0,0]
- courbes.ITEM[n0].beziers_knot.append(B)
- if len(l2)>1 and l2[-1] in Actions.keys():
- B.co[-2]=G_move(l2[0],0)
- B.co[-1]=G_move(l2[1],1)
- else:
- B.co[-2]=G_move(CP[0],0)
- B.co[-1]=G_move(CP[1],1)
- return courbes,n0,CP
-
-def ligne_tracee_l(l,n0,CP):
- B=Bez()
- B.co=[G_move(l[0],0),
- G_move(l[1],1),
- G_move(l[0],0),
- G_move(l[1],1),
- G_move(l[0],0),
- G_move(l[1],1)]
- B.ha=[0,0]
- courbes.ITEM[n0].beziers_knot.append(B)
- CP=[l[0],l[1]]
- return courbes,n0,CP
-
-def rligne_tracee_l(l,n0,CP):
- B=Bez()
- B.co=["%4f"%(float(l[0])+float(CP[0])),
- "%4f"%(float(l[1])+float(CP[1])),
- "%4f"%(float(l[0])+float(CP[0])),
- "%4f"%(float(l[1])+float(CP[1])),
- "%4f"%(float(l[0])+float(CP[0])),
- "%4f"%(float(l[1])+float(CP[1]))]
- B.ha=[0,0]
- courbes.ITEM[n0].beziers_knot.append(B)
- CP=[l[0],l[1]]
- return courbes,n0,CP
-
-Actions= { "curveto" : courbe_vers_c,
- "curveto" : courbe_vers_c,
- "moveto" : mouvement_vers,
- "rmoveto" : mouvement_vers,
- "lineto" : ligne_tracee_l,
- "rlineto" : rligne_tracee_l
-}
-
-TAGcourbe=Actions.keys()
-
-"""
-def pik_pattern(t,l):
- global npat, PATTERN, BOUNDINGBOX
- while t[l].find('%%EndSetup')!=0:
- if t[l].find('%%BoundingBox:')!=-1:
- l0=t[l].split()
- BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])]
- r=BOUNDINGBOX['rec']
- BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0])
- print l,
- if t[l].find('BeginPatternLayer')!=-1:
- npat+=1
- PATTERN[npat]=[]
- while t[l].find('EndPatternLayer')==-1:
- print t[l]
- PATTERN[npat].append(l)
- l+=1
- if l+1<len(t):
- l=l+1
- else:
- return 1,l
- return 1,l
-"""
-
-def scan_FILE(nom):
- global CP, courbes, SCALE, scale, GSTACK, GSCALE, GTRANSLATE
- dir,name=split(nom)
- name=name.split('.')
- n0=0
- result=0
- t=filtreFICHIER(nom)
- #print t
- if t!='false' and (nom.upper().find('.EPS')!=-1 or nom.upper().find('.PS')!=-1 ):
- if not SHARP_IMPORT:
- warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3"
- scale = Blender.Draw.PupMenu(warning)
- npat=0
- l=0
- do=0
- while l <len(t)-1 :
- if t[l].find('%%BoundingBox:')!=-1:
- l0=t[l].split()
- BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])]
- r=BOUNDINGBOX['rec']
- BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0])
- """
- if not do:
- do,l=pik_pattern(t,l)
- """
- #print 'len(t)',len(t)
- t[l].replace('\n','')
- if t[l][0]!='%':
- l0=t[l].split()
- if l0!=[] and l0[-1] in TAGcourbe:
- if l0[-1] in ['curveto']:
- l2=t[l+1].split()
- courbes,n0,CP=Actions[l0[-1]](l0,l2,n0,CP)
- else:
- courbes,n0,CP=Actions[l0[-1]](l0,n0,CP)
- # modifs 10/06/2005
- elif l0!=[] and l0[-1] in ['scale']:
- GSCALE=[float(l0[-3]),float(l0[-2])]
- elif l0!=[] and l0[-1] in ['translate']:
- GTRANSLATE=[float(l0[-3]),float(l0[-2])]
- elif l0!=[] and l0[-1] in ['concat'] and l0[0] in ['gsave']:
- l0[1]=l0[1].replace('[','')
- l0[-2]=l0[-2].replace(']','')
- stack=transform([float(l0[1]),float(l0[2]),float(l0[3]),float(l0[4])],float(l0[5]),float(l0[6]))
- GSTACK.append(stack)
- #print GSTACK
- elif l0!=[] and l0[-1] in ['concat'] and l0[0] in ['grestore']:
- del GSTACK[-1]
- # modifs 12/06/2005 : end
-
-
- l=l+1#; print l
- t=[]
-
- if t!='false':
- courbes.number_of_items=len(courbes.ITEM.keys())
-
- for k in courbes.ITEM.keys():
- courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot)
-
- if test_egalitedespositions(courbes.ITEM[k].Origine,
- [courbes.ITEM[k].beziers_knot[-1].co[-2],
- courbes.ITEM[k].beziers_knot[-1].co[-1]]):
- courbes.ITEM[k].flagUV[0]=1
- courbes.ITEM[k].pntsUV[0] -=1
-
- if courbes.number_of_items>0:
- if len(PATTERN.keys() )>0:
- #print len(PATTERN.keys() )
- pass
- t=create_GEOtext(courbes)
- save_GEOfile(dir,name[0],t)
- Open_GEOfile(dir,name[0])
-
- # 03 juillet 2006 ----------------------
- Blender.Object.Get()[-1].setName(name[0])
- # 03 juillet 2006 ----------------------
-
- else:
- pass
-
-
-#=====================================================================
-#====================== EPS format mouvements =========================
-#=====================================================================
-#=========================================================
-# une sorte de contournement qui permet d'utiliser la fonction
-# et de documenter les variables Window.FileSelector
-#=========================================================
-def fonctionSELECT(nom):
- scan_FILE(nom)
-
-if __name__=="__main__":
- Blender.Window.FileSelector (fonctionSELECT, 'SELECT EPS FILE')
-
-
diff --git a/release/scripts/bpymodules/paths_gimp2obj.py b/release/scripts/bpymodules/paths_gimp2obj.py
deleted file mode 100644
index c2ce9718c71..00000000000
--- a/release/scripts/bpymodules/paths_gimp2obj.py
+++ /dev/null
@@ -1,363 +0,0 @@
-# -*- coding: latin-1 -*-
-"""
-#----------------------------------------------
-# (c) jm soler juillet 2004,
-#----------------------------------------------
- released under GNU Licence
- for the Blender 2.45 Python Scripts Bundle.
-Ce programme est libre, vous pouvez le redistribuer et/ou
-le modifier selon les termes de la Licence Publique Générale GNU
-publiée par la Free Software Foundation (version 2 ou bien toute
-autre version ultérieure choisie par vous).
-
-Ce programme est distribué car potentiellement utile, mais SANS
-AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties
-de commercialisation ou d'adaptation dans un but spécifique.
-Reportez-vous à la Licence Publique Générale GNU pour plus de détails.
-
-Vous devez avoir reçu une copie de la Licence Publique Générale GNU
-en même temps que ce programme ; si ce n'est pas le cas, écrivez à la
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307, États-Unis.
-
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-"""
-
-# ---------------------------------------------------------------
-# last update : 07/05/2007
-#----------------------------------------------
-# Page officielle :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_gimp.htm
-# Communiquer les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-# Modification History:
-# 2008-03-12 Added character encoding line so french text does not break
-# python interpreters.
-#---------------------------------------------
-
-SHARP_IMPORT=0
-SCALE=1
-
-import sys
-#oldpath=sys.path
-
-import Blender
-BLversion=Blender.Get('version')
-
-try:
- import nt
- os=nt
- os.sep='\\'
-
-except:
- import posix
- os=posix
- os.sep='/'
-
-def isdir(path):
- try:
- st = os.stat(path)
- return 1
- except:
- return 0
-
-def split(pathname):
- if pathname.find(os.sep)!=-1:
- k0=pathname.split(os.sep)
- else:
- if os.sep=='/':
- k0=pathname.split('\\')
- else:
- k0=pathname.split('/')
-
- directory=pathname.replace(k0[len(k0)-1],'')
- Name=k0[len(k0)-1]
- return directory, Name
-
-def join(l0,l1):
- return l0+os.sep+l1
-
-os.isdir=isdir
-os.split=split
-os.join=join
-
-def filtreFICHIER(nom):
- f=open(nom,'r')
- t=f.readlines()
- f.close()
- if len(t)==1 and t[0].find('\r'):
- t=t[0].split('\r')
- if len(t)>1 and t[1].find('#POINTS:')==0:
- return t
- else:
- warning = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1
- result = Blender.Draw.PupMenu(warning)
- return "false"
-
-#===============================
-# Data
-#===============================
-#===============================
-# Blender Curve Data
-#===============================
-objBEZIER=0
-objSURFACE=5
-typBEZIER3D=1 #3D
-typBEZIER2D=9 #2D
-
-class Bez:
- def __init__(self):
- self.co=[]
- self.ha=[0,0]
-
- def echo(self):
- #print 'co = ', self.co
- #print 'ha = ', self.ha
- pass
-
-class ITEM:
- def __init__(self):
- self.type = typBEZIER3D,
- self.pntsUV = [0,0]
- self.resolUV = [32,0]
- self.orderUV = [0,0]
- self.flagUV = [0,0]
- self.Origine = [0.0,0.0]
- self.beziers_knot = []
-
-class COURBE:
- def __init__(self):
- self.magic_number='3DG3'
- self.type = objBEZIER
- self.number_of_items = 0
- self.ext1_ext2 = [0,0]
- self.matrix = """0.0 0.0 1.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 """ #- right-handed object matrix. Used to determine position, rotation and size
- self.ITEM = {}
-
-courbes=COURBE()
-PATTERN={}
-BOUNDINGBOX={'rec':[],'coef':1.0}
-npat=0
-#=====================================================================
-#======== name of the curve in the courbes dictionnary ===============
-#=====================================================================
-n0=0
-
-#=====================================================================
-#====================== current Point ================================
-#=====================================================================
-CP=[0.0,0.0] #currentPoint
-
-def MINMAX(b):
- global BOUNDINGBOX
- r=BOUNDINGBOX['rec']
- for m in range(0,len(b)-2,2):
- #print m, m+1 , len(b)-1
- #print b[m], r, r[0]
- if float(b[m])<r[0]:
- r[0]=float(b[m])
-
- if float(b[m])>r[2]: r[2]=float(b[m])
-
- if float(b[m+1])<r[1]: r[1]=float(b[m+1])
- if float(b[m+1])>r[3]: r[3]=float(b[m+1])
-
-#=====================================================================
-#===== to compare last position to the original move to displacement =
-#===== needed for cyclic efinition =================================
-#=====================================================================
-def test_egalitedespositions(f1,f2):
- if f1[0]==f2[0] and f1[1]==f2[1]:
- return Blender.TRUE
- else:
- return Blender.FALSE
-
-
-def Open_GEOfile(dir,nom):
- if BLversion>=233:
- Blender.Load(dir+nom+'OOO.obj', 1)
- BO=Blender.Scene.GetCurrent().objects.active
- BO.LocZ=1.0
- BO.makeDisplayList()
- Blender.Window.RedrawAll()
- else:
- print "Not yet implemented"
-
-def create_GEOtext(courbes):
- global SCALE, B, BOUNDINGBOX
- r=BOUNDINGBOX['rec']
- if SCALE==1:
- SCALE=1.0
- elif SCALE==2:
- SCALE=r[2]-r[0]
- elif SCALE==3:
- SCALE=r[3]-r[1]
-
- t=[]
- t.append(courbes.magic_number+'\n')
- t.append(str(courbes.type)+'\n')
- t.append(str(courbes.number_of_items)+'\n')
- t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n')
- t.append(courbes.matrix+'\n')
-
- for k in courbes.ITEM.keys():
-
- t.append("%s\n"%courbes.ITEM[k].type)
-
- t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1]))
- t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1]))
-
- flag =0#courbes.ITEM[k].flagUV[0]
-
- for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)):
- k1 =courbes.ITEM[k].beziers_knot[k2]
- t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE))
- t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE))
- t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE))
- t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n')
- return t
-
-def save_GEOfile(dir,nom,t):
- f=open(dir+nom+'OOO.obj','w')
- f.writelines(t)
- f.close()
- #warning = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1"
- #result = Blender.Draw.PupMenu(warning)
-
-
-#=====================================================================
-#===== GIMP format : DEBUT =========================
-#=====================================================================
-CLOSED=0
-
-def mouvement_vers(l,l1,l2,n0):
- global BOUNDINGBOX, CP
- if l[1] == '3' :
- n0+=1
- courbes.ITEM[n0]=ITEM()
- courbes.ITEM[n0].Origine=[l[-3],l[-1],]
- courbes.ITEM[n0-1].beziers_knot[0].co[0]=CP[0]
- courbes.ITEM[n0-1].beziers_knot[0].co[1]=CP[1]
- CP=[l2[-3], l2[-1]]
-
- elif l[1]=='1' and (n0 not in courbes.ITEM.keys()):
- courbes.ITEM[n0]=ITEM()
- courbes.ITEM[n0].Origine=[l[-3],l[-1],]
- CP=[l2[-3], l2[-1]]
-
- B=Bez()
- B.co=[ CP[0],CP[1],
- l1[-3], l1[-1],
- l[-3], l[-1]]
-
- CP=[l2[-3], l2[-1]]
-
- if BOUNDINGBOX['rec']==[]:
- BOUNDINGBOX['rec']=[float(l2[-3]), float(l2[-1]), float(l[-3]), float(l[-1])]
- B.ha=[0,0]
-
- """
- if len( courbes.ITEM[n0].beziers_knot)>=1:
- courbes.ITEM[n0].beziers_knot[-1].co[2]=l1[-3]
- courbes.ITEM[n0].beziers_knot[-1].co[3]=l1[-1]
- """
-
- MINMAX(B.co)
- courbes.ITEM[n0].beziers_knot.append(B)
- return courbes,n0
-
-Actions= { "1" : mouvement_vers,
- "3" : mouvement_vers }
-
-TAGcourbe=Actions.keys()
-
-def scan_FILE(nom):
- global CP, courbes, SCALE, MAX, MIN, CLOSED
- dir,name=split(nom)
- name=name.split('.')
- #print name
- n0=0
- result=0
- t=filtreFICHIER(nom)
- if t!="false":
- if not SHARP_IMPORT:
- warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3"
- SCALE = Blender.Draw.PupMenu(warning)
- npat=0
- l=0
- while l <len(t)-1 :
- #print 'len(t)',len(t)
- t[l].replace('\n','')
- if t[l][0]!='%':
- l0=t[l].split()
- #print l0[0], l0[1]
- if l0[0]=='TYPE:' and l0[1] in TAGcourbe:
- #print l0[0], l0[1],
- l1=t[l+1].split()
- l2=t[l+2].split()
- courbes,n0=Actions[l0[1]](l0,l1,l2,n0)
- elif l0[0]=='#Point':
- POINTS= int(l0[0])
- elif l0[0]=='CLOSED:' and l0[1]=='1':
- CLOSED=1
- l=l+1;
-
- courbes.number_of_items=len(courbes.ITEM.keys())
-
- courbes.ITEM[n0].beziers_knot[0].co[0]=CP[0]
- courbes.ITEM[n0].beziers_knot[0].co[1]=CP[1]
-
- for k in courbes.ITEM.keys():
- #print k
- if CLOSED == 1:
- B=Bez()
- B.co=courbes.ITEM[k].beziers_knot[0].co[:]
- B.ha=courbes.ITEM[k].beziers_knot[0].ha[:]
- B.echo()
- courbes.ITEM[k].beziers_knot.append(B)
- courbes.ITEM[k].flagUV[0]=1
- courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot)
-
- if courbes.number_of_items>0:
- t=create_GEOtext(courbes)
- save_GEOfile(dir,name[0],t)
- Open_GEOfile(dir,name[0])
- # 0.1.8 ---------------------------------
- Blender.Object.Get()[-1].setName(name[0])
- # 0.1.8 ---------------------------------
-
- else:
- pass
-
-#=====================================================================
-#====================== GIMP Path format mouvements =========================
-#=====================================================================
-#=========================================================
-# une sorte de contournement qui permet d'utiliser la fonction
-# et de documenter les variables Window.FileSelector
-#=========================================================
-def fonctionSELECT(nom):
- scan_FILE(nom)
-
-if __name__=="__main__":
- Blender.Window.FileSelector (fonctionSELECT, 'SELECT GIMP FILE')
-
diff --git a/release/scripts/bpymodules/paths_svg2obj.py b/release/scripts/bpymodules/paths_svg2obj.py
deleted file mode 100644
index 6bab6dcbfd8..00000000000
--- a/release/scripts/bpymodules/paths_svg2obj.py
+++ /dev/null
@@ -1,1651 +0,0 @@
-# -*- coding: latin-1 -*-
-"""
-SVG 2 OBJ translater, 0.5.9o
-Copyright (c) jm soler juillet/novembre 2004-april 2009,
-# ---------------------------------------------------------------
- released under GNU Licence
- for the Blender 2.42 Python Scripts Bundle.
-Ce programme est libre, vous pouvez le redistribuer et/ou
-le modifier selon les termes de la Licence Publique Générale GNU
-publiée par la Free Software Foundation (version 2 ou bien toute
-autre version ultérieure choisie par vous).
-
-Ce programme est distribué car potentiellement utile, mais SANS
-AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties
-de commercialisation ou d'adaptation dans un but spécifique.
-Reportez-vous à la Licence Publique Générale GNU pour plus de détails.
-
-Vous devez avoir reçu une copie de la Licence Publique Générale GNU
-en même temps que ce programme ; si ce n'est pas le cas, écrivez à la
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307, États-Unis.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# ---------------------------------------------------------------
-#
-#---------------------------------------------------------------------------
-# Page officielle :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg.htm
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg_en.htm
-# Communiquer les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#---------------------------------------------------------------------------
-
---Old Concept : translate SVG file in GEO .obj file and try to load it.
- was removed for the Blender 2.4x release.
- .-- Curiousity : the original matrix must be :
- |
- | 0.0 0.0 1.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
- |
- | and not:
- | 1.0 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
- |
- '-- Possible bug : sometime, the new curves object's RotY value
- jumps to -90.0 degrees without any reason.
-
---Options :
- SHARP_IMPORT = 0
- choise between "As is", "Devide by height" and "Devide by width"
- SHARP_IMPORT = 1
- no choise
-
-
-
-All commands are managed:
- M : absolute move to
- Z : close path
- L : absolute line to
- C : absolute curve to
- S : absolute curve to with only one handle
- H : absolute horizontal line to
- V : absolute vertical line to
-
- l : relative line to 2004/08/03
- c : relative curve to 2004/08/03
- s : relative curve to with only one handle
- h : relative horizontal line to
- v : relative vertical line to
-
- A : curve_to_a,
- V : draw_line_v,
- H : draw_line_h,
- Z : close_z,
- Q : curve_to_q,
- T : curve_to_t,
- a : curve_to_a,
- v : draw_line_v,
- h : draw_line_h,
- z : close_z,
- q : curve_to_q,
-
- transfrom for <g> tag
- transform for <path> tag
-
-The circle, rectangle closed or open polygons lines are managed too.
-
-Changelog:
- 0.1.1 : - control file without extension
- 0.2.0 : - improved reading of several data of the same type
- following the same command (for gimp import)
- 0.2.1 : - better choice for viewboxing ( takes the viewbox if found,
- instead of x,y,width and height
- 0.2.2 : - read compact path data from Illustrator 10
- 0.2.3 : - read a few new relative displacements
- 0.2.4 : - better hash for command followed by a lone data
- (h,v) or uncommun number (a)
- 0.2.5 : - correction for gimp import
- 0.2.6 : - correction for illustrator 10 SVG
- 0.2.7 : - correction for inskape 0.40 cvs SVG
- 0.2.8 : - correction for inskape plain SVG
- 0.3 : - reading of the transform properties added :
- translate
- 0.3.1 : - compatibility restored with gimp
- 0.3.2 : - transform properties added (june, 15-16):
- scale,
- rotate,
- matrix,
- skew
- - added a test on __name__ to load the script
- outside from the blender menu
- 0.3.3 : - matrix transform content control
- 0.3.4 : - paths data reading rewritten (19/06/05)
- 0.3.5 : - test on empty curve (22/06/05)
- - removed overlayed points
- 0.3.6 : - rewriting of the bezier point contruction to correct
- a problem in the connection between L type point and
- C or S type point
- 0.3.7 : - code correction for bezier knot in Curveto command when
- the command close a path
- 0.3.8 : - code was aded to manage quadratic bezier,
- Q,q command and T,t commands, as a normal blender's bezier point
- - The last modications does not work with gimp 2.0 svg export .
- corrected too .
- 0.3.9 : - Path's A,a command for ellipse's arc .
- 0.4.0 : - To speed up the function filter_DATA was removed and text
- variables are changed into numeric variables
- 0.4.1 : - svg, groups and shapes hierarchy added
- - now transform properties are computed using a stack with all
- parented groups
- - removed or replaced useless functions :
- - skewY, skewX transforms
- - radians in rotate transform
- 0.4.2 : - Added functon to translate others shapes in path
- rect, line, polyline, polygon
- 0.4.3 : - various corrections
- text font (id property exported by Adobe Illustrator are between coma)
- function to code s tag has been rewritten
- 0.4.4 : - various corrections
- to oblige the script to understand a line feed just after
- a tag . Rarely encountered problem, but it exits in a svg file
- format exported by a outliner script for mesh .
- 0.4.5 : - update for CVS only, at least blender 2.38 and upper
- no BezTriple module in older version
- added a createCURVES function to avoid to use
- the OBJ format export/import .
- Perhaps problems with cyclic curves . If a closed curve
- does not appear closed in blender, enter edit mode select
- all knot with Akey, do a Hkey to set handle type (without
- this the knot are recalculated) , and finally use the Ckey
- to close the curve .
- Should work ... not guaranted .
- 0.4.6 : - cyclic flag ...
- 0.4.7 : - Management of the svgz files . the complete python or the
- gzip.py file is needed .
- Little improvement of the curve drawing using the createCURVES
- function
- 0.4.8 : - short modif for a fantasy font case in the OOo svg format
- ('viewbox' is written 'viewBox', for instance) .
- Note that (at this time, 2006/05/01, 1OOo exports in svg
- but does not read its own export
- 0.4.9 : - skipped version : private test
- 0.5.0 : - the script worked perfectly with Blender 2.41 but in Blender
- 2.42, use the original svg name file + 'OOO.obj' to
- write a videoscape file made blender crash under window XP when
- the script loaded it . Curiously, use a more simple
- name with a sole 'O' solved this problem .
- - script returned errors on open path : corrected
- - in b2.42, several successive imports seem to be added to
- the same original curve . So now the script automaticaly
- renames the last group of imported curve with the original
- name file .
- 0.5.1 : - without join option in the internal curve creation function
- 0.5.2 : - the createCURVES() function has been cleanded . Now it works
- fine but all bezier curves are joined in the same curve object .
- 0.5.3 : - removed two things :
- 1/ the ajustement function to increase speed . 35 % faster :
- 5690 curves and 30254 points in 11 seconds . User should do
- a ctrl-a on the object .
- 2/ the import method menu . No reason to choose between the
- old extern curve creat and the new intern curve creation
- this last one is largely faster .
- 0.5.4 : - translation of the functions' name + improvment in the dict lookup .
- Quite 15% faster . 9.75 seconds instead of 11 to load the file test .
- A test was also added to find the fill style so now the script closes
- these curves even if they are not defined as closed in the strict path
- commands .
- The old non used functions have been completely removed .
- 0.5.5 : - Modifs for architect users .
- 0.5.6 : - Exec was removed from the collect_ATTRIBUTS function .
- Other uses was evaluated.
- 0.5.7 : - Wash down of some handle problems.
-
- 0.5.8 : - 2007/3/9
- Wash down of the last exec and correction of a
- problem with the curve's first beztriple handle
- which was not recorded at first time .
- - Added some units managements
- - Correction of the rotate matrix
- - Correction of the skew matrix
- - change in the wash_DATA function suggested by cambo
- - added __slot__ in class Bez, ITEM and CURVE suggested by cambo
- - remove unused properties in class ITEM and CURVE
-
- 0.5.9 : - 2007/3/28
- - many improvements for faster and clearer code suggested by cambo and martin.
- replacement of "%s" statement by str function.
- - correction of an error in the scale transform management
- - correction in the management of the stack transformation that rise an error
- under python 2.5 but curiously not with python 2.4
-
- 0.5.9a : - 2007/3/29
- - Again a lot of minors corrections
- - Backward to 0.5.8 of the function that manages float numbers exported
- by the Adobe Illustrator's SVG. After a lot of tests it seems that this oldest
- version is also faster too .
- - correction (bad) on handle management with V and H commands.
-
- 0.5.9b : - 2007/3/31
- - one or two minor corrections
- - now the new object curve is added in the current layer.
- - short modif in the scale menu...
-
- 0.5.9d : - 2007/4/5
- - when a svg file containts several curves they can be imported in
- separate object.
- - managment of paths' name when paths are imported as separate curves.
- - a menu was added to select between separate or joined curves
- - management of colors
-
- 0.5.9e : - 2007/4/7
- - corrected a scale problem that only appears when one uses beveldepth
- - in separate curve option, name is also given to the curve data
- - added the list of svg's color names (147) and modified the color's method
- to work with.
-
- 0.5.9h : - 2007/5/2
- - script was updated with the modifs by cambo
- - removed all debug statements
- - correction of a zero division error in the calc_arc function.
-
- 0.5.9f: - 2007/15/7
- - Correction de plusieurs bugs sur l'attributions des couleurs et le nommage
- des courbes
-
- 0.5.9i : - ??/??/??
- - Patch externe réalisé sur blender.org project.
-
- 0.5.9j : - 08/11/2008
- 0.5.9k : - 14/01/2009
- 0.5.9l : - 31/01/2009
- 0.5.9n : - 01/02/2009
- 0.5.9o : - 04/04/2009, remove pattern if it made with path.
-
-
-==================================================================================
-=================================================================================="""
-SHARP_IMPORT=0
-SCALE=1
-scale_=1
-DEBUG = 0
-DEVELOPPEMENT=0
-TESTCOLOR=0
-
-LAST_ID=''
-LAST_COLOR=[0.0,0.0,0.0,0.0]
-SEPARATE_CURVES=0
-USE_COLORS=0
-PATTERN=0
-
-SVGCOLORNAMELIST={ 'aliceblue':[240, 248, 255] ,'antiquewhite':[250, 235, 215]
-,'aqua':[ 0, 255, 255], 'aquamarine':[127, 255, 212]
-,'azure':[240, 255, 255], 'beige':[245, 245, 220]
-,'bisque':[255, 228, 196], 'black':[ 0, 0, 0]
-,'blanchedalmond':[255, 235, 205] ,'blue':[ 0, 0, 255]
-,'blueviolet':[138, 43, 226],'brown':[165, 42, 42]
-,'burlywood':[222, 184, 135],'cadetblue':[ 95, 158, 160]
-,'chartreuse':[127, 255, 0] ,'chocolate':[210, 105, 30]
-,'coral':[255, 127, 80],'cornflowerblue':[100, 149, 237]
-,'cornsilk':[255, 248, 220],'crimson':[220, 20, 60]
-,'cyan':[ 0, 255, 255],'darkblue':[ 0, 0, 139]
-,'darkcyan':[ 0, 139, 139],'darkgoldenrod':[184, 134, 11]
-,'darkgray':[169, 169, 169],'darkgreen':[ 0, 100, 0]
-,'darkgrey':[169, 169, 169],'darkkhaki':[189, 183, 107]
-,'darkmagenta':[139, 0, 139],'darkolivegreen':[ 85, 107, 47]
-,'darkorange':[255, 140, 0],'darkorchid':[153, 50, 204]
-,'darkred':[139, 0, 0],'darksalmon':[233, 150, 122]
-,'darkseagreen':[143, 188, 143],'darkslateblue':[ 72, 61, 139]
-,'darkslategray':[ 47, 79, 79],'darkslategrey':[ 47, 79, 79]
-,'darkturquoise':[ 0, 206, 209],'darkviolet':[148, 0, 211]
-,'deeppink':[255, 20, 147],'deepskyblue':[ 0, 191, 255]
-,'dimgray':[105, 105, 105],'dimgrey':[105, 105, 105]
-,'dodgerblue':[ 30, 144, 255],'firebrick':[178, 34, 34]
-,'floralwhite':[255, 250, 240],'forestgreen':[ 34, 139, 34]
-,'fuchsia':[255, 0, 255],'gainsboro':[220, 220, 220]
-,'ghostwhite':[248, 248, 255],'gold':[255, 215, 0]
-,'goldenrod':[218, 165, 32],'gray':[128, 128, 128]
-,'grey':[128, 128, 128],'green':[ 0, 128, 0]
-,'greenyellow':[173, 255, 47],'honeydew':[240, 255, 240]
-,'hotpink':[255, 105, 180],'indianred':[205, 92, 92]
-,'indigo':[ 75, 0, 130],'ivory':[255, 255, 240]
-,'khaki':[240, 230, 140],'lavender':[230, 230, 250]
-,'lavenderblush':[255, 240, 245],'lawngreen':[124, 252, 0]
-,'lemonchiffon':[255, 250, 205],'lightblue':[173, 216, 230]
-,'lightcoral':[240, 128, 128],'lightcyan':[224, 255, 255]
-,'lightgoldenrodyellow':[250, 250, 210],'lightgray':[211, 211, 211]
-,'lightgreen':[144, 238, 144],'lightgrey':[211, 211, 211]
-,'lightpink':[255, 182, 193],'lightsalmon':[255, 160, 122]
-,'lightseagreen':[ 32, 178, 170],'lightskyblue':[135, 206, 250]
-,'lightslategray':[119, 136, 153],'lightslategrey':[119, 136, 153]
-,'lightsteelblue':[176, 196, 222],'lightyellow':[255, 255, 224]
-,'lime':[ 0, 255, 0],'limegreen':[ 50, 205, 50]
-,'linen':[250, 240, 230],'magenta':[255, 0, 255]
-,'maroon':[128, 0, 0],'mediumaquamarine':[102, 205, 170]
-,'mediumblue':[ 0, 0, 205],'mediumorchid':[186, 85, 211]
-,'mediumpurple':[147, 112, 219],'mediumseagreen':[ 60, 179, 113]
-,'mediumslateblue':[123, 104, 238],'mediumspringgreen':[ 0, 250, 154]
-,'mediumturquoise':[ 72, 209, 204],'mediumvioletred':[199, 21, 133]
-,'midnightblue':[ 25, 25, 112],'mintcream':[245, 255, 250]
-,'mistyrose':[255, 228, 225],'moccasin':[255, 228, 181]
-,'navajowhite':[255, 222, 173],'navy':[ 0, 0, 128]
-,'oldlace':[253, 245, 230],'olive':[128, 128, 0]
-,'olivedrab':[107, 142, 35],'orange':[255, 165, 0]
-,'orangered':[255, 69, 0],'orchid':[218, 112, 214]
-,'palegoldenrod':[238, 232, 170],'palegreen':[152, 251, 152]
-,'paleturquoise':[175, 238, 238],'palevioletred':[219, 112, 147]
-,'papayawhip':[255, 239, 213],'peachpuff':[255, 218, 185]
-,'peru':[205, 133, 63],'pink':[255, 192, 203]
-,'plum':[221, 160, 221],'powderblue':[176, 224, 230]
-,'purple':[128, 0, 128],'red':[255, 0, 0]
-,'rosybrown':[188, 143, 143],'royalblue':[ 65, 105, 225]
-,'saddlebrown':[139, 69, 19],'salmon':[250, 128, 114]
-,'sandybrown':[244, 164, 96],'seagreen':[ 46, 139, 87]
-,'seashell':[255, 245, 238],'sienna':[160, 82, 45]
-,'silver':[192, 192, 192],'skyblue':[135, 206, 235]
-,'slateblue':[106, 90, 205],'slategray':[112, 128, 144]
-,'slategrey':[112, 128, 144],'snow':[255, 250, 250]
-,'springgreen':[ 0, 255, 127],'steelblue':[ 70, 130, 180]
-,'tan':[210, 180, 140],'teal':[ 0, 128, 128]
-,'thistle':[216, 191, 216],'tomato':[255, 99, 71]
-,'turquoise':[ 64, 224, 208],'violet':[238, 130, 238]
-,'wheat':[245, 222, 179],'white':[255, 255, 255]
-,'whitesmoke':[245, 245, 245],'yellow':[255, 255, 0]
-,'yellowgreen':[154, 205, 50]}
-
-
-import sys
-from math import cos,sin,tan, atan2, pi, ceil
-PI=pi
-import Blender
-from Blender import Mathutils
-
-try:
- import nt
- os=nt
- os.sep='\\'
-
-except:
- import posix
- os=posix
- os.sep='/'
-
-def isdir(path):
- try:
- st = os.stat(path)
- return 1
- except:
- return 0
-
-def split(pathname):
- if os.sep in pathname:
- k0=pathname.split(os.sep)
- else:
- if os.sep=='/':
- k0=pathname.split('\\')
- else:
- k0=pathname.split('/')
- directory=pathname.replace(k0[len(k0)-1],'')
- Name=k0[len(k0)-1]
- return directory, Name
-
-def join(l0,l1):
- return l0+os.sep+l1
-
-os.isdir=isdir
-os.split=split
-os.join=join
-
-def filterFILE(nom):
- """
- Function filterFILE
-
- in : string nom , filename
- out : string t , if correct filecontaint
-
- read the file's content and try to see if the format
- is correct .
-
- Lit le contenu du fichier et en fait une pre-analyse
- pour savoir s'il merite d'etre traite .
- """
- # ----------
- # 0.4.7
- # ----------
- if nom.upper().endswith('.SVGZ'):
- try :
- import gzip
- tz=gzip.GzipFile(nom)
- t=tz.read()
- except:
- name = "ERROR: fail to import gzip module or gzip error ... "
- result = Blender.Draw.PupMenu(name)
- return "false"
- else:
- f=open(nom,'rU')
- t=f.read()
- f.close()
- # ----------
- # 0.4.7 : end
- # ----------
- # -----------------
- # pre-format ...
- # -----------------
- # --------------------
- # 0.4.4 '\r','' --> '\r',' '
- # '\n','' --> '\n',' '
- #--------------------
- t=t.replace('\r',' ')
- t=t.replace('\n',' ')
- t=t.replace('svg:','')
- #--------------------
- # may be needed in some import case when the
- # file is saved from a mozilla display
- #--------------------
- t=t.replace(chr(0),'')
- if not '<SVG' in t.upper():
- name = "ERROR: invalid or empty file ... " # if no %xN int is set, indices start from 1
- result = Blender.Draw.PupMenu(name)
- return "false"
- else:
- return t
-
-#===============================
-# Data
-#===============================
-#===============================
-# Blender Curve Data
-#===============================
-objBEZIER=0
-objSURFACE=5
-typBEZIER3D=1 #3D
-typBEZIER2D=9 #2D
-
-class Bez(object):
- __slots__ = 'co', 'ha', 'tag' # suggested by cambo, should save memory
- def __init__(self):
- self.co=[]
- self.ha=['C','C']
- self.tag=''
-
-class ITEM(object):
- __slots__ = 'type', 'pntsUV', 'flagUV', 'beziers_knot','fill','color','id','mat','matname'
- def __init__(self):
- self.type = typBEZIER3D
- self.pntsUV = [0,0]
- self.flagUV = [0,0]
- self.beziers_knot = []
- self.fill=0
- self.color=[0.0,0.0,0.0,0.0]
- self.id=''
- self.mat=0
- self.matname=''
-
-class CURVE(object):
- __slots__ = 'type','number_of_items','ITEM'
- def __init__(self):
- self.type = objBEZIER
- self.number_of_items = 0
- self.ITEM = {}
-
-curves=CURVE()
-PATTERN={}
-BOUNDINGBOX={'rec':[],'coef':1.0}
-
-npat=0
-#=====================================================================
-#======== name of the curve in the curves dictionnary ===============
-#=====================================================================
-n0=0
-
-#=====================================================================
-#====================== current Point ================================
-#=====================================================================
-CP=[0.0,0.0] #currentPoint
-
-
-#=====================================================================
-#===== to compare last position to the original move to displacement =
-#===== needed for cyclic definition in AI, EPS forma ================
-#=====================================================================
-def test_samelocations(f1,f2):
- EPSILON=0.0001
- if abs(f1[4])- abs(f2[4])< EPSILON and abs(f1[4])- abs(f2[4])>= 0.0\
- and abs(f1[5])-abs(f2[5])< EPSILON and abs(f1[5])-abs(f2[5])>= 0.0 :
- return 1
- else:
- return 0
-
-
-#--------------------
-# 0.4.5 : for blender cvs 2.38 ....
-#--------------------
-def createCURVES(curves, name):
- """
- internal curves creation
- """
- global SCALE, B, BOUNDINGBOX,scale_, SEPARATE_CURVES
- global USE_COLORS
- from Blender import Curve, Object, Scene, BezTriple
- HANDLE={'C':BezTriple.HandleTypes.FREE,'L':BezTriple.HandleTypes.VECT}
- r=BOUNDINGBOX['rec']
-
- if scale_==3:
- SCALE=1.0
- elif scale_==1:
- SCALE=r[2]-r[0]
- elif scale_==2:
- SCALE=r[3]-r[1]
-
- scene = Scene.GetCurrent()
- scene.objects.selected = []
-
- if not SEPARATE_CURVES:
- c = Curve.New()
- c.setResolu(24)
-
- MATNAME=[]
- nloc=0.0
-
- def new_MATERIAL(val):
- # -----------------------
- # have to create a material
- #------------------------
- if val.matname and val.matname in MATNAME:
- mat = Blender.Material.Get(val.matname)
- elif val.matname:
- mat = Blender.Material.New(val.matname)
- mat.rgbCol = [val.color[0]/255.0, val.color[1]/255.0, val.color[2]/255.0]
- else:
- mat = Blender.Material.New(val.id)
- mat.rgbCol = [val.color[0]/255.0, val.color[1]/255.0, val.color[2]/255.0]
- return [mat]
-
- for I,val in curves.ITEM.iteritems():
- if SEPARATE_CURVES:
- c = Curve.New()
- c.setResolu(24)
- if USE_COLORS and val.mat:
- c.materials=new_MATERIAL(val)
-
- bzn=0
- if val.beziers_knot[-1].tag in ['L','l','V','v','H','h'] and\
- test_samelocations(val.beziers_knot[-1].co,val.beziers_knot[0].co):
- del val.beziers_knot[-1]
-
- for k2 in xrange(0,len(val.beziers_knot)):
- bz= [co for co in val.beziers_knot[k2].co]
- if bzn==0:
- cp1 = bz[4]/SCALE, bz[5]/-SCALE,0.0, bz[0]/SCALE, bz[1]/-SCALE,0.0, bz[2]/SCALE,bz[3]/-SCALE,0.0,
- beztriple1 = BezTriple.New(cp1)
- bez = c.appendNurb(beztriple1)
- bez[0].handleTypes=(HANDLE[val.beziers_knot[k2].ha[0]],HANDLE[val.beziers_knot[k2].ha[1]])
- bzn = 1
- else:
- cp2 = bz[4]/SCALE,bz[5]/-SCALE,0.0 , bz[0]/SCALE, bz[1]/-SCALE,0.0, bz[2]/SCALE,bz[3]/-SCALE,0.0
- beztriple2 = BezTriple.New(cp2)
- beztriple2.handleTypes= (HANDLE[val.beziers_knot[k2].ha[0]],HANDLE[val.beziers_knot[k2].ha[1]])
- bez.append(beztriple2)
-
- if val.flagUV[0]==1 or val.fill==1:
- #--------------------
- # 0.4.6 : cyclic flag ...
- #--------------------
- bez.flagU += 1
-
- if SEPARATE_CURVES:
- ob = scene.objects.new(c,val.id)
- scene.objects.active = ob
- ob.setLocation(0.0,0.0,nloc)
- nloc+=0.0001
- c.update()
-
- if not SEPARATE_CURVES:
- ob = scene.objects.new(c,name)
- scene.objects.active = ob
- c.update()
-
-#=====================================================================
-#===== SVG format : DEBUT =========================
-#=====================================================================
-#--------------------
-# 0.5.8, needed with the new
-# tranform evaluation
-#--------------------
-pxUNIT={'pt':1.25,
- 'pc':15.0,
- 'mm':3.543307,
- 'cm':35.43307,
- 'in':90.0,
- 'em':1.0, # should be taken from font size
- # but not currently managed
- 'ex':1.0, # should be taken from font size
- # but not currently managed
- '%':1.0,
- }
-
-#--------------------
-# 0.4.2
-# 0.5.8, to remove exec
-#--------------------
-def rect(prp):
- """
- build rectangle paths
- """
- D=[]
- if 'x' not in prp: x=0.0
- else : x=float(prp['x'])
- if 'y' not in prp: y=0.0
- else : y=float(prp['y'])
- #--------------------
- # 0.5.8
- #--------------------
- try:
- height=float(prp['height'])
- except:
- pxUNIT['%']=(BOUNDINGBOX['rec'][3]-BOUNDINGBOX['rec'][1])/100.0
- for key in pxUNIT:#.keys():
- if key in prp['height']:
- height=float(prp['height'].replace(key,''))*pxUNIT[key]
- try:
- width=float(prp['width'])
- except:
- pxUNIT['%']=(BOUNDINGBOX['rec'][2]-BOUNDINGBOX['rec'][0])/100.0
- for key in pxUNIT:#.keys():
- if key in prp['width']:
- width=float(prp['width'].replace(key,''))*pxUNIT[key]
- #--------------------
- # 0.5.8, end
- #--------------------
- """
- normal rect
- x,y
- h1
- *----------*
- | |
- | |
- | |
- *----------* v1
- h2
- """
- if 'rx' not in prp or 'rx' not in prp:
- D=['M',str(x),str(y),'h',str(width),'v',str(height),'h',str(-width),'z']
- else :
- rx=float(prp['rx'])
- if 'ry' not in prp :
- ry=float(prp['rx'])
- else : ry=float(prp['ry'])
- if 'rx' in prp and prp['rx']<0.0: rx*=-1
- if 'ry' in prp and prp['ry']<0.0: ry*=-1
- """
- rounded corner
-
- x,y M h1
- ---*----------*
- / \
- / \
- v2 * * c1
- | |
- | |
- | |
- c3 * * v2
- \ /
- \ /
- *----------*
- h2 c2
- """
-
- D=['M',str(x+rx),str(y),
- 'h',str(width-2*rx),
- 'c',str(rx),'0.0',str(rx),str(ry),str(rx),str(ry),
- 'v',str(height-ry),
- 'c','0.0',str(ry),str(-rx),str(ry),str(-rx),str(ry),
- 'h',str(-width+2*rx),
- 'c',str(-rx),'0.0',str(-rx),str(-ry),str(-rx),str(-ry),
- 'v',str(-height+ry),
- 'c','0.0','0.0','0.0',str(-ry),str(rx),str(-ry),
- 'z']
-
- return D
-
-#--------------------
-# 0.4.2
-# 0.5.8, to remove exec
-#--------------------
-def circle(prp):
- if 'cx' not in prp: cx=0.0
- else : cx =float(prp['cx'])
- if 'cy' not in prp: cy=0.0
- else : cy =float(prp['cy'])
- r = float(prp['r'])
- D=['M',str(cx),str(cy+r),
- 'C',str(cx-r), str(cy+r*0.552),str(cx-0.552*r),str(cy+r), str(cx),str(cy+r),
- 'C',str(cx+r*0.552), str(cy+r), str(cx+r), str(cy+r*0.552), str(cx+r),str(cy),
- 'C',str(cx+r), str(cy-r*0.552),str(cx+r*0.552),str(cy-r),str(cx), str(cy-r),
- 'C',str(cx-r*0.552), str(cy-r), str(cx-r), str(cy-r*0.552),str(cx-r),str(cy),
- 'Z']
- return D
-
-#--------------------
-# 0.4.2
-# 0.5.8, to remove exec
-#--------------------
-def ellipse(prp):
- if 'cx' not in prp: cx=0.0
- else : cx =float(prp['cx'])
- if 'cy' not in prp: cy=0.0
- else : cy =float(prp['cy'])
- ry = float(prp['rx'])
- rx = float(prp['ry'])
- D=['M',str(cx),str(cy+rx),
- 'C',str(cx-ry),str(cy+rx*0.552),str(cx-0.552*ry),str(cy+rx),str(cx),str(cy+rx),
- 'C',str(cx+ry*0.552),str(cy+rx),str(cx+ry),str(cy+rx*0.552),str(cx+ry),str(cy),
- 'C',str(cx+ry),str(cy-rx*0.552),str(cx+ry*0.552),str(cy-rx),str(cx),str(cy-rx),
- 'C',str(cx-ry*0.552),str(cy-rx),str(cx-ry),str(cy-rx*0.552),str(cx-ry),str(cy),
- 'z']
- return D
-
-#--------------------
-# 0.4.2
-# 0.5.8, to remove exec
-#--------------------
-def line(prp):
- D=['M',str(prp['x1']),str(prp['y1']),
- 'L',str(prp['x2']),str(prp['y2'])]
- return D
-
-#--------------------
-# 0.4.2
-# 0.5.8, to remove exec
-#--------------------
-def polyline(prp):
- if 'points' in prp:
- points=prp['points'].split(' ')
- np=0
- for p in points:
- if p!='':
- p=p.split(',')
- if np==0:
- D=['M',str(p[0]),str(p[1])]
- np+=1
- else:
- D.append('L'); D.append(str(p[0])); D.append(str(p[1]))
- return D
- else:
- return []
-
-#--------------------
-# 0.4.2
-# 0.5.8, to remove exec
-#--------------------
-def polygon(prp):
- D=polyline(prp)
- if D!=[]:
- D.append('Z')
- return D
-
-
-#--------------------
-# 0.5.8, to remove exec
-#--------------------
-OTHERSSHAPES={ 'rect' : rect,
- 'line' : line,
- 'polyline': polyline,
- 'polygon' : polygon,
- 'circle' : circle,
- 'ellipse' : ellipse}
-
-#--------------------
-# 0.3.9
-#--------------------
-def calc_arc (cpx,cpy, rx, ry, ang, fa , fs , x, y) :
- """
- Calc arc paths
- """
- rx=abs(rx)
- ry=abs(ry)
- px=abs((cos(ang)*(cpx-x)+sin(ang)*(cpy-y))*0.5)**2.0
- py=abs((cos(ang)*(cpy-y)-sin(ang)*(cpx-x))*0.5)**2.0
- rpx=rpy=0.0
- if abs(rx)>0.0: rpx=px/(rx**2.0)
- if abs(ry)>0.0: rpy=py/(ry**2.0)
- pl=rpx+rpy
- if pl>1.0:
- pl=pl**0.5;rx*=pl;ry*=pl
- carx=sarx=cary=sary=0.0
- if abs(rx)>0.0:
- carx=cos(ang)/rx;sarx=sin(ang)/rx
- if abs(ry)>0.0:
- cary=cos(ang)/ry;sary=sin(ang)/ry
- x0=(carx)*cpx+(sarx)*cpy
- y0=(-sary)*cpx+(cary)*cpy
- x1=(carx)*x+(sarx)*y
- y1=(-sary)*x+(cary)*y
- d=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)
- if abs(d)>0.0 :sq=1.0/d-0.25
- else: sq=-0.25
- if sq<0.0 :sq=0.0
- sf=sq**0.5
- if fs==fa :sf=-sf
- xc=0.5*(x0+x1)-sf*(y1-y0)
- yc=0.5*(y0+y1)+sf*(x1-x0)
- ang_0=atan2(y0-yc,x0-xc)
- ang_1=atan2(y1-yc,x1-xc)
- ang_arc=ang_1-ang_0;
- if (ang_arc < 0.0 and fs==1) :
- ang_arc += 2.0 * PI
- elif (ang_arc>0.0 and fs==0) :
- ang_arc-=2.0*PI
- n_segs=int(ceil(abs(ang_arc*2.0/(PI*0.5+0.001))))
- P=[]
- for i in xrange(n_segs):
- ang0=ang_0+i*ang_arc/n_segs
- ang1=ang_0+(i+1)*ang_arc/n_segs
- ang_demi=0.25*(ang1-ang0)
- t=2.66666*sin(ang_demi)*sin(ang_demi)/sin(ang_demi*2.0)
- x1=xc+cos(ang0)-t*sin(ang0)
- y1=yc+sin(ang0)+t*cos(ang0)
- x2=xc+cos(ang1)
- y2=yc+sin(ang1)
- x3=x2+t*sin(ang1)
- y3=y2-t*cos(ang1)
- P.append([[(cos(ang)*rx)*x1+(-sin(ang)*ry)*y1,
- (sin(ang)*rx)*x1+(cos(ang)*ry)*y1],
- [(cos(ang)*rx)*x3+(-sin(ang)*ry)*y3,
- (sin(ang)*rx)*x3+(cos(ang)*ry)*y3],
- [(cos(ang)*rx)*x2+(-sin(ang)*ry)*y2,
- (sin(ang)*rx)*x2+(cos(ang)*ry)*y2]])
- return P
-
-#--------------------
-# 0.3.9
-#--------------------
-def curve_to_a(curves, c,D,n0,CP): #A,a
- global SCALE
- l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),
- int(D[c[1]+4]),int(D[c[1]+5]),float(D[c[1]+6]),float(D[c[1]+7])]
- if c[0]=='a':
- l[5]=l[5] + CP[0]
- l[6]=l[6] + CP[1]
- B=Bez()
- B.co=[ CP[0], CP[1], CP[0], CP[1], CP[0], CP[1] ]
- B.ha=['C','C']
- B.tag=c[0]
- POINTS= calc_arc (CP[0],CP[1],
- l[0], l[1], l[2]*(PI / 180.0),
- l[3], l[4],
- l[5], l[6] )
- for p in POINTS :
- B=Bez()
- B.co=[ p[2][0],p[2][1], p[0][0],p[0][1], p[1][0],p[1][1]]
- B.ha=['C','C']
- B.tag='C'
- BP=curves.ITEM[n0].beziers_knot[-1]
- BP.co[2]=B.co[2]
- BP.co[3]=B.co[3]
- curves.ITEM[n0].beziers_knot.append(B)
- BP=curves.ITEM[n0].beziers_knot[-1]
- BP.co[2]=BP.co[0]
- BP.co[3]=BP.co[1]
- CP=[l[5], l[6]]
- #---------- 059m------------
- if len(D)>c[1]+7 and D[c[1]+8] not in TAGcourbe :
- c[1]+=7
- curves,n0,CP=curve_to_a(curves, c, D, n0,CP)
- #---------- 059m------------
- return curves,n0,CP
-
-def move_to(curves, c, D, n0,CP, proprietes):
- global DEBUG,TAGcourbe, LAST_ID
- global USE_COLORS
-
- l=[float(D[c[1]+1]),float(D[c[1]+2])]
-
- if c[0]=='m':
- l=[l[0]+CP[0],
- l[1] + CP[1]]
-
- if n0 in curves.ITEM:
- n0+=1
- CP=[l[0],l[1]]
- curves.ITEM[n0]=ITEM()
-
- if 'id' in proprietes:
- curves.ITEM[n0].id=proprietes['id']
- else:
- curves.ITEM[n0].id=LAST_ID
-
- proprietes['n'].append(n0)
- if USE_COLORS:
- pr= proprietes.get('fill') # None or the property
- if pr != None:
- if '#' in pr:
- i=1
- curves.ITEM[n0].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)]
- curves.ITEM[n0].mat=1
- elif pr in SVGCOLORNAMELIST:
- Courbe[n].color=SVGCOLORNAMELIST[pr]
- Courbe[n].mat=1
-
- B=Bez()
- B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]]
- B.ha=['L','C']
- B.tag=c[0]
- curves.ITEM[n0].beziers_knot.append(B)
- return curves,n0,CP
-
-def close_z(curves, c,D,n0,CP): #Z,z
- curves.ITEM[n0].flagUV[0]=1
- if len(curves.ITEM[n0].beziers_knot)>1:
- BP=curves.ITEM[n0].beziers_knot[-1]
- BP0=curves.ITEM[n0].beziers_knot[0]
- if BP.tag in ['c','C','s','S',]:
- BP.co[2]=BP0.co[2] #4-5 point prec
- BP.co[3]=BP0.co[3]
- del curves.ITEM[n0].beziers_knot[0]
- else:
- del curves.ITEM[n0]
- n0-=1
- return curves,n0,CP
-
-def curve_to_q(curves, c,D,n0,CP): #Q,q
- l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),float(D[c[1]+4])]
- if c[0]=='q':
- l=[l[0]+CP[0], l[1]+CP[1], l[2]+CP[0], l[3]+CP[1]]
- B=Bez()
- B.co=[l[2], l[3], l[2], l[3], l[0], l[1]] #plus toucher au 2-3
- B.ha=['C','C']
- B.tag=c[0]
- BP=curves.ITEM[n0].beziers_knot[-1]
- BP.co[2]=BP.co[0]
- BP.co[3]=BP.co[1]
- curves.ITEM[n0].beziers_knot.append(B)
- CP=[l[2],l[3]]
- #if DEBUG==1: pass
- if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe :
- c[1]+=4
- curves,n0,CP=curve_to_q(curves, c, D, n0,CP)
- return curves,n0,CP
-
-def curve_to_t(curves, c,D,n0,CP): #T,t
- l=[float(D[c[1]+1]),float(D[c[1]+2])]
- if c[0]=='t':
- l=[l[0]+CP[0], l[1]+CP[1]]
- B=Bez()
- B.co=[l[0], l[1], l[0], l[1], l[0], l[1]] #plus toucher au 2-3
- B.ha=['C','C']
- B.tag=c[0]
- BP=curves.ITEM[n0].beziers_knot[-1]
- l0=build_SYMETRIC([BP.co[0],BP.co[1],BP.co[4],BP.co[5]])
- if BP.tag in ['q','Q','t','T','m','M']:
- BP.co[2]=l0[2]
- BP.co[3]=l0[3]
- curves.ITEM[n0].beziers_knot.append(B)
- CP=[l[0],l[1]]
- if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe :
- c[1]+=4
- curves,n0,CP=curve_to_t(curves, c, D, n0,CP)
- return curves,n0,CP
-
-#--------------------
-# 0.4.3 : rewritten
-#--------------------
-def build_SYMETRIC(l):
- X=l[2]-(l[0]-l[2])
- Y=l[3]-(l[1]-l[3])
- return X,Y
-
-def curve_to_s(curves, c,D,n0,CP): #S,s
- l=[float(D[c[1]+1]),
- float(D[c[1]+2]),
- float(D[c[1]+3]),
- float(D[c[1]+4])]
- if c[0]=='s':
- l=[l[0]+CP[0], l[1]+CP[1],
- l[2]+CP[0], l[3]+CP[1]]
- B=Bez()
- B.co=[l[2],l[3],l[2],l[3],l[0],l[1]] #plus toucher au 2-3
- B.ha=['C','C']
- B.tag=c[0]
- BP=curves.ITEM[n0].beziers_knot[-1]
- #--------------------
- # 0.4.3
- #--------------------
- BP.co[2],BP.co[3]=build_SYMETRIC([BP.co[4],BP.co[5],BP.co[0],BP.co[1]])
- curves.ITEM[n0].beziers_knot.append(B)
- #--------------------
- # 0.4.3
- #--------------------
- CP=[l[2],l[3]]
- if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe :
- c[1]+=4
- curves,n0,CP=curve_to_c(curves, c, D, n0,CP)
- return curves,n0,CP
-
-def curve_to_c(curves, c, D, n0,CP): #c,C
- l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),
- float(D[c[1]+4]),float(D[c[1]+5]),float(D[c[1]+6])]
- if c[0]=='c':
- l=[l[0]+CP[0],
- l[1]+CP[1],
- l[2]+CP[0],
- l[3]+CP[1],
- l[4]+CP[0],
- l[5]+CP[1]]
- B=Bez()
- B.co=[l[4],
- l[5],
- l[4],
- l[5],
- l[2],
- l[3]] #plus toucher au 2-3
-
-
- B.ha=['C','C']
- B.tag=c[0]
- BP=curves.ITEM[n0].beziers_knot[-1]
- BP.co[2]=l[0]
- BP.co[3]=l[1]
- BP.ha[1]='C'
- curves.ITEM[n0].beziers_knot.append(B)
- CP=[l[4],l[5]]
- if len(D)>c[1]+7 and D[c[1]+7] not in TAGcourbe :
- c[1]+=6
- curves,n0,CP=curve_to_c(curves, c, D, n0,CP)
- return curves,n0,CP
-
-def draw_line_l(curves, c, D, n0,CP): #L,l
-
- l=[float(D[c[1]+1]),float(D[c[1]+2])]
- if c[0]=='l':
- l=[l[0]+CP[0],
- l[1]+CP[1]]
- B=Bez()
- B.co=[l[0],l[1],
- l[0],l[1],
- l[0],l[1]]
-
- B.ha=['L','L']
- B.tag=c[0]
- BP=curves.ITEM[n0].beziers_knot[-1]
- BP.ha[1]='L'
-
- curves.ITEM[n0].beziers_knot.append(B)
- CP=[B.co[4],B.co[5]]
-
- if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe :
- c[1]+=2
- curves,n0,CP=draw_line_l(curves, c, D, n0,CP) #L
-
- return curves,n0,CP
-
-def draw_line_h(curves, c,D,n0,CP): #H,h
- if c[0]=='h':
- l=[float(D[c[1]+1])+float(CP[0]),CP[1]]
- else:
- l=[float(D[c[1]+1]),CP[1]]
- B=Bez()
- B.co=[l[0],l[1],l[0],l[1],l[0],l[1]]
- B.ha=['L','L']
- B.tag=c[0]
- #BP=curves.ITEM[n0].beziers_knot[-1]
- #BP.ha[0]='L'
- curves.ITEM[n0].beziers_knot.append(B)
- CP=[l[0],l[1]]
- return curves,n0,CP
-
-def draw_line_v(curves, c,D,n0,CP): #V, v
- if c[0]=='v':
- l=[CP[0], float(D[c[1]+1])+CP[1]]
- else:
- l=[CP[0], float(D[c[1]+1])]
-
- B=Bez()
- B.co=[l[0],l[1],l[0],l[1],l[0],l[1]]
- B.ha=['L','L']
- B.tag=c[0]
- #BP=curves.ITEM[n0].beziers_knot[-1]
- #BP.ha[0]='L'
- curves.ITEM[n0].beziers_knot.append(B)
- CP=[l[0],l[1]]
- return curves,n0,CP
-
-Actions= { "C" : curve_to_c,
- "A" : curve_to_a,
- "S" : curve_to_s,
- "M" : move_to,
- "V" : draw_line_v,
- "L" : draw_line_l,
- "H" : draw_line_h,
- "Z" : close_z,
- "Q" : curve_to_q,
- "T" : curve_to_t,
-
- "c" : curve_to_c,
- "a" : curve_to_a,
- "s" : curve_to_s,
- "m" : move_to,
- "v" : draw_line_v,
- "l" : draw_line_l,
- "h" : draw_line_h,
- "z" : close_z,
- "q" : curve_to_q,
- "T" : curve_to_t
-}
-
-TAGcourbe=Actions.keys()
-TAGtransform=['M','L','C','S','H','V','T','Q']
-tagTRANSFORM=0
-
-def wash_DATA(ndata):
- if ndata:
- ndata = ndata.strip()
-
- if ndata[0]==',':ndata=ndata[1:]
- if ndata[-1]==',':ndata=ndata[:-1]
-
- #--------------------
- # 0.4.0 : 'e'
- #--------------------
- ni=0
- i = ndata.find('-',ni)
- if i != -1:
- while i>-1 :
- i = ndata.find('-',ni)
- # 059l ------
- if i>0 :
- if ndata[i-1] not in [' ',',','e']:
- ndata=ndata[:i]+','+ndata[i:]
- ni=i+2
- else:
- ni=i+1
- elif i>-1:
- ni=1
- # 059l ------
-
- ndata=ndata.replace(',,',',')
- ndata=ndata.replace(' ',',')
- ndata=ndata.split(',')
- ndata=[i for i in ndata if i] #059a
-
- return ndata
-
-#--------------------
-# 0.3.4 : - read data rewrittten
-#--------------------
-def list_DATA(DATA):
- """
- This function translate a text in a list of
- correct commandswith the right number of waited
- values for each of them . For example :
- d="'M0,14.0 z" becomes ['M','0.0','14.0','z']
- """
- # ----------------------------------------
- # borner les differents segments qui devront etre
- # traites
- # pour cela construire une liste avec chaque
- # position de chaque emplacement tag de type
- # commande path...
- # ----------------------------------------
- tagplace=[]
- for d in Actions:
- b1=0
- while True:
- i = DATA.find(d,b1)
- if i==-1: break
- tagplace.append(i)
- b1=i+1
- #------------------------------------------
- # cette liste doit etre traites dans l'ordre
- # d'apparition des tags
- #------------------------------------------
- tagplace.sort()
-
- tpn=range(len(tagplace))
-
-
- #--------------------
- # 0.3.5 :: short data, only one tag
- #--------------------
- if len(tagplace)-1>0:
- DATA2=[]
- for t in tpn[:-1]:
- DATA2.append(DATA[tagplace[t]:tagplace[t]+1])
- ndata=DATA[tagplace[t]+1:tagplace[t+1]]
-
- if DATA2[-1] not in ['z','Z'] :
- ndata=wash_DATA(ndata)
- DATA2.extend(ndata)
-
- DATA2.append(DATA[tagplace[t+1]:tagplace[t+1]+1])
-
- if DATA2[-1] not in ['z','Z'] and len(DATA)-1>=tagplace[t+1]+1:
- ndata=DATA[tagplace[t+1]+1:]
- ndata=wash_DATA(ndata)
- DATA2.extend(ndata) #059a
-
- else:
- #--------------------
- # 0.3.5 : short data,only one tag
- #--------------------
- DATA2=[]
- DATA2.append(DATA[tagplace[0]:tagplace[0]+1])
- ndata=DATA[tagplace[0]+1:]
- ndata=wash_DATA(ndata)
- DATA2.extend(ndata)
- return DATA2
-
-#----------------------------------------------
-# 0.3
-# 0.5.8, to remove exec
-#----------------------------------------------
-def translate(t):
- tx=t[0]
- ty=t[1]
- return [1, 0, tx], [0, 1, ty],[0,0,1]
-
-#----------------------------------------------
-# 0.3.2
-# 0.5.8, to remove exec
-#----------------------------------------------
-def scale(s):
- sx=s[0]
- if len(s)>1: sy=s[1]
- else: sy=sx
- return [sx, 0, 0], [0, sy, 0],[0,0,1]
-
-#----------------------------------------------
-# 0.4.1 : transslate a in radians
-# 0.5.8, to remove exec
-#----------------------------------------------
-def rotate(t):
- a=t[0]
- return [cos(a*3.1416/180.0), -sin(a*3.1416/180.0), 0], [sin(a*3.1416/180.0), cos(a*3.1416/180.0),0],[0,0,1]
-
-#----------------------------------------------
-# 0.3.2
-# 0.5.8, to remove exec
-#----------------------------------------------
-def skewx(t):
- a=t[0]
- return [1, tan(a*3.1416/180.0), 0], [0, 1, 0],[0,0,1]
-
-#----------------------------------------------
-# 0.4.1
-# 0.5.8, to remove exec
-#----------------------------------------------
-def skewy(t):
- a=t[0]
- return [1, 0, 0], [tan(a*3.1416/180.0), 1 , 0],[0,0,1]
-
-#----------------------------------------------
-# 0.3.2
-# 0.5.8, to remove exec
-#----------------------------------------------
-def matrix(t):
- a,b,c,d,e,f=t
- return [a,c,e],[b,d,f],[0,0,1]
-
-#--------------------
-# 0.5.8, to remove exec
-#--------------------
-matrixTRANSFORM={ 'translate':translate,
- 'scale':scale,
- 'rotate':rotate,
- 'skewx':skewx,
- 'skewy':skewy,
- 'matrix':matrix
- }
-
-#----------------------------------------------
-# 0.4.2 : rewritten
-# 0.5.8 : to remove exec uses.
-#----------------------------------------------
-def control_CONTAINT(txt):
- """
- the transforms' descriptions can be sole or several
- and separators might be forgotten
- """
- t0=0
- tlist=[]
- while txt.count(')',t0)>0:
- t1=txt.find(')',t0)
- nt0=txt[t0:t1+1]
- t2=nt0[nt0.find('(')+1:-1]
- val=nt0[:nt0.find('(')]
-
- while t2.find(' ')!=-1:
- t2=t2.replace(' ',' ')
- while t2.find(', ')!=-1: #059l
- t2=t2.replace(', ',',') #059l
-
- t2=t2.replace(' ',',')
- t2=[float(t) for t in t2.split(',')]
-
- if val=='rotate' :
- t3=t2
- if len(t3)==3:
- tlist.append(['translate',[t3[1],t3[2]]])
- tlist.append(['rotate',[t3[0]/180.0*3.1416]])
- tlist.append(['translate',[-t3[1],-t3[2]]])
- else:
- tlist.append(['rotate',[t3[0]]])
- else:
- tlist.append([val,t2])
- t0=t1+1
- return tlist
-
-
-def curve_FILL(Courbe,proprietes):
- global USE_COLORS
- for n in proprietes['n']:
- pr = proprietes['style']
- if n in Courbe and 'fill:' in pr:
- if not 'fill:none' in pr:
- Courbe[n].fill=1
- if USE_COLORS:
- i= pr.find('fill:#')
- if i != -1:
- i= i+6
- Courbe[n].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)]
- Courbe[n].mat=1
- elif ';fill-opacity' in pr:
- if pr.find('fill:url')==-1:
- i= pr.find('fill:')+5
- i2= pr.find(';',i)
- COLORNAME= pr[i:i2]
- Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
- Courbe[n].mat=1
- elif 'color:' in pr:
- i= pr.find('color:')+6
- i2= pr.find(';',i)
- COLORNAME= pr[i:i2]
- Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
- Courbe[n].mat=1
- else :
- COLORNAME= 'white'
- Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
- Courbe[n].mat=1
-
-#----------------------------------------------
-# 0.4.1 : apply transform stack
-#----------------------------------------------
-def curve_TRANSFORM(Courbe,proprietes):
- # 1/ unpack the STACK
- # create a matrix for each transform
- ST=[]
- for st in proprietes['stack'] :
- if st and type(st)==list:
- for t in st:
- code = control_CONTAINT(t)
- a,b,c=matrixTRANSFORM[code[0][0]](code[0][1][:])
- T=Mathutils.Matrix(a,b,c)
- ST.append(T)
- elif st :
- code = control_CONTAINT(st)
- a,b,c=matrixTRANSFORM[code[0][0]](code[0][1][:])
- T=Mathutils.Matrix(a,b,c)
- ST.append(T)
- if 'transform' in proprietes:
- for trans in control_CONTAINT(proprietes['transform']):
- #--------------------
- # 0.5.8, to remove exec
- #--------------------
- a,b,c=matrixTRANSFORM[trans[0].strip()](trans[1][:]) #059
- T=Mathutils.Matrix(a,b,c)
- ST.append(T)
- ST.reverse()
- for n in proprietes['n']:
- if n in Courbe:
- for bez0 in Courbe[n].beziers_knot:
- bez=bez0.co
- for b in [0,2,4]:
- for t in ST:
- v=t * Mathutils.Vector([bez[b],bez[b+1],1.0]) #059a
- bez[b]=v[0]
- bez[b+1]=v[1]
-
-def filter(d):
- for nn in d:
- if nn not in '0123456789.': #059a
- d=d.replace(nn,"")
- return d
-
-def get_BOUNDBOX(BOUNDINGBOX,SVG):
- if 'viewbox' not in SVG:
- h=float(filter(SVG['height']))
-
- w=float(filter(SVG['width']))
- BOUNDINGBOX['rec']=[0.0,0.0,w,h]
- r=BOUNDINGBOX['rec']
- BOUNDINGBOX['coef']=w/h
- else:
- viewbox=SVG['viewbox'].split()
- BOUNDINGBOX['rec']=[float(viewbox[0]),float(viewbox[1]),float(viewbox[2]),float(viewbox[3])]
- r=BOUNDINGBOX['rec']
- BOUNDINGBOX['coef']=(r[2]-r[0])/(r[3]-r[1])
- return BOUNDINGBOX
-
-#----------------------------------------------
-# 0.4.1 : attributs ex : 'id=', 'transform=', 'd=' ...
-#----------------------------------------------
-def collect_ATTRIBUTS(data):
- #----------------------------------------------
- # 0.4.8 : short modif for a fantasy font case
- # in the OOo svg format ('viewbox' is
- # written 'viewBox', for instance)
- #----------------------------------------------
- data=data.replace(' ',' ').lower()
- ELEM={'TYPE':data[1:data.find(' ')]}
- t1=len(data)
- t2=0
- ct=data.count('="')
- while ct>0:
- t0=data.find('="',t2)
- t2=data.find(' ',t2)+1
- id=data[t2:t0]
- t2=data.find('"',t0+2)
- if id!='d':
- ELEM[id]=data[t0+2:t2].replace('\\','/')
- else:
- ELEM[id]=[]
- ELEM[id].append(t0+2)
- ELEM[id].append(t2)
- ct=data.count('="',t2)
- return ELEM
-
-# --------------------------------------------
-# 0.4.1 : to avoid to use sax and ths xml
-# tools of the complete python
-# --------------------------------------------
-def build_HIERARCHY(t):
- global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM
- global LAST_ID, PATTERN
- TRANSFORM=0
- t=t.replace('\t',' ')
- while t.find(' ')!=-1: t=t.replace(' ',' ')
- n0=0
- t0=t1=0
- #baliste=[]
- balisetype=['?','?','/','/','!','!']
- BALISES=['D', #DECL_TEXTE',
- 'D', #DECL_TEXTE',
- 'F', #FERMANTE',
- 'E', #ELEM_VIDE',
- 'd', #DOC',
- 'R', #REMARQUES',
- 'C', #CONTENU',
- 'O' #OUVRANTE'
- ]
- STACK=[]
- while t1<len(t) and t0>-1:
- t0=t.find('<',t0)
- t1=t.find('>',t0)
- ouvrante=0
- #--------------------
- # 0.4.4 , add 'else:' and 'break' to the 'if' statement
- #--------------------
- if t0>-1 and t1>-1:
- if t[t0+1] in balisetype:
- b=balisetype.index(t[t0+1])
-
- if t[t0+2]=='-':
- b=balisetype.index(t[t0+1])+1
-
- balise=BALISES[b]
-
- if b==2:
- parent=STACK.pop(-1)
- if parent!=None and TRANSFORM>0:
- TRANSFORM-=1
-
- elif t[t1-1] in balisetype:
- balise=BALISES[balisetype.index(t[t1-1])+1]
-
- else:
- t2=t.find(' ',t0)
- if t2>t1: t2=t1
- ouvrante=1
- NOM=t[t0+1:t2]
-
-
- if '</'+NOM in t: #.find('</'+NOM)>-1:
- balise=BALISES[-1]
- if NOM=='pattern' and not PATTERN:
- t1=t.find('</'+NOM+'>',t0)+len('</'+NOM+'>')
- balise=BALISES[-3]
- else:
- balise=BALISES[-2]
-
- if balise=='E' or balise=='O':
-
- proprietes=collect_ATTRIBUTS(t[t0:t1+ouvrante])
-
- if 'id' in proprietes:
- LAST_ID=proprietes['id']
-
- if balise=='O' and 'transform' in proprietes:
- STACK.append(proprietes['transform'])
- TRANSFORM+=1
- elif balise=='O' :
- STACK.append(None)
-
- proprietes['stack']=STACK[:]
- D=[]
-
- if proprietes['TYPE'] in ['path'] and (proprietes['d'][1]-proprietes['d'][0]>1):
- D=list_DATA(t[proprietes['d'][0]+t0:proprietes['d'][1]+t0])
-
- elif proprietes['TYPE'] in OTHERSSHAPES:
- #--------------------
- # 0.5.8, to remove exec
- #--------------------
- D=OTHERSSHAPES[proprietes['TYPE']](proprietes)
-
- #elif proprietes['TYPE'] in ['pattern']:
- # print 'pattern'
- # D=''
-
- CP=[0.0,0.0]
- if len(D)>0:
- cursor=0
- proprietes['n']=[]
- for cell in D:
-
- if len(cell)>=1 and cell[0] in TAGcourbe:
- #--------------------
- # 0.5.8, to remove exec
- #--------------------
- if cell[0] in ['m','M']:
- curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP,proprietes)
- else:
- curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP)
-
- cursor+=1
- if TRANSFORM>0 or 'transform' in proprietes :
- curve_TRANSFORM(curves.ITEM,proprietes)
-
- if 'style' in proprietes :
- curve_FILL(curves.ITEM,proprietes)
-
-
- elif proprietes['TYPE'] == 'svg':
- BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,proprietes)
- else:
- #--------------------
- # 0.4.4
- #--------------------
- break
- t1+=1
- t0=t1
-
-def scan_FILE(nom):
- global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM
- global SEPARATE_CURVES, USE_COLORS, PATTERN
-
- dir,name=split(nom)
- name=name.split('.')
- result=0
- #Choise=1
- t1=Blender.sys.time()
- t=filterFILE(nom)
- if t!='false':
- Blender.Window.EditMode(0)
- if not SHARP_IMPORT:
- togH = Blender.Draw.Create(1)
- togW = Blender.Draw.Create(0)
- togAS = Blender.Draw.Create(0)
- togSP = Blender.Draw.Create(0)
- togCOL = Blender.Draw.Create(0)
- Pattern= Blender.Draw.Create(0)
- block=[\
- ("Clamp Width 1", togW, "Rescale the import with a Width of one unit"),\
- ("Clamp Height 1", togH, "Rescale the import with a Heightof one unit"),\
- ("No Rescaling", togAS, "No rescaling, the result can be very large"),\
- ("Separate Curves", togSP, "Create an object for each curve, Slower. May manage colors"),\
- ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option"),\
- ("Import Patterns", Pattern, "import pattern content if it is made with paths.")]
- retval = Blender.Draw.PupBlock("Import Options", block)
- if togW.val: scale_=1
- elif togH.val: scale_=2
- elif togAS.val: scale_=3
-
- if togSP.val: SEPARATE_CURVES=1
-
- if togCOL.val and SEPARATE_CURVES : USE_COLORS=1
-
- if Pattern.val : PATTERN =1
-
- t1=Blender.sys.time()
- # 0.4.1 : to avoid to use sax and the xml
- # tools of the complete python
- build_HIERARCHY(t)
- r=BOUNDINGBOX['rec']
- curves.number_of_items=len(curves.ITEM)
- for k, val in curves.ITEM.iteritems():
- val.pntsUV[0] =len(val.beziers_knot)
- if curves.number_of_items>0 : #and Choise==1 :
- #--------------------
- # 0.4.5 and 0.4.9
- #--------------------
- createCURVES(curves, name[0])
- else:
- pass
- print ' elapsed time : ',Blender.sys.time()-t1
- Blender.Redraw()
-
-#=====================================================================
-#====================== SVG format mouvements ========================
-#=====================================================================
-def functionSELECT(nom):
- scan_FILE(nom)
-
-
-if __name__=='__main__':
- Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg') \ No newline at end of file
diff --git a/release/scripts/bvh_import.py b/release/scripts/bvh_import.py
deleted file mode 100644
index 4134503c511..00000000000
--- a/release/scripts/bvh_import.py
+++ /dev/null
@@ -1,757 +0,0 @@
-#!BPY
-
-"""
-Name: 'Motion Capture (.bvh)...'
-Blender: 242
-Group: 'Import'
-Tip: 'Import a (.bvh) motion capture file'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("blender.org", "blenderartists.org")
-__version__ = "1.90 06/08/01"
-
-__bpydoc__ = """\
-This script imports BVH motion capture data to Blender.
-as empties or armatures.
-"""
-
-# --------------------------------------------------------------------------
-# BVH Import v2.0 by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-import BPyMessages
-Vector= Blender.Mathutils.Vector
-Euler= Blender.Mathutils.Euler
-Matrix= Blender.Mathutils.Matrix
-RotationMatrix = Blender.Mathutils.RotationMatrix
-TranslationMatrix= Blender.Mathutils.TranslationMatrix
-
-DEG2RAD = 0.017453292519943295
-
-class bvh_node_class(object):
- __slots__=(\
- 'name',# bvh joint name
- 'parent',# bvh_node_class type or None for no parent
- 'children',# a list of children of this type.
- 'rest_head_world',# worldspace rest location for the head of this node
- 'rest_head_local',# localspace rest location for the head of this node
- 'rest_tail_world',# # worldspace rest location for the tail of this node
- 'rest_tail_local',# # worldspace rest location for the tail of this node
- 'channels',# list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, lock triple then rot triple
- 'rot_order',# a triple of indicies as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation.
- 'anim_data',# a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz)
- 'has_loc',# Conveinience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 channels[2]!=-1)
- 'has_rot',# Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1)
- 'temp')# use this for whatever you want
-
- def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order):
- self.name= name
- self.rest_head_world= rest_head_world
- self.rest_head_local= rest_head_local
- self.rest_tail_world= None
- self.rest_tail_local= None
- self.parent= parent
- self.channels= channels
- self.rot_order= rot_order
-
- # convenience functions
- self.has_loc= channels[0] != -1 or channels[1] != -1 or channels[2] != -1
- self.has_rot= channels[3] != -1 or channels[4] != -1 or channels[5] != -1
-
-
- self.children= []
-
- # list of 6 length tuples: (lx,ly,lz, rx,ry,rz)
- # even if the channels arnt used they will just be zero
- #
- self.anim_data= [(0,0,0,0,0,0)]
-
-
- def __repr__(self):
- return 'BVH name:"%s", rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)' %\
- (self.name,\
- self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z,\
- self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z)
-
-
-
-# Change the order rotation is applied.
-MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1])
-MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
-
-def eulerRotate(x,y,z, rot_order):
- # Clamp all values between 0 and 360, values outside this raise an error.
- mats=[RotationMatrix(x%360,3,'x'), RotationMatrix(y%360,3,'y'), RotationMatrix(z%360,3,'z')]
- # print rot_order
- # Standard BVH multiplication order, apply the rotation in the order Z,X,Y
- return (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
-
-def read_bvh(file_path, GLOBAL_SCALE=1.0):
- # File loading stuff
- # Open the file for importing
- file = open(file_path, 'rU')
-
- # Seperate into a list of lists, each line a list of words.
- file_lines = file.readlines()
- # Non standard carrage returns?
- if len(file_lines) == 1:
- file_lines = file_lines[0].split('\r')
-
- # Split by whitespace.
- file_lines =[ll for ll in [ l.split() for l in file_lines] if ll]
-
-
- # Create Hirachy as empties
-
- if file_lines[0][0].lower() == 'hierarchy':
- #print 'Importing the BVH Hierarchy for:', file_path
- pass
- else:
- raise 'ERROR: This is not a BVH file'
-
- bvh_nodes= {None:None}
- bvh_nodes_serial = [None]
-
- channelIndex = -1
-
-
- lineIdx = 0 # An index for the file.
- while lineIdx < len(file_lines) -1:
- #...
- if file_lines[lineIdx][0].lower() == 'root' or file_lines[lineIdx][0].lower() == 'joint':
-
- # Join spaces into 1 word with underscores joining it.
- if len(file_lines[lineIdx]) > 2:
- file_lines[lineIdx][1] = '_'.join(file_lines[lineIdx][1:])
- file_lines[lineIdx] = file_lines[lineIdx][:2]
-
- # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
-
- # Make sure the names are unique- Object names will match joint names exactly and both will be unique.
- name = file_lines[lineIdx][1]
-
- #print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
-
- lineIdx += 2 # Incriment to the next line (Offset)
- rest_head_local = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
- lineIdx += 1 # Incriment to the next line (Channels)
-
- # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
- # newChannel references indecies to the motiondata,
- # if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended
- # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
- my_channel = [-1, -1, -1, -1, -1, -1]
- my_rot_order= [None, None, None]
- rot_count= 0
- for channel in file_lines[lineIdx][2:]:
- channel= channel.lower()
- channelIndex += 1 # So the index points to the right channel
- if channel == 'xposition': my_channel[0] = channelIndex
- elif channel == 'yposition': my_channel[1] = channelIndex
- elif channel == 'zposition': my_channel[2] = channelIndex
-
- elif channel == 'xrotation':
- my_channel[3] = channelIndex
- my_rot_order[rot_count]= 0
- rot_count+=1
- elif channel == 'yrotation':
- my_channel[4] = channelIndex
- my_rot_order[rot_count]= 1
- rot_count+=1
- elif channel == 'zrotation':
- my_channel[5] = channelIndex
- my_rot_order[rot_count]= 2
- rot_count+=1
-
- channels = file_lines[lineIdx][2:]
-
- my_parent= bvh_nodes_serial[-1] # account for none
-
-
- # Apply the parents offset accumletivly
- if my_parent==None:
- rest_head_world= Vector(rest_head_local)
- else:
- rest_head_world= my_parent.rest_head_world + rest_head_local
-
- bvh_node= bvh_nodes[name]= bvh_node_class(name, rest_head_world, rest_head_local, my_parent, my_channel, my_rot_order)
-
- # If we have another child then we can call ourselves a parent, else
- bvh_nodes_serial.append(bvh_node)
-
- # Account for an end node
- if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it.
- lineIdx += 2 # Incriment to the next line (Offset)
- rest_tail = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
-
- bvh_nodes_serial[-1].rest_tail_world= bvh_nodes_serial[-1].rest_head_world + rest_tail
- bvh_nodes_serial[-1].rest_tail_local= rest_tail
-
-
- # Just so we can remove the Parents in a uniform way- End end never has kids
- # so this is a placeholder
- bvh_nodes_serial.append(None)
-
- if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0] == '}': # == ['}']
- bvh_nodes_serial.pop() # Remove the last item
-
- if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion':
- #print '\nImporting motion data'
- lineIdx += 3 # Set the cursor to the first frame
- break
-
- lineIdx += 1
-
-
- # Remove the None value used for easy parent reference
- del bvh_nodes[None]
- # Dont use anymore
- del bvh_nodes_serial
-
- bvh_nodes_list= bvh_nodes.values()
-
- while lineIdx < len(file_lines):
- line= file_lines[lineIdx]
- for bvh_node in bvh_nodes_list:
- #for bvh_node in bvh_nodes_serial:
- lx= ly= lz= rx= ry= rz= 0.0
- channels= bvh_node.channels
- anim_data= bvh_node.anim_data
- if channels[0] != -1:
- lx= GLOBAL_SCALE * float( line[channels[0]] )
-
- if channels[1] != -1:
- ly= GLOBAL_SCALE * float( line[channels[1]] )
-
- if channels[2] != -1:
- lz= GLOBAL_SCALE * float( line[channels[2]] )
-
- if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
- rx, ry, rz = eulerRotate(float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] ), bvh_node.rot_order)
- #x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
-
- # Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
- # Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
-
- while anim_data[-1][3] - rx > 180: rx+=360
- while anim_data[-1][3] - rx < -180: rx-=360
-
- while anim_data[-1][4] - ry > 180: ry+=360
- while anim_data[-1][4] - ry < -180: ry-=360
-
- while anim_data[-1][5] - rz > 180: rz+=360
- while anim_data[-1][5] - rz < -180: rz-=360
-
- # Done importing motion data #
- anim_data.append( (lx, ly, lz, rx, ry, rz) )
- lineIdx += 1
-
- # Assign children
- for bvh_node in bvh_nodes.itervalues():
- bvh_node_parent= bvh_node.parent
- if bvh_node_parent:
- bvh_node_parent.children.append(bvh_node)
-
- # Now set the tip of each bvh_node
- for bvh_node in bvh_nodes.itervalues():
-
- if not bvh_node.rest_tail_world:
- if len(bvh_node.children)==0:
- # could just fail here, but rare BVH files have childless nodes
- bvh_node.rest_tail_world = Vector(bvh_node.rest_head_world)
- bvh_node.rest_tail_local = Vector(bvh_node.rest_head_local)
- elif len(bvh_node.children)==1:
- bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world)
- bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local)
- else:
- # allow this, see above
- #if not bvh_node.children:
- # raise 'error, bvh node has no end and no children. bad file'
-
- # Removed temp for now
- rest_tail_world= Vector(0,0,0)
- rest_tail_local= Vector(0,0,0)
- for bvh_node_child in bvh_node.children:
- rest_tail_world += bvh_node_child.rest_head_world
- rest_tail_local += bvh_node_child.rest_head_local
-
- bvh_node.rest_tail_world= rest_tail_world * (1.0/len(bvh_node.children))
- bvh_node.rest_tail_local= rest_tail_local * (1.0/len(bvh_node.children))
-
- # Make sure tail isnt the same location as the head.
- if (bvh_node.rest_tail_local-bvh_node.rest_head_local).length <= 0.001*GLOBAL_SCALE:
-
- bvh_node.rest_tail_local.y= bvh_node.rest_tail_local.y + GLOBAL_SCALE/10
- bvh_node.rest_tail_world.y= bvh_node.rest_tail_world.y + GLOBAL_SCALE/10
-
-
-
- return bvh_nodes
-
-
-
-def bvh_node_dict2objects(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
-
- if IMPORT_START_FRAME<1:
- IMPORT_START_FRAME= 1
-
- scn= bpy.data.scenes.active
- scn.objects.selected = []
-
- objects= []
-
- def add_ob(name):
- ob = scn.objects.new('Empty')
- objects.append(ob)
- return ob
-
- # Add objects
- for name, bvh_node in bvh_nodes.iteritems():
- bvh_node.temp= add_ob(name)
-
- # Parent the objects
- for bvh_node in bvh_nodes.itervalues():
- bvh_node.temp.makeParent([ bvh_node_child.temp for bvh_node_child in bvh_node.children ], 1, 0) # ojbs, noninverse, 1 = not fast.
-
- # Offset
- for bvh_node in bvh_nodes.itervalues():
- # Make relative to parents offset
- bvh_node.temp.loc= bvh_node.rest_head_local
-
- # Add tail objects
- for name, bvh_node in bvh_nodes.iteritems():
- if not bvh_node.children:
- ob_end= add_ob(name + '_end')
- bvh_node.temp.makeParent([ob_end], 1, 0) # ojbs, noninverse, 1 = not fast.
- ob_end.loc= bvh_node.rest_tail_local
-
-
- # Animate the data, the last used bvh_node will do since they all have the same number of frames
- for current_frame in xrange(len(bvh_node.anim_data)):
- Blender.Set('curframe', current_frame+IMPORT_START_FRAME)
-
- for bvh_node in bvh_nodes.itervalues():
- lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame]
-
- rest_head_local= bvh_node.rest_head_local
- bvh_node.temp.loc= rest_head_local.x+lx, rest_head_local.y+ly, rest_head_local.z+lz
-
- bvh_node.temp.rot= rx*DEG2RAD,ry*DEG2RAD,rz*DEG2RAD
-
- bvh_node.temp.insertIpoKey(Blender.Object.IpoKeyTypes.LOCROT)
-
- scn.update(1)
- return objects
-
-
-
-def bvh_node_dict2armature(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
-
- if IMPORT_START_FRAME<1:
- IMPORT_START_FRAME= 1
-
-
- # Add the new armature,
- scn = bpy.data.scenes.active
- scn.objects.selected = []
-
- arm_data= bpy.data.armatures.new()
- arm_ob = scn.objects.new(arm_data)
- scn.objects.context = [arm_ob]
- scn.objects.active = arm_ob
-
- # Put us into editmode
- arm_data.makeEditable()
-
- # Get the average bone length for zero length bones, we may not use this.
- average_bone_length= 0.0
- nonzero_count= 0
- for bvh_node in bvh_nodes.itervalues():
- l= (bvh_node.rest_head_local-bvh_node.rest_tail_local).length
- if l:
- average_bone_length+= l
- nonzero_count+=1
-
- # Very rare cases all bones couldbe zero length???
- if not average_bone_length:
- average_bone_length = 0.1
- else:
- # Normal operation
- average_bone_length = average_bone_length/nonzero_count
-
-
-
- ZERO_AREA_BONES= []
- for name, bvh_node in bvh_nodes.iteritems():
- # New editbone
- bone= bvh_node.temp= Blender.Armature.Editbone()
-
- bone.name= name
- arm_data.bones[name]= bone
-
- bone.head= bvh_node.rest_head_world
- bone.tail= bvh_node.rest_tail_world
-
- # ZERO AREA BONES.
- if (bone.head-bone.tail).length < 0.001:
- if bvh_node.parent:
- ofs= bvh_node.parent.rest_head_local- bvh_node.parent.rest_tail_local
- if ofs.length: # is our parent zero length also?? unlikely
- bone.tail= bone.tail+ofs
- else:
- bone.tail.y= bone.tail.y+average_bone_length
- else:
- bone.tail.y= bone.tail.y+average_bone_length
-
- ZERO_AREA_BONES.append(bone.name)
-
-
- for bvh_node in bvh_nodes.itervalues():
- if bvh_node.parent:
- # bvh_node.temp is the Editbone
-
- # Set the bone parent
- bvh_node.temp.parent= bvh_node.parent.temp
-
- # Set the connection state
- if not bvh_node.has_loc and\
- bvh_node.parent and\
- bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
- bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
- bvh_node.temp.options= [Blender.Armature.CONNECTED]
-
- # Replace the editbone with the editbone name,
- # to avoid memory errors accessing the editbone outside editmode
- for bvh_node in bvh_nodes.itervalues():
- bvh_node.temp= bvh_node.temp.name
-
- arm_data.update()
-
- # Now Apply the animation to the armature
-
- # Get armature animation data
- pose= arm_ob.getPose()
- pose_bones= pose.bones
-
- action = Blender.Armature.NLA.NewAction("Action")
- action.setActive(arm_ob)
- #xformConstants= [ Blender.Object.Pose.LOC, Blender.Object.Pose.ROT ]
-
- # Replace the bvh_node.temp (currently an editbone)
- # With a tuple (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv)
- for bvh_node in bvh_nodes.itervalues():
- bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
- pose_bone= pose_bones[bone_name]
- rest_bone= arm_data.bones[bone_name]
- bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart()
-
- bone_rest_matrix_inv= Matrix(bone_rest_matrix)
- bone_rest_matrix_inv.invert()
-
- bone_rest_matrix_inv.resize4x4()
- bone_rest_matrix.resize4x4()
- bvh_node.temp= (pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv)
-
-
- # Make a dict for fast access without rebuilding a list all the time.
- xformConstants_dict={
- (True,True): [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT],\
- (False,True): [Blender.Object.Pose.ROT],\
- (True,False): [Blender.Object.Pose.LOC],\
- (False,False): [],\
- }
-
-
- # KEYFRAME METHOD, SLOW, USE IPOS DIRECT
-
- # Animate the data, the last used bvh_node will do since they all have the same number of frames
- for current_frame in xrange(len(bvh_node.anim_data)-1): # skip the first frame (rest frame)
- # print current_frame
-
- #if current_frame==40: # debugging
- # break
-
- # Dont neet to set the current frame
- for bvh_node in bvh_nodes.itervalues():
- pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
- lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame+1]
-
- if bvh_node.has_rot:
- # Set the rotation, not so simple
- bone_rotation_matrix= Euler(rx,ry,rz).toMatrix()
- bone_rotation_matrix.resize4x4()
- pose_bone.quat= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()
-
- if bvh_node.has_loc:
- # Set the Location, simple too
- pose_bone.loc= (\
- TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) *\
- bone_rest_matrix_inv).translationPart() # WHY * 10? - just how pose works
-
- # Get the transform
- xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
-
-
- if xformConstants:
- # Insert the keyframe from the loc/quat
- pose_bone.insertKey(arm_ob, current_frame+IMPORT_START_FRAME, xformConstants, True )
-
- # First time, set the IPO's to linear
- if current_frame==0:
- for ipo in action.getAllChannelIpos().itervalues():
- if ipo:
- for cur in ipo:
- cur.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
- if IMPORT_LOOP:
- cur.extend = Blender.IpoCurve.ExtendTypes.CYCLIC
-
-
-
-
- # END KEYFRAME METHOD
-
-
- """
- # IPO KEYFRAME SETTING
- # Add in the IPOs by adding keyframes, AFAIK theres no way to add IPOs to an action so I do this :/
- for bvh_node in bvh_nodes.itervalues():
- pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
-
- # Get the transform
- xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
- if xformConstants:
- pose_bone.loc[:]= 0,0,0
- pose_bone.quat[:]= 0,0,1,0
- # Insert the keyframe from the loc/quat
- pose_bone.insertKey(arm_ob, IMPORT_START_FRAME, xformConstants)
-
-
- action_ipos= action.getAllChannelIpos()
-
-
- for bvh_node in bvh_nodes.itervalues():
- has_loc= bvh_node.has_loc
- has_rot= bvh_node.has_rot
-
- if not has_rot and not has_loc:
- # No animation data
- continue
-
- ipo= action_ipos[bvh_node.temp[0].name] # posebones name as key
-
- if has_loc:
- curve_xloc= ipo[Blender.Ipo.PO_LOCX]
- curve_yloc= ipo[Blender.Ipo.PO_LOCY]
- curve_zloc= ipo[Blender.Ipo.PO_LOCZ]
-
- curve_xloc.interpolation= \
- curve_yloc.interpolation= \
- curve_zloc.interpolation= \
- Blender.IpoCurve.InterpTypes.LINEAR
-
-
- if has_rot:
- curve_wquat= ipo[Blender.Ipo.PO_QUATW]
- curve_xquat= ipo[Blender.Ipo.PO_QUATX]
- curve_yquat= ipo[Blender.Ipo.PO_QUATY]
- curve_zquat= ipo[Blender.Ipo.PO_QUATZ]
-
- curve_wquat.interpolation= \
- curve_xquat.interpolation= \
- curve_yquat.interpolation= \
- curve_zquat.interpolation= \
- Blender.IpoCurve.InterpTypes.LINEAR
-
- # Get the bone
- pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
-
-
- def pose_rot(anim_data):
- bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix()
- bone_rotation_matrix.resize4x4()
- return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz
-
- def pose_loc(anim_data):
- return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart())
-
-
- last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
-
- if has_loc:
- pose_locations= [pose_loc(anim_key) for anim_key in bvh_node.anim_data]
-
- # Add the start at the end, we know the start is just 0,0,0 anyway
- curve_xloc.append((last_frame, pose_locations[-1][0]))
- curve_yloc.append((last_frame, pose_locations[-1][1]))
- curve_zloc.append((last_frame, pose_locations[-1][2]))
-
- if len(pose_locations) > 1:
- ox,oy,oz= pose_locations[0]
- x,y,z= pose_locations[1]
-
- for i in xrange(1, len(pose_locations)-1): # from second frame to second last frame
-
- nx,ny,nz= pose_locations[i+1]
- xset= yset= zset= True # we set all these by default
- if abs((ox+nx)/2 - x) < 0.00001: xset= False
- if abs((oy+ny)/2 - y) < 0.00001: yset= False
- if abs((oz+nz)/2 - z) < 0.00001: zset= False
-
- if xset: curve_xloc.append((i+IMPORT_START_FRAME, x))
- if yset: curve_yloc.append((i+IMPORT_START_FRAME, y))
- if zset: curve_zloc.append((i+IMPORT_START_FRAME, z))
-
- # Set the old and use the new
- ox,oy,oz= x,y,z
- x,y,z= nx,ny,nz
-
-
- if has_rot:
- pose_rotations= [pose_rot(anim_key) for anim_key in bvh_node.anim_data]
-
- # Add the start at the end, we know the start is just 0,0,0 anyway
- curve_wquat.append((last_frame, pose_rotations[-1][0]))
- curve_xquat.append((last_frame, pose_rotations[-1][1]))
- curve_yquat.append((last_frame, pose_rotations[-1][2]))
- curve_zquat.append((last_frame, pose_rotations[-1][3]))
-
-
- if len(pose_rotations) > 1:
- ow,ox,oy,oz= pose_rotations[0]
- w,x,y,z= pose_rotations[1]
-
- for i in xrange(1, len(pose_rotations)-1): # from second frame to second last frame
-
- nw, nx,ny,nz= pose_rotations[i+1]
- wset= xset= yset= zset= True # we set all these by default
- if abs((ow+nw)/2 - w) < 0.00001: wset= False
- if abs((ox+nx)/2 - x) < 0.00001: xset= False
- if abs((oy+ny)/2 - y) < 0.00001: yset= False
- if abs((oz+nz)/2 - z) < 0.00001: zset= False
-
- if wset: curve_wquat.append((i+IMPORT_START_FRAME, w))
- if xset: curve_xquat.append((i+IMPORT_START_FRAME, x))
- if yset: curve_yquat.append((i+IMPORT_START_FRAME, y))
- if zset: curve_zquat.append((i+IMPORT_START_FRAME, z))
-
- # Set the old and use the new
- ow,ox,oy,oz= w,x,y,z
- w,x,y,z= nw,nx,ny,nz
-
- # IPO KEYFRAME SETTING
- """
- pose.update()
- return arm_ob
-
-
-#=============#
-# TESTING #
-#=============#
-
-#('/metavr/mocap/bvh/boxer.bvh')
-#('/d/staggered_walk.bvh')
-#('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
-#('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
-#('/metavr/mocap/bvh/walk4.bvh') # 0 channels
-
-'''
-import os
-DIR = '/metavr/mocap/bvh/'
-for f in ('/d/staggered_walk.bvh',):
- #for f in os.listdir(DIR)[5:6]:
- #for f in os.listdir(DIR):
- if f.endswith('.bvh'):
- s = Blender.Scene.New(f)
- s.makeCurrent()
- #file= DIR + f
- file= f
- print f
- bvh_nodes= read_bvh(file, 1.0)
- bvh_node_dict2armature(bvh_nodes, 1)
-'''
-
-def load_bvh_ui(file, PREF_UI= True):
-
- if BPyMessages.Error_NoFile(file):
- return
-
- Draw= Blender.Draw
-
- IMPORT_SCALE = Draw.Create(0.1)
- IMPORT_START_FRAME = Draw.Create(1)
- IMPORT_AS_ARMATURE = Draw.Create(1)
- IMPORT_AS_EMPTIES = Draw.Create(0)
- IMPORT_LOOP = Draw.Create(0)
-
- # Get USER Options
- if PREF_UI:
- pup_block = [\
- ('As Armature', IMPORT_AS_ARMATURE, 'Imports the BVH as an armature'),\
- ('As Empties', IMPORT_AS_EMPTIES, 'Imports the BVH as empties'),\
- ('Scale: ', IMPORT_SCALE, 0.001, 100.0, 'Scale the BVH, Use 0.01 when 1.0 is 1 metre'),\
- ('Start Frame: ', IMPORT_START_FRAME, 1, 30000, 'Frame to start BVH motion'),\
- ('Loop Animation', IMPORT_LOOP, 'Enable cyclic IPOs'),\
- ]
-
- if not Draw.PupBlock('BVH Import...', pup_block):
- return
-
- print 'Attempting import BVH', file
-
- IMPORT_SCALE = IMPORT_SCALE.val
- IMPORT_START_FRAME = IMPORT_START_FRAME.val
- IMPORT_AS_ARMATURE = IMPORT_AS_ARMATURE.val
- IMPORT_AS_EMPTIES = IMPORT_AS_EMPTIES.val
- IMPORT_LOOP = IMPORT_LOOP.val
-
- if not IMPORT_AS_ARMATURE and not IMPORT_AS_EMPTIES:
- Blender.Draw.PupMenu('No import option selected')
- return
- Blender.Window.WaitCursor(1)
- # Get the BVH data and act on it.
- t1= Blender.sys.time()
- print '\tparsing bvh...',
- bvh_nodes= read_bvh(file, IMPORT_SCALE)
- print '%.4f' % (Blender.sys.time()-t1)
- t1= Blender.sys.time()
- print '\timporting to blender...',
- if IMPORT_AS_ARMATURE: bvh_node_dict2armature(bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
- if IMPORT_AS_EMPTIES: bvh_node_dict2objects(bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
-
- print 'Done in %.4f\n' % (Blender.sys.time()-t1)
- Blender.Window.WaitCursor(0)
-
-def main():
- Blender.Window.FileSelector(load_bvh_ui, 'Import BVH', '*.bvh')
-
-if __name__ == '__main__':
- #def foo():
- main()
- '''
- scn = bpy.data.scenes.active
- for ob in list(scn.objects):
- if ob.name!='arm__':
- scn.objects.unlink(ob)
- load_bvh_ui('/test.bvh', False)
- ''' \ No newline at end of file
diff --git a/release/scripts/c3d_import.py b/release/scripts/c3d_import.py
deleted file mode 100644
index 98f643cbab9..00000000000
--- a/release/scripts/c3d_import.py
+++ /dev/null
@@ -1,1244 +0,0 @@
-#!BPY
-# -*- coding: latin-1 -*-
-"""
-Name: 'Motion Capture (.c3d)...'
-Blender: 246
-Group: 'Import'
-Tooltip: 'Import a C3D Motion Capture file'
-"""
-__script__ = "C3D Motion Capture file import"
-__author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)"
-__version__ = "0.9"
-__url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"]
-__email__= ["rogerwickes@yahoo.com", "c3d script"]
-__bpydoc__ = """\
-c3d_import.py v0.8
-
-Script loading Graphics Lab Motion Capture file,
-Usage:<br>
- - Run the script <br>
- - Choose the file to open<br>
- - Press Import C3D button<br>
-
-Version History:
- 0.4: PERIN Released under Blender Artistic Licence
- 0.5: WICKES used marker names, fixed 2.45 depricated call
- 0.6: WICKES creates armature for each subject
- 0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s
- 0.8: WICKES resolved DEC support issue
- 0.9: BARTON removed scene name change, whitespace edits. WICKES added IK layers
-"""
-
-#----------------------------------------------
-# (c) Jean-Baptiste PERIN december 2005, released under Blender Artistic Licence
-# for the Blender 2.40 Python Scripts Bundle.
-#----------------------------------------------
-
-######################################################
-# This script imports a C3D file into blender.
-# Loader is based on MATLAB C3D loader from
-# Alan Morris, Toronto, October 1998
-# Jaap Harlaar, Amsterdam, april 2002
-######################################################
-
-import string
-import Blender
-from Blender import *
-import bpy
-import struct
-import BPyMessages
-Vector= Blender.Mathutils.Vector
-Euler= Blender.Mathutils.Euler
-Matrix= Blender.Mathutils.Matrix
-RotationMatrix = Blender.Mathutils.RotationMatrix
-TranslationMatrix= Blender.Mathutils.TranslationMatrix
-
-#=================
-# Global Variables, Constants, Defaults, and Shorthand References
-#=================
-# set senstitivity for displaying debug/console messages. 0=few, 100=max, including clicks at major steps
-# debug(num,string) to conditionally display status/info in console window
-DEBUG=Blender.Get('rt')
-
-# marker sets known in the world
-HUMAN_CMU= "HumanRTKm.mkr" # The Human Real-Time capture marker set used by CMU
-HUMAN_CMU2="HumanRT.mkr" # found in another file, seems same as others in that series
-MARKER_SETS = [ HUMAN_CMU, HUMAN_CMU2 ] # marker sets that this program supports (can make an armature for)
-XYZ_LIMIT= 10000 #max value for coordinates if in integer format
-
-# what layers to put stuff on in scene. 1 is selected, so everything goes there
-# selecting only layer 2 shows only the armature moving, 12 shows only the empties
-LAYERS_ARMOB= [1,2]
-LAYERS_MARKER=[1,12]
-LAYERS_IK=[1,11]
-IK_PREFIX="ik_" # prefix in empty name: ik_prefix+subject prefix+bone name
-
-CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits?
-
-scn = Blender.Scene.GetCurrent()
-
-BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket
-trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ}
-trackup={"x":BCS.UPX, "y":BCS.UPY, "z":BCS.UPZ}
-
-#=============================#
-# Classes
-#=============================#
-class Marker:
- def __init__(self, x, y, z):
- self.x=0.0
- self.y=0.0
- self.z=0.0
-
- def __repr__(self): #report on self, as in if just printed
- return str("[x = "+str(self.x) +" y = " + str(self.y)+" z = "+ str(self.z)+"]")
-
-class ParameterGroup:
- def __init__(self, nom, description, parameter):
- self.name = nom
- self.description = description
- self.parameter = parameter
-
- def __repr__(self):
- return self.name, " ", self.description, " ", self.parameter
-
-class Parameter:
- def __init__(self, name, datatype, dim, data, description):
- self.name = name
- self.datatype = datatype
- self.dim = dim
- self.data = data
- self.description = description
-
- def __repr__(self):
- return self.name, " ", self.description, " ", self.dim
-
-class MyVector:
- def __init__(self, fx,fy,fz):
- self.x=fx
- self.y=fy
- self.z=fz
-
-class Mybone:
- "information structure for bone generation and posing"
- def __init__(self, name,vec,par,head,tail,const):
- self.name=name # name of this bone. must be unique within armature
- self.vec=vec # edit bone vector it points
- self.parent=par # name of parent bone to locate head and form a chain
- self.headMark=head # list of 0+ markers where the head of this non-parented bone should be placed
- self.tailMark=tail # list of 0+ markers where the tip should be placed
- self.const=const # list of 0+ constraint tuples to control posing
- self.head=MyVector(0,0,0) #T-pose location
- self.tail=MyVector(0,0,0)
- def __repr__(self):
- return '[Mybone "%s"]' % self.name
-
-
-#=============================#
-# functions/modules
-#=============================#
-def error(str):
- Draw.PupMenu('ERROR%t|'+str)
- return
-def status(str):
- Draw.PupMenu('STATUS%t|'+str+"|Continue?")
- return
-def debug(num,msg): #use log4j or just console here.
- if DEBUG >= num:
- print 'debug:', (' '*num), msg
- #TODO: if level 0, make a text file in Blender file to record major stuff
- return
-
-def names(ob): return ob.name
-
-
-#########
-# Cette fonction renvoie la liste des empties
-# in :
-# out : emp_list (List of Object) la liste des objets de type "Empty"
-#########
-def getEmpty(name):
- obs = [ob for ob in scn.objects if ob.type=="Empty" and ob.name==name]
- if len(obs)==0:
- return None
- elif len(obs)==1:
- return obs[0]
- else:
- error("FATAL ERROR: %i empties %s in file" % (len(obs),ob[0]))
-#########
-# Cette fonction renvoie un empty
-# in : objname : le nom de l'empty recherche
-# out : myobj : l'empty cree ou retrouve
-#########
-def getOrCreateEmpty(objname):
- myobj= getEmpty(objname)
- if myobj==None:
- myobj = scn.objects.new("Empty",objname)
- debug(50,'Marker/Empty created %s' % myobj)
- return myobj
-
-def getOrCreateCurve(ipo, curvename):
- """
- Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
-
- >>> import mylib
-
- >>> lIpo = GetOrCreateIPO("Une IPO")
- >>> laCurve = getOrCreateCurve(lIpo, "RotX")
-
- Either an ipo curve named C{curvename} exists before the call then this curve is returned,
- Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned
-
- @type ipo: Blender Ipo
- @param ipo: the Ipo in which the curve must be retrieved or created.
- @type curvename: string
- @param curvename: name of the IPO.
- @rtype: Blender Curve
- @return: a Blender Curve named C{curvename} in the C{ipo} Ipo
- """
- try:
- mycurve = ipo.getCurve(curvename)
- if mycurve != None:
- pass
- else:
- mycurve = ipo.addCurve(curvename)
- except:
- mycurve = ipo.addCurve(curvename)
- return mycurve
-
-def eraseIPO (objectname):
- object = Blender.Object.Get(objectname)
- lIpo = object.getIpo()
- if lIpo != None:
- nbCurves = lIpo.getNcurves()
- for i in range(nbCurves):
- nbBezPoints = lIpo.getNBezPoints(i)
- for j in range(nbBezPoints):
- lIpo.delBezPoint(i)
-
-def comp_loc(emptyNameList):
- myloc=Vector(0,0,0)
- for emName in emptyNameList:
- myobj = Blender.Object.Get(emName)
- for i in range(3):
- myloc[i]= myloc[i]+(myobj.loc[i]/len(emptyNameList)) #take the average loc of all marks
- return myloc
-
-def comp_len(head, tail): # computes the length of a bone
- headvec=comp_loc(head)
- tailvec=comp_loc(tail)
- netvec=headvec-tailvec
- return netvec.length
-
-def createHumanCMU(): # human bone structure, makes a node set for CMU MoCap Lab
- # order of bones: "spine","chest","neck","head",...face toward you in front view
- # pose constraints are tuples of (type,target,influence,other-as-needed)
- # constraint stack order is important. for proper bone pointing and orinetation:
- # IK, then TT +YZ in world space. then LR XZ to 0 in world space, this points the bone, twists it, but then
- # limits the rotation to the sidebar enpty with the Z facing it, and Y pointing along the bone.
- nodes=[] # bonename, vector, parent, head targets, tail targets, constraint list
- for i in range(23): nodes.append(Mybone("name","vec","par",[],[],[]))
- nodes[0]= Mybone("root", "-Y","",["RBWT", "LBWT"],["RFWT", "LFWT", "RBWT", "LBWT"],[("LOC","RBWT",1.0),("LOC","LBWT",0.5),("IK","RFWT",1.0),("IK","LFWT",0.5),("TT","RBWT",1,"+YZ"),("LR","XZ",1)])
- nodes[1]= Mybone("spine","+Z","root",[],["STRN","T10"],[("IK","STRN",1.0),("IK","T10",0.5),("TT","STRN",1,"+YZ"),("LR","XZ",1)])
- nodes[2]= Mybone("chest","+Z","spine",[],["CLAV","C7"],[("IK","CLAV",1.0),("IK","C7",0.5),("TT","CLAV",1,"+YZ"),("LR","XZ",1)])
- nodes[3]= Mybone("neck", "+Z","chest",[],["RBHD","LBHD"],[("IK","RBHD",1.0),("IK","LBHD",0.5),("TT","LBHD",1,"+YZ"),("LR","XZ",1)])
- nodes[4]= Mybone("head" ,"-Y","neck",[],["RFHD","LFHD"],[("IK","RFHD",1.0),("IK","LFHD",0.5),("TT","LFHD",1,"+YZ"),("LR","XZ",1)])
-
- nodes[5]= Mybone("shoulder.R","-X","chest",[],["RSHO"],[("IK","RSHO",1.0)])
- nodes[6]= Mybone("toparm.R", "-X","shoulder.R",[],["RELB"],[("IK","RELB",1.0),("TT","RUPA",1,"+YZ"),("LR","XZ",1)])
- nodes[7]= Mybone("lowarm.R", "-X","toparm.R",[],["RWRA","RWRB"],[("IK","RWRA",1.0),("IK","RWRB",0.5),("TT","RFRM",1,"+YZ"),("LR","XZ",1)])
- nodes[8]= Mybone("hand.R", "-X","lowarm.R",[],["RFIN"],[("IK","RFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"RTHM"
-
- nodes[9]= Mybone("hip.R", "-X","root",[],["RFWT","RBWT"],[("IK","RFWT",1.0),("IK","RBWT",0.5)])
- nodes[10]=Mybone("topleg.R","-Z","hip.R",[],["RKNE"],[("IK","RKNE",1),("TT","RTHI",1,"+YZ"),("LR","XZ",1)])
- nodes[11]=Mybone("lowleg.R","-Z","topleg.R",[],["RANK","RHEE"],[("IK","RHEE",1.0),("TT","RSHN",1,"+YZ"),("LR","XZ",1)])
- nodes[12]=Mybone("foot.R", "-Y","lowleg.R",[],["RTOE","RMT5"],[("IK","RTOE",1.0),("IK","RMT5",0.2),("TT","RMT5",1,"+YZ")])
- nodes[13]=Mybone("toes.R", "-Y","foot.R",[],["RTOE"],[("IK","RTOE",1.0)])
-
- nodes[14]=Mybone("shoulder.L","+X","chest",[],["LSHO"],[("IK","LSHO",1.0)])
- nodes[15]=Mybone("toparm.L", "+X","shoulder.L",[],["LELB"],[("IK","LELB",1.0),("TT","LUPA",1,"+YZ"),("LR","XZ",1)])
- nodes[16]=Mybone("lowarm.L", "+X","toparm.L",[],["LWRA","LWRB"],[("IK","LWRA",1.0),("IK","LWRB",0.5),("TT","LFRM",1,"+YZ"),("LR","XZ",1)])
- nodes[17]=Mybone("hand.L", "+X","lowarm.L",[],["LFIN"],[("IK","LFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"LTHM"
-
- nodes[18]=Mybone("hip.L", "+X","root",[],["LFWT","LBWT"],[("IK","LFWT",1.0),("IK","LBWT",0.5)])
- nodes[19]=Mybone("topleg.L","-Z","hip.L",[],["LKNE"],[("IK","LKNE",1),("TT","LTHI",1,"+YZ"),("LR","XZ",1)])
- nodes[20]=Mybone("lowleg.L","-Z","topleg.L",[],["LANK","LHEE"],[("IK","LHEE",1.0),("TT","LSHN",1,"+YZ"),("LR","XZ",1)])
- nodes[21]=Mybone("foot.L", "-Y","lowleg.L",[],["LTOE","LMT5"],[("IK","LTOE",1.0),("IK","LMT5",0.2),("TT","LMT5",1,"+YZ"),("LR","XZ",1)])
- nodes[22]=Mybone("toes.L", "-Y","foot.L",[],["LTOE"],[("IK","LTOE",1.0)])
- return nodes
-
-def createNodes(marker_set): # make a list of bone name, parent, edit head loc, edit tail loc, pose constraints
- #ultimately, I want to read in an XML file here that specifies the node trees for various marker sets
- if marker_set==HUMAN_CMU: nodes= createHumanCMU() #load up and verify the file has the CMU marker set
- elif marker_set==HUMAN_CMU2: nodes= createHumanCMU()
- else: nodes=[]
- return nodes
-def findEntry(item,list):
- for i in range(len(list)):
- if item==list[i]: break
- debug(100,"findEtnry %s is %i in list of %i items" % (item,i,len(list)))
- return i
-def makeNodes(prefix, markerList, empties, marker_set): #make sure the file has the nodes selected
- nodes= createNodes(marker_set) # list has generic marker names; replace them with the actual object names created
- #each entry in markerlist has a corresponding entry in empties in the same order
- errList=[]
- for i in range(len(nodes)):
- node= nodes[i]
- debug(60,"Adapting node %s to prefix %s" % (node,prefix))
-
- #replace generic head markers with actual empty names
- for im in range(len(node.headMark)):
- marker= node.headMark[im]
- mark= prefix+marker
- imn= findEntry(mark,markerList)
- if imn < len(markerList):
- debug(90,"Adapating head marker %s to %s" % (marker,empties[imn].name))
- nodes[i].headMark[im]= empties[imn].name
- else: errList.append([node.name,"head location",mark,node,2])
-
- #replace generic tail markers with actual empty names
- for im in range(len(node.tailMark)):
- marker= node.tailMark[im]
- mark= prefix+marker
- imn= findEntry(mark,markerList)
- if imn < len(markerList):
- debug(90,"Adapating marker %s to %s" % (marker,empties[imn].name))
- nodes[i].tailMark[im]= empties[imn].name
- else: errList.append([node.name,"tail location",mark,node,2])
-
- #replace generic constraint markers (if the constraint references a marker) with empty name
- for im in range(len(node.const)):
- const=node.const[im]
- if const[0] in ("LOC","IK","TT"):
- marker=const[1]
- mark= prefix+marker
- imn= findEntry(mark,markerList)
- if imn < len(markerList):
- debug(90,"Adapating %s constraint marker %s to %s" % (const[0],marker,empties[imn].name))
- if const[0] in ("IK","LR","LOC"):
- nodes[i].const[im]=(const[0], empties[imn].name, const[2])
- else: nodes[i].const[im]=(const[0], empties[imn].name, const[2], const[3])
- else: errList.append([node.name,const[0]+" constraint",mark,node,4])
-
- if errList!=[]: #we have issues.
- for err in errList:
- debug(0,"Bone "+err[0]+" specifies "+err[2]+" as "+err[1]+"which was not specified in file.")
- #need a popup here to ignore/cleanup node tree, or add the marker(?) or abort
- usrOption= 1
- if usrOption==0: #ignore this marker (remove it)
- for node in nodes: #find the bone in error
- if node.name==err[0]:
- print "Before",node
- if err[3] in range(2,3):
- node[err[3]].remove(err[2]) #find the marker in error and remove it
- elif err[3]==4: #find the constraint and remove it
- for const in node.const:
- if const[1]==err[2]: node.const.remove(const)
- print "After",node
- elif usrOption==1: #add these markers as static empties, and user will automate them later
- #and the bones will be keyed to them, so it will all be good.
- #file may have just mis-named the empty, or the location can be derived based on other markers
- em= getOrCreateEmpty(err[2])
- em.layers= LAYERS_MARKER
- else: abort() #abend
- if DEBUG==100: status("Nodes Updated")
- return nodes #nodes may be updated
-
-def makeBones(arm,nodes):
- debug(20,"Making %i edit bones" % len(nodes))
- for node in nodes:
- bone= Blender.Armature.Editbone()
- bone.name= node.name
- arm.bones[bone.name]= bone #add it to the armature
- debug(50,"Bone added: %s" % bone)
- if bone.name <> node.name:
- debug(0,"ERROR: duplicate node % name specified" % node.name)
- node.name= bone.name #you may not get what you asked for
- if node.parent!="": #parent
- debug(60,"Bone parent: %s"%node.parent)
- bone.parent= arm.bones[node.parent]
- bone.options = [Armature.CONNECTED]
- #compute head = average of the reference empties
- if node.headMark==[]: # no head explicitly stated, must be tail of parent
- for parnode in nodes:
- if node.parent==parnode.name: break
- node.headMark= parnode.tailMark
- node.head= parnode.tail
- else: node.head= comp_loc(node.headMark) #node head is specified, probably only for root.
-
- bone.head= node.head
- debug(60,"%s bone head: (%0.2f, %0.2f, %0.2f)" % (bone.name,bone.head.x, bone.head.y, bone.head.z))
- mylen=comp_len(node.headMark,node.tailMark) # length of the bone as it was recorded for that person
- # for our T position, compute the bone length, add it to the head vector component to get the tail
- if node.vec[0]=="-": mylen=-mylen
- debug(80,"Bone vector %s length %0.2f" %(node.vec,mylen))
- node.tail= Vector(node.head)
- myvec=node.vec[1].lower()
- if myvec=="x": node.tail.x+=mylen
- elif myvec=="y": node.tail.y+=mylen
- elif myvec=="z": node.tail.z+=mylen
- else:
- debug(0,"%s %s %s %s" % (node.vec,myvec,node.vec[0],node.vec[1]))
- error("ERROR IN BONE SPEC ")
- bone.tail= node.tail
- debug(60,"Bone tail: (%i,%i,%i)" %(bone.tail.x, bone.tail.y, bone.tail.z))
- #Armature created in the T postion, but with bone lengths to match the marker set and subject
- #when this is constrained to the markers, the recorded action will be relative to a know Rotation
- #so that all recorded actions should be interchangeable. wooot!
- #Only have to adjust starting object loc when matching up actions.
- return #arm #updated
-
-def makeConstLoc(pbone,const):
- const_new= pbone.constraints.append(Constraint.Type.COPYLOC)
- const_new.name = const[0]+"-"+const[1]
- const_target=Blender.Object.Get(const[1])
- const_new[BCS.TARGET]= const_target
- const_new.influence = const[2]
- return
-
-def makeConstLimRot(pbone,const):
- const_new= pbone.constraints.append(Constraint.Type.LIMITROT)
- const_new.name = const[0]+"-"+const[1]
- for axis in const[1]:
- if axis.lower()=="x": const_new[BCS.LIMIT] |= BCS.LIMIT_XROT #set
- if axis.lower()=="y": const_new[BCS.LIMIT] |= BCS.LIMIT_YROT #set
- if axis.lower()=="z": const_new[BCS.LIMIT] |= BCS.LIMIT_ZROT #set
- const_new[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
- const_new.influence = const[2]
- # fyi, const[Constraint.Settings.LIMIT] &= ~Constraint.Settings.LIMIT_XROT #reset
- return
-
-def makeConstIK(prefix,pbone,const):
- #Blender 246 only supports one IK Solver per bone, but we might want many,
- # so we need to create a reference empty named after the bone
- # that floats between the markers, so the bone can point to it as a singularity
- myob= getOrCreateEmpty(IK_PREFIX+prefix+pbone.name)
- myob.layers= LAYERS_IK
- # note that this empty gets all the IK constraints added on as location constraints
- myconst= myob.constraints.append(Constraint.Type.COPYLOC)
- myconst.name=const[0]+"-"+const[1]
- myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1])
- myconst.influence = const[2]
-
- #point the bone once to the empty via IK
- success=False
- for myconst in pbone.constraints:
- if myconst.type == Constraint.Type.IKSOLVER: success=True
- if not(success): #add an IK constraint to the bone to point to the empty
- #print pbone
- myconst= pbone.constraints.append(Constraint.Type.IKSOLVER)
- myconst.name = const[1]
- myconst[BCS.TARGET]= myob
- myconst.influence = const[2]
- #const_new[Constraint.Settings.BONE]= ?
- myconst[BCS.CHAINLEN]= 1
- myconst[BCS.USETIP]= True
- myconst[BCS.STRETCH]= False
- return
-
-def makeConstTT(pbone,const):
- myconst= pbone.constraints.append(Constraint.Type.TRACKTO)
- myconst.name=const[0]+"-"+const[1]
- debug(70,"%s %s" % (myconst,const[3]))
- myob= getEmpty(const[1])
- if myob!= None:
- myconst[BCS.TARGET]= myob
- myconst.influence = const[2]
- #const[3] is the Track and the thrird char is the Up indicator
- myconst[BCS.TRACK]= trackto[const[3][0:2].lower()]
- myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction
- myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
- myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL]
- if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE")
- else: #marker not found. could be missing from this file, or an error in node spec
- error("TrackTo Constraint for %s |specifies unknown marker %s" % (pbone.name,const[1]))
- return
-
-def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements
- #this is constraint-based posing, not hard-keyed posing.
- #we do constraint-based first so that user can adjust the constraints, possibly smooth/tweak motion
- # add additional bones or referneces/constraints, before baking to hard keyframes
-
- pose= arm_ob.getPose()
- debug(0,"Posing %s %s" % (arm_ob, pose))
- for node in nodes:
- debug(30, "examining %s" %node)
- if len(node.const)>0: #constraints for this bone are desired
- pbone = pose.bones[node.name]
- debug(40,"Posing bone %s" %pbone)
- for const in node.const:
- debug(50,"Constraining %s by %s" %(pbone,const))
- if const[0]=="LOC":makeConstLoc(pbone,const)
- elif const[0]=="IK": makeConstIK(prefix,pbone,const)
- elif const[0]=="LR": makeConstLimRot(pbone,const)
- elif const[0]=="TT": makeConstTT(pbone,const)
- else:
- error("FATAL: constraint %s not supported" %const[0])
- break
- debug(10, "Posing complete. Cycling pose and edit mode")
- pose.update()
- return
-
-def make_arm(subject,prefix,markerList, emptyList,marker_set):
- debug(10,"**************************")
- debug(00, "**** Making Armature for %s..." % subject)
- debug(10, "**************************")
- # copied from bvh import bvh_node_dict2armature; trying to use similar process for further integtration down the road
- # Add the new armature,
-
- nodes= makeNodes(prefix, markerList, emptyList, marker_set) #assume everyone in file uses the same mocap suit
- # each person in the file may be different height, so each needs their own new armature to match marker location
-
-## obs= Blender.Object.Get()
-## success=False
-## for ob in obs:
-## if ob.name==subject:
-## success=True
-## if success:
-## menu="Human Armature already exists for this subject."
-## menu+="%t|Create another in this scene"
-## menu+="%l|Start a new scene"
-## menu+="%l|Use this armature"
-## menusel= Draw.PupMenu(menu)
-
- arm= Blender.Armature.New(subject) #make an armature.
- debug(10,"Created Armature %s" % arm)
- # Put us into editmode
- arm.makeEditable()
- arm.drawType = Armature.OCTAHEDRON
- makeBones(arm,nodes)
- scn = Blender.Scene.GetCurrent() #add it to the current scene. could create new scenes here as yaf
- arm_ob= scn.objects.new(arm) #instance it in the scene. this is the new way for 2.46 to instance objects
- arm_ob.name= subject #name it something like the person it represents
- arm_ob.layers= LAYERS_ARMOB
- debug(20,"Instanced Armature %s" % arm_ob)
- arm.update() #exit editmode. Arm must be instanced as an object before you can save changes or pose it
- Blender.Redraw() # show the world
- if DEBUG==100: status("T-Bones made.")
-
- makePoses(prefix,arm_ob,nodes) #constrain arm_ob with these markers
-
- scn.update(1) #make everyone behave themselves in the scene, and respect the new constraints
- return arm_ob
-
-def setupAnim(StartFrame, EndFrame, VideoFrameRate):
- debug(100, 'VideoFrameRate is %i' %VideoFrameRate)
- if VideoFrameRate<1: VideoFrameRate=1
- if VideoFrameRate>120: VideoFrameRate=120
- # set up anim panel for them
- context=scn.getRenderingContext()
- context.sFrame=StartFrame
- context.eFrame=EndFrame
- context.fps=int(VideoFrameRate)
-
- Blender.Set("curframe",StartFrame)
- Blender.Redraw()
- return
-
-def makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers):
- debug(10, "**************************")
- debug(00, "*** Making Cloud Formation")
- debug(10, "**************************")
- empties=[]
- ipos=[]
- curvesX=[]
- curvesY=[]
- curvesZ=[]
- debug(0, "%i Markers (empty cloud) will be put on layers %s" % (Nmarkers,LAYERS_MARKER))
- # Empty Cloud formation
- for i in range(Nmarkers):
- debug(100,"%i marker %s"%(i, markerList[i]))
- emptyname = markerList[i] # rdw: to use meaningful names from Points parameter
- em= getOrCreateEmpty(emptyname) #in this scene
- em.layers= LAYERS_MARKER
- #make a list of the actual empty
- empties.append(em)
- #assign it an ipo with the loc xyz curves
- lipo = Ipo.New("Object",em.name)
- ipos.append(lipo)
- curvesX.append(getOrCreateCurve(ipos[i],'LocX'))
- curvesY.append(getOrCreateCurve(ipos[i],'LocY'))
- curvesZ.append(getOrCreateCurve(ipos[i],'LocZ'))
- empties[i].setIpo(ipos[i])
- debug(30,"Cloud of %i empties created." % len(empties))
- NvideoFrames= EndFrame-StartFrame+1
- debug(10, "**************************")
- debug(00, "**** Calculating Marker Ipo Curves over %i Frames ..." % NvideoFrames)
- debug(10, "**************************")
- err= index=0 #number of errors, logical frame
- for frame in range(StartFrame,EndFrame+1):
- if index==0: start=sys.time()
- elif index==100:
- tmp=(NvideoFrames-100)*(sys.time()-start)/6000
- debug(0,"%i minutes process time estimated" % tmp)
- elif index >100: print index*100/(NvideoFrames-1),"% complete\r",
- for i in range(Nmarkers):
- if Markers[index][i].z < 0: Markers[index][i].z= -Markers[index][i].z
- success=True
- if CLEAN: #check for good data
- # C3D marker decoding may have coordinates negative (improper sign bit decoding?)
- myX= abs(Markers[index][i].x)
- myY= abs(Markers[index][i].y)
- myZ= Markers[index][i].z
- if myX > 10000 or myY > 10000 or myZ > 10000: success=False
- if myX <.01 and myY <.01 and myZ <.01: success=False # discontinuity in marker tracking (lost marker)
-
- if success:
- curvesX[i].append((frame, Markers[index][i].x)) #2.46 knot method
- curvesY[i].append((frame, Markers[index][i].y))
- curvesZ[i].append((frame, Markers[index][i].z))
- if frame==StartFrame: debug(40, "%s loc frame %i: (%0.2f, %0.2f, %0.2f)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z))
- else:
- err+=1 # some files have thousands...
- #debug(30,"Point ignored for marker:%s frame %i: (%i, %i, %i)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z))
- index += 1
- debug(70, "%i points ignored across all markers and frames. Recalculating..." % err)
-
- for i in range(Nmarkers):
- curvesX[i].Recalc()
- curvesY[i].Recalc()
- curvesZ[i].Recalc()
- Blender.Set('curframe', StartFrame)
- Blender.Redraw()
- if DEBUG==100: status("Clound formed")
- return empties
-
-def getNumber(str, length):
- if length==2: # unsigned short
- return struct.unpack('H',str[0:2])[0], str[2:]
- sum = 0
- for i in range(length):
- #sum = (sum << 8) + ord(str[i]) for big endian
- sum = sum + ord(str[i])*(2**(8*i))
- return sum, str[length:]
-def unpackFloat(chunk,proctype):
- #print proctype
- myvar=chunk[0:4]
- if proctype==2: #DEC-VAX
- myvar=chunk[2:4]+chunk[0:2] #swap lo=hi word order pair
- return struct.unpack('f',myvar[0:4])[0]
-
-def getFloat(chunk,proctype):
- return unpackFloat(chunk, proctype), chunk[4:]
-def parseFloat(chunk,ptr,proctype):
- return unpackFloat(chunk[ptr:ptr+4], proctype), ptr+4
-
-
-def load_c3d(FullFileName):
-# Input: FullFileName - file (including path) to be read
-#
-# Variable:
-# Markers 3D-marker data [Nmarkers x NvideoFrames x Ndim(=3)]
-# VideoFrameRate Frames/sec
-# AnalogSignals Analog signals [Nsignals x NanalogSamples ]
-# AnalogFrameRate Samples/sec
-# Event Event(Nevents).time ..value ..name
-# ParameterGroup ParameterGroup(Ngroups).Parameters(Nparameters).data ..etc.
-# CameraInfo MarkerRelated CameraInfo [Nmarkers x NvideoFrames]
-# ResidualError MarkerRelated ErrorInfo [Nmarkers x NvideoFrames]
-
- Markers=[];
- VideoFrameRate=120;
- AnalogSignals=[];
- AnalogFrameRate=0;
- Event=[];
- ParameterGroups=[];
- CameraInfo=[];
- ResidualError=[];
-
- debug(10, "*********************")
- debug(10, "**** Opening File ***")
- debug(10, "*********************")
-
- #ind=findstr(FullFileName,'\');
- #if ind>0, FileName=FullFileName(ind(length(ind))+1:length(FullFileName)); else FileName=FullFileName; end
- debug(0, "FileName = " + FullFileName)
- fid=open(FullFileName,'rb'); # native format (PC-intel). ideasman says maybe rU
- content = fid.read();
- content_memory = content
- #Header section
- NrecordFirstParameterblock, content = getNumber(content,1) # Reading record number of parameter section
-
- key, content = getNumber(content,1)
- if key!=80:
- error('File: does not comply to the C3D format')
- fid.close()
- return
- #Paramter section
- content = content[512*(NrecordFirstParameterblock-1)+1:] # first word ignored
- #file format spec says that 3rd byte=NumberofParmaterRecords... but is ignored here.
- proctype,content =getNumber(content,1)
- proctype = proctype-83
- proctypes= ["unknown","(INTEL-PC)","(DEC-VAX)","(MIPS-SUN/SGI)"]
-
- if proctype in (1,2): debug(0, "Processor coding %s"%proctypes[proctype])
- elif proctype==3: debug(0,"Program untested with %s"%proctypes[proctype])
- else:
- debug(0, "INVALID processor type %i"%proctype)
- proctype=1
- debug(0,"OVERRIDE processor type %i"%proctype)
-
- #if proctype==2,
- # fclose(fid);
- # fid=fopen(FullFileName,'r','d'); % DEC VAX D floating point and VAX ordering
- #end
- debug(10, "***********************")
- debug(00, "**** Reading Header ***")
- debug(10, "***********************")
-
- # ###############################################
- # ## ##
- # ## read header ##
- # ## ##
- # ###############################################
-
- #%NrecordFirstParameterblock=fread(fid,1,'int8'); % Reading record number of parameter section
- #%key1=fread(fid,1,'int8'); % key = 80;
-
- content = content_memory
- #fseek(fid,2,'bof');
- content = content[2:]
-
- #
- Nmarkers, content=getNumber(content, 2)
- NanalogSamplesPerVideoFrame, content = getNumber(content, 2)
- StartFrame, content = getNumber(content, 2)
- EndFrame, content = getNumber(content, 2)
- MaxInterpolationGap, content = getNumber(content, 2)
-
- Scale, content = getFloat(content,proctype)
-
- NrecordDataBlock, content = getNumber(content, 2)
- NanalogFramesPerVideoFrame, content = getNumber(content, 2)
-
- if NanalogFramesPerVideoFrame > 0:
- NanalogChannels=NanalogSamplesPerVideoFrame/NanalogFramesPerVideoFrame
- else:
- NanalogChannels=0
-
- VideoFrameRate, content = getFloat(content,proctype)
-
- AnalogFrameRate=VideoFrameRate*NanalogFramesPerVideoFrame
- NvideoFrames = EndFrame - StartFrame + 1
-
- debug(0, "Scale= %0.2f" %Scale)
- debug(0, "NanalogFramesPerVideoFrame= %i" %NanalogFramesPerVideoFrame)
- debug(0, "Video Frame Rate= %i" %VideoFrameRate)
- debug(0, "AnalogFrame Rate= %i"%AnalogFrameRate)
- debug(0, "# markers= %i" %Nmarkers)
- debug(0, "StartFrame= %i" %StartFrame)
- debug(0, "EndFrame= %i" %EndFrame)
- debug(0, "# Video Frames= %i" %NvideoFrames)
-
- if Scale>0:
- debug(0, "Marker data is in integer format")
- if Scale>(XYZ_LIMIT/32767):
- Scale=XYZ_LIMIT/32767.0
- debug(0, "OVERRIDE: Max coordinate is %i, Scale changed to %0.2f" % (XYZ_LIMIT,Scale))
- else: debug(0, "Marker data is in floating point format")
- if VideoFrameRate<1 or VideoFrameRate>120:
- VideoFrameRate= 120
- debug(0, "OVERRIDE Video Frame Rate= %i" %VideoFrameRate)
- if proctype not in (1,2): # Intel, DEC are known good
- debug(0, "OVERRIDE|Program not tested with this encoding. Set to Intel")
- proctype= 1
-
- debug(10, "***********************")
- debug(10, "**** Reading Events ...")
- debug(10, "***********************")
-
- content = content_memory
- content = content[298:] #bizarre .. ce devrait être 150 selon la doc rdw skips first 299 bytes?
-
- EventIndicator, content = getNumber(content, 2)
- EventTime=[]
- EventValue=[]
- EventName=[]
-
- debug(0, "Event Indicator = %i" %EventIndicator)
- if EventIndicator==12345: #rdw: somehow, this original code seems fishy, but I cannot deny it.
- Nevents, content = getNumber(content, 2)
- debug(0, "Nevents= %i" %Nevents)
- content = content[2:]
- if Nevents>0:
- for i in range(Nevents):
- letime, content = getFloat(content,proctype)
- EventTime.append(letime)
- content = content_memory
- content = content[188*2:]
- for i in range(Nevents):
- lavalue, content = getNumber(content, 1)
- EventValue.append(lavalue)
- content = content_memory
- content = content[198*2:]
- for i in range(Nevents):
- lenom = content[0:4]
- content = content[4:]
- EventName.append(lenom)
-
- debug(00, "***************************")
- debug(00, "**** Reading Parameters ...")
- debug(10, "***************************")
- subjects=[] # a name would be nice, but human will do
- prefixes=[] # added on to mocap marker names, one for each subject
- marker_subjects = [] # hopefully will be specified in the file and known to this program
- markerList=[]
- ParameterGroups = []
- ParameterNumberIndex = []
-
- content = content_memory
- content = content[512*(NrecordFirstParameterblock-1):]
-
- dat1, content = getNumber(content, 1)
- key2, content = getNumber(content, 1)
-
- NparameterRecords, content = getNumber(content, 1)
- debug(100, "NparameterRecords=%i"%NparameterRecords)
- proctype,content =getNumber(content,1)
- proctype = proctype-83 # proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI)
-
- for i in range(NparameterRecords):
- leparam = ParameterGroup(None, None, [])
- ParameterGroups.append(leparam)
- ParameterNumberIndex.append(0)
- #
- Ncharacters, content = getNumber(content, 1)
- if Ncharacters>=128:
- Ncharacters = -(2**8)+(Ncharacters)
- GroupNumber, content = getNumber(content, 1)
- if GroupNumber>=128:
- GroupNumber = -(2**8)+(GroupNumber)
- debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters))
-
- while Ncharacters > 0:
- if GroupNumber<0:
- GroupNumber=abs(GroupNumber)
- GroupName = content[0:Ncharacters]
- content = content[Ncharacters:]
- #print "Group Number = ", GroupNumber
- ParameterGroups[GroupNumber].name = GroupName
- #print "ParameterGroupName =", GroupName
- offset, content = getNumber(content, 2)
- deschars, content = getNumber(content, 1)
- GroupDescription = content[0:deschars]
- content = content[deschars:]
- ParameterGroups[GroupNumber].description = GroupDescription
- #
- ParameterNumberIndex[GroupNumber]=0
- content = content[offset-3-deschars:]
- else:
-
- ParameterNumberIndex[GroupNumber]=ParameterNumberIndex[GroupNumber]+1
- ParameterNumber=ParameterNumberIndex[GroupNumber]
- #print "ParameterNumber=", ParameterNumber
- ParameterGroups[GroupNumber].parameter.append(Parameter(None, None, [], [], None))
- ParameterName = content[0:Ncharacters]
- content = content[Ncharacters:]
- #print "ParameterName = ",ParameterName
- if len(ParameterName)>0:
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].name=ParameterName
- offset, content = getNumber(content, 2)
- filepos = len(content_memory)-len(content)
- nextrec = filepos+offset-2
-
- type, content=getNumber(content, 1)
- if type>=128:
- type = -(2**8)+type
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].type=type
-
- dimnum, content=getNumber(content, 1)
- if dimnum == 0:
- datalength = abs(type)
- else:
- mult=1
- dimension=[]
- for j in range (dimnum):
- ladim, content = getNumber(content, 1)
- dimension.append(ladim)
- mult=mult*dimension[j]
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].dim.append(dimension[j])
- datalength = abs(type)*mult
-
- #print "ParameterNumber = ", ParameterNumber, " Group Number = ", GroupNumber
-
- if type==-1:
- data = ""
- wordlength=dimension[0]
- if dimnum==2 and datalength>0:
- for j in range(dimension[1]):
- data=string.rstrip(content[0:wordlength])
- content = content[wordlength:]
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data)
- elif dimnum==1 and datalength>0:
- data=content[0:wordlength]
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data) # ???
-
- myParam=string.rstrip(ParameterName)
- myGroup=string.rstrip(GroupName)
- msg= "-%s-%s-" % (myGroup,myParam)
- if myGroup == "POINT":
- if myParam== "LABELS":
- # named in form of subject:marker.
- # the list "empties" is a corresponding list of actual empty object names that make up the cloud
- markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- debug(0, "%sLABELS = %i %s" %(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points
- elif myParam== "LABELS2": #more labels
- # named in form of subject:marker.
- # the list "empties" is a corresponding list of actual empty object names that make up the cloud
- momarkList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- markerList+=momarkList
- debug(0, "%sLABELS2 = %i %s" %(msg, len(momarkList),momarkList)) #list of logical markers from 0 to n corresponding to points
- else: debug(70, "%s UNUSED = %s" %(msg,ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data))
- elif myGroup in ["SUBJECT", "SUBJECTS"]: #info about the actor
- if myParam in ["NAME", "NAMES"]:
- subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- debug(0, "%sNames of Subjects = %s" %(msg, subjects)) # might be useful in naming armatures
- for i in range(len(subjects)):
- subjects[i]=subjects[i].rstrip()
- if subjects[i]=="": subjects[i]="Human"
- elif myParam == "LABEL_PREFIXES":
- prefixes = ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- debug(0, "%sMarker Prefixes = %s" %(msg, prefixes)) # to xlate marker name to that in file
- for i in range(len(prefixes)):
- prefixes[i]=prefixes[i].rstrip()
- elif myParam== "MARKER_SETS":
- marker_subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- debug(0, "%sMarker Set = %s"%(msg, marker_subjects)) # marker set that each subject was wearing
- elif myParam== "MODEL_PARAM":
- action= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- debug(0, "%sModel Paramter = %s"%(msg,action)) # might be a good name for the blender scene
- elif myParam== "LABELS":
- # named in form of subject:marker.
- # the list "empties" is a corresponding list of actual empty object names that make up the cloud
- markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- debug(0, "%sLABELS = %i %s"%(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points
- else: debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data))
- else:
- debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data))
- elif type == 1:
- debug(100,"Block type %i is largely unsupported and untested."%type)
- data = []
- Nparameters=datalength/abs(type)
- debug(100, "Nparameters=%i"%Nparameters)
- for i in range(Nparameters):
- ladata,content = getNumber(content, 1)
- data.append(ladata)
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
- #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
-
- #print "type boolean"
- elif type == 2 and datalength>0:
- debug(100,"Block type %i is largely unsupported and untested."%type)
- data = []
- Nparameters=datalength/abs(type)
- debug(100, "Nparameters=%i"%Nparameters)
- for i in range(Nparameters):
- ladata,content = getNumber(content, 2)
- data.append(ladata)
- #ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
- if dimnum>1:
- #???? print "arg je comprends pas"
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
- #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension)
- else:
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
- #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- #pass
- #print "type integer"
- elif type == 4 and datalength>0:
- debug(100,"Block type %i is largely unsupported and untested."%type)
- data = []
- Nparameters=datalength/abs(type)
- debug(100, "Nparameters=%i"%Nparameters)
- for i in range(Nparameters):
- ladata,content = getFloat(content,proctype)
- data.append(ladata)
- if dimnum>1:
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
- #print "arg je comprends pas"
- #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension)
- else:
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
- #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
- else:
- debug(100,"Block type %i is largely unsupported and untested."%type)
- #print "error"
- pass
- deschars, content= getNumber(content, 1)
- if deschars>0:
- description = content[0:deschars]
- content = content[deschars:]
- ParameterGroups[GroupNumber].parameter[ParameterNumber-1].description=description
-
- content = content_memory
- content = content[nextrec:]
-
- Ncharacters,content = getNumber(content, 1)
- if Ncharacters>=128:
- Ncharacters = -(2**8)+(Ncharacters)
- GroupNumber,content = getNumber(content, 1)
- if GroupNumber>=128:
- GroupNumber = -(2**8)+(GroupNumber)
- debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters))
-
- debug(00, "***************************")
- debug(00, "**** Examining Parameters ...")
- debug(10, "***************************")
-
- if len(subjects)==0: subjects=["Test"] #well, somebody got mocapped!
- for i in range(0, len(subjects)-len(prefixes)): prefixes.append("")
- for i in range(0, len(subjects)-len(marker_subjects)): marker_subjects.append(subjects[i])
-
- #make a markerlist if they didn't
- debug(0, "%i Markers specified, %i marker names supplied" %(Nmarkers,len(markerList)))
- if len(markerList)==0:
- debug(0, "File missing any POINT LABELS marker list. Making defaults")
- #I guess just make cloud of empty.xxx
- if len(markerList)<Nmarkers:
- for i in range(len(markerList),Nmarkers): markerList.append("mark."+str(i))
- #note that they may supply more markers than Nmarkers, extras are usually null or ignored
- #an idea here to winnow down the marker List is to go through the nodes and see if there are markers
- # in the list that are not used in constraining the armature, and discard them or set them debug(0,
- # so that later on in processing we don't bother saving their location, possibly speeding up processing
- # because we can just skip over their data block.
- # put this on TODO list since it gets pretty complicated going throuch each marker set and all constraints etc.
-
- ## ###############################################
- ## ## ##
- ## ## Initalize Arrays and Allocate Memory
- ## ## ##
- ## ###############################################
- ## Get the coordinate and analog data
- #
-
- content = content_memory
- content = content[(NrecordDataBlock-1)*512:]
- debug(20,"Allocating memory for %i floats" %NvideoFrames*(Nmarkers*3+2))
- for i in range (NvideoFrames):
- Markers.append([])
- ResidualError.append([])
- CameraInfo.append([])
- for j in range (Nmarkers):
- Markers[i].append(Marker(0.0,0.0,0.0))
- ResidualError[i].append(0)
- CameraInfo[i].append(0)
-
- #print Markers
- #
- #if Scale < 0
- # for i=1:NvideoFrames
- # for j=1:Nmarkers
- # Markers(i,j,1:3)=fread(fid,3,'float32')';
- # a=fix(fread(fid,1,'float32'));
- # highbyte=fix(a/256);
- # lowbyte=a-highbyte*256;
- # CameraInfo(i,j)=highbyte;
- # ResidualError(i,j)=lowbyte*abs(Scale);
- # end
- # waitbar(i/NvideoFrames)
- # for j=1:NanalogFramesPerVideoFrame,
- # AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=...
- # fread(fid,NanalogChannels,'int16')';
- # end
- # end
-
- debug(10, "***************************")
- debug(00, "**** Reading DataBlock of %i Frames...." % NvideoFrames)
- debug(10, "***************************")
- residuals= NanalogFramesPerVideoFrame*NanalogChannels*2
- err=0 #keep track of errors or serious data issues
- ptr_read = 0
-
- if Scale < 0.0: # 3D Data - 4-byte Floating-point Format
- for i in range (NvideoFrames):
- if i==0: start=sys.time()
- elif i==10:
- tmp=(sys.time()-start)*NvideoFrames/600
- debug(0,"%i minutes remaining..." % tmp)
- else: print "%i percent complete. On Frame %i Points procesed: %i\r" % (i*100/NvideoFrames,i,i*Nmarkers),
- for j in range (Nmarkers):
-
- x,ptr_read = parseFloat(content, ptr_read, proctype)
- y,ptr_read = parseFloat(content, ptr_read, proctype)
- z,ptr_read = parseFloat(content, ptr_read, proctype)
- myx= x * -Scale
- myy= y * -Scale
- myz= z * -Scale
-
- if abs(myx)>XYZ_LIMIT or abs(myy)>XYZ_LIMIT or abs(myz)>XYZ_LIMIT:
- err+=1
- if err>100:
- debug(0, "Warning: 100 data points for markers seem way out there")
- debug(0, "data read: (%i, %i, %i)" %(x,y,z))
- debug(0, "Consider revising Scale %0.2f" % Scale)
- debug(0, "which now givs coordinates: (%i, %i, %i)" %(x*Scale,y*Scale,z*Scale))
- err=-0
- if abs(myx)>XYZ_LIMIT: myx= XYZ_LIMIT*myx/abs(myx) #preserve sign
- if abs(myy)>XYZ_LIMIT: myy= XYZ_LIMIT*myy/abs(myy) #preserve sign
- if abs(myz)>XYZ_LIMIT: myz= XYZ_LIMIT*myz/abs(myz) #preserve sign
- Markers[i][j].x = myx
- Markers[i][j].y = myy
- Markers[i][j].z = myz
-
- a,ptr_read = parseFloat(content, ptr_read, proctype)
- a = int(a)
- highbyte = int(a/256)
- lowbyte=a-highbyte*256
- CameraInfo[i][j] = highbyte
- ResidualError[i][j] = lowbyte*abs(Scale)
- #Monitor marker location to ensure data block is being parsed properly
- if j==0: debug(90,"Frame %i loc of %s: (%i, %i, %i)" % (i,markerList[j],myx,myy,myz))
- if i==0: debug(50, "Initial loc of %s: (%i, %i, %i)" % (markerList[j],myx,myy,myz))
-
- ptr_read+=residuals #skip over the following
- #for j in range (NanalogFramesPerVideoFrame):
- # for k in range(NanalogChannels):
- # val, content = getNumber(content, 2)
- # AnalogSignals[j+NanalogFramesPerVideoFrame*(i)][k]=val #??? i-1
- #else
- # for i=1:NvideoFrames
- # for j=1:Nmarkers
- # Markers(i,j,1:3)=fread(fid,3,'int16')'.*Scale;
- # ResidualError(i,j)=fread(fid,1,'int8');
- # CameraInfo(i,j)=fread(fid,1,'int8');
- # end
- # waitbar(i/NvideoFrames)
- # for j=1:NanalogFramesPerVideoFrame,
- # AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=...
- # fread(fid,NanalogChannels,'int16')';
- # end
- # end
- #end
-
- else: #Scale is positive, but should be <1 to scale down, like 0.05
- two16= -2**16
- if len(content) < NvideoFrames*(Nmarkers*(6+2)+residuals):
- error("%i bytes is not enough data for |%i frames|%i markers|%i residual" %(len(content),NvideoFrames,Nmarkers,residuals))
- #Note: I really tried to optimize this loop, since it was taking hours to process
- for i in range(NvideoFrames):
- if i==0: start=sys.time()
- elif i==10:
- tmp=(sys.time()-start)*NvideoFrames/600
- debug(0,"%i minutes remaining..." % tmp)
- else: print "%i percent complete. On Frame %i Points procesed: %i\r" % (i*100/NvideoFrames,i,i*Nmarkers),
-
- for j in range(Nmarkers):
- #x, content = getNumber(content,2)
- # this is old skool signed int, not but not a short.
- x = ord(content[ptr_read+0]) + (ord(content[ptr_read+1])<<8)
- if x>32768: x+=two16
- y = ord(content[ptr_read+2]) + (ord(content[ptr_read+3])<<8)
- if y>32768: y+=two16
- z = ord(content[ptr_read+4]) + (ord(content[ptr_read+5])<<8)
- if z>32768: z+=two16
-
-##
-## x = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8)
-## ptr_read+=2
-## if x > 32768:
-## x=-(2**16)+(x)
-## #y, content = getNumber(content,2)
-## y = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8)
-## ptr_read+=2
-## if y > 32768:
-## y=-(2**16)+(y)
-## #z, content = getNumber(content,2)
-## z = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8)
-## ptr_read+=2
-## if z > 32768:
-## z=-(2**16)+(z)
-##
-## print "(%i=%i, %i=%i, %i=%i)" %(x,myx,y,myy,z,myz)
-
- # for integers, I changed Scale above to avoid getting impossible numbers
- Markers[i][j].x = x*Scale
- Markers[i][j].y = y*Scale
- Markers[i][j].z = z*Scale
-
-## ResidualError[i][j], content = getNumber(content, 1)
-## CameraInfo[i][j], content = getNumber(content, 1)
- #try to improve performance by:
- ResidualError[i][j]= ord(content[ptr_read+6])
- CameraInfo[i][j]= ord(content[ptr_read+7])
-
- content= content[ptr_read+8:]
- ptr_read=0
-
- if j==0: debug(100,"Frame %i loc of %s: %s" % (i,markerList[j],Markers[i][j]))
- if i==0: debug(50, "Initial loc of %s: (%s)" % (markerList[j],Markers[i][j]))
-
- #for j in range (NanalogFramesPerVideoFrame):
- # for k in range(NanalogChannels):
- # val, content = getNumber(content, 2)
- #AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=val
- ptr_read= residuals # skip over the above
- print "\ndone with file."
- fid.close()
-
- cloud= makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers)
-
- setupAnim(StartFrame, EndFrame,VideoFrameRate)
-
- debug(10, "**************************")
- debug(00, "**** Making %i Armatures" % len(subjects))
- debug(10, "**************************")
- for i in range(len(subjects)):
- marker_set= marker_subjects[i]
- success=False
- if len(marker_set)>0:
- for trymark in MARKER_SETS:
- if trymark[0:len(marker_set)]==marker_set:
- marker_set=trymark
- success=True
- if success:
- debug(0, "Armature for %s will be put on layers %s" % (subjects[i],LAYERS_ARMOB))
- debug(0, " based on an markers beginning with %s" % prefixes[i])
- ob= make_arm(subjects[i],prefixes[i],markerList,cloud,marker_set)
- else:
- debug(00, "Presently, this program can automatically create a constrained armature for marker sets %s" % MARKER_SETS)
- debug(00, "%s uses an unknown marker set %s" % (subjects[i],marker_set))
- debug(10, "Have a nice day! If you figure out an armature node system for this cloud, please add it to the program.")
-
- debug(10, "**************************")
- debug(00, "**** Conclusion")
- minmax=[0,0,0,0,0,0]
- for i in range(NvideoFrames):
- for j in range(Nmarkers):
- if minmax[0]>Markers[i][j].x: minmax[0]=Markers[i][j].x
- if minmax[1]>Markers[i][j].y: minmax[1]=Markers[i][j].y
- if minmax[2]>Markers[i][j].z: minmax[2]=Markers[i][j].z
- if minmax[3]<Markers[i][j].x: minmax[3]=Markers[i][j].x
- if minmax[4]<Markers[i][j].y: minmax[4]=Markers[i][j].y
- if minmax[5]<Markers[i][j].z: minmax[5]=Markers[i][j].z
- debug(0,"Markers move in 3D space from (%i,%i,%i) to (%i,%i,%i). "%(minmax[0],minmax[1],minmax[2],minmax[3],minmax[4],minmax[5]))
- debug(0,"Set your 3D View Properties Clip End and zoom out your display.")
-def my_callback(filename):
- # processing options UI goes here, eventually
- Window.WaitCursor(1)
- t = sys.time()
- load_c3d(filename)
- # Timing the script is a good way to be aware on any speed hits when scripting
- debug(0, '%s file processed in %.2f sec.' % (filename,sys.time()-t))
- Window.WaitCursor(0)
-
-def processFile():
- # select file and pass a handle to the processor
- Blender.Window.FileSelector(my_callback, "Import C3D") # makes a window a file selector and processes it
- #processing contiues while file is being worked
-
-def main():
- # Display the GUI
-
- # Run the function
- processFile()
-
- #Close files, display stats, cleanup, advice on next steps
-
-# This lets you import the script without running it
-if __name__ == '__main__':
- debug(00, "------------------------------------")
- debug(00, '%s %s script began at %.0f' % (__script__,__version__,sys.time()))
- main()
-
-
-
diff --git a/release/scripts/camera_changer.py b/release/scripts/camera_changer.py
deleted file mode 100644
index 7ae1bd64c8c..00000000000
--- a/release/scripts/camera_changer.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Camera Changer'
-Blender: 234
-Group: 'Animation'
-Tip: 'Create script link to change cameras (based on their names) during an animation'
-"""
-
-__author__ = '3R - R3gis'
-__version__ = '1.2'
-__url__ = ["Author's site , http://cybercreator.free.fr", "French Blender support forum, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender"]
-__email__=["3R, r3gis@free.fr"]
-
-
-__bpydoc__ = """\
-This script creates an script link to change cameras during an animation.
-
-The created script link (a Blender Text) is linked to Scene Frame Changed events.
-
-Usage:
-
-Run the script, then name the camera Object with the number of the frame(s)
-where you want this camera to become active.
-
-For example:<br>
- - a camera called "10" will become active at frame 10.<br>
- - a camera called "10,25,185" will become active at frames 10, 25 and 185.
-
-Notes:<br>
- - This script creates another script named camera.py, which is linked to the current scene.<br>
- - If there is already a text called "camera.py", but it's from an old version or is not recognized,
-you can choose if you want to rename or overwrite it.
- - Script inspired by Jean-Michel (jms) Soler's:<br>
- http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_changerdecamera.htm
-"""
-
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004-2005: Regis Montoya
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-#Script inspired of the idea of this one :
-#http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_changerdecamera.htm
-#
-#----------------------------------------------
-# R3gis Montoya (3R)
-#
-# Pout tout probleme a:
-# cybercreator@free.fr
-# ---------------------------------------------
-
-import Blender
-from Blender import *
-import string
-
-header = '# camera.py 1.3 scriptlink'
-
-camera_change_scriptlink = header + \
-'''
-import Blender
-def main():
- scn = Blender.Scene.GetCurrent()
- frame = str(Blender.Get('curframe'))
-
- # change the camera if it has the current frame
- for ob_cam in [ob for ob in scn.objects if ob.type == 'Camera']:
- for number in ob_cam.name.split(','):
- if number == frame:
- scn.setCurrentCamera(ob_cam)
- return
-main()
-'''
-
-def main():
-
- # Get the text
- try: cam_text = Blender.Text.Get('camera.py')
- except: cam_text = None
-
- if cam_text:
- if cam_text.asLines()[0] != header:
- ret = Blender.Draw.PupMenu("WARNING: An old camera.py exists%t|Overwrite|Rename old version text")
- if ret == -1: return # EXIT DO NOTHING
- elif ret == 1: Text.unlink(cam_text)
- elif ret == 2: cam_text.name = 'old_camera.txt'
- cam_text = None
-
- if not cam_text:
- scripting=Blender.Text.New('camera.py')
- scripting.write(camera_change_scriptlink)
-
- scn=Scene.GetCurrent()
- scriptlinks = scn.getScriptLinks('FrameChanged')
- if not scriptlinks or ('camera.py' not in scriptlinks):
- scn.addScriptLink('camera.py','FrameChanged')
- Blender.Draw.PupMenu('FrameChange Scriptlink Added%t|Name camera objects to their activation frame numbers(s) seperated by commas|valid names are "1,10,46" or "1,10,200" or "200" (without quotation marks)')
- Blender.Window.RedrawAll()
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/config.py b/release/scripts/config.py
deleted file mode 100644
index cbf8e272b91..00000000000
--- a/release/scripts/config.py
+++ /dev/null
@@ -1,801 +0,0 @@
-#!BPY
-
-"""
-Name: 'Scripts Config Editor'
-Blender: 236
-Group: 'System'
-Tooltip: 'View and edit available scripts configuration data'
-"""
-
-__author__ = "Willian P. Germano"
-__version__ = "0.1 2005/04/14"
-__email__ = ('scripts', 'Author, wgermano:ig*com*br')
-__url__ = ('blender', 'blenderartists.org')
-
-__bpydoc__ ="""\
-This script can be used to view and edit configuration data stored
-by other scripts.
-
-Technical: this data is saved as dictionary keys with the
-Blender.Registry module functions. It is persistent while Blender is
-running and, if the script's author chose to, is also saved to a file
-in the scripts config data dir.
-
-Usage:
-
-- Start Screen:
-
-To access any available key, select it from (one of) the menu(s).
-
-Hotkeys:<br>
- ESC or Q: [Q]uit<br>
- H: [H]elp
-
-- Keys Config Screen:
-
-This screen exposes the configuration data for the chosen script key. If the
-buttons don't fit completely on the screen, you can scroll up or down with
-arrow keys or a mouse wheel. Leave the mouse pointer over any button to get
-a tooltip about that option.
-
-Any change can be reverted -- unless you have already applied it.
-
-If the key is already stored in a config file, there will be a toggle button
-(called 'file') that controls whether the changes will be written back to
-the file or not. If you just want to change the configuration for the current
-session, simply unset that button. Note, though, that data from files has
-precedence over those keys already loaded in Blender, so if you re-run this
-config editor, unsaved changes will not be seen.
-
-Hotkeys:<br>
- ESC: back to Start Screen<br>
- Q: [Q]uit<br>
- U: [U]ndo changes<br>
- ENTER: apply changes (can't be reverted, then)<br>
- UP, DOWN Arrows and mouse wheel: scroll text up / down
-
-Notes:
-
-a) Available keys are determined by which scripts you use. If the key you
-expect isn't available (or maybe there are none or too few keys), either the
-related script doesn't need or still doesn't support this feature or the key
-has not been stored yet, in which case you just need to run that script once
-to make its config data available.
-
-b) There are two places where config data files can be saved: the
-bpydata/config/ dir (1) inside the default scripts dir or (2) inside the user
-defined Python scripts dir
-(User Preferences window -> File Paths tab -> Python path). If available,
-(2) is the default and also the recommended option, because then fresh Blender
-installations won't delete your config data. To use this option, simply set a
-dir for Python scripts at the User Preferences window and make sure this dir
-has the subdirs bpydata/ and bpydata/config/ inside it.
-
-c) The key called "General" in the "Other" menu has general config options.
-All scripts where that data is relevant are recommended to access it and set
-behaviors accordingly.
-"""
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# config.py version 0.1 2005/04/08
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Draw, BGL, Registry, Window, sys as bsys
-from Blender.Window import Theme
-from BPyRegistry import LoadConfigData, SaveConfigData, HasConfigData,\
- BPY_KEY_IN_FILE
-
-MAX_STR_LEN = 300 # max length for a string
-MAX_ITEMS_NUM = 100 # max number for each type of button
-
-# ---
-# The "General" configure options key is managed from this script.
-verbose = True
-confirm_overwrite = True
-
-tooltips = {
- 'verbose': 'print script messages (info, warnings, errors) to the console',
- 'confirm_overwrite': 'scripts should always confirm before overwriting files'
-}
-
-CFG_LIST = ['verbose', 'confirm_overwrite', 'tooltips']
-KEY_NAME = 'General'
-
-def update_registry():
- rd = {}
- for var in CFG_LIST:
- exec("rd['%s']=%s" % (var, var))
- Registry.SetKey(KEY_NAME, rd, True)
-
-rd = Registry.GetKey('General', True)
-if rd:
- try:
- for var in CFG_LIST[:-1]: # no need to update tooltips
- exec("%s=rd['%s']" % (var, var))
- except: update_registry()
-
-else:
- update_registry()
-# ---
-
-# script globals:
-CFGKEY = ''
-LABELS = []
-GD = {} # groups dict (includes "Other" for unmapped keys)
-INDEX = 0 # to pass button indices to fs callbacks
-FREEKEY_IDX = 0 # index of set of keys not mapped to a script name
-KEYMENUS = []
-ALL_SCRIPTS = {}
-ALL_GROUPS = []
-START_SCREEN = 0
-CONFIG_SCREEN = 1
-DISK_UPDATE = True # write changed data to its config file
-
-ACCEPTED_TYPES = [bool, int, float, str, unicode]
-
-SCREEN = START_SCREEN
-
-SCROLL_DOWN = 0
-
-# events:
-BEVT_START = 50
-BEVT_EXIT = 0 + BEVT_START
-BEVT_BACK = 1 + BEVT_START
-BEVT_DISK = 2 + BEVT_START
-BEVT_CANCEL = 3 + BEVT_START
-BEVT_APPLY = 4 + BEVT_START
-BEVT_HELP = 5 + BEVT_START
-BEVT_DEL = 6 + BEVT_START
-BEVT_KEYMENU = []
-BUT_KEYMENU = []
-BEVT_BOOL = 100
-BEVT_INT = BEVT_BOOL + MAX_ITEMS_NUM
-BEVT_FLOAT = BEVT_BOOL + 2*MAX_ITEMS_NUM
-BEVT_STR = BEVT_BOOL + 3*MAX_ITEMS_NUM
-BEVT_BROWSEDIR = BEVT_BOOL + 4*MAX_ITEMS_NUM
-BEVT_BROWSEFILE = BEVT_BOOL + 5*MAX_ITEMS_NUM
-BUT_TYPES = {
- bool: 0,
- int: 0,
- float: 0,
- str: 0
-}
-
-# Function definitions:
-
-def get_keys():
- LoadConfigData() # loads all data from files in (u)scripts/bpydata/config/
- return [k for k in Registry.Keys() if k[0] != "_"]
-
-
-def show_help(script = 'config.py'):
- Blender.ShowHelp(script)
-
-
-def fs_dir_callback(pathname):
- global CFGKEY, INDEX
-
- pathname = bsys.dirname(pathname)
- datatypes = CFGKEY.sorteddata
- datatypes[str][INDEX][1] = pathname
-
-
-def fs_file_callback(pathname):
- global CFGKEY, INDEX
-
- datatypes = CFGKEY.sorteddata
- datatypes[str][INDEX][1] = pathname
-
-
-# parse Bpymenus file to get all script filenames
-# (used to show help for a given key)
-def fill_scripts_dict():
- global ALL_SCRIPTS, ALL_GROUPS
-
- group = ''
- group_len = 0
- sep = bsys.sep
- home = Blender.Get('homedir')
- if not home:
- errmsg = """
-Can't find Blender's home dir and so can't find the
-Bpymenus file automatically stored inside it, which
-is needed by this script. Please run the
-Help -> System -> System Information script to get
-information about how to fix this.
-"""
- raise SystemError, errmsg
- fname = bsys.join(home, 'Bpymenus')
- if not bsys.exists(fname): return False
- f = file(fname, 'r')
- lines = f.readlines()
- f.close()
- for l in lines:
- if l.rfind('{') > 0:
- group = l.split()[0]
- ALL_GROUPS.append(group)
- group_len += 1
- continue
- elif l[0] != "'": continue
- fields = l.split("'")
- if len(fields) > 2:
- menuname = fields[1].replace('...','')
- fields = fields[2].split()
- if len(fields) > 1:
- fname = fields[1].split(sep)[-1]
- i = 1
- while not fname.endswith('.py'):
- i += 1
- fname = "%s %s" % (fname, fields[i])
- ALL_SCRIPTS[fname] = (menuname, group_len - 1)
- return True
-
-
-def map_to_registered_script(name):
- global ALL_SCRIPTS
-
- if not name.endswith('.py'):
- name = "%s.py" % name
- if ALL_SCRIPTS.has_key(name):
- return ALL_SCRIPTS[name] # == (menuname, group index)
- return None
-
-
-def reset():
- global LABELS, GD, KEYMENUS, KEYS
-
- # init_data is recalled when a key is deleted, so:
- LABELS = []
- GD = {}
- KEYMENUS = []
- KEYS = get_keys()
-
-
-# gather all script info, fill gui menus
-def init_data():
- global KEYS, GD, ALL_GROUPS, ALL_SCRIPTS, KEYMENUS, LABELS
- global BUT_KEYMENU, BEVT_KEYMENU, FREEKEY_IDX
-
- for k in ALL_GROUPS:
- GD[k] = []
- GD[None] = []
-
- for k in KEYS:
- res = map_to_registered_script(k)
- if res:
- GD[ALL_GROUPS[res[1]]].append((k, res[0]))
- else: GD[None].append((k, k))
-
- for k in GD.keys():
- if not GD[k]: GD.pop(k)
-
- if GD.has_key(None):
- GD['Other'] = GD[None]
- GD.pop(None)
- FREEKEY_IDX = -1
-
- BUT_KEYMENU = range(len(GD))
-
- for k in GD.keys():
- kmenu = ['Configuration Keys: %s%%t' % k]
- for j in GD[k]:
- kmenu.append(j[1])
- kmenu = "|".join(kmenu)
- KEYMENUS.append(kmenu)
- LABELS.append(k)
-
- if FREEKEY_IDX < 0:
- FREEKEY_IDX = LABELS.index('Other')
-
- length = len(KEYMENUS)
- BEVT_KEYMENU = range(1, length + 1)
- BUT_KEYMENU = range(length)
-
-
-# for theme colors:
-def float_colors(cols):
- return map(lambda x: x / 255.0, cols)
-
-
-
-class Config:
-
- def __init__(self, key, has_group = True):
- global DISK_UPDATE
-
- self.key = key
- self.has_group = has_group
- self.name = key
- self.fromdisk = HasConfigData(key) & BPY_KEY_IN_FILE
- if not self.fromdisk: DISK_UPDATE = False
- else: DISK_UPDATE = True
-
- self.origdata = Registry.GetKey(key, True)
- data = self.data = self.origdata.copy()
-
- if not data:
- Draw.PupMenu('ERROR: couldn\'t find requested data')
- self.data = None
- return
-
- keys = data.keys()
- nd = {}
- for k in keys:
- nd[k.lower()] = k
-
- if nd.has_key('tooltips'):
- ndval = nd['tooltips']
- self.tips = data[ndval]
- data.pop(ndval)
- else: self.tips = 0
-
- if nd.has_key('limits'):
- ndval = nd['limits']
- self.limits = data[ndval]
- data.pop(ndval)
- else: self.limits = 0
-
- if self.has_group:
- scriptname = key
- if not scriptname.endswith('.py'):
- scriptname = "%s.py" % scriptname
- elif nd.has_key('script'):
- ndval = nd['script']
- scriptname = data[ndval]
- data.pop(ndval)
- if not scriptname.endswith('.py'):
- scriptname = "%s.py" % scriptname
- else: scriptname = None
-
- self.scriptname = scriptname
-
- self.sort()
-
-
- def needs_update(self): # check if user changed data
- data = self.data
- new = self.sorteddata
-
- for vartype in new.keys():
- for i in new[vartype]:
- if data[i[0]] != i[1]: return 1
-
- return 0 # no changes
-
-
- def update(self): # update original key
- global DISK_UPDATE
-
- data = self.data
- odata = self.origdata
- new = self.sorteddata
- for vartype in new.keys():
- for i in new[vartype]:
- if data[i[0]] != i[1]: data[i[0]] = i[1]
- if odata[i[0]] != i[1]: odata[i[0]] = i[1]
-
- if DISK_UPDATE: Registry.SetKey(self.key, odata, True)
-
- def delete(self):
- global DISK_UPDATE
-
- delmsg = 'OK?%t|Delete key from memory'
- if DISK_UPDATE:
- delmsg = "%s and from disk" % delmsg
- if Draw.PupMenu(delmsg) == 1:
- Registry.RemoveKey(self.key, DISK_UPDATE)
- return True
-
- return False
-
-
- def revert(self): # revert to original key
- data = self.data
- new = self.sorteddata
- for vartype in new.keys():
- for i in new[vartype]:
- if data[i[0]] != i[1]: i[1] = data[i[0]]
-
-
- def sort(self): # create a new dict with types as keys
- global ACCEPTED_TYPES, BUT_TYPES
-
- data = self.data
- datatypes = {}
- keys = [k for k in data.keys() if k[0] != '_']
- for k in keys:
- val = data[k]
- tval = type(val)
- if tval not in ACCEPTED_TYPES: continue
- if not datatypes.has_key(tval):
- datatypes[tval] = []
- datatypes[type(val)].append([k, val])
- if datatypes.has_key(unicode):
- if not datatypes.has_key(str): datatypes[str] = datatypes[unicode]
- else:
- for i in datatypes[unicode]: datatypes[str].append(i)
- datatypes.pop(unicode)
- for k in datatypes.keys():
- dk = datatypes[k]
- dk.sort()
- dk.reverse()
- BUT_TYPES[k] = range(len(dk))
- self.sorteddata = datatypes
-
-
-# GUI:
-
-# gui callbacks:
-
-def gui(): # drawing the screen
-
- global SCREEN, START_SCREEN, CONFIG_SCREEN, KEYMENUS, LABELS
- global BEVT_KEYMENU, BUT_KEYMENU, CFGKEY
- global BUT_TYPES, SCROLL_DOWN, VARS_NUM
-
- WIDTH, HEIGHT = Window.GetAreaSize()
-
- theme = Theme.Get()[0]
- tui = theme.get('ui')
- ttxt = theme.get('text')
-
- COL_BG = float_colors(ttxt.back)
- COL_TXT = ttxt.text
- COL_TXTHI = ttxt.text_hi
-
- BGL.glClearColor(COL_BG[0],COL_BG[1],COL_BG[2],COL_BG[3])
- BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
- BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
-
- if SCREEN == START_SCREEN:
- x = 10
- y = 10
- h = 20
- w = 90
- BGL.glRasterPos2i(x, y)
- Draw.Text('Select a configuration key to access it. Press Q or ESC to leave.')
- km_len = len(KEYMENUS)
- km_columns = (WIDTH - x) / w
- if km_columns == 0: km_rows = km_len
- else:
- km_rows = km_len / km_columns
- if (km_len % km_columns): km_rows += 1
- if km_rows == 0: km_rows = 1
- ystart = y + 2*h*km_rows
- if ystart > (HEIGHT - 70): ystart = HEIGHT - 70
- y = ystart
- column = 1
- for i, km in enumerate(KEYMENUS):
- column += 1
- BGL.glRasterPos2i(x + 2, y + h + 5)
- Draw.Text(LABELS[i])
- BUT_KEYMENU[i] = Draw.Menu(km, BEVT_KEYMENU[i],
- x, y, w - 10, h, 0, 'Choose a key to access its configuration data')
- if column > km_columns:
- column = 1
- y -= 2*h
- if y < 35: break
- x = 10
- else: x += w
- x = 10
- y = 50 + ystart
- BGL.glColor3ub(COL_TXTHI[0], COL_TXTHI[1], COL_TXTHI[2])
- BGL.glRasterPos2i(x, y)
- Draw.Text('Scripts Configuration Editor')
- Draw.PushButton('help', BEVT_HELP, x, 22, 45, 16,
- 'View help information about this script (hotkey: H)')
-
- elif SCREEN == CONFIG_SCREEN:
- x = y = 10
- h = 18
- data = CFGKEY.sorteddata
- tips = CFGKEY.tips
- fromdisk = CFGKEY.fromdisk
- limits = CFGKEY.limits
- VARS_NUM = 0
- for k in data.keys():
- VARS_NUM += len(data[k])
- lines = VARS_NUM + 5 # to account for header and footer
- y = lines*h
- if y > HEIGHT - 20: y = HEIGHT - 20
- BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2])
- BGL.glRasterPos2i(x, y)
- Draw.Text('Scripts Configuration Editor')
- y -= 20
- BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
- txtsize = 10
- if HEIGHT < lines*h:
- BGL.glRasterPos2i(10, 5)
- txtsize += Draw.Text('Arrow keys or mouse wheel to scroll, ')
- BGL.glRasterPos2i(txtsize, 5)
- Draw.Text('Q or ESC to return.')
- BGL.glRasterPos2i(x, y)
- Draw.Text('Key: "%s"' % CFGKEY.name)
- bh = 16
- bw = 45
- by = 16
- i = -1
- if CFGKEY.scriptname:
- i = 0
- Draw.PushButton('help', BEVT_HELP, x, by, bw, bh,
- 'Show documentation for the script that owns this key (hotkey: H)')
- Draw.PushButton('back', BEVT_BACK, x + (1+i)*bw, by, bw, bh,
- 'Back to config keys selection screen (hotkey: ESC)')
- Draw.PushButton('exit', BEVT_EXIT, x + (2+i)*bw, by, bw, bh,
- 'Exit from Scripts Config Editor (hotkey: Q)')
- Draw.PushButton('revert', BEVT_CANCEL, x + (3+i)*bw, by, bw, bh,
- 'Revert data to original values (hotkey: U)')
- Draw.PushButton('apply', BEVT_APPLY, x + (4+i)*bw, by, bw, bh,
- 'Apply changes, if any (hotkey: ENTER)')
- delmsg = 'Delete this data key from memory'
- if fromdisk: delmsg = "%s and from disk" % delmsg
- Draw.PushButton('delete', BEVT_DEL, x + (5+i)*bw, by, bw, bh,
- '%s (hotkey: DELETE)' % delmsg)
- if fromdisk:
- Draw.Toggle("file", BEVT_DISK, x + 3 + (6+i)*bw, by, bw, bh, DISK_UPDATE,
- 'Update also the file where this config key is stored')
- i = -1
- top = -1
- y -= 20
- yend = 30
- if data.has_key(bool) and y > 0:
- lst = data[bool]
- for l in lst:
- top += 1
- i += 1
- if top < SCROLL_DOWN: continue
- y -= h
- if y < yend: break
- w = 20
- tog = data[bool][i][1]
- if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
- else: tooltip = "click to toggle"
- BUT_TYPES[bool][i] = Draw.Toggle("", BEVT_BOOL + i,
- x, y, w, h, tog, tooltip)
- BGL.glRasterPos2i(x + w + 3, y + 5)
- Draw.Text(l[0].lower().replace('_', ' '))
- i = -1
- y -= 5
- if data.has_key(int) and y > 0:
- lst = data[int]
- for l in lst:
- w = 70
- top += 1
- i += 1
- if top < SCROLL_DOWN: continue
- y -= h
- if y < yend: break
- val = data[int][i][1]
- if limits: min, max = limits[l[0]]
- else: min, max = 0, 10
- if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
- else: tooltip = "click / drag to change"
- BUT_TYPES[int][i] = Draw.Number("", BEVT_INT + i,
- x, y, w, h, val, min, max, tooltip)
- BGL.glRasterPos2i(x + w + 3, y + 3)
- Draw.Text(l[0].lower().replace('_', ' '))
- i = -1
- y -= 5
- if data.has_key(float) and y > 0:
- lst = data[float]
- for l in lst:
- w = 70
- top += 1
- i += 1
- if top < SCROLL_DOWN: continue
- y -= h
- if y < yend: break
- val = data[float][i][1]
- if limits: min, max = limits[l[0]]
- else: min, max = 0.0, 1.0
- if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
- else: tooltip = "click and drag to change"
- BUT_TYPES[float][i] = Draw.Number("", BEVT_FLOAT + i,
- x, y, w, h, val, min, max, tooltip)
- BGL.glRasterPos2i(x + w + 3, y + 3)
- Draw.Text(l[0].lower().replace('_', ' '))
- i = -1
- y -= 5
- if data.has_key(str) and y > 0:
- lst = data[str]
- for l in lst:
- top += 1
- i += 1
- if top < SCROLL_DOWN: continue
- y -= h
- if y < yend: break
- name = l[0].lower()
- is_dir = is_file = False
- if name.find('_dir', -4) > 0: is_dir = True
- elif name.find('_file', -5) > 0: is_file = True
- w = WIDTH - 20
- wbrowse = 50
- if is_dir and w > wbrowse: w -= wbrowse
- if tips and tips.has_key(l[0]): tooltip = tips[l[0]]
- else: tooltip = "click to write a new string"
- name = name.replace('_',' ') + ': '
- if len(l[1]) > MAX_STR_LEN:
- l[1] = l[1][:MAX_STR_LEN]
- BUT_TYPES[str][i] = Draw.String(name, BEVT_STR + i,
- x, y, w, h, l[1], MAX_STR_LEN, tooltip)
- if is_dir:
- Draw.PushButton('browse', BEVT_BROWSEDIR + i, x+w+1, y, wbrowse, h,
- 'click to open a file selector (pick any file in the desired dir)')
- elif is_file:
- Draw.PushButton('browse', BEVT_BROWSEFILE + i, x + w + 1, y, 50, h,
- 'click to open a file selector')
-
-
-def fit_scroll():
- global SCROLL_DOWN, VARS_NUM
- max = VARS_NUM - 1 # so last item is always visible
- if SCROLL_DOWN > max:
- SCROLL_DOWN = max
- elif SCROLL_DOWN < 0:
- SCROLL_DOWN = 0
-
-
-def event(evt, val): # input events
-
- global SCREEN, START_SCREEN, CONFIG_SCREEN
- global SCROLL_DOWN, CFGKEY
-
- if not val: return
-
- if evt == Draw.ESCKEY:
- if SCREEN == START_SCREEN: Draw.Exit()
- else:
- if CFGKEY.needs_update():
- if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
- CFGKEY.update()
- SCREEN = START_SCREEN
- SCROLL_DOWN = 0
- Draw.Redraw()
- return
- elif evt == Draw.QKEY:
- if SCREEN == CONFIG_SCREEN and CFGKEY.needs_update():
- if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
- CFGKEY.update()
- Draw.Exit()
- return
- elif evt == Draw.HKEY:
- if SCREEN == START_SCREEN: show_help()
- elif CFGKEY.scriptname: show_help(CFGKEY.scriptname)
- return
-
- elif SCREEN == CONFIG_SCREEN:
- if evt in [Draw.DOWNARROWKEY, Draw.WHEELDOWNMOUSE]:
- SCROLL_DOWN += 1
- fit_scroll()
- elif evt in [Draw.UPARROWKEY, Draw.WHEELUPMOUSE]:
- SCROLL_DOWN -= 1
- fit_scroll()
- elif evt == Draw.UKEY:
- if CFGKEY.needs_update():
- CFGKEY.revert()
- elif evt == Draw.RETKEY or evt == Draw.PADENTER:
- if CFGKEY.needs_update():
- CFGKEY.update()
- elif evt == Draw.DELKEY:
- if CFGKEY.delete():
- reset()
- init_data()
- SCREEN = START_SCREEN
- SCROLL_DOWN = 0
- else: return
- Draw.Redraw()
-
-
-def button_event(evt): # gui button events
-
- global SCREEN, START_SCREEN, CONFIG_SCREEN, CFGKEY, DISK_UPDATE
- global BEVT_KEYMENU, BUT_KEYMENU, BUT_TYPES, SCROLL_DOWN, GD, INDEX
- global BEVT_EXIT, BEVT_BACK, BEVT_APPLY, BEVT_CANCEL, BEVT_HELP, FREEKEY_IDX
-
- if SCREEN == START_SCREEN:
- for e in BEVT_KEYMENU:
- if evt == e:
- index = e - 1
- k = BUT_KEYMENU[index].val - 1
- CFGKEY = Config(GD[LABELS[index]][k][0], index != FREEKEY_IDX)
- if CFGKEY.data:
- SCREEN = CONFIG_SCREEN
- Draw.Redraw()
- return
- if evt == BEVT_EXIT:
- Draw.Exit()
- elif evt == BEVT_HELP:
- show_help()
- return
-
- elif SCREEN == CONFIG_SCREEN:
- datatypes = CFGKEY.sorteddata
- if evt >= BEVT_BROWSEFILE:
- INDEX = evt - BEVT_BROWSEFILE
- Window.FileSelector(fs_file_callback, 'Choose file')
- elif evt >= BEVT_BROWSEDIR:
- INDEX = evt - BEVT_BROWSEDIR
- Window.FileSelector(fs_dir_callback, 'Choose any file')
- elif evt >= BEVT_STR:
- var = BUT_TYPES[str][evt - BEVT_STR].val
- datatypes[str][evt - BEVT_STR][1] = var
- elif evt >= BEVT_FLOAT:
- var = BUT_TYPES[float][evt - BEVT_FLOAT].val
- datatypes[float][evt - BEVT_FLOAT][1] = var
- elif evt >= BEVT_INT:
- var = BUT_TYPES[int][evt - BEVT_INT].val
- datatypes[int][evt - BEVT_INT][1] = var
- elif evt >= BEVT_BOOL:
- var = datatypes[bool][evt - BEVT_BOOL][1]
- if var == True: var = False
- else: var = True
- datatypes[bool][evt - BEVT_BOOL][1] = var
-
- elif evt == BEVT_BACK:
- if SCREEN == CONFIG_SCREEN:
- SCREEN = START_SCREEN
- SCROLL_DOWN = 0
- Draw.Redraw()
- elif evt == BEVT_EXIT:
- if CFGKEY.needs_update():
- if Draw.PupMenu('UPDATE?%t|Data was changed') == 1:
- CFGKEY.update()
- Draw.Exit()
- return
- elif evt == BEVT_APPLY:
- if CFGKEY.needs_update():
- CFGKEY.update()
- elif evt == BEVT_CANCEL:
- if CFGKEY.needs_update():
- CFGKEY.revert()
- elif evt == BEVT_DEL:
- if CFGKEY.delete():
- reset()
- init_data()
- SCREEN = START_SCREEN
- SCROLL_DOWN = 0
- elif evt == BEVT_DISK:
- if DISK_UPDATE: DISK_UPDATE = False
- else: DISK_UPDATE = True
- elif evt == BEVT_HELP:
- show_help(CFGKEY.scriptname)
- return
- else:
- return
- Draw.Redraw()
-
-# End of definitions
-
-
-KEYS = get_keys()
-
-if not KEYS:
- Draw.PupMenu("NO DATA: please read this help screen")
- Blender.ShowHelp('config.py')
-else:
- fill_scripts_dict()
- init_data()
- Draw.Register(gui, event, button_event)
diff --git a/release/scripts/console.py b/release/scripts/console.py
deleted file mode 100644
index c6ae22a86f5..00000000000
--- a/release/scripts/console.py
+++ /dev/null
@@ -1,861 +0,0 @@
-#!BPY
-
-"""
-Name: 'Interactive Python Console'
-Blender: 245
-Group: 'System'
-Tooltip: 'Interactive Python Console'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__bpydoc__ = """\
-This is an interactive console, similar to Python's own command line interpreter. Since it is embedded in Blender, it has access to all Blender Python modules.
-
-Those completely new to Python are recommended to check the link button above
-that points to its official homepage, with news, downloads and documentation.
-
-Usage:<br>
- Type your code and hit "Enter" to get it executed.<br>
- - Right mouse click: Console Menu (Save output, etc);<br>
- - Mousewheel: Scroll text
- - Arrow keys: command history and cursor;<br>
- - Shift + Backspace: Backspace whole word;<br>
- - Shift + Arrow keys: jump words;<br>
- - Ctrl + (+/- or mousewheel): Zoom text size;<br>
- - Ctrl + Enter: auto compleate based on variable names and modules loaded -- multiple choices popup a menu;<br>
- - Shift + Enter: multiline functions -- delays executing code until only Enter is pressed.
-"""
-
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-from Blender import *
-import sys as python_sys
-import StringIO
-
-# Constants
-__DELIMETERS__ = '. ,=+-*/%<>&~][{}():\t'
-__VARIABLE_DELIMETERS__ = ' ,=+-*/%<>&~{}():\t'
-
-__LINE_HISTORY__ = 500
-
-global __FONT_SIZE__
-
-__FONT_SIZES__ = ( ('tiny', 10), ('small', 12), ('normalfix', 14), ('large', 16) )
-__FONT_SIZE__ = 2 # index for the list above, normal default.
-
-global __CONSOLE_LINE_OFFSET__
-__CONSOLE_LINE_OFFSET__ = 0
-
-cmdBuffer = [] # dosnt need to be global
-
-'''
-# Generic Blender functions
-def getActScriptWinRect():
- area = Window.GetAreaSize()
- area = (area[0]-1, area[1]-1)
- for scrInfo in Window.GetScreenInfo(Window.Types['SCRIPT'], 'win', ''):
- if scrInfo['vertices'][2]-scrInfo['vertices'][0] == area[0]:
- if scrInfo['vertices'][3]-scrInfo['vertices'][1] == area[1]:
- return scrInfo['vertices']
- return None
-'''
-
-
-# menuText, # per group
-def PupMenuLess(menu, groupSize=35):
- more = [' more...']
- less = [' less...']
-
- menuList= menu.split('|')
-
- # No Less Needed, just call.
- if len(menuList) < groupSize:
- return Draw.PupMenu(menu)
-
- title = menuList[0].split('%t')[0]
-
- # Split the list into groups
- menuGroups = [[]]
- for li in menuList[1:]:
- if len(menuGroups[-1]) < groupSize:
- menuGroups[-1].append(li)
- else:
- menuGroups.append([li])
-
- # Stores teh current menu group we are looking at
- groupIdx = 0
- while 1:
- # Give us a title with the menu number
- numTitle = [ ' '.join([title, str(groupIdx + 1), 'of', str(len(menuGroups)), '%t'])]
- if groupIdx == 0:
- menuString = '|'.join(numTitle + menuGroups[groupIdx] + more)
- elif groupIdx == len(menuGroups)-1:
- menuString = '|'.join(numTitle + less + menuGroups[groupIdx])
- else: # In the middle somewhere so Show a more and less
- menuString = '|'.join(numTitle + less + menuGroups[groupIdx] + more)
- result = Draw.PupMenu(menuString)
- # User Exit
- if result == -1:
- return -1
-
- if groupIdx == 0: # First menu
- if result-1 < groupSize:
- return result
- else: # must be more
- groupIdx +=1
- elif groupIdx == len(menuGroups): # Last Menu
- if result == 1: # Must be less
- groupIdx -= 1
- else: # Must be a choice
- return result + (groupIdx*groupSize)
-
- else:
- if result == 1: # Must be less
- groupIdx -= 1
- elif result-2 == groupSize:
- groupIdx +=1
- else:
- return result - 1 + (groupIdx*groupSize)
-
-
-
-# Use newstyle classes, Im not bothering with inheretence
-# but slots are faster.
-class cmdLine(object):
- __slots__ = [\
- 'cmd', # is the command string, or any other message
- 'type',# type: 0:user input 1:program feedback 2:error message. 3:option feedback
- 'exe' # 0- not yet executed 1:executed
- ]
- def __init__(self, cmd, type, exe):
- self.cmd = cmd
- self.type = type
- self.exe = exe
-
-# Include external file with internal namespace
-def include(filename):
- file = open(filename, 'r')
- filedata = file.read()
- file.close()
- return compile(filedata, filename, 'exec')
-
-# Writes command line data to a blender text file.
-def writeCmdData(type):
- newText = Text.New('command_output.py', 1)
- if type == 3: newText.write('\n'.join( [ myCmd.cmd for myCmd in cmdBuffer ] ))
- else: newText.write('\n'.join( [ myCmd.cmd for myCmd in cmdBuffer if myCmd.type is type] ))
- Draw.PupMenu('%s written' % newText.name)
-
-def insertCmdData():
- texts = list(bpy.data.texts)
- textNames = [tex.name for tex in texts]
- if textNames:
- choice = Draw.PupMenu('|'.join(textNames))
- if choice != -1:
- text = texts[choice-1]
-
- # Add the text!
- for l in text.asLines():
- cmdBuffer.append(cmdLine('%s ' % l, 0, 0))
- Draw.Redraw()
-
-
-COLLECTED_VAR_NAMES = {} # a list of keys, each key has a list of absolute paths
-
-# Pain and simple recursice dir(), accepts a string
-unused_types = str, dict, list, float, int, str, type, tuple, type(dir), type(None)
-def rdir(dirString, depth=0):
- #print ' ' * depth, dirString
- # MAX DEPTH SET HERE
- if depth > 5:
- # print 'maxdepoth reached.'
- return
-
- global COLLECTED_VAR_NAMES
- dirStringSplit = dirString.split('.')
-
- exec('value=' + dirString)
-
- if type(value) in unused_types:
- # print 'bad type'
- return
- dirList = dir(value)
-
- for dirItem in dirList:
- if dirItem.startswith('_'):
- continue
-
- dirData = None
- try:
- # Rare cases this can mess up, material.shader was a problem.
- exec('dirData = %s.%s' % (dirString, dirItem))
- #print dirData
- except:
- # Dont bother with this data.
- continue
- #print 'HEY', dirData, dirItem
- #if type(dirItem) != str:
- # print dirItem, type(dirItem)
-
- if dirItem not in COLLECTED_VAR_NAMES: # .keys()
- COLLECTED_VAR_NAMES[dirItem] = []
-
- # Add the string
- # splitD = dirString.split('"')[-2]
-
- # Example of dirString
- # __CONSOLE_VAR_DICT__["Main"].scenes.active.render
-
- # Works but can be faster
- # splitD = dirString.replace('__CONSOLE_VAR_DICT__["', '').replace('"]', '')
-
- splitD = dirString[22:].replace('"]', '')
-
- if splitD not in COLLECTED_VAR_NAMES[dirItem]:
- # print dirItem, dirString, splitD,
- COLLECTED_VAR_NAMES[dirItem].append(splitD)
-
-
- # Stops recursice stuff, overlooping
- #print type(dirItem)
- #if type(dirData) == types.ClassType or \
- # type(dirData) == types.ModuleType:
- type_dirData = type(dirData)
- if type_dirData not in unused_types:
- # print type(dirData), dirItem
- # Dont loop up dirs for strings ints etc.
- if dirItem not in dirStringSplit:
- rdir( '%s.%s' % (dirString, dirItem), depth+1)
- '''
- elif depth == 0: # Add local variables
- # print type(dirData), dirItem
- # Dont loop up dirs for strings ints etc.
- if dirItem not in dirStringSplit:
- rdir( '%s.%s' % (dirString, dirItem), depth+1)
- '''
-
-def recursive_dir():
- global COLLECTED_VAR_NAMES
-
- for name in __CONSOLE_VAR_DICT__: # .keys()
- if not name.startswith('_'): # Dont pick names like __name__
- rdir('__CONSOLE_VAR_DICT__["%s"]' % name)
- #print COLLECTED_VAR_NAMES
- COLLECTED_VAR_NAMES[name] = ['']
- return COLLECTED_VAR_NAMES
-
-# Runs the code line(s) the user has entered and handle errors
-# As well as feeding back the output into the blender window.
-def runUserCode(__USER_CODE_STRING__):
- global __CONSOLE_VAR_DICT__ # We manipulate the variables here. loading and saving from localspace to this global var.
-
- # Open A File like object to write all output to, that would useually be printed.
- python_sys.stdout.flush() # Get rid of whatever came before
- __FILE_LIKE_STRING__ = StringIO.StringIO() # make a new file like string, this saves up from making a file.
- __STD_OUTPUT__ = python_sys.stdout # we need to store the normal output.
- python_sys.stdout=__FILE_LIKE_STRING__ # Now anything printed will be written to the file like string.
-
- # Try and run the user entered line(s)
- try:
- # Load all variabls from global dict to local space.
- __TMP_VAR_NAME__ = __TMP_VAR__ = '' # so as not to raise an error when del'ing
-
- for __TMP_VAR_NAME__, __TMP_VAR__ in __CONSOLE_VAR_DICT__.items():
- exec('%s%s' % (__TMP_VAR_NAME__,'=__TMP_VAR__'))
- del __TMP_VAR_NAME__
- del __TMP_VAR__
-
- # Now all the vars are loaded, execute the code. # Newline thanks to phillip,
- exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'single')) #exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'exec'))
-
- # Flush global dict, allow the user to remove items.
- __CONSOLE_VAR_DICT__ = {}
-
- __TMP_VAR_NAME__ = '' # so as not to raise an error when del'ing
- # Write local veriables to global __CONSOLE_VAR_DICT__
- for __TMP_VAR_NAME__ in dir():
- if __TMP_VAR_NAME__ != '__FILE_LIKE_STRING__' and\
- __TMP_VAR_NAME__ != '__STD_OUTPUT__' and\
- __TMP_VAR_NAME__ != '__TMP_VAR_NAME__' and\
- __TMP_VAR_NAME__ != '__USER_CODE_STRING__':
-
- # Execute the local > global coversion.
- exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__))
- del __TMP_VAR_NAME__
-
- except: # Prints the REAL exception.
- error = '%s: %s' % (python_sys.exc_type, python_sys.exc_value)
- for errorLine in error.split('\n'):
- cmdBuffer.append(cmdLine(errorLine, 2, None)) # new line to type into
-
- python_sys.stdout = __STD_OUTPUT__ # Go back to output to the normal blender console
-
- # Copy all new output to cmdBuffer
-
- __FILE_LIKE_STRING__.seek(0) # the readline function requires that we go back to the start of the file.
-
- for line in __FILE_LIKE_STRING__.readlines():
- cmdBuffer.append(cmdLine(line, 1, None))
-
- cmdBuffer.append(cmdLine(' ', 0, 0)) # new line to type into
- python_sys.stdout=__STD_OUTPUT__
- __FILE_LIKE_STRING__.close()
-
-
-
-
-
-#------------------------------------------------------------------------------#
-# event handling code #
-#------------------------------------------------------------------------------#
-def handle_event(evt, val):
-
- # Insert Char into the cammand line
- def insCh(ch): # Instert a char
- global cursor
- # Later account for a cursor variable
- cmdBuffer[-1].cmd = ('%s%s%s' % ( cmdBuffer[-1].cmd[:cursor], ch, cmdBuffer[-1].cmd[cursor:]))
-
- #------------------------------------------------------------------------------#
- # Define Complex Key Actions #
- #------------------------------------------------------------------------------#
- def actionEnterKey():
- global histIndex, cursor
-
- def getIndent(string):
- # Gather white space to add in the previous line
- # Ignore the last char since its padding.
- whiteSpace = ''
- #for i in range(len(cmdBuffer[-1].cmd)):
- for i in xrange(len(string)-1):
- if cmdBuffer[-1].cmd[i] == ' ' or cmdBuffer[-1].cmd[i] == '\t':
- whiteSpace += string[i]
- else:
- break
- return whiteSpace
-
- # Autocomplete
- if Window.GetKeyQualifiers() & Window.Qual.CTRL:
- actionAutoCompleate()
- return
-
- # Are we in the middle of a multiline part or not?
- # try be smart about it
- if cmdBuffer[-1].cmd.split('#')[0].rstrip().endswith(':'):
- # : indicates an indent is needed
- cmdBuffer.append(cmdLine('\t%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
- print ': indicates an indent is needed'
-
- elif cmdBuffer[-1].cmd[0] in [' ', '\t'] and len(cmdBuffer[-1].cmd) > 1 and cmdBuffer[-1].cmd.split():
- # white space at the start means he havnt finished the multiline.
- cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
- print 'white space at the start means he havnt finished the multiline.'
-
- elif Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- # Crtl forces multiline
- cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0))
- print 'Crtl forces multiline'
-
- else: # Execute multiline code block
-
- # Multiline code will still run with 1 line,
- multiLineCode = ['if 1:'] # End of the multiline first.
-
- # Seek the start of the file multiline
- i = 1
- while cmdBuffer[-i].exe == 0:
- i+=1
-
- while i > 1:
- i-=1
-
- if cmdBuffer[-i].cmd == ' ':# Tag as an output type so its not used in the key history
- cmdBuffer[-i].type = 1
- else: # Tab added at the start for added if 1: statement
- multiLineCode.append('\t%s' % cmdBuffer[-i].cmd )
-
- # Mark as executed
- cmdBuffer[-i].exe = 1
-
- multiLineCode.append('\tpass') # reverse will make this the start.
-
- # Dubug, print the code that is executed.
- #for m in multiLineCode: print m
-
- runUserCode('\n'.join(multiLineCode))
-
- # Clear the output based on __LINE_HISTORY__
- if len(cmdBuffer) > __LINE_HISTORY__:
- cmdBuffer[:__LINE_HISTORY__] = []
-
- histIndex = cursor = -1 # Reset cursor and history
-
- def actionUpKey():
- global histIndex
- if abs(histIndex)+1 >= len(cmdBuffer):
- histIndex = -1
-
- # When wrapping allow 1 plank lines
- if cmdBuffer[-1].cmd != ' ':
- cmdBuffer[-1].cmd = ' '
- return
-
- histIndex_orig = histIndex
- histIndex -= 1
-
- while (cmdBuffer[histIndex].type != 0 and abs(histIndex) < len(cmdBuffer)) or \
- ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd):
- histIndex -= 1
-
- if cmdBuffer[histIndex].type == 0: # we found one
- cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd
-
- def actionDownKey():
- global histIndex
- if histIndex >= -2:
- histIndex = -len(cmdBuffer)
-
- # When wrapping allow 1 plank lines
- if cmdBuffer[-1].cmd != ' ':
- cmdBuffer[-1].cmd = ' '
- return
-
- histIndex_orig = histIndex
- histIndex += 1
- while (cmdBuffer[histIndex].type != 0 and histIndex != -2) or \
- ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd):
-
- histIndex += 1
-
- if cmdBuffer[histIndex].type == 0: # we found one
- cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd
-
- def actionRightMouse():
- global __FONT_SIZE__
- choice = Draw.PupMenu('Console Menu%t|Write Input Data (white)|Write Output Data (blue)|Write Error Data (red)|Write All Text|%l|Insert Blender text|%l|Font Size|%l|Clear Output|Quit')
-
- if choice == 1:
- writeCmdData(0) # type 0 user
- elif choice == 2:
- writeCmdData(1) # type 1 user output
- elif choice == 3:
- writeCmdData(2) # type 2 errors
- elif choice == 4:
- writeCmdData(3) # All
- elif choice == 6:
- insertCmdData() # Insert text from Blender and run it.
- elif choice == 8:
- # Fontsize.
- font_choice = Draw.PupMenu('Font Size%t|Large|Normal|Small|Tiny')
- if font_choice != -1:
- if font_choice == 1:
- __FONT_SIZE__ = 3
- elif font_choice == 2:
- __FONT_SIZE__ = 2
- elif font_choice == 3:
- __FONT_SIZE__ = 1
- elif font_choice == 4:
- __FONT_SIZE__ = 0
- Draw.Redraw()
- elif choice == 10: # Clear all output
- cmdBuffer[:] = [cmd for cmd in cmdBuffer if cmd.type == 0] # keep user input
- Draw.Redraw()
- elif choice == 11: # Exit
- Draw.Exit()
-
-
- # Auto compleating, quite complex- use recutsice dir for the moment.
- def actionAutoCompleate(): # Ctrl + Tab
- if not cmdBuffer[-1].cmd[:cursor].split():
- return
-
-
- RECURSIVE_DIR = recursive_dir()
-
- # get last name of user input
- editVar = cmdBuffer[-1].cmd[:cursor]
- # Split off spaces operators etc from the staryt of the command so we can use the startswith function.
- for splitChar in __VARIABLE_DELIMETERS__:
- editVar = editVar[:-1].split(splitChar)[-1] + editVar[-1]
-
-
- # Now we should have the var by its self
- if editVar:
- possibilities = []
-
- for __TMP_VAR_NAME__ in RECURSIVE_DIR: #.keys():
- #print '\t', __TMP_VAR_NAME__
- if __TMP_VAR_NAME__ == editVar:
- # print 'ADITVAR IS A VAR'
- pass
- '''
- elif __TMP_VAR_NAME__.startswith( editVar ):
- print __TMP_VAR_NAME__, 'aaa'
- possibilities.append( __TMP_VAR_NAME__ )
- '''
- possibilities.append( __TMP_VAR_NAME__ )
-
- if len(possibilities) == 1:
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], possibilities[0], cmdBuffer[-1].cmd[cursor:]))
-
- elif possibilities: # If its not just []
- # -1 with insert is the second last.
-
- # Text choice
- #cmdBuffer.insert(-1, cmdLine('options: %s' % ' '.join(possibilities), 3, None))
-
- menuList = [] # A lits of tuples- ABSOLUTE, RELATIVE
-
- for __TMP_VAR_NAME__ in possibilities:
- for usage in RECURSIVE_DIR[__TMP_VAR_NAME__]:
- # Account for non absolute (variables for eg.)
- if usage: # not ''
- absName = '%s.%s' % (usage, __TMP_VAR_NAME__)
-
- if __TMP_VAR_NAME__.startswith(editVar):
- menuList.append( # Used for names and can be entered when pressing shift.
- (absName, # Absolute name
- __TMP_VAR_NAME__) # Relative name, non shift
- )
-
- #else:
- # if absName.find(editVar) != -1:
- # menuList.append((__TMP_VAR_NAME__, __TMP_VAR_NAME__)) # Used for names and can be entered when pressing shift.
-
- # No items to display? no menu
- if not menuList:
- return
-
- menuList.sort()
-
- choice = PupMenuLess( # Menu for the user to choose the autocompleate
- 'Choices (Shift for local name, Ctrl for Docs)%t|' + # Title Text
- '|'.join(['%s, %s' % m for m in menuList])) # Use Absolute names m[0]
-
- if choice != -1:
- if Window.GetKeyQualifiers() & Window.Qual.CTRL: # Help
- cmdBuffer[-1].cmd = ('help(%s%s) ' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0]))
- elif Window.GetKeyQualifiers() & Window.Qual.SHIFT: # Put in the long name
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))
- else: # Only paste in the Short name
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0], cmdBuffer[-1].cmd[cursor:]))
-
-
- else:
- # print 'NO EDITVAR'
- return
-
- # ------------------end------------------ #
-
- # Quit from menu only
- #if (evt == Draw.ESCKEY and not val):
- # Draw.Exit()
- if evt == Draw.MOUSEX or evt == Draw.MOUSEY: # AVOID TOO MANY REDRAWS.
- return
-
-
- global cursor
- global histIndex
- global __FONT_SIZE__
- global __CONSOLE_LINE_OFFSET__
-
- ascii = Blender.event
-
- resetScroll = True
-
- #------------------------------------------------------------------------------#
- # key codes and key handling #
- #------------------------------------------------------------------------------#
-
- # UP DOWN ARROW KEYS, TO TRAVERSE HISTORY
- if (evt == Draw.UPARROWKEY and val): actionUpKey()
- elif (evt == Draw.DOWNARROWKEY and val): actionDownKey()
-
- elif (evt == Draw.RIGHTARROWKEY and val):
- if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- wordJump = False
- newCursor = cursor+1
- while newCursor<0:
-
- if cmdBuffer[-1].cmd[newCursor] not in __DELIMETERS__:
- newCursor+=1
- else:
- wordJump = True
- break
- if wordJump: # Did we find a new cursor pos?
- cursor = newCursor
- else:
- cursor = -1 # end of line
- else:
- cursor +=1
- if cursor > -1:
- cursor = -1
-
- elif (evt == Draw.LEFTARROWKEY and val):
- if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- wordJump = False
- newCursor = cursor-1
- while abs(newCursor) < len(cmdBuffer[-1].cmd):
-
- if cmdBuffer[-1].cmd[newCursor] not in __DELIMETERS__ or\
- newCursor == cursor:
- newCursor-=1
- else:
- wordJump = True
- break
- if wordJump: # Did we find a new cursor pos?
- cursor = newCursor
- else:
- cursor = -len(cmdBuffer[-1].cmd) # Start of line
-
- else:
- if len(cmdBuffer[-1].cmd) > abs(cursor):
- cursor -=1
-
- elif (evt == Draw.HOMEKEY and val):
- cursor = -len(cmdBuffer[-1].cmd)
-
- elif (evt == Draw.ENDKEY and val):
- cursor = -1
-
- elif (evt == Draw.TABKEY and val):
- insCh('\t')
-
- elif (evt == Draw.BACKSPACEKEY and val):
- if Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- i = -1
- for d in __DELIMETERS__:
- i = max(i, cmdBuffer[-1].cmd[:cursor-1].rfind(d))
- if i == -1:
- i=0
- cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:i] , cmdBuffer[-1].cmd[cursor:]))
-
- else:
- # Normal backspace.
- cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:cursor-1] , cmdBuffer[-1].cmd[cursor:]))
-
- elif (evt == Draw.DELKEY and val) and cursor < -1:
- cmdBuffer[-1].cmd = cmdBuffer[-1].cmd[:cursor] + cmdBuffer[-1].cmd[cursor+1:]
- cursor +=1
-
- elif ((evt == Draw.RETKEY or evt == Draw.PADENTER) and val):
- actionEnterKey()
-
- elif (evt == Draw.RIGHTMOUSE and not val): actionRightMouse(); return
-
- elif (evt == Draw.PADPLUSKEY or evt == Draw.EQUALKEY or evt == Draw.WHEELUPMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL:
- __FONT_SIZE__ += 1
- __FONT_SIZE__ = min(len(__FONT_SIZES__)-1, __FONT_SIZE__)
- elif (evt == Draw.PADMINUS or evt == Draw.MINUSKEY or evt == Draw.WHEELDOWNMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL:
- __FONT_SIZE__ -=1
- __FONT_SIZE__ = max(0, __FONT_SIZE__)
-
-
- elif evt == Draw.WHEELUPMOUSE and val:
- __CONSOLE_LINE_OFFSET__ += 1
- __CONSOLE_LINE_OFFSET__ = min(len(cmdBuffer)-2, __CONSOLE_LINE_OFFSET__)
- resetScroll = False
-
- elif evt == Draw.WHEELDOWNMOUSE and val:
- __CONSOLE_LINE_OFFSET__ -= 1
- __CONSOLE_LINE_OFFSET__ = max(0, __CONSOLE_LINE_OFFSET__)
- resetScroll = False
-
-
- elif ascii:
- insCh(chr(ascii))
- else:
- return # dont redraw.
-
- # If the user types in anything then scroll to bottom.
- if resetScroll:
- __CONSOLE_LINE_OFFSET__ = 0
- Draw.Redraw()
-
-
-def draw_gui():
- # Get the bounds from ObleGL directly
- __CONSOLE_RECT__ = BGL.Buffer(BGL.GL_FLOAT, 4)
- BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, __CONSOLE_RECT__)
- __CONSOLE_RECT__= __CONSOLE_RECT__.list
-
- # Clear the screen
- BGL.glClearColor(0.0, 0.0, 0.0, 1.0)
- BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) # use it to clear the color buffer
-
-
- # Fixed margin. use a margin since 0 margin can be hard to seewhen close to a crt's edge.
- margin = 4
-
- # Convenience
- FNT_NAME, FNT_HEIGHT = __FONT_SIZES__[__FONT_SIZE__]
-
- # Draw cursor location colour
- if __CONSOLE_LINE_OFFSET__ == 0:
- cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], FNT_NAME)
- BGL.glColor3f(0.8, 0.2, 0.2)
- if cmd2curWidth == 0:
- BGL.glRecti(margin,2,margin+2, FNT_HEIGHT+2)
- else:
- BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, FNT_HEIGHT+2)
-
- BGL.glColor3f(1,1,1)
- # Draw the set of cammands to the buffer
- consoleLineIdx = __CONSOLE_LINE_OFFSET__ + 1
- wrapLineIndex = 0
- while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * FNT_HEIGHT:
- if cmdBuffer[-consoleLineIdx].type == 0:
- BGL.glColor3f(1, 1, 1)
- elif cmdBuffer[-consoleLineIdx].type == 1:
- BGL.glColor3f(.3, .3, 1)
- elif cmdBuffer[-consoleLineIdx].type == 2:
- BGL.glColor3f(1.0, 0, 0)
- elif cmdBuffer[-consoleLineIdx].type == 3:
- BGL.glColor3f(0, 0.8, 0)
- else:
- BGL.glColor3f(1, 1, 0)
-
- if consoleLineIdx == 1: # user input
- BGL.glRasterPos2i(margin, (FNT_HEIGHT * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8)
- Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME)
- else: # WRAP
- lwid = Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME)
- if margin + lwid > __CONSOLE_RECT__[2]:
- wrapLineList = []
- wtext = cmdBuffer[-consoleLineIdx].cmd
- wlimit = len(wtext)
- chunksz = int(( __CONSOLE_RECT__[2] - margin ) / (lwid / len(wtext)))
- lstart = 0
- fsize = FNT_NAME
- while lstart < wlimit:
- lend = min(lstart+chunksz,wlimit)
- ttext = wtext[lstart:lend]
- while lend < wlimit and Draw.GetStringWidth(ttext, fsize) + margin < __CONSOLE_RECT__[2]:
- lend += 1
- ttext = wtext[lstart:lend]
- while lend > lstart+1 and Draw.GetStringWidth(ttext, fsize) + margin > __CONSOLE_RECT__[2]:
- lend -= 1
- ttext = wtext[lstart:lend]
- wrapLineList.append(ttext)
- lstart = lend
- # Now we have a list of lines, draw them (OpenGLs reverse ordering requires this odd change)
- wrapLineList.reverse()
- for wline in wrapLineList:
- BGL.glRasterPos2i(margin, (FNT_HEIGHT*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8)
- Draw.Text(wline, FNT_NAME)
- wrapLineIndex += 1
- wrapLineIndex-=1 # otherwise we get a silly extra line.
-
- else: # no wrapping.
-
- BGL.glRasterPos2i(margin, (FNT_HEIGHT * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8)
- Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME)
- consoleLineIdx += 1
-
-# This recieves the event index, call a function from here depending on the event.
-def handle_button_event(evt):
- pass
-
-
-# Run the console
-__CONSOLE_VAR_DICT__ = {} # Initialize var dict
-
-
-# Print Startup lines, add __bpydoc__ to the console startup.
-for l in __bpydoc__.split('<br>'):
- cmdBuffer.append( cmdLine(l, 1, None) )
-
-
-histIndex = cursor = -1 # How far back from the first letter are we? - in current CMD line, history if for moving up and down lines.
-
-# Autoexec, startup code.
-scriptDir = Get('scriptsdir')
-console_autoexec = None
-if scriptDir:
- if not scriptDir.endswith(Blender.sys.sep):
- scriptDir += Blender.sys.sep
-
- console_autoexec = '%s%s' % (scriptDir, 'console_autoexec.py')
-
- if not sys.exists(console_autoexec):
- # touch the file
- try:
- open(console_autoexec, 'w').close()
- cmdBuffer.append(cmdLine('...console_autoexec.py not found, making new in scripts dir', 1, None))
- except:
- cmdBuffer.append(cmdLine('...console_autoexec.py could not write, this is ok', 1, None))
- scriptDir = None # make sure we only use this for console_autoexec.py
-
- if not sys.exists(console_autoexec):
- console_autoexec = None
-
- else:
- cmdBuffer.append(cmdLine('...Using existing console_autoexec.py in scripts dir', 1, None))
-
-
-
-#-Autoexec---------------------------------------------------------------------#
-# Just use the function to jump into local naming mode.
-# This is so we can loop through all of the autoexec functions / vars and add them to the __CONSOLE_VAR_DICT__
-def include_console(includeFile):
- global __CONSOLE_VAR_DICT__ # write autoexec vars to this.
-
- # Execute an external py file as if local
- exec(include(includeFile))
-
-def standard_imports():
- # Write local to global __CONSOLE_VAR_DICT__ for reuse,
-
- exec('%s%s' % ('__CONSOLE_VAR_DICT__["bpy"]=', 'bpy'))
- exec('%s%s' % ('__CONSOLE_VAR_DICT__["Blender"]=', 'Blender'))
-
- for ls in (dir(), dir(Blender)):
- for __TMP_VAR_NAME__ in ls:
- # Execute the local > global coversion.
- exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__))
-
- # Add dummy imports to input so output scripts to a text file work as expected
- cmdBuffer.append(cmdLine('import bpy', 0, 1))
- cmdBuffer.append(cmdLine('import Blender', 0, 1)) # pretend we have been executed, as we kindof have.
- cmdBuffer.append(cmdLine('from Blender import *', 0, 1))
-
-if scriptDir and console_autoexec:
- include_console(console_autoexec) # pass the blender module
-
-standard_imports() # import Blender and bpy
-
-#-end autoexec-----------------------------------------------------------------#
-
-
-# Append new line to write to
-cmdBuffer.append(cmdLine(' ', 0, 0))
-
-#------------------------------------------------------------------------------#
-# register the event handling code, GUI #
-#------------------------------------------------------------------------------#
-def main():
- Draw.Register(draw_gui, handle_event, handle_button_event)
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/discombobulator.py b/release/scripts/discombobulator.py
deleted file mode 100644
index 6dbb4e5382b..00000000000
--- a/release/scripts/discombobulator.py
+++ /dev/null
@@ -1,1526 +0,0 @@
-#!BPY
-
-"""
-Name: 'Discombobulator'
-Blender: 237
-Group: 'Mesh'
-Tip: 'Adds random geometry to a mesh'
-"""
-
-__author__ = "Evan J. Rosky (syrux)"
-__url__ = ("Script's homepage, http://evan.nerdsofparadise.com/programs/discombobulator/index.html")
-__version__ = "237"
-__bpydoc__ = """\
-Discombobulator adds random geometry to a mesh.
-
-As an example, this script can easily give a "high-tech"
-look to walls and spaceships.
-
-Definitions:<br>
- - Protrusions: extrusions of each original face on the mesh.
-You may have from 1 to 4 protrusions on each face.<br>
- - Taper: The tips of each protrusion will be a percentage
-smaller than the base.<br>
- - Doodads: small extruded blocks/shapes that are randomly placed
-about the top of a protrusion or face.
-
-
-Usage:<br>
- Input your settings, make sure the mesh you would like to modify
-is selected (active) and then click on "Discombobulate".<br>
- See the scripts tutorial page (on the homepage) for more info.
-
-
-New Features:<br>
- - Will use existing materials if there are any.<br>
- - Clicking "Assign materials by part" will allow assigning
-of different material indices to Protrusion or Doodad Sides
-and Tops in the gui element below it.<br>
- - Setting a material index to 0 will use whatever material
-is assigned to the face that is discombobulated.
- - You can now scroll using the arrow keys.
-
-
-Notes:<br>
- - Modifications can be restricted to selected faces
-by setting "Only selected faces" for protrusions and/or
-doodads.<br>
- - It's possible to restrict mesh generation to add only
-protrusions or only doodads instead of both.<br>
- - You may also choose to have Discombobulator select the
-tops of created protrusions by clicking the corresponding
-number of protrusion buttons under "Select Tops". You may
-also do the same for doodads by choosing "Select Doodads" and
-"Only Select Tops". You may choose to select the whole doodads
-by leaving "Only Select Tops" off.<br>
- - By selecting "Deselect Selected" you can have
-discombobulator deselect everything but the selections it
-makes.<br>
- - The "Face %" option will set the percentage of faces that
-will be modified either for the doodads or the protrusions.<br>
- - "Copy Before Modifying" will create a new object with the
-modifications where leaving it off will overwrite the original
-mesh.<br>
-
-You can find more information at the Link above.
-"""
-
-
-# $Id$
-#
-# Updated 2006-09-26
-# Changes since last version:
-# > Works with Blender CVS and hopefully with Blender 2.40.
-# > Swaps min/max values when min>max rather than complaining.
-# > Will keep previously assigned materials.
-# > Now allows user to assign custom material indices to
-# Protrusion and Doodad Sides and Tops.
-# > The initial Gui Layout will change depending on the aspect
-# ratio of the window it is in.
-# > Using the arrow keys will scroll the gui.
-#
-# --------------------------------------------------------------------------
-# Discombobulator v2.1b
-# by Evan J. Rosky, 2005
-# This plugin is protected by the GPL: Gnu Public Licence
-# GPL - http://www.gnu.org/copyleft/gpl.html
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2005: Evan J. Rosky
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-#Hit Alt-P to run
-
-import Blender
-from Blender import NMesh,Object,Material,Window,Types,Scene
-from Blender.NMesh import Vert,Face
-from Blender.Mathutils import *
-
-import defaultdoodads
-import BPyMathutils
-from BPyMathutils import genrand
-a = BPyMathutils.sgenrand(int(round(Rand(1000,99999),0)))
-
-#Create random numbers
-def randnum(low,high):
- num = genrand()
- num = num*(high-low)
- num = num+low
- return num
-
-#Object Vars
-newmesh = NMesh.GetRaw()
-materialArray = [0]
-
-#Material Vars
-reassignMats = 0
-protSideMat = 1
-protTopMat = 2
-doodSideMat = 3
-doodTopMat = 4
-thereAreMats = 0
-currmat = 0
-
-#Global Vars
-makenewobj = 1
-errortext = "Remember to select an object."
-editmode = 0
-
-#Protrusion Vars
-makeprots = 1
-faceschangedpercent = 1.0
-minimumheight = 0.2
-maximumheight = 0.4
-subface1 = 1
-subface2 = 1
-subface3 = 1
-subface4 = 1
-subfaceArray = [1,2,3,4]
-minsubfaces = 1
-minimumtaperpercent = 0.15
-maximumtaperpercent = 0.35
-useselectedfaces = 0
-selectface1 = 1
-selectface2 = 1
-selectface3 = 1
-selectface4 = 1
-deselface = 1
-
-#Doodad Vars
-makedoodads = 1
-doodadfacepercent = 1.0
-selectdoodad = 0
-onlyonprotrusions = 0
-doodonselectedfaces = 0
-selectdoodadtoponly = 0
-doodad1 = 1
-doodad2 = 1
-doodad3 = 1
-doodad4 = 1
-doodad5 = 1
-doodad6 = 1
-doodadminperface = 2
-doodadmaxperface = 6
-doodadminsize = 0.15
-doodadmaxsize = 0.45
-doodadminheight = 0.0
-doodadmaxheight = 0.1
-doodadArray = [1,2,3,4,5,6]
-
-def makeSubfaceArray():
- global subfaceArray
- global subface1
- global subface2
- global subface3
- global subface4
-
- subfaceArray = []
- if subface1 > 0:
- subfaceArray.append(1)
- if subface2 > 0:
- subfaceArray.append(2)
- if subface3 > 0:
- subfaceArray.append(3)
- if subface4 > 0:
- subfaceArray.append(4)
-
-def makeDoodadArray():
- global doodadArray
- global doodad1
- global doodad2
- global doodad3
- global doodad4
- global doodad5
- global doodad6
-
- doodadArray = []
- if doodad1 > 0:
- doodadArray.append(1)
- if doodad2 > 0:
- doodadArray.append(2)
- if doodad3 > 0:
- doodadArray.append(3)
- if doodad4 > 0:
- doodadArray.append(4)
- if doodad5 > 0:
- doodadArray.append(5)
- if doodad6 > 0:
- doodadArray.append(6)
-
-def extrude(mid,nor,protrusion,v1,v2,v3,v4,tosel=1,flipnor=0):
- taper = 1 - randnum(minimumtaperpercent,maximumtaperpercent)
- newmesh_verts = newmesh.verts
- newmesh_faces = newmesh.faces
-
- vert = newmesh_verts[v1]
- point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
- ver = Vert(point[0],point[1],point[2])
- ver.sel = tosel
- newmesh_verts.append(ver)
- vert = newmesh_verts[v2]
- point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
- ver = Vert(point[0],point[1],point[2])
- ver.sel = tosel
- newmesh_verts.append(ver)
- vert = newmesh_verts[v3]
- point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
- ver = Vert(point[0],point[1],point[2])
- ver.sel = tosel
- newmesh_verts.append(ver)
- vert = newmesh_verts[v4]
- point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
- ver = Vert(point[0],point[1],point[2])
- ver.sel = tosel
- newmesh_verts.append(ver)
-
- faceindex = len(newmesh_verts) - 4
-
- #side face 1
- face = Face([newmesh_verts[v1], newmesh_verts[v2], newmesh_verts[faceindex+1], newmesh_verts[faceindex]])
- if flipnor != 0:
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh_faces.append(face)
-
- #side face 2
- face = Face([newmesh_verts[v2], newmesh_verts[v3], newmesh_verts[faceindex+2], newmesh_verts[faceindex+1]])
- if flipnor != 0:
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh_faces.append(face)
-
- #side face 3
- face = Face([newmesh_verts[v3], newmesh_verts[v4], newmesh_verts[faceindex+3], newmesh_verts[faceindex+2]])
- if flipnor != 0:
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh_faces.append(face)
-
- #side face 4
- face = Face([newmesh_verts[v4], newmesh_verts[v1], newmesh_verts[faceindex], newmesh_verts[faceindex+3]])
- if flipnor != 0:
- face.v.reverse()
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh_faces.append(face)
-
- #top face
- face = Face(newmesh_verts[-4:])
- if flipnor != 0:
- face.v.reverse()
- if tosel == 1:
- face.sel = 1
- if thereAreMats == 1:
- if reassignMats == 0 or protTopMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protTopMat-1
- newmesh_faces.append(face)
- return face
-
-#Sets the global protrusion values
-def setProtrusionValues(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15):
-
- #Protrusions
- global makeprots
- global minimumtaperpercent
- global maximumtaperpercent
- global faceschangedpercent
- global minimumheight
- global maximumheight
- global subface1
- global subface2
- global subface3
- global subface4
- global useselectedfaces
- global selectface1
- global selectface2
- global selectface3
- global selectface4
- global deselface
- global subfaceArray
-
- #Protrusions
- makeprots = p0
- faceschangedpercent = p1
- minimumheight = p2
- maximumheight = p3
- subface1 = p4
- subface2 = p5
- subface3 = p6
- subface4 = p7
- minimumtaperpercent = p8
- maximumtaperpercent = p9
- useselectedfaces = p10
- selectface1 = p11
- selectface2 = p12
- selectface3 = p13
- selectface4 = p14
- deselface = p15
- makeSubfaceArray()
- if len(subfaceArray) == 0:
- makeprots = 0
-
- if minimumheight > maximumheight:
- a = maximumheight
- maximimheight = minimumheight
- minimumheight = a
- elif minimumtaperpercent > maximumtaperpercent:
- a = maximumtaperpercent
- maximimtaperpercent = minimumtaperpercent
- minimumtaperpercent = a
-
-#Sets the global Doodad values
-def setDoodadValues(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17):
-
- #Doodads
- global makedoodads
- global doodadfacepercent
- global selectdoodad
- global onlyonprotrusions
- global doodad1
- global doodad2
- global doodad3
- global doodad4
- global doodad5
- global doodad6
- global doodadminperface
- global doodadmaxperface
- global doodadminsize
- global doodadmaxsize
- global doodadminheight
- global doodadmaxheight
- global doodadArray
- global doodonselectedfaces
- global selectdoodadtoponly
-
- #Doodads
- makedoodads = d0
- doodadfacepercent = d1
- selectdoodad = d2
- onlyonprotrusions = d3
- doodad1 = d4
- doodad2 = d5
- doodad3 = d6
- doodad4 = d7
- doodad5 = d8
- doodad6 = d9
- doodadminperface = d10
- doodadmaxperface = d11
- doodadminsize = d12
- doodadmaxsize = d13
- doodadminheight = d14
- doodadmaxheight = d15
- doodonselectedfaces = d16
- selectdoodadtoponly = d17
- makeDoodadArray()
- if len(doodadArray) == 0:
- makedoodads = 0
-
- elif doodadminperface > doodadmaxperface:
- a = doodadmaxperface
- doodadmaxperface = doodadminperface
- doodadminperface = a
- elif doodadminsize > doodadmaxsize:
- a = doodadmaxsize
- doodadmaxsize = doodadminsize
- doodadminsize = a
- elif doodadminheight > doodadmaxheight:
- a = doodadmaxheight
- doodadmaxheight = doodadminheight
- doodadminheight = a
-
-#Sets other global values
-def setOtherValues(g0,m0,m1,m2,m3,m4):
-
- #Global
- global reassignMats
- global makenewobj
- global protSideMat
- global protTopMat
- global doodSideMat
- global doodTopMat
-
- #Get Misc Variables
- makenewobj = g0
- reassignMats = m0
- protSideMat = m1
- protTopMat = m2
- doodSideMat = m3
- doodTopMat = m4
-
-def discombobulate():
-
- #Global
- global origmesh
- global newmesh
- global makenewobj
- global origobj
- global newobj
- global messagetext
- global errortext
- global editmode
-
- #Protrusions
- global makeprots
- global minimumtaperpercent
- global maximumtaperpercent
- global faceschangedpercent
- global minimumheight
- global maximumheight
- global subface1
- global subface2
- global subface3
- global subface4
- global useselectedfaces
- global selectface1
- global selectface2
- global selectface3
- global selectface4
- global deselface
- global subfaceArray
-
- #Doodads
- global makedoodads
- global doodadfacepercent
- global selectdoodad
- global onlyonprotrusions
- global doodad1
- global doodad2
- global doodad3
- global doodad4
- global doodad5
- global doodad6
- global doodadminperface
- global doodadmaxperface
- global doodadminsize
- global doodadmaxsize
- global doodadminheight
- global doodadmaxheight
- global doodadArray
- global doodonselectedfaces
- global selectdoodadtoponly
-
- #Global
- global materialArray
- global reassignMats
- global protSideMat
- global protTopMat
- global doodSideMat
- global doodTopMat
- global thereAreMats
- global currmat
-
- origobj = Scene.GetCurrent().objects.active
- if not origobj:
- glRasterPos2d(10,50)
- errortext = "YOU MUST SELECT AN OBJECT!"
- messagetext = ErrorText(errortext)
- Blender.Redraw()
- return
-
- #Leave Editmode
- editmode = Window.EditMode()
- if editmode: Window.EditMode(0)
-
- #Get Major Variables
-
- origmesh = origobj.getData()
-
- if origobj.type != 'Mesh':
- glRasterPos2d(10,50)
- errortext = "OBJECT MUST BE MESH!"
- messagetext = ErrorText(errortext)
- Blender.Redraw()
- return
-
- newmesh = NMesh.GetRaw()
- materialArray = origmesh.getMaterials()
- if len(materialArray) < 1:
- thereAreMats = 0
- else:
- thereAreMats = 1
-
- #add material indices if necessary (only up to 4)
- if thereAreMats == 1 and reassignMats == 1:
- if len(materialArray) < 4:
- if protSideMat > 4: protSideMat = 4
- if protTopMat > 4: protTopMat = 4
- if doodSideMat > 4: doodSideMat = 4
- if doodTopMat > 4: doodTopMat = 4
- else:
- if protSideMat > len(materialArray): protSideMat = len(materialArray)
- if protTopMat > len(materialArray): protTopMat = len(materialArray)
- if doodSideMat > len(materialArray): doodSideMat = len(materialArray)
- if doodTopMat > len(materialArray): doodTopMat = len(materialArray)
-
- #This only does something if there are less than 4 verts
- for matind in [protSideMat,protTopMat,doodSideMat,doodTopMat]:
- if matind > len(materialArray) and matind <= 4:
- for i in xrange(len(materialArray),matind+1):
- materialArray.append(Material.New("AddedMat " + str(i)))
-
- #Sets the materials
- newmesh.setMaterials(materialArray)
-
- #Set the doodad settings
- defaultdoodads.settings(selectdoodadtoponly,materialArray,reassignMats,thereAreMats,doodSideMat,doodTopMat)
- #defaultdoodads.settings(selectdoodadtoponly,materialArray,reassignMats,thereAreMats,currmat)
-
- newmesh.verts.extend(origmesh.verts)
-
- #Start modifying faces
- for currface in origmesh.faces:
-
- currmat = currface.materialIndex
- defaultdoodads.setCurrMat(currmat)
-
- #Check if it is a triangle
- if len(currface.v)<4:
- face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index]])
- if thereAreMats == 1:
- face.materialIndex = currmat
- newmesh.faces.append(face)
- continue
-
- #Check whether or not to make protrusions
- if makeprots == 0:
- face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
- if thereAreMats == 1:
- face.materialIndex = currmat
- newmesh.faces.append(face)
- if makedoodads == 1 and onlyonprotrusions == 0:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- continue
-
- #Check if only changing selected faces
- if useselectedfaces == 1:
- #check if currface is selected
- if currface.sel:
- a = 1
- else:
- face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
- if thereAreMats == 1:
- face.materialIndex = currmat
- newmesh.faces.append(face)
- if makedoodads == 1 and onlyonprotrusions == 0:
- if doodonselectedfaces != 1:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- continue
- #Check if face should be modified by random chance
- if randnum(0,1)>faceschangedpercent:
- face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
- if thereAreMats == 1:
- face.materialIndex = currmat
- newmesh.faces.append(face)
- if makedoodads == 1 and onlyonprotrusions == 0:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- continue
-
- center = Vector([0,0,0])
- for pt in currface.v:
- center = center + pt.co
- center = center / len(currface.v)
-
- #Determine amount of subfaces
- subfaces = round(randnum(1,len(subfaceArray)),0)
- subfaces = subfaceArray[(int(subfaces) - 1)]
-
- ######################## START DEALING WITH PROTRUSIONS #####################
-
- if subfaces == 1:
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,currface.v[0].index,currface.v[1].index,currface.v[2].index,currface.v[3].index,selectface1)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
-
- elif subfaces == 2:
- orientation = int(round(randnum(0,1)))
- p1 = currface.v[orientation]
- p2 = currface.v[orientation + 1]
- p3 = ((p2.co - p1.co)/2) + p1.co
- ve1 = Vert(p3[0],p3[1],p3[2])
- ve1.sel = 0
- p1 = currface.v[2 + orientation]
- if orientation < 0.5:
- p2 = currface.v[3]
- else:
- p2 = currface.v[0]
- p3 = ((p2.co - p1.co)/2) + p1.co
- ve2 = Vert(p3[0],p3[1],p3[2])
- ve2.sel = 0
- if orientation < 0.5:
- verti = currface.v[3]
- p3 = verti.index
- v1 = p3
- verti = currface.v[0]
- p0 = verti.index
- v2 = p0
- else:
- verti = currface.v[0]
- p0 = verti.index
- v1 = p0
- verti = currface.v[1]
- p1 = verti.index
- v2 = p1
- newmesh.verts.append(ve1)
- newmesh.verts.append(ve2)
- index = len(newmesh.verts) - 2
- v4 = index + 1
- v3 = index
- center = Vector([0, 0, 0])
- for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,v1,v2,v3,v4,selectface2)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- if orientation < 0.5:
- verti = currface.v[1]
- p1 = verti.index
- v1 = p1
- verti = currface.v[2]
- p2 = verti.index
- v2 = p2
- else:
- verti = currface.v[2]
- p2 = verti.index
- v1 = p2
- verti = currface.v[3]
- p3 = verti.index
- v2 = p3
- center = Vector([0]*3)
- for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,v1,v2,v4,v3,selectface2)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- if orientation < 0.5:
- face = Face([newmesh.verts[p0],newmesh.verts[p1],newmesh.verts[v3]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[p2],newmesh.verts[p3],newmesh.verts[v4]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- else:
- face = Face([newmesh.verts[p1],newmesh.verts[p2],newmesh.verts[v3]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[p3],newmesh.verts[p0],newmesh.verts[v4]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
-
- elif subfaces == 3:
- layer2inds = []
- layer2verts = []
- orientation = int(round(randnum(0,1)))
- rotation = int(round(randnum(0,1)))
- p1 = currface.v[orientation]
- p2 = currface.v[orientation + 1]
- p3 = ((p2.co - p1.co)/2) + p1.co
- ve1 = Vert(p3[0],p3[1],p3[2])
- ve1.sel = 0
- p1 = currface.v[2 + orientation]
- if orientation < 0.5:
- p2 = currface.v[3]
- else:
- p2 = currface.v[0]
- p3 = ((p2.co - p1.co)/2) + p1.co
- ve2 = Vert(p3[0],p3[1],p3[2])
- ve2.sel = 0
- fp = []
-
- #make first protrusion
- if rotation < 0.5:
- if orientation < 0.5:
- verti = currface.v[3]
- fp.append(verti.index)
- v1 = verti.index
- verti = currface.v[0]
- fp.append(verti.index)
- v2 = verti.index
- layer2verts.extend([newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index]])
- else:
- verti = currface.v[0]
- fp.append(verti.index)
- v1 = verti.index
- verti = currface.v[1]
- fp.append(verti.index)
- v2 = verti.index
- layer2verts.extend([newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
- newmesh.verts.append(ve1)
- newmesh.verts.append(ve2)
- index = len(newmesh.verts) - 2
- v4 = index + 1
- v3 = index
- center = Vector([0]*3)
- for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- layer2inds.extend([v3,v4])
- tempface = extrude(center,currface.no,prot,v1,v2,v3,v4,selectface3)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- #Still first protrusion
- else:
- if orientation < 0.5:
- verti = currface.v[1]
- fp.append(verti.index)
- v1 = verti.index
- verti = currface.v[2]
- fp.append(verti.index)
- v2 = verti.index
- layer2verts.extend([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[3].index]])
- else:
- verti = currface.v[2]
- fp.append(verti.index)
- v1 = verti.index
- verti = currface.v[3]
- fp.append(verti.index)
- v2 = verti.index
- layer2verts.extend([newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[0].index]])
- newmesh.verts.append(ve2)
- newmesh.verts.append(ve1)
- index = len(newmesh.verts) - 2
- v4 = index
- v3 = index + 1
- center = Vector([0]*3)
- for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- layer2inds.extend([index, index +1])
- tempface = extrude(center,currface.no,prot,v1,v2,v4,v3,selectface3)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
-
- #split next rect(pre-arranged, no orientation crud)--make flag in extruder for only one existing vert in mesh
- p1 = newmesh.verts[layer2inds[0]]
- p2 = newmesh.verts[layer2inds[1]]
- p3 = ((p2.co - p1.co)/2) + p1.co
- ve3 = Vert(p3[0],p3[1],p3[2])
- ve3.sel = 0
- p1 = layer2verts[0]
- p2 = layer2verts[1]
- p3 = ((p2.co - p1.co)/2) + p1.co
- ve4 = Vert(p3[0],p3[1],p3[2])
- ve4.sel = 0
- newmesh.verts.append(ve3)
- newmesh.verts.append(ve4)
- tempindex = len(newmesh.verts) - 2
- v5 = tempindex
- v6 = tempindex + 1
- verti = layer2verts[0]
- t0 = verti.index
- center = Vector([0]*3)
- for pt in [newmesh.verts[v5],newmesh.verts[v6],newmesh.verts[t0],newmesh.verts[v3]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- if rotation < 0.5: flino = 1
- else: flino = 0
- tempface = extrude(center,currface.no,prot,v3,v5,v6,t0,selectface3,flino)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- if rotation < 0.5:
- fpt = t0
- face = Face([newmesh.verts[fp[1]],newmesh.verts[fpt],newmesh.verts[v3]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- else:
- fpt = t0
- face = Face([newmesh.verts[fp[0]],newmesh.verts[v3],newmesh.verts[fpt]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- verti = layer2verts[1]
- tempindex = verti.index
- center = Vector([0]*3)
- for pt in [newmesh.verts[v5],newmesh.verts[v6],newmesh.verts[tempindex],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,v6,v5,v4,tempindex,selectface3,flino)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- if rotation < 0.5:
- face = Face([newmesh.verts[tempindex],newmesh.verts[fp[0]],newmesh.verts[v4]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[fpt],newmesh.verts[tempindex],newmesh.verts[v6]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- else:
- face = Face([newmesh.verts[tempindex],newmesh.verts[v4],newmesh.verts[fp[1]]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[tempindex],newmesh.verts[fpt],newmesh.verts[v6]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
-
- else:
- #get all points
- verti = currface.v[0]
- p0 = verti.index
-
- verti = currface.v[1]
- p1 = verti.index
-
- pt = ((newmesh.verts[p1].co - newmesh.verts[p0].co)/2) + newmesh.verts[p0].co
- v1 = Vert(pt[0],pt[1],pt[2])
- v1.sel = 0
-
- verti = currface.v[2]
- p2 = verti.index
-
- pt = ((newmesh.verts[p2].co - newmesh.verts[p1].co)/2) + newmesh.verts[p1].co
- v2 = Vert(pt[0],pt[1],pt[2])
- v2.sel = 0
-
- verti = currface.v[3]
- p3 = verti.index
-
- pt = ((newmesh.verts[p3].co - newmesh.verts[p2].co)/2) + newmesh.verts[p2].co
- v3 = Vert(pt[0],pt[1],pt[2])
- v3.sel = 0
-
- pt = ((newmesh.verts[p0].co - newmesh.verts[p3].co)/2) + newmesh.verts[p3].co
- v4 = Vert(pt[0],pt[1],pt[2])
- v4.sel = 0
-
- pt = ((v3.co - v1.co)/2) + v1.co
- m = Vert(pt[0],pt[1],pt[2])
- m.sel = 0
-
- #extrusion 1
- newmesh.verts.extend([v1,m,v4])
- index = len(newmesh.verts) - 3
- v1 = index
- m = index + 1
- v4 = index + 2
- center = Vector([0]*3)
- for pt in [newmesh.verts[p0],newmesh.verts[v1],newmesh.verts[m],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,p0,v1,m,v4,selectface4)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
-
- #extrusion 2
- newmesh.verts.extend([v2])
- index = len(newmesh.verts) - 1
- v2 = index
- center = Vector([0]*3)
- for pt in [newmesh.verts[m],newmesh.verts[v1],newmesh.verts[p1],newmesh.verts[v2]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,m,v1,p1,v2,selectface4)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
-
- #extrusion 3
- newmesh.verts.extend([v3])
- index = len(newmesh.verts) - 1
- v3 = index
- center = Vector([0]*3)
- for pt in [newmesh.verts[m],newmesh.verts[v2],newmesh.verts[p2],newmesh.verts[v3]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,m,v2,p2,v3,selectface4)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
-
- #extrusion 4
- center = Vector([0]*3)
- for pt in [newmesh.verts[m],newmesh.verts[v3],newmesh.verts[p3],newmesh.verts[v4]]:
- center += pt.co
- center = center/4
- prot = randnum(minimumheight,maximumheight)
- tempface = extrude(center,currface.no,prot,v4,m,v3,p3,selectface4)
- if makedoodads == 1:
- if doodonselectedfaces == 1:
- if currface.sel:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
- else:
- tempmesh = NMesh.GetRaw()
- tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
- newmesh.verts.extend(tempmesh.verts)
- newmesh.faces.extend(tempmesh.faces)
-
- face = Face([newmesh.verts[p0],newmesh.verts[p1],newmesh.verts[v1]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[p1],newmesh.verts[p2],newmesh.verts[v2]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[p2],newmesh.verts[p3],newmesh.verts[v3]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
- face = Face([newmesh.verts[p3],newmesh.verts[p0],newmesh.verts[v4]])
- if thereAreMats == 1:
- if reassignMats == 0 or protSideMat == 0:
- face.materialIndex = currmat
- else:
- face.materialIndex = protSideMat-1
- newmesh.faces.append(face)
-
- #NMesh.PutRaw(newmesh)
- if deselface == 1:
- for unvert in origmesh.verts:
- newmesh.verts[unvert.index].sel = 0
- if makenewobj == 1:
- newobj = origobj.__copy__()
- newobj.link(newmesh)
- scene = Blender.Scene.GetCurrent()
- scene.objects.link(newobj)
- origobj.sel = 0
- else:
- origobj.link(newmesh)
-
- #Return to Editmode if previously in it
- if editmode: Window.EditMode(1)
-
-####################### gui ######################
-from Blender.BGL import *
-from Blender.Draw import *
-
-def ErrorText(errortext):
- Window.WaitCursor(0)
- Text(errortext)
- PupMenu("ERROR: %s" % errortext.lower())
-
-#Global Buttons
-makenewobject = Create(makenewobj)
-messagetext = Create(errortext)
-
-#Protrusion Buttons
-doprots = Create(makeprots)
-facechange = Create(faceschangedpercent*100)
-minheight = Create(minimumheight)
-maxheight = Create(maximumheight)
-sub1 = Create(subface1)
-sub2 = Create(subface2)
-sub3 = Create(subface3)
-sub4 = Create(subface4)
-mintaper = Create(minimumtaperpercent*100)
-maxtaper = Create(maximumtaperpercent*100)
-useselected = Create(useselectedfaces)
-selface1 = Create(selectface1)
-selface2 = Create(selectface2)
-selface3 = Create(selectface3)
-selface4 = Create(selectface4)
-deselectvertices = Create(deselface)
-#selectbyverts = Create(vertselected)
-
-#Doodad Buttons
-dodoodads = Create(makedoodads)
-doodadfacechange = Create(doodadfacepercent*100)
-seldoodad = Create(selectdoodad)
-onprot = Create(onlyonprotrusions)
-dood1 = Create(doodad1)
-dood2 = Create(doodad2)
-dood3 = Create(doodad3)
-dood4 = Create(doodad4)
-dood5 = Create(doodad5)
-dood6 = Create(doodad6)
-doodadminamount = Create(doodadminperface)
-doodadmaxamount = Create(doodadmaxperface)
-doodsizemin = Create(doodadminsize*100)
-doodsizemax = Create(doodadmaxsize*100)
-doodheightmin = Create(doodadminheight)
-doodheightmax = Create(doodadmaxheight)
-doodonselface = Create(doodonselectedfaces)
-seldoodtop = Create(selectdoodadtoponly)
-
-#Material Buttons
-assignNewMats = Create(reassignMats)
-replProtSideIndex = Create(protSideMat)
-replProtTopIndex = Create(protTopMat)
-replDoodSideIndex = Create(doodSideMat)
-replDoodTopIndex = Create(doodTopMat)
-
-# Events
-EVENT_NONE = 1
-EVENT_DISCOMBOBULATE = 2
-EVENT_EXIT = 3
-
-# Additions for moving gui
-hadd = 0
-wadd = 0
-thadd = 410
-phadd = 245
-pwadd = 0
-dhadd = 55
-dwadd = 0
-ghadd = 10
-gwadd = 0
-mhadd = 55
-mwadd = 312
-
-def colorbox(x,y,xright,bottom):
- glColor3f(0.75, 0.75, 0.75)
- glRecti(x + 1, y + 1, xright - 1, bottom - 1)
-
-firstDraw = 1
-
-def draw():
-
- #Protrusions
- global doprots
- global facechange
- global minheight
- global maxheight
- global sub1
- global sub2
- global sub3
- global sub4
- global mintaper
- global maxtaper
- global useselected
- global selface1
- global selface2
- global selface3
- global selface4
- global deselectvertices
- #global selectbyverts
-
- #Doodads
- global dodoodads
- global doodadfacechange
- global seldoodad
- global onprot
- global dood1
- global dood2
- global dood3
- global dood4
- global dood5
- global dood6
- global doodadminamount
- global doodadmaxamount
- global doodsizemin
- global doodsizemax
- global doodheightmin
- global doodheightmax
- global doodonselface
- global seldoodtop
-
- #Materials
- global assignNewMats
- global replProtSideIndex
- global replProtTopIndex
- global replDoodSideIndex
- global replDoodTopIndex
-
- #Global Settings
- global makenewobject
- global messagetext
- global errortext
- global EVENT_NONE,EVENT_DRAW,EVENT_EXIT,EVENT_UP,EVENT_DOWN,EVENT_LEFT,EVENT_RIGHT
-
- # Additions for moving gui
- global hadd
- global wadd
- global thadd
- global phadd
- global pwadd
- global dhadd
- global dwadd
- global ghadd
- global gwadd
- global mhadd
- global mwadd
-
- #This is for creating the initial layout
- global firstDraw
- if(firstDraw == 1):
- if(((Window.GetAreaSize()[1])*1.7) < Window.GetAreaSize()[0]):
- thadd = 180
- phadd = 10
- dhadd = 10
- mhadd = 55
- ghadd = 10
- pwadd = 0
- dwadd = 305
- mwadd = 610
- gwadd = 610
- else:
- thadd = 505
- phadd = 346
- dhadd = 160
- mhadd = 56
- ghadd = 10
- pwadd = 0
- dwadd = 0
- mwadd = 0
- gwadd = 0
- firstDraw = 0
-
-
- #Title :420high
- glClearColor(0.6, 0.6, 0.6, 1.0)
- glClear(GL_COLOR_BUFFER_BIT)
- glColor3f(0.0,0.0,0.0)
- glRasterPos2d(8+wadd, thadd+hadd)
- Text("Discombobulator v2.1b")
-
- #Protrusion
- colorbox(8+pwadd+wadd,150+phadd+hadd,312+pwadd+wadd,phadd-5+hadd)
- glColor3f(0.0,0.0,0.0)
- glRasterPos2d(12+pwadd+wadd, 140+phadd+hadd)
- Text("Protrusions:")
- doprots = Toggle("Make Protrusions",EVENT_NONE,12+pwadd+wadd,117+phadd+hadd,145,18,doprots.val,"Make Protrusions?")
- facechange = Number("Face %: ",EVENT_NONE,162+pwadd+wadd,117+phadd+hadd,145,18,facechange.val,0,100,"Percentage of faces that will grow protrusions")
- useselected = Toggle("Only selected faces",EVENT_NONE,12+pwadd+wadd,97+phadd+hadd,145,18,useselected.val,"If on, only selected faces will be modified")
- deselectvertices = Toggle("Deselect Selected",EVENT_NONE,162+pwadd+wadd,97+phadd+hadd,145,18,deselectvertices.val,"Deselects any selected vertex except for ones selected by \"Select Tops\"")
-
- #Protrusion properties
- glColor3f(0.0,0.0,0.0)
- glRasterPos2d(12+pwadd+wadd, 80+phadd+hadd)
- Text("Protrusion Properties:")
- BeginAlign()
- minheight = Number("Min Height: ",EVENT_NONE,12+pwadd+wadd,57+phadd+hadd,145,18,minheight.val,-100.0,100.0,"Minimum height of any protrusion")
- maxheight = Number("Max Height: ",EVENT_NONE,162+pwadd+wadd,57+phadd+hadd,145,18,maxheight.val,-100.0,100.0,"Maximum height of any protrusion")
- EndAlign()
- BeginAlign()
- mintaper = Number("Min Taper %: ",EVENT_NONE,12+pwadd+wadd,37+phadd+hadd,145,18,mintaper.val,0,100,"Minimum taper percentage of protrusion")
- maxtaper = Number("Max Taper %: ",EVENT_NONE,162+pwadd+wadd,37+phadd+hadd,145,18,maxtaper.val,0,100,"Maximum taper percentage of protrusion")
- EndAlign()
- glRasterPos2d(19+pwadd+wadd, 22+phadd+hadd)
- Text("Number of protrusions:")
- BeginAlign()
- sub1 = Toggle("1",EVENT_NONE,12+pwadd+wadd,phadd+hadd,34,18,sub1.val,"One Protrusion")
- sub2 = Toggle("2",EVENT_NONE,48+pwadd+wadd,phadd+hadd,34,18,sub2.val,"Two Protrusions")
- sub3 = Toggle("3",EVENT_NONE,84+pwadd+wadd,phadd+hadd,34,18,sub3.val,"Three Protrusions")
- sub4 = Toggle("4",EVENT_NONE,120+pwadd+wadd,phadd+hadd,34,18,sub4.val,"Four Protrusions")
- EndAlign()
- glRasterPos2d(195+pwadd+wadd, 22+phadd+hadd)
- Text("Select tops of:")
- BeginAlign()
- selface1 = Toggle("1",EVENT_NONE,165+pwadd+wadd,phadd+hadd,34,18,selface1.val,"Select the tip of the protrusion when it is created")
- selface2 = Toggle("2",EVENT_NONE,201+pwadd+wadd,phadd+hadd,34,18,selface2.val,"Select the tips of each protrusion when they are created")
- selface3 = Toggle("3",EVENT_NONE,237+pwadd+wadd,phadd+hadd,34,18,selface3.val,"Select the tips of each protrusion when they are created")
- selface4 = Toggle("4",EVENT_NONE,273+pwadd+wadd,phadd+hadd,34,18,selface4.val,"Select the tips of each protrusion when they are created")
- EndAlign()
- #Doodads
- colorbox(8+dwadd+wadd,175+dhadd+hadd,312+dwadd+wadd,dhadd-5+hadd)
- glColor3f(0.0,0.0,0.0)
- glRasterPos2d(12+dwadd+wadd, 165+dhadd+hadd)
- Text("Doodads:")
- BeginAlign()
- dood1 = Toggle("1 Box",EVENT_NONE,12+dwadd+wadd,142+dhadd+hadd,45,18,dood1.val,"Creates a rectangular box")
- dood2 = Toggle("2 Box",EVENT_NONE,61+dwadd+wadd,142+dhadd+hadd,45,18,dood2.val,"Creates 2 side-by-side rectangular boxes")
- dood3 = Toggle("3 Box",EVENT_NONE,110+dwadd+wadd,142+dhadd+hadd,45,18,dood3.val,"Creates 3 side-by-side rectangular boxes")
- EndAlign()
- BeginAlign()
- dood4 = Toggle("\"L\"",EVENT_NONE,164+dwadd+wadd,142+dhadd+hadd,45,18,dood4.val,"Creates a Tetris-style \"L\" shape")
- dood5 = Toggle("\"T\"",EVENT_NONE,213+dwadd+wadd,142+dhadd+hadd,45,18,dood5.val,"Creates a Tetris-style \"T\" shape")
- dood6 = Toggle("\"S\"",EVENT_NONE,262+dwadd+wadd,142+dhadd+hadd,45,18,dood6.val,"Creates a sort-of \"S\" or \"Z\" shape")
- EndAlign()
- dodoodads = Toggle("Make Doodads",EVENT_NONE,12+dwadd+wadd,120+dhadd+hadd,145,18,dodoodads.val,"Make Doodads?")
- doodadfacechange = Number("Face %: ",EVENT_NONE,162+dwadd+wadd,120+dhadd+hadd,145,18,doodadfacechange.val,0,100,"Percentage of faces that will gain doodads")
- seldoodad = Toggle("Select Doodads",EVENT_NONE,12+dwadd+wadd,100+dhadd+hadd,145,18,seldoodad.val,"Selects doodads when they are created")
- seldoodtop = Toggle("Only Select Tops",EVENT_NONE,162+dwadd+wadd,100+dhadd+hadd,145,18,seldoodtop.val,"Only Selects tops of doodads when\"Select Doodads\" is on")
- doodonselface = Toggle("Only selected faces",EVENT_NONE,12+dwadd+wadd,80+dhadd+hadd,145,18,doodonselface.val,"Only create doodads on selected faces")
- onprot = Toggle("Only on Protrusions",EVENT_NONE,162+dwadd+wadd,80+dhadd+hadd,145,18,onprot.val,"Only place doodads on protrusions")
-
- #Doodad Properties
- glColor3f(0.0,0.0,0.0)
- glRasterPos2d(12+dwadd+wadd, 63+dhadd+hadd)
- Text("Doodad Properties:")
- BeginAlign()
- doodadminamount = Number("Min Amount: ",EVENT_NONE,12+dwadd+wadd,40+dhadd+hadd,145,18,doodadminamount.val,0,100,"Minimum number of doodads per face")
- doodadmaxamount = Number("Max Amount: ",EVENT_NONE,162+dwadd+wadd,40+dhadd+hadd,145,18,doodadmaxamount.val,0,100,"Maximum number of doodads per face")
- EndAlign()
- BeginAlign()
- doodheightmin = Number("Min Height: ",EVENT_NONE,12+dwadd+wadd,20+dhadd+hadd,145,18,doodheightmin.val,0.0,100.0,"Minimum height of any doodad")
- doodheightmax = Number("Max Height: ",EVENT_NONE,162+dwadd+wadd,20+dhadd+hadd,145,18,doodheightmax.val,0.0,100.0,"Maximum height of any doodad")
- EndAlign()
- BeginAlign()
- doodsizemin = Number("Min Size %: ",EVENT_NONE,12+dwadd+wadd,dhadd+hadd,145,18,doodsizemin.val,0.0,100.0,"Minimum size of any doodad in percentage of face")
- doodsizemax = Number("Max Size %: ",EVENT_NONE,162+dwadd+wadd,dhadd+hadd,145,18,doodsizemax.val,0.0,100.0,"Maximum size of any doodad in percentage of face")
- EndAlign()
-
- #Materials
- colorbox(8+mwadd+wadd,93+mhadd+hadd,312+mwadd+wadd,mhadd-5+hadd)
- glColor3f(0.0,0.0,0.0)
- glRasterPos2d(12+mwadd+wadd, 83+mhadd+hadd)
- Text("Materials:")
- glRasterPos2d(12+mwadd+wadd, 43+mhadd+hadd)
- Text("Assigned Material Indices:")
- assignNewMats = Toggle("Assign materials by part",EVENT_NONE,32+mwadd+wadd,60+mhadd+hadd,256,18,assignNewMats.val,"Otherwise, previous materials will be preserved")
- replProtSideIndex = Number("Protrusion Sides:",EVENT_NONE,12+mwadd+wadd,20+mhadd+hadd,145,18,replProtSideIndex.val,0,16,"Material index assigned to sides of protrusions")
- replProtTopIndex = Number("Protrusion Tops:",EVENT_NONE,162+mwadd+wadd,20+mhadd+hadd,145,18,replProtTopIndex.val,0,16,"Material index assigned to tops of protrusions")
- replDoodSideIndex = Number("Doodad Sides:",EVENT_NONE,12+mwadd+wadd,mhadd+hadd,145,18,replDoodSideIndex.val,0,16,"Material index assigned to sides of doodads")
- replDoodTopIndex = Number("Doodad Tops:",EVENT_NONE,162+mwadd+wadd,mhadd+hadd,145,18,replDoodTopIndex.val,0,16,"Material index assigned to tops and bottoms of doodads")
-
- #Global Parts
- colorbox(8+gwadd+wadd,35+ghadd+hadd,312+gwadd+wadd,ghadd-5+hadd)
- glColor3f(1.0,0.0,0.0)
- glRasterPos2d(12+gwadd+wadd,25+ghadd+hadd)
- messagetext = Text(errortext)
- glColor3f(0.0,0.0,0.0)
- makenewobject = Toggle("Copy Before Modifying",EVENT_NONE,162+gwadd+wadd,ghadd+hadd,145,18,makenewobject.val,"If selected, the original object will be copied before it is changed")
- Button("Discombobulate",EVENT_DISCOMBOBULATE,12+gwadd+wadd,ghadd+hadd,100,18)
- Button("Exit",EVENT_EXIT,120+gwadd+wadd,ghadd+hadd,30,18)
-
-def event(evt, val):
- global wadd
- global hadd
-
- if (evt == RIGHTARROWKEY and val):
- wadd = wadd + 20
- Redraw(1)
- if (evt == LEFTARROWKEY and val):
- wadd = wadd - 20
- Redraw(1)
- if (evt == UPARROWKEY and val):
- hadd = hadd + 20
- Redraw(1)
- if (evt == DOWNARROWKEY and val):
- hadd = hadd - 20
- Redraw(1)
- if (evt == QKEY and not val):
- Exit()
-
-def bevent(evt):
-
- #Protrusions
- global doprots
- global facechange
- global minheight
- global maxheight
- global sub1
- global sub2
- global sub3
- global sub4
- global mintaper
- global maxtaper
- global useselected
- global selface1
- global selface2
- global selface3
- global selface4
- global deselectvertices
- #global selectbyverts
-
- #Doodads
- global dodoodads
- global doodadfacechange
- global seldoodad
- global onprot
- global dood1
- global dood2
- global dood3
- global dood4
- global dood5
- global dood6
- global doodadminamount
- global doodadmaxamount
- global doodsizemin
- global doodsizemax
- global doodheightmin
- global doodheightmax
- global doodonselface
- global seldoodtop
-
- #Materials
- global assignNewMats
- global replProtSideIndex
- global replProtTopIndex
- global replDoodSideIndex
- global replDoodTopIndex
-
- #Global Settings
- global makenewobject
- global messagetext
- global errortext
- global EVENT_NONE,EVENT_DRAW,EVENT_EXIT
-
- ######### Manages GUI events
- if evt==EVENT_EXIT:
- Exit()
- elif evt==EVENT_DISCOMBOBULATE:
- Window.WaitCursor(1)
- setProtrusionValues(doprots.val,facechange.val/100,minheight.val,maxheight.val,sub1.val,sub2.val,sub3.val,sub4.val,mintaper.val/100,maxtaper.val/100,useselected.val,selface1.val,selface2.val,selface3.val,selface4.val,deselectvertices.val)
- setDoodadValues(dodoodads.val,doodadfacechange.val/100,seldoodad.val,onprot.val,dood1.val,dood2.val,dood3.val,dood4.val,dood5.val,dood6.val,doodadminamount.val,doodadmaxamount.val,doodsizemin.val/100,doodsizemax.val/100,doodheightmin.val,doodheightmax.val,doodonselface.val,seldoodtop.val)
- setOtherValues(makenewobject.val,assignNewMats.val,replProtSideIndex.val,replProtTopIndex.val,replDoodSideIndex.val,replDoodTopIndex.val)
- discombobulate()
- Window.WaitCursor(0)
- Blender.Redraw()
-
-Register(draw, event, bevent)
diff --git a/release/scripts/envelope_symmetry.py b/release/scripts/envelope_symmetry.py
deleted file mode 100644
index a72e8c060b4..00000000000
--- a/release/scripts/envelope_symmetry.py
+++ /dev/null
@@ -1,174 +0,0 @@
-#!BPY
-
-"""
-Name: 'Envelope Symmetry'
-Blender: 234
-Group: 'Animation'
-Tooltip: 'Make envelope symmetrical'
-"""
-
-__author__ = "Jonas Petersen"
-__url__ = ("blender", "blenderartists.org", "Script's homepage, http://www.mindfloaters.de/blender/", "thread at blender.org, http://www.blender.org/modules.php?op=modload&name=phpBB2&file=viewtopic&t=4858 ")
-__version__ = "0.9 2004-11-10"
-__doc__ = """\
-This script creates perfectly symmetrical envelope sets. It is part of the
-envelop assignment tools.
-
-"Envelopes" are Mesh objects with names following this naming convention:
-
-<bone name>:<float value>
-
-Please check the script's homepage and the thread at blender.org (last link button above) for more info.
-
-For this version users need to edit the script code to change default options.
-"""
-
-# --------------------------------------------------------------------------
-# "Envelope Symmetry" by Jonas Petersen
-# Version 0.9 - 10th November 2004 - first public release
-# --------------------------------------------------------------------------
-#
-# A script for creating perfectly symmetrical envelope sets. It is
-# part of the envelope assignment tool.
-#
-# It is available in Object Mode via the menu item:
-#
-# Object -> Scripts -> Envelope Symmetry
-#
-# With default settings it will:
-#
-# - Look for bones
-#
-# Find the latest version at: http://www.mindfloaters.de/blender/
-#
-# --------------------------------------------------------------------------
-# $Id$
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004: Jonas Petersen, jonas at mindfloaters dot de
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-# --------------------------------------------------------------------------
-# CONFIGURATION
-# --------------------------------------------------------------------------
-
-# Note: Theses values will later be editable via a gui interface
-# within Blender.
-
-# The suffix for the reference and opposite envelope.
-# The configuration of of the opposite envelope will be overwritten by
-# the configuration of the reference envelope (shape, position, bone, weight).
-# The default is REF_SUFFIX = '.L' and OPP_SUFFIX = '.R'.
-REF_SUFFIX = '.R'
-OPP_SUFFIX = '.L'
-
-# MIRROR_AXIS defines the axis in which bones are mirrored/aligned.
-# Values:
-# 0 for X (default)
-# 1 for Y
-# 2 for Z
-MIRROR_AXIS = 0
-
-# SEPARATOR is the character used to delimit the bone name and the weight
-# in the envelope name.
-SEPARATOR = ":"
-
-# --------------------------------------------------------------------------
-# END OF CONFIGURATION
-# --------------------------------------------------------------------------
-
-import Blender, math, sys
-from Blender import Mathutils
-from BPyNMesh import *
-
-def flipFace(v):
- if len(v) == 3: v[0], v[1], v[2] = v[2], v[1], v[0]
- elif len(v) == 4: v[0], v[1], v[2], v[3] = v[3], v[2], v[1], v[0]
-
-# return object with given object name (with variable parts) and mesh name
-def getObjectByName(obj_name, mesh_name):
- for obj in Blender.Scene.GetCurrent().objects:
- if obj.type == "Mesh":
-# if obj.getName()[0:len(obj_name)] == obj_name and obj.getData().name == mesh_name:
- # use only mesh_name so bone name and weight (in the envelope name)
- # can be changed by the user and mirrored by the script.
- if obj.getData(name_only=1) == mesh_name:
- return obj
- return False
-
-SUFFIX_LEN = len(REF_SUFFIX);
-
-Blender.Window.EditMode(0)
-
-count = 0
-for obj in Blender.Scene.GetCurrent().objects:
- if obj.type != 'Mesh':
- continue
-
- count += 1
- name = obj.name
- pos = name.find(SEPARATOR)
- if (pos > -1):
- ApplySizeAndRotation(obj)
-
- base_name = name[0:pos-SUFFIX_LEN]
- suffix = name[pos-SUFFIX_LEN:pos]
- weight = name[pos:len(name)] # the SEPARATOR following a float value
-
- if suffix == REF_SUFFIX:
- mesh = obj.getData()
- mirror_name = base_name + OPP_SUFFIX + weight
- mirror_mesh_name = mesh.name + ".mirror"
-
- mirror_obj = getObjectByName(base_name + OPP_SUFFIX, mirror_mesh_name)
-
- if mirror_obj:
-
- # update vertices
-
- mirror_mesh = mirror_obj.getData()
- for i in xrange(len(mesh.verts)):
- org = mesh.verts[i]
- mir = mirror_mesh.verts[i]
- mir.co[0], mir.co[1], mir.co[2] = org.co[0], org.co[1], org.co[2]
- mir.co[MIRROR_AXIS] *= -1
-
- mirror_mesh.update()
- else:
-
- # create mirror object
-
- mirror_mesh = obj.data
- for face in mirror_mesh.faces:
- flipFace(face.v)
- for vert in mirror_mesh.verts:
- vert.co[MIRROR_AXIS] *= -1
-
- mirror_obj = Blender.NMesh.PutRaw(mirror_mesh, mirror_mesh_name)
-
- # update name, drawType and location
-
- mirror_obj.setName(mirror_name)
- mirror_obj.drawType = obj.drawType
-
- loc = [obj.LocX, obj.LocY, obj.LocZ]
- loc[MIRROR_AXIS] *= -1
- mirror_obj.setLocation(loc)
-
-Blender.Window.EditMode(0)
diff --git a/release/scripts/export-iv-0.1.py b/release/scripts/export-iv-0.1.py
deleted file mode 100644
index 647dd9c5518..00000000000
--- a/release/scripts/export-iv-0.1.py
+++ /dev/null
@@ -1,304 +0,0 @@
-#!BPY
-
-"""
-Name: 'OpenInventor (.iv)...'
-Blender: 236
-Group: 'Export'
-Tip: 'Export to OpenInventor file format. (.iv)'
-"""
-__author__ = ("Radek Barton")
-__url__ = ["http://blackhex.no-ip.org/"]
-__email__ = ["scripts"]
-__version__ = "0.1"
-
-
-__bpydoc__ = """\
-This script exports to the Open Inventor format.
-
-Usage:
-
-Run this script from "File->Export" menu.
-
-Note:
-"""
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Radek 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 *****
-#
-
-import Blender
-math_pi= 3.1415926535897931
-
-def WriteHeader(file):
- file.write("#Inventor V2.1 ascii\n\n")
- file.write("Separator\n")
- file.write("{\n")
- file.write(" ShapeHints\n")
- file.write(" {\n")
- file.write(" vertexOrdering COUNTERCLOCKWISE\n")
- file.write(" }\n")
-
-def WriteFooter(file):
- file.write("}\n")
-
-def WriteMesh(file, ob):
- file.write(" Separator\n")
- file.write(" {\n")
- file.write(" # %s\n" % ob.name)
- WriteMatrix(file, ob)
- mesh = ob.getData()
- WriteMaterials(file, mesh)
- WriteTexture(file, mesh)
- WriteNormals(file, mesh)
- WriteVertices(file, mesh)
- WriteFaces(file, mesh)
- file.write(" }\n")
-
-def WriteMatrix(file, ob):
- matrix = ob.getMatrix()
- file.write(" MatrixTransform\n")
- file.write(" {\n")
- file.write(" matrix\n")
- for line in matrix:
- file.write(" %.6f %.6f %.6f %.6f\n" % (line[0], line[1], line[2], line[3]))
- file.write(" }\n")
-
-def WriteColors(file, mesh):
- file.write(" vertexProperty VertexProperty\n")
- file.write(" {\n")
- file.write(" orderedRGBA\n")
- file.write(" [\n")
- for face in mesh.faces:
- for I in xrange(len(face)):
- file.write(" 0x%02x%02x%02x%02x,\n" % (face.col[I].r,
- face.col[I].g, face.col[I].b, face.col[I].a))
- file.write(" ]\n")
- file.write(" materialBinding PER_VERTEX\n")
- file.write(" }\n")
-
-def WriteMaterials(file, mesh):
- if mesh.materials:
- file.write(" Material\n")
- file.write(" {\n")
- file.write(" ambientColor\n")
- file.write(" [\n")
- for mat in mesh.materials:
- file.write(" %.6f %.6f %.6f,\n" % (mat.mirCol[0], mat.mirCol[1],
- mat.mirCol[2]))
- file.write(" ]\n")
- file.write(" diffuseColor\n")
- file.write(" [\n")
- for mat in mesh.materials:
- file.write(" %.6f %.6f %.6f,\n" % (mat.rgbCol[0], mat.rgbCol[1],
- mat.rgbCol[2]))
- file.write(" ]\n")
- file.write(" specularColor\n")
- file.write(" [\n")
- for mat in mesh.materials:
- file.write(" %.6f %.6f %.6f,\n" % (mat.specCol[0] * mat.spec / 2.0,
- mat.specCol[1] * mat.spec / 2.0, mat.specCol[2] * mat.spec / 2.0))
- file.write(" ]\n")
- file.write(" emissiveColor\n")
- file.write(" [\n")
- for mat in mesh.materials:
- file.write(" %.6f %.6f %.6f,\n" % (mat.rgbCol[0] * mat.emit,
- mat.rgbCol[1] * mat.emit, mat.rgbCol[0] * mat.emit))
- file.write(" ]\n")
- file.write(" shininess\n")
- file.write(" [\n")
- for mat in mesh.materials:
- file.write(" %.6f,\n" % (mat.hard / 255.0))
- file.write(" ]\n")
- file.write(" transparency\n")
- file.write(" [\n")
- for mat in mesh.materials:
- file.write(" %.6f,\n" % (1.0 - mat.alpha))
- file.write(" ]\n")
- file.write(" }\n")
- file.write(" MaterialBinding\n")
- file.write(" {\n")
- file.write(" value PER_FACE_INDEXED\n")
- file.write(" }\n")
-
-def WriteTexture(file, mesh):
- texture = mesh.faces[0].image # BAD Ju Ju
- if texture:
- file.write(" Texture2\n")
- file.write(" {\n")
- file.write(' filename "%s"\n' % texture.getName())
- file.write(" }\n")
- file.write(" TextureCoordinate2\n")
- file.write(" {\n")
- file.write(" point\n")
- file.write(" [\n")
- if mesh.hasVertexUV():
- for vert in mesh.verts:
- file.write(" %s %s,\n" % (vert.uvco[0], vert.uvco[1]))
- file.write(" ]\n")
- file.write(" }\n")
- file.write(" TextureCoordinateBinding\n")
- file.write(" {\n")
- file.write(" value PER_VERTEX_INDEXED\n")
- file.write(" }\n")
- elif mesh.hasFaceUV():
- for face in mesh.faces:
- for uv in face.uv:
- file.write(" %.6f %.6f,\n" % (uv[0], uv[1]))
- file.write(" ]\n")
- file.write(" }\n")
- file.write(" TextureCoordinateBinding\n")
- file.write(" {\n")
- file.write(" value PER_VERTEX\n")
- file.write(" }\n")
-
-def WriteVertices(file, mesh):
- file.write(" Coordinate3\n")
- file.write(" {\n")
- file.write(" point\n")
- file.write(" [\n")
- for vert in mesh.verts:
- file.write(" %.6f %.6f %.6f,\n" % (vert[0], vert[1], vert[2]))
- file.write(" ]\n")
- file.write(" }\n")
-
-def WriteNormals(file, mesh):
- file.write(" Normal\n")
- file.write(" {\n")
- file.write(" vector\n")
- file.write(" [\n")
-
- # make copy of vertex normals
- normals = []
- for face in mesh.faces:
- if len(face.v) in [3, 4]:
- if face.smooth:
- for v in face.v:
- normals.append(v.no)
- else:
- for v in face.v:
- normals.append(face.no)
-
- # write normals
- for no in normals:
- file.write(" %.6f %.6f %.6f,\n" % (no[0], no[1], no[2]))
- file.write(" ]\n")
- file.write(" }\n")
-
- # write way how normals are binded
- file.write(" NormalBinding\n")
- file.write(" {\n")
- file.write(" value PER_VERTEX\n")
- file.write(" }\n")
-
-def WriteFaces(file, mesh):
- file.write(" IndexedFaceSet\n")
- file.write(" {\n")
-
- # write vertex paint
- if mesh.hasVertexColours():
- WriteColors(file, mesh)
-
- # write material indexes
- file.write(" materialIndex\n")
- file.write(" [\n")
- for face in mesh.faces:
- file.write(" %i,\n" % face.mat);
- file.write(" ]\n")
-
- # write faces with coordinate indexes
- file.write(" coordIndex\n")
- file.write(" [\n")
- for face in mesh.faces:
- face_v= face.v
- if len(face_v) == 3:
- file.write(" %i, %i, %i, -1,\n" % (face_v[0].index,
- face_v[1].index, face_v[2].index))
- elif len(face_v) == 4:
- file.write(" %i, %i, %i, %i, -1,\n" % (face_v[0].index,
- face_v[1].index, face_v[2].index, face_v[3].index))
- file.write(" ]\n")
- file.write(" }\n")
-
-
-def WriteCamera(file, ob):
- camera = ob.getData();
- # perspective camera
- if camera.type == 0:
- file.write(" PerspectiveCamera\n")
- file.write(" {\n")
- file.write(" nearDistance %s\n" % (camera.clipStart))
- file.write(" farDistance %s\n" % (camera.clipEnd))
- file.write(" }\n")
- # ortho camera
- else:
- print camera.type
-
-def WriteLamp(file, ob):
- lamp = ob.getData();
- # spot lamp
- if lamp.type == 2:
- file.write(" SpotLight\n")
- file.write(" {\n")
- file.write(" intensity %s\n" % (lamp.energy / 10.0))
- file.write(" color %s %s %s\n" % (lamp.col[0], lamp.col[1], lamp.col[2]))
- #file.write(" location %s\n" % ())
- #file.write(" direction %s\n" % ())
- file.write(" dropOffRate %s\n" % (lamp.spotBlend))
- file.write(" cutOffAngle %s\n" % (lamp.spotSize * math_pi / 180.0))
- file.write(" }\n")
-
-# script main function
-def ExportToIv(file_name):
- scene = Blender.Scene.GetCurrent()
- file = open(file_name, "w")
-
- # make lists of individual ob types
- meshes = []
- lamps = []
- cameras = []
- for ob in scene.objects:
- obtype= ob.type
- if obtype == "Mesh":
- meshes.append(ob);
- #elif obtype == "Lamp":
- # lamps.append(ob);
- #elif obtype == "Camera":
- # cameras.append(ob);
- #else:
- # print "Exporting %s objects isn't supported!" % ob.type
-
- # write header, footer and groups of ob types
- WriteHeader(file);
- #for camera in cameras:
- # WriteCamera(file, camera);
- #for lamp in lamps:
- # WriteLamp(file, lamp)
- for mesh in meshes:
- WriteMesh(file, mesh)
- WriteFooter(file)
-
- file.close()
-
-def FileSelectorCB(file_name):
- if not file_name.lower().endswith('.iv'):
- file_name += '.iv'
- ExportToIv(file_name)
-
-if __name__ == '__main__':
- Blender.Window.FileSelector(FileSelectorCB, "Export IV", Blender.sys.makename(ext='.iv'))
diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py
deleted file mode 100644
index 17f2132fbe8..00000000000
--- a/release/scripts/export_dxf.py
+++ /dev/null
@@ -1,3041 +0,0 @@
-#!BPY
-
-"""
- Name: 'Autodesk DXF (.dxf/dwg)'
- Blender: 249
- Group: 'Export'
- Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).'
-"""
-
-__version__ = "1.35 - 2009.06.18"
-__author__ = "Remigiusz Fiedler (AKA migius)"
-__license__ = "GPL"
-__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf"
-__bpydoc__ ="""The script exports Blender geometry to DXF format r12 version.
-
-Version %s
-Copyright %s
-License %s
-
-extern dependances: dxfLibrary.py, dxfColorMap.py (optionaly: DConvertCon.exe)
-
-CONTRIBUTORS:
-Remigiusz Fiedler (AKA migius)
-Alexandros Sigalas (AKA alxarch)
-Stani Michiels (AKA stani)
-
-See the homepage for documentation.
-url: %s
-
-IDEAs:
-- HPGL output, usefull for correct scaled printing of 2d drawings
-
-TODO:
-- export dupligroups and dupliverts as blocks (as option)
-- optimize POLYFACE routine: remove double-vertices
-- fix support for X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert()
-- support hierarchies: groups, instances, parented structures
-- support n/f-gons as POLYFACEs with invisible edges
-- mapping materials to DXF-styles
-- ProgressBar
-- export rotation of Camera to VIEW/VPORT
-- export parented Cameras to VIEW/VPORT
-- wip: write drawing extends for automatic view positioning in CAD
-- wip: fix text-objects in persp-projection
-- wip: translate current 3D-View to *ACTIVE-VPORT
-- wip: fix support Include-Duplis, cause not conform with INSERT-method
-
-History
-v1.35 - 2009.06.18 by migius
-- export multiple-instances of Curve-Objects as BLOCK/INSERTs
-- added export Cameras (ortho and persp) to VPORTs, incl. clipping
-- added export Cameras (ortho and persp) to VIEWs, incl. clipping
-- export multiple-instances of Mesh-Objects as BLOCK/INSERTs
-- on start prints dxfLibrary version
-v1.34 - 2009.06.08 by migius
-- export Lamps and Cameras as POINTs
-- export passepartout for perspective projection
-- added option for export objects only from visible layers
-- optimized POLYFACE output: remove loose vertices in back-faces-mode
-- cleaning code
-- fix nasty bug in getExtrusion()
-- support text-objects, also in ortho/persp-projection
-- support XYmirrored 2d-curves to 2dPOLYLINEs
-- support thickness and elevation for curve-objects
-- fix extrusion 210-code (3d orientation vector)
-- fix POLYFACE export, synchronized also dxfLibrary.py
-- changed to the new 2.49 method Vector.cross()
-- output style manager (first try)
-v1.33 - 2009.05.25 by migius
-- bugfix flipping normals in mirrored mesh-objects
-- added UI-Button for future Shadow Generator
-- support curve objects in projection-2d mode
-- UI stuff: camera selector/manager
-v1.32 - 2009.05.22 by migius
-- debug mode for curve-objects: output redirect to Blender
-- wip support 210-code(extrusion) calculation
-- default settings for 2D and 3D export
-v1.31 - 2009.05.18 by migius
-- globals translated to GUI_A/B dictionary
-- optimizing back-faces removal for "hidden-lines" mode
-- presets for global location and scale (architecture)
-- UI layout: scrollbars, pan with MMB/WHEEL, dynamic width
-- new GUI with Draw.Register() from DXF-importer.py
-v1.30 - 2008.12.14 by migius
-- started work on GUI with Draw.Register()
-v1.29 - 2009.04.11 by stani
-- added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter
-v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch)
-- added option to apply modifiers on exported meshes
-- added option to also export duplicates (from dupliverts etc)
-v1.28 - 2008.10.22 by migius
-- workaround for PVert-bug on ubuntu (reported by Yorik)
-- add support for FGons - ignore invisible_tagged edges
-- add support for camera: ortho and perspective
-v1.27 - 2008.10.07 by migius
-- exclude Stani's DXF-Library to extern module
-v1.26 - 2008.10.05 by migius
-- add "hidden mode" substitut: back-faces removal
-- add support for mesh ->POLYFACE
-- optimized code for "Flat" procedure
-v1.25 - 2008.09.28 by migius
-- modif FACE class for r12
-- add mesh-polygon -> Bezier-curve converter (Yorik's code)
-- add support for curves ->POLYLINEs
-- add "3d-View to Flat" - geometry projection to XY-plane
-v1.24 - 2008.09.27 by migius
-- add start UI with preferences
-- modif POLYLINE class for r12
-- changing output format from r9 to r12(AC1009)
-v1.23 - 2008.09.26 by migius
-- add finish message-box
-v1.22 - 2008.09.26 by migius
-- add support for curves ->LINEs
-- add support for mesh-edges ->LINEs
-v1.21 - 2008.06.04 by migius
-- initial adaptation for Blender
-v1.1 (20/6/2005) by Stani Michiels www.stani.be/python/sdxf
-- Python library to generate dxf drawings
-______________________________________________________________
-""" % (__author__,__version__,__license__,__url__)
-
-# --------------------------------------------------------------------------
-# Script copyright (C) 2008 Remigiusz Fiedler (AKA migius)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-
-import Blender
-from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple
-from Blender import Registry, Object, Mesh, Curve
-import os
-import subprocess
-
-try:
- import dxfLibrary as DXF
- #reload(DXF)
- #reload(dxfLibrary)
- #from dxfLibrary import *
-except:
- DXF=None
- print "DXF-Exporter: error! found no dxfLibrary.py module in Blender script folder"
- Draw.PupMenu("Error%t|found no dxfLibrary.py module in script folder")
-
-
-import math
-from math import atan, atan2, log10, sin, cos
-
-#pi = math.pi
-#pi = 3.14159265359
-r2d = 180.0 / math.pi
-d2r = math.pi / 180.0
-#note: d2r * angle == math.radians(angle)
-#note: r2d * angle == math.degrees(angle)
-
-
-#DEBUG = True #activates debug mode
-
-
-#----globals------------------------------------------
-ONLYSELECTED = 1 # 0/1 = False/True
-ONLYVISIBLE = 1 # ignore objects on invisible layers
-POLYLINES = 1 # prefer POLYLINEs not LINEs
-POLYFACES = 1 # prefer POLYFACEs not 3DFACEs
-PROJECTION = 0 # output geometry will be projected to XYplane with Z=0.0
-HIDDEN_LINES = 0 #filter out hidden geometry
-SHADOWS = 0 # sun/shadows simulation
-CAMERA = 1 # selected camera index
-PERSPECTIVE = 0 # projection (camera) type: perspective, opposite to orthographic
-CAMERAVIEW = 0 # use camera for projection, opposite is 3d-view
-INSTANCES = 1 # Export instances of Mesh/Curve as BLOCK/INSERTs on/off
-APPLY_MODIFIERS = 1
-INCLUDE_DUPLIS = 0
-OUTPUT_DWG = 0 #optional save to DWG with extern converter
-
-G_SCALE = 1.0 #(0.0001-1000) global scaling factor for output dxf data
-G_ORIGIN = [0.0,0.0,0.0] #global translation-vector (x,y,z) in Blender units
-ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units
-
-BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults
-BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults
-PREFIX = 'BF_' #used as prefix for DXF names
-LAYERNAME_DEF = '' #default layer name
-LAYERCOLOR_DEF = 7 #default layer color index
-LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType
-ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index
-ENTITYCOLOR_DEF = BYLAYER #default entity color index
-ENTITYLTYPE_DEF = BYLAYER #default entity lineType
-
-E_M = 0
-LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction"
-M_OBJ = 0
-
-FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
-NAMELENGTH_MAX = 80 #max_obnamelength in DXF, (limited to 256? )
-INIFILE_DEFAULT_NAME = 'exportDXF'
-INIFILE_EXTENSION = '.ini'
-INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data'
-INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data'
-
-BLOCKREGISTRY = {} # registry and map for BLOCKs
-SCENE = None
-WORLDX = Mathutils.Vector((1,0,0))
-WORLDY = Mathutils.Vector((0,1,0))
-WORLDZ = Mathutils.Vector((0,0,1))
-
-AUTO = BezTriple.HandleTypes.AUTO
-FREE = BezTriple.HandleTypes.FREE
-VECT = BezTriple.HandleTypes.VECT
-ALIGN = BezTriple.HandleTypes.ALIGN
-
-
-#-------- DWG support ------------------------------------------
-extCONV_OK = True
-extCONV = 'DConvertCon.exe'
-extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV)
-if not os.path.isfile(extCONV_PATH):
- extCONV_OK = False
- extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
-Copy first %s into Blender script directory.|\
-More details in online Help.' %extCONV
-else:
- if not os.sys.platform.startswith('win'):
- # check if Wine installed:
- if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip():
- extCONV_PATH = 'wine %s'%extCONV_PATH
- else:
- extCONV_OK = False
- extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
-The external DWG-converter (%s) needs Wine installed on your system.|\
-More details in online Help.' %extCONV
-#print 'extCONV_PATH = ', extCONV_PATH
-
-
-#----------------------------------------------
-def updateMenuCAMERA():
- global CAMERAS
- global MenuCAMERA
- global MenuLIGHT
-
- scn = Scene.GetCurrent()
- objs = scn.getChildren()
- currcam = scn.getCurrentCamera()
- if currcam: currcam = currcam.getName()
- maincams = []
- MenuCAMERA = "Select Camera%t"
- for cam in objs:
- if cam.getType() == 'Camera':
- if cam.getName()[0:4] != "Temp":
- maincams.append(cam.getName())
- maincams.sort()
- maincams.reverse()
- CAMERAS = maincams
- for i, cam in enumerate(CAMERAS):
- if cam==currcam:
- MenuCAMERA += "|* " + cam
- else: MenuCAMERA += "| " + cam
- MenuCAMERA += "|current 3d-View"
- MenuLIGHT = "Select Sun%t| *todo"
-
-
-#----------------------------------------------
-def updateCAMERA():
- global CAMERA, GUI_A
- #CAMERA = 1
- scn = Scene.GetCurrent()
- currcam = scn.getCurrentCamera()
- if currcam: currcam = currcam.getName()
- if currcam in CAMERAS:
- CAMERA = CAMERAS.index(currcam)+1
- GUI_A['camera_selected'].val = CAMERA
-
-#----------------------------------------------
-def gotoCAMERA():
- cam = Object.Get(CAMERAS[CAMERA-1])
- #print 'deb: CAMERA, cam',CAMERA, cam
- if cam.getType() != 'Camera':
- sure = Draw.PupMenu("Info: %t| It is not a Camera Object.")
- else:
- scn = Scene.getCurrent()
- scn.setCurrentCamera(cam)
- Window.CameraView(0)
- Window.Redraw()
- updateMenuCAMERA()
-
-
-#------- Duplicates support ----------------------------------------------
-def dupTest(object):
- """
- Checks objects for duplicates enabled (any type)
- object: Blender Object.
- Returns: Boolean - True if object has any kind of duplicates enabled.
- """
- if (object.enableDupFrames or \
- object.enableDupGroup or \
- object.enableDupVerts):
- return True
- else:
- return False
-
-def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False):
- """
- Return a list of real objects and duplicates and optionally their matrices
- oblist: List of Blender Objects
- MATRICES: Boolean - Check to also get the objects matrices, default=False
- HACK: Boolean - See note, default=False
- Returns: List of objects or
- List of tuples of the form:(ob,matrix) if MATRICES is set to True
- NOTE: There is an ugly hack here that excludes all objects whose name
- starts with "dpl_" to exclude objects that are parented to a duplicating
- object, User must name objects properly if hack is used.
- """
-
- result = []
- for ob in oblist:
- if INCLUDE_DUPLIS and dupTest(ob):
- dup_obs=ob.DupObjects
- if len(dup_obs):
- for dup_ob, dup_mx in dup_obs:
- if MATRICES:
- result.append((dup_ob,dup_mx))
- else:
- result.append(dup_ob)
- else:
- if HACK:
- if ob.getName()[0:4] != "dpl_":
- if MATRICES:
- mx = ob.mat
- result.append((ob,mx))
- else:
- result.append(ob)
- else:
- if MATRICES:
- mx = ob.mat
- result.append((ob,mx))
- else:
- result.append(ob)
- return result
-
-#-----------------------------------------------------
-def hidden_status(faces, mx, mx_n):
- # sort out back-faces = with normals pointed away from camera
- #print 'HIDDEN_LINES: caution! not full implemented yet'
- front_faces = []
- front_edges = []
- for f in faces:
- #print 'deb: face=', f #---------
- #print 'deb: dir(face)=', dir(f) #---------
- # get its normal-vector in localCS
- vec_normal = f.no.copy()
- #print 'deb: vec_normal=', vec_normal #------------------
- # must be transfered to camera/view-CS
- vec_normal *= mx_n
- #vec_normal *= mb.rotationPart()
- #print 'deb:2vec_normal=', vec_normal #------------------
- #vec_normal *= mw0.rotationPart()
- #print 'deb:3vec_normal=', vec_normal, '\n' #------------------
-
-
- frontFace = False
- if not PERSPECTIVE: #for ortho mode ----------
- # normal must point the Z direction-hemisphere
- if vec_normal[2] > 0.00001:
- frontFace = True
- else:
- v = f.verts[0]
- vert = Mathutils.Vector(v.co) * mx
- if Mathutils.DotVecs(vert, vec_normal) < 0.00001:
- frontFace = True
-
- if frontFace:
- front_faces.append(f.index)
- for key in f.edge_keys:
- #this test can be done faster with set()
- if key not in front_edges:
- front_edges.append(key)
-
- #print 'deb: amount of visible faces=', len(front_faces) #---------
- #print 'deb: visible faces=', front_faces #---------
- #print 'deb: amount of visible edges=', len(front_edges) #---------
- #print 'deb: visible edges=', front_edges #---------
- return front_faces, front_edges
-
-
-#---- migration to 2.49-------------------------------------------------
-if 'cross' in dir(Mathutils.Vector()):
- #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!')
- def M_CrossVecs(v1,v2):
- return v1.cross(v2) #for up2.49
- def M_DotVecs(v1,v2):
- return v1.dot(v2) #for up2.49
-else:
- def M_CrossVecs(v1,v2):
- return Mathutils.CrossVecs(v1,v2) #for pre2.49
- def M_DotVecs(v1,v2):
- return Mathutils.DotVecs(v1,v2) #for pre2.49
-
-
-#-----------------------------------------------------
-def getExtrusion(matrix):
- """calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors
-
- """
- AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector
- Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]]
- if AZaxis[2]==1.0:
- Extrusion = None
- AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
- else:
- threshold = 1.0 / 64.0
- if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold:
- # AXaxis is the intersection WorldPlane and ExtrusionPlane
- AXaxis = M_CrossVecs(WORLDY,AZaxis)
- else:
- AXaxis = M_CrossVecs(WORLDZ,AZaxis)
- #print 'deb:\n' #-------------
- #print 'deb:getExtrusion() Extrusion=', Extrusion #---------
- return Extrusion, AXaxis.normalize()
-
-
-#-----------------------------------------------------
-def getZRotation(AXaxis, rot_matrix_invert):
- """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis
-
- """
- # this works: Xaxis is the obj.matrix-Xaxis vector
- # but not correct for all orientations
- #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
- ##Xaxis.normalize() # = ArbitraryXvector
- #ZRotation = - Mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians
-
- # this works for all orientations, maybe a bit faster
- # transform AXaxis into OCS:Object-Coord-System
- #rot_matrix = normalizeMat(matrix.rotationPart())
- #rot_matrix_invert = rot_matrix.invert()
- vec = AXaxis * rot_matrix_invert
- ##vec = AXaxis * matrix.copy().invert()
- ##vec.normalize() # not needed for atan2()
- #print '\ndeb:getExtrusion() vec=', vec #---------
- ZRotation = - atan2(vec[1],vec[0]) #output in radians
-
- #print 'deb:ZRotation() ZRotation=', ZRotation*r2d #---------
- return ZRotation
-
-
-#------------------------------------------
-def normalizeMat(matrix):
- mat12 = matrix.copy()
- mat12 = [Mathutils.Vector(v).normalize() for v in mat12]
- if len(mat12)>3:
- matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2],mat12[3])
- else:
- matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2])
- return matr12
-
-
-#-----------------------------------------------------
-def projected_co(verts, matrix):
- """ converts coordinates of points from OCS to WCS->ScreenCS
- needs matrix: a projection matrix
- needs verts: a list of vectors[x,y,z]
- returns a list of [x,y,z]
- """
- #print 'deb:projected_co() verts=', verts #---------
- temp_verts = [Mathutils.Vector(v)*matrix for v in verts]
- #print 'deb:projected_co() temp_verts=', temp_verts #---------
-
- if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val
- else: locZ = 0.0
-
- if PROJECTION:
- if PERSPECTIVE:
- clipStart = 10.0
- for v in temp_verts:
- coef = - clipStart / v[2]
- v[0] *= coef
- v[1] *= coef
- v[2] = locZ
- for v in temp_verts:
- v[2] = locZ
- temp_verts = [v[:3] for v in temp_verts]
- #print 'deb:projected_co() out_verts=', temp_verts #---------
- return temp_verts
-
-
-#-----------------------------------------------------
-def isLeftHand(matrix):
- #Is the matrix a left-hand-system, or not?
- ma = matrix.rotationPart()
- crossXY = M_CrossVecs(ma[0], ma[1])
- check = M_DotVecs(ma[2], crossXY)
- if check < 0.00001: return 1
- return 0
-
-
-#-----------------------------------------------------
-def exportMesh(ob, mx, mx_n, me=None, **common):
- """converts Mesh-Object to desired projection and representation(DXF-Entity type)
- """
- global BLOCKREGISTRY
- entities = []
- block = None
- #print 'deb:exportMesh() given common=', common #---------
- if me==None:
- me = ob.getData(mesh=1)
- else:
- me.getFromObject(ob)
- # idea: me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
- # the .transform-method is fast, but bad, cause invasive:
- # it manipulates original geometry and by retransformation lefts back rounding-errors
- # we dont want to manipulate original data!
- #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
- if me.verts:
- #print 'deb:exportMesh() started' #---------
-
- #print 'deb:exportMesh() ob.name=', ob.name #---------
- #print 'deb:exportMesh() me.name=', me.name #---------
- #print 'deb:exportMesh() me.users=', me.users #---------
- # check if there are more instances of this mesh (if used by other objects), then write to BLOCK/INSERT
- if GUI_A['instances_on'].val and me.users>1 and not PROJECTION:
- if me.name in BLOCKREGISTRY.keys():
- insert_name = BLOCKREGISTRY[me.name]
- # write INSERT to entities
- entities = exportInsert(ob, mx,insert_name, **common)
- else:
- # generate geom_output in ObjectCS
- allpoints = [v.co for v in me.verts]
- identity_matrix = Mathutils.Matrix().identity()
- allpoints = projected_co(allpoints, identity_matrix)
- #allpoints = toGlobalOrigin(allpoints)
- faces=[]
- edges=[]
- for e in me.edges: edges.append(e.key)
- faces = [[v.index for v in f.verts] for f in me.faces]
- entities = writeMeshEntities(allpoints, edges, faces, **common)
- if entities: # if not empty block
- # write BLOCK definition and INSERT entity
- # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
- BLOCKREGISTRY[me.name]=validDXFr12name(('ME_'+ me.name))
- insert_name = BLOCKREGISTRY[me.name]
- block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
- # write INSERT as entity
- entities = exportInsert(ob, mx, insert_name, **common)
-
- else: # no other instances, so go the standard way
- allpoints = [v.co for v in me.verts]
- allpoints = projected_co(allpoints, mx)
- allpoints = toGlobalOrigin(allpoints)
- faces=[]
- edges=[]
- if me.faces and PROJECTION and HIDDEN_LINES:
- #if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #---------
- faces, edges = hidden_status(me.faces, mx, mx_n)
- faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces]
- else:
- #if DEBUG: print 'deb:exportMesh STANDARD mode' #---------
- for e in me.edges: edges.append(e.key)
- #faces = [f.index for f in me.faces]
- faces = [[v.index for v in f.verts] for f in me.faces]
- #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces]
- #print 'deb: allpoints=\n', allpoints #---------
- #print 'deb: edges=\n', edges #---------
- #print 'deb: faces=\n', faces #---------
- if isLeftHand(mx): # then change vertex-order in every face
- for f in faces:
- f.reverse()
- #f = [f[-1]] + f[:-1] #TODO: might be needed
- #print 'deb: faces=\n', faces #---------
- entities = writeMeshEntities(allpoints, edges, faces, **common)
-
- return entities, block
-
-
-#-------------------------------------------------
-def writeMeshEntities(allpoints, edges, faces, **common):
- """help routine for exportMesh()
- """
- entities = []
-
- c = mesh_as_list[GUI_A['mesh_as'].val]
- if 'POINTs'==c: # export Mesh as multiple POINTs
- for p in allpoints:
- dxfPOINT = DXF.Point(points=[p],**common)
- entities.append(dxfPOINT)
- elif 'LINEs'==c or (not faces):
- if edges and allpoints:
- if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene
- for e in edges:
- points = [allpoints[e[0]], allpoints[e[1]]]
- dxfLINE = DXF.Line(points, **common)
- entities.append(dxfLINE)
- elif faces:
- if c in ('POLYFACE','POLYLINE'):
- if allpoints:
- #TODO: purge allpoints: left only vertices used by faces
- if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
- if not (PROJECTION and HIDDEN_LINES):
- faces = [[v+1 for v in f] for f in faces]
- else:
- # for back-Faces-mode remove face-free verts
- map=verts_state= [0]*len(allpoints)
- for f in faces:
- for v in f:
- verts_state[v]=1
- if 0 in verts_state: # if dirty state
- i,newverts=0,[]
- for used_i,used in enumerate(verts_state):
- if used:
- newverts.append(allpoints[used_i])
- map[used_i]=i
- i+=1
- allpoints = newverts
- faces = [[map[v]+1 for v in f] for f in faces]
- dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common)
- #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #-------------
- entities.append(dxfPOLYFACE)
- elif '3DFACEs'==c:
- if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
- for f in faces:
- #print 'deb: face=', f #---------
- points = [allpoints[key] for key in f]
- #points = [p.co[:3] for p in points]
- #print 'deb: pointsXX=\n', points #---------
- dxfFACE = DXF.Face(points, **common)
- entities.append(dxfFACE)
-
- return entities
-
-
-#-----------------------------------------------------
-def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
- #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
- ob = Object.New("Mesh",name)
- me = Mesh.New(name)
- #print 'deb: vertList=\n', vertList #---------
- #print 'deb: edgeList=\n', edgeList #---------
- #print 'deb: faceList=\n', faceList #---------
- me.verts.extend(vertList)
- if edgeList: me.edges.extend(edgeList)
- if faceList: me.faces.extend(faceList)
- if flatten:
- for v in me.verts: v.co.z = 0.0
- ob.link(me)
- if link:
- sce = Scene.getCurrent()
- sce.objects.link(ob)
- #me.triangleToQuad()
- if AT_CUR:
- cur_loc = Window.GetCursorPos()
- ob.setLocation(cur_loc)
- Blender.Redraw()
- #return ob
-
-#-----------------------------------------------------
-def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True):
- #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
- ob = Object.New("Curve",name)
- cu = Curve.New(name)
- #print 'deb: vertList=\n', vertList #---------
- curve = cu.appendNurb(BezTriple.New(vertList[0]))
- for p in vertList[1:]:
- curve.append(BezTriple.New(p))
- for point in curve:
- #point.handleTypes = [VECT, VECT]
- point.handleTypes = [FREE, FREE]
- point.radius = 1.0
- curve.flagU = closed # 0 sets the curve not cyclic=open
- cu.setResolu(6)
- cu.update() #important for handles calculation
- if flatten:
- for v in cu.verts: v.co.z = 0.0
- ob.link(cu)
- if link:
- sce = Scene.getCurrent()
- sce.objects.link(ob)
- #me.triangleToQuad()
- if AT_CUR:
- cur_loc = Window.GetCursorPos()
- ob.setLocation(cur_loc)
- elif org_point:
- cur_loc=org_point
- ob.setLocation(cur_loc)
- Blender.Redraw()
- #return ob
-
-
-#-----------------------------------------------------
-def toGlobalOrigin(points):
- """relocates points to the new location
- needs a list of points [x,y,z]
- """
- if GUI_A['g_origin_on'].val:
- for p in points:
- p[0] += G_ORIGIN[0]
- p[1] += G_ORIGIN[1]
- p[2] += G_ORIGIN[2]
- return points
-
-
-#-----------------------------------------------------
-def exportEmpty(ob, mx, mw, **common):
- """converts Empty-Object to desired projection and representation(DXF-Entity type)
- """
- p = Mathutils.Vector(ob.loc)
- [p] = projected_co([p], mx)
- [p] = toGlobalOrigin([p])
-
- entities = []
- c = empty_as_list[GUI_A['empty_as'].val]
- if c=="POINT": # export Empty as POINT
- dxfPOINT = DXF.Point(points=[p],**common)
- entities.append(dxfPOINT)
- return entities
-
-#-----------------------------------------------------
-def exportCamera(ob, mx, mw, **common):
- """converts Camera-Object to desired projection and representation(DXF-Entity type)
- """
- location = Mathutils.Vector(ob.loc)
- [location] = projected_co([location], mx)
- [location] = toGlobalOrigin([location])
- view_name=validDXFr12name(('CAM_'+ ob.name))
-
- camera = Camera.Get(ob.getData(name_only=True))
- #print 'deb: camera=', dir(camera) #------------------
- if camera.type=='persp':
- mode = 1+2+4+16
- # mode flags: 1=persp, 2=frontclip, 4=backclip,16=FrontZ
- elif camera.type=='ortho':
- mode = 0+2+4+16
-
- leftBottom=(0.0,0.0) # default
- rightTop=(1.0,1.0) # default
- center=(0.0,0.0) # default
-
- direction = Mathutils.Vector(0.0,0.0,1.0) * mx.rotationPart() # in W-C-S
- direction.normalize()
- target=Mathutils.Vector(ob.loc) - direction # in W-C-S
- #ratio=1.0
- width=height= camera.scale # for ortho-camera
- lens = camera.lens # for persp-camera
- frontClipping = -(camera.clipStart - 1.0)
- backClipping = -(camera.clipEnd - 1.0)
-
- entities, vport, view = [], None, None
- c = camera_as_list[GUI_A['camera_as'].val]
- if c=="POINT": # export as POINT
- dxfPOINT = DXF.Point(points=[location],**common)
- entities.append(dxfPOINT)
- elif c=="VIEW": # export as VIEW
- view = DXF.View(name=view_name,
- center=center, width=width, height=height,
- frontClipping=frontClipping,backClipping=backClipping,
- direction=direction,target=target,lens=lens,mode=mode
- )
- elif c=="VPORT": # export as VPORT
- vport = DXF.VPort(name=view_name,
- center=center, ratio=1.0, height=height,
- frontClipping=frontClipping,backClipping=backClipping,
- direction=direction,target=target,lens=lens,mode=mode
- )
- return entities, vport, view
-
-#-----------------------------------------------------
-def exportLamp(ob, mx, mw, **common):
- """converts Lamp-Object to desired projection and representation(DXF-Entity type)
- """
- p = Mathutils.Vector(ob.loc)
- [p] = projected_co([p], mx)
- [p] = toGlobalOrigin([p])
-
- entities = []
- c = lamp_as_list[GUI_A['lamp_as'].val]
- if c=="POINT": # export as POINT
- dxfPOINT = DXF.Point(points=[p],**common)
- entities.append(dxfPOINT)
- return entities
-
-#-----------------------------------------------------
-def exportInsert(ob, mx, insert_name, **common):
- """converts Object to DXF-INSERT in given orientation
- """
- WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
- sizeX = ob.SizeX
- sizeY = ob.SizeY
- sizeZ = ob.SizeZ
- rotX = ob.RotX
- rotY = ob.RotY
- rotZ = ob.RotZ
- #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
-
- Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
-
- AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
- if not PROJECTION:
- #Extrusion, ZRotation, Elevation = getExtrusion(mx)
- Extrusion, AXaxis = getExtrusion(mx)
-
- entities = []
-
- if 1:
- if not PROJECTION:
- ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
- AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
- ZRotation *= r2d
- point = ECS_origin
- else: #TODO: fails correct location
- point1 = Mathutils.Vector(ob.loc)
- [point] = projected_co([point1], mx)
- if PERSPECTIVE:
- clipStart = 10.0
- coef = -clipStart / (point1*mx)[2]
- #print 'deb: coef=', coef #--------------
- #TODO: ? sizeX *= coef
- #sizeY *= coef
- #sizeZ *= coef
-
- #print 'deb: point=', point #--------------
- [point] = toGlobalOrigin([point])
-
- #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
- common['extrusion']= Extrusion
- #common['elevation']= Elevation
- #print 'deb: common=', common #------------------
- if 0: #DEBUG
- #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
- linepoints = [[0,0,0], point]
- dxfLINE = DXF.Line(linepoints,**common)
- entities.append(dxfLINE)
-
- xscale=sizeX
- yscale=sizeY
- zscale=sizeZ
- cols=None
- colspacing=None
- rows=None
- rowspacing=None
-
- dxfINSERT = DXF.Insert(insert_name,point=point,rotation=ZRotation,\
- xscale=xscale,yscale=yscale,zscale=zscale,\
- cols=cols,colspacing=colspacing,rows=rows,rowspacing=rowspacing,\
- **common)
- entities.append(dxfINSERT)
-
- return entities
-
-
-#-----------------------------------------------------
-def exportText(ob, mx, mw, **common):
- """converts Text-Object to desired projection and representation(DXF-Entity type)
- """
- text3d = ob.getData()
- textstr = text3d.getText()
- WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
- sizeX = ob.SizeX
- sizeY = ob.SizeY
- sizeZ = ob.SizeZ
- rotX = ob.RotX
- rotY = ob.RotY
- rotZ = ob.RotZ
- #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
-
- Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
-
- AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
- if not PROJECTION:
- #Extrusion, ZRotation, Elevation = getExtrusion(mx)
- Extrusion, AXaxis = getExtrusion(mx)
-
- # no thickness/width for TEXTs converted into ScreenCS
- if text3d.getExtrudeDepth():
- Thickness = text3d.getExtrudeDepth() * sizeZ
-
- #Horizontal text justification type, code 72, (optional, default = 0)
- # integer codes (not bit-coded)
- #0=left, 1=center, 2=right
- #3=aligned, 4=middle, 5=fit
- Alignment = None
- alignment = text3d.getAlignment().value
- if alignment in (1,2): Alignment = alignment
-
- textHeight = text3d.getSize() / 1.7
- textFlag = 0
- if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored
- if sizeZ < 0.0: textFlag |= 4 # vertical mirrored
-
- entities = []
- c = text_as_list[GUI_A['text_as'].val]
-
- if c=="TEXT": # export text as TEXT
- if not PROJECTION:
- ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
- AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
- ZRotation *= r2d
- point = ECS_origin
- else: #TODO: fails correct location
- point1 = Mathutils.Vector(ob.loc)
- [point] = projected_co([point1], mx)
- if PERSPECTIVE:
- clipStart = 10.0
- coef = -clipStart / (point1*mx)[2]
- textHeight *= coef
- #print 'deb: coef=', coef #--------------
-
- #print 'deb: point=', point #--------------
- [point] = toGlobalOrigin([point])
- point2 = point
-
- #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
- common['extrusion']= Extrusion
- #common['elevation']= Elevation
- common['thickness']= Thickness
- #print 'deb: common=', common #------------------
- if 0: #DEBUG
- #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
- linepoints = [[0,0,0], point]
- dxfLINE = DXF.Line(linepoints,**common)
- entities.append(dxfLINE)
-
- dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
- flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
- entities.append(dxfTEXT)
- if Thickness:
- common['thickness']= -Thickness
- dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
- flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
- entities.append(dxfTEXT)
- return entities
-
-
-#-------------------------------------------
-def euler2matrix(rx, ry, rz):
- """creates full 3D rotation matrix (optimized)
- needs rx, ry, rz angles in radians
- """
- #print 'rx, ry, rz: ', rx, ry, rz
- A, B = sin(rx), cos(rx)
- C, D = sin(ry), cos(ry)
- E, F = sin(rz), cos(rz)
- AC, BC = A*C, B*C
- return Mathutils.Matrix([D*F, D*E, -C],
- [AC*F-B*E, AC*E+B*F, A*D],
- [BC*F+A*E, BC*E-A*F, B*D])
-
-
-#-----------------------------------------------------
-def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ):
- """given
- """
- if 1:
- rot_matrix = normalizeMat(mx.rotationPart())
- #TODO: workaround for blender negative-matrix.invert()
- # partially done: works only for rotX,rotY==0.0
- if sizeX<0.0: rot_matrix[0] *= -1
- if sizeY<0.0: rot_matrix[1] *= -1
- #if sizeZ<0.0: rot_matrix[2] *= -1
- rot_matrix_invert = rot_matrix.invert()
- else: #TODO: to check, why below rot_matrix_invert is not equal above one
- rot_euler_matrix = euler2matrix(rotX,rotY,rotZ)
- rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ)
-
- # OCS_origin is Global_Origin in ObjectCoordSystem
- OCS_origin = Mathutils.Vector(WCS_loc) * rot_matrix_invert
- #print 'deb: OCS_origin=', OCS_origin #---------
-
- ZRotation = rotZ
- if Extrusion!=None:
- ZRotation = getZRotation(AXaxis,rot_matrix_invert)
- #Zrotmatrix = Mathutils.RotationMatrix(-ZRotation, 3, "Z")
- rs, rc = sin(ZRotation), cos(ZRotation)
- Zrotmatrix = Mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0])
- #print 'deb: Zrotmatrix=\n', Zrotmatrix #--------------
-
- # ECS_origin is Global_Origin in EntityCoordSystem
- ECS_origin = OCS_origin * Zrotmatrix
- #print 'deb: ECS_origin=', ECS_origin #---------
- #TODO: it doesnt work yet for negative scaled curve-objects!
- return ZRotation,Zrotmatrix,OCS_origin,ECS_origin
-
-
-#-----------------------------------------------------
-def exportCurve(ob, mx, mw, **common):
- """converts Curve-Object to desired projection and representation(DXF-Entity type)
- """
- entities = []
- block = None
- curve = ob.getData()
- #print 'deb: curve=', dir(curve) #---------
- # TODO: should be: if curve.users>1 and not (PERSPECTIVE or (PROJECTION and HIDDEN_MODE):
- if GUI_A['instances_on'].val and curve.users>1 and not PROJECTION:
- if curve.name in BLOCKREGISTRY.keys():
- insert_name = BLOCKREGISTRY[curve.name]
- # write INSERT to entities
- entities = exportInsert(ob, mx,insert_name, **common)
- else:
- # generate geom_output in ObjectCS
- imx = Mathutils.Matrix().identity()
- WCS_loc = [0,0,0] # WCS_loc is object location in WorldCoordSystem
- #print 'deb: WCS_loc=', WCS_loc #---------
- sizeX = sizeY = sizeZ = 1.0
- rotX = rotY = rotZ = 0.0
- Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
- ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
- AXaxis = imx[0].copy().resize3D() # = ArbitraryXvector
- OCS_origin = [0,0,0]
- if not PROJECTION:
- #Extrusion, ZRotation, Elevation = getExtrusion(mx)
- Extrusion, AXaxis = getExtrusion(imx)
-
- # no thickness/width for POLYLINEs converted into Screen-C-S
- #print 'deb: curve.ext1=', curve.ext1 #---------
- if curve.ext1: Thickness = curve.ext1 * sizeZ
- if curve.ext2 and sizeX==sizeY:
- Width = curve.ext2 * sizeX
- if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
- ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(imx,Extrusion,\
- AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
-
- entities = writeCurveEntities(curve, imx,
- Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
- WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
- **common)
-
- if entities: # if not empty block
- # write BLOCK definition and INSERT entity
- # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
- BLOCKREGISTRY[curve.name]=validDXFr12name(('CU_'+ curve.name))
- insert_name = BLOCKREGISTRY[curve.name]
- block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
- # write INSERT as entity
- entities = exportInsert(ob, mx, insert_name, **common)
-
- else: # no other instances, so go the standard way
- WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
- #print 'deb: WCS_loc=', WCS_loc #---------
- sizeX = ob.SizeX
- sizeY = ob.SizeY
- sizeZ = ob.SizeZ
- rotX = ob.RotX
- rotY = ob.RotY
- rotZ = ob.RotZ
- #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
-
- Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
- ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
- AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
- OCS_origin = [0,0,0]
- if not PROJECTION:
- #Extrusion, ZRotation, Elevation = getExtrusion(mx)
- Extrusion, AXaxis = getExtrusion(mx)
-
- # no thickness/width for POLYLINEs converted into Screen-C-S
- #print 'deb: curve.ext1=', curve.ext1 #---------
- if curve.ext1: Thickness = curve.ext1 * sizeZ
- if curve.ext2 and sizeX==sizeY:
- Width = curve.ext2 * sizeX
- if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
- ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
- AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
- entities = writeCurveEntities(curve, mx,
- Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
- WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
- **common)
-
- return entities, block
-
-
-#-------------------------------------------------
-def writeCurveEntities(curve, mx,
- Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
- WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
- **common):
- """help routine for exportCurve()
- """
- entities = []
-
- if 1:
- for cur in curve:
- #print 'deb: START cur=', cur #--------------
- points = []
- if cur.isNurb():
- for point in cur:
- #print 'deb:isNurb point=', point #---------
- vec = point[0:3]
- #print 'deb: vec=', vec #---------
- pkt = Mathutils.Vector(vec)
- #print 'deb: pkt=', pkt #---------
- points.append(pkt)
- else:
- for point in cur:
- #print 'deb:isBezier point=', point.getTriple() #---------
- vec = point.getTriple()[1]
- #print 'deb: vec=', vec #---------
- pkt = Mathutils.Vector(vec)
- #print 'deb: pkt=', pkt #---------
- points.append(pkt)
-
- #print 'deb: points', points #--------------
- if len(points)>1:
- c = curve_as_list[GUI_A['curve_as'].val]
-
- if c=="POLYLINE": # export Curve as POLYLINE
- if not PROJECTION:
- # recalculate points(2d=X,Y) into Entity-Coords-System
- for p in points: # list of vectors
- p[0] *= sizeX
- p[1] *= sizeY
- p2 = p * Zrotmatrix
- p2[0] += ECS_origin[0]
- p2[1] += ECS_origin[1]
- p[0],p[1] = p2[0],p2[1]
- else:
- points = projected_co(points, mx)
- #print 'deb: points', points #--------------
-
- if cur.isCyclic(): closed = 1
- else: closed = 0
- points = toGlobalOrigin(points)
-
- if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
-
- common['extrusion']= Extrusion
- ##common['rotation']= ZRotation
- ##common['elevation']= Elevation
- common['thickness']= Thickness
- #print 'deb: common=', common #------------------
-
- if 0: #DEBUG
- p=AXaxis[:3]
- entities.append(DXF.Line([[0,0,0], p],**common))
- p=ECS_origin[:3]
- entities.append(DXF.Line([[0,0,0], p],**common))
- common['color']= 5
- p=OCS_origin[:3]
- entities.append(DXF.Line([[0,0,0], p],**common))
- #OCS_origin=[0,0,0] #only debug----------------
- dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
- entities.append(dxfPLINE)
-
- dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
- entities.append(dxfPLINE)
- if Thickness:
- common['thickness']= -Thickness
- dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
- entities.append(dxfPLINE)
-
- elif c=="LINEs": # export Curve as multiple LINEs
- points = projected_co(points, mx)
- if cur.isCyclic(): points.append(points[0])
- #print 'deb: points', points #--------------
- points = toGlobalOrigin(points)
-
- if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
- common['extrusion']= Extrusion
- common['elevation']= Elevation
- common['thickness']= Thickness
- #print 'deb: common=', common #------------------
- for i in range(len(points)-1):
- linepoints = [points[i], points[i+1]]
- dxfLINE = DXF.Line(linepoints,**common)
- entities.append(dxfLINE)
- if Thickness:
- common['thickness']= -Thickness
- for i in range(len(points)-1):
- linepoints = [points[i], points[i+1]]
- dxfLINE = DXF.Line(linepoints,**common)
- entities.append(dxfLINE)
-
- elif c=="POINTs": # export Curve as multiple POINTs
- points = projected_co(points, mx)
- for p in points:
- dxfPOINT = DXF.Point(points=[p],**common)
- entities.append(dxfPOINT)
- return entities
-
-
-#-----------------------------------------------------
-def getClipBox(camera):
- """calculates Field-of-View-Clipping-Box of given Camera
- returns clip_box: a list of vertices
- returns matr: translation matrix
- """
- sce = Scene.GetCurrent()
- context = sce.getRenderingContext()
- #print 'deb: context=\n', context #------------------
- sizeX = context.sizeX
- sizeY = context.sizeY
- ratioXY = sizeX/float(sizeY)
- #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------
-
- clip1_Z = - camera.clipStart
- clip2_Z = - camera.clipEnd
- #print 'deb: clip Start=', camera.clipStart #------------------
- #print 'deb: clip End=', camera.clipEnd #------------------
-
- if camera.type=='ortho':
- scale = camera.scale
- #print 'deb: camscale=', scale #------------------
- clip1shiftX = clip2shiftX = camera.shiftX * scale
- clip1shiftY = clip2shiftY = camera.shiftY * scale
- clip1_X = scale * 0.5
- clip1_Y = scale * 0.5
- if ratioXY > 1.0: clip1_Y /= ratioXY
- else: clip1_X *= ratioXY
- clip2_X = clip1_X
- clip2_Y = clip1_Y
-
- near = clip1_Z
- far = clip2_Z
- right, left = clip1_X, -clip1_X
- top, bottom = clip1_Y, -clip1_Y
-
- scaleX = 2.0/float(right - left)
- x3 = -float(right + left)/float(right - left)
- scaleY = 2.0/float(top - bottom)
- y3 = -float(top + bottom)/float(top - bottom)
- scaleZ = 1.0/float(far - near)
- z3 = -float(near)/float(far - near)
-
- matrix = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3],
- [0.0, scaleY, 0.0, y3],
- [0.0, 0.0, scaleZ, z3],
- [0.0, 0.0, 0.0, 1.0])
-
- elif camera.type=='persp':
- #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe
- #lens = camera.lens
- angle = camera.angle
- #print 'deb: cam angle=', angle #------------------
- shiftX = camera.shiftX
- shiftY = camera.shiftY
- fov_coef = atan(angle * d2r)
- fov_coef *= 1.3 #incl. passpartou
- clip1_k = clip1_Z * fov_coef
- clip2_k = clip2_Z * fov_coef
- clip1shiftX = - camera.shiftX * clip1_k
- clip2shiftX = - camera.shiftX * clip2_k
- clip1shiftY = - camera.shiftY * clip1_k
- clip2shiftY = - camera.shiftY * clip2_k
- clip1_X = clip1_Y = clip1_k * 0.5
- clip2_X = clip2_Y = clip2_k * 0.5
- if ratioXY > 1.0:
- clip1_Y /= ratioXY
- clip2_Y /= ratioXY
- else:
- clip1_X *= ratioXY
- clip2_X *= ratioXY
-
- near = clip1_Z
- far = clip2_Z
- right, left = clip1_X, -clip1_X
- top, bottom = clip1_Y, -clip1_Y
- #return Matrix( [scaleX, 0.0, x2, 0.0],
- #[0.0, scaleY, y2, 0.0],
- #[0.0, 0.0, scaleZ, wZ],
- #[0.0, 0.0, -1.0, 0.0])
- matrix = Mathutils.Matrix( [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0],
- [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0],
- [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)],
- [0.0, 0.0, -1.0, 0.0])
-
-
- clip_box = [
- -clip1_X + clip1shiftX, clip1_X + clip1shiftX,
- -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY,
- -clip2_X + clip2shiftX, clip2_X + clip2shiftX,
- -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY,
- clip1_Z, clip2_Z]
- #print 'deb: clip_box=\n', clip_box #------------------
- #drawClipBox(clip_box)
- return clip_box, matrix
-
-
-#-----------------------------------------------------
-def drawClipBox(clip_box):
- """debug tool: draws Clipping-Box of a Camera View
- """
- min_X1, max_X1, min_Y1, max_Y1,\
- min_X2, max_X2, min_Y2, max_Y2,\
- min_Z, max_Z = clip_box
- verts = []
- verts.append([min_X1, min_Y1, min_Z])
- verts.append([max_X1, min_Y1, min_Z])
- verts.append([max_X1, max_Y1, min_Z])
- verts.append([min_X1, max_Y1, min_Z])
- verts.append([min_X2, min_Y2, max_Z])
- verts.append([max_X2, min_Y2, max_Z])
- verts.append([max_X2, max_Y2, max_Z])
- verts.append([min_X2, max_Y2, max_Z])
- faces = [[0,1,2,3],[4,5,6,7]]
- newmesh = Mesh.New()
- newmesh.verts.extend(verts)
- newmesh.faces.extend(faces)
-
- plan = Object.New('Mesh','clip_box')
- plan.link(newmesh)
- sce = Scene.GetCurrent()
- sce.objects.link(plan)
- plan.setMatrix(sce.objects.camera.matrix)
-
-
-#-------------------------------------------------
-def getCommons(ob):
- """set up common attributes for output style:
- color=None
- extrusion=None
- layer='0',
- lineType=None
- lineTypeScale=None
- lineWeight=None
- thickness=None
- parent=None
- """
-
- layers = ob.layers #gives a list e.g.[1,5,19]
- if layers: ob_layer_nr = layers[0]
- #print 'ob_layer_nr=', ob_layer_nr #--------------
-
- materials = ob.getMaterials()
- if materials:
- ob_material = materials[0]
- ob_mat_color = ob_material.rgbCol
- else: ob_mat_color, ob_material = None, None
- #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #--------------
-
- data = ob.getData()
- data_materials = ob.getMaterials()
- if data_materials:
- data_material = data_materials[0]
- data_mat_color = data_material.rgbCol
- else: data_mat_color, data_material = None, None
- #print 'data_mat_color, data_material=', data_mat_color, data_material #--------------
-
- entitylayer = ENTITYLAYER_DEF
- c = entitylayer_from_list[GUI_A['entitylayer_from'].val]
- #["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
- if c=="default_LAYER":
- entitylayer = LAYERNAME_DEF
- elif c=="obj.layer" and ob_layer_nr:
- entitylayer = 'LAYER'+ str(ob_layer_nr)
- elif c=="obj.material" and ob_material:
- entitylayer = ob_material.name
- elif c=="obj.name":
- entitylayer = ob.name
- elif c=="obj.data.material" and ob_material:
- entitylayer = data_material.name
- elif c=="obj.data.name":
- entitylayer = data.name
- entitylayer = validDXFr12name(PREFIX+entitylayer)
- if entitylayer=="": entitylayer = "BF_0"
-
- entitycolor = ENTITYCOLOR_DEF
- c = entitycolor_from_list[GUI_A['entitycolor_from'].val]
- if c=="default_COLOR":
- entitycolor = LAYERCOLOR_DEF
- elif c=="BYLAYER":
- entitycolor = BYLAYER
- elif c=="BYBLOCK":
- entitycolor = BYBLOCK
- elif c=="obj.layer" and ob_layer_nr:
- entitycolor = ob_layer_nr
- elif c=="obj.color" and ob.color:
- entitycolor = col2DXF(ob.color)
- elif c=="obj.material" and ob_mat_color:
- entitycolor = col2DXF(ob_mat_color)
- elif c=="obj.data.material" and data_mat_color:
- entitycolor = col2DXF(data_mat_color)
- #if entitycolor!=None: layercolor = entitycolor
-
- entityltype = ENTITYLTYPE_DEF
- c = entityltype_from_list[GUI_A['entityltype_from'].val]
- if c=="default_LTYPE":
- entityltype = LAYERLTYPE_DEF
- elif c=="BYLAYER":
- entityltype = BYLAYER
- elif c=="BYBLOCK":
- entityltype = BYBLOCK
- elif c:
- entityltype = c
-
- return entitylayer,entitycolor,entityltype
-
-
-#-----------------------------------------------------
-def do_export(export_list, filepath):
- global PERSPECTIVE, CAMERAVIEW, BLOCKREGISTRY
- Window.WaitCursor(1)
- t = Blender.sys.time()
-
- # init Drawing ---------------------
- d=DXF.Drawing()
- # add Tables -----------------
- # initialized automatic: d.blocks.append(b) #section BLOCKS
- # initialized automatic: d.styles.append(DXF.Style()) #table STYLE
-
- #table LTYPE ---------------
- #d.linetypes.append(DXF.LineType(name='CONTINUOUS',description='--------',elements=[0.0]))
- d.linetypes.append(DXF.LineType(name='DOT',description='. . . . . . .',elements=[0.25, 0.0, -0.25]))
- d.linetypes.append(DXF.LineType(name='DASHED',description='__ __ __ __ __',elements=[0.8, 0.5, -0.3]))
- d.linetypes.append(DXF.LineType(name='DASHDOT',description='__ . __ . __ .',elements=[1.0, 0.5, -0.25, 0.0, -0.25]))
- d.linetypes.append(DXF.LineType(name='DIVIDE',description='____ . . ____ . . ',elements=[1.25, 0.5, -0.25, 0.0, -0.25, 0.0, -0.25]))
- d.linetypes.append(DXF.LineType(name='BORDER',description='__ __ . __ __ . ',elements=[1.75, 0.5, -0.25, 0.5, -0.25, 0.0, -0.25]))
- d.linetypes.append(DXF.LineType(name='HIDDEN',description='__ __ __ __ __',elements=[0.4, 0.25, -0.25]))
- d.linetypes.append(DXF.LineType(name='CENTER',description='____ _ ____ _ __',elements=[2.0, 1.25, -0.25, 0.25, -0.25]))
-
- #d.vports.append(DXF.VPort('*ACTIVE'))
- d.vports.append(DXF.VPort('*ACTIVE',center=(-5.0,1.0),height=10.0))
- #d.vports.append(DXF.VPort('*ACTIVE',leftBottom=(-100.0,-60.0),rightTop=(100.0,60.0)))
- #d.views.append(DXF.View('Normal')) #table view
- d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem
-
- # add Entities --------------------
- BLOCKREGISTRY = {} # registry and map for BLOCKs
- PERSPECTIVE = 0
- something_ready = 0
- selected_len = len(export_list)
- sce = Scene.GetCurrent()
-
- mw = Mathutils.Matrix( [1.0, 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])
- if PROJECTION:
- if CAMERA<len(CAMERAS)+1: # the biggest number is the current 3d-view
- act_camera = Object.Get(CAMERAS[CAMERA-1])
- #context = sce.getRenderingContext()
- #print 'deb: context=\n', context #------------------
- #print 'deb: context=\n', dir(context) #------------------
- #act_camera = sce.objects.camera
- #print 'deb: act_camera=', act_camera #------------------
- if act_camera:
- CAMERAVIEW = 1
- mc0 = act_camera.matrix.copy()
- #print 'deb: camera.Matrix=\n', mc0 #------------------
- camera = Camera.Get(act_camera.getData(name_only=True))
- #print 'deb: camera=', dir(camera) #------------------
- if camera.type=='persp': PERSPECTIVE = 1
- elif camera.type=='ortho': PERSPECTIVE = 0
- # mcp is matrix.camera.perspective
- clip_box, mcp = getClipBox(camera)
- if PERSPECTIVE:
- # get border
- # lens = camera.lens
- min_X1, max_X1, min_Y1, max_Y1,\
- min_X2, max_X2, min_Y2, max_Y2,\
- min_Z, max_Z = clip_box
- verts = []
- verts.append([min_X1, min_Y1, min_Z])
- verts.append([max_X1, min_Y1, min_Z])
- verts.append([max_X1, max_Y1, min_Z])
- verts.append([min_X1, max_Y1, min_Z])
- border=verts
- mw = mc0.copy().invert()
-
- else: # get 3D-View instead of camera-view
- #ViewVector = Mathutils.Vector(Window.GetViewVector())
- #print 'deb: ViewVector=\n', ViewVector #------------------
- #TODO: what is Window.GetViewOffset() for?
- #print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
- #Window.SetViewOffset([0,0,0])
- mw0 = Window.GetViewMatrix()
- #print 'deb: mwOrtho =\n', mw0 #---------
- mwp = Window.GetPerspMatrix() #TODO: how to get it working?
- #print 'deb: mwPersp =\n', mwp #---------
- mw = mw0.copy()
-
- #print 'deb: ViewMatrix=\n', mw #------------------
-
- if APPLY_MODIFIERS: tmp_me = Mesh.New('tmp')
- else: tmp_me = None
-
- if GUI_A['paper_space_on'].val==1: espace=1
- else: espace=None
-
- layernames = []
- for ob,mx in export_list:
- entities = []
- block = None
- #mx = ob.matrix.copy()
- #print 'deb: ob =', ob #---------
- #print 'deb: ob.type =', ob.type #---------
- #print 'deb: mx =\n', mx #---------
- #print 'deb: mw0 =\n', mw0 #---------
- #mx_n is trans-matrix for normal_vectors for front-side faces
- mx_n = mx.rotationPart() * mw.rotationPart()
- if G_SCALE!=1.0: mx *= G_SCALE
- mx *= mw
-
- #mx_inv = mx.copy().invert()
- #print 'deb: mx =\n', mx #---------
- #print 'deb: mx_inv=\n', mx_inv #---------
-
- if ob.type in ('Mesh','Curve','Empty','Text','Camera','Lamp'):
- elayer,ecolor,eltype = getCommons(ob)
- #print 'deb: elayer,ecolor,eltype =', elayer,ecolor,eltype #--------------
-
- #TODO: use ob.boundBox for drawing extends
-
- if elayer!=None:
- if elayer not in layernames:
- layernames.append(elayer)
- if ecolor!=None: tempcolor = ecolor
- else: tempcolor = LAYERCOLOR_DEF
- d.layers.append(DXF.Layer(color=tempcolor, name=elayer))
-
- if (ob.type == 'Mesh') and GUI_B['bmesh'].val:
- entities, block = exportMesh(ob, mx, mx_n, tmp_me,\
- paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
- elif (ob.type == 'Curve') and GUI_B['bcurve'].val:
- entities, block = exportCurve(ob, mx, mw, \
- paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
- elif (ob.type == 'Empty') and GUI_B['empty'].val:
- entities = exportEmpty(ob, mx, mw, \
- paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
- elif (ob.type == 'Text') and GUI_B['text'].val:
- entities = exportText(ob, mx, mw, \
- paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
- elif (ob.type == 'Camera') and GUI_B['camera'].val:
- entities, vport, view = exportCamera(ob, mx, mw, \
- paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
- if vport: d.vports.append(vport)
- if view: d.views.append(view)
- elif (ob.type == 'Lamp') and GUI_B['lamp'].val:
- entities = exportLamp(ob, mx, mw, \
- paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
-
- if entities:
- something_ready += 1
- for e in entities:
- d.append(e)
-
- if block:
- d.blocks.append(block) #add to BLOCK-section
-
-
- if something_ready:
- if PERSPECTIVE: # generate view border - passepartout
- identity_matrix = Mathutils.Matrix().identity()
- points = projected_co(border, identity_matrix)
- closed = 1
- points = toGlobalOrigin(points)
- c = curve_as_list[GUI_A['curve_as'].val]
- if c=="LINEs": # export Curve as multiple LINEs
- for i in range(len(points)-1):
- linepoints = [points[i], points[i+1]]
- dxfLINE = DXF.Line(linepoints,paperspace=espace,color=LAYERCOLOR_DEF)
- entities.append(dxfLINE)
- else:
- dxfPLINE = DXF.PolyLine(points,points[0],closed,\
- paperspace=espace, color=LAYERCOLOR_DEF)
- d.append(dxfPLINE)
-
-
- if not GUI_A['outputDWG_on'].val:
- print 'writing to %s' % filepath
- try:
- d.saveas(filepath)
- Window.WaitCursor(0)
- #print '%s objects exported to %s' %(something_ready,filepath)
- print '%s/%s objects exported in %.2f seconds. -----DONE-----' %(something_ready,selected_len,(Blender.sys.time()-t))
- Draw.PupMenu('DXF Exporter: job finished!| %s/%s objects exported in %.2f sek.' %(something_ready,selected_len, (Blender.sys.time()-t)))
- except IOError:
- Window.WaitCursor(0)
- Draw.PupMenu('DXF Exporter: Write Error: Permission denied:| %s' %filepath)
-
- else:
- if not extCONV_OK:
- Draw.PupMenu(extCONV_TEXT)
- Window.WaitCursor(False)
- else:
- print 'temp. exporting to %s' % filepath
- d.saveas(filepath)
- #Draw.PupMenu('DXF Exporter: job finished')
- #print 'exported to %s' % filepath
- #print 'finished in %.2f seconds' % (Blender.sys.time()-t)
- filedwg = filepath[:-3]+'dwg'
- print 'exporting to %s' % filedwg
- os.system('%s %s -acad13 -dwg' %(extCONV_PATH,filepath))
- #os.chdir(cwd)
- os.remove(filepath)
- Window.WaitCursor(0)
- print ' finished in %.2f seconds. -----DONE-----' % (Blender.sys.time()-t)
- Draw.PupMenu('DWG Exporter: job finished!| %s/%s objects exported in %.2f sek.' %(something_ready,selected_len, (Blender.sys.time()-t)))
- else:
- Window.WaitCursor(0)
- print "Abort: selected objects dont match choosen export option, nothing exported!"
- Draw.PupMenu('DXF Exporter: nothing exported!|selected objects dont match choosen export option!')
-
-
-#------------------------------------------------------
-"""
-v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
-28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,\
-123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,\
-151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,\
-171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,\
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,\
-211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,\
-231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
-invalid = ''.join([chr(i) for i in v])
-del v, i
-"""
-#TODO: validDXFr14 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.'
-validDXFr12 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
-
-#------------------------------------------------------
-def cleanName(name,valid):
- validname = ''
- for ch in name:
- if ch not in valid: ch = '_'
- validname += ch
- return validname
-
-#------------------------------------------------------
-def validDXFr12name(str_name):
- dxfname = str(str_name)
- dxfname = dxfname[:NAMELENGTH_MAX].upper()
- dxfname = cleanName(dxfname,validDXFr12)
- return dxfname
-
-#print cleanName('dumka',validDXFr12)
-#print validDXFr12name('dum 15%ka')
-
-#------------------------------------------------------
-def col2RGB(color):
- return [int(floor(255*color[0])),
- int(floor(255*color[1])),
- int(floor(255*color[2]))]
-
-global dxfColors
-dxfColors=None
-
-#------------------------------------------------------
-def col2DXF(rgbcolor):
- global dxfColors
- if dxfColors is None:
- from dxfColorMap import color_map
- dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
- dxfColors.sort()
- entry = (tuple(rgbcolor), -1)
- dxfColors.append(entry)
- dxfColors.sort()
- i = dxfColors.index(entry)
- dxfColors.pop(i)
- return dxfColors[i-1][1]
-
-
-
-# NEW UI -----#################################################-----------------
-# ------------#################################################-----------------
-
-class Settings: #-----------------------------------------------------------------
- """A container for all the export settings and objects.
-
- This is like a collection of globally accessable persistant properties and functions.
- """
- # Optimization constants
- MIN = 0
- MID = 1
- PRO = 2
- MAX = 3
-
- def __init__(self, keywords, drawTypes):
- """initialize all the important settings used by the export functions.
- """
- self.obj_number = 1 #global object_number for progress_bar
-
- self.var = dict(keywords) #a dictionary of (key_variable:Value) control parameter
- self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type
-
- self.var['colorFilter_on'] = False #deb:remi------------
- self.acceptedColors = [0,2,3,4,5,6,7,8,9,
- 10 ]
-
- self.var['materialFilter_on'] = False #deb:remi------------
- self.acceptedLayers = ['3',
- '0'
- ]
-
- self.var['groupFilter_on'] = False #deb:remi------------
- self.acceptedLayers = ['3',
- '0'
- ]
-
- #self.var['objectFilter_on'] = 0 #deb:remi------------
- self.acceptedBlocks = ['WALL_1871',
- 'BOX02'
- ]
- self.unwantedBlocks = ['BOX05',
- 'BOX04'
- ]
-
-
- def update(self, keywords, drawTypes):
- """update all the important settings used by the draw functions.
- mostly used after loading parameters from INI-file
- """
-
- for k, v in keywords.iteritems():
- self.var[k] = v
- #print 'deb:settings_update var %s= %s' %(k, self.var[k]) #--------------
- for t, v in drawTypes.iteritems():
- self.drawTypes[t] = v
- #print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #--------------
-
- self.drawTypes['arc'] = self.drawTypes['surface']
- self.drawTypes['circle'] = self.drawTypes['surface']
- self.drawTypes['ellipse'] = self.drawTypes['surface']
- self.drawTypes['trace'] = self.drawTypes['solid']
- self.drawTypes['insert'] = self.drawTypes['group']
- #self.drawTypes['vport'] = self.drawTypes['view']
-
- #print 'deb:self.drawTypes', self.drawTypes #---------------
-
-
- def validate(self, drawing):
- """Given the drawing, build dictionaries of Layers, Colors and Blocks.
- """
- global oblist
- #adjust the distance parameter to globalScale
- if self.var['g_scale'] != 1.0:
- self.var['dist_min'] = self.var['dist_min'] / self.var['g_scale']
- self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ'])
-
-
- def write(self, text, newline=True):
- """Wraps the built-in print command in a optimization check.
- """
- if self.var['optimization'] <= self.MID:
- if newline:
- print text
- else:
- print text,
-
-
- def redraw(self):
- """Update Blender if optimization level is low enough.
- """
- if self.var['optimization'] <= self.MIN:
- Blender.Redraw()
-
-
- def progress(self, done, text):
- """Wrapper for Blender.Window.DrawProgressBar.
- """
- if self.var['optimization'] <= self.PRO:
- progressbar = done * self.obj_number
- Window.DrawProgressBar(progressbar, text)
- #print 'deb:drawer done, progressbar: ', done, progressbar #-----------------------
-
-
-
-# GUI STUFF -----#################################################-----------------
-from Blender.BGL import *
-
-EVENT_NONE = 1
-EVENT_START = 2
-EVENT_REDRAW = 3
-EVENT_LOAD_INI = 4
-EVENT_SAVE_INI = 5
-EVENT_RESET = 6
-EVENT_CHOOSE_INI = 7
-EVENT_CHOOSE_DXF = 8
-EVENT_HELP = 9
-EVENT_CAMERA = 10
-EVENT_LIGHT =11
-EVENT_DXF_DIR = 12
-EVENT_setCAMERA = 13
-# = 14
-EVENT_ORIGIN = 15
-EVENT_SCALE = 16
-EVENT_PRESET2D = 20
-EVENT_PRESET3D = 21
-EVENT_PRESETPLINE = 22
-EVENT_PRESETS = 23
-EVENT_EXIT = 100
-
-GUI_A = {} # GUI-buttons dictionary for parameter
-GUI_B = {} # GUI-buttons dictionary for drawingTypes
-
-# settings default, initialize ------------------------
-
-#-----------------------------------------------
-def prepareMenu(title,list):
- menu = title
- for i, item in enumerate(list):
- menu += '|'+ item + ' %x' + str(i)
- return menu
-
-#-----------------------------------------------
-mesh_as_list = ["3DFACEs","POLYFACE","POLYLINE","LINEs","POINTs"]
-mesh_as_menu = prepareMenu("export to: %t", mesh_as_list)
-
-curve_as_list = ["LINEs","POLYLINE","..LWPOLYLINE r14","..SPLINE r14","POINTs"]
-curve_as_menu = prepareMenu("export to: %t", curve_as_list)
-
-surface_as_list = ["..3DFACEs","..POLYFACE","..POINTs","..NURBS"]
-surface_as_menu = prepareMenu("export to: %t", surface_as_list)
-
-meta_as_list = ["..3DFACEs","..POLYFACE","..3DSOLID"]
-meta_as_menu = prepareMenu("export to: %t", meta_as_list)
-
-text_as_list = ["TEXT","..MTEXT","..ATTRIBUT"]
-text_as_menu = prepareMenu("export to: %t", text_as_list)
-
-empty_as_list = ["POINT","..INSERT","..XREF"]
-empty_as_menu = prepareMenu("export to: %t|", empty_as_list)
-
-group_as_list = ["..GROUP","..BLOCK","..ungroup"]
-group_as_menu = prepareMenu("export to: %t", group_as_list)
-
-parent_as_list = ["..BLOCK","..ungroup"]
-parent_as_menu = prepareMenu("export to: %t", parent_as_list)
-
-proxy_as_list = ["..BLOCK","..XREF","..ungroup","..POINT"]
-proxy_as_menu = prepareMenu("export to: %t", proxy_as_list)
-
-camera_as_list = ["..BLOCK","..A_CAMERA","VPORT","VIEW","POINT"]
-camera_as_menu = prepareMenu("export to: %t", camera_as_list)
-
-lamp_as_list = ["..BLOCK","..A_LAMP","POINT"]
-lamp_as_menu = prepareMenu("export to: %t", lamp_as_list)
-
-material_to_list= ["COLOR","LAYER","..LINESTYLE","..BLOCK","..XDATA","..INI-File"]
-material_to_menu = prepareMenu("export to: %t", material_to_list)
-
-ltype_map_list= ["object_rgb","material_rgb","..map_table"]
-ltype_map_menu = prepareMenu("export to: %t", ltype_map_list)
-
-
-
-layername_from_list = [LAYERNAME_DEF,"drawing_name","scene_name"]
-layername_from_menu = prepareMenu("defaultLAYER: %t", layername_from_list)
-
-layerltype_def_list = ["CONTINUOUS","DOT","DASHED","DASHDOT","BORDER","HIDDEN"]
-layerltype_def_menu = prepareMenu("LINETYPE set to: %t",layerltype_def_list)
-
-entitylayer_from_list = ["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
-entitylayer_from_menu = prepareMenu("entityLAYER from: %t", entitylayer_from_list)
-#print 'deb: entitylayer_from_menu=', entitylayer_from_menu #--------------
-
-entitycolor_from_list = ["default_COLOR","BYLAYER","BYBLOCK","obj.layer","obj.color","obj.material","obj.data.material","..map_table"]
-entitycolor_from_menu = prepareMenu("entityCOLOR set to: %t",entitycolor_from_list)
-
-entityltype_from_list = ["default_LTYPE","BYLAYER","BYBLOCK","CONTINUOUS","DOT","DASHED","DASHDOT","BORDER","HIDDEN"]
-entityltype_from_menu = prepareMenu("entityCOLOR set to: %t",entityltype_from_list)
-
-#dxf-LINE,ARC,CIRCLE,ELLIPSE
-
-g_scale_list = ''.join((
- 'scale factor: %t',
- '|user def. %x12',
- '|yard to m %x8',
- '|feet to m %x7',
- '|inch to m %x6',
- '| x 100000 %x5',
- '| x 10000 %x4',
- '| x 1000 %x3',
- '| x 100 %x2',
- '| x 10 %x1',
- '| x 1 %x0',
- '| x 0.1 %x-1',
- '| x 0.01 %x-2',
- '| x 0.001 %x-3',
- '| x 0.0001 %x-4',
- '| x 0.00001 %x-5'))
-
-#print 'deb: g_scale_list', g_scale_list #-----------
-
-dxfFileName = Draw.Create("")
-iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
-user_preset = 0
-config_UI = Draw.Create(0) #switch_on/off extended config_UI
-g_scale_as = Draw.Create(int(log10(G_SCALE)))
-
-
-keywords_org = {
- 'optimization': 2,
- 'dummy_on' : 0,
-
- 'xref_on' : 1,
- 'block_nn': 0,
-
- 'paper_space_on': 0,
- 'layFrozen_on': 0,
- 'objectFilter_on': 0,
- 'materialFilter_on': 0,
- 'colorFilter_on': 0,
- 'groupFilter_on': 0,
-
- 'only_selected_on': ONLYSELECTED,
- 'only_visible_on': ONLYVISIBLE,
- 'projection_on' : PROJECTION,
- 'hidden_lines_on': HIDDEN_LINES,
- 'shadows_on' : SHADOWS,
- 'light_on' : 1,
- 'outputDWG_on' : OUTPUT_DWG,
- 'to_polyline_on': POLYLINES,
- 'to_polyface_on': POLYFACES,
- 'instances_on': INSTANCES,
- 'apply_modifiers_on': APPLY_MODIFIERS,
- 'include_duplis_on': INCLUDE_DUPLIS,
- 'camera_selected': CAMERA,
-
- 'g_originX' : G_ORIGIN[0],
- 'g_originY' : G_ORIGIN[1],
- 'g_originZ' : G_ORIGIN[2],
- 'g_origin_on': 0,
- 'g_scale' : float(G_SCALE),
-# 'g_scale_as': int(log10(G_SCALE)), # 0,
- 'g_scale_on': 0,
- 'Z_force_on': 0,
- 'Z_elev': float(ELEVATION),
-
-
- 'prefix_def' : PREFIX,
- 'layername_def' : LAYERNAME_DEF,
- 'layercolor_def': LAYERCOLOR_DEF,
- 'layerltype_def': LAYERLTYPE_DEF,
- 'entitylayer_from': 5,
- 'entitycolor_from': 1,
- 'entityltype_from' : 1,
-
- 'material_on': 1,
- 'material_to': 2,
- 'fill_on' : 1,
-
- 'mesh_as' : 1,
- 'curve_as' : 1,
- 'surface_as' : 1,
- 'meta_as' : 1,
- 'text_as' : 0,
- 'empty_as' : 0,
- 'group_as' : 0,
- 'parent_as' : 0,
- 'proxy_as' : 0,
- 'camera_as': 3,
- 'lamp_as' : 2,
- }
-
-drawTypes_org = {
- 'bmesh' : 1,
- 'bcurve': 1,
- 'surface': 0,
- 'bmeta' : 0,
- 'text' : 1,
- 'empty' : 1,
- 'group' : 1,
- 'parent': 1,
- 'proxy' : 0,
- 'camera': 0,
- 'lamp' : 0,
-
-# 'view' : 0,
- }
-
-# creating of GUI-buttons
-# GUI_A - GUI-buttons dictionary for parameter
-# GUI_B - GUI-buttons dictionary for drawingTypes
-for k, v in keywords_org.iteritems():
- GUI_A[k] = Draw.Create(v)
-for k, v in drawTypes_org.iteritems():
- GUI_B[k] = Draw.Create(v)
-#print 'deb:init GUI_A: ', GUI_A #---------------
-#print 'deb:init GUI_B: ', GUI_B #---------------
-
-model_space_on = Draw.Create(1)
-
-# initialize settings-object controls how dxf entities are drawn
-settings = Settings(keywords_org, drawTypes_org)
-
-
-def update_RegistryKey(key, item): #
- """updates key in Blender.Registry
- """
- cache = True # data is also saved to a file
- rdict = Registry.GetKey('DXF_Exporter', cache)
- if not rdict: rdict = {}
- if item:
- rdict[key] = item
- Registry.SetKey('DXF_Exporter', rdict, cache)
- #print 'deb:update_RegistryKey rdict', rdict #---------------
-
-
-def check_RegistryKey(key):
- """ check if the key is already there (saved on a previous execution of this script)
- """
- cache = True # data is also saved to a file
- rdict = Registry.GetKey('DXF_Exporter', cache)
- #print 'deb:check_RegistryKey rdict:', rdict #----------------
- if rdict: # if found, get the values saved there
- try:
- item = rdict[key]
- return item
- except:
- #update_RegistryKey() # if data isn't valid rewrite it
- pass
-
-def saveConfig(): #--todo-----------------------------------------------
- """Save settings/config/materials from GUI to INI-file.
-
- Write all config data to INI-file.
- """
- global iniFileName
-
- iniFile = iniFileName.val
- #print 'deb:saveConfig inifFile: ', inifFile #----------------------
- if iniFile.lower().endswith(INIFILE_EXTENSION):
-
- #--todo-- sort key.list for output
- #key_list = GUI_A.keys().val
- #key_list.sort()
- #for key in key_list:
- # l_name, l_data = key, GUI_A[key].val
- # list_A
-
- output_str = '[%s,%s]' %(GUI_A, GUI_B)
- if output_str =='None':
- Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no config-data present to save!')
- else:
- if Blender.sys.exists(iniFile):
- f = file(iniFile, 'r')
- header_str = f.readline()
- f.close()
- if header_str.startswith(INIFILE_HEADER[0:13]):
- if Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
- save_ok = True
- else: save_ok = False
- elif Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile +
- '|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1:
- save_ok = True
- else: save_ok = False
- else: save_ok = True
-
- if save_ok:
- # replace: ',' -> ',\n'
- # replace: '{' -> '\n{\n'
- # replace: '}' -> '\n}\n'
- output_str = ',\n'.join(output_str.split(','))
- output_str = '\n}'.join(output_str.split('}'))
- output_str = '{\n'.join(output_str.split('{'))
- try:
- f = file(iniFile, 'w')
- f.write(INIFILE_HEADER + '\n# this is a comment line\n')
- f.write(output_str)
- f.close()
- #Draw.PupMenu('DXF-Exporter: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
- except:
- Draw.PupMenu('DXF-Exporter: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
-
- else:
- Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid name/extension for INI-file selected!')
- print "DXF-Exporter: Alert!: no valid INI-file selected."
- if not iniFile:
- if dxfFileName.val.lower().endswith('.dxf'):
- iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
-
-
-def loadConfig(): #remi--todo-----------------------------------------------
- """Load settings/config/materials from INI-file.
-
- TODO: Read material-assignements from config-file.
- """
- #20070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
- global iniFileName, GUI_A, GUI_B
-
- iniFile = iniFileName.val
- update_RegistryKey('iniFileName', iniFile)
- #print 'deb:loadConfig iniFile: ', iniFile #----------------------
- if iniFile.lower().endswith(INIFILE_EXTENSION) and Blender.sys.exists(iniFile):
- f = file(iniFile, 'r')
- header_str = f.readline()
- if header_str.startswith(INIFILE_HEADER):
- data_str = f.read()
- f.close()
- #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #-----------------
- data = eval(data_str)
- for k, v in data[0].iteritems():
- try: GUI_A[k].val = v
- except: GUI_A[k] = Draw.Create(v)
- for k, v in data[1].iteritems():
- try: GUI_B[k].val = v
- except: GUI_B[k] = Draw.Create(v)
- else:
- f.close()
- Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
- else:
- Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid INI-file selected!')
- print "DXF-Exporter: Alert!: no valid INI-file selected."
- if not iniFileName:
- if dxfFileName.val.lower().endswith('.dxf'):
- iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
-
-
-
-def updateConfig(keywords, drawTypes): #-----------------------------------------------
- """updates GUI_settings with given dictionaries
-
- """
- global GUI_A, GUI_B
- #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
- for k, v in keywords.iteritems():
- GUI_A[k].val = v
- for k, v in drawTypes.iteritems():
- GUI_B[k].val = v
-
-def resetDefaultConfig(): #-----------------------------------------------
- """Resets settings/config/materials to defaults.
-
- """
- #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
- updateConfig(keywords_org, drawTypes_org)
-
-
-def presetConfig_polyline(activate): #-----------------------------------------------
- """Sets settings/config for polygon representation: POLYLINE(FACE) or LINEs/3DFACEs.
-
- """
- global GUI_A
- if activate:
- GUI_A['to_polyline_on'].val = 1
- GUI_A['mesh_as'].val = 1
- GUI_A['curve_as'].val = 1
- else:
- GUI_A['to_polyline_on'].val = 0
- GUI_A['mesh_as'].val = 0
- GUI_A['curve_as'].val = 0
-
-def resetDefaultConfig_2D(): #-----------------------------------------------
- """Sets settings/config/materials to defaults 2D.
-
- """
- keywords2d = {
- 'projection_on' : 1,
- 'fill_on' : 1,
- 'text_as' : 0,
- 'group_as' : 0,
- }
-
- drawTypes2d = {
- 'bmesh' : 1,
- 'bcurve': 1,
- 'surface':0,
- 'bmeta' : 0,
- 'text' : 1,
- 'empty' : 1,
- 'group' : 1,
- 'parent' : 1,
- #'proxy' : 0,
- #'camera': 0,
- #'lamp' : 0,
-
- }
- presetConfig_polyline(1)
- updateConfig(keywords2d, drawTypes2d)
-
-def resetDefaultConfig_3D(): #-----------------------------------------------
- """Sets settings/config/materials to defaults 3D.
-
- """
- keywords3d = {
- 'projection_on' : 0,
- 'fill_on' : 0,
- 'text_as' : 0,
- 'group_as' : 0,
- }
-
- drawTypes3d = {
- 'bmesh' : 1,
- 'bcurve': 1,
- 'surface':0,
- 'bmeta' : 0,
- 'text' : 0,
- 'empty' : 1,
- 'group' : 1,
- 'parent' : 1,
- #'proxy' : 0,
- #'camera': 1,
- #'lamp' : 1,
- }
- presetConfig_polyline(1)
- updateConfig(keywords3d, drawTypes3d)
-
-
-def inputGlobalScale():
- """Pop-up UI-Block for global scale factor
- """
- global GUI_A
- #print 'deb:inputGlobalScale ##########' #------------
- x_scale = Draw.Create(GUI_A['g_scale'].val)
- block = []
- #block.append("global translation vector:")
- block.append(("", x_scale, 0.0, 10000000.0))
-
- retval = Draw.PupBlock("set global scale factor:", block)
-
- GUI_A['g_scale'].val = float(x_scale.val)
-
-
-def inputOriginVector():
- """Pop-up UI-Block for global translation vector
- """
- global GUI_A
- #print 'deb:inputOriginVector ##########' #------------
- x_origin = Draw.Create(GUI_A['g_originX'].val)
- y_origin = Draw.Create(GUI_A['g_originY'].val)
- z_origin = Draw.Create(GUI_A['g_originZ'].val)
- block = []
- #block.append("global translation vector:")
- block.append(("X: ", x_origin, -100000000.0, 100000000.0))
- block.append(("Y: ", y_origin, -100000000.0, 100000000.0))
- block.append(("Z: ", z_origin, -100000000.0, 100000000.0))
-
- retval = Draw.PupBlock("set global translation vector:", block)
-
- GUI_A['g_originX'].val = x_origin.val
- GUI_A['g_originY'].val = y_origin.val
- GUI_A['g_originZ'].val = z_origin.val
-
-
-def update_globals(): #-----------------------------------------------------------------
- """ update globals if GUI_A changed
- """
- global ONLYSELECTED,ONLYVISIBLE, DEBUG,\
- PROJECTION, HIDDEN_LINES, CAMERA, \
- G_SCALE, G_ORIGIN,\
- PREFIX, LAYERNAME_DEF, LAYERCOLOR_DEF, LAYERLTYPE_DEF,\
- APPLY_MODIFIERS, INCLUDE_DUPLIS,\
- OUTPUT_DWG
- #global POLYLINES
-
- ONLYSELECTED = GUI_A['only_selected_on'].val
- ONLYVISIBLE = GUI_A['only_visible_on'].val
- """
- POLYLINES = GUI_A['to_polyline_on'].val
- if GUI_A['curve_as'].val==1: POLYLINES=1
- else: POLYLINES=0
- """
-
- if GUI_A['optimization'].val==0: DEBUG = 1
- else: DEBUG = 0
- PROJECTION = GUI_A['projection_on'].val
- HIDDEN_LINES = GUI_A['hidden_lines_on'].val
- CAMERA = GUI_A['camera_selected'].val
- G_SCALE = GUI_A['g_scale'].val
- if GUI_A['g_origin_on'].val:
- G_ORIGIN[0] = GUI_A['g_originX'].val
- G_ORIGIN[1] = GUI_A['g_originY'].val
- G_ORIGIN[2] = GUI_A['g_originZ'].val
- if GUI_A['g_scale_on'].val:
- G_ORIGIN[0] *= G_SCALE
- G_ORIGIN[1] *= G_SCALE
- G_ORIGIN[2] *= G_SCALE
-
- PREFIX = GUI_A['prefix_def'].val
- LAYERNAME_DEF = GUI_A['layername_def'].val
- LAYERCOLOR_DEF = GUI_A['layercolor_def'].val
- LAYERLTYPE_DEF = layerltype_def_list[GUI_A['layerltype_def'].val]
-
- APPLY_MODIFIERS = GUI_A['apply_modifiers_on'].val
- INCLUDE_DUPLIS = GUI_A['include_duplis_on'].val
- OUTPUT_DWG = GUI_A['outputDWG_on'].val
- #print 'deb: GUI HIDDEN_LINES=', HIDDEN_LINES #---------
- #print 'deb: GUI GUI_A: ', GUI_A['hidden_lines_on'].val #---------------
- #print 'deb: GUI GUI_B: ', GUI_B #---------------
-
-
-def draw_UI(): #-----------------------------------------------------------------
- """ Draw startUI and setup Settings.
- """
- global GUI_A, GUI_B #__version__
- global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
- global model_space_on
- global SCROLL
-
- global mPAN_X, menu_orgX, mPAN_Xmax
- global mPAN_Y, menu_orgY, mPAN_Ymax
- global menu__Area, headerArea, screenArea, scrollArea
-
- size=Buffer(GL_FLOAT, 4)
- glGetFloatv(GL_SCISSOR_BOX, size) #window X,Y,sizeX,sizeY
- size= size.list
- #print '-------------size:', size #--------------------------
- for s in [0,1,2,3]: size[s]=int(size[s])
- window_Area = [0,0,size[2],size[3]-2]
- scrollXArea = [0,0,window_Area[2],15]
- scrollYArea = [0,0,15,window_Area[3]]
-
- menu_orgX = -mPAN_X
- #menu_orgX = 0 #scrollW
- #if menu_pan: menu_orgX -= mPAN_X
- if menu_orgX < -mPAN_Xmax: menu_orgX, mPAN_X = -mPAN_Xmax,mPAN_Xmax
- if menu_orgX > 0: menu_orgX, mPAN_X = 0,0
-
- menu_orgY = -mPAN_Y
- #if menu_pan: menu_orgY -= mPAN_Y
- if menu_orgY < -mPAN_Ymax: menu_orgY, mPAN_Y = -mPAN_Ymax,mPAN_Ymax
- if menu_orgY > 0: menu_orgY, mPAN_Y = 0,0
-
-
- menu_margin = 10
- butt_margin = 10
- common_column = int((window_Area[2] - (3 * butt_margin) - (2 * menu_margin)-30) / 4.0)
- common_column = 70
- # This is for easy layout changes
- but_0c = common_column #button 1.column width
- but_1c = common_column #button 1.column width
- but_2c = common_column #button 2.column
- but_3c = common_column #button 3.column
- menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width
-
- simple_menu_h = 260
- extend_menu_h = 345
- menu_h = simple_menu_h # y is menu upper.y
- if config_UI.val:
- menu_h += extend_menu_h
-
- mPAN_Xmax = menu_w-window_Area[2]+50
- mPAN_Ymax = menu_h-window_Area[3]+30
-
- y = menu_h
- x = 0 #menu left.x
- x +=menu_orgX+20
- y +=menu_orgY+20
-
-
- but0c = x + menu_margin #buttons 0.column position.x
- but1c = but0c + but_0c + butt_margin
- but2c = but1c + but_1c + butt_margin
- but3c = but2c + but_2c + butt_margin
- but4c = but3c + but_3c
-
- # Here starts menu -----------------------------------------------------
- #glClear(GL_COLOR_BUFFER_BIT)
- #glRasterPos2d(8, 125)
-
-
- ui_box(x, y, x+menu_w+menu_margin*2, y-menu_h)
- y -= 20
- Draw.Label("DXF(r12)-Exporter v" + __version__, but0c, y, menu_w, 20)
-
- if config_UI.val:
- b0, b0_ = but0c, but_0c-20 + butt_margin
- b1, b1_ = but1c-20, but_1c+20
- y_top = y
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_B['bmesh'] = Draw.Toggle('Mesh', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmesh'].val, "Export Mesh-Objects on/off")
- if GUI_B['bmesh'].val:
- GUI_A['mesh_as'] = Draw.Menu(mesh_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['mesh_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['bcurve'] = Draw.Toggle('Curve', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bcurve'].val, "Export Curve-Objects on/off")
- if GUI_B['bcurve'].val:
- GUI_A['curve_as'] = Draw.Menu(curve_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['curve_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['surface'] = Draw.Toggle('..Surface', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['surface'].val, "(*todo) Export Surface-Objects on/off")
- if GUI_B['surface'].val:
- GUI_A['surface_as'] = Draw.Menu(surface_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['surface_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['bmeta'] = Draw.Toggle('..Meta', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmeta'].val, "(*todo) Export Meta-Objects on/off")
- if GUI_B['bmeta'].val:
- GUI_A['meta_as'] = Draw.Menu(meta_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['meta_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['text'] = Draw.Toggle('Text', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['text'].val, "Export Text-Objects on/off")
- if GUI_B['text'].val:
- GUI_A['text_as'] = Draw.Menu(text_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['text_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['empty'] = Draw.Toggle('Empty', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['empty'].val, "Export Empty-Objects on/off")
- if GUI_B['empty'].val:
- GUI_A['empty_as'] = Draw.Menu(empty_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['empty_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y_down = y
- # -----------------------------------------------
-
- y = y_top
- b0, b0_ = but2c, but_2c-20 + butt_margin
- b1, b1_ = but3c-20, but_3c+20
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_B['group'] = Draw.Toggle('..Group', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['group'].val, "(*todo) Export Group-Relationships on/off")
- if GUI_B['group'].val:
- GUI_A['group_as'] = Draw.Menu(group_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['group_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['parent'] = Draw.Toggle('..Parent', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['parent'].val, "(*todo) Export Parent-Relationships on/off")
- if GUI_B['parent'].val:
- GUI_A['parent_as'] = Draw.Menu(parent_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['parent_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['proxy'] = Draw.Toggle('..Proxy', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['proxy'].val, "(*todo) Export Proxy-Objects on/off")
- if GUI_B['proxy'].val:
- GUI_A['proxy_as'] = Draw.Menu(proxy_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['proxy_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['camera'] = Draw.Toggle('Camera', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['camera'].val, "(*wip) Export Camera-Objects on/off")
- if GUI_B['camera'].val:
- GUI_A['camera_as'] = Draw.Menu(camera_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['camera_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['lamp'] = Draw.Toggle('Lamp', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['lamp'].val, "(*wip) Export Lamp-Objects on/off")
- if GUI_B['lamp'].val:
- GUI_A['lamp_as'] = Draw.Menu(lamp_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['lamp_as'].val, "Select target DXF-object")
- Draw.EndAlign()
-
-
- if y < y_down: y_down = y
- # -----end supported objects--------------------------------------
-
- y_top = y_down
- y = y_top
- y -= 10
- y -= 20
- but_ = menu_w / 6
- b0 = but0c + (menu_w - but_*6)/2
- Draw.BeginAlign()
- #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['dummy_on'].val, "placeholder only on/off")
- GUI_A['paper_space_on'] = Draw.Toggle('Paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "Export to Paper-Space, otherwise to Model-Space on/off")
- GUI_A['layFrozen_on'] = Draw.Toggle ('..frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "(*todo) Support LAYER.frozen status on/off")
- GUI_A['materialFilter_on'] = Draw.Toggle('..material', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['materialFilter_on'].val, "(*todo) Material filtering on/off")
- GUI_A['colorFilter_on'] = Draw.Toggle('..color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*todo) Color filtering on/off")
- GUI_A['groupFilter_on'] = Draw.Toggle('..group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*todo) Group filtering on/off")
- GUI_A['objectFilter_on'] = Draw.Toggle('..object', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['objectFilter_on'].val, "(*todo) Object filtering on/off")
- Draw.EndAlign()
-
- # -----end filters--------------------------------------
-
- b0, b0_ = but0c, but_0c + butt_margin
- b1, b1_ = but1c, but_1c
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_A['g_origin_on'] = Draw.Toggle('Location', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "Global relocate all objects on/off")
- if GUI_A['g_origin_on'].val:
- tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "Edit relocation-vector (x,y,z in DXF units)")
- origin_str = '(%.4f, %.4f, %.4f)' % (
- GUI_A['g_originX'].val,
- GUI_A['g_originY'].val,
- GUI_A['g_originZ'].val
- )
- tmp = Draw.Label(origin_str, b1+20, y, 300, 20)
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['g_scale_on'] = Draw.Toggle('Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "Global scale all objects on/off")
- if GUI_A['g_scale_on'].val:
- g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "Factor for scaling the DXFdata")
- if g_scale_as.val == 12:
- pass
- else:
- if g_scale_as.val == 6: #scale inches to meters
- GUI_A['g_scale'].val = 0.0254000
- elif g_scale_as.val == 7: #scale feets to meters
- GUI_A['g_scale'].val = 0.3048000
- elif g_scale_as.val == 8: #scale yards to meters
- GUI_A['g_scale'].val = 0.9144000
- else:
- GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val)
- scale_float = GUI_A['g_scale'].val
- if scale_float < 0.000001 or scale_float > 1000000:
- scale_str = ' = %s' % GUI_A['g_scale'].val
- else:
- scale_str = ' = %.6f' % GUI_A['g_scale'].val
- Draw.Label(scale_str, b1+45, y, 200, 20)
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['Z_force_on'] = Draw.Toggle('Elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, "Overwrite Z-coordinates (flatten geometry) on/off")
- if GUI_A['Z_force_on'].val:
- GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "Set value for default Z-coordinate (in DXF units)")
- Draw.EndAlign()
-
- """
- y -= 30
- Draw.BeginAlign()
- GUI_A['material_on'] = Draw.Toggle('.material', EVENT_REDRAW, b0, y, b0_-20, 20, GUI_A['material_on'].val, "Support for material assignment on/off")
- if GUI_A['material_on'].val:
- GUI_A['material_to'] = Draw.Menu(material_to_menu, EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_to'].val, "Material assigned to?")
- Draw.EndAlign()
- """
-
- #b0, b0_ = but0c, but_0c + butt_margin
- b0, b0_ = but0c, 50
- b1, b1_ = b0+b0_, but_0c-b0_+ but_1c + butt_margin
- b2, b2_ = but2c, but_2c
- b3, b3_ = but3c, but_3c
-
- y -= 30
- Draw.Label('Output:', b0, y, b0_, 20)
- Draw.Label('LAYER:', b1, y, b1_, 20)
- Draw.Label('COLOR:', b2, y, b2_, 20)
- Draw.Label('LINETYPE:', b3, y, b3_, 20)
- #Draw.Label('LINESIZE:', b4, y, b4_, 20)
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['prefix_def'] = Draw.String('', EVENT_NONE, b0, y, b0_, 20, GUI_A['prefix_def'].val, 10, "Type Prefix for LAYERs")
- GUI_A['layername_def'] = Draw.String('', EVENT_NONE, b1, y, b1_, 20, GUI_A['layername_def'].val, 10, "Type default LAYER name")
- GUI_A['layercolor_def'] = Draw.Number('', EVENT_NONE, b2, y, b2_, 20, GUI_A['layercolor_def'].val, 1, 255, "Set default COLOR. (0=BYBLOCK,256=BYLAYER)")
- GUI_A['layerltype_def'] = Draw.Menu(layerltype_def_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['layerltype_def'].val, "Set default LINETYPE")
- Draw.EndAlign()
-
- y -= 25
- Draw.Label('Style:', b0, y, b0_, 20)
- Draw.BeginAlign()
- GUI_A['entitylayer_from'] = Draw.Menu(entitylayer_from_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['entitylayer_from'].val, "entity LAYER assigned to?")
- GUI_A['entitycolor_from'] = Draw.Menu(entitycolor_from_menu, EVENT_NONE, b2, y, b2_, 20, GUI_A['entitycolor_from'].val, "entity COLOR assigned to?")
- GUI_A['entityltype_from'] = Draw.Menu(entityltype_from_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['entityltype_from'].val, "Set entity LINETYPE")
- Draw.EndAlign()
-
- y -= 10
-
- y_down = y
- # -----end material,translate,scale------------------------------------------
-
-
- #--------------------------------------
- y_top = y_down
- y = y_top
-
- y -= 30
- Draw.BeginAlign()
- Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file with file selector')
- iniFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_1c-60, 20, iniFileName.val, FILENAME_MAX, "Write here the name of the INI-file")
- but = but4c-60
- Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "Toggle Preset-INI-files")
- Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from selected ini-file: %s' % iniFileName.val)
- Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to selected ini-file: %s' % iniFileName.val)
- Draw.EndAlign()
-
- bm = butt_margin/2
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file with file selector')
- dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_0c-menu_margin, 20, dxfFileName.val, FILENAME_MAX, "Type path/name of output DXF-file")
- Draw.EndAlign()
-
- y -= 30
- config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' )
- Draw.BeginAlign()
- but, but_ = but1c, but_1c+bm
- but_ /= 3
- Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "Reset configuration to defaults")
- Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'Set to standard configuration for 2D export')
- Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'Set to standard configuration for 3D import')
- Draw.EndAlign()
-
-
- y -= 30
- b0, b0_ = but0c, but_0c + butt_margin +but_1c
- GUI_A['only_selected_on'] = Draw.Toggle('Export Selection', EVENT_NONE, b0, y, b0_, 20, GUI_A['only_selected_on'].val, "Export only selected geometry on/off")
- b0, b0_ = but2c, but_2c + butt_margin + but_3c
- Draw.BeginAlign()
- GUI_A['projection_on'] = Draw.Toggle('2d Projection', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['projection_on'].val, "Export a 2d Projection according 3d-View or Camera-View on/off")
- if GUI_A['projection_on'].val:
- GUI_A['camera_selected'] = Draw.Menu(MenuCAMERA, EVENT_CAMERA, b0, y-20, b0_-20, 20, GUI_A['camera_selected'].val, 'Choose the camera to be rendered')
- Draw.PushButton('>', EVENT_setCAMERA, b0+b0_-20, y-20, 20, 20, 'switch to selected Camera - make it active')
- GUI_A['hidden_lines_on'] = Draw.Toggle('Remove backFaces', EVENT_NONE, b0, y-40, b0_, 20, GUI_A['hidden_lines_on'].val, "Filter out backFaces on/off")
- #GUI_A['shadows_on'] = Draw.Toggle('..Shadows', EVENT_REDRAW, b0, y-60, but_2c, 20, GUI_A['shadows_on'].val, "(*todo) Shadow tracing on/off")
- #GUI_A['light_on'] = Draw.Menu(MenuLIGHT, EVENT_LIGHT, but3c, y-60, but_3c, 20, GUI_A['light_on'].val, '(*todo) Choose the light source(sun) to be rendered')
- Draw.EndAlign()
-
- y -= 20
- b0, b0_ = but0c, but_0c + butt_margin +but_1c
- GUI_A['only_visible_on'] = Draw.Toggle('Visible only', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['only_visible_on'].val, "Export only from visible layers on/off")
- #b0, b0_ = but2c, but_2c + butt_margin + but_3c
-
- y -= 20
- b0, b0_ = but0c, but_0c + butt_margin +but_1c
- GUI_A['to_polyline_on'] = Draw.Toggle('POLYLINE-Mode', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['to_polyline_on'].val, "Export to POLYLINE/POLYFACEs, otherwise to LINEs/3DFACEs on/off")
- #b0, b0_ = but2c, but_2c + butt_margin + but_3c
-
- y -= 20
- b0, b0_ = but0c, but_0c + butt_margin +but_1c
- GUI_A['instances_on'] = Draw.Toggle('Instances as BLOCKs', EVENT_NONE, b0, y, b0_, 20, GUI_A['instances_on'].val, "Export instances (multi-users) of Mesh/Curve as BLOCK/INSERTs on/off")
- #b0, b0_ = but2c, but_2c + butt_margin + but_3c
-
- y -= 20
- b0, b0_ = but0c, but_0c + butt_margin +but_1c
- GUI_A['apply_modifiers_on'] = Draw.Toggle('Apply Modifiers', EVENT_NONE, b0, y, b0_, 20, GUI_A['apply_modifiers_on'].val, "Apply modifier stack to mesh objects before export on/off")
- #b0, b0_ = but2c, but_2c + butt_margin + but_3c
-
- y -= 20
- b0, b0_ = but0c, but_0c + butt_margin +but_1c
- GUI_A['include_duplis_on'] = Draw.Toggle('Include Duplis', EVENT_NONE, b0, y, b0_, 20, GUI_A['include_duplis_on'].val, "Export Duplicates (dupliverts, dupliframes, dupligroups) on/off")
- #b0, b0_ = but2c, but_2c + butt_margin + but_3c
-
-
-
- y -= 30
- Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' )
- Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'goes to online-Manual on wiki.blender.org')
- GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/Draw-in, 1=Verbose, 2=ProgressBar, 3=SilentMode")
- GUI_A['outputDWG_on'] = Draw.Toggle('DWG*', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['outputDWG_on'].val, "converts DXF to DWG (needs external converter) on/off")
-
- Draw.BeginAlign()
- Draw.PushButton('START EXPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the export process. For Cancel go to console and hit Ctrl-C')
- Draw.EndAlign()
-
- y -= 20
- #Draw.BeginAlign()
- #Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
- #Draw.Label(LAB, but0c, y, menu_w, 20)
- Draw.Label(LAB, 30, y, menu_w, 20)
- #Draw.Label(' ', but0c+menu_w, y, menu_margin, 20)
- #Draw.EndAlign()
-
- ui_scrollbarX(menu_orgX, menu_w+50, scrollXArea, c_fg, c_bg)
- ui_scrollbarY(menu_orgY, menu_h+30, scrollYArea, c_fg, c_bg)
-
-
-
-
-#-- END GUI Stuf-----------------------------------------------------
-
-c0=[0.2,0.2,0.2,0.0]
-c1=[0.7,0.7,0.9,0.0]
-c2=[0.71,0.71,0.71,0.0]
-c3=[0.4,0.4,0.4,0.0]
-c4=[0.95,0.95,0.9,0.0]
-c5=[0.64,0.64,0.64,0]
-c6=[0.75,0.75,0.75,0]
-c7=[0.6,0.6,0.6,0]
-c8=[1.0,0.0,0.0,0]
-c9=[0.7,0.0,0.0,0]
-c10=[0.64,0.81,0.81,0]
-c11=[0.57,0.71,0.71,0]
-c_nor= c5[:3]
-c_act= c10[:3]
-c_sel= c11[:3]
-c_tx = c0[:3]
-c_fg = c2[:3]
-c_bg = c5[:3]
-
-def ui_rect(coords,color):
- [X1,Y1,X2,Y2],[r,g,b] = coords,color
- glColor3f(r,g,b)
- glRecti(X1,Y1,X2,Y2)
-def ui_rectA(coords,color):
- [X1,Y1,X2,Y2],[r,g,b,a] = coords,color
- glColor4f(r,g,b,a)
- glRecti(X1,Y1,X2,Y2) #integer coords
- #glRectf(X1,Y1,X2,Y2) #floating coords
-def ui_line(coords,color):
- [X1,Y1,X2,Y2],[r,g,b] = coords,color
- glColor3f(r,g,b)
- glBegin(GL_LINES)
- glVertex2i(X1,Y1)
- glVertex2i(X2,Y2)
- glEnd()
-def ui_panel(posX,posY,L,H,color):
- [r,g,b] = color
- ui_rect([posX+4,posY-4,posX+L+4,posY-H-4],[.55,.55,.55]) #1st shadow
- ui_rect([posX+3,posY-3,posX+L+3,posY-H-3],[.45,.45,.45])
- ui_rect([posX+3,posY-3,posX+L+2,posY-H-2],[.30,.30,.30]) #2nd shadow
- ui_rect([posX,posY-H,posX+L,posY],[r,g,b]) #Main
- ui_rect([posX+3,posY-19,posX+L-3,posY-2],[.75*r,.75*g,.75*b]) #Titlebar
- ui_line([posX+3,posY-19,posX+3,posY-2],[.25,.25,.25])
- ui_line([posX+4,posY-19,posX+4,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4])
- ui_line([posX+4,posY-2,posX+L-3,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4])
-def ui_box(x,y,xright,bottom):
- color = [0.75, 0.75, 0.75]
- coords = x+1,y+1,xright-1,bottom-1
- ui_rect(coords,color)
-
-def ui_scrollbarX(Focus,PanelH,Area, color_fg, color_bg):
- # Area = ScrollBarArea
- # point1=down/left, point2=top/right
- P1X,P1Y,P2X,P2Y = Area
- AreaH = P2X-P1X
- if PanelH > AreaH:
- Slider = int(AreaH * (AreaH / float(PanelH)))
- if Slider<3: Slider = 3 #minimal slider heigh
- posX = -int(AreaH * (Focus / float(PanelH)))
- ui_rect([P1X,P1Y,P2X,P2Y], color_bg)
- ui_rect([P1X+posX,P1Y+3,P1X+posX+Slider,P2Y-3], color_fg)
-
-def ui_scrollbarY(Focus,PanelH,Area, color_fg, color_bg):
- # Area = ScrollBarArea
- # point1=down/left, point2=top/right
- P1X,P1Y,P2X,P2Y = Area
- AreaH = P2Y-P1Y
- if PanelH > AreaH:
- Slider = int(AreaH * (AreaH / float(PanelH)))
- if Slider<3: Slider = 3 #minimal slider heigh
- posY = -int(AreaH * (Focus / float(PanelH)))
- ui_rect([P1X,P1Y,P2X-1,P2Y], color_bg)
- #ui_rect([P1X+3,P2Y-posY,P2X-4,P2Y-posY-Slider], color_fg)
- ui_rect([P1X+3,P1Y+posY,P2X-4,P1Y+posY+Slider], color_fg)
-
-
-#------------------------------------------------------------
-def dxf_callback(input_filename):
- global dxfFileName
- dxfFileName.val=input_filename
-# dirname == Blender.sys.dirname(Blender.Get('filename'))
-# update_RegistryKey('DirName', dirname)
-# update_RegistryKey('dxfFileName', input_filename)
-
-def ini_callback(input_filename):
- global iniFileName
- iniFileName.val=input_filename
-
-#------------------------------------------------------------
-def getSpaceRect():
- __UI_RECT__ = Buffer(GL_FLOAT, 4)
- glGetFloatv(GL_SCISSOR_BOX, __UI_RECT__)
- __UI_RECT__ = __UI_RECT__.list
- return (int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2]), int(__UI_RECT__[3]))
-
-def getRelMousePos(mco, winRect):
- # mco = Blender.Window.GetMouseCoords()
- if pointInRect(mco, winRect):
- return (mco[0] - winRect[0], mco[1] - winRect[1])
- return None
-
-
-def pointInRect(pt, rect):
- if rect[0] < pt[0] < rect[0]+rect[2] and\
- rect[1] < pt[1] < rect[1]+rect[3]:
- return True
- else:
- return False
-
-
-
-#--- variables UI menu ---------------------------
-mco = [0,0] # mouse coordinaten
-mbX, mbY = 0,0 # mouse buffer coordinaten
-scrollW = 20 # width of scrollbar
-rowH = 20 # height of menu raw
-menu__H = 2 * rowH +5 # height of menu bar
-headerH = 1 * rowH # height of column header bar
-scroll_left = True # position of scrollbar
-menu_bottom = False # position of menu
-edit_mode = False # indicator/activator
-iconlib_mode = False # indicator/activator
-icon_maps = [] #[['blenderbuttons.png',12,25,20,21],
-#['referenceicons.png',12,25,20,21]]
-help_text = False # indicator/activator
-menu_pan = False # indicator/activator
-compact_DESIGN = True # toggle UI
-showLINK = True # toggle Links
-filterList=[-1,-1,-1,-1,-1]
-dubbleclik_delay = 0.25
-
-PAN_X,PAN_Y = 0,0 # pan coordinates in characters
-mPAN_X,mPAN_Y = 0,0 # manu pan coordinates in characters
-menu_orgX = 0
-menu_orgY = 0
-mPAN_Xmax = 800
-mPAN_Ymax = 800
-
-
-#------------------------------------------------------------
-def event(evt, val):
- global mbX, mbY, UP, UP0, scroll_pan, FOCUS_fix
- global menu_bottom, scroll_left, mco
- global PAN_X, PAN_Y, PAN_X0, PAN_Y0
- global mPAN_X, mPAN_Y, mPAN_X0, mPAN_Y0, menu_pan
-
- #if Blender.event:
- # print 'Blender.event:%s, evt:%s' %(Blender.event, evt) #------------
-
- if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
- print 'DXF-Exporter *** end ***' #---------------------
- Draw.Exit()
-
- elif val:
- if evt==Draw.MIDDLEMOUSE:
- mco2 = Window.GetMouseCoords()
- relativeMouseCo = getRelMousePos(mco2, getSpaceRect())
- if relativeMouseCo != None:
- #rect = [menu__X1,menu__Y1,menu__X2,menu__Y2]
- if 1: #pointInRect(relativeMouseCo, menu__Area):
- menu_pan = True
- mPAN_X0 = mPAN_X
- mPAN_Y0 = mPAN_Y
- mco = mco2
- elif evt == Draw.MOUSEY or evt == Draw.MOUSEX:
- if menu_pan:
- mco2 = Window.GetMouseCoords()
- mbX = mco2[0]-mco[0]
- mbY = mco2[1]-mco[1]
- mPAN_X = mPAN_X0 - mbX
- mPAN_Y = mPAN_Y0 - mbY
- #print mbX, mbY #--------------------
- Draw.Redraw()
- elif evt == Draw.WHEELDOWNMOUSE:
- mPAN_Y -= 80
- Draw.Redraw()
- elif evt == Draw.WHEELUPMOUSE:
- mPAN_Y += 80
- Draw.Redraw()
- else: # = if val==False:
- if evt==Draw.LEFTMOUSE:
- scroll_pan = False
- elif evt==Draw.MIDDLEMOUSE:
- menu_pan = False
-
-def bevent(evt):
- global config_UI, user_preset
- global CAMERA, GUI_A
-
- ######### Manages GUI events
- if (evt==EVENT_EXIT):
- Draw.Exit()
- print 'DXF-Exporter *** end ***' #---------------------
- elif (evt==EVENT_CHOOSE_INI):
- Window.FileSelector(ini_callback, "INI-file Selection", '*.ini')
- elif (evt==EVENT_REDRAW):
- Draw.Redraw()
- elif (evt==EVENT_RESET):
- resetDefaultConfig()
- Draw.Redraw()
- elif (evt==EVENT_PRESET2D):
- resetDefaultConfig_2D()
- Draw.Redraw()
- elif (evt==EVENT_PRESET3D):
- resetDefaultConfig_3D()
- Draw.Redraw()
- elif evt in (EVENT_CAMERA,EVENT_LIGHT):
- CAMERA = GUI_A['camera_selected'].val
- if CAMERA==len(CAMERAS)+1:
- doAllCameras = True
- else:
- pass #print 'deb: CAMERAS=',CAMERAS #----------------
- Draw.Redraw()
- elif (evt==EVENT_setCAMERA):
- if CAMERA<len(CAMERAS)+1:
- gotoCAMERA()
-
- elif (evt==EVENT_SCALE):
- if g_scale_as.val == 12:
- inputGlobalScale()
- if GUI_A['g_scale'].val < 0.00000001:
- GUI_A['g_scale'].val = 0.00000001
- Draw.Redraw()
- elif (evt==EVENT_ORIGIN):
- inputOriginVector()
- Draw.Redraw()
- elif (evt==EVENT_PRESETPLINE):
- presetConfig_polyline(GUI_A['to_polyline_on'].val)
- Draw.Redraw()
- elif (evt==EVENT_PRESETS):
- user_preset += 1
- index = str(user_preset)
- if user_preset > 5: user_preset = 0; index = ''
- iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
- Draw.Redraw()
- elif (evt==EVENT_HELP):
- try:
- import webbrowser
- webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
- except:
- Draw.PupMenu('DXF-Exporter: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\
-http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
- Draw.Redraw()
- elif (evt==EVENT_LOAD_INI):
- loadConfig()
- Draw.Redraw()
- elif (evt==EVENT_SAVE_INI):
- saveConfig()
- Draw.Redraw()
- elif (evt==EVENT_DXF_DIR):
- dxfFile = dxfFileName.val
- dxfPathName = ''
- if '/' in dxfFile:
- dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/'
- elif '\\' in dxfFile:
- dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\'
- dxfFileName.val = dxfPathName + '*.dxf'
-# dirname == Blender.sys.dirname(Blender.Get('filename'))
-# update_RegistryKey('DirName', dirname)
-# update_RegistryKey('dxfFileName', dxfFileName.val)
- GUI_A['only_selected_on'].val = 1
- Draw.Redraw()
- elif (evt==EVENT_CHOOSE_DXF):
- filename = '' # '*.dxf'
- if dxfFileName.val: filename = dxfFileName.val
- Window.FileSelector(dxf_callback, "DXF-file Selection", filename)
- elif (evt==EVENT_START):
- dxfFile = dxfFileName.val
- #print 'deb: dxfFile file: ', dxfFile #----------------------
- if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode
- update_RegistryKey('dxfFileName', dxfFileName.val)
- update_globals()
- if dxfFile.lower().endswith('*.dxf'):
- if Draw.PupMenu('DXF-Exporter: OK?|will write multiple DXF-files, one for each Scene, in:|%s' % dxfFile) == 1:
- global UI_MODE
- UI_MODE = False
- #TODO: multi_export(dxfFile[:-5]) # cut last 5 characters '*.dxf'
- Draw.Redraw()
- UI_MODE = True
- else:
- Draw.Redraw()
- elif dxfFile.lower()[-4:] in ('.dxf','.dwg'): # and Blender.sys.exists(dxfFile):
- print 'preparing for export ---' #Standard Mode: activated
- filepath = dxfFile
- sce = Scene.GetCurrent()
- if ONLYSELECTED: sel_group = sce.objects.selected
- else: sel_group = sce.objects
-
- if ONLYVISIBLE:
- sel_group_temp = []
- layerlist = sce.getLayers()
- for ob in sel_group:
- for lay in ob.layers:
- if lay in layerlist:
- sel_group_temp.append(ob)
- break
- sel_group = sel_group_temp
-
- export_list = getObjectsAndDuplis(sel_group,MATRICES=True)
-
- if export_list: do_export(export_list, filepath)
- else:
- print "Abort: selection was empty, no object to export!"
- Draw.PupMenu('DXF Exporter: nothing exported!|empty selection!')
- else:
- Draw.PupMenu('DXF-Exporter: Alert!%t|no valid DXF-file selected!')
- print "DXF-Exporter: error, no valid DXF-file selected! try again"
- Draw.Redraw()
-
-
-
-
-def multi_export(DIR): #TODO:
- """Imports all DXF-files from directory DIR.
-
- """
- global SCENE
- batchTIME = Blender.sys.time()
- #if #DIR == "": DIR = os.path.curdir
- if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename'))
- print 'Multifiles Import from %s' %DIR
- files = \
- [Blender.sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')]
- if not files:
- print '...None DXF-files found. Abort!'
- return
-
- i = 0
- for dxfFile in files:
- i += 1
- print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile
- if ONLYSELECTED:
- _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
- _dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
- _dxf_file = _dxf_file[:NAMELENGTH_MAX] #? [-NAMELENGTH_MAX:])
- SCENE = Blender.Scene.New(_dxf_file)
- SCENE.makeCurrent()
- #or so? Blender.Scene.makeCurrent(_dxf_file)
- #sce = bpy.data.scenes.new(_dxf_file)
- #bpy.data.scenes.active = sce
- else:
- SCENE = Blender.Scene.GetCurrent()
- SCENE.objects.selected = [] # deselect all
- main(dxfFile)
- #Blender.Redraw()
-
- print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME)
- print '\a\r', # beep when done
-
-
-#-----------------------------------------------------
-if __name__=='__main__':
-
- if DXF:
- print '\n\n\n'
- print 'DXF-Exporter v%s *** start ***' %(__version__) #---------------------
- print 'with Library %s' %(DXF.__version__) #---------------------
- if not DXF.copy:
- print "DXF-Exporter: dxfLibrary.py script requires a full Python install"
- Draw.PupMenu('Error%t|The dxfLibrary.py script requires a full Python install')
- else:
- #Window.FileSelector(dxf_export_ui, 'EXPORT DXF', Blender.sys.makename(ext='.dxf'))
- # recall last used DXF-file and INI-file names
- dxffilename = check_RegistryKey('dxfFileName')
- #print 'deb:start dxffilename:', dxffilename #----------------
- if dxffilename: dxfFileName.val = dxffilename
- else:
- dirname = Blender.sys.dirname(Blender.Get('filename'))
- #print 'deb:start dirname:', dirname #----------------
- dxfFileName.val = Blender.sys.join(dirname, '')
- inifilename = check_RegistryKey('iniFileName')
- if inifilename: iniFileName.val = inifilename
-
- updateMenuCAMERA()
- updateCAMERA()
-
- Draw.Register(draw_UI, event, bevent)
-
- \ No newline at end of file
diff --git a/release/scripts/export_lightwave_motion.py b/release/scripts/export_lightwave_motion.py
deleted file mode 100644
index 562e44f3a2b..00000000000
--- a/release/scripts/export_lightwave_motion.py
+++ /dev/null
@@ -1,157 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Lightwave Motion (.mot)...'
-Blender: 241
-Group: 'Export'
-Tip: 'Export Loc Rot Size chanels to a Lightwave .mot file'
-"""
-
-__author__ = "Daniel Salazar (ZanQdo)"
-__url__ = ("blender", "blenderartists.org",
-"e-mail: zanqdo@gmail.com")
-__version__ = "16/04/08"
-
-__bpydoc__ = """\
-This script exports the selected object's motion channels to Lightwave
-motion files (.mot).
-
-Usage:
-Run the script with one or more objects selected (any kind), frames exported
-are between Start and End frames in Render buttons.
-
-"""
-
-# $Id$
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2003, 2004: A Vanpoucke
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-import Blender as B
-import math as M
-#------------------------------------
-#Declarados:
-TotalCanales = 9
-#------------------------------------
-
-def FuncionPrincipal (Dir):
- B.Window.WaitCursor(1)
- ObjSelect = B.Object.GetSelected()
-
- if not ObjSelect:
- B.Draw.PupMenu('Select 1 or more objects, aborting.')
- return
-
- if not Dir.lower().endswith('.mot'):
- Dir += '.mot'
-
-
- SC = B.Scene.GetCurrent()
- SCR = SC.getRenderingContext()
-
- for ob in ObjSelect:
- origName= NombreObjeto= ob.name
- print '----\nExporting Object "%s" motion file...' % origName
-
- FrameA = B.Get('curframe')
- FrameP = B.Get('staframe')
- FrameF = B.Get('endframe')
-
- FrameRate = float(SCR.framesPerSec())
-
- #---------------------------------------------
-
- # Replace danger characters by '_'
- for ch in ' /\\~!@#$%^&*()+=[];\':",./<>?\t\r\n':
- NombreObjeto = NombreObjeto.replace(ch, '_')
-
- # Check for file path extension
- if len(ObjSelect) > 1:
- DirN= '%s_%s.mot' % (Dir[:-4], NombreObjeto)
- else:
- DirN= Dir
-
- # Open the file
- File = open(DirN,'w')
- File.write ('LWMO\n3\n\n') # 3 is the version number.
-
- # number of channels
- File.write ('NumChannels %i\n' % TotalCanales)
-
- # ----------------------------
- # Main Cycle
-
- def CicloPrimario(NumCanal):
- B.Set('curframe', FrameP)
-
- File.write ('Channel %i\n{ Envelope\n %i\n' % (NumCanal, (FrameF - FrameP + 1)))
-
- FrameA = FrameP
- while FrameA < (FrameF + 1):
-
- B.Set('curframe', FrameA)
-
- mat= ob.mat # Worldspace matrix
-
- if NumCanal == 0:
- Val = mat.translationPart().x
- elif NumCanal == 1:
- Val = mat.translationPart().z
- elif NumCanal == 2:
- Val = mat.translationPart().y
- elif NumCanal == 3:
- Val = M.radians (-mat.toEuler().z)
- elif NumCanal == 4:
- Val = M.radians (-mat.toEuler().x)
- elif NumCanal == 5:
- Val = M.radians (-mat.toEuler().y)
- elif NumCanal == 6:
- Val = mat.scalePart().x
- elif NumCanal == 7:
- Val = mat.scalePart().z
- elif NumCanal == 8:
- Val = mat.scalePart().y
- File.write (' Key %f %f 3 0 0 0 0 0 0\n' % (Val, (FrameA/FrameRate)))
-
- FrameA += 1
- # Ending Stuff
- File.write (' Behaviors 1 1\n}\n')
-
- NumObjetoActual = len(ObjSelect)
- Iteraciones = 0
- ProgBarVal = 0.0
- while Iteraciones < TotalCanales:
- CicloPrimario(Iteraciones)
-
- # Start Progress Bar
- B.Window.DrawProgressBar(ProgBarVal, origName)
- ProgBarVal = (float(Iteraciones) / TotalCanales) * 0.98
- Iteraciones += 1
-
- B.Window.DrawProgressBar(1.0, '') # Done
- print '\nDone, %s motion file location is:\n%s\n' % (origName, DirN)
- B.Window.WaitCursor(0)
-
-# Check if there are selected objects
-def main():
- B.Window.FileSelector(FuncionPrincipal, "Write .mot File", B.sys.makename(ext='.mot'))
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/export_m3g.py b/release/scripts/export_m3g.py
deleted file mode 100644
index c74e7acbcd3..00000000000
--- a/release/scripts/export_m3g.py
+++ /dev/null
@@ -1,3074 +0,0 @@
-#!BPY
-# coding: utf-8
-""" Registration info for Blender menus:
-Name: 'M3G (.m3g, .java)...'
-Blender: 244
-Group: 'Export'
-Tooltip: 'Export to M3G'
-"""
-#------------------------------------------------------------------------
-# M3G exporter for blender 2.37 or above
-#
-# Source: http://www.nelson-games.de/bl2m3g/source
-#
-# $Id$
-#
-# Author: Gerhard Völkl
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2005: gerhard völkl gkvoelkl@yahoo.de
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-#
-# To use script:
-# 1.) load this file in the text window.
-# (press SHIFT+F11, Open New via Datablock button)
-# 2.) make sure your mouse is over the text edit window and
-# run this script. (press ALT+P)
-# Or:
-# copy to the scripts directory and it will appear in the
-# export list. (Needs 2.32 or higher)
-#
-# Based on informations from:
-# wrl2export.py from Rick Kimball and others
-# --------------------------------------------------------------------------#
-# History 0.2
-# * maximal Precision in VertexArray (with algorithms from Kalle Raita)
-# * IPO Animation with mesh: Rotation, Translation and Size
-# History 0.3
-# * to find a 3d object in your java programm you can assign a userID
-# your blender object has name 'cube#01' your 3d object will have ID 01
-# the number after '#' is taken
-# * more than one material per mesh can be used
-# * uv texture support (implemented by Aki Koskinen and Juha Laitinen)
-# The image which is bound to the faces will be exportet within m3g-file
-# Limitations by M3G-API:
-# The width and height of the image must be non-negative powers of two,
-# but they need not to be equal. Maximum value is 256.
-# *.java export: Only PNG images can be used.
-# History 0.4
-# * check limitation of texture images (credit to MASTER_ZION for Brasil)
-# * Better light: The light modeles of Blender and M3G are naturally
-# different. So the export script trys to translate as much as possible
-#
-# M3G Light type Blender Light type
-# --------------------------------------------------------------
-# AMIENT Light Not available as light type in Blender
-# DIRECTIONAL Light SUN
-# OMNIdirectional light LAMP
-# SPOT light SPOT
-# not translated HEMI
-# not translated AREA
-#
-# Attributs of M3G Lights:
-#
-# Attenuation (OMNI,SPOT):
-# Intensity of light changes with distance
-# The attenuation factor is 1 / (c + l d + q d2)
-# where d is the distance between the light and the vertex being lighted
-# and c, l, q are the constant, linear, and quadratic coefficients.
-# In Blender exists much complex posibilies. To simplify exporter uses
-# only button Dist: distance at which the light intensity is half
-# the Energy
-# Color (ALL)
-# Color of light
-# Intensity (ALL)
-# The RGB color of this Light is multiplied component-wise with the
-# intensity. In Blender : energy
-# SpotAngle (SPOT)
-# the spot cone angle for this Light
-# In Blender: spotSize
-# SpotExponent (SPOT)
-# The spot exponent controls the distribution of the intensity of
-# this Light within the spot cone, such that larger values yield
-# a more concentrated cone. In Blender: SpotBl
-#
-# * Some GUI for options
-# First prototype of GUI was created using RipSting's Blender-Python
-# GUI designer. Download at Http://oregonstate.edu/~dennisa/Blender/BPG/
-#
-# * Ambiente light
-# Information is taken by world ambiente attribute
-#
-# * Parenting Part 1
-# In Blender the Empty object is used to group objects. All objects
-# which have the same empty as parent are the member of the same group.
-#
-# empty <-- Parent of -- element 1
-# <-- Parent of -- element 2
-#
-# is translated in M3G
-#
-# group-Node -- Member --> element 1
-# -- Member --> element 2
-#
-# In Blender every object can be the parent of every other object
-# In M3G that is not possible. Only a group object can be parent.
-# (Or the world object which is derived from group).
-# That will come later as Parenting Part 2
-#
-# * Backface Culling
-# you can use backface culling, if option "use backface culloing" is on.
-# Culling will be set in PolygonMode object of every mesh. The correct
-# winding is controlled.
-# History 0.5
-#* Bone Animation - Armature (Part 1)
-#
-# Armature is the skeleton for skinned meshes. It stores the bones in
-# rest position (more information http://www.blender.org/cms/How_Armatures_work.634.0.html)
-# You can work in Blender with bones and meshes in different ways. In
-# this first attempt only the use of vertex groups is assisted.
-#
-# Blender-Objekts translated into M3G-Objects
-#
-# MESH SkinnedMesh
-# | |
-# v v
-# ARMATURE Group
-# | |
-# v v
-# BONE_1 Group
-# Group_second
-# | |
-# V v
-# BONE_2 Group
-# Group_secound
-#
-# Every bone is translated into two groups at the moment, because
-# the second bone is needed to do the animation in an easy way.
-#
-# The animations in Blender for meshes are stored in action objects.
-#
-# Blender Objects translated into M3G-Objects
-#
-# ARMATURE
-# | activ
-# v
-# ACTION ANIMATIONCONTROLLER
-# | 1..n ^
-# v ANIMATIONTRACK --> Group_second
-# IPOs |
-# v
-# KEYSEQUENZE
-#
-# One action is translated into one animationcontroller. One IPO is
-# translated in one KEYSEQUENZE and one ANIMATIONTRACK.
-#
-# At the moment only the active action of the armature object is translated.
-#
-#* Print Info, if type of light is used that is not supported
-#
-# History 0.5
-#
-#* New Option exportAllAction (default value: false)
-# If that option is true, all actions will be exported - not only the active
-# action.
-# At the moment you can only assign one action to one armature.
-# To know which action is used with which armature the action
-# needs a special name :
-# <Action Name>#A<M3G ID of Armature>E<End Frame>#<ID of Action>
-
-# Example: Name of action : walk#A10E250#02
-# Name of armature : man#10
-# End Frame: 250
-#
-# History 0.6
-# Include the same image only one time into the m3g-file
-#
-# All the following changes of this version was made by Claus Hoefele
-#
-#* Until now all vertices of the faces was been written.
-# Now the vertices will be used again if possible:
-# normal and texture coordinates of to vertices have to be the same
-#
-#* Smooth/solid shading can now be defined for every single material:
-# in Editing panel (F9)>Link and Materials
-#
-#* This script uses now correctly the TexFace and Shadless Buttons in
-# Shading panel (F5)>Material buttons>Material box.
-# TexFace switches on/off the Export of texture coordinates.
-# Shadeless does the some with the normal coordinates
-#
-#* The GUI was redesigned in a PupBlock
-#
-#* Options:
-#
-#** Texturing Enabled: Switches on/off export of textures and texture
-# coordinates. Attention: the TextFace button switches only
-# for one mesh
-#** Texturing External: the textures will be included it mg3-file or
-# exported in seperate file
-#** Lighting Enabled: turns on/off export of lights and normal completly
-# Attention: Shadeless only for one mesh
-#** Persp. Correction: turns on/off perspective correction in PolygonMode.
-#** Smooth Shading: turns on/off smooth shading in PolygonMode.
-#
-#* Textures in external references are used again (with ImageFactory)
-#
-#* Blender function: Double Sided button in Editing Context
-# (F9)>Mesh panel)
-# turn on/off PolygonMode.CULL_BACK anzuschalten.
-#
-#* Script ingnores meshes that have no faces
-#
-# History 0.7
-#
-# * Exporter can work with texture coordinates greater 1 and smaller 0
-#
-# * Adler32 did not work always correct. New implementation made.
-#
-# * Modul shutil is not needed any longer. Exporter has its own copy_file.
-# (realized and inspired by ideasman_42 and Martin Neumann)
-#
-# History 0.8
-#
-# * Blender works with SpotAngles 1..180 but M3G works only with 0..90
-# M3G use the 'half angle' (cut off angle) (Thanks to Martin Storsjö)
-#
-# * Error fixed: Texture coordinates was not calculated correct.
-# (Thanks to Milan Piskla, Vlad, Max Gilead, Regis Cosnier ...)
-#
-# * New options in GUI:
-# M3G Version 2.0 : Will export M3G files Vers. 2.0 in future
-# Game Physics: Adds Game Physics infos for NOPE API
-#
-# --------------------------------------------------------------------------#
-# TODO: Export only selected mesh
-# TODO: Optimize Bones <--> Vertex Group mapping
-# TODO: Compressed File
-# TODO: MTex - Support
-# TODO: By Rotating use SQUAD instead of Beziere. It's smoother
-import Blender
-from Blender import Types,Lamp,Material,Texture,Window,Registry,Draw
-from Blender.BGL import *
-from Blender.Object import *
-from Blender.Camera import *
-from Blender.Mesh import *
-from array import array
-import sys, struct, zlib
-from inspect import *
-from types import *
-from Blender.Mathutils import *
-from os.path import *
-#import rpdb2
-
-# ---- Helper Functions -------------------------------------------------------#
-def copy_file(source, dest):
- file = open(source, 'rb')
- data = file.read()
- file.close()
-
- file = open(dest, 'wb')
- file.write(data)
- file.close()
-
-def tracer(frame, event, arg):
- '''Global trace function'''
- if event=='call':
- tmp = getargvalues(frame)
- print event, frame.f_code.co_name, frame.f_lineno, \
- formatargvalues(tmp[0],tmp[1],tmp[2],tmp[3])
- elif event=='line':
- print event, frame.f_code.co_name, frame.f_lineno
- #print event, frame.f_code.co_name, frame.f_lineno, \
- # getsourcelines(frame.f_code)[frame.f_lineno]
- elif event=='return':
- print event, frame.f_code.co_name, frame.f_lineno, "->", arg
- return tracer
-
-def doSearchDeep(inList,outList):
- '''Does deepsearch for all elements in inList'''
- for element in inList:
- if element != None : outList = element.searchDeep(outList)
- return outList
-
-
-def getId(aObject):
- ''' returns 0 if Object is None: M3G value for null'''
- if aObject == None: return 0
- return aObject.id
-
-def toJavaBoolean(aValue):
- ''' returns java equivalent to boolean'''
- if aValue:
- return 'true'
- else :
- return 'false'
-
-def sign(a):
- if a<0 : return -1
- elif a>0 : return 1
- else : return 0
-
-def isOrderClockWise(v,normal):
- ''' returns true, if order of vertices is clockwise. Important for
- culling '''
- # (v2-v0)x(v2-v1)=surface_normal
- #
- if type(v[0]) is Types.MVertType:
- mNormal = TriangleNormal(Vector(v[0].co),Vector(v[1].co),Vector(v[2].co))
- else:
- mNormal = TriangleNormal(Vector(v[0]),Vectot(v[1]),Vector(v[2]))
- #print "normal ",mNormal.normalize()
- #print "BNormal ",normal.normalize()
-
- # Do not use any longer. Blender does it correct
-
- result = (sign(normal.x)==sign(mNormal.x) and
- sign(normal.y)==sign(mNormal.y) and
- sign(normal.z)==sign(mNormal.z))
- #print "Result ",result
-
- return True
-
-
-# ---- M3G Types --------------------------------------------------------------#
-class M3GVertexList:
- def __init__(self, wrapList):
- self.mlist = wrapList
-
- def __getitem__(self, key):
- item = self.mlist[key]
- if type(item) is Types.MVertType:
- result =(item.co[0],item.co[1],item.co[2])
- else:
- result = item
- return result
-
-class M3GBoneReference:
- def __init__(self,first,count):
- self.firstVertex=first #UInt32
- self.vertexCount=count #UInt32
-
-
-class M3GBone:
- def __init__(self):
- self.verts=[] #List of influenced verts
- self.transformNode=None #ObjectIndex
- self.references = [] #References to Verts that are needed
- self.weight=0 #Int32
-
-
- def setVerts(self,aVerts):
- self.verts = aVerts
- self.createReferences()
-
- def createReferences(self):
- #print "createReference::len(verts) ",len(self.verts)
- if len(self.verts)==0: return #No Verts available
- self.verts.sort()
- ref = []
- list = []
- last = self.verts[0]-1
- count = 0
- for vert in self.verts:
- #print "vert ",vert
- if vert==last+1:
- list.append(vert)
- else:
- ref.append(M3GBoneReference(list[0],len(list)))
- #print list[0],len(list)
- list=[vert]
- last=vert
- #print "list ",list
- if len(list)>0:
- ref.append(M3GBoneReference(list[0],len(list)))
- self.references = ref
-
-
-class M3GVector3D:
- def __init__(self,ax=0.0,ay=0.0,az=0.0):
- self.x = ax #Float32
- self.y = ay #Float32
- self.z = az #Float32
-
- def writeJava(self):
- return str(self.x)+"f, "+str(self.y)+"f, "+str(self.z)+"f"
-
- def getData(self):
- return struct.pack("<3f",self.x,self.y,self.z)
-
- def getDataLength(self):
- return struct.calcsize("<3f")
-
-class M3GMatrix:
- """ A 4x4 generalized matrix. The 16 elements of the
- matrix are output in the same order as they are
- retrieved using the API Transform.get method. In
- other words, in this order:
- 0 1 2 3
- 4 5 6 7
- 8 9 10 11
- 12 13 14 15 """
- def __init__(self):
- self.elements=16 * [0.0] #Float32
-
- def identity(self):
- self.elements[ 0] = 1.0
- self.elements[ 5] = 1.0
- self.elements[10] = 1.0
- self.elements[15] = 1.0
-
- def getData(self):
- return struct.pack('<16f',self.elements[0],self.elements[1],
- self.elements[2],self.elements[3],
- self.elements[4],self.elements[5],
- self.elements[6],self.elements[7],
- self.elements[8],self.elements[9],
- self.elements[10],self.elements[11],
- self.elements[12],self.elements[13],
- self.elements[14],self.elements[15])
-
- def getDataLength(self):
- return struct.calcsize('<16f')
-
-
-class M3GColorRGB:
- """ A color, with no alpha information. Each compo-
- nent is scaled so that 0x00 is 0.0, and 0xFF is 1.0.
- """
- def __init__(self,ared=0,agreen=0,ablue=0):
- self.red = ared #Byte
- self.green = agreen #Byte
- self.blue = ablue #Byte
-
- def writeJava(self):
- return "0x"+("%02X%02X%02X%02X" % (0.0, self.red, self.green, self.blue))
-
- def getData(self):
- return struct.pack('3B',self.red,self.green,self.blue)
-
- def getDataLength(self):
- return struct.calcsize('3B')
-
-
-class M3GColorRGBA:
- """ A color, with alpha information. Each component
- is scaled so that 0x00 is 0.0, and 0xFF is 1.0. The
- alpha value is scaled so that 0x00 is completely
- transparent, and 0xFF is completely opaque.
- """
- def __init__(self,ared=0,agreen=0,ablue=0,aalpha=0):
- self.red = ared #Byte
- self.green = agreen #Byte
- self.blue = ablue #Byte
- self.alpha = aalpha #Byte
-
- def writeJava(self):
- return "0x"+("%02X%02X%02X%02X" % (self.alpha, self.red, self.green, self.blue))
-
- def getData(self):
- return struct.pack('4B',self.red,self.green,self.blue,self.alpha)
-
- def getDataLength(self):
- return struct.calcsize('4B')
-
-
-#ObjectIndex
-#The index of a previously encountered object in
-#the file. Although this is serialized as a single
-#unsigned integer, it is included in the compound
-#type list because of the additional semantic infor-
-#mation embodied in its type. A value of 0 is
-#reserved to indicate a null reference; actual object indices start from 1. Object indices must refer
-#only to null or to an object which has already been
-#created during the input deserialization of a file -
-#they must be less than or equal to the index of the
-#object in which they appear. Other values are dis-
-#allowed and must be treated as errors.
-#UInt32
-#index;
-
-# ---- M3G Proxy --------------------------------------------------------------- #
-class M3GProxy:
- def __init__(self):
- self.name = ""
- self.id=0
- self.ObjectType=0
- self.binaryFormat=''
-
- def __repr__(self):
- return "<"+str(self.__class__)[9:] + ":" + str(self.name) + ":" + str(self.id) + ">"
-
-
-class M3GHeaderObject(M3GProxy):
- def __init__(self):
- M3GProxy.__init__(self)
- self.M3GHeaderObject_binaryFormat = '<BBBII'
- self.ObjectType=0
- self.id = 1 #Special Object: always 1
- self.VersionNumber=[1,0] #Byte[2]
- self.hasExternalReferences=False #Boolean External Files needed? eg. Textures
- self.TotalFileSize=0 #UInt32
- self.ApproximateContentSize=0 #UInt32 Only a hint! External sources included
- self.AuthoringField='Blender M3G Export' #String
-
- def getData(self):
- data = struct.pack(self.M3GHeaderObject_binaryFormat,
- self.VersionNumber[0],
- self.VersionNumber[1],
- self.hasExternalReferences,
- self.TotalFileSize,
- self.ApproximateContentSize)
- data += struct.pack(str(len(self.AuthoringField)+1)+'s',self.AuthoringField)
- return data
-
- def getDataLength(self):
- value = struct.calcsize(self.M3GHeaderObject_binaryFormat)
- return value + struct.calcsize(str(len(self.AuthoringField)+1)+'s')
-
-class M3GExternalReference(M3GProxy):
- def __init__(self):
- M3GProxy.__init__(self)
- self.ObjectType=0xFF
- self.URI='' #reference URI
-
- def getData(self):
- data = struct.pack(str(len(self.URI)+1) + 's', self.URI)
- return data
-
- def getDataLength(self):
- return struct.calcsize(str(len(self.URI)+1)+'s')
-
- def searchDeep(self,alist):
- if not(self in alist): alist.append(self)
- return alist
-
- def __repr__(self):
- return M3GProxy.__repr__(self) + " (" + self.URI + ")"
-
-
-class M3GObject3D(M3GProxy):
- def __init__(self):
- M3GProxy.__init__(self)
- self.userID=0 #UInt32 - field may be any value
- self.animationTracks=[] #ObjectIndex[]
- self.userParameterCount=0 #UInt32 - No user parameter used
-
- def searchDeep(self,alist):
- alist = doSearchDeep(self.animationTracks,alist)
- if not(self in alist): alist.append(self)
- return alist
-
- def getData(self):
- data = struct.pack('<I',self.userID)
- print "write userID",self.userID,self.name,str(self), self.getDataLength()
- data += struct.pack('<I',len(self.animationTracks))
- for element in self.animationTracks:
- data += struct.pack('<I',getId(element))
- data += struct.pack('<I',self.userParameterCount)
- return data
-
- def getDataLength(self):
- value = struct.calcsize('<3I')
- if len(self.animationTracks) > 0:
- value += struct.calcsize('<'+str(len(self.animationTracks))+'I')
- return value
-
- def writeJava(self,aWriter,aCreate):
- if aCreate : pass #Abstract! Could not be created
- if len(self.animationTracks) > 0 :
- aWriter.write(2)
- for iTrack in self.animationTracks:
- aWriter.write(2,"BL%i.addAnimationTrack(BL%i);" % (self.id,iTrack.id))
-
-
-class M3GTransformable(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
- self.hasComponentTransform=False #Boolean
- #IF hasComponentTransform==TRUE, THEN
- self.translation=M3GVector3D(0,0,0) #Vector3D
- self.scale=M3GVector3D(1,1,1) #Vector3D
- self.orientationAngle=0 #Float32
- self.orientationAxis=M3GVector3D(0,0,0) #Vector3D undefined
- #END
- self.hasGeneralTransform=False #Boolean
- #IF hasGeneralTransform==TRUE, THEN
- self.transform = M3GMatrix() #Matrix identity
- self.transform.identity()
- #END
- #If either hasComponentTransform or hasGeneralTransform is false, the omitted fields will be
- #initialized to their default values (equivalent to an identity transform in both cases).
-
- def writeJava(self,aWriter,aCreate):
- if aCreate: pass #Abstract Base Class! Cant't be created
- M3GObject3D.writeJava(self,aWriter,False)
- if self.hasGeneralTransform :
- aWriter.write(2,"float[] BL%i_matrix = {" % (self.id))
- aWriter.writeList(self.transform.elements,4,"f")
- aWriter.write(2,"};")
- aWriter.write(2)
- aWriter.write(2,"Transform BL%i_transform = new Transform();" % (self.id))
- aWriter.write(2,"BL%i_transform.set(BL%i_matrix);" % (self.id,self.id))
- aWriter.write(2,"BL%i.setTransform(BL%i_transform);" % (self.id,self.id))
- aWriter.write(2)
- if self.hasComponentTransform:
- aWriter.write(2,("BL%i.setTranslation("+self.translation.writeJava()+");")
- %(self.id))
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += struct.pack("<B",self.hasComponentTransform)
- if self.hasComponentTransform==True:
- data += self.translation.getData()
- data += self.scale.getData()
- data += struct.pack('<f',self.orientationAngle)
- data += self.orientationAxis.getData()
- data += struct.pack("<B",self.hasGeneralTransform)
- if self.hasGeneralTransform==True:
- data += self.transform.getData()
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += struct.calcsize("<B")
- if self.hasComponentTransform==True:
- value += self.translation.getDataLength()
- value += self.scale.getDataLength()
- value += struct.calcsize('<f')
- value += self.orientationAxis.getDataLength()
- value += struct.calcsize("<B")
- if self.hasGeneralTransform==True:
- value += self.transform.getDataLength()
- return value
-
-
-class M3GNode(M3GTransformable):
- def __init__(self):
- M3GTransformable.__init__(self)
- self.blenderObj = None #Pointer to corrsponding BlenderObj
- self.parentBlenderObj = None #Pointer to Parent in Blender
- self.blenderMatrixWorld = None #BlenderObj matrixWorld
- self.M3GNode_binaryFormat = '<BBBIB'
- self.enableRendering=True #Boolean
- self.enablePicking=True #Boolean
- self.alphaFactor=255 #Byte 0x00 is equivalent to 0.0 (fully transparent), and 255 is equivalent to 1.0 (fully opaque);
- self.scope=4294967295 #-1 #UInt32
- self.hasAlignment = False #Boolean
- #IF hasAlignment==TRUE, THEN
- self.M3GNode_binaryFormat_2 = '<BBII'
- self.zTarget=0 #Byte The zTarget and yTarget fields must each hold a valid enumerated value,
- self.yTarget=0 #Byte as specified in the class definition. Other values must be treated as errors.
- self.zReference=None #ObjectIndex
- self.yReference=None #ObjectIndex
- #END
- #If the hasAlignment field is false, the omitted fields are initialized to their default values.
-
-
- def getData(self):
- data = M3GTransformable.getData(self)
- #print "Binary ",self.binaryFormat
- data += struct.pack(self.M3GNode_binaryFormat,
- self.enableRendering,
- self.enablePicking,
- self.alphaFactor,
- self.scope,
- self.hasAlignment)
-
- if self.hasAlignment:
- data += pack(self.M3GNode_binaryFormat_2,
- self.zTarget,
- self.yTarget,
- getId(self.zReference),
- getId(self.yReference))
- return data
-
- def getDataLength(self):
- value = M3GTransformable.getDataLength(self) + \
- struct.calcsize(self.M3GNode_binaryFormat)
- if self.hasAlignment:
- value += struct.calcsize(self.M3GNode_binaryFormat_2)
- return value
-
- def writeJava(self,aWriter,aCreate):
- if aCreate: pass #Abstract Base Class! Cant't be created
- M3GTransformable.writeJava(self,aWriter,False)
-
-class M3GGroup(M3GNode):
- def __init__(self):
- M3GNode.__init__(self)
- self.ObjectType=9
- self.children = [] #ObjectIndex[]
-
- def searchDeep(self,alist):
- for element in self.children:
- alist = element.searchDeep(alist)
- return M3GNode.searchDeep(self,alist)
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//Group:"+self.name )
- aWriter.write(2,"Group BL"+str(self.id)+" = new Group();")
- M3GNode.writeJava(self,aWriter,False)
- for element in self.children:
- aWriter.write(2,"BL%i.addChild(BL%i);" % (self.id,element.id))
-
- def getData(self):
- data = M3GNode.getData(self)
- data = data + struct.pack("<I",len(self.children))
- for element in self.children:
- data += struct.pack("<I",getId(element))
- return data
-
- def getDataLength(self):
- return M3GNode.getDataLength(self)+ \
- struct.calcsize("<"+str(len(self.children)+1)+"I")
-
-
-class M3GWorld(M3GGroup):
- def __init__(self):
- M3GGroup.__init__(self)
- self.ObjectType=22
- self.activeCamera=None #ObjectIndex
- self.background=None #ObjectIndex UInt32 0=None
- self.M3GWorld_binaryFormat='<II'
-
- def searchDeep(self,alist):
- alist = doSearchDeep([self.activeCamera, self.background],alist)
- return M3GGroup.searchDeep(self,alist)
-
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//World:"+self.name )
- aWriter.write(2,"World BL"+str(self.id)+" = new World();")
- M3GGroup.writeJava(self,aWriter,False)
- if self.background != None:
- aWriter.write(2,"BL"+str(self.id)+".setBackground(BL"+str(self.background.id)+");")
- if self.activeCamera != None:
- aWriter.write(2,"BL%i.setActiveCamera(BL%i);" %
- (self.id,self.activeCamera.id))
- aWriter.write(2)
-
-
- def getData(self):
- data = M3GGroup.getData(self)
- return data + \
- struct.pack(self.M3GWorld_binaryFormat,getId(self.activeCamera),getId(self.background))
-
-
- def getDataLength(self):
- return M3GGroup.getDataLength(self) + struct.calcsize(self.M3GWorld_binaryFormat)
-
-
-class M3GBackground(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
- self.ObjectType=4
- self.M3GBackground_binaryFormat = '<BBiiiiBB'
- self.backgroundColor=M3GColorRGBA(0,0,0,0) #ColorRGBA 0x00000000 (black, transparent)
- self.backgroundImage=None #ObjectIndex null (use the background color only)
- self.backgroundImageModeX=32; #Byte BORDER=32 REPEAT=33
- self.backgroundImageModeY=32; #Byte BORDER
- self.cropX = 0; #Int32
- self.cropY = 0 #Int32 ;
- self.cropWidth = 0 #Int32 ;
- self.cropHeight = 0;#Int32
- self.depthClearEnabled = True #Boolean
- self.colorClearEnabled = True #Boolean
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//Background:"+self.name )
- aWriter.write(2,"Background BL"+str(self.id)+" = new Background();")
- M3GObject3D.writeJava(self,aWriter,False)
- aWriter.write(2,"BL"+str(self.id)+".setColor("+self.backgroundColor.writeJava()+");")
- aWriter.write(2,"")
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += self.backgroundColor.getData()
- data += struct.pack('<I',getId(self.backgroundImage))
- data += struct.pack(self.M3GBackground_binaryFormat, self.backgroundImageModeX,
- self.backgroundImageModeY,
- self.cropX,
- self.cropY,
- self.cropWidth,
- self.cropHeight,
- self.depthClearEnabled,
- self.colorClearEnabled)
- return data
-
- def getDataLength(self):
- value=M3GObject3D.getDataLength(self)
- value += self.backgroundColor.getDataLength()
- value += struct.calcsize('<I')
- value += struct.calcsize(self.M3GBackground_binaryFormat)
- return value
-
-
-class M3GCamera(M3GNode):
- GENERIC=48 #Projection-Types
- PARALLEL=49
- PERSPECTIVE=50
-
- def __init__(self):
- M3GNode.__init__(self)
- self.ObjectType=5
- self.projectionType=M3GCamera.PARALLEL #Byte
- #IF projectionType==GENERIC, THEN
- self.projectionMatrix=M3GMatrix() #Matrix •view volume : opposite corners at (-1 -1 -1) and (1 1 1)
- # TODO: Set right matrix
- #ELSE
- self.fovy=0.0 #Float32
- self.AspectRatio=0.0#Float32
- self.near=0.0#Float32
- self.far=0.0#Float32
- #END
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//Camera " + self.name)
- aWriter.write(2,"Camera BL%i = new Camera();" % (self.id))
- M3GNode.writeJava(self,aWriter,False)
- aWriter.write(2,"BL%i.setPerspective(%ff, //Field of View" % \
- (self.id,self.fovy))
- aWriter.write(4,"(float)aCanvas.getWidth()/(float)aCanvas.getHeight(),")
- aWriter.write(4,str(self.near)+"f, //Near Clipping Plane")
- aWriter.write(4,str(self.far)+"f); //Far Clipping Plane")
-
- def getData(self):
- data = M3GNode.getData(self)
- data += struct.pack("B",self.projectionType)
- if self.projectionType == self.GENERIC:
- data += self.projectionMatrix.getData()
- else:
- data += struct.pack("<4f",self.fovy,self.AspectRatio,self.near,self.far)
- return data
-
- def getDataLength(self):
- value = M3GNode.getDataLength(self)
- value += struct.calcsize("B")
- if self.projectionType == self.GENERIC:
- value += self.projectionMatrix.getDataLength()
- else:
- value += struct.calcsize("<4f")
- return value
-
-
-class M3GMesh(M3GNode):
- def __init__(self,aVertexBuffer=None, aIndexBuffer=[], aAppearance=[]):
- M3GNode.__init__(self)
- self.ObjectType=14
- self.vertexBuffer = aVertexBuffer #ObjectIndex
- self.submeshCount=len(aIndexBuffer) #UInt32
- #FOR each submesh...
- self.indexBuffer=aIndexBuffer #ObjectIndex
- self.appearance=aAppearance #;ObjectIndex
- #END
-
- def getData(self):
- data = M3GNode.getData(self)
- data += struct.pack('<2I', getId(self.vertexBuffer),
- self.submeshCount)
- for i in range(len(self.indexBuffer)):
- data += struct.pack('<2I',getId(self.indexBuffer[i]),
- getId(self.appearance[i]))
- return data
-
- def getDataLength(self):
- value = M3GNode.getDataLength(self)
- value += struct.calcsize('<2I')
- for i in range(len(self.indexBuffer)):
- value += struct.calcsize('<2I')
- return value
-
- def searchDeep(self,alist):
- alist = doSearchDeep([self.vertexBuffer] +self.indexBuffer
- + self.appearance ,alist)
- return M3GNode.searchDeep(self,alist)
-
- def writeJava(self,aWriter,aCreate):
- self.writeBaseJava(aWriter,aCreate,"Mesh","")
-
- def writeBaseJava(self,aWriter,aCreate,aClassName,aExtension):
- if aCreate:
- aWriter.writeClass(aClassName,self)
- if self.submeshCount > 1:
- aWriter.write(2,"IndexBuffer[] BL%i_indexArray = {" % (self.id))
- aWriter.write(4,",".join(["BL%i" %(i.id) for i in self.indexBuffer ]))
- aWriter.write(2," };")
- aWriter.write(2)
- aWriter.write(2,"Appearance[] BL%i_appearanceArray = {" % (self.id))
- aWriter.write(4,",".join(["BL%i" %(i.id) for i in self.appearance ]))
- aWriter.write(2," };")
- aWriter.write(2)
- aWriter.write(2,"%s BL%i = new %s(BL%i,BL%i_indexArray,BL%i_appearanceArray%s);" % \
- (aClassName,self.id,aClassName,self.vertexBuffer.id, self.id,self.id,aExtension))
- else:
- #print "indexBuffer", len(self.indexBuffer)
- #print "appearance", len(self.appearance)
- aWriter.write(2,"%s BL%i = new %s(BL%i,BL%i,BL%i%s);" % \
- (aClassName,
- self.id,
- aClassName,
- self.vertexBuffer.id,
- self.indexBuffer[0].id,
- self.appearance[0].id,
- aExtension))
- M3GNode.writeJava(self,aWriter,False)
- aWriter.write(2)
-
-
-class M3GSkinnedMesh(M3GMesh):
- def __init__(self,aVertexBuffer=None, aIndexBuffer=[], aAppearance=[]):
- M3GMesh.__init__(self,aVertexBuffer, aIndexBuffer, aAppearance)
- self.ObjectType=16
- self.skeleton=None #ObjectIndex
- self.bones={}
- #print"M3GSkinnedMesh.__init__::self.vertexBuffer:",self.vertexBuffer
- ##ObjectIndex skeleton;
- ##UInt32 transformReferenceCount;
- ##FOR each bone reference...
- ## ObjectIndex transformNode;
- ## UInt32 firstVertex;
- ## UInt32 vertexCount;
- ## Int32 weight;
- ##END
-
- def searchDeep(self,alist):
- alist = doSearchDeep([self.skeleton],alist)
- return M3GMesh.searchDeep(self,alist)
-
- def addSecondBone(self):
- secondBones = {}
- for bone in self.bones.values():
- bone2 = M3GBone()
- bone2.verts=bone.verts
- bone.verts=[]
- mGroup = M3GGroup()
- mGroup.name=bone.transformNode.name+"_second"
- bone2.transformNode=mGroup
- bone2.references = bone.references
- bone.references = []
- bone2.weight = bone.weight
- bone.weight=0
- mGroup.children = bone.transformNode.children
- bone.transformNode.children = [mGroup]
- mGroup.animationTracks=bone.transformNode.animationTracks
- bone.transformNode.animationTracks = []
- secondBones[bone.transformNode.name+"_second"]=bone2
- for bone in secondBones.values():
- self.bones[bone.transformNode.name] = bone
-
- def getBlenderIndexes(self):
- #print "M3GSkinnedMesh.vertexBuffer:",self.vertexBuffer
- return self.vertexBuffer.positions.blenderIndexes
-
- def writeJava(self,aWriter,aCreate):
- self.writeBaseJava(aWriter,aCreate,"SkinnedMesh",
- (",BL%i" % (self.skeleton.id)))
- aWriter.write(2,"//Transforms")
- for bone in self.bones.values():
- #print "bone: ", bone
- #print "bone.references: ", bone.references
- for ref in bone.references:
- aWriter.write(2,"BL%i.addTransform(BL%i,%i,%i,%i);" %
- (self.id,
- bone.transformNode.id,bone.weight,
- ref.firstVertex, ref.vertexCount))
- aWriter.write(2)
-
- def getDataLength(self):
- value = M3GMesh.getDataLength(self)
- value += struct.calcsize('<I') #skeleton
- value += struct.calcsize('<I') #transformReferenceCount
- for bone in self.bones.values():
- for ref in bone.references:
- value += struct.calcsize('<3Ii')
- return value
-
- def getData(self):
- data = M3GMesh.getData(self)
- data += struct.pack('<I', getId(self.skeleton))
- count = 0
- for bone in self.bones.values(): count+=len(bone.references)
- data += struct.pack('<I',count)
- for bone in self.bones.values():
- for ref in bone.references:
- data += struct.pack('<I',getId(bone.transformNode))
- data += struct.pack('<2I',ref.firstVertex,ref.vertexCount)
- data += struct.pack('<i',bone.weight)
- return data
-
-class M3GLight(M3GNode):
- def __init__(self):
- M3GNode.__init__(self)
- self.ObjectType=12
- self.modes = {'AMBIENT':128,
- 'DIRECTIONAL':129,
- 'OMNI':130,
- 'SPOT':131}
- self.attenuationConstant = 1.0 #Float32
- self.attenuationLinear = 0.0 #Float32
- self.attenuationQuadratic = 0.0 #Float32
- self.color = M3GColorRGB(1.0, 1.0, 1.0) #ColorRGB
- self.mode = self.modes['DIRECTIONAL'] #Byte Enumurator mode: DIRECTIONAL
- self.intensity = 1.0 #Float32
- self.spotAngle = 45 #Float32
- self.spotExponent = 0.0 #Float32
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//Light: " + self.name)
- aWriter.write(2,"Light BL%i = new Light();" % (self.id))
- aWriter.write(2,"BL%i.setMode(%i);" % (self.id,self.mode)) #Light.OMNI
- if self.mode in [self.modes['OMNI'],self.modes['SPOT']]:#Attenuation
- aWriter.write(2,"BL%i.setAttenuation(%ff, %ff,%ff);"
- % (self.id,
- self.attenuationConstant,
- self.attenuationLinear,
- self.attenuationQuadratic))
- aWriter.write(2,("BL%i.setColor("+self.color.writeJava()+");")
- % (self.id))
- aWriter.write(2,"BL%i.setIntensity(%ff);"
- % (self.id,self.intensity))
- if self.mode == self.modes['SPOT']:
- aWriter.write(2,"BL%i.setSpotAngle(%ff);"
- % (self.id,self.spotAngle))
- aWriter.write(2,"BL%i.setSpotExponent(%ff);"
- % (self.id,self.spotExponent))
- M3GNode.writeJava(self,aWriter,False)
- aWriter.write(2)
-
-
- def getData(self):
- data = M3GNode.getData(self)
- data += struct.pack("<fff", self.attenuationConstant,
- self.attenuationLinear,
- self.attenuationQuadratic)
- data += self.color.getData()
- data += struct.pack("<Bfff", self.mode,
- self.intensity,
- self.spotAngle,
- self.spotExponent)
- return data
-
- def getDataLength(self):
- value = M3GNode.getDataLength(self)
- value += self.color.getDataLength()
- value += struct.calcsize('<B6f')
- return value
-
-class M3GMaterial(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
- self.ObjectType=13
- self.ambientColor=M3GColorRGB(0.2, 0.2, 0.2) #ColorRGB
- self.diffuseColor=M3GColorRGBA(0.8, 0.8, 0.8, 1.0) #ColorRGBA
- self.emissiveColor=M3GColorRGB(0.0, 0.0, 0.0) #ColorRGB
- self.specularColor=M3GColorRGB(0.0, 0.0, 0.0) #ColorRGB
- self.shininess=0.0 #Float32
- self.vertexColorTrackingEnabled=False #Boolean
-
- def writeJava(self,aWriter,aCreate):
- if aCreate :
- aWriter.write(2,"//Material: "+self.name )
- aWriter.write(2,"Material BL%i = new Material();" % (self.id))
- aWriter.write(2,("BL%i.setColor(Material.AMBIENT," +
- self.ambientColor.writeJava()+");") % (self.id) )
- aWriter.write(2,("BL%i.setColor(Material.SPECULAR," +
- self.specularColor.writeJava()+");") % (self.id) )
- aWriter.write(2,("BL%i.setColor(Material.DIFFUSE," +
- self.diffuseColor.writeJava()+");") % (self.id))
- aWriter.write(2,("BL%i.setColor(Material.EMISSIVE," +
- self.emissiveColor.writeJava()+");") % (self.id))
- aWriter.write(2,("BL%i.setShininess(%ff);") % (self.id,self.shininess))
- aWriter.write(2,("BL%i.setVertexColorTrackingEnable(" +
- toJavaBoolean(self.vertexColorTrackingEnabled) + ");") %
- (self.id))
- M3GObject3D.writeJava(self,aWriter,False)
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += self.ambientColor.getData()
- data += self.diffuseColor.getData()
- data += self.emissiveColor.getData()
- data += self.specularColor.getData()
- data += struct.pack('<fB',self.shininess,
- self.vertexColorTrackingEnabled)
- return data
-
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += self.ambientColor.getDataLength()
- value += self.diffuseColor.getDataLength()
- value += self.emissiveColor.getDataLength()
- value += self.specularColor.getDataLength()
- value += struct.calcsize('<fB')
- return value
-
-
-class M3GVertexArray(M3GObject3D):
- def __init__(self,aNumComponents,aComponentSize,aAutoScaling=False,aUVMapping=False):
- M3GObject3D.__init__(self)
- self.ObjectType=20
- self.blenderIndexes={} #Translation-Table from Blender index to m3g index
- self.autoscaling = aAutoScaling #bias and scale should be computed internal
- self.uvmapping=aUVMapping #Change coordinates from blender uv to uv-m3g
- self.bias = [0.0,0.0,0.0]
- self.scale = 1.0
- self.componentSize=aComponentSize #Byte number of bytes per component; must be [1, 2]
- self.componentCount=aNumComponents #Byte number of components per vertex; must be [2, 4]
- self.encoding=0 #Byte 0="raw" as bytes or 16 bit integers.
- self.vertexCount=0 #UInt16 number of vertices in this VertexArray; must be [1, 65535]
- if self.autoscaling==True:
- self.components = array('f')
- else:
- self.components = self.createComponentArray()
- #FOR each vertex...
- # IF componentSize==1, THEN
- # IF encoding==0, THEN
- # Byte[componentCount]
- # ELSE IF encoding==1, THEN
- # Byte[componentCount]
- # END
- # ELSE
- # IF encoding==0, THEN
- # Int16[componentCount]
- # ELSE IF encoding==1, THEN
- # Int16[componentCount]
- # END
- # END
- #END
-
- def createComponentArray(self):
- if self.componentSize == 1:
- return array('b') #Byte-Array
- else:
- return array('h') #Short-Array
-
- def useMaxPrecision(self,aBoundingBox):
- """With Bias and Scale you can maximize the precision of the array"""
- #print "useMaxPrecision"
- vertexList = M3GVertexList(aBoundingBox)
- first = vertexList[0]
- minimum =[first[0],first[1],first[2]]
- maximum = [first[0],first[1],first[2]] #Search maximal Dimension
- for element in vertexList:
- for i in range(3):
- if minimum[i] > element[i] : minimum[i] = element[i]
- if maximum[i] < element[i] : maximum[i] = element[i]
- #print i, maximum[i],element[i]
- lrange=[0,0,0]
- maxRange=0.0
- maxDimension=-1
- for i in range(3): #set bias
- lrange[i] = maximum[i]-minimum[i]
- self.bias[i] = minimum[i]*0.5+maximum[i]*0.5
- #print "Bias",i,self.bias[i],"min-max",minimum[i],maximum[i],"lrang",lrange[i]
- if lrange[i] > maxRange:
- maxRange = lrange[i]
- maxDimension=i
- self.scale = maxRange/65533.0
- #print "MaxRange ",maxRange
- #print "scale",self.scale
-
-
- def internalAutoScaling(self):
- print "internalAutoScaling"
- #Already done?
- print self.components.typecode
- if not self.autoscaling or self.components.typecode!="f":return
- #Find bais and scale
- minimum=[]
- maximum=[]
- for i in range(self.componentCount):
- minimum.append(self.components[i])
- maximum.append(self.components[i])
- for i in range(0,len(self.components),self.componentCount):
- for j in range(self.componentCount):
- if minimum[j] > self.components[i+j] : minimum[j] = self.components[i+j]
- if maximum[j] < self.components[i+j] : maximum[j] = self.components[i+j]
- #print "i+j=",i+j,"min=",minimum[j],"max=",maximum[j],"elem=",self.components[i+j]
- #print "min=", minimum
- #print "max=", maximum
- lrange=[0] * self.componentCount
- maxRange=0.0
- maxDimension=-1
- for i in range(self.componentCount): #set bias
- lrange[i] = maximum[i]-minimum[i]
- self.bias[i] = minimum[i]*0.5+maximum[i]*0.5
- #print "Bias",i,self.bias[i],"min-max",minimum[i],maximum[i],"lrang",lrange[i]
- if lrange[i] > maxRange:
- maxRange = lrange[i]
- maxDimension=i
- maxValue=(2**(8*self.componentSize)*1.0)-2.0
- #print "MaxValue=",maxValue
- self.scale = maxRange/maxValue
- #print "MaxRange ",maxRange
- #print "scale",self.scale
- #Copy Components
- oldArray=self.components
- self.components=self.createComponentArray()
- for i in range(0,len(oldArray),self.componentCount):
- for j in range(self.componentCount):
- element=int((oldArray[i+j]-self.bias[j])/self.scale)
- #print "element",element
- self.components.append(element)
- # Reverse t coordinate because M3G uses a different 2D coordinate system than Blender.
- if self.uvmapping:
- for i in range(0,len(self.components),2):
- self.components[i+1]= int(self.components[i+1]*(-1)) #Error in Version 0.7
- for i in range(len(self.components)):
- if abs(self.components[i])>maxValue:raise Exception( i+". element too great/small!")
-
- def writeJava(self,aWriter,aCreate):
- self.internalAutoScaling()
- if aCreate:
- aWriter.write(2,"// VertexArray " + self.name)
- if self.componentSize == 1:
- aWriter.write(2,"byte[] BL%i_array = {" % (self.id))
- else:
- aWriter.write(2,"short[] BL%i_array = {" % (self.id))
- aWriter.writeList(self.components)
- aWriter.write(2,"};")
- aWriter.write(2)
- aWriter.write(2,"VertexArray BL%i = new VertexArray(BL%i_array.length/%i,%i,%i);" %
- (self.id,self.id,
- self.componentCount,self.componentCount,self.componentSize))
- aWriter.write(2,"BL%i.set(0,BL%i_array.length/%i,BL%i_array);" %
- (self.id,self.id,self.componentCount,self.id))
- M3GObject3D.writeJava(self,aWriter,False)
- aWriter.write(2)
-
-
- def getData(self):
- self.internalAutoScaling()
- self.vertexCount = len(self.components)/self.componentCount
- data = M3GObject3D.getData(self)
- data += struct.pack('<3BH',self.componentSize,
- self.componentCount,
- self.encoding,
- self.vertexCount)
- componentType = ""
- if self.componentSize == 1:
- componentType = "b"
- else:
- componentType = "h"
- for element in self.components:
- data += struct.pack('<'+componentType,element)
- return data
-
- def getDataLength(self):
- self.internalAutoScaling()
- value = M3GObject3D.getDataLength(self)
- value += struct.calcsize('<3BH')
- componentType = ""
- if self.componentSize == 1:
- componentType = "b"
- else:
- componentType = "h"
- value += struct.calcsize('<'+str(len(self.components))+componentType)
- return value
-
- def append(self,element,index=None):
- #print "type(element):",type(element)
- if type(element) is Types.vectorType :
- for i in range(3):
- value = int((element[i]-self.bias[i])/self.scale)
- #print "append:",i,element[i],(element[i]-self.bias[i]),value
- self.components.append(value)
- elif type(element) is Types.MVertType:
- for i in range(3):
- value = int((element.co[i]-self.bias[i])/self.scale)
- #print "append:",i,element[i],(element[i]-self.bias[i]),value
- self.components.append(value)
- if index!=None:
- key=str(len(self.blenderIndexes))
- #print"key,index:",key,index
- self.blenderIndexes[key]=index
- #print"blenderIndexes",self.blenderIndexes
- else:
- print "VertexArray.append: element=",element
- self.components.append(element)
-
-class M3GVertexBuffer(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
- self.ObjectType=21
- self.defaultColor=M3GColorRGBA(255,255,255) #ColorRGBA 0xFFFFFFFF (opaque white).
- self.positions = None #ObjectIndex
- self.positionBias = [0.0,0.0,0.0] #Float32[3]
- self.positionScale = 1.0 #Float32
- self.normals = None #ObjectIndex
- self.colors = None #ObjectIndex
- self.texCoordArrays = []
- self.texcoordArrayCount = 0 #UInt32
-## #FOR each texture coordinate array...
-## self.texCoords = [] #ObjectIndex
-## self.texCoordBias=[] #Float32[3]
-## self.texCoordScale=[] #;Float32
-## #END
-## #If a texture coordinate array has only two components, the corresponding texCoordBias[2] element
-## #must be 0.0.
-## #Null texture coordinate arrays are never serialized, regardless of their position. A single texture
-## #coordinate array will therefore always be serialized as belonging to texturing unit 0, regardless of
-## #its original unit it was assigned to.
-## #There are as many references in the texture coordinates array as there are active texture units for
-## #this geometry. The texture coordinate references are loaded sequentially from texture unit 0. If the
-## #implementation supports more texture units than are specified, these are left in their default, inactive
-## #state, with a null texture coordinate reference and an undefined bias and scale.
-## #If more texture coordinate references are specified than are supported by the implementation, then
-## #this must be treated as an error, as it would be in the API. The application can then decide on an
-## #appropriate course of action to handle this case.
-
- def searchDeep(self,alist):
- if self.positions!=None: alist = self.positions.searchDeep(alist)
- if self.normals != None: alist = self.normals.searchDeep(alist)
- if self.colors!= None: alist = self.colors.searchDeep(alist)
- alist = doSearchDeep(self.texCoordArrays, alist)
- return M3GObject3D.searchDeep(self,alist)
-
- def setPositions(self,aVertexArray):
- self.positions = aVertexArray
- self.positionBias = aVertexArray.bias
- self.positionScale = aVertexArray.scale
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//VertexBuffer"+self.name )
- aWriter.write(2,"VertexBuffer BL%i = new VertexBuffer();" % (self.id))
- aWriter.write(2,"float BL%i_Bias[] = { %ff, %ff, %ff};" %
- (self.id,self.positionBias[0],
- self.positionBias[1],self.positionBias[2]))
- aWriter.write(2,"BL%i.setPositions(BL%i,%ff,BL%i_Bias);" %
- (self.id, self.positions.id,
- self.positionScale,self.id))
- aWriter.write(2,"BL%i.setNormals(BL%i);" % (self.id,self.normals.id))
- #if self.colors != None: aWriter.write(2,"BL%i.setTexCoords(0,BL%i,1.0f,null);" %
- # (self.id,self.colors.id))
- lIndex = 0
- for iTexCoord in self.texCoordArrays:
- aWriter.write(2,"float BL%i_%i_TexBias[] = { %ff, %ff, %ff};" %
- (self.id,lIndex, iTexCoord.bias[0],
- iTexCoord.bias[1],iTexCoord.bias[2]))
- #int index, javax.microedition.m3g.VertexArray194 texCoords, float scale, float[] bias
- aWriter.write(2,"BL%i.setTexCoords(%i,BL%i,%ff,BL%i_%i_TexBias);" %
- (self.id, lIndex, iTexCoord.id, iTexCoord.scale,self.id,lIndex))
- lIndex += 1
-
- M3GObject3D.writeJava(self,aWriter,False)
-
-
- def getData(self):
- self.texcoordArrayCount = len(self.texCoordArrays)
- data = M3GObject3D.getData(self)
- data += self.defaultColor.getData()
- data += struct.pack('<I4f3I',getId(self.positions),
- self.positionBias[0],
- self.positionBias[1],
- self.positionBias[2],
- self.positionScale,
- getId(self.normals),
- getId(self.colors),
- self.texcoordArrayCount)
- for iTexCoord in self.texCoordArrays:
- data += struct.pack('<I', getId(iTexCoord))
- data += struct.pack('<ffff', iTexCoord.bias[0],
- iTexCoord.bias[1],
- iTexCoord.bias[2],
- iTexCoord.scale)
- return data
-
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += self.defaultColor.getDataLength()
- value += struct.calcsize('<I4f3I')
- value += struct.calcsize('<Iffff') * len(self.texCoordArrays)
- return value
-
-
-class M3GPolygonMode(M3GObject3D):
- CULL_BACK=160
- CULL_NONE=162
- SHADE_FLAT=164
- SHADE_SMOOTH=165
- WINDING_CCW=168
- WINDING_CW=169
-
- def __init__(self):
- M3GObject3D.__init__(self)
- self.ObjectType=8
- self.culling=M3GPolygonMode.CULL_BACK #Byte
- self.shading=M3GPolygonMode.SHADE_SMOOTH #Byte
- self.winding=M3GPolygonMode.WINDING_CCW #Byte
- self.twoSidedLightingEnabled = False #Boolean
- self.localCameraLightingEnabled = False #Boolean
- self.perspectiveCorrectionEnabled = False #Boolean
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"PolygonMode BL%i = new PolygonMode();" % (self.id))
- aWriter.write(2,"BL%i.setCulling(%i);" % (self.id,self.culling))
- aWriter.write(2,"BL%i.setShading(%i);" % (self.id,self.shading))
- aWriter.write(2,"BL%i.setWinding(%i);" % (self.id,self.winding))
- aWriter.write(2,("BL%i.setTwoSidedLightingEnable(" +
- toJavaBoolean(self.twoSidedLightingEnabled) + ");") %
- (self.id))
- aWriter.write(2,("BL%i.setLocalCameraLightingEnable(" +
- toJavaBoolean(self.localCameraLightingEnabled) + ");") %
- (self.id))
- aWriter.write(2,("BL%i.setPerspectiveCorrectionEnable(" +
- toJavaBoolean(self.perspectiveCorrectionEnabled) + ");") %
- (self.id))
- aWriter.write(2)
- M3GObject3D.writeJava(self,aWriter,False)
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += struct.pack('6B',self.culling,
- self.shading,
- self.winding,
- self.twoSidedLightingEnabled,
- self.localCameraLightingEnabled,
- self.perspectiveCorrectionEnabled)
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += struct.calcsize('6B')
- return value
-
-class M3GIndexBuffer(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
-
- def getData(self):
- return M3GObject3D.getData(self)
-
- def getDataLength(self):
- return M3GObject3D.getDataLength(self)
-
- def writeJava(self,aWriter,aCreate):
- M3GObject3D.writeJava(self,aWriter,False)
-
-
-class M3GTriangleStripArray(M3GIndexBuffer):
- def __init__(self):
- M3GIndexBuffer.__init__(self)
- self.ObjectType=11
- self.encoding=128 #Byte Bit 7: 1 = explicit property on index buffer true
- #Bit 1 .. 6: 0 = "raw" integer values 1= a single byte will suffice
- #2 = a 16 bit integer is suffi to hold all the given index values
- #IF encoding == 0, THEN
- #self.startIndex = 0 #;UInt32
- #ELSE IF encoding == 1, THEN
- #Byte startIndex;
- #ELSE IF encoding == 2, THEN
- #UInt16 startIndex;
- #ELSE IF encoding == 128, THEN
- self.indices = [] #;UInt32[]
- #ELSE IF encoding == 129, THEN
- #Byte[] indices;
- #ELSE IF encoding == 130, THEN
- #UInt16[] indices;
- #END
- self.stripLengths = [] #;UInt32[]
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//length of TriangleStrips")
- aWriter.write(2,"int[] BL"+str(self.id)+"_stripLength ={"+
- ",".join([str(element) for element in self.stripLengths])+"};")
- aWriter.write(2)
- aWriter.write(2,"//IndexBuffer")
- aWriter.write(2,"int[] BL%i_Indices = {" % (self.id))
- aWriter.write(2,",".join([str(element) for element in self.indices])+"};")
- aWriter.write(2)
- aWriter.write(2,"IndexBuffer BL%i=new TriangleStripArray(BL%i_Indices,BL%i_stripLength);" %
- (self.id, self.id, self.id))
- M3GIndexBuffer.writeJava(self,aWriter,False)
- aWriter.write(2)
-
-
- def getData(self):
- data = M3GIndexBuffer.getData(self)
- data += struct.pack('<BI',self.encoding,
- len(self.indices))
- for element in self.indices:
- data += struct.pack('<I',element)
- data += struct.pack('<I',len(self.stripLengths))
- for element in self.stripLengths:
- data += struct.pack('<I',element)
- return data
-
- def getDataLength(self):
- value = M3GIndexBuffer.getDataLength(self)
- value += struct.calcsize('<BI')
- if len(self.indices) > 0 :
- value += struct.calcsize('<' + str(len(self.indices)) + 'I')
- value += struct.calcsize('<I')
- if len(self.stripLengths) > 0:
- value+= struct.calcsize('<'+str(len(self.stripLengths))+'I')
- return value
-
-
-class M3GAppearance(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
- self.ObjectType=3
- self.layer=0 #Byte
- self.compositingMode=None #ObjectIndex
- self.fog=None #ObjectIndex
- self.polygonMode=None #ObjectIndex
- self.material=None #ObjectIndex
- self.textures=[] #;ObjectIndex[]
-
- def searchDeep(self,alist):
- alist = doSearchDeep([self.compositingMode,self.fog,
- self.polygonMode,self.material]
- + self.textures,alist)
- return M3GObject3D.searchDeep(self,alist)
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += struct.pack("<B5I", self.layer,
- getId(self.compositingMode),
- getId(self.fog),
- getId(self.polygonMode),
- getId(self.material),
- len(self.textures))
- for element in self.textures:
- data += struct.pack("<I",getId(element))
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += struct.calcsize("<B5I")
- if len(self.textures) > 0 :
- value += struct.calcsize("<"+str(len(self.textures))+'I')
- return value
-
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//Appearance")
- aWriter.write(2,"Appearance BL%i = new Appearance();" % (self.id))
- if self.compositingMode!= None:
- aWriter.write(2,"BL%i.setPolygonMode(BL%i);" %
- (self.id,self.compositingMode.id))
- if self.fog!=None:
- aWriter.write(2,"BL%i.setFog(BL%i);" %
- (self.id,self.fog.id))
- if self.polygonMode!=None:
- aWriter.write(2,"BL%i.setPolygonMode(BL%i);" %
- (self.id,self.polygonMode.id))
- if self.material!=None:
- aWriter.write(2,"BL%i.setMaterial(BL%i);" %
- (self.id,self.material.id))
- i=0
- for itexture in self.textures:
- aWriter.write(2,"BL%i.setTexture(%i,BL%i);" %
- (self.id,i,itexture.id))
- i =+ 1
- M3GObject3D.writeJava(self,aWriter,False)
- aWriter.write(2)
-
-class M3GTexture2D(M3GTransformable):
- #M3G imposes the following restrictions when assigning textures to a model:
- #The dimensions must be powers of two (4, 8, 16, 32, 64, 128...).
-
- WRAP_REPEAT = 241
- WRAP_CLAMP = 240
- FILTER_BASE_LEVEL=208
- FILTER_LINEAR=209
- FILTER_NEAREST=210
- FUNC_ADD=224
- FUNC_BLEND=225
- FUNC_DECAL=226
- FUNC_MODULATE=227
- FUNC_REPLACE=228
-
- def __init__(self,aImage):
- M3GTransformable.__init__(self)
- self.ObjectType=17
- self.Image = aImage #ObjectIndex
- self.blendColor=M3GColorRGB(0,0,0)
- self.blending=M3GTexture2D.FUNC_MODULATE #Byte
- self.wrappingS=M3GTexture2D.WRAP_REPEAT #Byte
- self.wrappingT=M3GTexture2D.WRAP_REPEAT #Byte
- self.levelFilter=M3GTexture2D.FILTER_BASE_LEVEL #Byte
- self.imageFilter=M3GTexture2D.FILTER_NEAREST #Byte
-
- def searchDeep(self,alist):
- alist = doSearchDeep([self.Image],alist)
- return M3GTransformable.searchDeep(self,alist)
-
- def getData(self):
- data = M3GTransformable.getData(self)
- data += struct.pack('<I', getId(self.Image))
- data += self.blendColor.getData()
- data += struct.pack('5B',self.blending,
- self.wrappingS,
- self.wrappingT,
- self.levelFilter,
- self.imageFilter)
- return data
-
- def getDataLength(self):
- value = M3GTransformable.getDataLength(self)
- value += struct.calcsize('<I')
- value += self.blendColor.getDataLength()
- value += struct.calcsize('5B')
- return value
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.write(2,"//Texture")
- aWriter.write(2,"Texture2D BL%i = new Texture2D(BL%i);" % (self.id,
- self.Image.id))
- aWriter.write(2,"BL%i.setFiltering(%i,%i);" % (self.id,
- self.levelFilter,
- self.imageFilter))
- aWriter.write(2,"BL%i.setWrapping(%i,%i);" % (self.id,
- self.wrappingS,
- self.wrappingT))
- aWriter.write(2,"BL%i.setBlending(%i);" % (self.id,self.blending))
- aWriter.write(2)
- M3GTransformable.writeJava(self,aWriter,False)
-
-class ImageFactory:
- images={}
- def getImage(self, image, externalReference):
- # It's important to use getFilename() because getName() returns a
- # truncated string depending on the length of the file name.
- filename = Blender.sys.expandpath(image.getFilename())
-
- if self.images.has_key(filename):
- image = self.images[filename]
- elif externalReference:
- # Check for file ending (only relevant for external images). The M3G specification
- # mandates only PNG support, but some devices might also support additional image types.
- [path,ext] = splitext(filename)
- if ext != ".png":
- print "Warning: image file ends with " + ext + ". M3G specification only mandates PNG support."
-
- image = M3GExternalReference()
- image.URI = Blender.sys.basename(filename)
- self.images[filename] = image
- else:
- image = M3GImage2D(image)
- self.images[filename] = image
- return image
-
- getImage = classmethod(getImage)
-
-
-class M3GImage2D(M3GObject3D):
- ALPHA=96 #a single byte per pixel, representing pixel opacity
- LUMINANCE=97 #a single byte per pixel, representing pixel luminance.
- LUMINANCE_ALPHA=98 #two bytes per pixel. The first: luminance, the second: alpha.
- RGB=99 #three bytes per pixel, representing red, green and blue
- RGBA=100 #four bytes per pixel, representing red, green, blue and alpha
-
- def __init__(self, aImage, aFormat=RGBA):
- M3GObject3D.__init__(self)
- self.ObjectType=10
- self.image=aImage #Blender Image
- self.format=aFormat #Byte
- self.isMutable=False #Boolean changable or not
- [self.width, self.height] = aImage.getSize()
-
- #IF isMutable==false, THEN
- self.palette=0 #Byte[]
- self.pixels = array('B') #Byte[]
- self.extractPixelsFromImage()
- #END
-#For a palettised format, the pixels array contains a single palette
-#index per pixel, and the palette array will contain up to 256 entries,
-#each consisting of a pixel specifier appropriate to the format chosen.
-
-#For a non-palettised format, the palette array will be empty,
-#and the pixels array contains a pixel specifier appropriate to the format
-#chosen.
-#In a pixel specifier, each byte is scaled such that 0 represents the
-#value 0.0 and 255 represents the value 1.0. The different formats
-#require different data to be serialized, as follows:
-
-#The width and height of the image must be non-negative powers of two, but they need not be equal.
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += struct.pack('2B', self.format, self.isMutable)
- data += struct.pack('<2I', self.width, self.height)
- if self.isMutable == False:
- # TODO: support palettised formats also
- # export palette data
- data += struct.pack('<I', 0)
-
- # export pixel data
- if self.format == M3GImage2D.RGBA:
- #print "len pixels",len(self.pixels)
- data += struct.pack('<I', len(self.pixels))
- for pixel in self.pixels:
- data += struct.pack('B', pixel)
- #elif...
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += struct.calcsize('2B')
- value += struct.calcsize('<2I')
- if self.isMutable == False:
- # TODO: support palettised formats also
- value+= struct.calcsize('<I')
-
- # pixel data size
- if self.format == M3GImage2D.RGBA:
- value += struct.calcsize('<I')
- value += struct.calcsize(str(len(self.pixels))+'B')
- return value
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- lFileName = self.image.filename
- if not Blender.sys.exists(lFileName) :
- lFileName = Blender.sys.join(dirname(Blender.Get('filename')),
- basename(self.image.filename))
- elif not Blender.sys.exists(lFileName):
- raise FileError, 'Image file not found!'
- lTargetFile = Blender.sys.join(Blender.sys.dirname(aWriter.filename),
- Blender.sys.basename(self.image.filename))
- copy_file(lFileName,lTargetFile)
- #shutil.copyfile(lFileName,lTargetFile)
- aWriter.write(2,"//Image2D")
- aWriter.write(2,"Image BL%i_Image = null;" % (self.id))
- aWriter.write(2,"try {")
- aWriter.write(3,"BL%i_Image = Image.createImage(\"/%s\");" %
- (self.id,basename(self.image.filename)))
- aWriter.write(2,"} catch (IOException e) {")
- aWriter.write(3,"e.printStackTrace();")
- aWriter.write(2,"}")
- aWriter.write(2,"Image2D BL%i = new Image2D(Image2D.RGBA,BL%i_Image);" %
- (self.id,self.id))
- aWriter.write(2)
- M3GObject3D.writeJava(self,aWriter,False)
- aWriter.write(2)
-
- def extractPixelsFromImage(self):
- # Reverse t coordiante because M3G uses a different 2D coordinate system than OpenGL.
- for y in range(self.height):
- for x in range(self.width):
- [r, g, b, a] = self.image.getPixelI(x, self.height-1-y)
- self.pixels.append(r)
- self.pixels.append(g)
- self.pixels.append(b)
- self.pixels.append(a)
-
-class M3GAnimationController(M3GObject3D):
- def __init__(self):
- M3GObject3D.__init__(self)
- self.ObjectType=1
- self.speed = 1.0 #Float32
- self.weight = 1.0 #Float32
- self.activeIntervalStart = 0 #Int32 - (always active)
- self.activeIntervalEnd = 0 #Int32
- self.referenceSequenceTime = 0.0 #Float32
- self.referenceWorldTime = 0 #Int32
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.writeClass("AnimationController",self)
- aWriter.write(2,"AnimationController BL%i = new AnimationController();" %
- (self.id))
- aWriter.write(2,"BL%i.setActiveInterval(%i, %i);" %
- (self.id,self.activeIntervalStart,self.activeIntervalEnd))
- #lightAnim.setPosition(0, 2000);(2) Applying the animation during rendering
- M3GObject3D.writeJava(self,aWriter,False)
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += struct.pack("<ffiifi", self.speed,
- self.weight,
- self.activeIntervalStart,
- self.activeIntervalEnd,
- self.referenceSequenceTime,
- self.referenceWorldTime)
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- return value + struct.calcsize("<ffiifi")
-
-class M3GAnimationTrack(M3GObject3D):
- ALPHA=256
- AMBIENT_COLOR=257
- COLOR=258
- CROP=259
- DENSITY=260
- DIFFUSE_COLOR=261
- EMISSIVE_COLOR=262
- FAR_DISTANCE=263
- FIELD_OF_VIEW=264
- INTENSITY=265
- MORPH_WEIGHTS=266
- NEAR_DISTANCE=267
- ORIENTATION=268
- PICKABILITY=269
- SCALE=270
- SHININESS=271
- SPECULAR_COLOR=272
- SPOT_ANGLE=273
- SPOT_EXPONENT=274
- TRANSLATION=275
- VISIBILITY=276
-
- def __init__(self,aSequence,aProperty):
- M3GObject3D.__init__(self)
- self.ObjectType = 2
- self.keyframeSequence = aSequence #ObjectIndex
- self.animationController = None #ObjectIndex
- self.propertyID = aProperty #UInt32
-
- def getData(self):
- data = M3GObject3D.getData(self)
- data += struct.pack("<3I", getId(self.keyframeSequence),
- getId(self.animationController),
- self.propertyID)
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- return value + struct.calcsize("<3I")
-
- def writeJava(self,aWriter,aCreate):
- if aCreate:
- aWriter.writeClass("AnimationTrack",self)
- #print "self.id,self.keyframeSequence,self.propertyID",self.id,self.keyframeSequence,self.propertyID
- aWriter.write(2,"AnimationTrack BL%i = new AnimationTrack(BL%i,%i);" %
- (self.id,self.keyframeSequence.id,self.propertyID))
- aWriter.write(2,"BL%i.setController(BL%i);" %
- (self.id,self.animationController.id))
- M3GObject3D.writeJava(self,aWriter,False)
-
- def searchDeep(self,alist):
- alist = doSearchDeep([self.keyframeSequence, self.animationController],alist)
- return M3GObject3D.searchDeep(self,alist)
-
-class M3GKeyframeSequence(M3GObject3D):
- CONSTANT=192
- LINEAR=176
- LOOP=193
- SLERP=177
- SPLINE=178
- SQUAD=179
- STEP=180
-
- def __init__(self,aNumKeyframes, aNumComponents,aBlenderInterpolation,
- aM3GInterpolation=None):
- M3GObject3D.__init__(self)
- self.ObjectType = 19
- if aM3GInterpolation!=None:
- self.interpolation = aM3GInterpolation
- else:
- if aBlenderInterpolation == "Constant":
- self.interpolation = self.STEP #Byte
- elif aBlenderInterpolation == "Bezier":
- self.interpolation = self.SPLINE #Byte
- elif aBlenderInterpolation == "Linear":
- self.interpolation = self.LINEAR #Byte
- else:
- pass # TODO : Throw Error
- self.repeatMode = self.CONSTANT #Byte CONSTANT or LOOP
- self.encoding = 0 #Byte 0=raw
- # TODO: Other encodings
- self.duration = 0 #UInt32
- self.validRangeFirst = 0 #UInt32
- self.validRangeLast = 0 #UInt32
- self.componentCount = aNumComponents #UInt32
- self.keyframeCount = aNumKeyframes #UInt32
- #IF encoding == 0
- #FOR each key frame...
- self.time = [] #Int32
- self.vectorValue = [] # Float32[componentCount]
- #END
- #ELSE IF encoding == 1
- #Float32[componentCount] vectorBias;
- #Float32[componentCount] vectorScale;
- #FOR each key frame...
- #Int32 time;
- #Byte[componentCount] vectorValue;
- #END
- #ELSE IF encoding == 2
- #Float32[componentCount] vectorBias;
- #Float32[componentCount] vectorScale;
- #FOR each key frame...
- #Int32 time;
- #UInt16[componentCount] vectorValue;
- #END
- #END
-
-#All of the vectorValue arrays are the same size, so a separate count is stored outside the individual
-#keyframe's data rather than with each array. The encoding field indicates the encoding scheme to be used for the keyframe data. Only the
-#nominated values above are allowed. Other values must be treated as errors.
-
-#•Encoding 0 indicates that the values are stored "raw" as floats.
-#•Encodings 1 and 2 indicate that the values are quantized to 1 or 2 bytes. For each component,
-#a bias and scale are calculated from the sequence of values for that component. The bias is the
-#mimimum value, the scale is the maximum value minus the minimum value. The raw values
-#are then converted to a value 0..1 by subtracting the bias and dividing by the scale. These raw
-#values are then quantized into the range of a Byte or UInt16 by multiplying by 255 or 65535
-#respectively. The converse operation restores the original value from the quantized values.
-
- def beforeExport(self):
- #M3G can not work with negative zero
- #print"beforeExport ID= ",self.id
- for i in range(self.keyframeCount):
- for j in range(self.componentCount):
- x = struct.pack("<f",self.vectorValue[i][j])
- y = struct.unpack("<f",x)
- #print "beforeExport i,j ",i,j,self.vectorValue[i][j],y
- if abs(self.vectorValue[i][j]) < 0.000001 :
- #print "Negative Zero found!",self.vectorValue[i][j]
- self.vectorValue[i][j]=0.0
- #print "zero ",self.vectorValue[i][j]
-
- def getData(self):
- self.beforeExport()
- data = M3GObject3D.getData(self)
- data += struct.pack("<3B5I",self.interpolation,
- self.repeatMode,
- self.encoding,
- self.duration,
- self.validRangeFirst,
- self.validRangeLast,
- self.componentCount,
- self.keyframeCount)
- #FOR each key frame...
- for i in range(self.keyframeCount):
- data += struct.pack("<i",self.time[i]) #Int32
- for j in range(self.componentCount):
- data += struct.pack("<f",self.vectorValue[i][j]) # Float32[componentCount]
- return data
-
- def getDataLength(self):
- value = M3GObject3D.getDataLength(self)
- value += struct.calcsize("<3B5I")
- value += struct.calcsize("<i") * self.keyframeCount
- value += struct.calcsize("<f") * self.keyframeCount * self.componentCount
- return value
-
- def setRepeatMode(self,aBlenderMode):
- if aBlenderMode == "Constant" :
- self.repeatMode = self.CONSTANT
- elif aBlenderMode == "Cyclic":
- self.repeatMode = self.LOOP
- else:
- print "In IPO: Mode " + aBlenderMode + " is not assisted!"
-
- def setKeyframe(self, aIndex, aTime, aVector):
- self.time.append(aTime)
- self.vectorValue.append(aVector)
-
- def writeJava(self,aWriter,aCreate):
- self.beforeExport()
- if aCreate:
- aWriter.writeClass("KeyframeSequence",self)
- aWriter.write(2,"KeyframeSequence BL%i = new KeyframeSequence(%i, %i, %i);" %
- (self.id,self.keyframeCount,self.componentCount,self.interpolation))
- for i in range(len(self.time)):
- lLine = "BL%i.setKeyframe(%i,%i, new float[] { %ff, %ff, %ff" % \
- (self.id,i,self.time[i],self.vectorValue[i][0], \
- self.vectorValue[i][1],self.vectorValue[i][2])
- if self.componentCount == 4:
- lLine += ", %ff" % (self.vectorValue[i][3])
- lLine += "});"
- aWriter.write(2,lLine)
- # TODO : Works only with componentCount = 3
- aWriter.write(2,"BL%i.setDuration(%i);" % (self.id, self.duration))
- aWriter.write(2,"BL%i.setRepeatMode(%i);" % (self.id,self.repeatMode))
- M3GObject3D.writeJava(self,aWriter,False)
-
-# ---- Translator -------------------------------------------------------------- #
-
-class M3GTranslator:
- "Trys to translate a blender scene into a mg3 World"
-
- def __init__(self):
- self.world = None
- self.scene = None
- self.nodes = []
-
- def start(self):
- print "Translate started ..."
-
- self.scene = Blender.Scene.GetCurrent()
- self.world = self.translateWorld(self.scene)
-
- for obj in self.scene.objects :
- if obj.getType()=='Camera': # older Version: isinstance(obj.getData(),Types.CameraType)
- self.translateCamera(obj)
- elif obj.getType()=='Mesh':
- self.translateMesh(obj)
- elif obj.getType()=='Lamp' and mOptions.lightingEnabled: # older Version: isinstance(obj.getData(),Types.LampType)
- self.translateLamp(obj)
- elif obj.getType()=='Empty':
- self.translateEmpty(obj)
- else:
- print "Warning: could not translate" + str(obj) + ". Try to convert object to mesh using Alt-C"
-
- self.translateParenting()
-
- print "Translate finished."
- return self.world
-
- def translateParenting(self):
- for iNode in self.nodes:
- if iNode.parentBlenderObj == None:
- self.world.children.append(iNode)
- else:
- for jNode in self.nodes:
- if iNode.parentBlenderObj == jNode.blenderObj:
- #TODO : Every object can be parent
- jNode.children.append(iNode)
- #lMatrix = Matrix(iNode.blenderMatrixWorld) * Matrix(jNode.blenderMatrixWorld).invert()
- lMatrix = self.calculateChildMatrix(iNode.blenderMatrixWorld,jNode.blenderMatrixWorld)
- iNode.transform = self.translateMatrix(lMatrix)
- iNode.hasGeneralTransform=True
- break
-
- def calculateChildMatrix(self,child,parent):
- return Matrix(child) * Matrix(parent).invert()
-
- def translateArmature(self,obj,meshObj,aSkinnedMesh):
- print "translate Armature ..."
- #print "translateArmature::aSkinnedMesh.vertexBuffer:",aSkinnedMesh.vertexBuffer
- armature = obj.getData()
-
- #Pose
- #pose = obj.getPose()
- #print "pose ",pose
- #for bone in pose.bones.values():
- # print "bone local",bone.localMatrix
- # print "bone pose",bone.poseMatrix
-
- #Skeleton
- mGroup = M3GGroup()
- self.translateCore(obj,mGroup)
- aSkinnedMesh.skeleton = mGroup
- mGroup.transform = self.translateMatrix(
- self.calculateChildMatrix(obj.matrixWorld,
- meshObj.matrixWorld))
-
- #Bones
- #print "armature:",armature.bones
- for bone in armature.bones.values(): #Copy Bones
- mBone = M3GBone()
- mBone.transformNode = M3GGroup()
- self.translateCore(bone, mBone.transformNode)
- #mBone.transformNode.transform = self.translateMatrix(pose.bones[bone.name].poseMatrix)#Test!!!!
- #print "node transform", mBone.transformNode.transform
- #mBone.transformNode.transform=self.translateMatrix(self.calculateChildMatrix(bone.matrix['ARMATURESPACE'],meshObj.matrixWorld))
- if bone.hasParent():
- mBone.transformNode.transform = self.translateMatrix(
- self.calculateChildMatrix(bone.matrix['ARMATURESPACE'],
- bone.parent.matrix['ARMATURESPACE']))
- mBone.weight = bone.weight
- aSkinnedMesh.bones[bone.name]=mBone
-
- rootBone = [] #Copy Child-Parent-Structure
- for bone in armature.bones.values():
- mBone = aSkinnedMesh.bones[bone.name]
- if not bone.hasParent():
- rootBone.append(mBone)
- if bone.hasChildren():
- for childBone in bone.children:
- mChildBone = aSkinnedMesh.bones[childBone.name]
- mBone.transformNode.children.append(mChildBone.transformNode)
- for rbone in rootBone:
- aSkinnedMesh.skeleton.children.append(rbone.transformNode)
-
- #VertexGroups - Skinning
- if armature.vertexGroups:
- for boneName in aSkinnedMesh.bones.keys():
- aSkinnedMesh.bones[boneName].setVerts(self.translateVertsGroup(meshObj.getData(False,True).getVertsFromGroup(boneName),
- aSkinnedMesh))
- #Envelope - Skinning
- if armature.envelopes:
- pass #TODO
-
- #Action
- self.translateAction(obj,aSkinnedMesh)
- aSkinnedMesh.addSecondBone()
-
-
- def translateVertsGroup(self,group,aSkinnedMesh):
- #print "group: ",group
- #print "items: ",aSkinnedMesh.getBlenderIndexes().items()
- ergebnis = [int(k) for k,v in aSkinnedMesh.getBlenderIndexes().items() if v in group]
- #print "ergebnis: ",ergebnis
- return ergebnis
-
- def translateAction(self,armatureObj,aSkinnedMesh):
- action = armatureObj.getAction()
- if action==None: return
-
- print "tranlating Action ..."
- if mOptions.exportAllActions:
- lArmatureID = self.translateUserID(armatureObj.getData().name)
- print "armatureID ", lArmatureID, armatureObj
- for a in Blender.Armature.NLA.GetActions().values():
- (lArmatureActionID,lEndFrame,lActionID) = self.translateActionName(a.name)
- #print "action", a
- #print "lArmatureID", lArmatureActionID
- #print "lEndFrame", lEndFrame
- #print "lActionID", lActionID
- if lArmatureActionID == lArmatureID:
- #print "Action found"
- mController = self.translateActionIPOs(a,aSkinnedMesh,lEndFrame)
- mController.userID = lActionID
- #print "mController.userID ",mController.userID
-
- #print "getActionScripts() ", Blender.Armature.NLA.getActionStrips()
- else:
- self.translateActionIPOs(action,aSkinnedMesh)
-
-
- def translateActionIPOs(self,aAction,aSkinnedMesh,aEndFrame=0):
- ipos = aAction.getAllChannelIpos()
- mController=None
- for boneName in aSkinnedMesh.bones.keys():
- if ipos.has_key(boneName):
- ipo = ipos[boneName]
- if mController==None: mController = M3GAnimationController()
- self.translateIpo(ipo,aSkinnedMesh.bones[boneName].transformNode,mController,aEndFrame)
- return mController
-
- def translateActionName(self,name):
- # <Action Name>#A<M3G ID of Armature>E<End Frame>#<ID of Action>
- lError = "Armature name " + name + " is not ok. Perhaps you should set option 'ExportAllAction' to false."
- #print "name ", name
- lLetter = name.find("#")
- if lLetter == -1 :raise Exception(lError)
- if name[lLetter+1]!='A': raise Exception(lError)
- lName = name[lLetter+2:]
- #print "lName ", lName
- lLetter = lName.find("E")
- #print "lLetter ", lLetter
- if lLetter == -1 :raise Exception(lError)
- #print "lName[:]", lName[:0]
- lArmatureID = int(lName[:lLetter])
- lName = lName[lLetter+1:]
- lLetter = lName.find("#")
- if lLetter == -1:raise Exception(lError)
- lEndFrame = int(lName[:lLetter])
- lActionID = int(lName[lLetter+1:])
- return (lArmatureID,lEndFrame,lActionID)
-
-
- def translateWorld(self,scene):
- "creates world object"
- world = M3GWorld()
-
- #Background
- world.background = M3GBackground()
- blWorld= scene.world
- #AllWorlds = Blender.World.Get() # Set Color
- #if len(AllWorlds)>=1: # world object available
- if blWorld != None:
- world.background.backgroundColor=self.translateRGBA(blWorld.getHor(),0) # horizon color of the first world
- if mOptions.createAmbientLight & mOptions.lightingEnabled:
- lLight = M3GLight()
- lLight.mode = lLight.modes['AMBIENT']
- lLight.color = self.translateRGB(blWorld.getAmb())
- self.nodes.append(lLight)
-
- #TODO: Set background picture from world
-
- return world
-
- def translateEmpty(self,obj):
- print "translate empty ..."
- mGroup = M3GGroup()
- self.translateToNode(obj,mGroup)
-
- def translateCamera(self,obj):
- print "translate camera ..."
- camera = obj.getData()
- if camera.getType()!=0:
- print "Only perscpectiv cameras will work korrekt"
- return #Type=0 'perspectiv' Camera will be translated
- mCamera = M3GCamera()
- mCamera.projectionType=mCamera.PERSPECTIVE
- mCamera.fovy=60.0 # TODO: Calculate fovy from Blender.lens
- mCamera.AspectRatio=4.0/3.0 # TODO: different in every device
- mCamera.near=camera.getClipStart()
- mCamera.far=camera.getClipEnd()
- self.translateToNode(obj,mCamera)
- self.world.activeCamera = mCamera # Last one is always the active one
-
-
- def translateMaterials(self, aMaterial, aMesh, aMatIndex, createNormals, createUvs):
- print "translate materials ..."
-
- mAppearance = M3GAppearance()
-
- if createNormals:
- mMaterial = M3GMaterial()
- mMaterial.name = aMaterial.name
- mMaterial.diffuseColor = self.translateRGBA(aMaterial.rgbCol,1.0) #ColorRGBA
- #material.specularColor= self.translateRGB(mat.specCol) #ColorRGB
- mAppearance.material = mMaterial
-
- if createUvs:
- # Search file name in mesh face.
- lImage = None
- for iface in aMesh.faces:
- if iface.mat==aMatIndex:
- if iface.image != None:
- lImage = iface.image
- break
- if lImage==None:
- raise Exception("Mesh " + aMesh.name + ": No image found for uv-texture! Perhaps no uv-coordinates ?")
-
- # M3G requires textures to have power-of-two dimensions.
- [width, height] = lImage.getSize()
- powerWidth = 1
- while (powerWidth < width):
- powerWidth *= 2
- powerHeight = 1
- while (powerHeight < height):
- powerHeight *= 2
- if powerWidth != width or powerHeight != height:
- raise Exception("Image " + lImage.filename + ": width and height must be power-of-two!")
-
- # ImageFactory reuses existing images.
- mImage = ImageFactory.getImage(lImage, mOptions.textureExternal)
- mTexture = M3GTexture2D(mImage)
- mAppearance.textures.append(mTexture)
-
- mPolygonMode=M3GPolygonMode()
- mPolygonMode.perspectiveCorrectionEnabled = mOptions.perspectiveCorrection
- if not aMesh.mode & Modes.TWOSIDED:
- mPolygonMode.culling=M3GPolygonMode.CULL_BACK
- else:
- mPolygonMode.culling=M3GPolygonMode.CULL_NONE
- if mOptions.smoothShading:
- mPolygonMode.shading=M3GPolygonMode.SHADE_SMOOTH
- else:
- mPolygonMode.shading=M3GPolygonMode.SHADE_FLAT
-
- mAppearance.polygonMode = mPolygonMode
-
- return mAppearance
-
-
- def translateMesh(self,obj):
- print "translate mesh ..." + str(obj)
-
- # Mesh data.
- mesh = obj.getData(False, True) # get Mesh not NMesh object
- if len(mesh.faces) <= 0: # no need to process empty meshes
- print "Empty mesh " + str(obj) + " not processed."
- return
-
- vertexBuffer = M3GVertexBuffer()
- positions = M3GVertexArray(3, 2) # 3 coordinates - 2 bytes
- if mOptions.autoscaling: positions.useMaxPrecision(mesh.verts)
- indexBuffers = []
- appearances = []
- print str(len(mesh.materials)) + " material(s) found."
-
- # Texture coordinates.
- createUvs = False
- if mOptions.textureEnabled & mesh.faceUV:
- for material in mesh.materials:
- if material.getMode() & Material.Modes.TEXFACE: createUvs = True;
-
- if createUvs:
- if mOptions.autoscaling:
- uvCoordinates = M3GVertexArray(2,2,True,True) #2 coordinates - 2 bytes - autoscaling
- else:
- uvCoordinates = M3GVertexArray(2, 2) #2 coordinates - 2 bytes
- uvCoordinates.bias[0] = 0.5
- uvCoordinates.bias[1] = 0.5
- uvCoordinates.bias[2] = 0.5
- uvCoordinates.scale = 1.0/65535.0
- else:
- uvCoordinates = None
-
- # Normals.
- createNormals = False
- if mOptions.lightingEnabled:
- for material in mesh.materials:
- if not (material.getMode() & Material.Modes.SHADELESS): createNormals = True;
-
- if createNormals:
- normals = M3GVertexArray(3, 1) # 3 coordinates - 1 byte
- else:
- normals = None
-
- # Create a submesh for each material.
- for materialIndex, material in enumerate(mesh.materials):
- faces = [face for face in mesh.faces if face.mat == materialIndex]
- if len(faces) >= 0:
- indexBuffers.append(self.translateFaces(faces, positions, normals, uvCoordinates, createNormals, createUvs))
- appearances.append(self.translateMaterials(material, mesh, materialIndex, createNormals, createUvs))
-
- # If the above didn't result in any IndexBuffer (e.g. there's no material), write a single IndexBuffer
- # with all faces and a default Appearance.
- if len(indexBuffers) == 0:
- indexBuffers.append(self.translateFaces(mesh.faces, positions, normals, uvCoordinates, createNormals, createUvs))
- appearances.append(M3GAppearance())
-
- vertexBuffer.setPositions(positions)
- if createNormals: vertexBuffer.normals = normals
- if createUvs: vertexBuffer.texCoordArrays.append(uvCoordinates)
-
- parent = obj.getParent()
- if parent!=None and parent.getType()=='Armature': #Armatures ?
- mMesh = M3GSkinnedMesh(vertexBuffer,indexBuffers,appearances)
- #print"vertexBuffer.positions:",vertexBuffer.positions
- print"mMesh.vertexBuffer:",mMesh.vertexBuffer
- self.translateArmature(parent,obj,mMesh)
- else:
- mMesh = M3GMesh(vertexBuffer,indexBuffers,appearances)
-
- self.translateToNode(obj,mMesh)
-
- #Do Animation
- self.translateObjectIpo(obj,mMesh)
-
- def translateFaces(self, faces, positions, normals, uvCoordinates, createNormals, createUvs):
- """Translates a list of faces into vertex data and triangle strips."""
-
- # Create vertices and triangle strips.
- indices = [0, 0, 0, 0]
- triangleStrips = M3GTriangleStripArray()
-
- for face in faces:
- for vertexIndex, vertex in enumerate(face.verts):
- # Find candidates for sharing (vertices with same Blender ID).
- vertexCandidateIds = [int(k) for k, v in positions.blenderIndexes.items() if v == vertex.index]
-
- # Check normal.
- if createNormals and not face.smooth:
- # For solid faces, a vertex can only be shared if the the face normal is
- # the same as the normal of the shared vertex.
- for candidateId in vertexCandidateIds[:]:
- for j in range(3):
- if face.no[j]*127 != normals.components[candidateId*3 + j]:
- vertexCandidateIds.remove(candidateId)
- break
-
- # Check texture coordinates.
- if createUvs:
- # If texture coordinates are required, a vertex can only be shared if the
- # texture coordinates match.
- for candidateId in vertexCandidateIds[:]:
- s = int((face.uv[vertexIndex][0]-0.5)*65535)
- t = int((0.5-face.uv[vertexIndex][1])*65535)
- if (s != uvCoordinates.components[candidateId*2 + 0]) or (t != uvCoordinates.components[candidateId*2 + 1]):
- vertexCandidateIds.remove(candidateId)
-
- if len(vertexCandidateIds) > 0:
- # Share the vertex.
- indices[vertexIndex] = vertexCandidateIds[0]
- else:
- # Create new vertex.
- positions.append(vertex, vertex.index)
- indices[vertexIndex] = len(positions.components)/3 - 1
-
- # Normal.
- if createNormals:
- for j in range(3):
- if face.smooth:
- normals.append(int(vertex.no[j]*127)) # vertex normal
- else:
- normals.append(int(face.no[j]*127)) # face normal
-
- # Texture coordinates.
- if createUvs:
- lUvCoordinatesFound = True
- print "face.uv[vertexIndex][0]:",face.uv[vertexIndex][0]
- print "face.uv[vertexIndex][1]:",face.uv[vertexIndex][1]
- if mOptions.autoscaling:
- uvCoordinates.append(face.uv[vertexIndex][0])
- uvCoordinates.append(face.uv[vertexIndex][1])
- else:
- uvCoordinates.append(int((face.uv[vertexIndex][0]-0.5)*65535))
- # Reverse t coordinate because M3G uses a different 2D coordinate system than Blender.
- uvCoordinates.append(int((0.5-face.uv[vertexIndex][1])*65535))
-
- # IndexBuffer.
- triangleStrips.stripLengths.append(len(face.verts))
- if len(face.verts) > 3 :
- triangleStrips.indices += [indices[1], indices[2], indices[0], indices[3]] # quad
- else :
- triangleStrips.indices += [indices[0], indices[1], indices[2]] # tri
-
- return triangleStrips
-
-
- def translateObjectIpo(self,obj,aM3GObject):
- if obj.getIpo() == None : return #No Ipo available
- print "translate Ipo ..."
-
- lIpo = obj.getIpo()
- self.translateIpo(lIpo,aM3GObject)
-
-
- def translateIpo(self,aIpo,aM3GObject,aM3GAnimContr=None,aEndFrame=0):
- #Print info about curves
- #for iCurve in lIpo.getCurves():
- # print "Extrapolation",iCurve.getExtrapolation() #Constant, Extrapolation, Cyclic or Cyclic_extrapolation
- # print "Interpolation",iCurve.getInterpolation() #Constant, Bezier, or Linear
- # print "Name",iCurve.getName()
- # for iPoint in iCurve.getPoints():
- # print "Knode points",iPoint.getPoints()
- types = ['Loc','Rot','Size','Quat']
-
- for type in types:
- if aIpo.getCurve(type+'X'):
- self.translateIpoCurve(aIpo,aM3GObject,type,aM3GAnimContr,aEndFrame)
-
-
- def translateIpoCurve(self,aIpo,aM3GObject,aCurveType,aM3GAnimContr,aEndFrame=0):
-
- lContext = self.scene.getRenderingContext()
- if aEndFrame==0:
- lEndFrame = lContext.endFrame()
- else:
- lEndFrame = aEndFrame
-
- lTimePerFrame = 1.0 / lContext.framesPerSec() * 1000
-
- lCurveX = aIpo.getCurve(aCurveType+'X')
- lCurveY = aIpo.getCurve(aCurveType+'Y')
- lCurveZ = aIpo.getCurve(aCurveType+'Z')
- if aCurveType=='Quat': lCurveW = aIpo.getCurve(aCurveType+'W')
-
- lInterpolation = None
- if aCurveType == 'Rot' or aCurveType == 'Quat':
- lTrackType = M3GAnimationTrack.ORIENTATION
- lNumComponents=4
- lCurveFactor= 10 #45 Degrees = 4,5
- if aCurveType == 'Quat':
- lTrackType = M3GAnimationTrack.ORIENTATION
- lNumComponents=4
- lCurveFactor= 1
- lInterpolation = M3GKeyframeSequence.SLERP
- #lInterpolation = M3GKeyframeSequence.SQUAD
- elif aCurveType == 'Size':
- lTrackType = M3GAnimationTrack.SCALE
- lNumComponents=3
- lCurveFactor=1
- else:
- lTrackType = M3GAnimationTrack.TRANSLATION
- lNumComponents=3
- lCurveFactor=1
-
- mSequence = M3GKeyframeSequence(len(lCurveX.getPoints()),
- lNumComponents,
- lCurveX.getInterpolation(),
- lInterpolation)
-
- #print 'ComponentCount',mSequence.componentCount
-
- mSequence.duration = lEndFrame * lTimePerFrame
- mSequence.setRepeatMode(lCurveX.getExtrapolation())
-
- lIndex = 0
- for iPoint in lCurveX.getPoints():
- lPoint = iPoint.getPoints()
-
- lPointList = [(lPoint[1]*lCurveFactor),
- (lCurveY.evaluate(lPoint[0])*lCurveFactor),
- (lCurveZ.evaluate(lPoint[0])*lCurveFactor)]
-
- #print "aCurveType ", aCurveType
-
- if aCurveType == 'Loc':
- #print "PointList ", lPointList
- #lorgTransVector = aM3GObject.blenderTransformMatrix.translationPart()
- #ltrans = TranslationMatrix(Vector(lPointList))
- #ltrans2 = self.calculateChildMatrix(ltrans,aM3GObject.blenderTransformMatrix)
- #lVector = ltrans2.translationPart() + lorgTransVector
- #lPointList = [lVector.x, lVector.y,lVector.z]
- #print "PointList ", lPointList
- pass
-
- if aCurveType == 'Quat':
- lPointList.append(lCurveW.evaluate(lPoint[0])*lCurveFactor)
- #lQuat = Quaternion([lPointList[3],lPointList[0],lPointList[1],lPointList[2]])
- #print "Quat ", lQuat
- #print "Quat.angel ", lQuat.angle
- #print "Quat.axis ", lQuat.axis
- #print "PointList ", lPointList
-
- #print "PointList",lPointList
-
- if aCurveType =='Rot':
- lQuat = Euler(lPointList).toQuat()
- #lPointList = [lQuat.w,lQuat.x,lQuat.y,lQuat.z]
- lPointList = [lQuat.x,lQuat.y,lQuat.z,lQuat.w]
- #print " Quat=", lPointList
-
- mSequence.setKeyframe(lIndex,
- lPoint[0]*lTimePerFrame,
- lPointList)
- lIndex += 1
- mSequence.validRangeFirst = 0
- mSequence.validRangeLast = lIndex - 1
-
- mTrack = M3GAnimationTrack(mSequence,lTrackType)
- aM3GObject.animationTracks.append(mTrack)
- if aM3GAnimContr==None: aM3GAnimContr = M3GAnimationController()
- mTrack.animationController = aM3GAnimContr
-
-
- def translateLamp(self,obj):
- print "translate lamp ..."
- lamp = obj.getData()
-
- #Type
- lampType=lamp.getType()
- if not lampType in [Lamp.Types.Lamp,Lamp.Types.Spot,Lamp.Types.Sun]:
- print "INFO: Type of light is not supported. See documentation"
- return #create not light; type not supported
- mLight = M3GLight()
- if lampType == Lamp.Types.Lamp:
- mLight.mode = mLight.modes['OMNI']
- elif lampType == Lamp.Types.Spot:
- mLight.mode = mLight.modes['SPOT']
- elif lampType == Lamp.Types.Sun:
- mLight.mode = mLight.modes['DIRECTIONAL']
- #Attenuation (OMNI,SPOT):
- if lampType in [Lamp.Types.Lamp,Lamp.Types.Spot]:
- mLight.attenuationConstant = 0.0
- mLight.attenuationLinear = 2.0/lamp.dist
- mLight.attenuationQuadratic = 0.0
- #Color
- mLight.color = self.translateRGB(lamp.col)
- #Energy
- mLight.intensity = lamp.energy
- #SpotAngle, SpotExponent (SPOT)
- if lampType == Lamp.Types.Spot:
- mLight.spotAngle = lamp.spotSize/2
- mLight.spotExponent = lamp.spotBlend
- self.translateToNode(obj,mLight)
-
-
- def translateCore(self,obj,node):
- #Name
- node.name = obj.name
- node.userID = self.translateUserID(obj.name)
- #Location
- #node.translation=self.translateLoc(obj.LocX,obj.LocY,obj.LocZ
- #node.hasComponentTransform=True
- #Transform
- #node.transform = self.translateMatrix(obj.getMatrix('localspace'))
- if type(obj) is Types.BoneType:
- #print "BoneMatrix ",obj.matrix['BONESPACE']
- node.transform = self.translateMatrix(obj.matrix['ARMATURESPACE'])
- #'ARMATURESPACE' - this matrix of the bone in relation to the armature
- #'BONESPACE' - the matrix of the bone in relation to itself
- else:
- node.transform = self.translateMatrix(obj.matrixWorld)
- node.hasGeneralTransform=True
-
-
- def translateToNode(self,obj,node):
- self.translateCore(obj,node)
- #Nodes
- self.nodes.append(node)
- #Link to Blender Object
- node.blenderObj = obj
- node.blenderMatrixWorld = obj.matrixWorld
- lparent = None
- if obj.getParent()!=None:
- if obj.getParent().getType()!='Armature':
- lparent = obj.getParent()
- else:
- if obj.getParent().getParent()!=None and obj.getParent().getParent().getType()!='Armature':
- lparent = obj.getParent().getParent()
- node.parentBlenderObj = lparent
-
-
- def translateUserID(self, name):
- id = 0
- start = name.find('#')
-
- # Use digits that follow the # sign for id.
- if start != -1:
- start += 1
- end = start
- for char in name[start:]:
- if char.isdigit():
- end += 1
- else:
- break
-
- if end > start:
- id = int(name[start:end])
-
- return id
-
- def translateLoc(self,aLocX,aLocY,aLocZ):
- return M3GVector3D(aLocX,aLocY,aLocZ)
-
- def translateRGB(self,color):
- return M3GColorRGB(int(color[0]*255),
- int(color[1]*255),
- int(color[2]*255))
-
- def translateRGBA(self,color,alpha):
- return M3GColorRGBA(int(color[0]*255),
- int(color[1]*255),
- int(color[2]*255),
- int(alpha*255))
-
- def translateMatrix(self,aPyMatrix):
- """
-  0   1   2   3 
- 4   5   6   7 
- 8   9  10  11
- 12  13  14  15 """
- #print "Matrix:", aPyMatrix
- lMatrix = M3GMatrix()
- lMatrix.elements[0] = aPyMatrix[0][0]
- lMatrix.elements[1] = aPyMatrix[1][0]
- lMatrix.elements[2] = aPyMatrix[2][0]
- lMatrix.elements[3] = aPyMatrix[3][0]
- lMatrix.elements[4] = aPyMatrix[0][1]
- lMatrix.elements[5] = aPyMatrix[1][1]
- lMatrix.elements[6] = aPyMatrix[2][1]
- lMatrix.elements[7] = aPyMatrix[3][1]
- lMatrix.elements[8] = aPyMatrix[0][2]
- lMatrix.elements[9] = aPyMatrix[1][2]
- lMatrix.elements[10] = aPyMatrix[2][2]
- lMatrix.elements[11] = aPyMatrix[3][2]
- lMatrix.elements[12] = aPyMatrix[0][3]
- lMatrix.elements[13] = aPyMatrix[1][3]
- lMatrix.elements[14] = aPyMatrix[2][3]
- lMatrix.elements[15] = aPyMatrix[3][3]
- return lMatrix
-
-
-# ---- Exporter ---------------------------------------------------------------- #
-
-class M3GExporter:
- "Exports Blender-Scene to M3D"
- def __init__(self, aWriter):
- self.writer = aWriter
-
-
- def start(self):
- print "Info: starting export ..."
- #rpdb2.start_embedded_debugger("t",True)
- Translator = M3GTranslator()
- world = Translator.start()
-
- #sys.settrace(tracer)
- exportList = self.createDeepSearchList(world)
- externalReferences = [element for element in exportList if element.__class__ is M3GExternalReference]
- exportList = [element for element in exportList if element.__class__ is not M3GExternalReference]
- #sys.settrace(None)
-
- # 1 is reservated for HeaderObject.
- i=1
-
- # Next are the external references.
- for element in externalReferences:
- i += 1
- element.id = i
- print "object ",element.id, element
-
- # And the standard scene objects.
- for element in exportList:
- i += 1
- element.id = i
- print "object ",element.id, element
-
- self.writer.writeFile(world, exportList, externalReferences)
-
- print("Ready!")
-
-
- def createDeepSearchList(self,aWorld):
- "creates the right order for saving m3g : leafs first"
- return aWorld.searchDeep([])
-
-
-
-# ---- Writer ---------------------------------------------------------------- #
-class JavaWriter:
- "writes a java class which creates m3g-Scene in a j2me programm"
- def __init__(self,aFilename):
- self.filename = aFilename
- self.classname = Blender.sys.basename(aFilename)
- self.classname = self.classname[:-5] #without extention ".java"
- self.outFile = file(aFilename,"w")
-
- def write(self, tab, zeile=""):
- "writes to file"
- #print "\t" * tab + zeile
- print >>self.outFile, "\t" * tab + zeile
-
- def writeFile(self,aWorld,aExportList,externalReferences):
- self.world = aWorld
- self.writeHeader()
- for element in aExportList:
- element.writeJava(self,True)
- self.writeFooter()
- self.outFile.close()
-
- def writeHeader(self):
- "writes class header"
- self.write(0,"import javax.microedition.lcdui.Image;")
- self.write(0,"import javax.microedition.m3g.*;")
- self.write(0,"public final class "+self.classname+" {")
- self.write(1,"public static World getRoot(Canvas3D aCanvas) {")
-
- def writeFooter(self):
- self.write(1)
- self.write(1,"return BL"+str(self.world.id)+";")
- self.write(0,"}}")
-
- def writeList(self,alist,numberOfElementsPerLine=12,aType=""):
- '''Writes numberOfElementsPerLine'''
- line=""
- lastLine=""
- counter=0
- for element in alist:
- if counter!=0:
- line = line + "," + str(element) + aType
- else:
- line = str(element) + aType
- counter = counter + 1
- if counter == numberOfElementsPerLine:
- if len(lastLine)>0:
- self.write(3,lastLine+",")
- lastLine=line
- line=""
- counter = 0
- if len(lastLine)>0:
- if len(line)>0:
- self.write(3,lastLine+",")
- else:
- self.write(3,lastLine)
- if len(line) > 0: self.write(3,line)
-
- def writeClass(self,aName,aM3GObject):
- self.write(2)
- self.write(2,"//"+aName+":"+aM3GObject.name)
-
-
-class M3GSectionObject:
- def __init__(self,aObject):
- """Object Structure
- Each object in the file represents one object in the
- scene graph tree, and is stored in a chunk. The
- structure of an object chunk is as follows:
- Byte ObjectType
- UInt32 Length
- Byte[] Data"""
- #ObjectType
- #This field describes what type of object has been serialized.
- #The values 0 and 0xFF are special: 0 represents the header object,
- #and 0xFF represents an external reference.
- #Example: Byte ObjectType = 14
- self.ObjectType = aObject.ObjectType
- self.data = aObject.getData()
- self.length = aObject.getDataLength()
-
- def getData(self):
- data = struct.pack('<BI',self.ObjectType,self.length)
- data += self.data
- return data
-
- def getDataLength(self):
- return struct.calcsize('<BI') + self.length
-
-class M3GSection:
- '''Part of a M3G binary file'
- Section Structur
- Byte CompressionScheme
- UInt32 TotalSectionLength
- UInt32 UncompressedLength
- Byte[] Objects
- UInt32 Checksum '''
- def __init__(self,aObjectList,compressed=False):
- self.CompressionScheme=0
- self.TotalSectionLength=0 #including the CompressionScheme,
- #TotalSectionLength, UncompressedLength,
- #Objects and Checksum fields,
- self.UncompressedLength=0 #Length of Objects uncompresses
- self.Objects = ''
- for element in aObjectList:
- lObject = M3GSectionObject(element)
- #print "Obj:", lObject, lObject.getDataLength(), len(lObject.getData())
- self.Objects += lObject.getData()
- self.UncompressedLength += lObject.getDataLength()
- self.TotalSectionLength=struct.calcsize('<BIII')+self.UncompressedLength
-
- def getData(self):
- data = struct.pack('<BII',self.CompressionScheme,
- self.TotalSectionLength,
- self.UncompressedLength)
- data += self.Objects
- #self.Checksum = zlib.adler32(data)
- self.Checksum = self.ownAdler32(data)
- print "Checksum",self.Checksum
- #print "Own Checksum",self.ownAdler32(data)
- return data + struct.pack('<I',self.Checksum)
-
- def ownAdler32(self,data):
- s1 = int(1) #uint32_t
- s2 = int(0) #uint32_t
- for n in data:
- s1 = (s1 + int(struct.unpack("B",n)[0])) % 65521
- s2 = (s2 + s1) % 65521
- return (s2 << 16) + s1
-
- def getLength(self):
- return self.TotalSectionLength
-
- def write(self,aFile):
- print "Write Section.."
- print "TotalSectionLength:", str(self.TotalSectionLength)
- aFile.write(self.getData())
-
- #CompressionScheme
- #Example Byte CompressionScheme = 1;
- #0 Uncompressed, Adler32 Checksum
- #1 ZLib compression, 32 k buffer size, Adler32 Checksum
- #2...255 Reserved
- #TotalSectionLength: total length of the section in bytes
- #Example: UInt32 TotalSectionLength = 2056
- #UncompressedLength
- #contains the length of the Objects field after decompression.
- #If no compression is specified for this section,
- #this equals the actual number of bytes serialized in the Objects array.
- #CompressionScheme
- #Currently, only the Adler32 checksum is mandatory.
- #The checksum is calculated using all preceding bytes in
- #the section, i.e. the CompressionScheme,TotalSectionLength,
- #UncompressedLength, and the actual serialized data in the
- #Objects field (i.e. in its compressed form if compression is speci-
- #fied).
- #Example: UInt32 Checksum = 0xffe806a3
-
-
-
-
-class M3GFileIdentifier:
- def __init__(self):
- '''Byte[12] FileIdentifier = { 0xAB, 0x4A, 0x53, 0x52, 0x31, 0x38, 0x34,
- 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }
- This can also be expressed using C-style character definitions as:
- Byte[12] FileIdentifier = { '«', 'J', 'S', 'R', '1', '8', '4', '»', '\r',
- '\n', '\x1A', '\n' }'''
- self.data = [ 0xAB, 0x4A, 0x53, 0x52, 0x31, 0x38, 0x34,
- 0xBB, 0x0D, 0x0A, 0x1A, 0x0A ]
-
- def write(self,aFile):
- for element in self.data:
- aFile.write(struct.pack('B',element))
-
- def getLength(self):
- return len(self.data)
-
-
-class M3GWriter:
- """writes a m3g binary file
- File Structur
- File Identifier
- Section 0 File Header Object
- Section 1 External Reference Objects
- Section 2 Scene Objects
- Section 3 Scene Objects
- ... ...
- Section n Scene Objects"""
-
- def __init__(self,aFilename):
- self.FileName = aFilename
-
-
- def writeFile(self,aWorld,aExportList,externalReferences):
- '''Called after translation
- first atempt: all objects in one section'''
- print "M3G file writing .."
-
- fileIdentifier = M3GFileIdentifier()
-
- fileHeaderObject = M3GHeaderObject()
- section0 = M3GSection([fileHeaderObject])
- sectionN = M3GSection(aExportList)
-
- length = fileIdentifier.getLength()
- length += section0.getLength()
- length += sectionN.getLength()
-
- if len(externalReferences) != 0:
- section1 = M3GSection(externalReferences)
- length += section1.getLength()
- fileHeaderObject.hasExternalReferences = True
-
- fileHeaderObject.TotalFileSize=length
- fileHeaderObject.ApproximateContentSize=length
- section0 = M3GSection([fileHeaderObject])
-
- output = open(self.FileName, mode='wb')
-
- fileIdentifier.write(output)
- section0.write(output)
- if len(externalReferences) != 0:
- section1.write(output)
- sectionN.write(output)
-
- output.close()
-
- print "M3G file written."
-
-
-class OptionMgr:
- """Reads and saves options """
-
- def __init__(self):
- self.setDefault()
- rdict = Registry.GetKey('M3GExport', True) # True to check on disk as well
- if rdict: # if found, get the values saved there
- try:
- self.textureEnabled = rdict['textureEnabled']
- self.textureExternal = rdict['textureExternal']
- self.lightingEnabled = rdict['lightingEnabled']
- self.createAmbientLight = rdict['createAmbientLight']
- self.exportAllActions = rdict['exportAllActions']
- self.autoscaling = rdict['autoscaling']
- self.perspectiveCorrection = rdict['perspectiveCorrection']
- self.smoothShading = rdict['smoothShading']
- self.exportAsJava = rdict['exportAsJava']
- self.exportVersion2 = rdict['exportVersion2']
- self.exportGamePhysics = rdict['exportGamePhysics']
-
- except: self.save() # if data isn't valid, rewrite it
-
- def setDefault(self):
- self.textureEnabled = True
- self.textureExternal = False
- self.lightingEnabled = True
- self.createAmbientLight = False
- self.exportAllActions = False
- self.autoscaling = True
- self.perspectiveCorrection = False
- self.smoothShading = True
- self.exportAsJava = False
- self.exportVersion2 = False
- self.exportGamePhysics = False
-
- def save(self):
- d = {}
- d['textureEnabled'] = self.textureEnabled
- d['textureExternal'] = self.textureExternal
- d['lightingEnabled'] = self.lightingEnabled
- d['createAmbientLight'] = self.createAmbientLight
- d['exportAllActions'] = self.exportAllActions
- d['autoscaling'] = self.autoscaling
- d['perspectiveCorrection'] = self.perspectiveCorrection
- d['smoothShading'] = self.smoothShading
- d['exportAsJava'] = self.exportAsJava
- d['exportVersion2'] = self.exportVersion2
- d['exportGamePhysics'] = self.exportGamePhysics
-
- Blender.Registry.SetKey('M3GExport', d, True)
-
-
-# ---- User Interface -------------------------------------------------------- #
-mOptions = OptionMgr()
-
-def gui():
- """Draws the options menu."""
- # Flush events.
- for s in Window.GetScreenInfo():
- Window.QHandle(s['id'])
-
- # Display options.
- textureEnabled = Draw.Create(mOptions.textureEnabled)
- textureExternal = Draw.Create(mOptions.textureExternal)
- lightingEnabled = Draw.Create(mOptions.lightingEnabled)
- createAmbientLight = Draw.Create(mOptions.createAmbientLight)
- exportAllActions = Draw.Create(mOptions.exportAllActions)
- autoscaling = Draw.Create(mOptions.autoscaling)
- perspectiveCorrection = Draw.Create(mOptions.perspectiveCorrection)
- smoothShading = Draw.Create(mOptions.smoothShading)
- exportAsJava = Draw.Create(mOptions.exportAsJava)
- exportVersion2 = Draw.Create(mOptions.exportVersion2)
- exportGamePhysics = Draw.Create(mOptions.exportGamePhysics)
-
- pupBlock = [\
- ('Texturing'),\
- ('Enabled', textureEnabled, 'Enables texture export'),\
- ('External', textureExternal, 'References external files for textures'),\
- ('Lighting'),\
- ('Enabled', lightingEnabled, 'Enables light export'),\
- ('Ambient Light', createAmbientLight, 'Inserts an extra light object for ambient light'),\
- ('Mesh Options'),\
- ('Autoscaling', autoscaling, 'Uses maximum precision for vertex positions'),\
- ('Persp. Correction', perspectiveCorrection, 'Sets perspective correction flag'),\
- ('Smooth Shading', smoothShading, 'Sets smooth shading flag'),\
- ('Posing'),\
- ('All Armature Actions', exportAllActions, 'Exports all actions for armatures'),\
- ('Export'),\
- ('As Java Source', exportAsJava, 'Exports scene as Java source code'),\
- ('M3G Version 2.0', exportVersion2, 'Exports M3G Version 2.0 File'),\
- ('Game Physics', exportGamePhysics, 'Includes Game Physics infos for NOPE in export')
- ]
-
- # Only execute if use didn't quit (ESC).
- if Draw.PupBlock('M3G Export', pupBlock):
- mOptions.textureEnabled = textureEnabled.val
- mOptions.textureExternal = textureExternal.val
- mOptions.lightingEnabled = lightingEnabled.val
- mOptions.createAmbientLight = createAmbientLight.val
- mOptions.exportAllActions = exportAllActions.val
- mOptions.autoscaling = autoscaling.val
- mOptions.perspectiveCorrection = perspectiveCorrection.val
- mOptions.smoothShading = smoothShading.val
- mOptions.exportAsJava = exportAsJava.val
- mOptions.exportVersion2 = exportVersion2.val
- mOptions.exportGamePhysics = exportGamePhysics.val
- mOptions.save()
-
- if mOptions.exportAsJava:
- Window.FileSelector(file_callback_java, 'Export M3G as Java', Blender.sys.makename(ext='.java'))
- else:
- Window.FileSelector(file_callback_m3g, 'Export M3G Binary', Blender.sys.makename(ext='.m3g'))
-
-def file_callback_java(filename):
- Window.WaitCursor(1) # Blender will automatically remove wait cursor in case of an exception
- exporter=M3GExporter(JavaWriter(filename))
- exporter.start()
- Window.WaitCursor(0)
- Window.RedrawAll()
-
-def file_callback_m3g(filename):
- Window.WaitCursor(1)
- exporter=M3GExporter(M3GWriter(filename))
- exporter.start()
- Window.WaitCursor(0)
- Window.RedrawAll()
-
-if __name__ == '__main__':
- gui()
-
diff --git a/release/scripts/export_map.py b/release/scripts/export_map.py
deleted file mode 100644
index 2262ae3b89b..00000000000
--- a/release/scripts/export_map.py
+++ /dev/null
@@ -1,454 +0,0 @@
-#!BPY
-
-"""
-Name: 'Quake 3 (.map)'
-Blender: 249
-Group: 'Export'
-Tooltip: 'Export to Quake map format'
-"""
-
-__author__ = 'Campbell Barton'
-__version__ = '0.1a'
-__email__ = "ideasman42@gmail.com"
-__bpydoc__ = """\
-This script Exports a Quake 3 map format.
-
- Supports meshes, lights and nurbs patch surfaces
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C): Campbell 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 *****
-# --------------------------------------------------------------------------
-
-
-
-
-from Blender import *
-import BPyMesh
-
-PREF_SCALE= Draw.Create(100)
-PREF_FACE_THICK= Draw.Create(0.1)
-PREF_GRID_SNAP= Draw.Create(0)
-# Quake 1/2?
-# PREF_DEF_TEX_OPTS= Draw.Create(' 0 0 0 1 1\n') # not user settable yet
-# Quake 3+?
-PREF_DEF_TEX_OPTS= Draw.Create(' 0 0 0 1 1 0 0 0\n') # not user settable yet
-
-PREF_NULL_TEX= Draw.Create('NULL') # not user settable yet
-PREF_INVIS_TEX= Draw.Create('common/caulk')
-
-def write_cube2brush(file, faces):
- '''
- Takes 6 faces and writes a brush,
- these faces can be from 1 mesh, 1 cube within a mesh of larger cubes
- Faces could even come from different meshes or be contrived.
- '''
- # comment only
- # file.write('// brush "%s", "%s"\n' % (ob.name, ob.getData(name_only=1)))
- file.write('// brush from cube\n{\n')
-
- if PREF_GRID_SNAP.val: format_vec= '( %d %d %d ) '
- else: format_vec= '( %.8f %.8f %.8f ) '
-
- for f in faces:
- # from 4 verts this gets them in reversed order and only 3 of them
- # 0,1,2,3 -> 2,1,0
- for v in f.v[2::-1]:
- file.write(format_vec % tuple(v.co) )
-
- try: mode= f.mode
- except: mode= 0
-
- if mode & Mesh.FaceModes.INVISIBLE:
- file.write(PREF_INVIS_TEX.val)
- else:
- try: image= f.image
- except: image= None
-
- if image: file.write(sys.splitext(sys.basename(image.filename))[0])
- else: file.write(PREF_NULL_TEX.val)
-
- # Texture stuff ignored for now
- file.write(PREF_DEF_TEX_OPTS.val)
- file.write('}\n')
-
-
-def round_vec(v):
- if PREF_GRID_SNAP.val:
- return round(v.x), round(v.y), round(v.z)
- else:
- return tuple(v)
-
-def write_face2brush(file, face):
- '''
- takes a face and writes it as a brush
- each face is a cube/brush
- '''
-
- if PREF_GRID_SNAP.val: format_vec= '( %d %d %d ) '
- else: format_vec= '( %.8f %.8f %.8f ) '
-
-
- image_text= PREF_NULL_TEX.val
-
- try: mode= face.mode
- except: mode= 0
-
- if mode & Mesh.FaceModes.INVISIBLE:
- image_text= PREF_INVIS_TEX.val
- else:
- try: image= face.image
- except: image= None
- if image: image_text = sys.splitext(sys.basename(image.filename))[0]
-
- # original verts as tuples for writing
- orig_vco= [tuple(v.co) for v in face]
-
- # new verts that give the face a thickness
- dist= PREF_SCALE.val * PREF_FACE_THICK.val
- new_vco= [round_vec(v.co - (v.no * dist)) for v in face]
- #new_vco= [round_vec(v.co - (face.no * dist)) for v in face]
-
- file.write('// brush from face\n{\n')
- # front
- for co in orig_vco[2::-1]:
- file.write(format_vec % co )
- file.write(image_text)
- # Texture stuff ignored for now
- file.write(PREF_DEF_TEX_OPTS.val)
-
-
- for co in new_vco[:3]:
- file.write(format_vec % co )
- if mode & Mesh.FaceModes.TWOSIDE:
- file.write(image_text)
- else:
- file.write(PREF_INVIS_TEX.val)
-
- # Texture stuff ignored for now
- file.write(PREF_DEF_TEX_OPTS.val)
-
- # sides.
- if len(orig_vco)==3: # Tri, it seemms tri brushes are supported.
- index_pairs= ((0,1), (1,2), (2,0))
- else:
- index_pairs= ((0,1), (1,2), (2,3), (3,0))
-
- for i1, i2 in index_pairs:
- for co in orig_vco[i1], orig_vco[i2], new_vco[i2]:
- file.write( format_vec % co )
- file.write(PREF_INVIS_TEX.val)
- file.write(PREF_DEF_TEX_OPTS.val)
-
- file.write('}\n')
-
-def is_cube_facegroup(faces):
- '''
- Returens a bool, true if the faces make up a cube
- '''
- # cube must have 6 faces
- if len(faces) != 6:
- print '1'
- return False
-
- # Check for quads and that there are 6 unique verts
- verts= {}
- for f in faces:
- if len(f)!= 4:
- return False
-
- for v in f:
- verts[v.index]= 0
-
- if len(verts) != 8:
- return False
-
- # Now check that each vert has 3 face users
- for f in faces:
- for v in f:
- verts[v.index] += 1
-
- for v in verts.itervalues():
- if v != 3: # vert has 3 users?
- return False
-
- # Could we check for 12 unique edges??, probably not needed.
- return True
-
-def is_tricyl_facegroup(faces):
- '''
- is the face group a tri cylinder
- Returens a bool, true if the faces make an extruded tri solid
- '''
-
- # cube must have 5 faces
- if len(faces) != 5:
- print '1'
- return False
-
- # Check for quads and that there are 6 unique verts
- verts= {}
- tottri= 0
- for f in faces:
- if len(f)== 3:
- tottri+=1
-
- for v in f:
- verts[v.index]= 0
-
- if len(verts) != 6 or tottri != 2:
- return False
-
- # Now check that each vert has 3 face users
- for f in faces:
- for v in f:
- verts[v.index] += 1
-
- for v in verts.itervalues():
- if v != 3: # vert has 3 users?
- return False
-
- # Could we check for 12 unique edges??, probably not needed.
- return True
-
-def write_node_map(file, ob):
- '''
- Writes the properties of an object (empty in this case)
- as a MAP node as long as it has the property name - classname
- returns True/False based on weather a node was written
- '''
- props= [(p.name, p.data) for p in ob.game_properties]
-
- IS_MAP_NODE= False
- for name, value in props:
- if name=='classname':
- IS_MAP_NODE= True
- break
-
- if not IS_MAP_NODE:
- return False
-
- # Write a node
- file.write('{\n')
- for name_value in props:
- file.write('"%s" "%s"\n' % name_value)
- if PREF_GRID_SNAP.val:
- file.write('"origin" "%d %d %d"\n' % tuple([round(axis*PREF_SCALE.val) for axis in ob.getLocation('worldspace')]) )
- else:
- file.write('"origin" "%.6f %.6f %.6f"\n' % tuple([axis*PREF_SCALE.val for axis in ob.getLocation('worldspace')]) )
- file.write('}\n')
- return True
-
-
-def export_map(filepath):
-
- pup_block = [\
- ('Scale:', PREF_SCALE, 1, 1000, 'Scale the blender scene by this value.'),\
- ('Face Width:', PREF_FACE_THICK, 0.01, 10, 'Thickness of faces exported as brushes.'),\
- ('Grid Snap', PREF_GRID_SNAP, 'snaps floating point values to whole numbers.'),\
- 'Null Texture',\
- ('', PREF_NULL_TEX, 1, 128, 'Export textureless faces with this texture'),\
- 'Unseen Texture',\
- ('', PREF_INVIS_TEX, 1, 128, 'Export invisible faces with this texture'),\
- ]
-
- if not Draw.PupBlock('map export', pup_block):
- return
-
- Window.WaitCursor(1)
- time= sys.time()
- print 'Map Exporter 0.0'
- file= open(filepath, 'w')
-
-
- obs_mesh= []
- obs_lamp= []
- obs_surf= []
- obs_empty= []
-
- SCALE_MAT= Mathutils.Matrix()
- SCALE_MAT[0][0]= SCALE_MAT[1][1]= SCALE_MAT[2][2]= PREF_SCALE.val
-
- dummy_mesh= Mesh.New()
-
- TOTBRUSH= TOTLAMP= TOTNODE= 0
-
- for ob in Object.GetSelected():
- type= ob.type
- if type == 'Mesh': obs_mesh.append(ob)
- elif type == 'Surf': obs_surf.append(ob)
- elif type == 'Lamp': obs_lamp.append(ob)
- elif type == 'Empty': obs_empty.append(ob)
-
- if obs_mesh or obs_surf:
- # brushes and surf's must be under worldspan
- file.write('\n// entity 0\n')
- file.write('{\n')
- file.write('"classname" "worldspawn"\n')
-
-
- print '\twriting cubes from meshes'
- for ob in obs_mesh:
- dummy_mesh.getFromObject(ob.name)
-
- #print len(mesh_split2connected(dummy_mesh))
-
- # Is the object 1 cube? - object-is-a-brush
- dummy_mesh.transform(ob.matrixWorld*SCALE_MAT) # 1 to tx the normals also
-
- if PREF_GRID_SNAP.val:
- for v in dummy_mesh.verts:
- co= v.co
- co.x= round(co.x)
- co.y= round(co.y)
- co.z= round(co.z)
-
- # High quality normals
- BPyMesh.meshCalcNormals(dummy_mesh)
-
- # Split mesh into connected regions
- for face_group in BPyMesh.mesh2linkedFaces(dummy_mesh):
- if is_cube_facegroup(face_group):
- write_cube2brush(file, face_group)
- TOTBRUSH+=1
- elif is_tricyl_facegroup(face_group):
- write_cube2brush(file, face_group)
- TOTBRUSH+=1
- else:
- for f in face_group:
- write_face2brush(file, f)
- TOTBRUSH+=1
-
- #print 'warning, not exporting "%s" it is not a cube' % ob.name
-
-
- dummy_mesh.verts= None
-
-
- valid_dims= 3,5,7,9,11,13,15
- for ob in obs_surf:
- '''
- Surf, patches
- '''
- surf_name= ob.getData(name_only=1)
- data= Curve.Get(surf_name)
- mat = ob.matrixWorld*SCALE_MAT
-
- # This is what a valid patch looks like
-
- """
-// brush 0
-{
-patchDef2
-{
-NULL
-( 3 3 0 0 0 )
-(
-( ( -64 -64 0 0 0 ) ( -64 0 0 0 -2 ) ( -64 64 0 0 -4 ) )
-( ( 0 -64 0 2 0 ) ( 0 0 0 2 -2 ) ( 0 64 0 2 -4 ) )
-( ( 64 -64 0 4 0 ) ( 64 0 0 4 -2 ) ( 80 88 0 4 -4 ) )
-)
-}
-}
- """
- for i, nurb in enumerate(data):
- u= nurb.pointsU
- v= nurb.pointsV
- if u in valid_dims and v in valid_dims:
-
- file.write('// brush %d surf_name\n' % i)
- file.write('{\n')
- file.write('patchDef2\n')
- file.write('{\n')
- file.write('NULL\n')
- file.write('( %d %d 0 0 0 )\n' % (u, v) )
- file.write('(\n')
-
- u_iter = 0
- for p in nurb:
-
- if u_iter == 0:
- file.write('(')
-
- u_iter += 1
-
- # add nmapping 0 0 ?
- if PREF_GRID_SNAP.val:
- file.write(' ( %d %d %d 0 0 )' % round_vec(Mathutils.Vector(p[0:3]) * mat))
- else:
- file.write(' ( %.6f %.6f %.6f 0 0 )' % tuple(Mathutils.Vector(p[0:3]) * mat))
-
- # Move to next line
- if u_iter == u:
- file.write(' )\n')
- u_iter = 0
-
- file.write(')\n')
- file.write('}\n')
- file.write('}\n')
-
-
- # Debugging
- # for p in nurb: print 'patch', p
-
- else:
- print "NOT EXPORTING PATCH", surf_name, u,v, 'Unsupported'
-
-
- if obs_mesh or obs_surf:
- file.write('}\n') # end worldspan
-
-
- print '\twriting lamps'
- for ob in obs_lamp:
- print '\t\t%s' % ob.name
- lamp= ob.data
- file.write('{\n')
- file.write('"classname" "light"\n')
- file.write('"light" "%.6f"\n' % (lamp.dist* PREF_SCALE.val))
- if PREF_GRID_SNAP.val:
- file.write('"origin" "%d %d %d"\n' % tuple([round(axis*PREF_SCALE.val) for axis in ob.getLocation('worldspace')]) )
- else:
- file.write('"origin" "%.6f %.6f %.6f"\n' % tuple([axis*PREF_SCALE.val for axis in ob.getLocation('worldspace')]) )
- file.write('"_color" "%.6f %.6f %.6f"\n' % tuple(lamp.col))
- file.write('"style" "0"\n')
- file.write('}\n')
- TOTLAMP+=1
-
-
- print '\twriting empty objects as nodes'
- for ob in obs_empty:
- if write_node_map(file, ob):
- print '\t\t%s' % ob.name
- TOTNODE+=1
- else:
- print '\t\tignoring %s' % ob.name
-
- Window.WaitCursor(0)
-
- print 'Exported Map in %.4fsec' % (sys.time()-time)
- print 'Brushes: %d Nodes: %d Lamps %d\n' % (TOTBRUSH, TOTNODE, TOTLAMP)
-
-
-def main():
- Window.FileSelector(export_map, 'EXPORT MAP', '*.map')
-
-if __name__ == '__main__': main()
-# export_map('/foo.map')
diff --git a/release/scripts/export_mdd.py b/release/scripts/export_mdd.py
deleted file mode 100644
index 4f99c9175fd..00000000000
--- a/release/scripts/export_mdd.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!BPY
-
-"""
- Name: 'Vertex Keyframe Animation (.mdd)...'
- Blender: 242
- Group: 'Export'
- Tooltip: 'Animated mesh to MDD vertex keyframe file.'
-"""
-
-__author__ = "Bill L.Nieuwendorp"
-__bpydoc__ = """\
-This script Exports Lightwaves MotionDesigner format.
-
-The .mdd format has become quite a popular Pipeline format<br>
-for moving animations from package to package.
-
-Be sure not to use modifiers that change the number or order of verts in the mesh
-"""
-#Please send any fixes,updates,bugs to Slow67_at_Gmail.com or cbarton_at_metavr.com
-#Bill Niewuendorp
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import bpy
-import Blender
-from Blender import *
-import BPyMessages
-try:
- from struct import pack
-except:
- pack = None
-
-
-def zero_file(filepath):
- '''
- If a file fails, this replaces it with 1 char, better not remove it?
- '''
- file = open(filepath, 'w')
- file.write('\n') # aparently macosx needs some data in a blank file?
- file.close()
-
-
-def check_vertcount(mesh,vertcount):
- '''
- check and make sure the vertcount is consistent throghout the frame range
- '''
- if len(mesh.verts) != vertcount:
- Blender.Draw.PupMenu('Error%t|Number of verts has changed during animation|cannot export')
- f.close()
- zero_file(filepath)
- return
-
-
-def mdd_export(filepath, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
-
- Window.EditMode(0)
- Blender.Window.WaitCursor(1)
- mesh_orig = Mesh.New()
- mesh_orig.getFromObject(ob.name)
-
- #Flip y and z
- '''
- mat = Mathutils.Matrix()
- mat[2][2] = -1
- rotmat = Mathutils.RotationMatrix(90, 4, 'x')
- mat_flip = mat*rotmat
- '''
- # Above results in this matrix
- mat_flip= Mathutils.Matrix(\
- [1.0, 0.0, 0.0, 0.0],\
- [0.0, 0.0, 1.0, 0.0],\
- [0.0, 1.0, 0.0, 0.0],\
- [0.0, 0.0, 0.0, 1.0],\
- )
-
- me_tmp = Mesh.New() # container mesh
-
- numverts = len(mesh_orig.verts)
- numframes = PREF_ENDFRAME-PREF_STARTFRAME+1
- PREF_FPS= float(PREF_FPS)
- f = open(filepath, 'wb') #no Errors yet:Safe to create file
-
- # Write the header
- f.write(pack(">2i", numframes, numverts))
-
- # Write the frame times (should we use the time IPO??)
- f.write( pack(">%df" % (numframes), *[frame/PREF_FPS for frame in xrange(numframes)]) ) # seconds
-
- #rest frame needed to keep frames in sync
- Blender.Set('curframe', PREF_STARTFRAME)
- me_tmp.getFromObject(ob.name)
- check_vertcount(me_tmp,numverts)
- me_tmp.transform(ob.matrixWorld * mat_flip)
- f.write(pack(">%df" % (numverts*3), *[axis for v in me_tmp.verts for axis in v.co]))
- me_tmp.verts= None
-
- for frame in xrange(PREF_STARTFRAME,PREF_ENDFRAME+1):#in order to start at desired frame
- Blender.Set('curframe', frame)
-
- me_tmp.getFromObject(ob.name)
-
- check_vertcount(me_tmp,numverts)
-
- me_tmp.transform(ob.matrixWorld * mat_flip)
-
- # Write the vertex data
- f.write(pack(">%df" % (numverts*3), *[axis for v in me_tmp.verts for axis in v.co]))
-
- me_tmp.verts= None
- f.close()
-
- print'MDD Exported: %s frames:%d\n'% (filepath, numframes-1)
- Blender.Window.WaitCursor(0)
-
-
-def mdd_export_ui(filepath):
- # Dont overwrite
- if not BPyMessages.Warning_SaveOver(filepath):
- return
-
- scn= bpy.data.scenes.active
- ob_act= scn.objects.active
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
-
- ctx = scn.getRenderingContext()
- orig_frame = Blender.Get('curframe')
- PREF_STARTFRAME= Blender.Draw.Create(int(ctx.startFrame()))
- PREF_ENDFRAME= Blender.Draw.Create(int(ctx.endFrame()))
- PREF_FPS= Blender.Draw.Create(ctx.fps)
-
- block = [\
- ("Start Frame: ", PREF_STARTFRAME, 1, 30000, "Start Bake from what frame?: Default 1"),\
- ("End Frame: ", PREF_ENDFRAME, 1, 30000, "End Bake on what Frame?"),\
- ("FPS: ", PREF_FPS, 1, 100, "Frames per second")\
- ]
-
- if not Blender.Draw.PupBlock("Export MDD", block):
- return
-
- PREF_STARTFRAME, PREF_ENDFRAME=\
- min(PREF_STARTFRAME.val, PREF_ENDFRAME.val),\
- max(PREF_STARTFRAME.val, PREF_ENDFRAME.val)
-
- print (filepath, ob_act, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS.val)
- mdd_export(filepath, ob_act, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS.val)
- Blender.Set('curframe', orig_frame)
-
-if __name__=='__main__':
- if not pack:
- Draw.PupMenu('Error%t|This script requires a full python install')
-
- Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd')) \ No newline at end of file
diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py
deleted file mode 100644
index 7dffb5d2048..00000000000
--- a/release/scripts/export_obj.py
+++ /dev/null
@@ -1,933 +0,0 @@
-#!BPY
-
-"""
-Name: 'Wavefront (.obj)...'
-Blender: 249
-Group: 'Export'
-Tooltip: 'Save a Wavefront OBJ File'
-"""
-
-__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
-__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
-__version__ = "1.22"
-
-__bpydoc__ = """\
-This script is an exporter to OBJ file format.
-
-Usage:
-
-Select the objects you wish to export and run this script from "File->Export" menu.
-Selecting the default options from the popup box will be good in most cases.
-All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
-will be exported as mesh data.
-"""
-
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell J Barton 2007-2009
-# - V1.22- bspline import/export added (funded by PolyDimensions GmbH)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-import Blender
-from Blender import Mesh, Scene, Window, sys, Image, Draw
-import BPyMesh
-import BPyObject
-import BPySys
-import BPyMessages
-
-# Returns a tuple - path,extension.
-# 'hello.obj' > ('hello', '.obj')
-def splitExt(path):
- dotidx = path.rfind('.')
- if dotidx == -1:
- return path, ''
- else:
- return path[:dotidx], path[dotidx:]
-
-def fixName(name):
- if name == None:
- return 'None'
- else:
- return name.replace(' ', '_')
-
-# A Dict of Materials
-# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
-MTL_DICT = {}
-
-def write_mtl(filename):
-
- world = Blender.World.GetCurrent()
- if world:
- worldAmb = world.getAmb()
- else:
- worldAmb = (0,0,0) # Default value
-
- file = open(filename, "w")
- file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1])
- file.write('# Material Count: %i\n' % len(MTL_DICT))
- # Write material/image combinations we have used.
- for key, (mtl_mat_name, mat, img) in MTL_DICT.iteritems():
-
- # Get the Blender data for the material and the image.
- # Having an image named None will make a bug, dont do it :)
-
- file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
-
- if mat:
- file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's
- file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour,
- file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse
- file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular
- file.write('Ni %.6f\n' % mat.IOR) # Refraction index
- file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
-
- # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
- if mat.getMode() & Blender.Material.Modes['SHADELESS']:
- file.write('illum 0\n') # ignore lighting
- elif mat.getSpec() == 0:
- file.write('illum 1\n') # no specular.
- else:
- file.write('illum 2\n') # light normaly
-
- else:
- #write a dummy material here?
- file.write('Ns 0\n')
- file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour,
- file.write('Kd 0.8 0.8 0.8\n')
- file.write('Ks 0.8 0.8 0.8\n')
- file.write('d 1\n') # No alpha
- file.write('illum 2\n') # light normaly
-
- # Write images!
- if img: # We have an image on the face!
- file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
-
- elif mat: # No face image. if we havea material search for MTex image.
- for mtex in mat.getTextures():
- if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
- try:
- filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1]
- file.write('map_Kd %s\n' % filename) # Diffuse mapping image
- break
- except:
- # Texture has no image though its an image type, best ignore.
- pass
-
- file.write('\n\n')
-
- file.close()
-
-def copy_file(source, dest):
- file = open(source, 'rb')
- data = file.read()
- file.close()
-
- file = open(dest, 'wb')
- file.write(data)
- file.close()
-
-
-def copy_images(dest_dir):
- if dest_dir[-1] != sys.sep:
- dest_dir += sys.sep
-
- # Get unique image names
- uniqueImages = {}
- for matname, mat, image in MTL_DICT.itervalues(): # Only use image name
- # Get Texface images
- if image:
- uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default.
-
- # Get MTex images
- if mat:
- for mtex in mat.getTextures():
- if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
- image_tex = mtex.tex.image
- if image_tex:
- try:
- uniqueImages[image_tex] = image_tex
- except:
- pass
-
- # Now copy images
- copyCount = 0
-
- for bImage in uniqueImages.itervalues():
- image_path = sys.expandpath(bImage.filename)
- if sys.exists(image_path):
- # Make a name for the target path.
- dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
- if not sys.exists(dest_image_path): # Image isnt alredy there
- print '\tCopying "%s" > "%s"' % (image_path, dest_image_path)
- copy_file(image_path, dest_image_path)
- copyCount+=1
- print '\tCopied %d images' % copyCount
-
-
-def test_nurbs_compat(ob):
- if ob.type != 'Curve':
- return False
-
- for nu in ob.data:
- if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier
- return True
-
- return False
-
-def write_nurb(file, ob, ob_mat):
- tot_verts = 0
- cu = ob.data
-
- # use negative indices
- Vector = Blender.Mathutils.Vector
- for nu in cu:
-
- if nu.type==0: DEG_ORDER_U = 1
- else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct
-
- if nu.type==1:
- print "\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported"
- continue
-
- if nu.knotsV:
- print "\tWarning, surface:", ob.name, "only poly and nurbs curves supported"
- continue
-
- if len(nu) <= DEG_ORDER_U:
- print "\tWarning, orderU is lower then vert count, skipping:", ob.name
- continue
-
- pt_num = 0
- do_closed = (nu.flagU & 1)
- do_endpoints = (do_closed==0) and (nu.flagU & 2)
-
- for pt in nu:
- pt = Vector(pt[0], pt[1], pt[2]) * ob_mat
- file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2]))
- pt_num += 1
- tot_verts += pt_num
-
- file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too
- file.write('cstype bspline\n') # not ideal, hard coded
- file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still
-
- curve_ls = [-(i+1) for i in xrange(pt_num)]
-
- # 'curv' keyword
- if do_closed:
- if DEG_ORDER_U == 1:
- pt_num += 1
- curve_ls.append(-1)
- else:
- pt_num += DEG_ORDER_U
- curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U]
-
- file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve
-
- # 'parm' keyword
- tot_parm = (DEG_ORDER_U + 1) + pt_num
- tot_parm_div = float(tot_parm-1)
- parm_ls = [(i/tot_parm_div) for i in xrange(tot_parm)]
-
- if do_endpoints: # end points, force param
- for i in xrange(DEG_ORDER_U+1):
- parm_ls[i] = 0.0
- parm_ls[-(1+i)] = 1.0
-
- file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] ))
-
- file.write('end\n')
-
- return tot_verts
-
-def write(filename, objects,\
-EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\
-EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\
-EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\
-EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False,\
-EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True):
- '''
- Basic write function. The context and options must be alredy set
- This can be accessed externaly
- eg.
- write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
- '''
-
- def veckey3d(v):
- return round(v.x, 6), round(v.y, 6), round(v.z, 6)
-
- def veckey2d(v):
- return round(v.x, 6), round(v.y, 6)
-
- def findVertexGroupName(face, vWeightMap):
- """
- Searches the vertexDict to see what groups is assigned to a given face.
- We use a frequency system in order to sort out the name because a given vetex can
- belong to two or more groups at the same time. To find the right name for the face
- we list all the possible vertex group names with their frequency and then sort by
- frequency in descend order. The top element is the one shared by the highest number
- of vertices is the face's group
- """
- weightDict = {}
- for vert in face:
- vWeights = vWeightMap[vert.index]
- for vGroupName, weight in vWeights:
- weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight
-
- if weightDict:
- alist = [(weight,vGroupName) for vGroupName, weight in weightDict.iteritems()] # sort least to greatest amount of weight
- alist.sort()
- return(alist[-1][1]) # highest value last
- else:
- return '(null)'
-
-
- print 'OBJ Export path: "%s"' % filename
- temp_mesh_name = '~tmp-mesh'
-
- time1 = sys.time()
- scn = Scene.GetCurrent()
-
- file = open(filename, "w")
-
- # Write Header
- file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
- file.write('# www.blender3d.org\n')
-
- # Tell the obj file what material file to use.
- if EXPORT_MTL:
- mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1])
- file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] ))
-
- # Get the container mesh. - used for applying modifiers and non mesh objects.
- containerMesh = meshName = tempMesh = None
- for meshName in Blender.NMesh.GetNames():
- if meshName.startswith(temp_mesh_name):
- tempMesh = Mesh.Get(meshName)
- if not tempMesh.users:
- containerMesh = tempMesh
- if not containerMesh:
- containerMesh = Mesh.New(temp_mesh_name)
-
- if EXPORT_ROTX90:
- mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
-
- del meshName
- del tempMesh
-
- # Initialize totals, these are updated each object
- totverts = totuvco = totno = 1
-
- face_vert_index = 1
-
- globalNormals = {}
-
- # Get all meshes
- for ob_main in objects:
- for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
-
- # Nurbs curve support
- if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
- if EXPORT_ROTX90:
- ob_mat = ob_mat * mat_xrot90
-
- totverts += write_nurb(file, ob, ob_mat)
-
- continue
- # end nurbs
-
- # Will work for non meshes now! :)
- # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None)
- me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn)
- if not me:
- continue
-
- if EXPORT_UV:
- faceuv= me.faceUV
- else:
- faceuv = False
-
- # We have a valid mesh
- if EXPORT_TRI and me.faces:
- # Add a dummy object to it.
- has_quads = False
- for f in me.faces:
- if len(f) == 4:
- has_quads = True
- break
-
- if has_quads:
- oldmode = Mesh.Mode()
- Mesh.Mode(Mesh.SelectModes['FACE'])
-
- me.sel = True
- tempob = scn.objects.new(me)
- me.quadToTriangle(0) # more=0 shortest length
- oldmode = Mesh.Mode(oldmode)
- scn.objects.unlink(tempob)
-
- Mesh.Mode(oldmode)
-
- # Make our own list so it can be sorted to reduce context switching
- faces = [ f for f in me.faces ]
-
- if EXPORT_EDGES:
- edges = me.edges
- else:
- edges = []
-
- if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write
- continue # dont bother with this mesh.
-
- if EXPORT_ROTX90:
- me.transform(ob_mat*mat_xrot90)
- else:
- me.transform(ob_mat)
-
- # High Quality Normals
- if EXPORT_NORMALS and faces:
- if EXPORT_NORMALS_HQ:
- BPyMesh.meshCalcNormals(me)
- else:
- # transforming normals is incorrect
- # when the matrix is scaled,
- # better to recalculate them
- me.calcNormals()
-
- # # Crash Blender
- #materials = me.getMaterials(1) # 1 == will return None in the list.
- materials = me.materials
-
- materialNames = []
- materialItems = materials[:]
- if materials:
- for mat in materials:
- if mat: # !=None
- materialNames.append(mat.name)
- else:
- materialNames.append(None)
- # Cant use LC because some materials are None.
- # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken.
-
- # Possible there null materials, will mess up indicies
- # but at least it will export, wait until Blender gets fixed.
- materialNames.extend((16-len(materialNames)) * [None])
- materialItems.extend((16-len(materialItems)) * [None])
-
- # Sort by Material, then images
- # so we dont over context switch in the obj file.
- if EXPORT_KEEP_VERT_ORDER:
- pass
- elif faceuv:
- try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth))
- except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth)))
- elif len(materials) > 1:
- try: faces.sort(key = lambda a: (a.mat, a.smooth))
- except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth)))
- else:
- # no materials
- try: faces.sort(key = lambda a: a.smooth)
- except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth))
-
- # Set the default mat to no material and no image.
- contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get.
- contextSmooth = None # Will either be true or false, set bad to force initialization switch.
-
- if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB:
- name1 = ob.name
- name2 = ob.getData(1)
- if name1 == name2:
- obnamestring = fixName(name1)
- else:
- obnamestring = '%s_%s' % (fixName(name1), fixName(name2))
-
- if EXPORT_BLEN_OBS:
- file.write('o %s\n' % obnamestring) # Write Object name
- else: # if EXPORT_GROUP_BY_OB:
- file.write('g %s\n' % obnamestring)
-
-
- # Vert
- for v in me.verts:
- file.write('v %.6f %.6f %.6f\n' % tuple(v.co))
-
- # UV
- if faceuv:
- uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/
-
- uv_dict = {} # could use a set() here
- for f_index, f in enumerate(faces):
-
- for uv_index, uv in enumerate(f.uv):
- uvkey = veckey2d(uv)
- try:
- uv_face_mapping[f_index][uv_index] = uv_dict[uvkey]
- except:
- uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict)
- file.write('vt %.6f %.6f\n' % tuple(uv))
-
- uv_unique_count = len(uv_dict)
- del uv, uvkey, uv_dict, f_index, uv_index
- # Only need uv_unique_count and uv_face_mapping
-
- # NORMAL, Smooth/Non smoothed.
- if EXPORT_NORMALS:
- for f in faces:
- if f.smooth:
- for v in f:
- noKey = veckey3d(v.no)
- if not globalNormals.has_key( noKey ):
- globalNormals[noKey] = totno
- totno +=1
- file.write('vn %.6f %.6f %.6f\n' % noKey)
- else:
- # Hard, 1 normal from the face.
- noKey = veckey3d(f.no)
- if not globalNormals.has_key( noKey ):
- globalNormals[noKey] = totno
- totno +=1
- file.write('vn %.6f %.6f %.6f\n' % noKey)
-
- if not faceuv:
- f_image = None
-
- if EXPORT_POLYGROUPS:
- # Retrieve the list of vertex groups
- vertGroupNames = me.getVertGroupNames()
-
- currentVGroup = ''
- # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to
- vgroupsMap = [[] for _i in xrange(len(me.verts))]
- for vertexGroupName in vertGroupNames:
- for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1):
- vgroupsMap[vIdx].append((vertexGroupName, vWeight))
-
- for f_index, f in enumerate(faces):
- f_v= f.v
- f_smooth= f.smooth
- f_mat = min(f.mat, len(materialNames)-1)
- if faceuv:
- f_image = f.image
- f_uv= f.uv
-
- # MAKE KEY
- if faceuv and f_image: # Object is always true.
- key = materialNames[f_mat], f_image.name
- else:
- key = materialNames[f_mat], None # No image, use None instead.
-
- # Write the vertex group
- if EXPORT_POLYGROUPS:
- if vertGroupNames:
- # find what vertext group the face belongs to
- theVGroup = findVertexGroupName(f,vgroupsMap)
- if theVGroup != currentVGroup:
- currentVGroup = theVGroup
- file.write('g %s\n' % theVGroup)
-
- # CHECK FOR CONTEXT SWITCH
- if key == contextMat:
- pass # Context alredy switched, dont do anything
- else:
- if key[0] == None and key[1] == None:
- # Write a null material, since we know the context has changed.
- if EXPORT_GROUP_BY_MAT:
- file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null)
- file.write('usemtl (null)\n') # mat, image
-
- else:
- mat_data= MTL_DICT.get(key)
- if not mat_data:
- # First add to global dict so we can export to mtl
- # Then write mtl
-
- # Make a new names from the mat and image name,
- # converting any spaces to underscores with fixName.
-
- # If none image dont bother adding it to the name
- if key[1] == None:
- mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image
- else:
- mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image
-
- if EXPORT_GROUP_BY_MAT:
- file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null)
-
- file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null)
-
- contextMat = key
- if f_smooth != contextSmooth:
- if f_smooth: # on now off
- file.write('s 1\n')
- contextSmooth = f_smooth
- else: # was off now on
- file.write('s off\n')
- contextSmooth = f_smooth
-
- file.write('f')
- if faceuv:
- if EXPORT_NORMALS:
- if f_smooth: # Smoothed, use vertex normals
- for vi, v in enumerate(f_v):
- file.write( ' %d/%d/%d' % (\
- v.index+totverts,\
- totuvco + uv_face_mapping[f_index][vi],\
- globalNormals[ veckey3d(v.no) ])) # vert, uv, normal
-
- else: # No smoothing, face normals
- no = globalNormals[ veckey3d(f.no) ]
- for vi, v in enumerate(f_v):
- file.write( ' %d/%d/%d' % (\
- v.index+totverts,\
- totuvco + uv_face_mapping[f_index][vi],\
- no)) # vert, uv, normal
-
- else: # No Normals
- for vi, v in enumerate(f_v):
- file.write( ' %d/%d' % (\
- v.index+totverts,\
- totuvco + uv_face_mapping[f_index][vi])) # vert, uv
-
- face_vert_index += len(f_v)
-
- else: # No UV's
- if EXPORT_NORMALS:
- if f_smooth: # Smoothed, use vertex normals
- for v in f_v:
- file.write( ' %d//%d' % (\
- v.index+totverts,\
- globalNormals[ veckey3d(v.no) ]))
- else: # No smoothing, face normals
- no = globalNormals[ veckey3d(f.no) ]
- for v in f_v:
- file.write( ' %d//%d' % (\
- v.index+totverts,\
- no))
- else: # No Normals
- for v in f_v:
- file.write( ' %d' % (\
- v.index+totverts))
-
- file.write('\n')
-
- # Write edges.
- if EXPORT_EDGES:
- LOOSE= Mesh.EdgeFlags.LOOSE
- for ed in edges:
- if ed.flag & LOOSE:
- file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts))
-
- # Make the indicies global rather then per mesh
- totverts += len(me.verts)
- if faceuv:
- totuvco += uv_unique_count
- me.verts= None
- file.close()
-
-
- # Now we have all our materials, save them
- if EXPORT_MTL:
- write_mtl(mtlfilename)
- if EXPORT_COPY_IMAGES:
- dest_dir = filename
- # Remove chars until we are just the path.
- while dest_dir and dest_dir[-1] not in '\\/':
- dest_dir = dest_dir[:-1]
- if dest_dir:
- copy_images(dest_dir)
- else:
- print '\tError: "%s" could not be used as a base for an image path.' % filename
-
- print "OBJ Export time: %.2f" % (sys.time() - time1)
-
-
-
-def write_ui(filename):
-
- if not filename.lower().endswith('.obj'):
- filename += '.obj'
-
- if not BPyMessages.Warning_SaveOver(filename):
- return
-
- global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\
- EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\
- EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\
- EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\
- EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\
- EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS
-
- EXPORT_APPLY_MODIFIERS = Draw.Create(0)
- EXPORT_ROTX90 = Draw.Create(1)
- EXPORT_TRI = Draw.Create(0)
- EXPORT_EDGES = Draw.Create(1)
- EXPORT_NORMALS = Draw.Create(0)
- EXPORT_NORMALS_HQ = Draw.Create(0)
- EXPORT_UV = Draw.Create(1)
- EXPORT_MTL = Draw.Create(1)
- EXPORT_SEL_ONLY = Draw.Create(1)
- EXPORT_ALL_SCENES = Draw.Create(0)
- EXPORT_ANIMATION = Draw.Create(0)
- EXPORT_COPY_IMAGES = Draw.Create(0)
- EXPORT_BLEN_OBS = Draw.Create(0)
- EXPORT_GROUP_BY_OB = Draw.Create(0)
- EXPORT_GROUP_BY_MAT = Draw.Create(0)
- EXPORT_KEEP_VERT_ORDER = Draw.Create(1)
- EXPORT_POLYGROUPS = Draw.Create(0)
- EXPORT_CURVE_AS_NURBS = Draw.Create(1)
-
-
- # Old UI
- '''
- # removed too many options are bad!
-
- # Get USER Options
- pup_block = [\
- ('Context...'),\
- ('Selection Only', EXPORT_SEL_ONLY, 'Only export objects in visible selection. Else export whole scene.'),\
- ('All Scenes', EXPORT_ALL_SCENES, 'Each scene as a separate OBJ file.'),\
- ('Animation', EXPORT_ANIMATION, 'Each frame as a numbered OBJ file.'),\
- ('Object Prefs...'),\
- ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object. May break vert order for morph targets.'),\
- ('Rotate X90', EXPORT_ROTX90 , 'Rotate on export so Blenders UP is translated into OBJs UP'),\
- ('Keep Vert Order', EXPORT_KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\
- ('Extra Data...'),\
- ('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\
- ('Normals', EXPORT_NORMALS, 'Export vertex normal data (Ignored on import).'),\
- ('High Quality Normals', EXPORT_NORMALS_HQ, 'Calculate high quality normals for rendering.'),\
- ('UVs', EXPORT_UV, 'Export texface UV coords.'),\
- ('Materials', EXPORT_MTL, 'Write a separate MTL file with the OBJ.'),\
- ('Copy Images', EXPORT_COPY_IMAGES, 'Copy image files to the export directory, never overwrite.'),\
- ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\
- ('Grouping...'),\
- ('Objects', EXPORT_BLEN_OBS, 'Export blender objects as "OBJ objects".'),\
- ('Object Groups', EXPORT_GROUP_BY_OB, 'Export blender objects as "OBJ Groups".'),\
- ('Material Groups', EXPORT_GROUP_BY_MAT, 'Group by materials.'),\
- ]
-
- if not Draw.PupBlock('Export...', pup_block):
- return
- '''
-
- # BEGIN ALTERNATIVE UI *******************
- if True:
-
- EVENT_NONE = 0
- EVENT_EXIT = 1
- EVENT_REDRAW = 2
- EVENT_EXPORT = 3
-
- GLOBALS = {}
- GLOBALS['EVENT'] = EVENT_REDRAW
- #GLOBALS['MOUSE'] = Window.GetMouseCoords()
- GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
-
- def obj_ui_set_event(e,v):
- GLOBALS['EVENT'] = e
-
- def do_split(e,v):
- global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER, EXPORT_POLYGROUPS
- if EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val:
- EXPORT_KEEP_VERT_ORDER.val = 0
- else:
- EXPORT_KEEP_VERT_ORDER.val = 1
-
- def do_vertorder(e,v):
- global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER
- if EXPORT_KEEP_VERT_ORDER.val:
- EXPORT_BLEN_OBS.val = EXPORT_GROUP_BY_OB.val = EXPORT_GROUP_BY_MAT.val = EXPORT_APPLY_MODIFIERS.val = 0
- else:
- if not (EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val):
- EXPORT_KEEP_VERT_ORDER.val = 1
-
-
- def do_help(e,v):
- url = __url__[0]
- print 'Trying to open web browser with documentation at this address...'
- print '\t' + url
-
- try:
- import webbrowser
- webbrowser.open(url)
- except:
- print '...could not open a browser window.'
-
- def obj_ui():
- ui_x, ui_y = GLOBALS['MOUSE']
-
- # Center based on overall pup size
- ui_x -= 165
- ui_y -= 140
-
- global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\
- EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\
- EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\
- EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\
- EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\
- EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS
-
- Draw.Label('Context...', ui_x+9, ui_y+239, 220, 20)
- Draw.BeginAlign()
- EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+219, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.')
- EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+219, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.')
- EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+219, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.')
- Draw.EndAlign()
-
-
- Draw.Label('Output Options...', ui_x+9, ui_y+189, 220, 20)
- Draw.BeginAlign()
- EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+170, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split)
- EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+170, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP')
- EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+170, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.')
- Draw.EndAlign()
-
-
- Draw.Label('Export...', ui_x+9, ui_y+139, 220, 20)
- Draw.BeginAlign()
- EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+120, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.')
- EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+120, 70, 20, EXPORT_TRI.val, 'Triangulate quads.')
- Draw.EndAlign()
- Draw.BeginAlign()
- EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+120, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.')
- EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+120, 31, 20, EXPORT_UV.val, 'Export texface UV coords.')
- Draw.EndAlign()
- Draw.BeginAlign()
- EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+120, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).')
- EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+120, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.')
- Draw.EndAlign()
- EXPORT_POLYGROUPS = Draw.Toggle('Polygroups', EVENT_REDRAW, ui_x+9, ui_y+95, 120, 20, EXPORT_POLYGROUPS.val, 'Export vertex groups as OBJ groups (one group per face approximation).')
-
- EXPORT_CURVE_AS_NURBS = Draw.Toggle('Nurbs', EVENT_NONE, ui_x+139, ui_y+95, 100, 20, EXPORT_CURVE_AS_NURBS.val, 'Export 3D nurbs curves and polylines as OBJ curves, (bezier not supported).')
-
-
- Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20)
- Draw.BeginAlign()
- EXPORT_BLEN_OBS = Draw.Toggle('Objects', EVENT_REDRAW, ui_x+9, ui_y+39, 60, 20, EXPORT_BLEN_OBS.val, 'Export blender objects as "OBJ objects".', do_split)
- EXPORT_GROUP_BY_OB = Draw.Toggle('Groups', EVENT_REDRAW, ui_x+69, ui_y+39, 60, 20, EXPORT_GROUP_BY_OB.val, 'Export blender objects as "OBJ Groups".', do_split)
- EXPORT_GROUP_BY_MAT = Draw.Toggle('Material Groups', EVENT_REDRAW, ui_x+129, ui_y+39, 100, 20, EXPORT_GROUP_BY_MAT.val, 'Group by materials.', do_split)
- Draw.EndAlign()
-
- EXPORT_KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+239, ui_y+39, 100, 20, EXPORT_KEEP_VERT_ORDER.val, 'Keep vert and face order, disables some other options. Use for morph targets.', do_vertorder)
-
- Draw.BeginAlign()
- Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 20, 'Load the wiki page for this script', do_help)
- Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 20, '', obj_ui_set_event)
- Draw.PushButton('Export', EVENT_EXPORT, ui_x+229, ui_y+9, 110, 20, 'Export with these settings', obj_ui_set_event)
- Draw.EndAlign()
-
-
- # hack so the toggle buttons redraw. this is not nice at all
- while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_EXPORT):
- Draw.UIBlock(obj_ui, 0)
-
- if GLOBALS['EVENT'] != EVENT_EXPORT:
- return
-
- # END ALTERNATIVE UI *********************
-
-
- if EXPORT_KEEP_VERT_ORDER.val:
- EXPORT_BLEN_OBS.val = False
- EXPORT_GROUP_BY_OB.val = False
- EXPORT_GROUP_BY_MAT.val = False
- EXPORT_APPLY_MODIFIERS.val = False
-
- Window.EditMode(0)
- Window.WaitCursor(1)
-
- EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val
- EXPORT_ROTX90 = EXPORT_ROTX90.val
- EXPORT_TRI = EXPORT_TRI.val
- EXPORT_EDGES = EXPORT_EDGES.val
- EXPORT_NORMALS = EXPORT_NORMALS.val
- EXPORT_NORMALS_HQ = EXPORT_NORMALS_HQ.val
- EXPORT_UV = EXPORT_UV.val
- EXPORT_MTL = EXPORT_MTL.val
- EXPORT_SEL_ONLY = EXPORT_SEL_ONLY.val
- EXPORT_ALL_SCENES = EXPORT_ALL_SCENES.val
- EXPORT_ANIMATION = EXPORT_ANIMATION.val
- EXPORT_COPY_IMAGES = EXPORT_COPY_IMAGES.val
- EXPORT_BLEN_OBS = EXPORT_BLEN_OBS.val
- EXPORT_GROUP_BY_OB = EXPORT_GROUP_BY_OB.val
- EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val
- EXPORT_KEEP_VERT_ORDER = EXPORT_KEEP_VERT_ORDER.val
- EXPORT_POLYGROUPS = EXPORT_POLYGROUPS.val
- EXPORT_CURVE_AS_NURBS = EXPORT_CURVE_AS_NURBS.val
-
-
- base_name, ext = splitExt(filename)
- context_name = [base_name, '', '', ext] # basename, scene_name, framenumber, extension
-
- # Use the options to export the data using write()
- # def write(filename, objects, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, EXPORT_APPLY_MODIFIERS=True):
- orig_scene = Scene.GetCurrent()
- if EXPORT_ALL_SCENES:
- export_scenes = Scene.Get()
- else:
- export_scenes = [orig_scene]
-
- # Export all scenes.
- for scn in export_scenes:
- scn.makeCurrent() # If alredy current, this is not slow.
- context = scn.getRenderingContext()
- orig_frame = Blender.Get('curframe')
-
- if EXPORT_ALL_SCENES: # Add scene name into the context_name
- context_name[1] = '_%s' % BPySys.cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied.
-
- # Export an animation?
- if EXPORT_ANIMATION:
- scene_frames = xrange(context.startFrame(), context.endFrame()+1) # up to and including the end frame.
- else:
- scene_frames = [orig_frame] # Dont export an animation.
-
- # Loop through all frames in the scene and export.
- for frame in scene_frames:
- if EXPORT_ANIMATION: # Add frame to the filename.
- context_name[2] = '_%.6d' % frame
-
- Blender.Set('curframe', frame)
- if EXPORT_SEL_ONLY:
- export_objects = scn.objects.context
- else:
- export_objects = scn.objects
-
- full_path= ''.join(context_name)
-
- # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad.
- # EXPORT THE FILE.
- write(full_path, export_objects,\
- EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\
- EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\
- EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\
- EXPORT_ROTX90, EXPORT_BLEN_OBS,\
- EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\
- EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS)
-
- Blender.Set('curframe', orig_frame)
-
- # Restore old active scene.
- orig_scene.makeCurrent()
- Window.WaitCursor(0)
-
-
-if __name__ == '__main__':
- Window.FileSelector(write_ui, 'Export Wavefront OBJ', sys.makename(ext='.obj'))
diff --git a/release/scripts/faceselect_same_weights.py b/release/scripts/faceselect_same_weights.py
deleted file mode 100644
index 967aedec363..00000000000
--- a/release/scripts/faceselect_same_weights.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!BPY
-"""
-Name: 'Same Weights...'
-Blender: 245
-Group: 'FaceSelect'
-Tooltip: 'Select same faces with teh same weight for the active group.'
-"""
-
-__author__ = ["Campbell Barton aka ideasman42"]
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Select Same Weights
-
-Select same weights as the active face on the active group.
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Draw, Mesh
-import BPyMesh
-
-def selSameWeights(me, PREF_TOLERENCE):
-
- # Check for missing data
- if not me.faceUV: return
-
- act_group= me.activeGroup
- if not act_group: return
-
- act_face = me.faces[me.activeFace]
- if act_face == None: return
-
-
-
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
-
- def get_face_weight(f):
- '''
- Return the faces median weight and weight range.
- '''
- wmin = 1.0
- wmax = 0.0
- w = 0.0
- for v in f:
- try:
- new_weight = vWeightDict[v.index][act_group]
- if wmin > new_weight: wmin = new_weight
- if wmax < new_weight: wmax = new_weight
- w += new_weight
- except:
- pass
- return w, wmax-wmin # weight, range
-
- weight_from, weight_range_from = get_face_weight(act_face)
- for f in me.faces:
- if (not f.sel) and f != act_face:
- weight, weight_range = get_face_weight(f)
-
- # Compare the 2 faces weight difference and difference in their contrast.
- if\
- abs(weight - weight_from) <= PREF_TOLERENCE and\
- abs(weight_range - weight_range_from) <= PREF_TOLERENCE:
- f.sel = True
-
-
-def main():
- scn= Scene.GetCurrent()
- ob= scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- me= ob.getData(mesh=1)
-
- PREF_TOLERENCE= Draw.Create(0.1)
-
- pup_block= [\
- ('Tolerence:', PREF_TOLERENCE, 0.01, 1.0, 'Tolerence for selecting faces of the same weight.'),\
- ]
-
- if not Draw.PupBlock('Select Same Weight...', pup_block):
- return
-
- PREF_TOLERENCE= PREF_TOLERENCE.val
-
- selSameWeights(me, PREF_TOLERENCE)
-
-if __name__=='__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/flt_defaultp.py b/release/scripts/flt_defaultp.py
deleted file mode 100644
index 5c44fe29a6f..00000000000
--- a/release/scripts/flt_defaultp.py
+++ /dev/null
@@ -1 +0,0 @@
-pal = [-1,255,16711935,-16776961,-19529729,-19726337,-19922945,-20119553,-20316161,-20578305,-20840449,-21102593,-21364737,-21692417,-22020097,-22413313,-22806529,-23199745,-23658497,-24117249,-24641537,-25165825,-25755649,-26411009,-27066369,-27787265,-28573697,-29425665,-30343169,-31326209,-32374785,-33488897,-354549761,-371458049,-388366337,-405274625,-422182913,-439156737,-456130561,-473104385,-506855425,-540672001,-574488577,-608305153,-642121729,-676003841,-709885953,-760610817,-811335681,-862060545,-912850945,-980418561,-1048051713,-1115684865,-1183383553,-1267924993,-1352466433,-1453850625,-1555300353,-1656815617,-1775173633,-1893597185,-2028863489,2130771967,-1010376193,-1043996161,-1077681665,-1111367169,-1145052673,-1178738177,-1229200897,-1279663617,-1330126337,-1380654593,-1431182849,-1498488321,-1565793793,-1633164801,-1700535809,-1784684033,-1868832257,-1969823233,-2070814209,2123096575,2005262847,1887429119,1752752639,1601298943,1449779711,1281417727,1096278527,911073791,709026303,490201599,254534143,2023935,-1380857601,-1397700353,-1431320321,-1464940289,-1498560257,-1532180225,-1565865729,-1599551233,-1650013953,-1700476673,-1750939393,-1801402113,-1851864833,-1919170305,-1986475777,-2053781249,-2121086721,2089797887,2005649663,1904724223,1803798783,1686030591,1568262399,1450494207,1315883263,1164495103,1013041407,844810495,659736831,457885951,239192319,3655935,-1767919617,-1784762369,-1801605121,-1818447873,-1852067841,-1885687809,-1919307777,-1952927745,-1986547713,-2020167681,-2070564865,-2120962049,2123542527,2073079807,2022617087,1955377151,1888137215,1820897279,1736880127,1652797439,1568714751,1467854847,1366994943,1249357823,1131655167,997175295,862695423,711372799,560050175,391950335,207007743,5287935,2139657983,2122880767,2106103551,2089326335,2072549119,2055771903,2022217471,1988663039,1955108607,1921554175,1887934207,1854314239,1803917055,1753519871,1703122687,1652725503,1602328319,1535153919,1467979519,1400805119,1316853503,1232901887,1148950271,1048221439,947427071,846632703,729061119,611489535,477140735,326014719,174888703,6919935,1837268479,1820491263,1803714047,1786936831,1770159615,1753382399,1736605183,1719827967,1686273535,1652719103,1619164671,1585610239,1552055807,1518501375,1468169727,1417838079,1367506431,1317174783,1266843135,1199734271,1132625407,1065516543,998407679,914521599,830635519,729972223,629308927,528645631,411205119,293764607,159546879,8551935,-2086957569,-2103734785,-2120512001,-2137289217,2140900863,2107346431,2073791999,2040237311,2006682623,1973127935,1939573247,1906018559,1855686655,1805354751,1755022847,1704690943,1654359039,1587249919,1520140799,1453031679,1369145343,1285258751,1201372159,1100708351,1000044543,882603519,765162495,630943999,496725503,345729791,177956863,10183935,-1699437825,-1716215297,-1732992769,-1766547457,-1800102145,-1833656833,-1867211521,-1900766209,-1934320897,-1967875585,-2018207489,-2068539649,-2118871809,2125763327,2058653951,1991544575,1924435199,1857325823,1773438975,1689552127,1588888063,1488223999,1387559679,1270118143,1152676607,1018457855,884238847,733242623,565468927,397695231,213144319,11815935,-1311918593,-1345473281,-1379027969,-1412582657,-1446137345,-1479692289,-1513247233,-1546802177,-1597134337,-1647466497,-1697798657,-1748130817,-1798463233,-1865572865,-1932682497,-1999792129,-2083678977,2127401215,2043514111,1942849791,1842185215,1724743423,1607301631,1473082367,1338863103,1187866367,1020092415,852318207,667766783,466437887,248331519,13447935,-924398849,-957953793,-991508737,-1025063681,-1058618625,-1092173569,-1142505729,-1192837889,-1243170305,-1293502721,-1343835137,-1410944769,-1478054401,-1545164289,-1629051393,-1712938497,-1796825857,-1897490433,-1998155009,-2098819841,2078705407,1961263103,1827043583,1676046591,1525049599,1357275135,1172723199,971394047,753287423,518403327,283518975,15079935,-570434049,-603988993,-637543937,-671098881,-704653825,-754986241,-805318657,-855651073,-905983489,-973093377,-1040203265,-1107313153,-1174423041,-1258310401,-1342197761,-1442862593,-1543527425,-1644192257,-1761634561,-1879076865,-2013296641,2147450879,1996453631,1828678911,1660904191,1476351999,1275022335,1056915199,822030591,570368511,301928959,16711935,-503325185,-536880129,-570435073,-603990017,-637544961,-671100161,-721432577,-771764993,-822097409,-872430081,-922762753,-989872641,-1056982529,-1124092673,-1191202817,-1275090433,-1358978049,-1459642881,-1560307969,-1660973057,-1778415617,-1895858177,-2030078209,2113891583,1962894079,1795119103,1610566655,1426013951,1224683775,1006576127,771691007,520028415,-452993537,-469771265,-503326209,-536881153,-570436097,-603991297,-637546497,-671101697,-721434113,-771766785,-822099457,-872432129,-922764801,-989874945,-1056985089,-1124095489,-1191205889,-1275093505,-1358981377,-1459646465,-1560311809,-1677754369,-1795197185,-1912640257,-2046860545,2097108991,1946110975,1778335487,1593782527,1392452095,1174344191,939458815,-419439105,-436216833,-452994561,-469772289,-503327233,-536882433,-570437633,-603992833,-637548033,-671103489,-721436161,-771768833,-822101505,-872434433,-922767361,-989877761,-1056988161,-1124098561,-1207986433,-1291874305,-1375762433,-1476427777,-1577093377,-1694536449,-1811979521,-1946200065,-2080420865,2063548159,1912549631,1744773631,1560220159,1358889215,-385884673,-402662401,-419440129,-436217857,-452995585,-469773569,-503328769,-536883969,-570439169,-603994625,-637550081,-671105537,-721438209,-771771137,-822104065,-872437249,-922770433,-989880833,-1056991489,-1124102145,-1191213057,-1275101185,-1358989569,-1459655425,-1560321281,-1677764609,-1795208193,-1912652033,-2046873345,2097095167,1946096127,1778319615,-335553025,-352330753,-369108481,-385886209,-402663937,-419441921,-436219905,-452997889,-486553089,-520108545,-553664001,-587219457,-620774913,-654330625,-687886337,-738219521,-788552705,-838885889,-889219329,-939552769,-1006663681,-1073774593,-1140885761,-1224774401,-1308663041,-1392551937,-1493218305,-1593884929,-1711329025,-1828773377,-1962995201,-2097217281,-285221377,-301999105,-318776833,-335554561,-352332289,-369110273,-385888257,-402666241,-419444225,-436222465,-453000705,-469778945,-503334401,-536890113,-570445825,-604001793,-637557761,-671113729,-721447169,-771780609,-822114305,-872448001,-922781953,-989893377,-1057004801,-1124116481,-1191228417,-1275117825,-1359007489,-1459674625,-1560342017,-1677786881,-234889729,-234890241,-251667969,-268445697,-285223425,-302001409,-318779393,-335557377,-352335361,-369113601,-385891841,-402670081,-419448321,-436226817,-453005313,-469784065,-503340033,-536896001,-570452225,-604008449,-637564929,-671121409,-704678145,-755012353,-805346561,-855681025,-906015745,-973127937,-1040240385,-1107353089,-1174466049,-1258356481,-234889729,-234890241,-234890753,-234891265,-234891777,-234892545,-234893313,-234894081,-234894849,-251673089,-268451329,-285229569,-302007809,-318786305,-335564801,-352343553,-369122305,-385901057,-402680065,-419459073,-436238337,-453017601,-486574337,-520131329,-553688321,-587245569,-620803073,-654360833,-687918849,-738254337,-788590081,-838926081,-234889729,-234890241,-234890753,-234891265,-234891777,-234892545,-234893313,-234894081,-234894849,-234895873,-234896897,-234897921,-234898945,-234900225,-234901505,-234903041,-234904577,-234906113,-234907905,-234909697,-234911745,-251691009,-268470529,-285250305,-302030081,-318810113,-335590401,-352370945,-369151745,-385932801,-402714113,-419495681,-8705,-9217,-9729,-10241,-10753,-11521,-12289,-13057,-13825,-14849,-15873,-16897,-17921,-19201,-20481,-22017,-23553,-25089,-26881,-28673,-30721,-32769,-35073,-37633,-40193,-43009,-46081,-49409,-52993,-56833,-60929,-65281,-926209,-926721,-927233,-927745,-928257,-929025,-929793,-930561,-931329,-932353,-933377,-934401,-935425,-936705,-937985,-939521,-941057,-1008129,-1075457,-1142785,-1210369,-1277953,-1345793,-1413889,-1481985,-1550337,-1618945,-1687809,-1756929,-1826305,-1895937,-2031361,-926209,-926721,-927233,-927745,-928257,-929025,-929793,-996097,-1062401,-1128961,-1195521,-1262081,-1328641,-1395457,-1462273,-1529345,-1596417,-1663489,-1730817,-1798145,-1865729,-1998849,-2132225,-2265857,-2399489,-2533377,-2667521,-2867457,-3067649,-3268097,-3468801,-3669761,-926209,-992257,-1058305,-1124353,-1190401,-1256705,-1323009,-1389313,-1455617,-1522177,-1588737,-1655297,-1721857,-1788673,-1855489,-1988097,-2120705,-2253313,-2386177,-2519041,-2652161,-2785281,-2984193,-3183361,-3382529,-3581953,-3847169,-4112641,-4378369,-4644353,-4976129,-5308161,-1188353,-1254401,-1320449,-1386497,-1452545,-1518849,-1585153,-1651457,-1717761,-1784321,-1850881,-1982977,-2115073,-2247425,-2379777,-2512385,-2644993,-2777601,-2976001,-3174401,-3373057,-3571713,-3836161,-4100865,-4365569,-4630529,-4961281,-5292289,-5689089,-6086145,-6483457,-6946561,-1384961,-1451009,-1517057,-1583105,-1649153,-1715457,-1781761,-1848065,-1979905,-2112001,-2244097,-2376193,-2508289,-2640641,-2838529,-3036673,-3234817,-3432961,-3631361,-3895297,-4159489,-4423681,-4688129,-5018369,-5348609,-5744641,-6140929,-6537473,-6999809,-7462401,-7990785,-8584961,-1581569,-1647617,-1713665,-1779713,-1845761,-1977601,-2109441,-2241281,-2373121,-2505217,-2637313,-2769409,-2967041,-3164929,-3362817,-3560961,-3759105,-4022785,-4286721,-4550657,-4880385,-5210113,-5540097,-5935873,-6331649,-6793217,-7255041,-7782657,-8310529,-8904193,-9563649,-10223361,-1712641,-1778689,-1844737,-1976321,-2107905,-2239745,-2371585,-2503425,-2635265,-2767361,-2964993,-3162625,-3360257,-3558145,-3821569,-4085249,-4348929,-4612609,-4942081,-5271553,-5666817,-6062081,-6457601,-6918913,-7380225,-7907329,-8434689,-9027841,-9686785,-10345985,-11070977,-11861761,-1843713,-1975297,-2106881,-2238465,-2370049,-2501889,-2633729,-2765569,-2962945,-3160577,-3358209,-3555841,-3753473,-4016897,-4280321,-4544001,-4873217,-5202433,-5531905,-5926913,-6322177,-6782977,-7244033,-7770881,-8297729,-8890369,-9548801,-10207489,-10931969,-11722241,-12578305,-13500161,-1974785,-2106369,-2237953,-2369537,-2501121,-2632961,-2830337,-3027713,-3225089,-3422721,-3620353,-3883521,-4146689,-4410113,-4673537,-5002753,-5331969,-5726721,-6121729,-6582273,-7043073,-7503873,-8030465,-8622849,-9215233,-9873409,-10597377,-11387137,-12242689,-13164033,-14085633,-15138561,-2236929,-2368513,-2500097,-2631681,-2763265,-2960641,-3158017,-3355393,-3552769,-3815937,-4079105,-4342273,-4605441,-4934401,-5263361,-5658113,-6052865,-6447617,-6908161,-7368705,-7895041,-8421377,-9013505,-9671425,-10329345,-11053057,-11842561,-12697857,-13618945,-14605825,-15658497,-16776961] \ No newline at end of file
diff --git a/release/scripts/flt_dofedit.py b/release/scripts/flt_dofedit.py
deleted file mode 100644
index 36e8e4d2501..00000000000
--- a/release/scripts/flt_dofedit.py
+++ /dev/null
@@ -1,835 +0,0 @@
-#!BPY
-
-"""
-Name: 'FLT DOF Editor'
-Blender: 240
-Group: 'Misc'
-Tooltip: 'Degree of Freedom editor for FLT nodes'
-"""
-
-__author__ = "Geoffrey Bantle"
-__version__ = "1.0 11/21/07"
-__email__ = ('scripts', 'Author, ')
-__url__ = ('blender', 'blenderartists.org')
-
-__bpydoc__ ="""\
-This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/FLTools
-"""
-
-# --------------------------------------------------------------------------
-# flt_palettemanager.py version 0.1 2005/04/08
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import Blender.Draw as Draw
-from Blender.BGL import *
-import Blender
-import flt_properties
-reload(flt_properties)
-from flt_properties import *
-
-#event codes
-evcode = {
- "DOF_MAKE" : 100,
- "DOF_UPDATE" : 138,
- "DOF_DELETE" : 101,
- "DOF_TRANSX" : 102,
- "DOF_TRANSY" : 103,
- "DOF_TRANSZ" : 104,
- "DOF_ROTX" : 105,
- "DOF_ROTY" : 106,
- "DOF_ROTZ" : 107,
- "DOF_SCALEX" : 108,
- "DOF_SCALEY" : 109,
- "DOF_SCALEZ" : 110,
- "DOF_MIN_TRANSX" : 111,
- "DOF_MIN_TRANSY" : 112,
- "DOF_MIN_TRANSZ" : 113,
- "DOF_MIN_ROTX" : 114,
- "DOF_MIN_ROTY" : 115,
- "DOF_MIN_ROTZ" : 116,
- "DOF_MIN_SCALEX" : 117,
- "DOF_MIN_SCALEY" : 118,
- "DOF_MIN_SCALEZ" : 119,
- "DOF_MAX_TRANSX" : 120,
- "DOF_MAX_TRANSY" : 121,
- "DOF_MAX_TRANSZ" : 122,
- "DOF_MAX_ROTX" : 123,
- "DOF_MAX_ROTY" : 124,
- "DOF_MAX_ROTZ" : 125,
- "DOF_MAX_SCALEX" : 126,
- "DOF_MAX_SCALEY" : 127,
- "DOF_MAX_SCALEZ" : 128,
- "DOF_STEP_TRANSX" : 129,
- "DOF_STEP_TRANSY" : 130,
- "DOF_STEP_TRANSZ" : 131,
- "DOF_STEP_ROTX" : 132,
- "DOF_STEP_ROTY" : 133,
- "DOF_STEP_ROTZ" : 134,
- "DOF_STEP_SCALEX" : 135,
- "DOF_STEP_SCALEY" : 136,
- "DOF_STEP_SCALEZ" : 137
-}
-
-#system
-DOF_MAKE = None
-DOF_UPDATE = None
-DOF_DELETE = None
-
-#toggle buttons
-DOF_TRANSX = None
-DOF_TRANSY = None
-DOF_TRANSZ = None
-DOF_ROTX = None
-DOF_ROTY = None
-DOF_ROTZ = None
-DOF_SCALEX = None
-DOF_SCALEY = None
-DOF_SCALEZ = None
-
-#Minimums
-DOF_MIN_TRANSX = None
-DOF_MIN_TRANSY = None
-DOF_MIN_TRANSZ = None
-DOF_MIN_ROTX = None
-DOF_MIN_ROTY = None
-DOF_MIN_ROTZ = None
-DOF_MIN_SCALEX = None
-DOF_MIN_SCALEY = None
-DOF_MIN_SCALEZ = None
-
-#maximums
-DOF_MAX_TRANSX = None
-DOF_MAX_TRANSY = None
-DOF_MAX_TRANSZ = None
-DOF_MAX_ROTX = None
-DOF_MAX_ROTY = None
-DOF_MAX_ROTZ = None
-DOF_MAX_SCALEX = None
-DOF_MAX_SCALEY = None
-DOF_MAX_SCALEZ = None
-
-#step
-DOF_STEP_TRANSX = None
-DOF_STEP_TRANSY = None
-DOF_STEP_TRANSZ = None
-DOF_STEP_ROTX = None
-DOF_STEP_ROTY = None
-DOF_STEP_ROTZ = None
-DOF_STEP_SCALEX = None
-DOF_STEP_SCALEY = None
-DOF_STEP_SCALEZ = None
-
-#labels
-DOF_ROTSTRING = None
-DOF_TRANSTRING = None
-DOF_SCALESTRING = None
-DOF_EDITLABEL = None
-
-#make ID props easier/morereadable
-zmin = '14d!ZMIN'
-zmax = '15d!ZMAX'
-zcur = '16d!ZCUR'
-zstep = '17d!ZSTEP'
-ymin = '18d!YMIN'
-ymax = '19d!YMAX'
-ycur = '20d!YCUR'
-ystep = '21d!YSTEP'
-xmin = '22d!XMIN'
-xmax = '23d!XMAX'
-xcur = '24d!XCUR'
-xstep = '25d!XSTEP'
-pitchmin = '26d!PITCH-MIN'
-pitchmax = '27d!PITCH-MAX'
-pitchcur = '28d!PITCH-CUR'
-pitchstep = '29d!PITCH-STEP'
-rollmin = '30d!ROLL-MIN'
-rollmax = '31d!ROLL-MAX'
-rollcur = '32d!ROLL-CUR'
-rollstep = '33d!ROLL-STEP'
-yawmin = '34d!YAW-MIN'
-yawmax = '35d!YAW-MAX'
-yawcur = '36d!YAW-CUR'
-yawstep = '37d!YAW-STEP'
-zscalemin = '38d!ZSIZE-MIN'
-zscalemax = '39d!ZSIZE-MAX'
-zscalecur = '40d!ZSIZE-CUR'
-zscalestep = '41d!ZSIZE-STEP'
-yscalemin = '42d!YSIZE-MIN'
-yscalemax = '43d!YSIZE-MAX'
-yscalecur = '44d!YSIZE-CUR'
-yscalestep = '45d!YSIZE-STEP'
-xscalemin = '46d!XSIZE-MIN'
-xscalemax = '47d!XSIZE-MAX'
-xscalecur = '48d!XSIZE-CUR'
-xscalestep = '49d!XSIZE-STEP'
-
-
-
-def update_state():
- state = dict()
- state["activeScene"] = Blender.Scene.GetCurrent()
- state["activeObject"] = state["activeScene"].objects.active
- if state["activeObject"] and not state["activeObject"].sel:
- state["activeObject"] = None
- state["activeMesh"] = None
- if state["activeObject"] and state["activeObject"].type == 'Mesh':
- state["activeMesh"] = state["activeObject"].getData(mesh=True)
-
-
- state["activeFace"] = None
- if state["activeMesh"]:
- if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
- state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
-
-
- #update editmode
- state["editmode"] = Blender.Window.EditMode()
-
- return state
-
-def idprops_append(object, typecode, props):
- object.properties["FLT"] = dict()
- object.properties["FLT"]['type'] = typecode
- for prop in props:
- object.properties["FLT"][prop] = props[prop]
- object.properties["FLT"]['3t8!id'] = object.name
-
-def idprops_kill():
- state = update_state()
- if state["activeObject"] and state["activeObject"].properties.has_key('FLT'):
- state["activeObject"].properties.pop('FLT')
-
-def idprops_copy(source):
- state = update_state()
- if source.properties.has_key('FLT'):
- for object in state["activeScene"].objects:
- if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
- idprops_kill(object)
- object.properties['FLT'] = dict()
- for key in source.properties['FLT']:
- object.properties['FLT'][key] = source.properties['FLT'][key]
-
-def select_by_typecode(typecode):
- state = update_state()
-
- for object in state["activeScene"].objects:
- if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
- object.select(1)
-
-def DOF_get_frame():
- state = update_state()
-
- if not state["activeObject"] and not id_props_type(state["activeObject"], 14):
- return
-
- #Warning! assumes 1 BU == 10 meters.
- #do origin
- state["activeObject"].properties['FLT']['5d!ORIGX'] = state["activeObject"].getLocation('worldspace')[0]*10.0
- state["activeObject"].properties['FLT']['6d!ORIGY'] = state["activeObject"].getLocation('worldspace')[1]*10.0
- state["activeObject"].properties['FLT']['7d!ORIGZ'] = state["activeObject"].getLocation('worldspace')[2]*10.0
- #do X axis
- x = Blender.Mathutils.Vector(1.0,0.0,0.0)
- x = x * state["activeObject"].getMatrix('worldspace')
- x = x * 10.0
- state["activeObject"].properties['FLT']['8d!XAXIS-X'] = x[0]
- state["activeObject"].properties['FLT']['9d!XAXIS-Y'] = x[1]
- state["activeObject"].properties['FLT']['10d!XAXIS-Z'] = x[2]
- #do X/Y plane
- x = Blender.Mathutils.Vector(0.0,1.0,0.0)
- x.normalize()
- x = x * state["activeObject"].getMatrix('worldspace')
- x = x * 10.0
- state["activeObject"].properties['FLT']['11d!XYPLANE-X'] = x[0]
- state["activeObject"].properties['FLT']['12d!XYPLANE-Y'] = x[1]
- state["activeObject"].properties['FLT']['13d!XZPLANE-Z'] = x[2]
-
-def idprops_type(object, typecode):
- if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode:
- return True
- return False
-
-#ui type code
-def get_prop(typecode, prop):
-
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], typecode):
- props = state["activeObject"].properties['FLT']
- else:
- props = flt_properties.FLTDOF
-
- return props[prop]
-
-def set_prop(typecode, prop, value):
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"],typecode):
- state["activeObject"].properties['FLT'][prop] = value
-
-lockxtrans = (1 << 31)
-lockytrans = (1 << 30)
-lockztrans = (1 << 29)
-lockxrot = (1 << 28)
-lockyrot = (1 << 27)
-lockzrot = (1 << 26)
-lockxscale = (1 << 25)
-lockyscale = (1 << 24)
-lockzscale = (1 << 23)
-
-def get_lockmask(mask):
- state = update_state()
- if state["activeObject"]:
- flag = get_prop(14,'50I!FLAG')
- if flag & mask:
- return True
- return False
-
-def set_lockmask(mask):
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], 14):
- oldvalue = state["activeObject"].properties['FLT']['50I!FLAG']
- oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
- oldvalue |= mask
- state["activeObject"].properties['FLT']['50I!FLAG'] = struct.unpack('>i', struct.pack(">I", oldvalue))[0]
-
-def clear_lockmask(mask):
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], 14):
- oldvalue = state["activeObject"].properties['FLT']['50I!FLAG']
- oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
- oldvalue &= ~mask
- state["activeObject"].properties['FLT']['50I!FLAG'] = struct.unpack('>i',struct.pack('>I',oldvalue))[0]
-
-
-def create_dof():
- state = update_state()
- actobj = state["activeObject"]
- if actobj and not idprops_type(actobj, 14):
- idprops_kill()
- idprops_append(actobj,14, flt_properties.FLTDOF)
- DOF_get_frame()
-
-
-def event(evt,val):
- if evt == Draw.ESCKEY:
- Draw.Exit()
-
-def but_event(evt):
- global DOF_MAKE
- global DOF_UPDATE
- global DOF_DELETE
-
- global DOF_TRANSX
- global DOF_TRANSY
- global DOF_TRANSZ
- global DOF_ROTX
- global DOF_ROTY
- global DOF_ROTZ
- global DOF_SCALEX
- global DOF_SCALEY
- global DOF_SCALEZ
-
- global DOF_MIN_TRANSX
- global DOF_MIN_TRANSY
- global DOF_MIN_TRANSZ
- global DOF_MIN_ROTX
- global DOF_MIN_ROTY
- global DOF_MIN_ROTZ
- global DOF_MIN_SCALEX
- global DOF_MIN_SCALEY
- global DOF_MIN_SCALEZ
-
- global DOF_MAX_TRANSX
- global DOF_MAX_TRANSY
- global DOF_MAX_TRANSZ
- global DOF_MAX_ROTX
- global DOF_MAX_ROTY
- global DOF_MAX_ROTZ
- global DOF_MAX_SCALEX
- global DOF_MAX_SCALEY
- global DOF_MAX_SCALEZ
-
- global DOF_STEP_TRANSX
- global DOF_STEP_TRANSY
- global DOF_STEP_TRANSZ
- global DOF_STEP_ROTX
- global DOF_STEP_ROTY
- global DOF_STEP_ROTZ
- global DOF_STEP_SCALEX
- global DOF_STEP_SCALEY
- global DOF_STEP_SCALEZ
-
- #labels
- global DOF_ROTSTRING
- global DOF_TRANSTRING
- global DOF_SCALESTRING
-
-
- #masks
- global lockxtrans
- global lockytrans
- global lockztrans
- global lockxrot
- global lockyrot
- global lockzrot
- global lockxscale
- global lockyscale
- global lockzscale
-
- global zmin
- global zmax
- global zcur
- global zstep
- global ymin
- global ymax
- global ycur
- global ystep
- global xmin
- global xmax
- global xcur
- global xstep
- global pitchmin
- global pitchmax
- global pitchcur
- global pitchstep
- global rollmin
- global rollmax
- global rollcur
- global rollstep
- global yawmin
- global yawmax
- global yawcur
- global yawstep
- global zscalemin
- global zscalemax
- global zscalecur
- global zscalestep
- global yscalemin
- global yscalemax
- global yscalecur
- global yscalestep
- global xscalemin
- global xscalemax
- global xscalecur
- global xscalestep
-
-
-
- #do "system" events
- if evt == evcode["DOF_MAKE"]:
- create_dof()
-
- if evt == evcode["DOF_UPDATE"]:
- DOF_get_frame()
-
- if evt == evcode["DOF_DELETE"]:
- idprops_kill()
- #do translation lock events
- if evt == evcode["DOF_TRANSX"]:
- if DOF_TRANSX.val == True:
- set_lockmask(lockxtrans)
- else:
- clear_lockmask(lockxtrans)
-
- if evt == evcode["DOF_TRANSY"]:
- if DOF_TRANSY.val == True:
- set_lockmask(lockytrans)
- else:
- clear_lockmask(lockytrans)
-
- if evt == evcode["DOF_TRANSZ"]:
- if DOF_TRANSZ.val == True:
- set_lockmask(lockztrans)
- else:
- clear_lockmask(lockztrans)
-
-
- #do rotation lock events
- if evt == evcode["DOF_ROTX"]:
- if DOF_ROTX.val == True:
- set_lockmask(lockxrot)
- else:
- clear_lockmask(lockxrot)
-
- if evt == evcode["DOF_ROTY"]:
- if DOF_ROTY.val == True:
- set_lockmask(lockyrot)
- else:
- clear_lockmask(lockyrot)
-
- if evt == evcode["DOF_ROTZ"]:
- if DOF_ROTZ.val == True:
- set_lockmask(lockzrot)
- else:
- clear_lockmask(lockzrot)
-
- #do scale lock events
- if evt == evcode["DOF_SCALEX"]:
- if DOF_SCALEX.val == True:
- set_lockmask(lockxscale)
- else:
- clear_lockmask(lockxscale)
-
- if evt == evcode["DOF_SCALEY"]:
- if DOF_SCALEY.val == True:
- set_lockmask(lockyscale)
- else:
- clear_lockmask(lockyscale)
-
- if evt == evcode["DOF_SCALEZ"]:
- if DOF_SCALEZ.val == True:
- set_lockmask(lockzscale)
- else:
- clear_lockmask(lockzscale)
-
-
- #do translation buttons
- if evt == evcode["DOF_MIN_TRANSX"]:
- set_prop(14, xmin, DOF_MIN_TRANSX.val)
- if evt == evcode["DOF_MAX_TRANSX"]:
- set_prop(14,xmax, DOF_MAX_TRANSX.val)
- if evt == evcode["DOF_STEP_TRANSX"]:
- set_prop(14,xstep, DOF_STEP_TRANSX.val)
-
- if evt == evcode["DOF_MIN_TRANSY"]:
- set_prop(14, ymin, DOF_MIN_TRANSY.val)
- if evt == evcode["DOF_MAX_TRANSY"]:
- set_prop(14,ymax, DOF_MAX_TRANSY.val)
- if evt == evcode["DOF_STEP_TRANSY"]:
- set_prop(14,ystep, DOF_STEP_TRANSY.val)
-
- if evt == evcode["DOF_MIN_TRANSZ"]:
- set_prop(14, zmin, DOF_MIN_TRANSZ.val)
- if evt == evcode["DOF_MAX_TRANSZ"]:
- set_prop(14, zmax, DOF_MAX_TRANSZ.val)
- if evt == evcode["DOF_STEP_TRANSZ"]:
- set_prop(14, zstep, DOF_STEP_TRANSZ.val)
-
- #do rotation buttons
- if evt == evcode["DOF_MIN_ROTX"]:
- set_prop(14, pitchmin, DOF_MIN_ROTX.val)
- if evt == evcode["DOF_MAX_ROTX"]:
- set_prop(14, pitchmax, DOF_MAX_ROTX.val)
- if evt == evcode["DOF_STEP_ROTX"]:
- set_prop(14, pitchstep, DOF_STEP_ROTX.val)
-
- if evt == evcode["DOF_MIN_ROTY"]:
- set_prop(14, rollmin, DOF_MIN_ROTY.val)
- if evt == evcode["DOF_MAX_ROTY"]:
- set_prop(14, rollmax, DOF_MAX_ROTY.val)
- if evt == evcode["DOF_STEP_ROTY"]:
- set_prop(14, rollstep, DOF_STEP_ROTY.val)
-
- if evt == evcode["DOF_MIN_ROTZ"]:
- set_prop(14, yawmin, DOF_MIN_ROTZ.val)
- if evt == evcode["DOF_MAX_ROTZ"]:
- set_prop(14, yawmax, DOF_MAX_ROTZ.val)
- if evt == evcode["DOF_STEP_ROTZ"]:
- set_prop(14, yawstep, DOF_STEP_ROTZ.val)
-
- #do scale buttons
- if evt == evcode["DOF_MIN_SCALEX"]:
- set_prop(14, xscalemin, DOF_MIN_SCALEX.val)
- if evt == evcode["DOF_MAX_SCALEX"]:
- set_prop(14, xscalemax, DOF_MAX_SCALEX.val)
- if evt == evcode["DOF_STEP_SCALEX"]:
- set_prop(14, xscalestep, DOF_STEP_SCALEX.val)
-
- if evt == evcode["DOF_MIN_SCALEY"]:
- set_prop(14, yscalemin, DOF_MIN_SCALEY.val)
- if evt == evcode["DOF_MAX_SCALEY"]:
- set_prop(14, yscalemax, DOF_MAX_SCALEY.val)
- if evt == evcode["DOF_STEP_SCALEY"]:
- set_prop(14, yscalestep, DOF_STEP_SCALEY.val)
-
- if evt == evcode["DOF_MIN_SCALEZ"]:
- set_prop(14, zscalemin, DOF_MIN_SCALEZ.val)
- if evt == evcode["DOF_MAX_SCALEZ"]:
- set_prop(14, zscalemax, DOF_MAX_SCALEZ.val)
- if evt == evcode["DOF_STEP_SCALEZ"]:
- set_prop(14, zscalestep, DOF_STEP_SCALEZ.val)
-
-
- Draw.Redraw(1)
- Blender.Window.RedrawAll()
-
-def draw_propsheet(x,y):
- #UI buttons
- global DOF_MAKE
- global DOF_UPDATE
- global DOF_DELETE
-
- global DOF_TRANSX
- global DOF_TRANSY
- global DOF_TRANSZ
- global DOF_ROTX
- global DOF_ROTY
- global DOF_ROTZ
- global DOF_SCALEX
- global DOF_SCALEY
- global DOF_SCALEZ
-
- global DOF_MIN_TRANSX
- global DOF_MIN_TRANSY
- global DOF_MIN_TRANSZ
- global DOF_MIN_ROTX
- global DOF_MIN_ROTY
- global DOF_MIN_ROTZ
- global DOF_MIN_SCALEX
- global DOF_MIN_SCALEY
- global DOF_MIN_SCALEZ
-
- global DOF_MAX_TRANSX
- global DOF_MAX_TRANSY
- global DOF_MAX_TRANSZ
- global DOF_MAX_ROTX
- global DOF_MAX_ROTY
- global DOF_MAX_ROTZ
- global DOF_MAX_SCALEX
- global DOF_MAX_SCALEY
- global DOF_MAX_SCALEZ
-
- global DOF_STEP_TRANSX
- global DOF_STEP_TRANSY
- global DOF_STEP_TRANSZ
- global DOF_STEP_ROTX
- global DOF_STEP_ROTY
- global DOF_STEP_ROTZ
- global DOF_STEP_SCALEX
- global DOF_STEP_SCALEY
- global DOF_STEP_SCALEZ
-
- #labels
- global DOF_ROTSTRING
- global DOF_TRANSTRING
- global DOF_SCALESTRING
- global DOF_EDITLABEL
-
- #masks
- global lockxtrans
- global lockytrans
- global lockztrans
- global lockxrot
- global lockyrot
- global lockzrot
- global lockxscale
- global lockyscale
- global lockzscale
-
- global zmin
- global zmax
- global zcur
- global zstep
- global ymin
- global ymax
- global ycur
- global ystep
- global xmin
- global xmax
- global xcur
- global xstep
- global pitchmin
- global pitchmax
- global pitchcur
- global pitchstep
- global rollmin
- global rollmax
- global rollcur
- global rollstep
- global yawmin
- global yawmax
- global yawcur
- global yawstep
- global zscalemin
- global zscalemax
- global zscalecur
- global zscalestep
- global yscalemin
- global yscalemax
- global yscalecur
- global yscalestep
- global xscalemin
- global xscalemax
- global xscalecur
- global xscalestep
-
-
- global evcode
-
- state = update_state()
-
- row_height = 20
- toggle_width = 50
- input_width = 100
- pad = 10
- origx = x
- origy = (row_height * 15) + (pad * 15)
-
-
- #editor label
- x = origx
- y = origy
- #y = y - (row_height + pad)
- DOF_EDITLABEL = Blender.Draw.Label("FLT Degree of Freedom Editor", x, y, 200, row_height)
-
-
- #draw Translation limits
- x = origx
- y = y- (row_height + pad)
- DOF_TRANSTRING = Blender.Draw.Label("Translation Limits", x, y, input_width, row_height)
-
-
- #X limits
- x = origx
- y = y- (row_height + pad)
- DOF_TRANSX = Blender.Draw.Toggle("LimX", evcode["DOF_TRANSX"], x, y, toggle_width, row_height, get_lockmask(lockxtrans), "")
- x = x + (toggle_width + pad)
- DOF_MIN_TRANSX = Blender.Draw.Number("MinX", evcode["DOF_MIN_TRANSX"], x, y, input_width, row_height,get_prop(14,xmin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_TRANSX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_TRANSX"], x, y, input_width, row_height,get_prop(14,xmax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_TRANSX = Blender.Draw.Number("StepX", evcode["DOF_STEP_TRANSX"], x, y, input_width, row_height,get_prop(14,xstep), -1000000.0, 1000000.0, "")
-
- #Y limits
- x = origx
- y = y- (row_height + pad)
- DOF_TRANSY = Blender.Draw.Toggle("LimY", evcode["DOF_TRANSY"], x, y, toggle_width, row_height, get_lockmask(lockytrans), "")
- x = x + (toggle_width + pad)
- DOF_MIN_TRANSY = Blender.Draw.Number("MinY", evcode["DOF_MIN_TRANSY"], x, y, input_width, row_height, get_prop(14,ymin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_TRANSY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_TRANSY"], x, y, input_width, row_height, get_prop(14,ymax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_TRANSY = Blender.Draw.Number("StepY", evcode["DOF_STEP_TRANSY"], x, y, input_width, row_height, get_prop(14,ystep), -1000000.0, 1000000.0, "")
-
- #Z limits
- x = origx
- y = y- (row_height + pad)
- DOF_TRANSZ = Blender.Draw.Toggle("LimZ", evcode["DOF_TRANSZ"], x, y, toggle_width, row_height, get_lockmask(lockztrans), "")
- x = x + (toggle_width + pad)
- DOF_MIN_TRANSZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_TRANSZ"], x, y, input_width, row_height, get_prop(14,zmin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_TRANSZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_TRANSZ"], x, y, input_width, row_height, get_prop(14,zmax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_TRANSZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_TRANSZ"], x, y, input_width, row_height, get_prop(14,zstep), -1000000.0, 1000000.0, "")
-
- #draw Rotation limits
- x = origx
- y = y- (row_height + pad)
- DOF_ROTSTRING = Blender.Draw.Label("Rotation Limits", x, y, input_width, row_height)
-
- #draw Rotation limits
- #X limits
- x = origx
- y = y- (row_height + pad)
- DOF_ROTX = Blender.Draw.Toggle("LimX", evcode["DOF_ROTX"], x, y, toggle_width, row_height, get_lockmask(lockxrot), "")
- x = x + (toggle_width + pad)
- DOF_MIN_ROTX = Blender.Draw.Number("MinX", evcode["DOF_MIN_ROTX"], x, y, input_width, row_height, get_prop(14,pitchmin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_ROTX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_ROTX"], x, y, input_width, row_height, get_prop(14,pitchmax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_ROTX = Blender.Draw.Number("StepX", evcode["DOF_STEP_ROTX"], x, y, input_width, row_height, get_prop(14,pitchstep), -1000000.0, 1000000.0, "")
-
- #Y limits
- x = origx
- y = y- (row_height + pad)
- DOF_ROTY = Blender.Draw.Toggle("LimY", evcode["DOF_ROTY"], x, y, toggle_width, row_height, get_lockmask(lockyrot), "")
- x = x + (toggle_width + pad)
- DOF_MIN_ROTY = Blender.Draw.Number("MinY", evcode["DOF_MIN_ROTY"], x, y, input_width, row_height, get_prop(14,rollmin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_ROTY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_ROTY"], x, y, input_width, row_height, get_prop(14,rollmax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_ROTY = Blender.Draw.Number("StepY", evcode["DOF_STEP_ROTY"], x, y, input_width, row_height, get_prop(14,rollstep), -1000000.0, 1000000.0, "")
-
- #Z limits
- x = origx
- y = y- (row_height + pad)
- DOF_ROTZ = Blender.Draw.Toggle("LimZ", evcode["DOF_ROTZ"], x, y, toggle_width, row_height, get_lockmask(lockzrot), "")
- x = x + (toggle_width + pad)
- DOF_MIN_ROTZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_ROTZ"], x, y, input_width, row_height, get_prop(14, yawmin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_ROTZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_ROTZ"], x, y, input_width, row_height, get_prop(14, yawmax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_ROTZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_ROTZ"], x, y, input_width, row_height, get_prop(14, yawstep), -1000000.0, 1000000.0, "")
-
-
- #draw Scale limits
- x = origx
- y = y- (row_height + pad)
- DOF_SCALESTRING = Blender.Draw.Label("Scale Limits", x, y, input_width, row_height)
-
- #draw Scale limits
- #X limits
- x = origx
- y = y- (row_height + pad)
- DOF_SCALEX = Blender.Draw.Toggle("LimX", evcode["DOF_SCALEX"], x, y, toggle_width, row_height, get_lockmask(lockxscale), "")
- x = x + (toggle_width + pad)
- DOF_MIN_SCALEX = Blender.Draw.Number("MinX", evcode["DOF_MIN_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalemin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_SCALEX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalemax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_SCALEX = Blender.Draw.Number("StepX", evcode["DOF_STEP_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalestep), -1000000.0, 1000000.0, "")
-
- #Y limits
- x = origx
- y = y- (row_height + pad)
- DOF_SCALEY = Blender.Draw.Toggle("LimY", evcode["DOF_SCALEY"], x, y, toggle_width, row_height, get_lockmask(lockyscale), "")
- x = x + (toggle_width + pad)
- DOF_MIN_SCALEY = Blender.Draw.Number("MinY", evcode["DOF_MIN_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalemin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_SCALEY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalemax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_SCALEY = Blender.Draw.Number("StepY", evcode["DOF_STEP_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalestep), -1000000.0, 1000000.0, "")
-
- #Z limits
- x = origx
- y = y- (row_height + pad)
- DOF_SCALEZ = Blender.Draw.Toggle("LimZ", evcode["DOF_SCALEZ"], x, y, toggle_width, row_height, get_lockmask(lockzscale), "")
- x = x + (toggle_width + pad)
- DOF_MIN_SCALEZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalemin), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_MAX_SCALEZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalemax), -1000000.0, 1000000.0, "")
- x = x + (input_width + pad)
- DOF_STEP_SCALEZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalestep), -1000000.0, 1000000.0, "")
-
- #System
- x = origx
- y = y - (row_height + (pad)*3)
- DOF_MAKE = Blender.Draw.PushButton("Make DOF", evcode["DOF_MAKE"], x, y, input_width, row_height, "Make a Dof Node out of Active Object")
- x = x + (input_width + pad)
- DOF_UPDATE = Blender.Draw.PushButton("Grab Loc/Rot", evcode["DOF_UPDATE"], x, y, input_width, row_height, "Update the Dof Node position/orientation")
- x = x + (input_width + pad)
- DOF_DELETE = Blender.Draw.PushButton("Delete DOF", evcode["DOF_DELETE"], x, y, input_width, row_height, "Delete the Dof Node properties")
-
-
-
-
-def gui():
- #draw the propsheet/toolbox.
- psheety = 800
- #psheetx = psheety + 10
- draw_propsheet(20,psheety)
-
-Draw.Register(gui,event,but_event)
- \ No newline at end of file
diff --git a/release/scripts/flt_export.py b/release/scripts/flt_export.py
deleted file mode 100644
index c099c8e62d1..00000000000
--- a/release/scripts/flt_export.py
+++ /dev/null
@@ -1,1697 +0,0 @@
-#!BPY
-""" Registration info for Blender menus:
-Name: 'OpenFlight (.flt)...'
-Blender: 245
-Group: 'Export'
-Tip: 'Export to OpenFlight v16.0 (.flt)'
-"""
-
-__author__ = "Greg MacDonald, Geoffrey Bantle"
-__version__ = "2.0 11/21/07"
-__url__ = ("blender", "blenderartists.org", "Author's homepage, http://sourceforge.net/projects/blight/")
-__bpydoc__ = """\
-This script exports v16.0 OpenFlight files. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/Export/openflight_flt
-"""
-
-# flt_export.py is an OpenFlight exporter for blender.
-#
-# Copyright (C) 2005 Greg MacDonald, 2007 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.
-
-import Blender
-from Blender import Modifier
-import os.path
-import flt_properties
-import flt_defaultp as defaultp
-from flt_filewalker import FltOut
-from flt_filewalker import FileFinder
-from flt_properties import *
-import shutil
-import trace
-import sys
-
-FF = FileFinder()
-records = process_recordDefs()
-
-class ExporterOptions:
-
- def read_state(self):
- reg = Blender.Registry.GetKey('flt_export',1)
- if reg:
- for key in self.state:
- if reg.has_key(key):
- self.state[key] = reg[key]
-
- def write_state(self):
- d = dict()
- for key in self.state:
- d[key] = self.state[key]
- Blender.Registry.SetKey('flt_export', d, 1)
- def __init__(self):
- self.verbose = 1
- self.tolerance = 0.001
- self.writevcol = True
-
- self.state = {'export_shading' : 0,
- 'shading_default' : 45,
- 'basepath' : os.path.dirname(Blender.Get('filename')),
- 'scale': 1.0,
- 'doxrefs' : 1,
- 'attrib' : 0,
- 'copytex' : 0,
- 'transform' : 0,
- 'xapp' : 1}
-
- #default externals path
- if(os.path.exists(os.path.join(self.state['basepath'],'externals'))):
- self.state['externalspath'] = os.path.join(self.state['basepath'],'externals')
- else:
- self.state['externalspath'] = self.state['basepath']
-
- if(os.path.exists(os.path.join(self.state['basepath'],'textures'))):
- self.state['texturespath'] = os.path.join(self.state['basepath'],'textures')
- else:
- self.state['texturespath'] = self.state['basepath']
-
- self.state['xappath'] = ''
- self.read_state() #read from registry
-
-
-options = ExporterOptions()
-tex_files = dict() #a list of (possibly) modified texture path names
-
-tex_layers = ['Layer0', 'Layer1', 'Layer2', 'Layer3', 'Layer4', 'Layer5', 'Layer6', 'Layer7']
-mask = 2147483648
-mtexmasks = []
-for i in xrange(7):
- mtexmasks.append(mask)
- mask = mask / 2
-
-FLOAT_TOLERANCE = options.tolerance
-
-#need to move all this stuff to flt_properties.py.
-identity_matrix = [[1.0, 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]]
-alltypes = [2,4,14,11,73,63,111]
-childtypes = {
- 2 : [111,2,73,4,14,63],
- 4 : [111],
- 73 : [111,2,73,4,14,63],
- 63 : [],
- 14 : [111,2,73,4,14,63],
- 111 : []
-}
-recordlen = {
- 2: 44,
- 4: 28,
- 73: 80,
- 63: 216,
- 14: 384,
- 111: 156
-}
-
-def is_identity(m):
- for i in xrange(4):
- for j in xrange(4):
- if abs(m[i][j] - identity_matrix[i][j]) > FLOAT_TOLERANCE:
- return False
- return True
-
-class MaterialDesc:
- def __init__(self):
- self.name = 'Blender'
-
- # Colors, List of 3 floats.
- self.diffuse = [1.0, 1.0, 1.0]
- self.specular = [1.0, 1.0, 1.0]
-
- # Scalars
- self.ambient = 0.1 # [0.0, 1.0]
- self.emissive = 0.0 # [0.0, 1.0]
- self.shininess = 32.0 # Range is [0.0, 128.0]
- self.alpha = 1.0 # Range is [0.0, 1.0]
-
-class VertexDesc:
- def __init__(self, co=None, no=None, uv=None, fltindex=None,cindex=None):
- if co: self.x, self.y, self.z = tuple(co)
- else: self.x = self.y = self.z = 0.0
- if no: self.nx, self.ny, self.nz = tuple(no)
- else: self.nx = self.ny = self.nz = 0.0
- if uv: self.u, self.v = tuple(uv)
- else: self.u = self.v = 0.0
- if cindex: self.cindex = cindex
- else: self.cindex = 127
- self.fltindex = fltindex
- self.accum = 0
-
-class shadowVert:
- def __init__(self,bvert,object,world,normal):
- global options
-
- self.co = Blender.Mathutils.Vector(bvert.co[0],bvert.co[1],bvert.co[2])
- #if world:
- # vec = self.co
- # vec = Blender.Mathutils.Vector(vec[0] * options.scale, vec[1] * options.scale, vec[2] * options.scale) #scale
- # self.co = Blender.Mathutils.TranslationMatrix(vec) * (self.co * object.getMatrix('worldspace'))
-
- if normal:
- #if world:
- # self.no = Blender.Mathutils.Vector(normal * object.getMatrix('worldspace')).normalize()
- #else:
- self.no = Blender.Mathutils.Vector(normal[0],normal[1],normal[2])
-
- else:
- #if world:
- #self.no = Blender.Mathutils.Vector(bvert.no * object.getMatrix('worldspace')).normalize()
- #else:
- self.no = Blender.Mathutils.Vector(bvert.no[0],bvert.no[1],bvert.no[2])
-
- #do scaling factor
- #if options.scale != 1.0:
- #self.co[0] = self.co[0] * options.scale
- #self.co[1] = self.co[1] * options.scale
- #self.co[2] = self.co[2] * options.scale
-
- self.index = bvert.index
-
-class GlobalResourceRepository:
- def new_face_name(self):
- self.face_name += 1
- return 'f%i' % (self.face_name-1)
-
- def vertex_count(self):
- return len(self.vertex_lst)
-
- def request_vertex_desc(self, i):
- return self.vertex_lst[i]
-
- def request_vertex_index(self, object, mesh, face, vfindex, uvok,cindex):
-
- flatShadeNorm = None
- vno = None
-
-
- if type(face) is list:
- vertex = face[vfindex]
- elif str(type(face)) == "<type " + "'Blender MVert'>":
- vertex = face
- vno = Blender.Mathutils.Vector(0.0,0.0,1.0)
- elif str(type(face)) == "<type " + "'Blender MEdge'>":
- if vfindex == 1:
- vertex = face.v1
- elif vfindex == 2:
- vertex = face.v2
- elif str(type(face)) == "<type " + "'Blender MFace'>":
- if not face.smooth:
- flatShadeNorm = face.no
- vertex = face.v[vfindex]
- else:
- return None
-
- if not self.namehash.has_key(object.name):
- self.namehash[object.name] = dict()
- indexhash = self.namehash[object.name]
-
- #export in global space? THIS HAS BEEN MADE REDUNDANT... REMOVE ME
- if not options.state['transform']:
- vertex = shadowVert(vertex,object,True,flatShadeNorm)
- else:
- vertex = shadowVert(vertex,object,False,flatShadeNorm)
-
- if vno:
- vertex.no = vno
-
-
- #Check to see if this vertex has been visited before. If not, add
- if not indexhash.has_key(vertex.index):
- if uvok:
- newvdesc = VertexDesc(vertex.co, vertex.no, face.uv[vfindex], self.nextvindex,cindex=cindex)
- else:
- newvdesc = VertexDesc(co=vertex.co, no=vertex.no,fltindex=self.nextvindex,cindex=cindex)
-
- indexhash[vertex.index] = [newvdesc]
- self.vertex_lst.append(newvdesc)
- self.nextvindex = self.nextvindex + 1
- return newvdesc.fltindex
-
- else:
- desclist = indexhash[vertex.index]
- if uvok:
- faceu = face.uv[vfindex][0]
- facev = face.uv[vfindex][1]
- else:
- faceu = 0.0
- facev = 0.0
- for vdesc in desclist:
- if\
- abs(vdesc.x - vertex.co[0]) > FLOAT_TOLERANCE or\
- abs(vdesc.y - vertex.co[1]) > FLOAT_TOLERANCE or\
- abs(vdesc.z - vertex.co[2]) > FLOAT_TOLERANCE or\
- abs(vdesc.nx - vertex.no[0]) > FLOAT_TOLERANCE or\
- abs(vdesc.ny - vertex.no[1]) > FLOAT_TOLERANCE or\
- abs(vdesc.nz - vertex.no[2]) > FLOAT_TOLERANCE or\
- vdesc.cindex != cindex or\
- abs(vdesc.u - faceu) > FLOAT_TOLERANCE or\
- abs(vdesc.v - facev) > FLOAT_TOLERANCE:
- pass
- else:
- return vdesc.fltindex
-
- #if we get this far, we didnt find a match. Add a new one and return
- if uvok:
- newvdesc = VertexDesc(vertex.co, vertex.no, face.uv[vfindex], self.nextvindex,cindex=cindex)
- else:
- newvdesc = VertexDesc(co=vertex.co, no=vertex.no,fltindex=self.nextvindex,cindex=cindex)
- indexhash[vertex.index].append(newvdesc)
- self.vertex_lst.append(newvdesc)
- self.nextvindex = self.nextvindex + 1
- return newvdesc.fltindex
-
-
- def request_texture_index(self, image):
- match = None
- for i in xrange(len(self.texture_lst)):
- if self.texture_lst[i] != image:
- continue
- match = i
- break
- if match != None:
- return match
- else:
- self.texture_lst.append(image)
- return len(self.texture_lst) - 1
-
- def request_texture_filename(self, index):
- return Blender.sys.expandpath(self.texture_lst[index].getFilename())
-
- def texture_count(self):
- return len(self.texture_lst)
-
- def request_material_index(self, desc):
- match = None
- for i in xrange(len(self.material_lst)):
- if self.material_lst[i].diffuse != desc.diffuse:
- continue
- if self.material_lst[i].specular != desc.specular:
- continue
- if self.material_lst[i].ambient != desc.ambient:
- continue
- if self.material_lst[i].emissive != desc.emissive:
- continue
- if self.material_lst[i].shininess != desc.shininess:
- continue
- if self.material_lst[i].alpha != desc.alpha:
- continue
- match = i
- break
-
- if match != None:
- return i
- else:
- self.material_lst.append(desc)
- return len(self.material_lst) - 1
-
- def request_material_desc(self, index):
- return self.material_lst[index]
-
- def material_count(self):
- return len(self.material_lst)
-
- # Returns not actual index but one that includes intensity information.
- # color_index = 127*intensity + 128*actual_index
- def request_color_index(self, col):
- r,g,b = tuple(col)
- m = max(r, g, b)
- if m > 0.0:
- intensity = m / 1.0
- r = int(round(r/m * 255.0))
- g = int(round(g/m * 255.0))
- b = int(round(b/m * 255.0))
- brightest = [r, g, b]
- else:
- brightest = [255, 255, 255]
- intensity = 0.0
-
- match = None
- for i in xrange(len(self.color_lst)):
- if self.color_lst[i] != brightest:
- continue
-
- match = i
- break
-
- if match != None:
- index = match
- else:
- length = len(self.color_lst)
- if length <= 1024:
- self.color_lst.append(brightest)
- index = length
- else:
- if options.verbose >= 1:
- print 'Warning: Exceeded max color limit.'
- index = 0
-
- color_index = int(round(127.0*intensity)) + 128*index
- return color_index
-
- # Returns color from actual index.
- def request_max_color(self, index):
- return self.color_lst[index]
-
- def color_count(self):
- return len(self.color_lst)
-
- def __init__(self):
- #Vertex handling
- self.vertex_lst = []
- self.nextvindex = 0
- self.namehash = dict()
-
- self.texture_lst = []
- self.material_lst = []
- self.color_lst = [[255, 255, 255]]
- self.face_name = 0
-
-class Node:
- # Gathers info from blender needed for export.
- # The =[0] is a trick to emulate c-like static function variables
- # that are persistant between calls.
- def blender_export(self, level=[0]):
- if self.object:
- if options.verbose >= 2:
- print '\t' * level[0], self.name, self.object.type
- level[0] += 1
-
- self.children.reverse()
- for child in self.children:
- child.blender_export()
-
- level[0] -= 1
-
- # Exports this node's info to file.
- def write(self):
- pass
-
- def write_matrix(self):
- if self.matrix and not is_identity(self.matrix):
- self.header.fw.write_short(49) # Matrix opcode
- self.header.fw.write_ushort(68) # Length of record
- for i in xrange(4):
- for j in xrange(4):
- self.header.fw.write_float(self.matrix[i][j])
-
- def write_push(self):
- self.header.fw.write_short(10)
- self.header.fw.write_ushort(4)
-
- def write_pop(self):
- self.header.fw.write_short(11)
- self.header.fw.write_ushort(4)
-
- def write_push_extension(self):
- self.header.fw.write_short(21)
- self.header.fw.write_ushort(24)
- self.header.fw.pad(18)
- self.header.fw.write_ushort(0)
-
- def write_pop_extension(self):
- self.header.fw.write_short(22)
- self.header.fw.write_ushort(24)
- self.header.fw.pad(18)
- self.header.fw.write_ushort(0)
-
- def write_longid(self, name):
- length = len(name)
- if length >= 8:
- self.header.fw.write_short(33) # Long ID opcode
- self.header.fw.write_ushort(length+5) # Length of record
- self.header.fw.write_string(name, length+1) # name + zero terminator
-
- def write_comment(self,comment):
- length = len(comment)
- if length >= 65535:
- comment = comment[:65530]
- length = len(comment)
-
- pad = (length % 4) - 1
- if pad < 0:
- pad = None
- reclength = length + 5
- else:
- reclength = length + 5 + pad
-
- self.header.fw.write_short(31) # Comment Opcode
- self.header.fw.write_ushort(reclength) # Length of record is 4 + comment length + null terminator + pad
- self.header.fw.write_string(comment,length+1) # comment + zero terminator
- if pad:
- self.header.fw.pad(pad) # pad to multiple of 4 bytes
-
- # Initialization sets up basic tree structure.
- def __init__(self, parent, header, object,props):
- global options
-
- self.header = header
- self.object = object
- if object:
- self.name = self.object.name
- if not options.state['transform']:
- oloc = Blender.Mathutils.Vector(object.getLocation('worldspace'))
- vec = Blender.Mathutils.Vector(oloc[0] * options.state['scale'], oloc[1] * options.state['scale'], oloc[2] * options.state['scale']) #scale
- self.matrix = self.object.getMatrix('worldspace') * Blender.Mathutils.TranslationMatrix(vec - oloc)
- else:
- self.matrix = self.object.getMatrix('localspace') #do matrix mult here.
- self.props = props
- self.child_objects = self.header.parenthash[object.name]
- else:
- self.name = 'no name'
- self.matrix = None
- self.props = None
- self.child_objects = self.header.child_objects
-
- self.children = []
- self.parent = parent
- if parent:
- parent.children.append(self)
-
- # Spawn children.
- for child in self.child_objects:
- if(not child.restrictDisplay):
- childprops = None
- ftype = None
- if not child.properties.has_key('FLT'):
- if child.type == 'Empty':
- if child.DupGroup:
- childprops = FLTXRef.copy()
- ftype = 63
- else:
- childprops = FLTGroup.copy()
- ftype = 2
- elif child.type == 'Mesh':
- if self.header.childhash[child.name] or not child.parent:
- childprops = FLTGroup.copy()
- ftype = 2
- else:
- childprops = FLTObject.copy()
- ftype = 4
-
- else:
- childprops = dict()
- for prop in child.properties['FLT']:
- childprops[prop] = child.properties['FLT'][prop]
- ftype = child.properties['FLT']['type']
-
- if ftype in self.childtypes and ftype in alltypes:
- Newnode = FLTNode(self,header,child,childprops,ftype)
- if child.type == 'Mesh':
- self.header.mnodes.append(Newnode)
-class FaceDesc:
- def __init__(self):
- self.vertex_index_lst = []
- self.mface = None
- self.texture_index = 65535
- self.material_index = 65535
- self.color_index = 127
- self.renderstyle = 0
- self.twoside = 0
- self.name = None #uses next FLT name if not set... fix resolution of conflicts!
- self.billboard = 0
-
- #Multi-Tex info. Dosn't include first UV Layer!
- self.uvlayer = list() #list of list of tuples for UV coordinates.
- self.images = list() #list of texture indices for seperate UV layers
- self.mtex = list()
- self.subface = None #can either be 'Push' or 'Pop'
-
-def edge_get_othervert(vert, edge):
- if edge.v1 == vert:
- return edge.v2
- elif edge.v2 == vert:
- return edge.v1
- return None
-
-class FLTNode(Node):
- def walkLoop(self, targetvert, startvert, startedge, edgelist, visited, vedges, closeloop):
- loop = [targetvert]
-
- curvert = startvert
- curedge = startedge
- visited[curedge] = True
- found = False
-
- while not found:
- loop.append(curvert)
- disk = vedges[curvert.index]
- if not closeloop:
- if len(disk) == 1:
- visited[curedge] = True
- break
- else:
- if len(disk) < 2: #what?
- visited[curedge] = True
- return None
-
- if disk[0] == curedge:
- curedge = disk[1]
- else:
- curedge = disk[0]
- if curedge.v1.index == curvert.index:
- curvert = curedge.v2
- else:
- curvert = curedge.v1
-
- visited[curedge] = True
-
- if(curvert == targetvert):
- found = True
-
- return loop
-
- def buildVertFaces(self,vertuse):
- for vert in self.exportmesh.verts:
- if vertuse[vert.index][0] == False and vertuse[vert.index][1] == 0:
- face_desc = FaceDesc()
- face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, vert, 0,0,0))
- face_desc.renderstyle = 3
- face_desc.color_index = 227
- self.face_lst.append(face_desc)
-
- def buildEdgeFaces(self,vertuse):
- for edge in self.exportmesh.edges:
- v1 = vertuse[edge.v1.index]
- v2 = vertuse[edge.v2.index]
- if v1[0] == False and v2[0] == False:
- if v1[1] == 1 and v2[1] == 1:
- face_desc = FaceDesc()
- face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, edge, 1, 0,0))
- face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, edge, 2, 0,0))
- face_desc.renderstyle = 3
- face_desc.color_index = 227
- self.face_lst.append(face_desc)
-
-
- def vertwalk(self, startvert, loop, disk, visited):
- visited[startvert] = True
- for edge in disk[startvert]:
- othervert = edge_get_othervert(startvert, edge)
- if not visited[othervert]:
- loop.append(othervert)
- self.vertwalk(othervert,loop,disk,visited)
-
- def buildOpenFacesNew(self, vertuse):
- wireverts = list()
- wiredges = list()
- visited = dict()
- disk = dict()
- loops = list()
-
- for edge in self.exportmesh.edges:
- v1 = vertuse[edge.v1.index]
- v2 = vertuse[edge.v2.index]
- if v1[0] == False and v2[0] == False:
- if v1[1] < 3 and v2[1] < 3:
- wireverts.append(edge.v1)
- wireverts.append(edge.v2)
- wiredges.append(edge)
-
- #build disk data
- for vert in wireverts:
- visited[vert] = False
- disk[vert] = list()
- for edge in wiredges:
- disk[edge.v1].append(edge)
- disk[edge.v2].append(edge)
-
- #first pass: do open faces
- for vert in wireverts:
- if not visited[vert] and vertuse[vert.index][1] == 1:
- loop = list()
- done = 0
- startvert = vert
- while not done:
- done = 1
- visited[startvert] = True
- loop.append(startvert)
- for edge in disk[startvert]:
- othervert = edge_get_othervert(startvert, edge)
- if not visited[othervert]:
- done = 0
- startvert = othervert
- break
- if len(loop) > 2: loops.append( ('Open', loop) )
- for vert in wireverts:
- if not visited[vert]:
- loop = list()
- done = 0
- startvert = vert
- while not done:
- done = 1
- visited[startvert] = True
- loop.append(startvert)
- for edge in disk[startvert]:
- othervert = edge_get_othervert(startvert,edge)
- if not visited[othervert]:
- done = 0
- startvert = othervert
- break
- if len(loop) > 2: loops.append( ('closed', loop) )
-
- #now go through the loops and append.
- for l in loops:
- (ftype, loop) = l
- face_desc = FaceDesc()
- for i,vert in enumerate(loop):
- face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,loop,i,0,0))
- if ftype == 'closed':
- face_desc.renderstyle = 2
- else:
- face_desc.renderstyle = 3
- face_desc.color_index = 227
- self.face_lst.append(face_desc)
-
-
-
- def sortFLTFaces(self,a,b):
- aindex = a.getProperty("FLT_ORIGINDEX")
- bindex = b.getProperty("FLT_ORIGINDEX")
-
- if aindex > bindex:
- return 1
- elif aindex < bindex:
- return -1
- return 0
-
- def buildNormFaces(self):
-
- global options
- meshlayers = self.exportmesh.getUVLayerNames()
- oldlayer = self.exportmesh.activeUVLayer
- uvok = 0
- subfaceok = 0
- subfacelevel = 0
-
- #special case
- if self.exportmesh.faceUV and len(meshlayers) == 1:
- uvok = 1
- elif self.exportmesh.faceUV and tex_layers[0] in meshlayers:
- self.exportmesh.activeUVLayer = tex_layers[0]
- uvok = 1
-
- #Sort faces according to the subfaces/FLT indices
- if "FLT_ORIGINDEX" in self.exportmesh.faces.properties and "FLT_SFLEVEL" in self.exportmesh.faces.properties:
- exportfaces = list()
- for face in self.exportmesh.faces:
- exportfaces.append(face)
- exportfaces.sort(self.sortFLTFaces)
- subfaceok = 1
- else:
- exportfaces = self.exportmesh.faces
-
- # Faces described as lists of indices into the GRR's vertex_lst.
- for face in exportfaces:
- descs = list()
- #first we export the face as normal
- index_lst = []
- face_v = face.verts
- for i, v in enumerate(face_v):
- index_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,face,i,uvok,0))
- face_desc = FaceDesc()
- face_desc.vertex_index_lst = index_lst
- face_desc.mface = face
- descs.append(face_desc)
-
- #deal with subfaces
- if subfaceok:
- fsflevel = face.getProperty("FLT_SFLEVEL")
- for face_desc in descs:
- if fsflevel > subfacelevel:
- face_desc.subface = 'Push'
- subfacelevel = fsflevel
- elif fsflevel < subfacelevel:
- face_desc.subface = 'Pop'
- subfacelevel = fsflevel
-
-
- if uvok and (face.mode & Blender.Mesh.FaceModes.TWOSIDE):
- face_desc.renderstyle = 1
- for face_desc in descs:
- if "FLT_COL" in self.exportmesh.faces.properties:
- color_index = face.getProperty("FLT_COL")
-# if(color_index < 127):
-# color_index = 127 #sanity check for face color indices
- if(color_index == 0):
- color_index = 127
- face_desc.color_index = color_index
- else:
- face_desc.color_index = 127
- if "FLT_ID" in self.exportmesh.faces.properties:
- face_desc.name = face.getProperty("FLT_ID") #need better solution than this.
-
- if uvok and face.mode & Blender.Mesh.FaceModes["BILLBOARD"]:
- face_desc.billboard = 1
-
- self.face_lst.append(face_desc)
- if uvok:
- self.exportmesh.activeUVLayer = oldlayer
-
- def buildTexData(self):
-
- meshlayers = self.exportmesh.getUVLayerNames()
- oldlayer = self.exportmesh.activeUVLayer
- uvok = 0
-
- if self.exportmesh.faceUV and len(meshlayers) == 1:
- uvok = 1
- if self.exportmesh.faceUV and tex_layers[0] in meshlayers:
- self.exportmesh.activeUVLayer = tex_layers[0]
- uvok = 1
-
- if uvok:
- #do base layer. UVs have been stored on vertices directly already.
- for i, face in enumerate(self.face_lst):
- if face.mface:
- mface = face.mface
- image = mface.image
- if image != None and mface.mode & Blender.Mesh.FaceModes["TEX"]:
- index = self.header.GRR.request_texture_index(image)
- else:
- index = -1
- face.texture_index = index
-
- for i, face in enumerate(self.face_lst):
- if face.mface:
- mface_v = face.mface.v
- for v in mface_v:
- face.uvlayer.append([])
-
- for layername in tex_layers[1:]:
- if layername in meshlayers:
- self.exportmesh.activeUVLayer=layername
- for i, face in enumerate(self.face_lst):
- if face.mface:
-
- face.mtex.append(layername)
- mface = face.mface
- mface_v = mface.v
- image = mface.image
-
- if image != None and mface.mode & Blender.Mesh.FaceModes["TEX"]:
- index = self.header.GRR.request_texture_index(image)
- face.images.append(index)
- else:
- face.images.append(-1)
-
- for j, v in enumerate(mface_v):
- face.uvlayer[j].append(tuple(mface.uv[j]))
- if uvok:
- self.exportmesh.activeUVLayer = oldlayer
- def blender_export(self):
- global options
- Node.blender_export(self)
- if self.opcode == 111:
- self.exportmesh = Blender.Mesh.New()
- self.exportmesh.getFromObject(self.object.name)
-
- for vert in self.exportmesh.verts:
- if not options.state['transform']:
- vec = vert.co
- vec = Blender.Mathutils.Vector(vec[0] * options.state['scale'], vec[1] * options.state['scale'], vec[2] * options.state['scale']) #scale
- vert.co = Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace'))
-
- if options.state['scale'] != 1.0:
- vert.co = vert.co * options.state['scale']
-
- if("FLT_VCOL") in self.mesh.verts.properties:
- for v in self.exportmesh.verts:
- self.vert_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,v,0,0,v.getProperty("FLT_VCOL")))
- else:
- for v in self.mesh.verts:
- self.vert_lst.append(self.header.GRR.request_vertex_index(self.object,self.mesh,v,0,0,127))
-
-
-
- elif self.mesh:
- orig_mesh = self.object.getData(mesh=True)
- self.exportmesh = Blender.Mesh.New()
- default = None
-
-
- if options.state['export_shading']:
- mods = self.object.modifiers
- hasedsplit = False
- for mod in mods:
- if mod.type == Blender.Modifier.Types.EDGESPLIT:
- hasedsplit = True
- break
- if not hasedsplit:
- default = mods.append(Modifier.Types.EDGESPLIT)
- default[Modifier.Settings.EDGESPLIT_ANGLE] = options.state['shading_default']
- default[Modifier.Settings.EDGESPLIT_FROM_ANGLE] = True
- default[Modifier.Settings.EDGESPLIT_FROM_SHARP] = False
- self.object.makeDisplayList()
-
- self.exportmesh.getFromObject(self.object.name)
-
- #recalculate vertex positions
- for vert in self.exportmesh.verts:
- if not options.state['transform']:
- vec = vert.co
- vec = Blender.Mathutils.Vector(vec[0] * options.state['scale'], vec[1] * options.state['scale'], vec[2] * options.state['scale']) #scale
- vert.co = Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace'))
-
- if options.state['scale'] != 1.0:
- vert.co = vert.co * options.state['scale']
-
- flipped = self.object.getMatrix('worldspace').determinant()
-
- if not options.state['transform']:
- self.exportmesh.calcNormals()
-
-
- if default:
- #remove modifier from list
- mods.remove(default)
- self.object.makeDisplayList()
-
- #build some adjacency data
- vertuse = list()
- wiredges = list()
- openends = list()
- for v in self.exportmesh.verts:
- vertuse.append([False,0])
-
- #build face incidence data
- for face in self.exportmesh.faces:
- for i, v in enumerate(face.verts):
- vertuse[v.index][0] = True
-
- for edge in self.exportmesh.edges: #count valance
- vertuse[edge.v1.index][1] = vertuse[edge.v1.index][1] + 1
- vertuse[edge.v2.index][1] = vertuse[edge.v2.index][1] + 1
-
- #create all face types
- self.buildVertFaces(vertuse)
- self.buildEdgeFaces(vertuse)
- self.buildOpenFacesNew(vertuse)
- self.buildNormFaces()
- self.buildTexData()
-
- if not options.state['transform']:
- if flipped < 0:
- for vdesc in self.header.GRR.vertex_lst:
- vdesc.accum = 0
- for face in self.face_lst:
- face.vertex_index_lst.reverse()
- for vert in face.vertex_index_lst:
- self.header.GRR.vertex_lst[vert].accum = 1
-
- for vdesc in self.header.GRR.vertex_lst:
- if vdesc.accum:
- vdesc.nx = vdesc.nx * -1
- vdesc.ny = vdesc.ny * -1
- vdesc.nz = vdesc.nz * -1
-
-
- def write_faces(self):
- sublevel = 0
- for face_desc in self.face_lst:
- if face_desc.name:
- face_name = face_desc.name
- else:
- face_name = self.header.GRR.new_face_name()
-
- #grab the alpha value.
- alpha = 0
- if face_desc.texture_index > -1:
- try:
- typestring = os.path.splitext(self.header.GRR.texture_lst[face_desc.texture_index].getFilename())[1]
- if typestring == '.inta' or typestring == '.rgba':
- alpha = 1
- except:
- pass
-
- if not alpha:
- for index in face_desc.images:
- try:
- typestring = os.path.splitext(self.header.GRR.texture_lst[index].getFilename())[1]
- if typestring == '.inta' or typestring == '.rgba':
- alpha = 1
- except:
- pass
-
- if face_desc.billboard:
- alpha = 2
-
- if face_desc.subface:
- if face_desc.subface == 'Push':
- self.header.fw.write_short(19)
- self.header.fw.write_ushort(4)
- sublevel += 1
- else:
- self.header.fw.write_short(20)
- self.header.fw.write_ushort(4)
- sublevel -= 1
- self.header.fw.write_short(5) # Face opcode
- self.header.fw.write_ushort(80) # Length of record
- self.header.fw.write_string(face_name, 8) # ASCII ID
- self.header.fw.write_int(-1) # IR color code
- self.header.fw.write_short(0) # Relative priority
- self.header.fw.write_char(face_desc.renderstyle) # Draw type
- self.header.fw.write_char(0) # Draw textured white.
- self.header.fw.write_ushort(0) # Color name index
- self.header.fw.write_ushort(0) # Alt color name index
- self.header.fw.write_char(0) # Reserved
- self.header.fw.write_char(alpha) # Template
- self.header.fw.write_short(-1) # Detail tex pat index
- if face_desc.texture_index == -1:
- self.header.fw.write_ushort(65535)
- else:
- self.header.fw.write_ushort(face_desc.texture_index) # Tex pattern index
- if face_desc.material_index == -1:
- self.header.fw.write_ushort(65535)
- else:
- self.header.fw.write_ushort(face_desc.material_index) # material index
- self.header.fw.write_short(0) # SMC code
- self.header.fw.write_short(0) # Feature code
- self.header.fw.write_int(0) # IR material code
- self.header.fw.write_ushort(0) # transparency 0 = opaque
- self.header.fw.write_uchar(0) # LOD generation control
- self.header.fw.write_uchar(0) # line style index
- self.header.fw.write_int(0) # Flags
- self.header.fw.write_uchar(2) # Light mode
- #self.header.fw.write_uchar(3) # Light mode
-
- self.header.fw.pad(7) # Reserved
- self.header.fw.write_uint(0) # Packed color
- self.header.fw.write_uint(0) # Packed alt color
- self.header.fw.write_short(-1) # Tex map index
- self.header.fw.write_short(0) # Reserved
- self.header.fw.write_uint(face_desc.color_index) # Color index
- self.header.fw.write_uint(127) # Alt color index
- self.header.fw.write_short(0) # Reserved
- self.header.fw.write_short(-1) # Shader index
-
- self.write_longid(face_name)
-
-
- #Write Multitexture field if appropriate
- mtex = len(face_desc.mtex)
- if mtex:
- uvmask = 0
- for layername in face_desc.mtex:
- mask = mtexmasks[tex_layers.index(layername)-1]
- uvmask |= mask
- self.header.fw.write_ushort(52) # MultiTexture Opcode
- self.header.fw.write_ushort(8 + (mtex * 8)) # Length
- self.header.fw.write_uint(uvmask) # UV mask
- for i in xrange(mtex):
- if face_desc.images[i] == -1:
- self.header.fw.write_ushort(65535)
- else:
- self.header.fw.write_ushort(face_desc.images[i]) # Tex pattern index
- self.header.fw.write_ushort(0) # Tex effect
- self.header.fw.write_ushort(0) # Tex Mapping index
- self.header.fw.write_ushort(0) # Tex data. User defined
-
- self.write_push()
-
- # Vertex list record
- self.header.fw.write_short(72) # Vertex list opcode
- num_verts = len(face_desc.vertex_index_lst)
- self.header.fw.write_ushort(4*num_verts+4) # Length of record
-
- for vert_index in face_desc.vertex_index_lst:
- # Offset into vertex palette
- self.header.fw.write_int(vert_index*64+8)
-
- #UV list record
- if mtex:
- #length = 8 + (numverts * multitex * 8)
- self.header.fw.write_ushort(53) # UV List Ocode
- self.header.fw.write_ushort(8 + (num_verts*mtex*8)) # Record Length
- self.header.fw.write_uint(uvmask) # UV mask
- for i, vert_index in enumerate(face_desc.vertex_index_lst):
- for uv in face_desc.uvlayer[i]:
- self.header.fw.write_float(uv[0]) #U coordinate
- self.header.fw.write_float(uv[1]) #V coordinate
- self.write_pop()
- #clean up faces at the end of meshes....
- if sublevel:
- self.header.fw.write_short(20)
- self.header.fw.write_ushort(4)
-
- def write_lps(self):
- # Vertex list record
- self.write_push()
- self.header.fw.write_short(72) # Vertex list opcode
- num_verts = len(self.vert_lst)
- self.header.fw.write_ushort(4*num_verts+4) # Length of record
-
- for vert_index in self.vert_lst:
- # Offset into vertex palette
- self.header.fw.write_int(vert_index*64+8)
- self.write_pop()
- def write(self):
- self.header.fw.write_short(self.opcode)
- self.header.fw.write_ushort(recordlen[self.opcode])
- exportdict = FLT_Records[self.opcode].copy()
- if self.object:
- self.props['3t8!id'] = self.object.name[:7]
- for key in exportdict.keys():
- if self.props.has_key(key):
- exportdict[key] = self.props[key]
-
- if self.opcode == 63 and options.state['externalspath']:
- try:
- exportdict['3t200!filename'] = os.path.join(options.state['externalspath'],self.object.DupGroup.name+'.flt').replace("\\", "/")
- self.header.xrefnames.append(self.object.DupGroup.name)
- except:
- pass
-
- for key in records[self.opcode]:
- (ftype,length,propname) = records[self.opcode][key]
- write_prop(self.header.fw,ftype,exportdict[propname],length)
-
- if self.props.has_key('comment'):
- self.write_comment(self.props['comment'])
-
- if self.object and self.object.properties.has_key('FLT') and self.object.properties['FLT'].has_key('EXT'):
- datalen = len(self.object.properties['FLT']['EXT']['data'])
- self.write_push_extension()
- self.header.fw.write_short(100)
- self.header.fw.write_ushort(24 + datalen)
- for key in records[100]:
- (ftype,length,propname) = records[100][key]
- write_prop(self.header.fw,ftype,self.object.properties['FLT']['EXT'][propname],length)
- #write extension data
- for i in xrange(datalen):
- self.header.fw.write_uchar(struct.unpack('>B', struct.pack('>B', self.object.properties['FLT']['EXT']['data'][i]))[0])
- self.write_pop_extension()
-
-
- self.write_longid(self.name) #fix this!
-
- if options.state['transform'] or self.opcode == 63:
- #writing transform matrix....
- self.write_matrix()
-
- if self.opcode == 111:
- self.write_lps()
- elif self.face_lst != [] or self.children:
- self.write_push()
- if self.face_lst != []:
- #self.write_push()
- self.write_faces()
- #self.write_pop()
-
- if self.children:
- #self.write_push()
- for child in self.children:
- child.write()
- #self.write_pop()
- self.write_pop()
-
- def __init__(self, parent, header, object,props,ftype):
- self.opcode = ftype #both these next two lines need to be in the node class....
- self.childtypes = childtypes[self.opcode]
- Node.__init__(self, parent, header, object,props)
- self.face_lst = []
- self.vert_lst = [] #for light points.
- self.mesh = None
- self.uvlayer = 0
- self.flipx = False
- self.flipy = False
- self.flipz = False
-
-
- if self.object.type == 'Mesh':
- self.mesh = self.object.getData(mesh=True)
- if(self.mesh.faceUV):
- self.uvLayer = len(self.mesh.getUVLayerNames())
-
-class Database(Node):
- def write_header(self):
- if options.verbose >= 2:
- print 'Writing header.'
- self.fw.write_short(1) # Header opcode
- self.fw.write_ushort(324) # Length of record
- self.fw.write_string('db', 8) # ASCII ID
- self.fw.write_int(1600) # Revision Number
- self.fw.pad(44)
- self.fw.write_short(1) # Unit multiplier.
- self.fw.write_char(0) # Units, 0 = meters
- self.fw.write_char(0) # texwhite on new faces 0 = false
- self.fw.write_uint(0x80000000) # misc flags set to saving vertex normals
- self.fw.pad(24)
- self.fw.write_int(0) # projection type, 0 = flat earth
- self.fw.pad(30)
- self.fw.write_short(1) # double precision
- self.fw.write_int(100) # database origin type
- self.fw.pad(88)
- try:
- self.fw.write_double(self.header.scene.properties['FLT']['origin lat']) #database origin lattitude
- except:
- self.fw.write_double(0)
- try:
- self.fw.write_double(self.header.scene.properties['FLT']['origin lon']) #database origin longitude
- except:
- self.fw.write_double(0)
- self.fw.pad(32)
- self.fw.write_int(0) # ellipsoid model, 0 = WSG 1984
-
- self.fw.pad(52)
-
- def write_vert_pal(self):
- if options.verbose >= 2:
- print 'Writing vertex palette.'
- # Write record for vertex palette
- self.fw.write_short(67) # Vertex palette opcode.
- self.fw.write_short(8) # Length of record
- self.fw.write_int(self.GRR.vertex_count() * 64 + 8) # Length of everything.
- # Write records for individual vertices.
- for i in xrange(self.GRR.vertex_count()):
- desc = self.GRR.request_vertex_desc(i)
- self.fw.write_short(70) # Vertex with color normal and uv opcode.
- self.fw.write_ushort(64) # Length of record
- self.fw.write_ushort(0) # Color name index
- self.fw.write_short(1 << 14) # Frozen Normal
- self.fw.write_double(desc.x)
- self.fw.write_double(desc.y)
- self.fw.write_double(desc.z)
- self.fw.write_float(desc.nx)
- self.fw.write_float(desc.ny)
- self.fw.write_float(desc.nz)
- self.fw.write_float(desc.u)
- self.fw.write_float(desc.v)
- self.fw.pad(4)
- self.fw.write_uint(desc.cindex)
- self.fw.pad(4)
-
- def write_tex_pal(self):
- if options.verbose >= 2:
- print 'Writing texture palette.'
- # Write record for texture palette
- for i, img in enumerate(self.GRR.texture_lst):
- filename = tex_files[img.name]
- self.fw.write_short(64) # Texture palette opcode.
- self.fw.write_short(216) # Length of record
- self.fw.write_string(filename, 200) # Filename
- self.fw.write_int(i) # Texture index
- self.fw.write_int(0) # X
- self.fw.write_int(0) # Y
-
- def write_mat_pal(self):
- if options.verbose >= 2:
- print 'Writing material palette.'
- for i in xrange(self.GRR.material_count()):
- desc = self.GRR.request_material_desc(i)
- self.fw.write_short(113) # Material palette opcode.
- self.fw.write_short(84) # Length of record
- self.fw.write_int(i) # Material index
- self.fw.write_string(desc.name, 12) # Material name
- self.fw.write_uint(0x80000000) # Flags
- self.fw.write_float(desc.ambient[0]) # Ambient color.
- self.fw.write_float(desc.ambient[1]) # Ambient color.
- self.fw.write_float(desc.ambient[2]) # Ambient color.
- self.fw.write_float(desc.diffuse[0]) # Diffuse color.
- self.fw.write_float(desc.diffuse[1]) # Diffuse color.
- self.fw.write_float(desc.diffuse[2]) # Diffuse color.
- self.fw.write_float(desc.specular[0]) # Specular color.
- self.fw.write_float(desc.specular[1]) # Specular color.
- self.fw.write_float(desc.specular[2]) # Specular color.
- self.fw.write_float(desc.emissive[0]) # Emissive color.
- self.fw.write_float(desc.emissive[1]) # Emissive color.
- self.fw.write_float(desc.emissive[2]) # Emissive color.
- self.fw.write_float(desc.shininess)
- self.fw.write_float(desc.alpha)
- self.fw.write_int(0) # Reserved
-
- def write_col_pal(self):
- if options.verbose >= 2:
- print 'Writing color palette.'
- self.fw.write_short(32) # Color palette opcode.
- self.fw.write_short(4228) # Length of record
- self.fw.pad(128)
- try:
- cpalette = self.scene.properties['FLT']['Color Palette']
- except:
- cpalette = defaultp.pal
- count = len(cpalette)
- for i in xrange(count):
- color = struct.unpack('>BBBB',struct.pack('>i',cpalette[i]))
- self.fw.write_uchar(color[3]) # alpha
- self.fw.write_uchar(color[2]) # b
- self.fw.write_uchar(color[1]) # g
- self.fw.write_uchar(color[0]) # r
- self.fw.pad(max(4096-count*4, 0))
-
- def write(self):
- self.write_header()
- self.write_vert_pal()
- self.write_tex_pal()
- self.write_mat_pal()
- self.write_col_pal()
-
- self.write_push()
-
- for child in self.children:
- child.write()
- self.write_pop()
-
- def export_textures(self,texturepath):
- for i in xrange(self.GRR.texture_count()):
- texture = self.GRR.texture_lst[i]
-
- if options.state['copytex']:
- filename = os.path.normpath(os.path.join(options.state['texturespath'], os.path.basename(self.GRR.request_texture_filename(i))))
- else:
- filename = os.path.normpath(self.GRR.request_texture_filename(i))
-
- tex_files[texture.name] = filename
-
- def blender_export(self):
- Node.blender_export(self)
- self.export_textures(self)
- return self.xrefnames
- def __init__(self, scene, fw):
- self.fw = fw
- self.opcode = 1
- self.childtypes = [73,14,2,63]
- self.scene = scene
- self.childhash = dict()
- self.parenthash = dict()
- self.child_objects = list()
- self.mnodes = list()
- self.xrefnames = list()
- for i in self.scene.objects:
- self.parenthash[i.name] = list()
- self.childhash[i.name] = False
- for i in self.scene.objects:
- if i.parent:
- self.childhash[i.parent.name] = True
- self.parenthash[i.parent.name].append(i)
- else:
- self.child_objects.append(i)
-
- self.GRR = GlobalResourceRepository()
- Node.__init__(self, None, self, None,None)
-
-def write_attribute_files():
- for imgname in tex_files:
- blentex = Blender.Image.Get(imgname)
- exportdict = FLT_Records['Image'].copy()
-
- if blentex.properties.has_key('FLT'):
- for key in exportdict.keys():
- if blentex.properties.has_key(key):
- exportdict[key] = blentex.properties['FLT'][key]
-
- # ClampX/Y override
- if blentex.clampX:
- exportdict['11i!WrapU'] = 1
- if blentex.clampY:
- exportdict['12i!WrapV'] = 1
-
- exportdict['16i!Enviorment'] = 0
-
- # File type
- typecode = 0
- try:
- typestring = os.path.splitext(blentex.getFilename())[1]
-
- if typestring == '.rgba':
- typecode = 5
- elif typestring == '.rgb':
- typecode = 4
- elif typestring == '.inta':
- typecode = 3
- elif typestring == '.int':
- typecode = 2
- except:
- pass
-
- exportdict['7i!File Format'] = typecode
-
- fw = FltOut(tex_files[imgname] + '.attr')
- size = blentex.getSize()
- fw.write_int(size[0])
- fw.write_int(size[1])
- for key in records['Image']:
- (ftype,length,propname) = records['Image'][key]
- write_prop(fw,ftype,exportdict[propname],length)
- fw.close_file()
-
-#globals used by the scene export function
-exportlevel = None
-xrefsdone = None
-
-def dbexport_internal(scene):
- global exportlevel
- global xrefsdone
- global options
-
- if exportlevel == 0 or not options.state['externalspath']:
- fname = os.path.join(options.state['basepath'],scene.name + '.flt')
- else:
- fname = os.path.join(options.state['externalspath'],scene.name + '.flt')
-
- fw = FltOut(fname)
- db = Database(scene,fw)
-
- if options.verbose >= 1:
- print 'Pass 1: Exporting ', scene.name,'.flt from Blender.\n'
-
- xreflist = db.blender_export()
- if options.verbose >= 1:
- print 'Pass 2: Writing %s\n' % fname
- db.write()
- fw.close_file()
-
- if options.state['doxrefs']:
- for xname in xreflist:
- try:
- xrefscene = Blender.Scene.Get(xname)
- except:
- xrefscene = None
- if xrefscene and xname not in xrefsdone:
- xrefsdone.append(xname)
- exportlevel+=1
- dbexport_internal(xrefscene)
- exportlevel-=1
- return fname
-#main database export function
-def dbexport():
- global exportlevel
- global xrefsdone
- exportlevel = 0
- xrefsdone = list()
-
- Blender.Window.WaitCursor(True)
- time1 = Blender.sys.time() # Start timing
-
- if options.verbose >= 1:
- print '\nOpenFlight Exporter'
- print 'Version:', __version__
- print 'Author: Greg MacDonald, Geoffrey Bantle'
- print __url__[2]
- print
-
- fname = dbexport_internal(Blender.Scene.GetCurrent())
- if options.verbose >=1:
- print 'Done in %.4f sec.\n' % (Blender.sys.time() - time1)
- Blender.Window.WaitCursor(False)
-
- #optional: Copy textures
- if options.state['copytex']:
- for imgname in tex_files:
- #Check to see if texture exists in target directory
- if not os.path.exists(tex_files[imgname]):
- #Get original Blender file name
- origpath = Blender.sys.expandpath(Blender.Image.Get(imgname).getFilename())
- #copy original to new
- if os.path.exists(origpath):
- shutil.copyfile(origpath,tex_files[imgname])
-
- #optional: Write attribute files
- if options.state['attrib']:
- write_attribute_files()
-
- if options.state['xapp']:
- cmd= options.state['xappath'] + " " + fname
- status = os.system(cmd)
-
-
-#Begin UI code
-FLTExport = None
-FLTClose = None
-FLTLabel = None
-
-FLTBaseLabel = None
-FLTTextureLabel = None
-FLTXRefLabel = None
-
-FLTBaseString = None
-FLTTextureString = None
-FLTXRefString = None
-
-FLTBasePath = None
-FLTTexturePath = None
-FLTXRefPath = None
-
-FLTShadeExport = None
-FLTShadeDefault = None
-
-FLTCopyTex = None
-FLTDoXRef = None
-FLTGlobal = None
-
-FLTScale = None
-
-FLTXAPP = None
-FLTXAPPath = None
-FLTXAPPString = None
-FLTXAPPLabel = None
-FLTXAPPChooser = None
-
-FLTAttrib = None
-
-
-FLTWarn = None
-
-def setshadingangle(ID,val):
- global options
- options.state['shading_default'] = val
-def setBpath(fname):
- global options
- options.state['basepath'] = os.path.dirname(fname)
- #update xref and textures path too....
- if(os.path.exists(os.path.join(options.state['basepath'],'externals'))):
- options.state['externalspath'] = os.path.join(options.state['basepath'],'externals')
- if(os.path.exists(os.path.join(options.state['basepath'],'textures'))):
- options.state['texturespath'] = os.path.join(options.state['basepath'],'textures')
-def setexportscale(ID,val):
- global options
- options.state['scale'] = val
-
-def setTpath(fname):
- global options
- options.state['texturespath'] = os.path.dirname(fname)
-def setXpath(fname):
- global options
- options.state['externalspath'] = os.path.dirname(fname)
-def setXApath(fname):
- global options
- options.state['xappath'] = fname
-def event(evt, val):
- x = 1
-def but_event(evt):
- global options
-
- global FLTExport
- global FLTClose
- global FLTLabel
-
- global FLTBaseLabel
- global FLTTextureLabel
- global FLTXRefLabel
-
- global FLTBaseString
- global FLTTextureString
- global FLTXRefString
-
- global FLTBasePath
- global FLTTexturePath
- global FLTXRefPath
-
- global FLTShadeExport
- global FLTShadeDefault
-
- global FLTCopyTex
- global FLTDoXRef
- global FLTGlobal
-
- global FLTScale
-
-
- global FLTXAPP
- global FLTXAPPath
- global FLTXAPPString
- global FLTXAPPLabel
- global FLTXAPPChooser
-
- global FLTAttrib
-
- global FLTWarn
-
- #choose base path for export
- if evt == 4:
- Blender.Window.FileSelector(setBpath, "DB Root", options.state['basepath'])
-
- #choose XREF path
- if evt == 6:
- Blender.Window.FileSelector(setXpath,"DB Externals",options.state['externalspath'])
-
- #choose texture path
- if evt == 8:
- Blender.Window.FileSelector(setTpath,"DB Textures",options.state['texturespath'])
-
- #export shading toggle
- if evt == 9:
- options.state['export_shading'] = FLTShadeExport.val
- #export Textures
- if evt == 11:
- options.state['copytex']= FLTCopyTex.val
- #export XRefs
- if evt == 13:
- options.state['doxrefs'] = FLTDoXRef.val
- #export Transforms
- if evt == 12:
- options.state['transform'] = FLTGlobal.val
-
- if evt == 14:
- options.state['xapp'] = FLTXAPP.val
- if evt == 16:
- Blender.Window.FileSelector(setXApath,"External Application",options.state['xappath'])
- if evt == 20:
- options.state['attrib'] = FLTAttrib.val
-
- #Export DB
- if evt == 1:
- try:
- dbexport()
- except Exception, inst:
- import traceback
- FLTWarn = Draw.PupBlock("Export Error", ["See console for output!"])
- traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)
-
- #exit
- if evt == 2:
- Draw.Exit()
-
- options.write_state()
-
-from Blender.BGL import *
-from Blender import Draw
-def gui():
-
- global options
-
- global FLTExport
- global FLTClose
- global FLTLabel
-
- global FLTBaseLabel
- global FLTTextureLabel
- global FLTXRefLabel
-
- global FLTBaseString
- global FLTTextureString
- global FLTXRefString
-
- global FLTBasePath
- global FLTTexturePath
- global FLTXRefPath
-
- global FLTShadeExport
- global FLTShadeDefault
-
- global FLTCopyTex
- global FLTDoXRef
- global FLTGlobal
-
- global FLTScale
-
- global FLTXAPP
- global FLTXAPPath
- global FLTXAPPString
- global FLTXAPPLabel
- global FLTXAPPChooser
-
- global FLTAttrib
-
- glClearColor(0.880,0.890,0.730,1.0 )
- glClear(GL_COLOR_BUFFER_BIT)
-
- areas = Blender.Window.GetScreenInfo()
- curarea = Blender.Window.GetAreaID()
- curRect = None
-
- for area in areas:
- if area['id'] == curarea:
- curRect = area['vertices']
- break
-
- width = curRect[2] - curRect[0]
- height = curRect[3] - curRect[1]
- #draw from top to bottom....
- cx = 50
- #Draw Title Bar...
- #glRasterPos2d(cx, curRect[3]-100)
- #FLTLabel = Draw.Text("FLT Exporter V2.0",'large')
- cy = height - 80
-
- FLTBaseLabel = Draw.Label("Base Path:",cx,cy,100,20)
- FLTBaseString = Draw.String("",3,cx+100,cy,300,20,options.state['basepath'],255,"Folder to export to")
- FLTBaseChooser = Draw.PushButton("...",4,cx+400,cy,20,20,"Choose Folder")
-
- cy = cy-40
-
- #externals path
- FLTXRefLabel = Draw.Label("XRefs:",cx,cy,100,20)
- FLTXRefString = Draw.String("",5,cx+100,cy,300,20,options.state['externalspath'],255,"Folder for external references")
- FLTXRefChooser = Draw.PushButton("...",6,cx+400,cy,20,20,"Choose Folder")
- cy = cy-40
- #Textures path
- FLTTextureLabel = Draw.Label("Textures:",cx,cy,100,20)
- FLTTextureString = Draw.String("",7,cx+100,cy,300,20,options.state['texturespath'],255,"Folder for texture files")
- FLTTextureChooser = Draw.PushButton("...",8,cx+400,cy,20,20,"Choose Folder")
- cy=cy-40
- #External application path
- FLTXAPPLabel = Draw.Label("XApp:",cx,cy,100,20)
- FLTXAPPString = Draw.String("",15,cx+100,cy,300,20,options.state['xappath'],255,"External application to launch when done")
- FLTXAPPChooser = Draw.PushButton("...",16,cx+400, cy,20,20,"Choose Folder")
-
- cy = cy-60
- #Shading Options
- FLTShadeExport = Draw.Toggle("Default Shading",9,cx,cy,100,20,options.state['export_shading'],"Turn on export of custom shading")
- FLTShadDefault = Draw.Number("",10,cx + 120,cy,100,20,options.state['shading_default'],0.0,180.0,"Default shading angle for objects with no custom shading assigned",setshadingangle)
-
- cy = cy-40
- FLTScale = Draw.Number("Export Scale",14,cx,cy,220,20,options.state['scale'],0.0,100.0,"Export scaling factor",setexportscale)
-
- cy = cy-40
- #misc Options
- FLTCopyTex = Draw.Toggle("Copy Textures",11,cx,cy,220,20,options.state['copytex'],"Copy textures to folder indicated above")
- cy = cy-40
- FLTGlobal = Draw.Toggle("Export Transforms",12,cx,cy,220,20,options.state['transform'],"If unchecked, Global coordinates are used (recommended)")
- cy = cy-40
- FLTDoXRef = Draw.Toggle("Export XRefs", 13,cx,cy,220,20,options.state['doxrefs'],"Export External references (only those below current scene!)")
- cy = cy-40
- FLTXAPP = Draw.Toggle("Launch External App", 14, cx,cy,220,20,options.state['xapp'],"Launch External Application on export")
- cy = cy-40
- FLTAttrib = Draw.Toggle("Write Attribute Files", 20, cx, cy, 220,20,options.state['attrib'], "Write Texture Attribute files")
- #FLTXAPPATH = Draw.String("",15,cx,cy,300,20,options.xappath,255,"External application path")
-
-
- #Draw export/close buttons
- FLTExport = Draw.PushButton("Export",1,cx,20,100,20,"Export to FLT")
- FLTClose = Draw.PushButton("Close", 2, cx+120,20,100,20,"Close window")
-
-
-Draw.Register(gui,event,but_event) \ No newline at end of file
diff --git a/release/scripts/flt_filewalker.py b/release/scripts/flt_filewalker.py
deleted file mode 100644
index 4a9b86c45d2..00000000000
--- a/release/scripts/flt_filewalker.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#!BPY
-
-# flt_filewalker.py is an utility module for OpenFlight IO scripts for blender.
-# Copyright (C) 2005 Greg MacDonald
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-__bpydoc__ ="""\
-File read/write module used by OpenFlight I/O and tool scripts. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-"""
-
-import Blender
-from struct import *
-import re
-
-class FltIn:
- def __init__(self, filename):
- self.file = open(filename, 'rb')
- self.position = 0
- self.next_position = 100000
- self.opcode = 0
- self.length = 0
- self.level = 0
- self.repeat = False # Repeat the last record.
-
- def begin_record(self):
- if self.repeat == True:
- self.repeat = False
- else:
- self.position += self.length
- try:
- self.file.seek(self.position)
- input = self.file.read(4)
- except:
- print 'Parse Error!'
- return False
-
- if not input:
- self.close_file()
- return False
-
- self.opcode = unpack('>h', input[:2])[0]
- self.length = unpack('>H', input[-2:])[0]
-
- self.next_position = self.position + self.length
-
- return True
-
- def repeat_record(self):
- self.repeat = True
-
- def get_opcode(self):
- return self.opcode
-
- def get_level(self):
- return self.level
-
- def up_level(self):
- self.level += 1
-
- def down_level(self):
- self.level -= 1
-
- def read_string(self, length):
- s = ''
- if self.file.tell() + length <= self.next_position:
- start = self.file.tell()
- for i in xrange(length):
- char = self.file.read(1)
- if char == '\x00':
- break
- s = s + char
-
- self.file.seek(start+length)
-# else:
-# print 'Warning: string truncated'
-
- return s
-
- def read_int(self):
- if self.file.tell() + 4 <= self.next_position:
- return unpack('>i', self.file.read(4))[0]
- else:
- #print 'Warning: int truncated'
- return 0
-
- def read_uint(self):
- if self.file.tell() + 4 <= self.next_position:
- return unpack('>I', self.file.read(4))[0]
- else:
- #print 'Warning: uint truncated'
- return 0
-
- def read_double(self):
- if self.file.tell() + 8 <= self.next_position:
- return unpack('>d', self.file.read(8))[0]
- else:
- #print 'Warning: double truncated'
- return 0.0
-
- def read_float(self):
- if self.file.tell() + 4 <= self.next_position:
- return unpack('>f', self.file.read(4))[0]
- else:
- #print 'Warning: float truncated'
- return 0.0
-
- def read_ushort(self):
- if self.file.tell() + 2 <= self.next_position:
- return unpack('>H', self.file.read(2))[0]
- else:
- #print 'Warning: ushort truncated'
- return 0
-
- def read_short(self):
- if self.file.tell() + 2 <= self.next_position:
- return unpack('>h', self.file.read(2))[0]
- else:
- #print 'Warning: short trunated'
- return 0
-
- def read_uchar(self):
- if self.file.tell() + 1 <= self.next_position:
- return unpack('>B', self.file.read(1))[0]
- else:
- #print 'Warning: uchar truncated'
- return 0
-
- def read_char(self):
- if self.file.tell() + 1 <= self.next_position:
- return unpack('>b', self.file.read(1))[0]
- else:
- #print 'Warning: char truncated'
- return 0
-
- def read_ahead(self, i):
- if self.file.tell() + i <= self.next_position:
- self.file.seek(i, 1)
-# else:
-# print 'Warning: attempt to seek past record'
-
- def get_length(self):
- return self.length
-
- def close_file(self):
- self.file.close()
-
-class FltOut:
- # Length includes terminating null
- def write_string(self, string, length):
- if len(string) > length - 1:
- str_len = length - 1
- else:
- str_len = len(string)
-
- pad_len = length - str_len
-
- self.file.write(string[:str_len])
-
- self.pad(pad_len)
-
- def write_int(self, a):
- self.file.write( pack('>i', a) )
-
- def write_uint(self, a):
- self.file.write( pack('>I', a) )
-
- def write_double(self, a):
- self.file.write( pack('>d', a) )
-
- def write_float(self, a):
- self.file.write( pack('>f', a) )
-
- def write_ushort(self, a):
- self.file.write( pack('>H', a) )
-
- def write_short(self, a):
- self.file.write( pack('>h', a) )
-
- def write_uchar(self, a):
- self.file.write( pack('>B', a) )
-
- def write_char(self, a):
- self.file.write( pack('>b', a) )
-
- def pad(self, reps):
- for i in xrange(reps):
- self.file.write('\x00')
-
- def close_file(self):
- self.file.close()
-
- def __init__(self, filename):
- self.file = open(filename, 'wb')
- self.filename = filename
-
-
-class FileFinder:
- def add_file_to_search_path(self, filename):
- dir = Blender.sys.dirname(filename)
- if dir != None and dir != '':
- self.search_dirs.append(dir)
-
- def strip_path(self, full_path):
- # One of my flt files had a windows path with unix seperation. Basename
- # returned the whole path + filename, which isn't expected. So my
- # attempt to fix it is to replace all / or \ with the platform specific
- # dir seperator.
- #
- # note: \\\\ is actually just one \ indirected twice, once for python
- # then again for re.sub
- if Blender.sys.sep == '\\':
- full_path = re.sub('/', '\\\\', full_path)
- elif Blender.sys.sep == '/':
- full_path = re.sub('\\\\', '/', full_path)
-
- filename = Blender.sys.basename(full_path)
- return filename
-
- def find(self, full_path):
- if full_path == '':
- return None
-
- # Seperate out the path.
- dirname = Blender.sys.dirname(full_path)
-
- # Try it first.
- if Blender.sys.exists(full_path):
- if not dirname in self.search_dirs:
- self.search_dirs.append(dirname)
- return full_path
-
- # Maybe it's relative.
- for path in self.search_dirs:
- rel_full_path = Blender.sys.join(path, full_path)
- if Blender.sys.exists(rel_full_path):
- return rel_full_path
-
- # Search previous directories that have worked.
- filename = self.strip_path(full_path)
- for path in self.search_dirs:
- t = Blender.sys.join(path, filename)
- if Blender.sys.exists(t):
- return t
-
- # Ask user where it is.
- self.user_input = Blender.Draw.PupStrInput(filename + "? ", '', 100)
- #self.user_input = None
- if self.user_input != None:
- t = Blender.sys.join(self.user_input, filename)
- if Blender.sys.exists(t):
- user_dirname = Blender.sys.dirname(t)
- if not user_dirname in self.search_dirs:
- self.search_dirs.append(user_dirname)
- return t
-
- # Couldn't find it.
- return None
-
- def __init__(self):
- self.user_input = ''
- self.current_file = ''
- self.search_dirs = []
-
- dir = Blender.Get('texturesdir')
- if dir != None and dir != '':
- self.search_dirs.append(dir)
-
- dir = Blender.sys.dirname(Blender.Get('filename'))
- if dir != None and dir != '':
- print dir
- self.search_dirs.append(dir)
- \ No newline at end of file
diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py
deleted file mode 100644
index f8d31f7bb57..00000000000
--- a/release/scripts/flt_import.py
+++ /dev/null
@@ -1,2534 +0,0 @@
-#!BPY
-""" Registration info for Blender menus:
-Name: 'OpenFlight (.flt)...'
-Blender: 245
-Group: 'Import'
-Tip: 'Import OpenFlight (.flt)'
-"""
-
-
-
-__author__ = "Greg MacDonald, Campbell Barton, Geoffrey Bantle"
-__version__ = "2.0 11/21/07"
-__url__ = ("blender", "blenderartists.org", "Author's homepage, http://sourceforge.net/projects/blight/")
-__bpydoc__ = """\
-This script imports OpenFlight files into Blender. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/Import/openflight_fltss
-
-Note: This file is a grab-bag of old and new code. It needs some cleanup still.
-"""
-
-# flt_import.py is an OpenFlight importer for blender.
-# Copyright (C) 2005 Greg MacDonald, 2007 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.
-
-import Blender
-import os
-import BPyMesh
-import BPyImage
-import flt_filewalker
-import flt_properties
-import sys
-reload(flt_properties)
-from flt_properties import *
-
-#Globals. Should Clean these up and minimize their usage.
-
-typecodes = ['c','C','s','S','i','I','f','d','t']
-records = dict()
-
-FLTBaseLabel = None
-FLTBaseString = None
-FLTBaseChooser = None
-FLTExport = None
-FLTClose = None
-FLTDoXRef = None
-FLTScale = None
-FLTShadeImport = None
-FLTAttrib = None
-FLTWarn = None
-
-Vector= Blender.Mathutils.Vector
-FLOAT_TOLERANCE = 0.01
-
-FF = flt_filewalker.FileFinder()
-current_layer = 0x01
-
-global_prefs = dict()
-global_prefs['verbose']= 4
-global_prefs['get_texture'] = True
-global_prefs['get_diffuse'] = True
-global_prefs['get_specular'] = False
-global_prefs['get_emissive'] = False
-global_prefs['get_alpha'] = True
-global_prefs['get_ambient'] = False
-global_prefs['get_shininess'] = True
-global_prefs['color_from_face'] = True
-global_prefs['fltfile']= ''
-global_prefs['smoothshading'] = 1
-global_prefs['doxrefs'] = 1
-global_prefs['scale'] = 1.0
-global_prefs['attrib'] = 0
-msg_once = False
-
-reg = Blender.Registry.GetKey('flt_import',1)
-if reg:
- for key in global_prefs:
- if reg.has_key(key):
- global_prefs[key] = reg[key]
-
-
-
-throw_back_opcodes = [2, 73, 4, 11, 96, 14, 91, 98, 63,111] # Opcodes that indicate its time to return control to parent.
-do_not_report_opcodes = [76, 78, 79, 80, 81, 82, 94, 83, 33, 112, 101, 102, 97, 31, 103, 104, 117, 118, 120, 121, 124, 125]
-
-#Process FLT record definitions
-for record in FLT_Records:
- props = dict()
- for prop in FLT_Records[record]:
- position = ''
- slice = 0
- (format,name) = prop.split('!')
- for i in format:
- if i not in typecodes:
- position = position + i
- slice = slice + 1
- else:
- break
- type = format[slice:]
- length = type[1:]
- if len(length) == 0:
- length = 1
- else:
- type = type[0]
- length = int(length)
-
- props[int(position)] = (type,length,prop)
- records[record] = props
-
-def col_to_gray(c):
- return 0.3*c[0] + 0.59*c[1] + 0.11*c[2]
-class MaterialDesc:
- # Was going to use int(f*1000.0) instead of round(f,3), but for some reason
- # round produces better results, as in less dups.
- def make_key(self):
- key = list()
- if global_prefs['get_texture']:
- if self.tex0:
- key.append(self.tex0.getName())
- else:
- key.append(None)
-
- if global_prefs['get_alpha']:
- key.append(round(self.alpha, 3))
- else:
- key.append(None)
-
- if global_prefs['get_shininess']:
- key.append(round(self.shininess, 3))
- else:
- key.append(None)
-
- if global_prefs['get_emissive']:
- key.append(round(self.emissive, 3))
- else:
- key.append(None)
-
- if global_prefs['get_ambient']:
- key.append(round(self.ambient, 3))
- else:
- key.append(None)
-
- if global_prefs['get_specular']:
- for n in self.specular:
- key.append(round(n, 3))
- else:
- key.extend([None, None, None])
-
- if global_prefs['get_diffuse']:
- for n in self.diffuse:
- key.append(round(n, 3))
- else:
- key.extend([None, None, None])
-
-# key.extend(self.face_props.values())
-
- return tuple(key)
-
- def __init__(self):
- self.name = 'Material'
- # Colors, List of 3 floats.
- self.diffuse = [1.0, 1.0, 1.0]
- self.specular = [1.0, 1.0, 1.0]
-
- # Scalars
- self.ambient = 0.0 # [0.0, 1.0]
- self.emissive = 0.0 # [0.0, 1.0]
- self.shininess = 0.5 # Range is [0.0, 2.0]
- self.alpha = 1.0 # Range is [0.0, 1.0]
-
- self.tex0 = None
-
- # OpenFlight Face attributes
- self.face_props = dict.fromkeys(['comment', 'ir color', 'priority',
- 'draw type', 'texture white', 'template billboard',
- 'smc', 'fid', 'ir material', 'lod generation control',
- 'flags', 'light mode'])
-
-class VertexDesc:
- def make_key(self):
- return round(self.x, 6), round(self.y, 6), round(self.z, 6)
-
- def __init__(self):
-
- # Assign later, save memory, all verts have a loc
- self.x = 0.0
- self.y = 0.0
- self.z = 0.0
-
-
- self.nx = 0.0
- self.ny = 0.0
- self.nz = 0.0
-
- self.uv= Vector(0,0)
- self.cindex = 127 #default/lowest
- self.cnorm = False
-
-class LightPointAppDesc:
- def make_key(self):
- d = dict(self.props)
- del d['id']
- del d['type']
-
- if d['directionality'] != 0: # not omni
- d['nx'] = 0.0
- d['ny'] = 0.0
- d['nz'] = 0.0
-
- return tuple(d.values())
-
- def __init__(self):
- self.props = dict()
- self.props.update({'type': 'LPA'})
- self.props.update({'id': 'ap'})
- # Attribs not found in inline lightpoint.
- self.props.update({'visibility range': 0.0})
- self.props.update({'fade range ratio': 0.0})
- self.props.update({'fade in duration': 0.0})
- self.props.update({'fade out duration': 0.0})
- self.props.update({'LOD range ratio': 0.0})
- self.props.update({'LOD scale': 0.0})
-
-class GlobalResourceRepository:
- def request_lightpoint_app(self, desc, scene):
- match = self.light_point_app.get(desc.make_key())
-
- if match:
- return match.getName()
- else:
- # Create empty and fill with properties.
- name = desc.props['type'] + ': ' + desc.props['id']
- object = Blender.Object.New('Empty', name)
- scene.objects.link(object)
- object.Layers= current_layer
- object.sel= 1
-
- # Attach properties
- for name, value in desc.props.iteritems():
- object.addProperty(name, value)
-
- self.light_point_app.update({desc.make_key(): object})
-
- return object.getName()
-
- # Dont use request_vert - faster to make it from the vector direct.
- """
- def request_vert(self, desc):
- match = self.vert_dict.get(desc.make_key())
-
- if match:
- return match
- else:
- vert = Blender.Mathutils.Vector(desc.x, desc.y, desc.z)
- ''' IGNORE_NORMALS
- vert.no[0] = desc.nx
- vert.no[1] = desc.ny
- vert.no[2] = desc.nz
- '''
- self.vert_dict.update({desc.make_key(): vert})
- return vert
- """
- def request_mat(self, mat_desc):
- match = self.mat_dict.get(mat_desc.make_key())
- if match: return match
-
- mat = Blender.Material.New(mat_desc.name)
-
- if mat_desc.tex0 != None:
- mat.setTexture(0, mat_desc.tex0, Blender.Texture.TexCo.UV)
-
- mat.setAlpha(mat_desc.alpha)
- mat.setSpec(mat_desc.shininess)
- mat.setHardness(255)
- mat.setEmit(mat_desc.emissive)
- mat.setAmb(mat_desc.ambient)
- mat.setSpecCol(mat_desc.specular)
- mat.setRGBCol(mat_desc.diffuse)
-
- # Create a text object to store openflight face attribs until
- # user properties can be set on materials.
-# t = Blender.Text.New('FACE: ' + mat.getName())
-#
-# for name, value in mat_desc.face_props.items():
-# t.write(name + '\n' + str(value) + '\n\n')
-
- self.mat_dict.update({mat_desc.make_key(): mat})
-
- return mat
-
- def request_image(self, filename_with_path):
- if not global_prefs['get_texture']: return None
- return BPyImage.comprehensiveImageLoad(filename_with_path, global_prefs['fltfile']) # Use join in case of spaces
-
- def request_texture(self, image):
- if not global_prefs['get_texture']:
- return None
-
- tex = self.tex_dict.get(image.filename)
- if tex: return tex
-
- tex = Blender.Texture.New(Blender.sys.basename(image.filename))
- tex.setImage(image)
- tex.setType('Image')
- self.tex_dict.update({image.filename: tex})
- return tex
-
- def __init__(self):
-
- #list of scenes xrefs belong to.
- self.xrefs = dict()
- # material
- self.mat_dict = dict()
- mat_lst = Blender.Material.Get()
- for mat in mat_lst:
- mat_desc = MaterialDesc()
- mapto_lst = mat.getTextures()
- if mapto_lst[0]:
- mat_desc.tex0 = mapto_lst[0].tex
- else:
- mat_desc.tex0 = None
- mat_desc.alpha = mat.getAlpha()
- mat_desc.shininess = mat.getSpec()
- mat_desc.emissive = mat.getEmit()
- mat_desc.ambient = mat.getAmb()
- mat_desc.specular = mat.getSpecCol()
- mat_desc.diffuse = mat.getRGBCol()
-
- self.mat_dict.update({mat_desc.make_key(): mat})
-
- # texture
- self.tex_dict = dict()
- tex_lst = Blender.Texture.Get()
-
- for tex in tex_lst:
- img = tex.getImage()
- # Only interested in textures with images.
- if img:
- self.tex_dict.update({img.filename: tex})
-
- # vertex
- # self.vert_dict = dict()
-
- # light point
- self.light_point_app = dict()
-
-class Handler:
- def in_throw_back_lst(self, opcode):
- return opcode in self.throw_back_lst
-
- def handle(self, opcode):
- return self.handler[opcode]()
-
- def handles(self, opcode):
- return opcode in self.handler.iterkeys()
-
- def throws_back_all_unhandled(self):
- return self.throw_back_unhandled
-
- def set_throw_back_lst(self, a):
- self.throw_back_lst = a
-
- def set_throw_back_all_unhandled(self):
- self.throw_back_unhandled = True
-
- def set_only_throw_back_specified(self):
- self.throw_back_unhandled = False
-
- def set_handler(self, d):
- self.handler = d
-
- def __init__(self):
- # Dictionary of opcodes to handler methods.
- self.handler = dict()
- # Send all opcodes not handled to the parent node.
- self.throw_back_unhandled = False
- # If throw_back_unhandled is False then only throw back
- # if the opcodes in throw_back are encountered.
- self.throw_back_lst = list()
-
-class Node:
- def blender_import(self):
- if self.opcode in opcode_name and global_prefs['verbose'] >= 2:
- for i in xrange(self.get_level()):
- print ' ',
- print opcode_name[self.opcode],
- print '-', self.props['id'],
- print '-', self.props['comment'],
-
- print
-
- for child in self.children:
- child.blender_import()
-
-# Import comment.
-# if self.props['comment'] != '':
-# name = 'COMMENT: ' + self.props['id']
-# t = Blender.Text.New(name)
-# t.write(self.props['comment'])
-# self.props['comment'] = name
-
- # Always ignore extensions and anything in between them.
- def parse_push_extension(self):
- self.saved_handler = self.active_handler
- self.active_handler = self.extension_handler
- return True
-
- def parse_pop_extension(self):
- self.active_handler = self.saved_handler
- return True
-
- def parse_push(self):
- self.header.fw.up_level()
- # Ignore unknown children.
- self.ignore_unhandled = True
- # Don't do child records that might overwrite parent info. ex: longid
- self.active_handler = self.child_handler
- return True
-
- def parse_pop(self):
- self.header.fw.down_level()
-
- if self.header.fw.get_level() == self.level:
- return False
-
- return True
-
- def parse(self):
- while self.header.fw.begin_record():
- opcode = self.header.fw.get_opcode()
-
- # Print out info on opcode and tree level.
- if global_prefs['verbose'] >= 3:
- p = ''
- for i in xrange(self.header.fw.get_level()):
- p = p + ' '
- if opcode in opcode_name:
- p = p + opcode_name[opcode]
- else:
- if global_prefs['verbose'] >= 1:
- print 'undocumented opcode', opcode
- continue
-
- if self.global_handler.handles(opcode):
- if global_prefs['verbose'] >= 3:
- print p + ' handled globally'
- if self.global_handler.handle(opcode) == False:
- break
-
- elif self.active_handler.handles(opcode):
- if global_prefs['verbose'] >= 4:
- print p + ' handled'
- if self.active_handler.handle(opcode) == False:
- break
-
- else:
- if self.active_handler.throws_back_all_unhandled():
- if global_prefs['verbose'] >= 3:
- print p + ' handled elsewhere'
- self.header.fw.repeat_record()
- break
-
- elif self.active_handler.in_throw_back_lst(opcode):
- if global_prefs['verbose'] >= 3:
- print p + ' handled elsewhere'
- self.header.fw.repeat_record()
- break
-
- else:
- if global_prefs['verbose'] >= 3:
- print p + ' ignored'
- elif global_prefs['verbose'] >= 1 and not opcode in do_not_report_opcodes and opcode in opcode_name:
- print 'not handled'
-
- def get_level(self):
- return self.level
-
- def parse_long_id(self):
- self.props['id'] = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- def parse_comment(self):
- self.props['comment'] = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- def parse_extension(self):
- extension = dict()
- props = records[100]
- propkeys = props.keys()
- propkeys.sort()
- for position in propkeys:
- (type,length,name) = props[position]
- extension[name] = read_prop(self.header.fw,type,length)
- #read extension data.
- dstring = list()
- for i in xrange(self.header.fw.get_length()-24):
- dstring.append(self.header.fw.read_char())
- extension['data'] = dstring
- self.extension = extension
- def parse_record(self):
- self.props['type'] = self.opcode
- props = records[self.opcode]
- propkeys = props.keys()
- propkeys.sort()
- for position in propkeys:
- (type,length,name) = props[position]
- self.props[name] = read_prop(self.header.fw,type,length)
- try: #remove me!
- self.props['id'] = self.props['3t8!id']
- except:
- pass
- def __init__(self, parent, header):
- self.root_handler = Handler()
- self.child_handler = Handler()
- self.extension_handler = Handler()
- self.global_handler = Handler()
-
- self.global_handler.set_handler({21: self.parse_push_extension})
- self.active_handler = self.root_handler
-
- # used by parse_*_extension
- self.extension_handler.set_handler({22: self.parse_pop_extension})
- self.saved_handler = None
-
- self.header = header
- self.children = list()
-
- self.parent = parent
-
- if parent:
- parent.children.append(self)
-
- self.level = self.header.fw.get_level()
- self.opcode = self.header.fw.get_opcode()
-
- self.props = {'id': 'unnamed', 'comment': '', 'type': 'untyped'}
-
-class VertexPalette(Node):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- self.root_handler.set_handler({68: self.parse_vertex_c,
- 69: self.parse_vertex_cn,
- 70: self.parse_vertex_cnuv,
- 71: self.parse_vertex_cuv})
- self.root_handler.set_throw_back_all_unhandled()
-
- self.vert_desc_lst = list()
- self.blender_verts = list()
- self.offset = 8
- # Used to create a map from byte offset to vertex index.
- self.index = dict()
-
-
- def blender_import(self):
- self.blender_verts.extend([Vector(vert_desc.x, vert_desc.y, vert_desc.z) for vert_desc in self.vert_desc_lst ])
-
- def parse_vertex_common(self):
- # Add this vertex to an offset to index dictionary.
- #self.index_lst.append( (self.offset, self.next_index) )
- self.index[self.offset]= len(self.index)
-
- # Get ready for next record.
- self.offset += self.header.fw.get_length()
-
- v = VertexDesc()
-
- self.header.fw.read_ahead(2)
- v.flags = self.header.fw.read_short()
-
- v.x = self.header.fw.read_double()
- v.y = self.header.fw.read_double()
- v.z = self.header.fw.read_double()
-
- return v
-
- def parse_vertex_post_common(self, v):
- #if not v.flags & 0x2000: # 0x2000 = no color
- #if v.flags & 0x1000: # 0x1000 = packed color
- # v.a = self.header.fw.read_uchar()
- # v.b = self.header.fw.read_uchar()
- # v.g = self.header.fw.read_uchar()
- # v.r = self.header.fw.read_uchar()
- #else:
- self.header.fw.read_ahead(4) #skip packed color
- v.cindex = self.header.fw.read_uint()
- self.vert_desc_lst.append(v)
- return True
-
- def parse_vertex_c(self):
- v = self.parse_vertex_common()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cn(self):
- v = self.parse_vertex_common()
- v.cnorm = True
- v.nx = self.header.fw.read_float()
- v.ny = self.header.fw.read_float()
- v.nz = self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cuv(self):
- v = self.parse_vertex_common()
-
- v.uv[:] = self.header.fw.read_float(), self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cnuv(self):
- v = self.parse_vertex_common()
- v.cnorm = True
- v.nx = self.header.fw.read_float()
- v.ny = self.header.fw.read_float()
- v.nz = self.header.fw.read_float()
-
- v.uv[:] = self.header.fw.read_float(), self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse(self): # Run once per import
- Node.parse(self)
-
-
-class InterNode(Node):
- def __init__(self):
- self.object = None
- self.mesh = None
- self.swapmesh = None
- self.hasMesh = False
- self.faceLs= []
- self.matrix = None
- self.vis = True
- self.hasmtex = False
- self.uvlayers = dict()
- self.blayernames = dict()
- self.subfacelevel = 0
- self.extension = None
-
- mask = 2147483648
- for i in xrange(7):
- self.uvlayers[mask] = False
- mask = mask / 2
-
- #######################################################
- ## Begin Remove Doubles Replacement ##
- #######################################################
- def __xvertsort(self,__a,__b):
- (__vert, __x1) = __a
- (__vert2,__x2) = __b
-
- if __x1 > __x2:
- return 1
- elif __x1 < __x2:
- return -1
- return 0
- def __calcFaceNorm(self,__face):
- if len(__face) == 3:
- return Blender.Mathutils.TriangleNormal(__face[0].co, __face[1].co, __face[2].co)
- elif len(__face) == 4:
- return Blender.Mathutils.QuadNormal(__face[0].co, __face[1].co, __face[2].co, __face[3].co)
-
- def __replaceFaceVert(self,__weldface, __oldvert, __newvert):
- __index = None
- for __i, __v in enumerate(__weldface):
- if __v == __oldvert:
- __index = __i
- break
- __weldface[__index] = __newvert
-
- def __matchEdge(self,__weldmesh, __edge1, __edge2):
- if __edge1[0] in __weldmesh['Vertex Disk'][__edge2[1]] and __edge1[1] in __weldmesh['Vertex Disk'][__edge2[0]]:
- return True
- return False
- #have to compare original faces!
- def __faceWinding(self, __weldmesh, __face1, __face2):
-
- __f1edges = list()
- __f2edges = list()
-
- __f1edges.append((__face1.verts[0], __face1.verts[1]))
- __f1edges.append((__face1.verts[1], __face1.verts[2]))
- if len(__face1.verts) == 3:
- __f1edges.append((__face1.verts[2], __face1.verts[0]))
- else:
- __f1edges.append((__face1.verts[2], __face1.verts[3]))
- __f1edges.append((__face1.verts[3], __face1.verts[0]))
-
- __f2edges.append((__face2.verts[0], __face2.verts[1]))
- __f2edges.append((__face2.verts[1], __face2.verts[2]))
- if len(__face2.verts) == 3:
- __f2edges.append((__face2.verts[2], __face2.verts[0]))
- else:
- __f2edges.append((__face2.verts[2], __face2.verts[3]))
- __f2edges.append((__face2.verts[3], __face2.verts[0]))
-
-
- #find a matching edge
- for __edge1 in __f1edges:
- for __edge2 in __f2edges:
- if self.__matchEdge(__weldmesh, __edge1, __edge2): #no more tests nessecary
- return True
-
- return False
-
- def __floatcompare(self, __f1, __f2):
- epsilon = 0.1
- if ((__f1 + epsilon) > __f2) and ((__f1 - epsilon) < __f2):
- return True
- return False
- def __testFace(self,__weldmesh,__v1face, __v2face, __v1bface, __v2bface):
- limit = 0.01
- __matchvert = None
- #frst test (for real this time!). Are the faces the same face?
- if __v1face == __v2face:
- return False
-
- #first test: Do the faces possibly geometrically share more than two vertices? we should be comparing original faces for this? - Yes.....
- __match = 0
- for __vert in __v1bface.verts:
- for __vert2 in __v2bface.verts:
- #if (abs(__vert.co[0] - __vert2.co[0]) <= limit) and (abs(__vert.co[1] - __vert2.co[1]) <= limit) and (abs(__vert.co[2] - __vert2.co[2]) <= limit): #this needs to be fixed!
- if __vert2 in __weldmesh['Vertex Disk'][__vert] or __vert == __vert2:
- __match += 1
- __matchvert = __vert2
- #avoid faces sharing more than two verts
- if __match > 2:
- return False
-
- #consistent winding for face normals
- if __match == 2:
- if not self.__faceWinding(__weldmesh, __v1bface, __v2bface):
- return False
-
- #second test: Compatible normals.Anything beyond almost exact opposite is 'ok'
- __v1facenorm = self.__calcFaceNorm(__v1face)
- __v2facenorm = self.__calcFaceNorm(__v2face)
-
- #dont even mess with zero length faces
- if __v1facenorm.length < limit:
- return False
- if __v2facenorm.length < limit:
- return False
-
- __v1facenorm.normalize()
- __v2facenorm.normalize()
-
- if __match == 1:
- #special case, look for comparison of normals angle
- __angle = Blender.Mathutils.AngleBetweenVecs(__v1facenorm, __v2facenorm)
- if __angle > 70.0:
- return False
-
-
-
- __v2facenorm = __v2facenorm.negate()
-
- if self.__floatcompare(__v1facenorm[0], __v2facenorm[0]) and self.__floatcompare(__v1facenorm[1], __v2facenorm[1]) and self.__floatcompare(__v1facenorm[2], __v2facenorm[2]):
- return False
-
- #next test: dont weld a subface to a non-subface!
- if __v1bface.getProperty("FLT_SFLEVEL") != __v2bface.getProperty("FLT_SFLEVEL"):
- return False
-
- #final test: edge test - We dont want to create a non-manifold edge through our weld operation
-
- return True
-
- def __copyFaceData(self, __source, __target):
- #copy vcolor layers.
- __actColLayer = self.mesh.activeColorLayer
- for __colorlayer in self.mesh.getColorLayerNames():
- self.mesh.activeColorLayer = __colorlayer
- for __i, __col in enumerate(__source.col):
- __target.col[__i].r = __col.r
- __target.col[__i].g = __col.g
- __target.col[__i].b = __col.b
-
- self.mesh.activeColorLayer = __actColLayer
- #copy uv layers.
- __actUVLayer = self.mesh.activeUVLayer
- for __uvlayer in self.mesh.getUVLayerNames():
- self.mesh.activeUVLayer = __uvlayer
- __target.image = __source.image
- __target.mode = __source.mode
- __target.smooth = __source.smooth
- __target.transp = __source.transp
- for __i, __uv in enumerate(__source.uv):
- __target.uv[__i][0] = __uv[0]
- __target.uv[__i][1] = __uv[1]
-
- self.mesh.activeUVLayer = __actUVLayer
- #copy property layers
- for __property in self.mesh.faces.properties:
- __target.setProperty(__property, __source.getProperty(__property))
-
- def findDoubles(self):
- limit = 0.01
- sortblock = list()
- double = dict()
- for vert in self.mesh.verts:
- double[vert] = None
- sortblock.append((vert, vert.co[0] + vert.co[1] + vert.co[2]))
- sortblock.sort(self.__xvertsort)
-
- a = 0
- while a < len(self.mesh.verts):
- (vert,xsort) = sortblock[a]
- b = a+1
- if not double[vert]:
- while b < len(self.mesh.verts):
- (vert2, xsort2) = sortblock[b]
- if not double[vert2]:
- #first test, simple distance
- if (xsort2 - xsort) > limit:
- break
- #second test, more expensive
- if (abs(vert.co[0] - vert2.co[0]) <= limit) and (abs(vert.co[1] - vert2.co[1]) <= limit) and (abs(vert.co[2] - vert2.co[2]) <= limit):
- double[vert2] = vert
- b+=1
- a+=1
-
- return double
-
- def buildWeldMesh(self):
-
- weldmesh = dict()
- weldmesh['Vertex Disk'] = dict() #this is geometric adjacency
- weldmesh['Vertex Faces'] = dict() #topological adjacency
-
- #find the doubles for this mesh
- double = self.findDoubles()
-
- for vert in self.mesh.verts:
- weldmesh['Vertex Faces'][vert] = list()
-
- #create weld faces
- weldfaces = list()
- originalfaces = list()
- for face in self.mesh.faces:
- weldface = list()
- for vert in face.verts:
- weldface.append(vert)
- weldfaces.append(weldface)
- originalfaces.append(face)
- for i, weldface in enumerate(weldfaces):
- for vert in weldface:
- weldmesh['Vertex Faces'][vert].append(i)
- weldmesh['Weld Faces'] = weldfaces
- weldmesh['Original Faces'] = originalfaces
-
- #Now we need to build the vertex disk data. first we do just the 'target' vertices
- for vert in self.mesh.verts:
- if not double[vert]: #its a target
- weldmesh['Vertex Disk'][vert] = list()
- for vert in self.mesh.verts:
- if double[vert]: #its a double
- weldmesh['Vertex Disk'][double[vert]].append(vert)
-
- #Now we need to create the disk information for the remaining vertices
- targets = weldmesh['Vertex Disk'].keys()
- for target in targets:
- for doublevert in weldmesh['Vertex Disk'][target]:
- weldmesh['Vertex Disk'][doublevert] = [target]
- for othervert in weldmesh['Vertex Disk'][target]:
- if othervert != doublevert:
- weldmesh['Vertex Disk'][doublevert].append(othervert)
-
- return weldmesh
-
- def weldFuseFaces(self,weldmesh):
-
- #retain original loose vertices
- looseverts = dict()
- for vert in self.mesh.verts:
- looseverts[vert] = 0
- for edge in self.mesh.edges:
- looseverts[edge.v1] += 1
- looseverts[edge.v2] += 1
-
-
-
- #slight modification here: we need to walk around the mesh as many times as it takes to have no more matches
- done = 0
- while not done:
- done = 1
- for windex, weldface in enumerate(weldmesh['Weld Faces']):
- for vertex in weldface:
- #we walk around the faces of the doubles of this vertex and if possible, we weld them.
- for doublevert in weldmesh['Vertex Disk'][vertex]:
- removeFaces = list() #list of faces to remove from doubleverts face list
- for doublefaceindex in weldmesh['Vertex Faces'][doublevert]:
- doubleface = weldmesh['Weld Faces'][doublefaceindex]
- oface1 = self.mesh.faces[windex]
- oface2 = self.mesh.faces[doublefaceindex]
- ok = self.__testFace(weldmesh, weldface, doubleface, oface1, oface2)
- if ok:
- done = 0
- removeFaces.append(doublefaceindex)
- self.__replaceFaceVert(doubleface, doublevert, vertex)
- for doublefaceindex in removeFaces:
- weldmesh['Vertex Faces'][doublevert].remove(doublefaceindex)
- #old faces first
- oldindices = list()
- for face in self.mesh.faces:
- oldindices.append(face.index)
- #make our new faces.
- newfaces = list()
- for weldface in weldmesh['Weld Faces']:
- newfaces.append(weldface)
- newindices = self.mesh.faces.extend(newfaces, indexList=True, ignoreDups=True)
- #copy custom data over
- for i, newindex in enumerate(newindices):
- try:
- self.__copyFaceData(self.mesh.faces[oldindices[i]], self.mesh.faces[newindex])
- except:
- print "warning, could not copy face data!"
- #delete the old faces
- self.mesh.faces.delete(1, oldindices)
-
- #Clean up stray vertices
- vertuse = dict()
- for vert in self.mesh.verts:
- vertuse[vert] = 0
- for face in self.mesh.faces:
- for vert in face.verts:
- vertuse[vert] += 1
- delverts = list()
- for vert in self.mesh.verts:
- if not vertuse[vert] and vert.index != 0 and looseverts[vert]:
- delverts.append(vert)
-
- self.mesh.verts.delete(delverts)
-
-
- #######################################################
- ## End Remove Doubles Replacement ##
- #######################################################
-
- def blender_import_my_faces(self):
-
- # Add the verts onto the mesh
- blender_verts= self.header.vert_pal.blender_verts
- vert_desc_lst= self.header.vert_pal.vert_desc_lst
-
- vert_list= [ i for flt_face in self.faceLs for i in flt_face.indices] #splitting faces apart. Is this a good thing?
- face_edges= []
- face_verts= []
- self.mesh.verts.extend([blender_verts[i] for i in vert_list])
-
- new_faces= []
- new_faces_props= []
- ngon= BPyMesh.ngon
- vert_index= 1
-
- #add vertex color layer for baked face colors.
- self.mesh.addColorLayer("FLT_Fcol")
- self.mesh.activeColorLayer = "FLT_Fcol"
-
- FLT_OrigIndex = 0
- for flt_face in self.faceLs:
- if flt_face.tex_index != -1:
- try:
- image= self.header.tex_pal[flt_face.tex_index][1]
- except KeyError:
- image= None
- else:
- image= None
- face_len= len(flt_face.indices)
-
- #create dummy uvert dicts
- if len(flt_face.uverts) == 0:
- for i in xrange(face_len):
- flt_face.uverts.append(dict())
- #May need to patch up MTex info
- if self.hasmtex:
- #For every layer in mesh, there should be corresponding layer in the face
- for mask in self.uvlayers.keys():
- if self.uvlayers[mask]:
- if not flt_face.uvlayers.has_key(mask): #Does the face have this layer?
- #Create Layer info for this face
- flt_face.uvlayers[mask] = dict()
- flt_face.uvlayers[mask]['texture index'] = -1
- flt_face.uvlayers[mask]['texture enviorment'] = 3
- flt_face.uvlayers[mask]['texture mapping'] = 0
- flt_face.uvlayers[mask]['texture data'] = 0
-
- #now go through and create dummy uvs for this layer
- for uvert in flt_face.uverts:
- uv = Vector(0.0,0.0)
- uvert[mask] = uv
-
- # Get the indicies in reference to the mesh.
- uvs= [vert_desc_lst[j].uv for j in flt_face.indices]
- if face_len == 1:
- pass
- elif face_len == 2:
- face_edges.append((vert_index, vert_index+1))
- elif flt_face.props['draw type'] == 2 or flt_face.props['draw type'] == 3:
- i = 0
- while i < (face_len-1):
- face_edges.append((vert_index + i, vert_index + i + 1))
- i = i + 1
- if flt_face.props['draw type'] == 2:
- face_edges.append((vert_index + i,vert_index))
- elif face_len == 3 or face_len == 4: # tri or quad
- #if face_len == 1:
- # pass
- #if face_len == 2:
- # face_edges.append((vert_index, vert_index+1))
- new_faces.append( [i+vert_index for i in xrange(face_len)] )
- new_faces_props.append((None, image, uvs, flt_face.uverts, flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,0, flt_face.subfacelevel))
-
- else: # fgon
- mesh_face_indicies = [i+vert_index for i in xrange(face_len)]
- tri_ngons= ngon(self.mesh, mesh_face_indicies)
- if len(tri_ngons) != 1:
- new_faces.extend([ [mesh_face_indicies[t] for t in tri] for tri in tri_ngons])
- new_faces_props.extend( [ (None, image, (uvs[tri[0]], uvs[tri[1]], uvs[tri[2]]), [flt_face.uverts[tri[0]], flt_face.uverts[tri[1]], flt_face.uverts[tri[2]]], flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,1, flt_face.subfacelevel) for tri in tri_ngons ])
-
- vert_index+= face_len
- FLT_OrigIndex+=1
-
- self.mesh.faces.extend(new_faces)
- self.mesh.edges.extend(face_edges)
-
- #add in the FLT_ORIGINDEX layer
- if len(self.mesh.faces):
- try: self.mesh.faceUV= True
- except: pass
-
- if self.mesh.faceUV == True:
- self.mesh.renameUVLayer(self.mesh.activeUVLayer, 'Layer0')
-
- #create name layer for faces
- self.mesh.faces.addPropertyLayer("FLT_ID",Blender.Mesh.PropertyTypes["STRING"])
- #create layer for face color indices
- self.mesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"])
- #create index layer for faces. This is needed by both FGONs and subfaces
- self.mesh.faces.addPropertyLayer("FLT_ORIGINDEX",Blender.Mesh.PropertyTypes["INT"])
- #create temporary FGON flag layer. Delete after remove doubles
- self.mesh.faces.addPropertyLayer("FLT_FGON",Blender.Mesh.PropertyTypes["INT"])
- self.mesh.faces.addPropertyLayer("FLT_SFLEVEL", Blender.Mesh.PropertyTypes["INT"])
-
- for i, f in enumerate(self.mesh.faces):
- props = new_faces_props[i]
- if props[6]['template billboard'] > 0:
- f.transp |= Blender.Mesh.FaceTranspModes["ALPHA"]
- if props[6]['template billboard'] == 2:
- f.mode |= Blender.Mesh.FaceModes["BILLBOARD"]
- f.mode |= Blender.Mesh.FaceModes["LIGHT"]
- if props[6]['draw type'] == 1:
- f.mode |= Blender.Mesh.FaceModes["TWOSIDE"]
-
- #f.mat = props[0]
- f.image = props[1]
- f.uv = props[2]
- #set vertex colors
- color = self.header.get_color(props[5])
- if not color:
- color = [255,255,255,255]
- for mcol in f.col:
- mcol.a = color[3]
- mcol.r = color[0]
- mcol.g = color[1]
- mcol.b = color[2]
-
- f.setProperty("FLT_SFLEVEL", props[9])
- f.setProperty("FLT_ORIGINDEX",i)
- f.setProperty("FLT_ID",props[6]['id'])
- #if props[5] > 13199:
- # print "Warning, invalid color index read in! Using default!"
- # f.setProperty("FLT_COL",127)
- #else:
- if(1): #uh oh....
- value = struct.unpack('>i',struct.pack('>I',props[5]))[0]
- f.setProperty("FLT_COL",value)
-
- #if props[8]:
- # f.setProperty("FLT_FGON",1)
- #else:
- # f.setProperty("FLT_FGON",0)
-
-
- #Create multitex layers, if present.
- actuvlayer = self.mesh.activeUVLayer
- if(self.hasmtex):
- #For every multi-tex layer, we have to add a new UV layer to the mesh
- for i,mask in enumerate(reversed(sorted(self.uvlayers))):
- if self.uvlayers[mask]:
- self.blayernames[mask] = "Layer" + str(i+1)
- self.mesh.addUVLayer(self.blayernames[mask])
-
- #Cycle through availible multi-tex layers and add face UVS
- for mask in self.uvlayers:
- if self.uvlayers[mask]:
- self.mesh.activeUVLayer = self.blayernames[mask]
- for j, f in enumerate(self.mesh.faces):
- if props[6]['draw type'] == 1:
- f.mode |= Blender.Mesh.FaceModes["TWOSIDE"]
- f.transp |= Blender.Mesh.FaceTranspModes["ALPHA"]
- f.mode |= Blender.Mesh.FaceModes["LIGHT"]
- props = new_faces_props[j]
- uvlayers = props[4]
- if uvlayers.has_key(mask): #redundant
- uverts = props[3]
- for k, uv in enumerate(f.uv):
- uv[0] = uverts[k][mask][0]
- uv[1] = uverts[k][mask][1]
-
- uvlayer = uvlayers[mask]
- tex_index = uvlayer['texture index']
- if tex_index != -1:
- try:
- f.image = self.header.tex_pal[tex_index][1]
- except KeyError:
- f.image = None
-
- if global_prefs['smoothshading'] == True and len(self.mesh.faces):
- #We need to store per-face vertex normals in the faces as UV layers and delete them later.
- self.mesh.addUVLayer("FLTNorm1")
- self.mesh.addUVLayer("FLTNorm2")
- self.mesh.activeUVLayer = "FLTNorm1"
- for f in self.mesh.faces:
- f.smooth = 1
- #grab the X and Y components of normal and store them in UV
- for i, uv in enumerate(f.uv):
- vert = f.v[i].index
- vert_desc = vert_desc_lst[vert_list[vert-1]]
- if vert_desc.cnorm:
- uv[0] = vert_desc.nx
- uv[1] = vert_desc.ny
- else:
- uv[0] = 0.0
- uv[1] = 0.0
-
- #Now go through and populate the second UV Layer with the z component
- self.mesh.activeUVLayer = "FLTNorm2"
- for f in self.mesh.faces:
- for i, uv in enumerate(f.uv):
- vert = f.v[i].index
- vert_desc = vert_desc_lst[vert_list[vert-1]]
- if vert_desc.cnorm:
- uv[0] = vert_desc.nz
- uv[1] = 0.0
- else:
- uv[0] = 0.0
- uv[1] = 0.0
-
-
-
- #Finally, go through, remove dummy vertex, remove doubles and add edgesplit modifier.
- Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX'])
- self.mesh.sel= 1
- self.header.scene.update(1) #slow!
-
- #self.mesh.remDoubles(0.0001)
- weldmesh = self.buildWeldMesh()
- welded = self.weldFuseFaces(weldmesh)
- self.mesh.verts.delete(0) # remove the dummy vert
-
- edgeHash = dict()
-
- for edge in self.mesh.edges:
- edgeHash[edge.key] = edge.index
-
-
- if global_prefs['smoothshading'] == True and len(self.mesh.faces):
-
- #rip out the custom vertex normals from the mesh and place them in a face aligned list. Easier to compare this way.
- facenorms = []
- self.mesh.activeUVLayer = "FLTNorm1"
- for face in self.mesh.faces:
- facenorm = []
- for uv in face.uv:
- facenorm.append(Vector(uv[0],uv[1],0.0))
- facenorms.append(facenorm)
- self.mesh.activeUVLayer = "FLTNorm2"
- for i, face in enumerate(self.mesh.faces):
- facenorm = facenorms[i]
- for j, uv in enumerate(face.uv):
- facenorm[j][2] = uv[0]
- self.mesh.removeUVLayer("FLTNorm1")
- self.mesh.removeUVLayer("FLTNorm2")
-
- #find hard edges
- #store edge data for lookup by faces
- #edgeHash = dict()
- #for edge in self.mesh.edges:
- # edgeHash[edge.key] = edge.index
-
- edgeNormHash = dict()
- #make sure to align the edgenormals to key value!
- for i, face in enumerate(self.mesh.faces):
-
- facenorm = facenorms[i]
- faceEdges = []
- faceEdges.append((face.v[0].index,face.v[1].index,facenorm[0],facenorm[1],face.edge_keys[0]))
- faceEdges.append((face.v[1].index,face.v[2].index,facenorm[1],facenorm[2],face.edge_keys[1]))
- if len(face.v) == 3:
- faceEdges.append((face.v[2].index,face.v[0].index,facenorm[2],facenorm[0],face.edge_keys[2]))
- elif len(face.v) == 4:
- faceEdges.append((face.v[2].index,face.v[3].index,facenorm[2],facenorm[3],face.edge_keys[2]))
- faceEdges.append((face.v[3].index,face.v[0].index,facenorm[3],facenorm[0],face.edge_keys[3]))
-
- #check to see if edgeNormal has been placed in the edgeNormHash yet
- #this is a redundant test, and should be optimized to not be called as often as it is.
- for j, faceEdge in enumerate(faceEdges):
- #the value we are looking for is (faceEdge[2],faceEdge[3])
- hashvalue = (faceEdge[2],faceEdge[3])
- if (faceEdge[0],faceEdge[1]) != faceEdge[4]:
- hashvalue = (hashvalue[1],hashvalue[0])
- assert (faceEdge[1],faceEdge[0]) == faceEdge[4]
- if edgeNormHash.has_key(faceEdge[4]):
- #compare value in the hash, if different, mark as sharp
- edgeNorm = edgeNormHash[faceEdge[4]]
- if\
- abs(hashvalue[0][0] - edgeNorm[0][0]) > FLOAT_TOLERANCE or\
- abs(hashvalue[0][1] - edgeNorm[0][1]) > FLOAT_TOLERANCE or\
- abs(hashvalue[0][2] - edgeNorm[0][2]) > FLOAT_TOLERANCE or\
- abs(hashvalue[1][0] - edgeNorm[1][0]) > FLOAT_TOLERANCE or\
- abs(hashvalue[1][1] - edgeNorm[1][1]) > FLOAT_TOLERANCE or\
- abs(hashvalue[1][2] - edgeNorm[1][2]) > FLOAT_TOLERANCE:
- edge = self.mesh.edges[edgeHash[faceEdge[4]]]
- edge.flag |= Blender.Mesh.EdgeFlags.SHARP
-
- else:
- edgeNormHash[faceEdge[4]] = hashvalue
-
- #add in edgesplit modifier
- mod = self.object.modifiers.append(Blender.Modifier.Types.EDGESPLIT)
- mod[Blender.Modifier.Settings.EDGESPLIT_FROM_SHARP] = True
- mod[Blender.Modifier.Settings.EDGESPLIT_FROM_ANGLE] = False
-
- if(actuvlayer):
- self.mesh.activeUVLayer = actuvlayer
-
- def blender_import(self):
- if self.vis and self.parent.object:
- self.vis = self.parent.vis
- name = self.props['id']
-
-
- if self.hasMesh:
- self.mesh = Blender.Mesh.New()
- self.mesh.name = 'FLT_FaceList'
- self.mesh.fakeUser = True
- self.mesh.verts.extend( Vector()) #DUMMYVERT
- self.object = self.header.scene.objects.new(self.mesh)
- else:
- self.object = self.header.scene.objects.new('Empty')
-
- self.object.name = name
- self.header.group.objects.link(self.object)
-
- #id props import
- self.object.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.object.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
-
- if self.extension:
- self.object.properties['FLT']['EXT'] = dict()
- for key in self.extension:
- self.object.properties['FLT']['EXT'][key] = self.extension[key]
-
- if self.parent and self.parent.object and (self.header.scene == self.parent.header.scene):
- self.parent.object.makeParent([self.object],1)
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- if self.vis == False:
- self.object.restrictDisplay = True
- self.object.restrictRender = True
-
- else: #check for LOD children and set the proper flags
- lodlist = list()
- for child in self.children:
- if child.props.has_key('type') and child.props['type'] == 73:
- if child.props['6d!switch out'] != 0.0:
- child.vis = False
- #lodlist.append(child)
-
- #def LODmin(a,b):
- # if a.props['5d!switch in'] < b.props['5d!switch in']:
- # return a
- # return b
-
- #min= None
- #if len(lodlist) > 1:
- # for lod in lodlist:
- # lod.vis = False
- # min = lodlist[0]
- # for i in xrange(len(lodlist)):
- # min= LODmin(min,lodlist[i])
- # min.vis = True
-
-
- Node.blender_import(self) # Attach faces to self.faceLs
-
- if self.hasMesh:
- # Add all my faces into the mesh at once
- self.blender_import_my_faces()
-
- def parse_face(self):
- child = Face(self, self.subfacelevel)
- child.parse()
- return True
-
- def parse_group(self):
- child = Group(self)
- child.parse()
- return True
-
- def move_to_next_layer(self):
- global current_layer
- current_layer = current_layer << 1
- if current_layer > 0x80000:
- current_layer = 1
-
- def parse_lod(self):
- child = LOD(self)
- child.parse()
- return True
-
- def parse_unhandled(self):
- child = Unhandled(self)
- child.parse()
- return True
-
- def parse_object(self):
- child = Object(self)
- child.parse()
- return True
-
- def parse_xref(self):
- child = XRef(self)
- child.parse()
- return True
-
- def parse_dof(self):
- child = DOF(self)
- child.parse()
- return True
-
- def parse_indexed_light_point(self):
- child = IndexedLightPoint(self)
- child.parse()
- return True
-
- def parse_inline_light_point(self):
- child = InlineLightPoint(self)
- child.parse()
- return True
-
- def parse_matrix(self):
- m = list()
- for i in xrange(4):
- m.append([])
- for j in xrange(4):
- f = self.header.fw.read_float()
- m[i].append(f)
- self.matrix = Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3])
-
- def parse_subpush(self):
- self.parse_push()
- self.subfacelevel+= 1
- return True
- def parse_subpop(self):
- self.parse_pop()
- self.subfacelevel -= 1
- return True
-
-
-
-class Face(Node):
- def __init__(self, parent,subfacelevel):
- Node.__init__(self, parent, parent.header)
- self.root_handler.set_handler({31: self.parse_comment,
- 10: self.parse_push,
- 52: self.parse_multitex})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({72: self.parse_vertex_list,
- 10: self.parse_push,
- 11: self.parse_pop,
- 53: self.parse_uvlist})
-
- if parent:
- parent.hasMesh = True
-
- self.subfacelevel = subfacelevel
- self.indices = list() # face verts here
- self.uvlayers = dict() # MultiTexture layers keyed to layer bitmask.
- self.uverts = list() # Vertex aligned list of dictionaries keyed to layer bitmask.
- self.uvmask = 0 # Bitfield read from MTex record
-
- self.comment = ''
- self.props = dict()
- self.props['id'] = self.header.fw.read_string(8)
- # Load face.
- self.props['ir color'] = self.header.fw.read_int()
- self.props['priority'] = self.header.fw.read_short()
- self.props['draw type'] = self.header.fw.read_char()
- self.props['texture white'] = self.header.fw.read_char()
- self.header.fw.read_ahead(4) # color name indices
- self.header.fw.read_ahead(1) # reserved
- self.props['template billboard'] = self.header.fw.read_uchar()
- self.detail_tex_index = self.header.fw.read_short()
- self.tex_index = self.header.fw.read_short()
- self.mat_index = self.header.fw.read_short()
- self.props['smc'] = self.header.fw.read_short()
- self.props['fid'] = self.header.fw.read_short()
- self.props['ir material'] = self.header.fw.read_int()
- self.alpha = 1.0 - float(self.header.fw.read_ushort()) / 65535.0
- self.props['lod generation control'] = self.header.fw.read_uchar()
- self.header.fw.read_ahead(1) # line style index
- self.props['flags'] = self.header.fw.read_int()
- self.props['light mode'] = self.header.fw.read_uchar()
- self.header.fw.read_ahead(7)
- a = self.header.fw.read_uchar()
- b = self.header.fw.read_uchar()
- g = self.header.fw.read_uchar()
- r = self.header.fw.read_uchar()
- self.packed_color = [r, g, b, a]
- a = self.header.fw.read_uchar()
- b = self.header.fw.read_uchar()
- g = self.header.fw.read_uchar()
- r = self.header.fw.read_uchar()
- self.alt_packed_color = [r, g, b, a]
- self.tex_map_index = self.header.fw.read_short()
- self.header.fw.read_ahead(2)
- self.color_index = self.header.fw.read_uint()
- self.alt_color_index = self.header.fw.read_uint()
- #self.header.fw.read_ahead(2)
- #self.shader_index = self.header.fw.read_short()
-
- def parse_comment(self):
- self.comment = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- def blender_import(self):
- vert_count = len(self.indices)
- if vert_count < 1:
- if global_prefs['verbose'] >= 2:
- print 'Warning: Ignoring face with no vertices.'
- return
-
- # Assign material and image
-
- self.parent.faceLs.append(self)
- #need to store comment in mesh prop layer!
-
- # Store comment info in parent.
- #if self.comment != '':
- # if self.parent.props['comment'] != '':
- # self.parent.props['comment'] += '\n\nFrom Face:\n' + self.comment
- # else:
- # self.parent.props['comment'] = self.comment
-
- if self.uvlayers:
- #Make sure that the mesh knows about the layers that this face uses
- self.parent.hasmtex = True
- for mask in self.uvlayers.keys():
- self.parent.uvlayers[mask] = True
-
- def parse_vertex_list(self):
- length = self.header.fw.get_length()
- fw = self.header.fw
- vert_pal = self.header.vert_pal
-
- count = (length-4)/4
-
- # If this ever fails the chunk below does error checking
- self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)]
- '''
- for i in xrange(count):
- byte_offset = fw.read_int()
- if byte_offset in vert_pal.index:
- index = vert_pal.index[byte_offset]
- self.indices.append(index)
- elif global_prefs['verbose'] >= 1:
- print 'Warning: Unable to map byte offset %s' + \
- ' to vertex index.' % byte_offset
- '''
- return True
-
- def parse_multitex(self):
- #Parse MultiTex Record.
- length = self.header.fw.get_length()
- fw = self.header.fw
- #num layers == (length - 8) / 4
- uvmask = fw.read_uint()
- mask = 2147483648
- for i in xrange(7):
- if mask & uvmask:
- uvlayer = dict()
- self.uvlayers[mask] = uvlayer
- mask = mask / 2
-
- #read in record for each individual layer.
- for key in reversed(sorted(self.uvlayers)):
- uvlayer = self.uvlayers[key]
- uvlayer['texture index'] = fw.read_ushort()
- uvlayer['texture enviorment'] = fw.read_ushort()
- uvlayer['texture mapping'] = fw.read_ushort()
- uvlayer['texture data'] = fw.read_ushort()
-
- self.uvmask = uvmask
-
- def parse_uvlist(self):
- #for each uvlayer, add uv vertices
- length = self.header.fw.get_length()
- fw = self.header.fw
- uvmask = fw.read_uint()
- if uvmask != self.uvmask: #This should never happen!
- fw.read_ahead(self.length - 4) #potentially unnessecary?
- else:
- #need to store in uvverts dictionary for each vertex.
- totverts = len(self.indices)
- for i in xrange(totverts):
- uvert = dict()
- for key in reversed(sorted(self.uvlayers)):
- uv = Vector(0.0,0.0)
- uv[0] = fw.read_float()
- uv[1] = fw.read_float()
- uvert[key] = uv
- self.uverts.append(uvert)
-
-class Object(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 21: self.parse_push_extension,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({5: self.parse_face,
- 19: self.parse_subpush,
- 20: self.parse_subpop,
- 111: self.parse_inline_light_point,
- 10: self.parse_push,
- 11: self.parse_pop})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
- self.extension = dict()
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-class Group(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix,
- 21: self.parse_push_extension})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({5: self.parse_face,
- 19: self.parse_subpush,
- 20: self.parse_subpop,
- 111: self.parse_inline_light_point,
- 2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled,
- 14: self.parse_dof,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
-
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
- self.props = dict.fromkeys(['type', 'id', 'comment', 'priority', 'flags', 'special1',
- 'special2', 'significance', 'layer code', 'loop count',
- 'loop duration', 'last frame duration'])
-
- self.props['comment'] = ''
- self.parse_record()
-
- #self.props['type'] = str(self.opcode) + ':' + opcode_name[self.opcode]
- #props = records[self.opcode]
- #propkeys = props.keys()
- #propkeys.sort()
- #for position in propkeys:
- # (type,length,name) = props[position]
- # self.props[name] = read_prop(self.header.fw,type,length)
- #self.props['id'] = self.props['3t8!id']
-
-class DOF(InterNode):
- def blender_import(self):
- InterNode.blender_import(self)
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix,
- 21: self.parse_push_extension})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({#130: self.parse_indexed_light_point,
- 111: self.parse_inline_light_point,
- 2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled,
- 14: self.parse_dof,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-
-class XRef(InterNode):
- def parse(self):
- if self.xref:
- self.xref.parse()
- Node.parse(self)
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
- xref_filename = self.props['3t200!filename'] #I dont even think there is a reason to keep this around...
-
- if not os.path.isabs(xref_filename):
- absname = os.path.join(os.path.dirname(self.header.filename), xref_filename)
- else:
- absname = xref_filename
-
- self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(xref_filename))[0] #this is really wrong as well....
-
- if global_prefs['doxrefs'] and os.path.exists(absname) and not self.header.grr.xrefs.has_key(xref_filename):
- self.xref = Database(absname, self.header.grr, self)
- self.header.grr.xrefs[xref_filename] = self.xref
- else:
- self.xref = None
-
-
- def blender_import(self):
- #name = self.props['type'] + ': ' + self.props['id']
- name = self.props['id']
- self.object = self.header.scene.objects.new('Empty')
- self.object.name = name
- self.object.enableDupGroup = True
- self.header.group.objects.link(self.object)
-
- #for broken links its ok to leave this empty! they purely for visual purposes anyway.....
- try:
- self.object.DupGroup = self.header.grr.xrefs[self.props['3t200!filename']].group
- except:
- pass
-
-
-
-
- if self.parent and self.parent.object:
- self.parent.object.makeParent([self.object],1)
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
-
- #id props import
- self.object.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.object.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
- self.object.Layer = current_layer
- self.object.sel = 1
-
- Node.blender_import(self)
-
-
-class LOD(InterNode):
- def blender_import(self):
- #self.move_to_next_layer()
- InterNode.blender_import(self)
- #self.object.properties['FLT'] = self.props.copy()
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix,
- 21: self.parse_push_extension})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({2: self.parse_group,
- 111: self.parse_inline_light_point,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled, # switch
- 14: self.parse_dof, # DOF
- 91: self.parse_unhandled, # sound
- 98: self.parse_unhandled, # clip
- 63: self.parse_xref})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
-
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-class InlineLightPoint(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 21: self.parse_push_extension,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({72: self.parse_vertex_list,
- 10: self.parse_push,
- 11: self.parse_pop})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
- self.indices = list()
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-
- def blender_import(self):
-
-
- name = self.props['id']
- self.mesh= Blender.Mesh.New()
- self.mesh.name = 'FLT_LP'
- self.object = self.header.scene.objects.new(self.mesh)
- self.object.name = name
- #self.mesh.verts.extend(Vector() ) # DUMMYVERT
- self.object.Layer = current_layer
- self.object.sel= 1
-
- self.object.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.object.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
- if self.extension:
- self.object.properties['FLT']['EXT'] = dict()
- for key in self.extension:
- self.object.properties['FLT']['EXT'][key] = self.extension[key]
-
- if self.parent and self.parent.object and self.header.scene == self.parent.header.scene:
- self.parent.object.makeParent([self.object])
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- self.mesh.verts.extend([self.header.vert_pal.blender_verts[i] for i in self.indices])
-
- #add color index information.
- self.mesh.verts.addPropertyLayer("FLT_VCOL",Blender.Mesh.PropertyTypes["INT"])
- for i, vindex in enumerate(self.indices):
- vdesc = self.header.vert_pal.vert_desc_lst[vindex]
- v = self.mesh.verts[i]
- v.setProperty("FLT_VCOL",vdesc.cindex)
- #for i, v in enumerate(self.mesh.verts):
- # vdesc = self.header.vert_pal.vert_desc_lst[i]
- # v.setProperty("FLT_VCOL",vdesc.cindex)
- self.mesh.update()
-
- def parse_vertex_list(self):
- length = self.header.fw.get_length()
- fw = self.header.fw
- vert_pal = self.header.vert_pal
-
- count = (length-4)/4
-
- # If this ever fails the chunk below does error checking
- self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)]
-
- '''
- for i in xrange(count):
- byte_offset = fw.read_int()
- if byte_offset in vert_pal.index:
- index = vert_pal.index[byte_offset]
- self.indices.append(index)
- elif global_prefs['verbose'] >= 1:
- print 'Warning: Unable to map byte offset %s' + \
- ' to vertex index.' % byte_offset
- '''
-
- return True
-
-
-
-class IndexedLightPoint(InterNode):
- # return dictionary: lp_app name => index list
- def group_points(self, props):
-
- name_to_indices = {}
-
- for i in self.indices:
- vert_desc = self.header.vert_pal.vert_desc_lst[i]
- app_desc = LightPointAppDesc()
- app_desc.props.update(props)
- # add vertex normal and color
- app_desc.props.update({'nx': vert_desc.nx})
- app_desc.props.update({'ny': vert_desc.ny})
- app_desc.props.update({'nz': vert_desc.nz})
-
- app_desc.props.update({'r': vert_desc.r})
- app_desc.props.update({'g': vert_desc.g})
- app_desc.props.update({'b': vert_desc.b})
- app_desc.props.update({'a': vert_desc.a})
-
- app_name = self.header.grr.request_lightpoint_app(app_desc, self.header.scene)
-
- if name_to_indices.get(app_name):
- name_to_indices[app_name].append(i)
- else:
- name_to_indices.update({app_name: [i]})
-
- return name_to_indices
-
- def blender_import(self):
- name = self.props['type'] + ': ' + self.props['id']
-
- name_to_indices = self.group_points(self.header.lightpoint_appearance_pal[self.index])
-
- for app_name, indices in name_to_indices.iteritems():
- self.object = Blender.Object.New('Mesh', name)
- self.mesh= Blender.Mesh.New()
- self.mesh.verts.extend( Vector() ) # DUMMYVERT
- self.object.link(self.mesh)
-
- if self.parent:
- self.parent.object.makeParent([self.object])
-
- for i in indices:
- vert = self.header.vert_pal.blender_verts[i]
- self.mesh.verts.append(vert)
-
- self.header.scene.objects.link(self.object)
-
- self.object.Layer = current_layer
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- # Import comment.
- if self.props['comment'] != '':
- name = 'COMMENT: ' + self.props['id']
- t = Blender.Text.New(name)
- t.write(self.props['comment'])
- self.props['comment'] = name
-
- # Attach properties.
- self.props.update({'appearance': app_name})
- for name, value in self.props.iteritems():
- self.object.addProperty(name, value)
-
- self.mesh.update()
-
- def parse_vertex_list(self):
- length = self.header.fw.get_length()
- fw = self.header.fw
- vert_pal = self.header.vert_pal
-
- count = (length-4)/4
-
- # If this ever fails the chunk below does error checking
- self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)]
-
- '''
- for i in xrange(count):
- byte_offset = fw.read_int()
- if byte_offset in vert_pal.index:
- index = vert_pal.index[byte_offset]
- self.indices.append(index)
- elif global_prefs['verbose'] >= 1:
- print 'Warning: Unable to map byte offset %s' + \
- ' to vertex index.' % byte_offset
- '''
- return True
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({72: self.parse_vertex_list,
- 10: self.parse_push,
- 11: self.parse_pop})
-
- self.indices = list()
-
- self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance'])
- self.props['comment'] = ''
- self.props['type'] = 'Light Point'
- self.props['id'] = self.header.fw.read_string(8)
- self.index = self.header.fw.read_int()
- self.header.fw.read_ahead(4) # animation index
- self.props['draw order'] = self.header.fw.read_int()
-
-class Unhandled(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled, # switch
- 14: self.parse_dof, # DOF
- 91: self.parse_unhandled, # sound
- 98: self.parse_unhandled, # clip
- 63: self.parse_xref})
-
- self.props['id'] = self.header.fw.read_string(8)
-
-class Database(InterNode):
- def blender_import(self):
- for key in self.tex_pal.keys():
- path_filename= FF.find(self.tex_pal[key][0])
- if path_filename != None:
- img = self.grr.request_image(path_filename)
- if img:
- self.tex_pal[key][1] = img
- elif global_prefs['verbose'] >= 1:
- print 'Warning: Unable to find', self.tex_pal[key][0]
-
- self.scene.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.scene.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
- self.scene.properties['FLT']['Main'] = 0
- self.scene.properties['FLT']['Filename'] = self.bname
-
- for child in self.children:
- if child.props.has_key('type') and child.props['type'] == 73:
- if child.props['6d!switch out'] != 0.0:
- child.vis = False
-
- #import color palette
- carray = list()
- for color in self.col_pal:
- carray.append(struct.unpack('>i',struct.pack('>BBBB',color[0],color[1],color[2],color[3]))[0])
- self.scene.properties['FLT']['Color Palette'] = carray
- Node.blender_import(self)
-
- def parse_appearance_palette(self):
- props = dict()
- self.fw.read_ahead(4) # reserved
- props.update({'id': self.fw.read_string(256)})
- index = self.fw.read_int()
- props.update({'smc': self.fw.read_short()})
- props.update({'fid': self.fw.read_short()})
- props.update({'back color: a': self.fw.read_uchar()})
- props.update({'back color: b': self.fw.read_uchar()})
- props.update({'back color: g': self.fw.read_uchar()})
- props.update({'back color: r': self.fw.read_uchar()})
- props.update({'display mode': self.fw.read_int()})
- props.update({'intensity': self.fw.read_float()})
- props.update({'back intensity': self.fw.read_float()})
- props.update({'minimum defocus': self.fw.read_float()})
- props.update({'maximum defocus': self.fw.read_float()})
- props.update({'fading mode': self.fw.read_int()})
- props.update({'fog punch mode': self.fw.read_int()})
- props.update({'directional mode': self.fw.read_int()})
- props.update({'range mode': self.fw.read_int()})
- props.update({'min pixel size': self.fw.read_float()})
- props.update({'max pixel size': self.fw.read_float()})
- props.update({'actual size': self.fw.read_float()})
- props.update({'trans falloff pixel size': self.fw.read_float()})
- props.update({'trans falloff exponent': self.fw.read_float()})
- props.update({'trans falloff scalar': self.fw.read_float()})
- props.update({'trans falloff clamp': self.fw.read_float()})
- props.update({'fog scalar': self.fw.read_float()})
- props.update({'fog intensity': self.fw.read_float()})
- props.update({'size threshold': self.fw.read_float()})
- props.update({'directionality': self.fw.read_int()})
- props.update({'horizontal lobe angle': self.fw.read_float()})
- props.update({'vertical lobe angle': self.fw.read_float()})
- props.update({'lobe roll angle': self.fw.read_float()})
- props.update({'dir falloff exponent': self.fw.read_float()})
- props.update({'dir ambient intensity': self.fw.read_float()})
- props.update({'significance': self.fw.read_float()})
- props.update({'flags': self.fw.read_int()})
- props.update({'visibility range': self.fw.read_float()})
- props.update({'fade range ratio': self.fw.read_float()})
- props.update({'fade in duration': self.fw.read_float()})
- props.update({'fade out duration': self.fw.read_float()})
- props.update({'LOD range ratio': self.fw.read_float()})
- props.update({'LOD scale': self.fw.read_float()})
-
- self.lightpoint_appearance_pal.update({index: props})
-
- def parse_header(self):
- self.props['type'] = 'Header'
- self.props['comment'] = ''
- self.props['id'] = self.fw.read_string(8)
- self.props['version'] = self.fw.read_int()
- self.fw.read_ahead(46)
- self.props['units'] = self.fw.read_char()
- self.props['set white'] = bool(self.fw.read_char())
- self.props['flags'] = self.fw.read_int()
- self.fw.read_ahead(24)
- self.props['projection type'] = self.fw.read_int()
- self.fw.read_ahead(36)
- self.props['sw x'] = self.fw.read_double()
- self.props['sw y'] = self.fw.read_double()
- self.props['dx'] = self.fw.read_double()
- self.props['dy'] = self.fw.read_double()
- self.fw.read_ahead(24)
- self.props['sw lat'] = self.fw.read_double()
- self.props['sw lon'] = self.fw.read_double()
- self.props['ne lat'] = self.fw.read_double()
- self.props['ne lon'] = self.fw.read_double()
- self.props['origin lat'] = self.fw.read_double()
- self.props['origin lon'] = self.fw.read_double()
- self.props['lambert lat1'] = self.fw.read_double()
- self.props['lambert lat2'] = self.fw.read_double()
- self.fw.read_ahead(16)
- self.props['ellipsoid model'] = self.fw.read_int()
- self.fw.read_ahead(4)
- self.props['utm zone'] = self.fw.read_short()
- self.fw.read_ahead(6)
- self.props['dz'] = self.fw.read_double()
- self.props['radius'] = self.fw.read_double()
- self.fw.read_ahead(8)
- self.props['major axis'] = self.fw.read_double()
- self.props['minor axis'] = self.fw.read_double()
-
- if global_prefs['verbose'] >= 1:
- print 'OpenFlight Version:', float(self.props['version']) / 100.0
- print
-
- return True
-
- def parse_mat_palette(self):
- mat_desc = MaterialDesc()
- index = self.fw.read_int()
-
- name = self.fw.read_string(12)
- if len(mat_desc.name) > 0:
- mat_desc.name = name
-
- flag = self.fw.read_int()
- # skip material if not used
- if not flag & 0x80000000:
- return True
-
- ambient_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
- mat_desc.diffuse = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
- mat_desc.specular = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
- emissive_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
-
- mat_desc.shininess = self.fw.read_float() / 64.0 # [0.0, 128.0] => [0.0, 2.0]
- mat_desc.alpha = self.fw.read_float()
-
- # Convert ambient and emissive colors into intensitities.
- mat_desc.ambient = col_to_gray(ambient_col)
- mat_desc.emissive = col_to_gray(emissive_col)
-
- self.mat_desc_pal_lst.append( (index, mat_desc) )
-
- return True
-
- def get_color(self, color_index):
- color = None
- index = color_index / 128
- intensity = float(color_index - 128.0 * index) / 127.0
-
- if index >= 0 and index <= 1023:
- brightest = self.col_pal[index]
- r = int(brightest[0] * intensity)
- g = int(brightest[1] * intensity)
- b = int(brightest[2] * intensity)
- a = int(brightest[3])
-
- color = [r, g, b, a]
-
- return color
-
- def parse_color_palette(self):
- self.header.fw.read_ahead(128)
- for i in xrange(1024):
- a = self.header.fw.read_uchar()
- b = self.header.fw.read_uchar()
- g = self.header.fw.read_uchar()
- r = self.header.fw.read_uchar()
- self.col_pal.append((r, g, b, a))
- return True
-
- def parse_vertex_palette(self):
- self.vert_pal = VertexPalette(self)
- self.vert_pal.parse()
- return True
-
- def parse_texture_palette(self):
- name = self.fw.read_string(200)
- index = self.fw.read_int()
- self.tex_pal[index]= [name, None]
- return True
-
- def read_attribute_files(self):
- for tex in self.tex_pal.keys():
- [name,image] = self.tex_pal[tex]
- basename = os.path.basename(name)
- if(image):
- basename = basename + ".attr"
- dirname = os.path.dirname(Blender.sys.expandpath(image.getFilename())) #can't rely on original info stored in pallette since it might be relative link
- newpath = os.path.join(dirname, basename)
- if os.path.exists(newpath) and not image.properties.has_key('FLT'):
- fw = flt_filewalker.FltIn(newpath)
- fw.read_ahead(8) #We dont care what the attribute file says about x/y dimensions
- image.properties['FLT']={}
-
- #need to steal code from parse records....
- props = records['Image']
- propkeys = props.keys()
- propkeys.sort()
- for position in propkeys:
- (type,length,name) = props[position]
- image.properties['FLT'][name] = read_prop(fw,type,length)
- fw.close_file()
-
- #copy clamp settings
- wrap = image.properties['FLT']['10i!Wrap']
- wrapu = image.properties['FLT']['11i!WrapU']
- wrapv = image.properties['FLT']['12i!WrapV']
-
- if wrapu == 3 or wrapv == 3:
- wrapuv = (wrap,wrap)
- else:
- wrapuv = (wrapu, wrapv)
- image.clampX = wrapuv[0]
- image.clampY = wrapuv[1]
-
- elif not os.path.exists(newpath):
- print "Cannot read attribute file:" + newpath
-
- def __init__(self, filename, grr, parent=None):
- if global_prefs['verbose'] >= 1:
- print 'Parsing:', filename
- print
-
- #check to see if filename is a relative path
- #filename = os.path.abspath(filename)
-
- self.fw = flt_filewalker.FltIn(filename)
- self.filename = filename
- self.bname = os.path.splitext(os.path.basename(filename))[0]
- self.grr = grr
-
- Node.__init__(self, parent, self)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({1: self.parse_header,
- 67: self.parse_vertex_palette,
- 33: self.parse_long_id,
- 31: self.parse_comment,
- 64: self.parse_texture_palette,
- 32: self.parse_color_palette,
- 113: self.parse_mat_palette,
- 128: self.parse_appearance_palette,
- 10: self.parse_push})
- if parent:
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({#130: self.parse_indexed_light_point,
- 111: self.parse_inline_light_point,
- 2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled,
- 14: self.parse_dof,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
-
- self.scene = Blender.Scene.New(self.bname)
- self.group = Blender.Group.New(self.bname)
-
- self.vert_pal = None
- self.lightpoint_appearance_pal = dict()
- self.tex_pal = dict()
- #self.tex_pal_lst = list()
- #self.bl_tex_pal = dict()
- self.col_pal = list()
- self.mat_desc_pal_lst = list()
- self.mat_desc_pal = dict()
- self.props = dict.fromkeys(['id', 'type', 'comment', 'version', 'units', 'set white',
- 'flags', 'projection type', 'sw x', 'sw y', 'dx', 'dy', 'dz', 'sw lat',
- 'sw lon', 'ne lat', 'ne lon', 'origin lat', 'origin lon', 'lambert lat1',
- 'lambert lat2', 'ellipsoid model', 'utm zone', 'radius', 'major axis', 'minor axis'])
-
-
-def clearparent(root,childhash):
- for child in childhash[root]:
- clearparent(child,childhash)
- root.clrParent(2,0)
-
-def fixscale(root,childhash):
- for child in childhash[root]:
- fixscale(child,childhash)
- location = Blender.Mathutils.Vector(root.getLocation('worldspace'))
- if location[0] != 0.0 or location[1] != 0.0 or location[2] != 0.0:
- #direction = Blender.Mathutils.Vector(0-location[0],0-location[1],0-location[2]) #reverse vector
- smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4)
- root.setLocation(location * smat)
- #if its a mesh, we need to scale all of its vertices too
- if root.type == 'Mesh':
- smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4)
- rmesh = root.getData(mesh=True)
- for v in rmesh.verts:
- v.co = v.co * smat
-
-def reparent(root,childhash,sce):
- for child in childhash[root]:
- reparent(child,childhash,sce)
-
- root.makeParent(childhash[root])
- sce.update(1)
-
-def update_scene(root,sdone):
- for object in root.objects:
- if object.DupGroup:
- try:
- child = Blender.Scene.Get(object.DupGroup.name)
- except:
- child = None
- if child and child not in sdone:
- update_scene(child,sdone)
- root.makeCurrent()
- #create a list of children for each object
- childhash = dict()
- for object in root.objects:
- childhash[object] = list()
-
- for object in root.objects:
- if object.parent:
- childhash[object.parent].append(object)
-
- for object in root.objects:
- if not object.parent:
- #recursivley go through and clear all the children of their transformation, starting at deepest level first.
- clearparent(object,childhash)
- #now fix the location of everything
- fixscale(object,childhash)
- #now fix the parenting
- reparent(object,childhash,root)
-
- for object in root.objects:
- object.makeDisplayList()
- root.update(1)
- sdone.append(root)
-
-
-def select_file(filename, grr):
- if not Blender.sys.exists(filename):
- msg = 'Error: File ' + filename + ' does not exist.'
- Blender.Draw.PupMenu(msg)
- return
-
- if not filename.lower().endswith('.flt'):
- msg = 'Error: Not a flight file.'
- Blender.Draw.PupMenu(msg)
- print msg
- print
- return
-
- global_prefs['fltfile']= filename
- global_prefs['verbose']= 1
- global_prefs['get_texture'] = True
- global_prefs['get_diffuse'] = True
- global_prefs['get_specular'] = False
- global_prefs['get_emissive'] = False
- global_prefs['get_alpha'] = True
- global_prefs['get_ambient'] = False
- global_prefs['get_shininess'] = True
- global_prefs['color_from_face'] = True
- global_prefs['log to blender'] = True
-
-
-
- Blender.Window.WaitCursor(True)
- Blender.Window.EditMode(0)
-
-
- FF.add_file_to_search_path(filename)
-
- if global_prefs['verbose'] >= 1:
- print 'Pass 1: Loading.'
- print
-
- load_time = Blender.sys.time()
- db = Database(filename,grr)
- db.parse()
- load_time = Blender.sys.time() - load_time
-
- if global_prefs['verbose'] >= 1:
- print
- print 'Pass 2: Importing to Blender.'
- print
-
- import_time = Blender.sys.time()
- db.blender_import()
-
- if global_prefs['attrib']:
- print "reading attribute files"
- db.read_attribute_files()
-
- Blender.Window.ViewLayer(range(1,21))
-
- update_scene(db.scene,[])
- import_time = Blender.sys.time() - import_time
- if global_prefs['verbose'] >= 1:
- print 'Done.'
- print
- print 'Time to parse file: %.3f seconds' % load_time
- print 'Time to import to blender: %.3f seconds' % import_time
- print 'Total time: %.3f seconds' % (load_time + import_time)
-
- Blender.Window.WaitCursor(False)
-
-def setimportscale(ID,val):
- global global_prefs
- global_prefs['scale'] = val
-def setBpath(fname):
- global_prefs['fltfile'] = fname
- d = dict()
- for key in global_prefs:
- d[key] = global_prefs[key]
- Blender.Registry.SetKey('flt_import', d, 1)
-
-def event(evt,val):
- pass
-
-from Blender.BGL import *
-from Blender import Draw
-
-def but_event(evt):
-
- global FLTBaseLabel
- global FLTBaseString
- global FLTBaseChooser
-
- global FLTExport
- global FLTClose
-
- global FLTDoXRef
- global FLTShadeImport
- global FLTAttrib
-
- global FLTWarn
-
- #Import DB
- if evt == 1:
- if global_prefs['verbose'] >= 1:
- print
- print 'OpenFlight Importer'
- print 'Version:', __version__
- print 'Author: Greg MacDonald, Campbell Barton, Geoffrey Bantle'
- print __url__[2]
- print
-
- GRR = GlobalResourceRepository()
-
- try:
- select_file(global_prefs['fltfile'], GRR)
- except:
- import traceback
- FLTWarn = Draw.PupBlock("Ixport Error", ["See console for output!"])
- traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)
-
- #choose base path for export
- if evt == 4:
- Blender.Window.FileSelector(setBpath, "DB Root", global_prefs['fltfile'])
- #Import custom shading?
- if evt == 9:
- global_prefs['smoothshading'] = FLTShadeImport.val
- #Import Image attribute files
- if evt == 10:
- global_prefs['attrib'] = FLTAttrib.val
- #export XRefs
- if evt == 13:
- global_prefs['doxrefs'] = FLTDoXRef.val
-
- if evt == 2:
- Draw.Exit()
-
- d = dict()
- for key in global_prefs:
- d[key] = global_prefs[key]
- Blender.Registry.SetKey('flt_import', d, 1)
-
-def gui():
-
- global FLTBaseLabel
- global FLTBaseString
- global FLTBaseChooser
-
- global FLTExport
- global FLTClose
-
- global FLTDoXRef
- global FLTShadeImport
-
- global FLTAttrib
-
-
- glClearColor(0.772,0.832,0.847,1.0)
- glClear(GL_COLOR_BUFFER_BIT)
-
- areas = Blender.Window.GetScreenInfo()
- curarea = Blender.Window.GetAreaID()
- curRect = None
-
- for area in areas:
- if area['id'] == curarea:
- curRect = area['vertices']
- break
-
- width = curRect[2] - curRect[0]
- height = curRect[3] - curRect[1]
- cx = 50
- cy = height - 80
-
- FLTBaseLabel = Draw.Label("Base file:",cx,cy,100,20)
- FLTBaseString = Draw.String("",3,cx+100,cy,300,20,global_prefs['fltfile'],255,"Root DB file")
- FLTBaseChooser = Draw.PushButton("...",4,cx+400,cy,20,20,"Choose Folder")
-
- cy = cy-40
- FLTScale = Draw.Number("Import Scale",14,cx,cy,220,20,global_prefs['scale'],0.0,100.0,"Export scaleing factor",setimportscale)
-
- cy = cy-40
- FLTDoXRef = Draw.Toggle("Import XRefs", 13,cx,cy,220,20,global_prefs['doxrefs'],"Import External references")
-
- cy = cy-40
- FLTShadeImport = Draw.Toggle("Import Custom Shading",9,cx,cy,220,20,global_prefs['smoothshading'],"Import custom shading via edgesplit modifiers")
-
- cy = cy-40
- FLTAttrib = Draw.Toggle("Import Attribute Files", 10,cx,cy,220,20,global_prefs['attrib'],"Import Image Attribute files")
-
- cy = cy - 40
- FLTExport = Draw.PushButton("Import",1,cx,20,100,20,"Import FLT Database")
- FLTClose = Draw.PushButton("Close",2,cx+120,20,100,20,"Close Window")
-
-
-
-Draw.Register(gui,event,but_event) \ No newline at end of file
diff --git a/release/scripts/flt_lodedit.py b/release/scripts/flt_lodedit.py
deleted file mode 100644
index 58319b9e525..00000000000
--- a/release/scripts/flt_lodedit.py
+++ /dev/null
@@ -1,502 +0,0 @@
-#!BPY
-
-"""
-Name: 'FLT LOD Editor'
-Blender: 240
-Group: 'Misc'
-Tooltip: 'Level of Detail Edtior for FLT nodes'
-"""
-
-__author__ = "Geoffrey Bantle"
-__version__ = "1.0 11/21/07"
-__email__ = ('scripts', 'Author, ')
-__url__ = ('blender', 'blenderartists.org')
-
-__bpydoc__ ="""\
-This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/FLTools
-"""
-
-# --------------------------------------------------------------------------
-# flt_palettemanager.py version 0.1 2005/04/08
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import Blender.Draw as Draw
-from Blender.BGL import *
-import Blender
-import flt_properties
-reload(flt_properties)
-from flt_properties import *
-
-#event codes
-evcode = {
- "LOD_MAKE" : 100,
- "LOD_DELETE" : 101,
- "LOD_CALC_CENTER" : 102,
- "LOD_GRAB_CENTER" : 103,
- "LOD_X" : 104,
- "LOD_Y" : 105,
- "LOD_Z" : 106,
- "LOD_FREEZE" : 107,
- "LOD_SIG" : 108,
- "LOD_IN" : 109,
- "LOD_OUT" : 110,
- "LOD_TRANS" : 111,
- "LOD_PREVIOUS" : 112
-}
-
-
-#system
-LOD_MAKE = None #PushButton
-LOD_DELETE = None #PushButton
-LOD_CALC_CENTER = None #PushButton
-LOD_GRAB_CENTER = None #Pushbutton
-LOD_FREEZE = None #Toggle
-LOD_PREVIOUS = None #Toggle
-
-LOD_X = None #Input
-LOD_Y = None #Input
-LOD_Z = None #Input
-
-LOD_SIG = None #Input
-LOD_IN = None #Input
-LOD_OUT = None #Input
-LOD_TRANS = None #Input
-
-#labels
-LOD_EDITLABEL = None
-LOD_SWITCHLABEL = None
-LOD_CENTERLABEL = None
-
-LOD_XLABEL = None
-LOD_YLABEL = None
-LOD_ZLABEL = None
-LOD_SIGLABEL = None
-LOD_INLABEL = None
-LOD_OUTLABEL = None
-LOD_TRANSLABEL = None
-
-
-#ID Props
-switch_in = '5d!switch in'
-switch_out = '6d!switch out'
-xco = '10d!X co'
-yco = '11d!Y co'
-zco = '12d!Z co'
-trans = '13d!Transition'
-sig_size = '14d!Sig Size'
-
-#Flags
-lodflag = '9I!flags'
-previous_mask = (1 << 31)
-freeze_mask = (1 << 29)
-
-def update_state():
- state = dict()
- state["activeScene"] = Blender.Scene.GetCurrent()
- state["activeObject"] = state["activeScene"].objects.active
- if state["activeObject"] and not state["activeObject"].sel:
- state["activeObject"] = None
- state["activeMesh"] = None
- if state["activeObject"] and state["activeObject"].type == 'Mesh':
- state["activeMesh"] = state["activeObject"].getData(mesh=True)
-
- state["activeFace"] = None
- if state["activeMesh"]:
- if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
- state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
-
-
- #update editmode
- state["editmode"] = Blender.Window.EditMode()
-
- return state
-
-def idprops_append(object, typecode, props):
- object.properties["FLT"] = dict()
- object.properties["FLT"]['type'] = typecode
- for prop in props:
- object.properties["FLT"][prop] = props[prop]
- object.properties["FLT"]['3t8!id'] = object.name
-
-def idprops_kill():
- state = update_state()
- if state["activeObject"] and state["activeObject"].properties.has_key('FLT'):
- state["activeObject"].properties.pop('FLT')
-
-def idprops_copy(source):
- state = update_state()
- if source.properties.has_key('FLT'):
- for object in state["activeScene"].objects:
- if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
- idprops_kill(object)
- object.properties['FLT'] = dict()
- for key in source.properties['FLT']:
- object.properties['FLT'][key] = source.properties['FLT'][key]
-
-def select_by_typecode(typecode):
- state = update_state()
-
- for object in state["activeScene"].objects:
- if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
- object.select(1)
-
-def idprops_type(object, typecode):
- if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode:
- return True
- return False
-
-#ui type code
-def get_prop(typecode, prop):
-
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], typecode):
- props = state["activeObject"].properties['FLT']
- else:
- props = flt_properties.FLTLOD
-
- return props[prop]
-
-def set_prop(typecode, prop, value):
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"],typecode):
- state["activeObject"].properties['FLT'][prop] = value
-
-
-
-def get_lockmask(mask):
- global lodflag
- state = update_state()
- if state["activeObject"]:
- flag = get_prop(73,lodflag)
- if flag & mask:
- return True
- return False
-
-def set_lockmask(mask):
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], 73):
- oldvalue = state["activeObject"].properties['FLT'][lodflag]
- oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
- oldvalue |= mask
- state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i', struct.pack(">I", oldvalue))[0]
-
-def clear_lockmask(mask):
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], 73):
- oldvalue = state["activeObject"].properties['FLT'][lodflag]
- oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
- oldvalue &= ~mask
- state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i',struct.pack('>I',oldvalue))[0]
-
-def findchildren(object):
- state = update_state()
- children = list()
- for candidate in state["activeScene"].objects:
- if candidate.parent == object:
- children.append(candidate)
- retlist = list(children)
- for child in children:
- retlist = retlist + findchildren(child)
- return retlist
-
-def get_object_center(object):
- bbox = object.getBoundBox(1)
- average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
-
- for point in bbox:
- average[0] += point[0]
- average[1] += point[1]
- average[2] += point[2]
-
- average[0] = average[0] / 8.0
- average[1] = average[1] / 8.0
- average[2] = average[2] / 8.0
-
- return average
-
-
-def calc_center():
-
- global xco
- global yco
- global zco
-
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], 73):
- average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
- children = findchildren(state["activeObject"]) #get children objects
- if children:
- for child in children:
- center = get_object_center(child)
- average[0] += center[0]
- average[1] += center[1]
- average[2] += center[2]
-
- average[0] = average[0] / len(children)
- average[1] = average[1] / len(children)
- average[2] = average[2] / len(children)
-
- set_prop(73, xco, average[0])
- set_prop(73, yco, average[1])
- set_prop(73, zco, average[2])
-
-
-def grab_center():
-
- global xco
- global yco
- global zco
-
- state = update_state()
- if state["activeObject"] and idprops_type(state["activeObject"], 73):
- center = Blender.Window.GetCursorPos()
-
- set_prop(73, xco, center[0])
- set_prop(73, yco, center[1])
- set_prop(73, zco, center[2])
-
-
-def create_lod():
- state = update_state()
- actobj = state["activeObject"]
- if actobj and not idprops_type(actobj, 73):
- idprops_kill()
- idprops_append(actobj,73, flt_properties.FLTLOD)
- calc_center()
-
-
-
-def event(evt,val):
- if evt == Draw.ESCKEY:
- Draw.Exit()
-
-def but_event(evt):
-
- global LOD_MAKE
- global LOD_DELETE
- global LOD_CALC_CENTER
- global LOD_GRAB_CENTER
- global LOD_FREEZE
- global LOD_PREVIOUS
- global LOD_X
- global LOD_Y
- global LOD_Z
- global LOD_SIG
- global LOD_IN
- global LOD_OUT
- global LOD_TRANS
-
- global switch_in
- global switch_out
- global xco
- global yco
- global zco
- global trans
- global sig_size
-
- global lodflag
- global previous_mask
- global freeze_mask
-
- global evcode
-
- #do "system" events
- if evt == evcode["LOD_MAKE"]:
- create_lod()
-
- if evt == evcode["LOD_CALC_CENTER"]:
- calc_center()
-
- if evt == evcode["LOD_DELETE"]:
- idprops_kill()
-
- if evt == evcode["LOD_GRAB_CENTER"]:
- grab_center()
-
- #do mask events
- if evt == evcode["LOD_FREEZE"]:
- if LOD_FREEZE.val == True:
- set_lockmask(freeze_mask)
- else:
- clear_lockmask(freeze_mask)
-
- if evt == evcode["LOD_PREVIOUS"]:
- if LOD_PREVIOUS.val == True:
- set_lockmask(previous_mask)
- else:
- clear_lockmask(previous_mask)
-
- #do input events
- if evt == evcode["LOD_X"]:
- set_prop(73, xco, LOD_X.val)
- if evt == evcode["LOD_Y"]:
- set_prop(73, yco, LOD_Y.val)
- if evt == evcode["LOD_Z"]:
- set_prop(73, zco, LOD_Z.val)
- if evt == evcode["LOD_SIG"]:
- set_prop(73, sig_size, LOD_SIG.val)
- if evt == evcode["LOD_IN"]:
- set_prop(73, switch_in, LOD_IN.val)
- if evt == evcode["LOD_OUT"]:
- set_prop(73, switch_out, LOD_OUT.val)
- if evt == evcode["LOD_TRANS"]:
- set_prop(73, trans, LOD_TRANS.val)
-
-
- Draw.Redraw(1)
- Blender.Window.RedrawAll()
-
-def draw_propsheet(x,y):
-
- global LOD_MAKE
- global LOD_DELETE
- global LOD_CALC_CENTER
- global LOD_GRAB_CENTER
- global LOD_FREEZE
- global LOD_PREVIOUS
- global LOD_X
- global LOD_Y
- global LOD_Z
- global LOD_SIG
- global LOD_IN
- global LOD_OUT
- global LOD_TRANS
-
- #labels
- global LOD_EDITLABEL
- global LOD_SWITCHLABEL
- global LOD_CENTERLABEL
- global LOD_XLABEL
- global LOD_YLABEL
- global LOD_ZLABEL
- global LOD_SIGLABEL
- global LOD_INLABEL
- global LOD_OUTLABEL
- global LOD_TRANSLABEL
-
-
- global switch_in
- global switch_out
- global xco
- global yco
- global zco
- global trans
- global sig_size
-
- global lodflag
- global previous_mask
- global freeze_mask
-
- global evcode
-
-
- global evcode
-
- state = update_state()
-
- label_width = 100
- row_height = 20
- toggle_width = 50
- input_width = 100
- pad = 10
- origx = x
- origy = (row_height * 16) + (pad * 16)
-
-
- #editor label
- x = origx
- y = origy
- LOD_EDITLABEL = Blender.Draw.Label("FLT Level of Detail Editor", x, y, 250, row_height)
-
-
- #Center inputs
- x = origx
- y = y- (row_height + pad)
- LOD_CENTERLABEL = Blender.Draw.Label("LOD center", x, y, label_width, row_height)
- y = y- (row_height + pad)
- LOD_XLABEL = Blender.Draw.Label("X Coordinate", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_X = Blender.Draw.Number("", evcode["LOD_X"], x, y, input_width, row_height,get_prop(73,xco), -1000000.0, 1000000.0, "")
- x = origx
- y = y- (row_height + pad)
- LOD_YLABEL = Blender.Draw.Label("Y Coordinate", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_Y = Blender.Draw.Number("", evcode["LOD_Y"], x, y, input_width, row_height,get_prop(73,yco), -1000000.0, 1000000.0, "")
- x = origx
- y = y- (row_height + pad)
- LOD_ZLABEL = Blender.Draw.Label("Z Coordinate", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_Z = Blender.Draw.Number("", evcode["LOD_Z"], x, y, input_width, row_height,get_prop(73,zco), -1000000.0, 1000000.0, "")
-
-
- #Switch inputs
- x = origx
- y = y- (row_height + pad)
- LOD_SWITCHLABEL = Blender.Draw.Label("Switch Settings", x, y, input_width, row_height)
- y = y- (row_height + pad)
- LOD_SIGLABEL = Blender.Draw.Label("Significant Size", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_SIG = Blender.Draw.Number("", evcode["LOD_SIG"], x, y, input_width, row_height, get_prop(73,sig_size), -1000000.0, 1000000.0, "")
- x = origx
- y = y- (row_height + pad)
- LOD_INLABEL = Blender.Draw.Label("Switch In", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_IN = Blender.Draw.Number("", evcode["LOD_IN"], x, y, input_width, row_height, get_prop(73,switch_in), -1000000.0, 1000000.0, "")
- x = origx
- y = y- (row_height + pad)
- LOD_OUTLABEL = Blender.Draw.Label("Switch Out", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_OUT = Blender.Draw.Number("", evcode["LOD_OUT"], x, y, input_width, row_height, get_prop(73,switch_out), -1000000.0, 1000000.0, "")
- x = origx
- y = y- (row_height + pad)
- LOD_TRANSLABEL = Blender.Draw.Label("Transition", x, y, label_width, row_height)
- x = origx + (label_width + pad)
- LOD_TRANS = Blender.Draw.Number("", evcode["LOD_TRANS"], x, y, input_width, row_height, get_prop(73,trans), -1000000.0, 1000000.0, "")
-
-
- x = origx
- y = y - (row_height + pad)
- LOD_MAKE = Blender.Draw.PushButton("Make LOD", evcode["LOD_MAKE"], x, y, input_width + label_width + pad, row_height, "Make a LOD Node out of Active Object")
- y = y - (row_height + pad)
- LOD_DELETE = Blender.Draw.PushButton("Delete LOD", evcode["LOD_DELETE"], x, y, input_width + label_width + pad, row_height, "Delete the LOD Node properties")
- y = y - (row_height + pad)
- LOD_CALC_CENTER = Blender.Draw.PushButton("Calculate Center", evcode["LOD_CALC_CENTER"], x, y, input_width + label_width + pad, row_height, "Calculate the center of this LOD")
- y = y - (row_height + pad)
- LOD_GRAB_CENTER = Blender.Draw.PushButton("Grab Center", evcode["LOD_GRAB_CENTER"], x, y, input_width + label_width + pad, row_height, "Grab center from 3d cursor")
- y = y - (row_height + pad)
- LOD_FREEZE = Blender.Draw.Toggle("Freeze Center", evcode["LOD_FREEZE"], x, y, input_width + label_width + pad, row_height, get_lockmask(freeze_mask), "")
- y = y - (row_height + pad)
- LOD_PREVIOUS = Blender.Draw.Toggle("Previous Range", evcode["LOD_PREVIOUS"], x, y, input_width + label_width + pad, row_height, get_lockmask(previous_mask), "")
-
-def gui():
- #draw the propsheet/toolbox.
- psheety = 800
- #psheetx = psheety + 10
- draw_propsheet(20,psheety)
-
-Draw.Register(gui,event,but_event)
- \ No newline at end of file
diff --git a/release/scripts/flt_palettemanager.py b/release/scripts/flt_palettemanager.py
deleted file mode 100644
index c2f1380a6fa..00000000000
--- a/release/scripts/flt_palettemanager.py
+++ /dev/null
@@ -1,505 +0,0 @@
-#!BPY
-
-"""
-Name: 'FLT Palette Manager'
-Blender: 240
-Group: 'Misc'
-Tooltip: 'Manage FLT colors'
-"""
-
-__author__ = "Geoffrey Bantle"
-__version__ = "1.0 11/21/2007"
-__email__ = ('scripts', 'Author, ')
-__url__ = ('blender', 'blenderartists.org')
-
-__bpydoc__ ="""\
-
-This script manages colors in OpenFlight databases. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Todo:
--Figure out whats causing the PC speaker to beep when initializing...
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/FLTools
-"""
-
-# --------------------------------------------------------------------------
-# flt_palettemanager.py version 1.0 2005/04/08
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import Blender.Draw as Draw
-from Blender.BGL import *
-import Blender
-import flt_properties
-import flt_defaultp as defaultp
-from flt_properties import *
-
-def RGBtoHSV( r, g, b):
- minc = min( r, g, b )
- maxc = max( r, g, b )
- v = maxc
-
- delta = maxc - minc
-
- if( max != 0 ):
- s = delta / maxc
- else:
- s = 0
- h = -1
- return (h,s,v)
-
- if( r == maxc ):
- h = ( g - b ) / delta
- elif( g == maxc ):
- h = 2 + ( b - r ) / delta
- else:
- h = 4 + ( r - g ) / delta
-
- h *= 60
- if( h < 0 ):
- h += 360
-
- return(h,s,v)
-
-def HSVtoRGB(h,s,v):
-
- if( s == 0 ):
- return (v,v,v)
-
-
- h /= 60
- i = math.floor( h)
- f = h - i
- p = v * ( 1 - s )
- q = v * ( 1 - s * f )
- t = v * ( 1 - s * ( 1 - f ) )
-
- if i == 0:
- r = v
- g = t
- b = p
- elif i == 1:
- r = q
- g = v
- b = p
-
- elif i== 2:
- r = p
- g = v
- b = t
- elif i==3:
- r = p
- g = q
- b = v
- elif i==4:
- r = t
- g = p
- b = v
-
- else:
- r = v
- g = p
- b = q
-
- return(r,g,b)
-
-
-palette_size = 12
-palette_x = 0
-palette_y = 0
-
-colors = list()
-curint = 1.0
-curswatch = 0
-#make a default palette, not very useful.
-cinc = 1.0 / 1024.0
-cstep = 0.0
-picker = None
-ptt = ""
-
-
-ts1=None
-ts2=None
-ts3=None
-ts4=None
-ts5=None
-
-for i in xrange(1024):
- colors.append([cstep,cstep,cstep])
- cstep = cstep + cinc
-def update_state():
- state = dict()
- state["activeScene"] = Blender.Scene.getCurrent()
- state["activeObject"] = state["activeScene"].getActiveObject()
- state["activeMesh"] = None
- if state["activeObject"] and state["activeObject"].type == 'Mesh':
- state["activeMesh"] = state["activeObject"].getData(mesh=True)
-
- state["activeFace"] = None
- if state["activeMesh"]:
- if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
- state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
-
- return state
-
-def pack_face_index(index, intensity):
- return ((127*intensity)+(128*index))
-def unpack_face_index(face_index):
- index = face_index / 128
- intensity = float(face_index - 128.0 * index) / 127.0
- return(index,intensity)
-
-def event(evt,val):
- global palette_size
- global palette_x
- global palette_y
- global colors
- global curint
- global curswatch
-
- areas = Blender.Window.GetScreenInfo()
- curarea = Blender.Window.GetAreaID()
- curRect = None
- editmode = 0
-
- for area in areas:
- if area['id'] == curarea:
- curRect = area['vertices']
- break
-
- if evt == Draw.LEFTMOUSE:
- mval = Blender.Window.GetMouseCoords()
- rastx = mval[0] - curRect[0]
- rasty = mval[1] - curRect[1]
-
- swatchx = (rastx -palette_x) / palette_size #+state["palette_x"]
- swatchy = (rasty -palette_y) / palette_size #+state["palette_y"]
- if rastx > palette_x and rastx < (palette_x + palette_size * 32) and rasty > palette_y and rasty < (palette_y+ palette_size* 32):
- if swatchx < 32 and swatchy < 32:
- curswatch = (swatchx * 32) + swatchy
- Draw.Redraw(1)
-
- elif swatchy < 34 and swatchx < 32:
- curint = 1.0 - (float(rastx-palette_x)/(palette_size*32.0))
- Draw.Redraw(1)
-
- #copy current color and intensity to selected faces.
- elif evt == Draw.VKEY:
-
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
- state = update_state()
-
- #retrieve color from palette
- color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
- actmesh = state["activeMesh"]
- if actmesh:
- if(Blender.Window.GetKeyQualifiers() != Blender.Window.Qual["CTRL"]):
- selfaces = list()
- for face in actmesh.faces:
- if face.sel:
- selfaces.append(face)
-
- if not "FLT_COL" in actmesh.faces.properties:
- actmesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"])
- for face in actmesh.faces:
- face.setProperty("FLT_COL",127) #default
- try:
- actmesh.activeColorLayer = "FLT_Fcol"
- except:
- actmesh.addColorLayer("FLT_Fcol")
- actmesh.activeColorLayer = "FLT_Fcol"
-
-
- for face in selfaces:
- #First append packed index + color and store in face property
- face.setProperty("FLT_COL",int(pack_face_index(curswatch,curint)))
- #Save baked color to face vertex colors
- for col in face.col:
- col.r = int(color[0] * curint)
- col.g = int(color[1] * curint)
- col.b = int(color[2] * curint)
- col.a = int(color[3] * curint)
- else:
- if Blender.Mesh.Mode() == Blender.Mesh.SelectModes['VERTEX']:
- if not 'FLT_VCOL' in actmesh.verts.properties:
- actmesh.verts.addPropertyLayer("FLT_VCOL",Blender.Mesh.PropertyTypes["INT"])
- for vert in actmesh.verts:
- vert.setProperty("FLT_VCOL",127)
- else:
- for vert in actmesh.verts:
- if vert.sel:
- vert.setProperty("FLT_VCOL",int(pack_face_index(curswatch,curint)))
-
- if editmode:
- Blender.Window.EditMode(1)
-
- Blender.Window.RedrawAll()
-
- #grab color and intensity from active face
- elif evt == Draw.CKEY:
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
- state = update_state()
-
- actmesh = state["activeMesh"]
- activeFace = state["activeFace"]
-
-
- if activeFace:
- if not "FLT_COL" in actmesh.faces.properties:
- actmesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"])
- for face in actmesh.faces:
- face.setProperty("FLT_COL",127) #default
- try:
- actmesh.activeColorLayer = "FLT_Fcol"
- except:
- actmesh.addColorLayer("FLT_Fcol")
- actmesh.activeColorLayer = "FLT_Fcol"
- tcol = activeFace.getProperty("FLT_COL")
- (index,intensity) = unpack_face_index(tcol)
- curswatch = index
- curint = intensity
-
- if editmode:
- Blender.Window.EditMode(1)
-
- Blender.Window.RedrawAll()
-
- elif evt == Draw.GKEY:
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode =1
- state = update_state()
-
- actmesh = state["activeMesh"]
- activeFace = state["activeFace"]
-
- if activeFace and "FLT_COL" in actmesh.faces.properties:
- (index,intensity) = unpack_face_index(activeFace.getProperty("FLT_COL"))
- for face in actmesh.faces:
- (index2, intensity2) = unpack_face_index(face.getProperty("FLT_COL"))
- if index == index2:
- face.sel = 1
-
-
- elif evt == Draw.ESCKEY:
- Draw.Exit()
-
- if editmode:
- Blender.Window.EditMode(1)
-
-def update_all():
- global colors
- state = update_state()
- #update the baked FLT colors for all meshes.
- for object in state["activeScene"].objects:
- if object.type == "Mesh":
- mesh = object.getData(mesh=True)
- if 'FLT_COL' in mesh.faces.properties and "FLT_Fcol" in mesh.getColorLayerNames():
- mesh.activeColorLayer = "FLT_Fcol"
- for face in mesh.faces:
- (index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
- color = struct.unpack('>BBBB',struct.pack('>i',colors[index]))
- #update the vertex colors for this face
- for col in face.col:
- col.r = int(color[0] * intensity)
- col.g = int(color[1] * intensity)
- col.b = int(color[2] * intensity)
- col.a = 255
-
-
-def but_event(evt):
- global palette_size
- global palette_x
- global palette_y
- global colors
- global curint
- global curswatch
- global picker
- state = update_state()
-
- if evt == 1:
- if picker.val:
- rval = (int(picker.val[0]*255),int(picker.val[1]*255),int(picker.val[2]*255),255)
- rval = struct.pack('>BBBB',rval[0],rval[1],rval[2],rval[3])
- rval = struct.unpack('>i',rval)
- colors[curswatch] = rval[0]
- #go cd through all meshes and update their FLT colors
- update_all()
-
- Draw.Redraw(1)
-def init_pal():
- global palette_size
- global palette_x
- global palette_y
- global colors
- global curint
- global curswatch
-
- state = update_state()
-
- if not state["activeScene"].properties.has_key('FLT'):
- state["activeScene"].properties['FLT'] = dict()
-
- try:
- colors = state["activeScene"].properties['FLT']['Color Palette']
- except:
- state["activeScene"].properties['FLT']['Color Palette'] = defaultp.pal
- colors = state["activeScene"].properties['FLT']['Color Palette']
-
-def draw_palette():
- global palette_size
- global palette_x
- global palette_y
- global colors
- global curint
- global curswatch
- global picker
- global ts1
- global ts2
- global ts3
- global ts4
- global ts5
-
- state = update_state()
- init_pal()
-
- ssize = palette_size
- xpos = palette_x
- cid = 0
-
- highlight = [(palette_x,palette_y),(palette_x+palette_size,palette_y),(palette_x+palette_size,palette_y+palette_size),(palette_x,palette_y+palette_size)]
- for x in xrange(32):
- ypos = palette_y
- for y in xrange(32):
- color = struct.unpack('>BBBB',struct.pack('>i',colors[cid]))
- glColor3f(color[0]/255.0,color[1]/255.0,color[2]/255.0)
- glBegin(GL_POLYGON)
- glVertex2i(xpos,ypos)
- glVertex2i(xpos+ssize,ypos)
- glVertex2i(xpos+ssize,ypos+ssize)
- glVertex2i(xpos,ypos+ssize)
- glEnd()
-
- if curswatch == cid:
- highlight[0] = (xpos,ypos)
- highlight[1] = (xpos+ssize,ypos)
- highlight[2] = (xpos+ssize,ypos+ssize)
- highlight[3] = (xpos,ypos+ssize)
-
- glColor3f(0.0,0.0,0.0)
- glBegin(GL_LINE_LOOP)
- glVertex2i(xpos,ypos)
- glVertex2i(xpos+ssize,ypos)
- glVertex2i(xpos+ssize,ypos+ssize)
- glVertex2i(xpos,ypos+ssize)
- glVertex2i(xpos,ypos)
- glEnd()
-
-
- cid = cid + 1
- ypos = ypos + ssize
-
- xpos = xpos + ssize
-
- #draw intensity gradient
- color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
- color = [color[0]/255.0,color[1]/255.0,color[2]/255.0]
- colsteps = [color[0]/255.0,color[1]/255.0,color[2]/255.0]
- stripwidth = (palette_size * 32.0) / 256
- strippad = palette_size / 2.0
-
- xpos = palette_x
- grady = (palette_y + (palette_size * 32.0)) + strippad
- for x in xrange(256):
- color[0] = color[0] - colsteps[0]
- color[1] = color[1] - colsteps[1]
- color[2] = color[2] - colsteps[2]
-
- glColor3f(color[0], color[1] ,color[2])
- glBegin(GL_POLYGON)
- glVertex2f(xpos,grady)
- glVertex2f(xpos+stripwidth,grady)
- glVertex2f(xpos+stripwidth,grady+palette_size)
- glVertex2f(xpos,grady+palette_size)
- glEnd()
- xpos = xpos + stripwidth
-
- #draw intensity slider bar
- #xposition == 512 - ((curint) * 512)
- xpos = ((palette_size*32) * (1.0 - curint)) + palette_x
- glColor3f(1.0,1.0,1.0)
- glBegin(GL_LINE_LOOP)
- glVertex2i(int(xpos-6),int(grady-1))
- glVertex2i(int(xpos+6),int(grady-1))
- glVertex2i(int(xpos+6),int(grady+palette_size+1))
- glVertex2i(int(xpos-6),int(grady+palette_size+1))
- #glVertex2i(xpos-6,grady+7)
- glEnd()
-
- #draw color picker
- color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
- pickcol = (color[0]/255.0,color[1]/255.0,color[2]/255.0)
- picker = Blender.Draw.ColorPicker(1,highlight[0][0]+1,highlight[0][1]+1,ssize-2,ssize-2,pickcol,ptt)
-
- #draw highlight swatch
- glColor3f(1.0,1.0,1.0)
- glBegin(GL_LINE_LOOP)
- glVertex2i(highlight[0][0],highlight[0][1])
- glVertex2i(highlight[1][0],highlight[1][1])
- glVertex2i(highlight[2][0],highlight[2][1])
- glVertex2i(highlight[3][0],highlight[3][1])
- glVertex2i(highlight[0][0],highlight[0][1])
- glEnd()
-
- #draw text string explanations
- xpos = palette_size*32+20
- ypos = palette_size*32+10
- glRasterPos2d(xpos,ypos)
- ts1 = Blender.Draw.Text("FLT Palette Manager V 1.0")
- ypos = ypos - 20
- glRasterPos2d(xpos,ypos)
- ts3 = Blender.Draw.Text("CKEY - Copy Active Face Color*")
- ypos = ypos - 20
- glRasterPos2d(xpos,ypos)
- ts2 = Blender.Draw.Text("VKEY - Paste Color to Selected Faces")
- ypos = ypos - 20
- glRasterPos2d(xpos,ypos)
- ts4 = Blender.Draw.Text("GKEY - Select Faces With Same Color")
- ypos = ypos - 15
- glRasterPos2d(xpos,ypos)
- ts5 = Blender.Draw.Text("(*Requires mesh with UV coordinates)", 'small')
-
-def gui():
- glClearColor(0.5,0.5,0.5,1.0)
- glClear(GL_COLOR_BUFFER_BIT)
- draw_palette()
-
-
-init_pal()
-Draw.Register(gui,event,but_event)
- \ No newline at end of file
diff --git a/release/scripts/flt_properties.py b/release/scripts/flt_properties.py
deleted file mode 100644
index b9d93b5f52d..00000000000
--- a/release/scripts/flt_properties.py
+++ /dev/null
@@ -1,630 +0,0 @@
-# flt_properties.py. For setting default OpenFLight ID property types
-# Copyright (C) 2007 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.
-
-__bpydoc__ ="""\
-Utility functions and data defintions used by OpenFlight I/O and tool scripts. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-"""
-
-
-import struct
-
-bitsLSB = [2147483648]
-for i in xrange(31):
- bitsLSB.append(bitsLSB[-1]/2)
-bitsRSB = bitsLSB[:]
-bitsRSB.reverse()
-
-def pack_color(col):
- return struct.pack('>B',col[3]) + struct.pack('>B',col[2]) + struct.pack('>B',col[1]) + struct.pack('>B',col[0])
-
-def unpack_color(col):
- string = struct.pack('>I', col)
- r = struct.unpack('>B',string[3:4])
- g = struct.unpack('>B',string[2:3])
- b = struct.unpack('>B',string[1:2])
- a = struct.unpack('>B',string[0:1])
- return [r,g,b,a]
-
-def reverse_bits(len,num):
- bitbucket = list()
- rval = 0
-
- for i in xrange(len):
- if num & bitsRSB[i]:
- bitbucket.append(1)
- else:
- bitbucket.append(0)
-
- bitbucket.reverse()
-
- for i, bit in enumerate(bitbucket):
- if bit:
- rval |= bitsLSB[i]
-
- return rval
-
-
-opcode_name = { 0: 'db',
- 1: 'head',
- 2: 'grp',
- 4: 'obj',
- 5: 'face',
- 10: 'push',
- 11: 'pop',
- 14: 'dof',
- 19: 'push sub',
- 20: 'pop sub',
- 21: 'push ext',
- 22: 'pop ext',
- 23: 'cont',
- 31: 'comment',
- 32: 'color pal',
- 33: 'long id',
- 49: 'matrix',
- 50: 'vector',
- 52: 'multi-tex',
- 53: 'uv lst',
- 55: 'bsp',
- 60: 'rep',
- 61: 'inst ref',
- 62: 'inst def',
- 63: 'ext ref',
- 64: 'tex pal',
- 67: 'vert pal',
- 68: 'vert w col',
- 69: 'vert w col & norm',
- 70: 'vert w col, norm & uv',
- 71: 'vert w col & uv',
- 72: 'vert lst',
- 73: 'lod',
- 74: 'bndin box',
- 76: 'rot edge',
- 78: 'trans',
- 79: 'scl',
- 80: 'rot pnt',
- 81: 'rot and/or scale pnt',
- 82: 'put',
- 83: 'eyepoint & trackplane pal',
- 84: 'mesh',
- 85: 'local vert pool',
- 86: 'mesh prim',
- 87: 'road seg',
- 88: 'road zone',
- 89: 'morph vert lst',
- 90: 'link pal',
- 91: 'snd',
- 92: 'rd path',
- 93: 'snd pal',
- 94: 'gen matrix',
- 95: 'txt',
- 96: 'sw',
- 97: 'line styl pal',
- 98: 'clip reg',
- 100: 'ext',
- 101: 'light src',
- 102: 'light src pal',
- 103: 'reserved',
- 104: 'reserved',
- 105: 'bndin sph',
- 106: 'bndin cyl',
- 107: 'bndin hull',
- 108: 'bndin vol cntr',
- 109: 'bndin vol orient',
- 110: 'rsrvd',
- 111: 'light pnt',
- 112: 'tex map pal',
- 113: 'mat pal',
- 114: 'name tab',
- 115: 'cat',
- 116: 'cat dat',
- 117: 'rsrvd',
- 118: 'rsrvd',
- 119: 'bounding hist',
- 120: 'rsrvd',
- 121: 'rsrvd',
- 122: 'push attrib',
- 123: 'pop attrib',
- 124: 'rsrvd',
- 125: 'rsrvd',
- 126: 'curv',
- 127: 'road const',
- 128: 'light pnt appear pal',
- 129: 'light pnt anim pal',
- 130: 'indexed lp',
- 131: 'lp sys',
- 132: 'indx str',
- 133: 'shdr pal'}
-
-
-typecodes = ['c','C','s','S','i','I','f','d','t']
-
-FLT_GRP = 2
-FLT_OBJ = 4
-FLT_LOD = 73
-FLT_XRF = 63
-FLT_DOF = 14
-FLT_ILP = 111
-FLT_DB = 1
-FLT_FCE = 5
-
-#not actual opcodes
-FLT_NUL = 0
-FLT_EXP = -1
-
-#valid childtypes for each FLT node type
-FLT_CHILDTYPES = {
- FLT_GRP : [111,2,73,4,14,63],
- FLT_OBJ : [111],
- FLT_LOD : [111,2,73,4,14,63],
- FLT_XRF : [],
- FLT_DOF : [111,2,73,4,14,63],
- FLT_ILP : []
-}
-
-#List of nodes that can have faces as children
-FLT_FACETYPES = [
- FLT_GRP,
- FLT_OBJ,
- FLT_LOD,
- FLT_DOF
-]
-
-def write_prop(fw,type,value,length):
- if type == 'c':
- fw.write_char(value)
- elif type == 'C':
- fw.write_uchar(value)
- elif type == 's':
- fw.write_short(value)
- elif type == 'S':
- fw.write_ushort(value)
- elif type == 'i':
- fw.write_int(value)
- elif type == 'I':
- #NOTE!:
- #there is no unsigned int type in python, but we can only store signed ints in ID props
- newvalue = struct.unpack('>I', struct.pack('>i', value))[0]
- fw.write_uint(newvalue)
- elif type == 'd':
- fw.write_double(value)
- elif type == 'f':
- fw.write_float(value)
- elif type == 't':
- fw.write_string(value,length)
-
-def read_prop(fw,type,length):
- rval = None
- if type == 'c':
- rval = fw.read_char()
- elif type == 'C':
- rval = fw.read_uchar()
- elif type == 's':
- rval = fw.read_short()
- elif type == 'S':
- rval = fw.read_ushort()
- elif type == 'i':
- rval = fw.read_int()
- elif type == 'I':
- rval = fw.read_uint()
- elif type == 'd':
- rval = fw.read_double()
- elif type == 'f':
- rval = fw.read_float()
- elif type == 't':
- rval = fw.read_string(length)
- return rval
-
-
-FLTExt = {
- '3t8!id' : 'Ext',
- '4t8!sid' : '',
- '5c!reserved': 0,
- '6c!revision' : 0,
- '7S!recordcode' : 0
-}
-FLTGroup = {
- '3t8!id' : 'G',
- '4s!priority' : 0,
- '5s!reserved1' : 0,
- '6i!flags' : 0,
- '7s!special1' : 0,
- '8s!special2' : 0,
- '9s!significance' : 0,
- '10c!layer code' : 0,
- '11c!reserved2' : 0,
- '12i!reserved3' : 0,
- '13i!loop count' : 0,
- '14f!loop duration' : 0,
- '15f!last frame duration' : 0
-}
-FLTGroupDisplay = [5,11,12]
-
-FLTObject = {
- '3t8!id' : 'O',
- '4I!flags' : 0,
- '5s!priority' : 0,
- '6S!transp' : 0,
- '7s!SFX1' : 0,
- '8s!SFX2' : 0,
- '9s!significance' : 0,
- '10s!reserved' : 0
-}
-FLTObjectDisplay = [10]
-
-FLTLOD = {
- '3t8!id' : 'L',
- '4i!reserved' : 0,
- '5d!switch in' : 0.0,
- '6d!switch out' : 0.0,
- '7s!sfx ID1' : 0,
- '8s!sfx ID2' : 0,
- '9I!flags' : 0,
- '10d!X co' : 0.0,
- '11d!Y co' : 0.0,
- '12d!Z co' : 0.0,
- '13d!Transition' : 0.0,
- '14d!Sig Size' : 0.0
-}
-FLTLODDisplay = [4]
-
-FLTInlineLP = {
- '3t8!id' : 'Lp',
- '4s!smc' : 0,
- '5s!fid' : 0,
- '6C!back color: a' : 255,
- '7C!back color: b' : 255,
- '8C!back color: g' : 255,
- '9C!back color: r' : 255,
- '10i!display mode' : 0,
- '11f!intensity' : 1.0,
- '12f!back intensity' : 0.0,
- '13f!minimum defocus' : 0.0,
- '14f!maximum defocus' : 1.0,
- '15i!fading mode' : 0,
- '16i!fog punch mode' : 0,
- '17i!directional mode' : 1,
- '18i!range mode' : 0,
- '19f!min pixel size' : 1.0,
- '20f!max pixel size' : 1024,
- '21f!actual size' : 0.25,
- '22f!trans falloff pixel size' : 0.25,
- '23f!trans falloff exponent' : 1.0,
- '24f!trans falloff scalar' : 1.0,
- '25f!trans falloff clamp' : 1.0,
- '26f!fog scalar' : 0.25,
- '27f!fog intensity' : 1.0,
- '28f!size threshold' : 0.1,
- '29i!directionality' : 0,
- '30f!horizontal lobe angle' : 180.0,
- '31f!vertical lobe angle' : 180.0,
- '32f!lobe roll angle' : 0.0,
- '33f!dir falloff exponent' : 1.0,
- '34f!dir ambient intensity' : 0.1,
- '35f!anim period' : 2,
- '36f!anim phase' : 0,
- '37f!anim enabled' : 1.0,
- '38f!significance' : 0.0,
- '39i!draw order' : 0,
- '40I!flags' : 277004288,
- '41f!roti' : 0,
- '42f!rotj' : 0,
- '43f!rotk' : 1.0
-}
-
-FLTInlineLPDisplay = [35,36,37,41,42,43]
-
-FLTXRef = {
- '3t200!filename' : '', #we dont actually use this value on export
- '4i!reserved' : 0,
- '5I!flag' : -478150656,
- '6s!bbox' : 0,
- '7s!reserved' : 0
-}
-
-FLTXRefDisplay = [4,7,3]
-
-FLTDOF = {
- '3t8!id' : 'D',
- '4i!reserved' : 0,
- '5d!ORIGX' : 0.0,
- '6d!ORIGY' : 0.0,
- '7d!ORIGZ' : 0.0,
- '8d!XAXIS-X' : 10.0,
- '9d!XAXIS-Y' : 0.0,
- '10d!XAXIS-Z' : 0.0,
- '11d!XYPLANE-X' : 0.0,
- '12d!XYPLANE-Y' : 10.0,
- '13d!XZPLANE-Z' : 0.0,
- '14d!ZMIN' : 0.0,
- '15d!ZMAX' : 0.0,
- '16d!ZCUR' : 0.0,
- '17d!ZSTEP' : 0.0,
- '18d!YMIN' : 0.0,
- '19d!YMAX' : 0.0,
- '20d!YCUR' : 0.0,
- '21d!YSTEP' : 0.0,
- '22d!XMIN' : 0.0,
- '23d!XMAX' : 0.0,
- '24d!XCUR' : 0.0,
- '25d!XSTEP' : 0.0,
- '26d!PITCH-MIN' : 0.0,
- '27d!PITCH-MAX' : 0.0,
- '28d!PITCH-CUR' : 0.0,
- '29d!PITCH-STEP' : 0.0,
- '30d!ROLL-MIN' : 0.0,
- '31d!ROLL-MAX' : 0.0,
- '32d!ROLL-CUR' : 0.0,
- '33d!ROLL-STEP' : 0.0,
- '34d!YAW-MIN' : 0.0,
- '35d!YAW-MAX' : 0.0,
- '36d!YAW-CUR' : 0.0,
- '37d!YAW-STEP' : 0.0,
- '38d!ZSIZE-MIN' : 0.0,
- '39d!ZSIZE-MAX' : 0.0,
- '40d!ZSIZE-CUR' : 1.0,
- '41d!ZSIZE-STEP' : 0.0,
- '42d!YSIZE-MIN' : 0.0,
- '43d!YSIZE-MAX' : 0.0,
- '44d!YSIZE-CUR' : 1.0,
- '45d!YSIZE-STEP' : 0.0,
- '46d!XSIZE-MIN' : 0.0,
- '47d!XSIZE-MAX' : 0.0,
- '48d!XSIZE-CUR' : 1.0,
- '49d!XSIZE-STEP' : 0.0,
- '50I!FLAG' : 1897582,
- '51i!reserved2' : 0
-}
-
-FLTDOFDisplay = [4]
-
-FLTImage = {
- '3i!RealU Direction' : 0,
- '4i!RealV Direction' : 0,
- '5i!UpX' : 0,
- '6i!UpY' : 0,
- '7i!File Format' : 0,
- '8i!Min Filter' : 6,
- '9i!Mag Filter' : 1,
- '10i!Wrap' : 0,
- '11i!WrapU' : 0,
- '12i!WrapV' : 0,
- '13i!Modified' : 0,
- '14i!PivotX' : 0,
- '15i!PivotY' : 0,
- '16i!Enviorment' : 0,
- '17i!WhiteAlpha' : 0,
- '18i!reserved1' : 0,
- '19i!reserved2' : 0,
- '20i!reserved3' : 0,
- '21i!reserved4' : 0,
- '22i!reserved5' : 0,
- '23i!reserved6' : 0,
- '24i!reserved7' : 0,
- '25i!reserved8' : 0,
- '26i!reserved9' : 0,
- '27d!RealU Direction' : 0,
- '28d!RealV Direction' : 0,
- '29i!Origin' : 0,
- '30i!Kernel no.' : 0,
- '31i!Internal Format' : 0,
- '32i!External Format' : 0,
- '33i!MipMap Filter?' : 0,
- '34f!MMF1' : 0.0,
- '35f!MMF2' : 0.0,
- '36f!MMF3' : 0.0,
- '37f!MMF4' : 0.0,
- '38f!MMF5' : 0.0,
- '39f!MMF6' : 0.0,
- '40f!MMF7' : 0.0,
- '41f!MMF8' : 0.0,
- '42i!Tex CPs?' : 0,
- '43f!LOD0 CP' : 0.0,
- '44f!Scale0 CP' : 0.0,
- '45f!LOD1 CP' : 0.0,
- '46f!Scale1 CP' : 0.0,
- '47f!LOD2 CP' : 0.0,
- '48f!Scale2 CP' : 0.0,
- '49f!LOD3 CP' : 0.0,
- '50f!Scale3 CP' : 0.0,
- '51f!LOD4 CP' : 0.0,
- '52f!Scale4 CP' : 0.0,
- '53f!LOD5 CP' : 0.0,
- '54f!Scale5 CP' : 0.0,
- '55f!LOD6 CP' : 0.0,
- '56f!Scale6 CP' : 0.0,
- '57f!LOD7 CP' : 0.0,
- '58f!Scale7 CP' : 0.0,
- '59f!Control Clamp' : 0.0,
- '60i!Mag Alpha Filter' : 0,
- '61i!Mag Color Filter' : 0,
- '62f!reserved10' : 0,
- '63f!reserved11' : 0,
- '64f!reserved12' : 0,
- '65f!reserved13' : 0,
- '66f!reserved14' : 0,
- '67f!reserved15' : 0,
- '68f!reserved16' : 0,
- '69f!reserved17' : 0,
- '70f!reserved18' : 0,
- '71d!Lambert Central' : 0.0,
- '72d!Lambert Upper' : 0.0,
- '73d!Lambert Lower' : 0.0,
- '74d!reserved19' : 0,
- '75f!reserved20' : 0,
- '76f!reserved21' : 0,
- '77f!reserved22' : 0,
- '78f!reserved23' : 0,
- '79f!reserved24' : 0,
- '80i!Tex Detail?' : 0,
- '81i!Tex J' : 0,
- '82i!Tex K' : 0,
- '83i!Tex M' : 0,
- '84i!Tex N' : 0,
- '85i!Tex Scramble' : 0,
- '86i!Tex Tile?' : 0,
- '87f!Tex Tile LLU' : 0.0,
- '88f!Tex Tile LLV' : 0.0,
- '89f!Tex Tile URU' : 0.0,
- '90f!Tex Tile URV' : 0.0,
- '91i!Projection' : 0,
- '92i!Earth Model' : 0,
- '93i!reserved25' : 0,
- '94i!UTM Zone' : 0,
- '95i!Image Origin' : 0,
- '96i!GPU' : 0,
- '97i!reserved26' : 0,
- '98i!reserved27' : 0,
- '99i!GPU Hemi' : 0,
- '100i!reserved41' : 0,
- '101i!reserved42' : 0,
- '102i!reserved43' : 0,
- '103i!Cubemap' : 0,
- '104t588!reserved44' : '',
- '105t512!Comments' : '',
- '106i!reserved28' : 0,
- '107i!reserved29' : 0,
- '108i!reserved30' : 0,
- '109i!reserved31' : 0,
- '110i!reserved32' : 0,
- '111i!reserved33' : 0,
- '112i!reserved34' : 0,
- '113i!reserved35' : 0,
- '114i!reserved36' : 0,
- '115i!reserved37' : 0,
- '116i!reserved38' : 0,
- '117i!reserved39' : 0,
- '118i!reserved40' : 0,
- '119i!reserved45' : 0,
- '120i!Format Version' : 0,
- '121i!GPU num' : 0,
-}
-
-FLTImageDisplay = [18,19,29,21,22,23,24,25,26,62,63,64,65,66,67,68,69,70,74,75,76,77,78,79,93,97,98,102,114]
-
-FLTHeader = {
- '3t8!id' : 'db',
- '4i!version' : 1620,
- '5i!editversion' : 0,
- '6t32!date' : 0,
- '7s!NGID' : 0,
- '8s!NLID' : 0,
- '9s!NOID' : 0,
- '10s!NFID' : 0,
- '11s!UMULT' : 1,
- '12c!units' : 0,
- '13c!set white' : 0,
- '14I!flags' : 0x80000000,
- '15i!reserved1' : 0,
- '16i!reserved2' : 0,
- '17i!reserved3' : 0,
- '18i!reserved4' : 0,
- '19i!reserved5' : 0,
- '20i!reserved6' : 0,
- '21i!projection type' : 0,
- '22i!reserved7' : 0,
- '23i!reserved8' : 0,
- '24i!reserved9' : 0,
- '25i!reserved10' : 0,
- '26i!reserved11' : 0,
- '27i!reserved12' : 0,
- '28i!reserved13' : 0,
- '29s!NDID' : 0,
- '30s!vstore' : 1,
- '31i!origin' : 0,
- '32d!sw x' : 0,
- '33d!sw y' : 0,
- '34d!dx' : 0,
- '35d!dy' : 0,
- '36s!NSID' : 0,
- '37s!NPID' : 0,
- '38i!reserved14' : 0,
- '39i!reserved15' : 0,
- '40s!NCID' : 0,
- '41s!NTID' : 0,
- '42s!NBID' : 0,
- '43s!NWID' : 0,
- '44i!reserved14' : 0,
- '45d!sw lat' : 0,
- '46d!sw lon' : 0,
- '47d!ne lat' : 0,
- '48d!ne lon' : 0,
- '49d!origin lat' : 0,
- '50d!origin lon' : 0,
- '51d!lambert lat1' : 0,
- '52d!lambert lat2' : 0,
- '53s!NLSID' : 0,
- '54s!NLPID' : 0,
- '55s!NRID' : 0,
- '56s!NCATID' : 0,
- '57s!reserved15' : 0,
- '58s!reserved16' : 0,
- '59s!reserved17' : 0,
- '60s!reserved18' : 0,
- '61i!ellipsoid model' : 1,
- '62s!NAID' : 0,
- '63s!NCVID' : 0,
- '64s!utm zone' : 0,
- '65t6!reserved19' : 0,
- '66d!dz' : 0,
- '67d!radius' : 0,
- '68S!NMID' : 0,
- '69S!NLPSID' : 0,
- '70i!reserved20' : 0,
- '71d!major axis' : 0,
- '72d!minor axis' : 0,
-}
-
-FLT_Records = {
- 2 : FLTGroup,
- 4 : FLTObject,
- 73 : FLTLOD,
- 63 : FLTXRef,
- 14 : FLTDOF,
- 1 : FLTHeader,
- 111 : FLTInlineLP,
- 100 : FLTExt,
- 'Image' : FLTImage
-}
-
-def process_recordDefs():
- records = dict()
- for record in FLT_Records:
- props = dict()
- for prop in FLT_Records[record]:
- position = ''
- slice = 0
- (format,name) = prop.split('!')
- for i in format:
- if i not in typecodes:
- position = position + i
- slice = slice + 1
- else:
- break
- type = format[slice:]
- length = type[1:]
- if len(length) == 0:
- length = 1
- else:
- type = type[0]
- length = int(length)
-
- props[int(position)] = (type,length,prop)
- records[record] = props
- return records
-
-
diff --git a/release/scripts/flt_toolbar.py b/release/scripts/flt_toolbar.py
deleted file mode 100644
index a707b87f846..00000000000
--- a/release/scripts/flt_toolbar.py
+++ /dev/null
@@ -1,809 +0,0 @@
-#!BPY
-
-"""
-Name: 'FLT Toolbar'
-Blender: 240
-Group: 'Misc'
-Tooltip: 'Tools for working with FLT databases'
-"""
-
-__author__ = "Geoffrey Bantle"
-__version__ = "1.0 11/21/07"
-__email__ = ('scripts', 'Author, ')
-__url__ = ('blender', 'blenderartists.org')
-
-__bpydoc__ ="""\
-This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/FLTools
-"""
-
-# --------------------------------------------------------------------------
-# flt_palettemanager.py version 0.1 2005/04/08
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import Blender.Draw as Draw
-from Blender.BGL import *
-import Blender
-import flt_properties
-reload(flt_properties)
-from flt_properties import *
-
-xrefprefix = ""
-xrefstack = list()
-vofsstack = list()
-vquatstack = list()
-prop_w = 256
-prop_h = 256
-
-
-#event codes
-evcode = {
- "XREF_MAKE" : 100,
- "XREF_EDIT" : 101,
- "XREF_FILE" : 102,
- "XREF_PICK" : 103,
- "XREF_SELECT" : 104,
- "XREF_POP" : 105,
- "XREF_PREFIX" : 106,
- "FACE_NAME" : 200,
- "FACE_MAKESUB" : 201,
- "FACE_KILLSUB" : 202,
- "FACE_SELSUB" : 203,
- "SCENE_UPDATE" : 303,
- "IDPROP_COPY" : 501,
- "IDPROP_KILL" : 502,
- "CLIGHT_MAKE" : 700,
- "DFROMACT" : 701,
- "FIXCOL" : 702
-}
-
-XREF_PREFIX = None
-XREF_MAKE = None
-XREF_EDIT = None
-XREF_SELECT = None
-XREF_POP = None
-FACE_MAKESUB = None
-FACE_SELSUB = None
-FACE_KILLSUB = None
-IDPROP_KILL = None
-IDPROP_COPY = None
-SCENE_UPDATE = None
-CLIGHT_MAKE = None
-DFROMACT = None
-FIXCOL = None
-
-
-def RGBtoHSV( r, g, b):
- cmin = min( r, g, b )
- cmax = max( r, g, b )
- v = cmax
-
- if(cmax!=0.0):
- s = (cmax-cmin)/cmax
- else:
- s = 0.0
- h = 0.0
-
- if(s == 0.0):
- h = -1.0
- else:
- cdelta = cmax-cmin
- rc = (cmax-r)/cdelta
- gc = (cmax-g)/cdelta
- bc = (cmax-b)/cdelta
- if(r==cmax):
- h = bc-gc
- else:
- if(g==cmax):
- h = 2.0+rc-bc
- else:
- h = 4.0+gc-rc
- h = h*60.0
- if(h<0.0):
- h += 360.0
-
-
- h = h/360.0
- if(h < 0.0):
- h = 0.0
- return (h,s,v)
-
-
-def update_state():
- state = dict()
- state["activeScene"] = Blender.Scene.GetCurrent()
- state["activeObject"] = state["activeScene"].objects.active
- if state["activeObject"] and not state["activeObject"].sel:
- state["activeObject"] = None
- state["activeMesh"] = None
- if state["activeObject"] and state["activeObject"].type == 'Mesh':
- state["activeMesh"] = state["activeObject"].getData(mesh=True)
-
- state["activeFace"] = None
- if state["activeMesh"]:
- if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
- state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
-
- #update editmode
- state["editmode"] = Blender.Window.EditMode()
-
- return state
-def pack_face_index(index, intensity):
- return ((127*intensity)+(128*index))
-def unpack_face_index(face_index):
- index = face_index / 128
- intensity = float(face_index - 128.0 * index) / 127.0
- return(index,intensity)
-
-def idprops_append(object, typecode, props):
- object.properties["FLT"] = dict()
- object.properties["FLT"]['type'] = typecode
- for prop in props:
- object.properties["FLT"][prop] = props[prop]
- object.properties["FLT"]['3t8!id'] = object.name
-
-def idprops_kill(object):
- state = update_state()
- if object and object.properties.has_key('FLT'):
- object.properties.pop('FLT')
-
-def idprops_copy(source):
- state = update_state()
- if source.properties.has_key('FLT'):
- for object in state["activeScene"].objects:
- if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
- idprops_kill(object)
- object.properties['FLT'] = dict()
- for key in source.properties['FLT']:
- object.properties['FLT'][key] = source.properties['FLT'][key]
-
-def unpack_color(color):
- return struct.unpack('>BBBB',struct.pack('>I',color))
-
-
-def findColorKey(colordict, hsv):
- hdelta = 0.001
- for key in colordict:
- if not (((hsv[0] < (key[0] + hdelta)) and (hsv[0] > (key[0] - hdelta))) and ((hsv[1] < (key[1] + hdelta)) and (hsv[1] > (key[1] - hdelta)))):
- return key
- return None
-
-def hsvsort(a, b):
- (index1, mag1) = a
- (index2, mag2) = b
- if mag1 > mag2:
- return 1
- elif mag1 < mag2:
- return -1
- return 0
-
-def fix_colors():
-
- editmode = 0
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
- state = update_state()
-
- scene = state["activeScene"]
- colors = None
- if state["activeScene"].properties.has_key('FLT'):
- try:
- colors = state["activeScene"].properties['FLT']['Color Palette']
- except:
- pass
- if not colors:
- return
-
- #first build a HSV version of our palette
- hsvpalette = list()
- for swatch in colors:
- color = unpack_color(swatch)
- hsv = RGBtoHSV(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0)
- hsvpalette.append(hsv)
-
- #collect all of our meshes
- meshes = list()
- for object in scene.objects.context:
- if object.sel and object.type == 'Mesh':
- mesh = object.getData(mesh=True)
- if "FLT_COL" in mesh.faces.properties:
- meshes.append(mesh)
-
-
- #Now go through our meshes, and build a dictionary of face lists keyed according to (hue,saturation) of the baked color
- colordict = dict()
- for mesh in meshes:
- for face in mesh.faces:
- hsv = RGBtoHSV(face.col[0].r/255.0, face.col[0].g/255.0, face.col[0].b/255.0) #retrieve baked color
- if colordict.has_key((hsv[0],hsv[1])):
- colordict[(hsv[0],hsv[1])].append(face)
- else:
- colordict[(hsv[0],hsv[1])] = [face]
-
-
- #for each color key in the color dict, build a list of distances from it to the values in hsvpalette and then quicksort them for closest match
- for key in colordict:
- maglist = list()
- for i, hsv in enumerate(hsvpalette):
- norm = Blender.Mathutils.Vector(hsv[0], hsv[1]) - Blender.Mathutils.Vector(key[0],key[1])
- maglist.append((i,norm.length))
- maglist.sort(hsvsort)
- print maglist[0]
- for face in colordict[key]:
- (index, intensity) = unpack_face_index(face.getProperty("FLT_COL"))
- newfindex = pack_face_index(maglist[0][0],intensity)
- face.setProperty("FLT_COL", int(newfindex))
-
- for mesh in meshes:
- update_mesh_colors(colors,mesh)
-
- if editmode:
- Blender.Window.EditMode(1)
-
-
-def update_mesh_colors(colors, mesh):
- if 'FLT_COL' in mesh.faces.properties:
- mesh.activeColorLayer = "FLT_Fcol"
- for face in mesh.faces:
- (index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
- color = struct.unpack('>BBBB',struct.pack('>I',colors[index]))
-
- if index == 0 and intensity == 0:
- color = (255,255,255)
- intensity = 1.0
- #update the vertex colors for this face
- for col in face.col:
- col.r = int(color[0] * intensity)
- col.g = int(color[1] * intensity)
- col.b = int(color[2] * intensity)
- col.a = 255
-
-
-def update_all():
-
- editmode = 0
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
- state = update_state()
- colors = None
- if state["activeScene"].properties.has_key('FLT'):
- try:
- colors = state["activeScene"].properties['FLT']['Color Palette']
- except:
- pass
- if colors:
- #update the baked FLT colors for all meshes.
- for object in state["activeScene"].objects:
- if object.type == "Mesh":
- mesh = object.getData(mesh=True)
- update_mesh_colors(colors,mesh)
- if editmode:
- Blender.Window.EditMode(1)
-
-#Change this to find the deep parent
-def xref_create():
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- state = update_state()
-
- def findchildren(object):
- children = list()
- for candidate in state["activeScene"].objects:
- if candidate.parent == object:
- children.append(candidate)
- retlist = list(children)
- for child in children:
- retlist = retlist + findchildren(child)
- return retlist
-
- actObject = state["activeObject"]
- if actObject and xrefprefix:
- scenenames = list()
- for scene in Blender.Scene.Get():
- scenenames.append(scene.name)
-
- if xrefprefix in scenenames:
- #build a unique name for the xref...
- suffix = 1
- found = False
- while not found:
- candidate = xrefprefix + str(suffix)
- if not candidate in scenenames:
- xrefname = candidate
- found = True
- suffix+=1
- else:
- xrefname = xrefprefix
- #create our XRef node
- xnode = state["activeScene"].objects.new('Empty')
- xnode.name = 'X:' + xrefname
- xnode.properties['FLT'] = dict()
- for prop in FLTXRef:
- xnode.properties['FLT'][prop] = FLTXRef[prop]
- xnode.properties['FLT']['3t200!filename'] = xrefname + '.flt'
- xnode.properties['FLT']['type'] = 63
- xnode.enableDupGroup = True
- xnode.DupGroup = Blender.Group.New(xrefname) #this is dangerous... be careful!
-
- #copy rot and loc of actObject
- xnode.setLocation(actObject.getLocation())
- xnode.setEuler(actObject.getEuler())
-
- #build the new scene
- xrefscene = Blender.Scene.New(xrefname)
- xrefscene.properties['FLT'] = dict()
- xrefscene.properties['FLT']['Filename'] = xrefname
- xrefscene.properties['FLT']['Main'] = 0
-
- #find the children of actObject so that we can add them to the group
- linkobjects = findchildren(actObject)
- linkobjects.append(actObject)
- for object in linkobjects:
- xrefscene.objects.link(object)
- state["activeScene"].objects.unlink(object)
- xnode.DupGroup.objects.link(object)
- #clear rotation of actObject and location
- actObject.setLocation(0.0,0.0,0.0)
- actObject.setEuler(0.0,0.0,0.0)
-
- xrefscene.update(1)
- state["activeScene"].update(1)
-
-def xref_select():
- state = update_state()
- candidates = list()
- scenelist = [scene.name for scene in Blender.Scene.Get()]
- for object in state["activeScene"].objects:
- if object.type == 'Empty' and object.enableDupGroup == True and object.DupGroup:
- candidates.append(object)
-
- for object in candidates:
- if object.DupGroup.name in scenelist:
- object.sel = 1
-
-def xref_edit():
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- state = update_state()
-
- actObject = state["activeObject"]
-
- if actObject and actObject.type == 'Empty' and actObject.DupGroup:
-# if actObject.properties.has_key('FLT') and actObject.properties['FLT']['type'] == 63:
- for FLTscene in Blender.Scene.Get():
- if FLTscene.properties.has_key('FLT') and FLTscene.name == actObject.DupGroup.name:
- actObject.sel = 0
- xrefstack.append(state["activeScene"])
- vofsstack.append(Blender.Window.GetViewOffset())
- vquatstack.append(Blender.Window.GetViewQuat())
- FLTscene.makeCurrent()
- Blender.Window.SetViewOffset(0.0,0.0,0.0)
-
-def xref_finish():
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- state = update_state()
- if xrefstack:
- scene = xrefstack.pop()
- Blender.Window.SetViewQuat(vquatstack.pop())
- Blender.Window.SetViewOffset(vofsstack.pop())
- scene.makeCurrent()
-
-
-def sortSub(a,b):
- aindex = a.getProperty("FLT_ORIGINDEX")
- bindex = b.getProperty("FLT_ORIGINDEX")
-
- if aindex > bindex:
- return 1
- elif aindex < bindex:
- return -1
- return 0
-
-def subface_make():
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- editmode = 0
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
-
- state = update_state()
-
- actmesh = state["activeMesh"]
- activeFace = state["activeFace"]
- if actmesh:
- if not "FLT_ORIGINDEX" in actmesh.faces.properties:
- actmesh.faces.addPropertyLayer("FLT_ORIGINDEX",Blender.Mesh.PropertyTypes["INT"])
- for i, face in enumerate(actmesh.faces):
- face.setProperty("FLT_ORIGINDEX",i)
- if not "FLT_SFLEVEL" in actmesh.faces.properties:
- actmesh.faces.addPropertyLayer("FLT_SFLEVEL",Blender.Mesh.PropertyTypes["INT"])
-
- #attach the subfaces to the active face. Note, this doesnt really work 100 percent properly yet, just enough for one level!
- if activeFace:
- #steps:
- #remove actface and selected faces from the facelist
- #quicksort facelist
- #append actface and subfaces to end of facelist.
- #generate new indices
- facelist = list()
- sublist = list()
- for face in actmesh.faces:
- facelist.append(face)
- for face in facelist:
- if face == activeFace:
- face.setProperty("FLT_SFLEVEL",0)
- sublist.insert(0,face)
- elif face.sel:
- face.setProperty("FLT_SFLEVEL",1)
- sublist.append(face)
- for face in sublist:
- facelist.remove(face)
- facelist.sort(sortSub)
- for face in sublist:
- facelist.append(face)
- for i, face in enumerate(facelist):
- face.setProperty("FLT_ORIGINDEX",i)
- else:
- pass
-
- if editmode:
- Blender.Window.EditMode(1)
-
-def subface_kill():
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- editmode = 0
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
- state = update_state()
-
- actmesh = state["activeMesh"]
- if actmesh:
- if "FLT_ORIGINDEX" in actmesh.faces.properties and "FLT_SFLEVEL" in actmesh.faces.properties:
- for i,face in enumerate(actmesh.faces):
- face.setProperty("FLT_ORIGINDEX",i)
- face.setProperty("FLT_SFLEVEL",0)
- if editmode:
- Blender.Window.EditMode(1)
-
-def subface_select():
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- editmode = 0
- if Blender.Window.EditMode():
- Blender.Window.EditMode(0)
- editmode = 1
- state = update_state()
-
- actmesh = state["activeMesh"]
- activeFace = state["activeFace"]
- if actmesh and activeFace:
- if "FLT_ORIGINDEX" in actmesh.faces.properties and "FLT_SFLEVEL" in actmesh.faces.properties:
- facelist = list()
- actIndex = None
- sublevel = None
- for face in actmesh.faces:
- facelist.append(face)
- facelist.sort(sortSub)
- for i, face in enumerate(facelist):
- if face == activeFace:
- actIndex = i
- sublevel = face.getProperty("FLT_SFLEVEL")+1
- break
- leftover = facelist[actIndex+1:]
- for face in leftover:
- if face.getProperty("FLT_SFLEVEL") == sublevel:
- face.sel = 1
- else:
- break
- if editmode:
- Blender.Window.EditMode(1)
-
-def select_by_typecode(typecode):
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
-
- state = update_state()
-
- for object in state["activeScene"].objects:
- if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
- object.select(1)
-def clight_make():
- state = update_state()
- actmesh = state["activeMesh"]
- actobj = state["activeObject"]
-
- if actobj and actmesh:
- actobj.properties['FLT'] = dict()
- actobj.properties['FLT']['type'] = 111
- for prop in FLTInlineLP:
- actobj.properties['FLT'][prop] = FLTInlineLP[prop]
-
- actmesh.verts.addPropertyLayer("FLT_VCOL", Blender.Mesh.PropertyTypes["INT"])
- for v in actmesh.verts:
- v.setProperty("FLT_VCOL", 83815)
-
-def dfromact():
- state = update_state()
- actobj = state["activeObject"]
- actscene = state["activeScene"]
- dof = None
-
- for object in actscene.objects.context:
- if object.sel and (object != actobj):
- if not dof:
- dof = object
- else:
- break
-
- if not dof:
- return
-
- if 'FLT' not in dof.properties:
- dof.properties['FLT'] = dict()
-
- #Warning! assumes 1 BU == 10 meters.
- #do origin
- dof.properties['FLT']['5d!ORIGX'] = actobj.getLocation('worldspace')[0]*10.0
- dof.properties['FLT']['6d!ORIGY'] = actobj.getLocation('worldspace')[1]*10.0
- dof.properties['FLT']['7d!ORIGZ'] = actobj.getLocation('worldspace')[2]*10.0
- #do X axis
- x = Blender.Mathutils.Vector(1.0,0.0,0.0)
- x = x * actobj.getMatrix('worldspace')
- x = x * 10.0
- dof.properties['FLT']['8d!XAXIS-X'] = x[0]
- dof.properties['FLT']['9d!XAXIS-Y'] = x[1]
- dof.properties['FLT']['10d!XAXIS-Z'] = x[2]
- #do X/Y plane
- x = Blender.Mathutils.Vector(1.0,1.0,0.0)
- x.normalize()
- x = x * actobj.getMatrix('worldspace')
- x = x * 10.0
- dof.properties['FLT']['11d!XYPLANE-X'] = x[0]
- dof.properties['FLT']['12d!XYPLANE-Y'] = x[1]
- dof.properties['FLT']['13d!XZPLANE-Z'] = x[2]
-
-
-
-
-
-def event(evt,val):
- if evt == Draw.ESCKEY:
- Draw.Exit()
-
-def but_event(evt):
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
- global evcode
-
- state = update_state()
-
- #do Xref buttons
- if evt == evcode["XREF_PREFIX"]:
- xrefprefix = XREF_PREFIX.val
- if evt == evcode["XREF_EDIT"]:
- xref_edit()
- if evt == evcode["XREF_SELECT"]:
- xref_select()
- if evt == evcode["XREF_MAKE"]:
- xref_create()
- #do scene buttons
- if evt == evcode["SCENE_UPDATE"]:
- update_all()
- #do face buttons
- if evt == evcode["FACE_MAKESUB"]:
- subface_make()
- if evt== evcode["FACE_KILLSUB"]:
- subface_kill()
- if evt== evcode["FACE_SELSUB"]:
- subface_select()
- #common buttons
- if evt == evcode["IDPROP_KILL"]:
- if state["activeObject"]:
- idprops_kill(state["activeObject"])
- if evt == evcode["IDPROP_COPY"]:
- if state["activeObject"]:
- idprops_copy(state["activeObject"])
- if evt == evcode["XREF_POP"]:
- xref_finish()
- if evt == evcode["CLIGHT_MAKE"]:
- clight_make()
- if evt == evcode["DFROMACT"]:
- dfromact()
- if evt == evcode["FIXCOL"]:
- fix_colors()
- Draw.Redraw(1)
- Blender.Window.RedrawAll()
-
-
-def box(x,y,w,h,c,mode):
- glColor3f(c[0],c[1],c[2])
- if mode == "outline":
- glBegin(GL_LINE_LOOP)
- else:
- glBegin(GL_POLYGON)
- glVertex2i(x,y)
- glVertex2i(x+w,y)
- glVertex2i(x+w,y+h)
- glVertex2i(x,y+h)
- glEnd()
-
-def draw_postcommon(x,y,finaly):
- global sheetlabel
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
- global evcode
-
- state = update_state()
-
- width = prop_w
- height = prop_h
-
- #draw the header
- glColor3f(0.15,0.15,0.15)
- glBegin(GL_POLYGON)
- glVertex2i(x-1,y)
- glVertex2i(x+width+1,y)
- glVertex2i(x+width+1,y-25)
- glVertex2i(x-1,y-25)
- glEnd()
- glColor3f(1,1,1)
- glRasterPos2i(x,y-20)
- sheetlabel = Blender.Draw.Text("FLT Tools Panel")
- #draw the box outline
- glColor3f(0,0,0)
- glBegin(GL_LINE_LOOP)
- glVertex2i(x-1,y)
- glVertex2i(x+1+width,y)
- glVertex2i(x+1+width,finaly-1)
- glVertex2i(x-1,finaly-1)
- glEnd()
- return finaly
-
-
-def draw_propsheet(x,y):
- global XREF_PREFIX
- global XREF_MAKE
- global XREF_EDIT
- global XREF_SELECT
- global XREF_POP
- global FACE_MAKESUB
- global FACE_SELSUB
- global FACE_KILLSUB
- global IDPROP_KILL
- global IDPROP_COPY
- global SCENE_UPDATE
- global DFROMACT
- global FIXCOL
-
- global CLIGHT_MAKE
- global xrefprefix
- global xrefstack
- global vofsstack
- global vquatstack
- global prop_w
- global prop_h
- global evcode
-
- state = update_state()
-
- width = prop_w
- height = prop_h
- origx = x
- origy = y
-
- #draw Xref tools
- y = y-20
- XREF_PREFIX = Blender.Draw.String("XRef Name:",evcode["XREF_PREFIX"],x,y,width,20,xrefprefix,18,"Xref prefix name, Actual name is generated from this")
- y = y-20
- XREF_MAKE = Blender.Draw.PushButton("Make XRef",evcode["XREF_MAKE"],x,y,width,20,"Make External Reference")
- y = y-20
- XREF_EDIT = Blender.Draw.PushButton("Edit XRef",evcode["XREF_EDIT"],x,y,width,20,"Edit External Reference")
- y = y-20
- XREF_SELECT = Blender.Draw.PushButton("Select XRefs",evcode["XREF_SELECT"],x,y,width,20,"Select External References")
- y = y - 20
- XREF_POP = Blender.Draw.PushButton("Return to previous scene",evcode["XREF_POP"],x,y,width,20,"Go up one level in xref hierarchy")
-
- #Draw facetools
- y = y-20
- FACE_MAKESUB = Blender.Draw.PushButton("Make Subfaces",evcode["FACE_MAKESUB"],x,y,width,20,"Make subfaces")
- y = y-20
- FACE_SELSUB = Blender.Draw.PushButton("Select Subfaces",evcode["FACE_SELSUB"],x,y,width,20,"Select subfaces")
- y = y-20
- FACE_KILLSUB = Blender.Draw.PushButton("Kill Subfaces",evcode["FACE_KILLSUB"],x,y,width,20,"Kill subfaces")
-
- #Draw ID Property tools
- y = y - 20
- IDPROP_KILL = Blender.Draw.PushButton("Delete ID props",evcode["IDPROP_KILL"],x,y,width,20,"Delete ID props")
- y = y - 20
- IDPROP_COPY = Blender.Draw.PushButton("Copy to selected",evcode["IDPROP_COPY"],x,y,width,20, "Copy from active to all selected")
-
- y= y - 20
- CLIGHT_MAKE = Blender.Draw.PushButton("Make Light Point", evcode["CLIGHT_MAKE"],x,y,width,20,"Create inline light points from current mesh")
- #General tools
- y = y-20
- SCENE_UPDATE = Blender.Draw.PushButton("Update All",evcode["SCENE_UPDATE"],x,y,width,20,"Update all vertex colors")
-
- y=y-20
- DFROMACT = Blender.Draw.PushButton("Dof from Active", evcode["DFROMACT"],x,y,width,20,"Get Dof origin from active object")
- y=y-20
- FIXCOL = Blender.Draw.PushButton("Fix Colors", evcode["FIXCOL"],x,y,width,20,"Fix baked FLT colors of selected meshes")
- draw_postcommon(origx, origy,y)
-
-def gui():
- #draw the propsheet/toolbox.
- psheety = 300
- #psheetx = psheety + 10
- draw_propsheet(0,psheety)
-Draw.Register(gui,event,but_event)
- \ No newline at end of file
diff --git a/release/scripts/help_bpy_api.py b/release/scripts/help_bpy_api.py
deleted file mode 100644
index e8d77ed8452..00000000000
--- a/release/scripts/help_bpy_api.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!BPY
-"""
-Name: 'Blender/Python Scripting API'
-Blender: 248
-Group: 'Help'
-Tooltip: 'The Blender Python API reference manual'
-"""
-
-__author__ = "Matt Ebb"
-__url__ = ("blender", "blenderartist")
-__version__ = "1.0.1"
-__bpydoc__ = """\
-This script opens the user's default web browser at http://www.blender.org's
-"Blender Python API Reference" page.
-"""
-
-# --------------------------------------------------------------------------
-# Blender/Python Scripting Reference Help Menu Item
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-try: import webbrowser
-except: webbrowser = None
-
-if webbrowser:
- version = str(int(Blender.Get('version')))
- webbrowser.open('http://www.blender.org/documentation/'+ version +'PythonDoc/')
-else:
- Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
diff --git a/release/scripts/help_browser.py b/release/scripts/help_browser.py
deleted file mode 100644
index c207a12068f..00000000000
--- a/release/scripts/help_browser.py
+++ /dev/null
@@ -1,814 +0,0 @@
-#!BPY
-
-"""
-Name: 'Scripts Help Browser'
-Blender: 234
-Group: 'Help'
-Tooltip: 'Show help information about a chosen installed script.'
-"""
-
-__author__ = "Willian P. Germano"
-__version__ = "0.3 01/21/09"
-__email__ = ('scripts', 'Author, wgermano:ig*com*br')
-__url__ = ('blender', 'blenderartists.org')
-
-__bpydoc__ ="""\
-This script shows help information for scripts registered in the menus.
-
-Usage:
-
-- Start Screen:
-
-To read any script's "user manual" select a script from one of the
-available category menus. If the script has help information in the format
-expected by this Help Browser, it will be displayed in the Script Help
-Screen. Otherwise you'll be offered the possibility of loading the chosen
-script's source file in Blender's Text Editor. The programmer(s) may have
-written useful comments there for users.
-
-Hotkeys:<br>
- ESC or Q: [Q]uit
-
-- Script Help Screen:
-
-This screen shows the user manual page for the chosen script. If the text
-doesn't fit completely on the screen, you can scroll it up or down with
-arrow keys or a mouse wheel. There may be link and email buttons that if
-clicked should open your default web browser and email client programs for
-further information or support.
-
-Hotkeys:<br>
- ESC: back to Start Screen<br>
- Q: [Q]uit<br>
- S: view script's [S]ource code in Text Editor<br>
- UP, DOWN Arrows and mouse wheel: scroll text up / down
-"""
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-# Thanks: Brendon Murphy (suggestion) and Kevin Morgan (implementation)
-# for the "run" button; Jean-Michel Soler for pointing a parsing error
-# with multilines using triple single quotes.
-
-import Blender
-from Blender import sys as bsys, Draw, Window, Registry
-
-WEBBROWSER = True
-try:
- import webbrowser
-except:
- WEBBROWSER = False
-
-DEFAULT_EMAILS = {
- 'scripts': ['Bf-scripts-dev', 'bf-scripts-dev@blender.org']
-}
-
-DEFAULT_LINKS = {
- 'blender': ["blender.org\'s Python forum", "http://www.blender.org/modules.php?op=modload&name=phpBB2&file=viewforum&f=9"]
-}
-
-PADDING = 15
-COLUMNS = 1
-TEXT_WRAP = 100
-WIN_W = WIN_H = 200
-SCROLL_DOWN = 0
-
-def screen_was_resized():
- global WIN_W, WIN_H
-
- w, h = Window.GetAreaSize()
- if WIN_W != w or WIN_H != h:
- WIN_W = w
- WIN_H = h
- return True
- return False
-
-def fit_on_screen():
- global TEXT_WRAP, PADDING, WIN_W, WIN_H, COLUMNS
-
- COLUMNS = 1
- WIN_W, WIN_H = Window.GetAreaSize()
- TEXT_WRAP = int((WIN_W - PADDING) / 6)
- if TEXT_WRAP < 40:
- TEXT_WRAP = 40
- elif TEXT_WRAP > 100:
- if TEXT_WRAP > 110:
- COLUMNS = 2
- TEXT_WRAP /= 2
- else: TEXT_WRAP = 100
-
-def cut_point(text, length):
- "Returns position of the last space found before 'length' chars"
- l = length
- c = text[l]
- while c != ' ':
- l -= 1
- if l == 0: return length # no space found
- c = text[l]
- return l
-
-def text_wrap(text, length = None):
- global TEXT_WRAP
-
- wrapped = []
- lines = text.split('<br>')
- llen = len(lines)
- if llen > 1:
- if lines[-1] == '': llen -= 1
- for i in range(llen - 1):
- lines[i] = lines[i].rstrip() + '<br>'
- lines[llen-1] = lines[llen-1].rstrip()
-
- if not length: length = TEXT_WRAP
-
- for l in lines:
- while len(l) > length:
- cpt = cut_point(l, length)
- line, l = l[:cpt], l[cpt + 1:]
- wrapped.append(line)
- wrapped.append(l)
- return wrapped
-
-def load_script_text(script):
- global PATHS, SCRIPT_INFO
-
- if script.userdir:
- path = PATHS['uscripts']
- else:
- path = PATHS['scripts']
-
- fname = bsys.join(path, script.fname)
-
- source = Blender.Text.Load(fname)
- if source:
- Draw.PupMenu("File loaded%%t|Please check the file \"%s\" in the Text Editor window" % source.name)
-
-
-# for theme colors:
-def float_colors(cols):
- return map(lambda x: x / 255.0, cols)
-
-# globals
-
-SCRIPT_INFO = None
-
-PATHS = {
- 'home': Blender.Get('homedir'),
- 'scripts': Blender.Get('scriptsdir'),
- 'uscripts': Blender.Get('uscriptsdir')
-}
-
-if not PATHS['home']:
- errmsg = """
-Can't find Blender's home dir and so can't find the
-Bpymenus file automatically stored inside it, which
-is needed by this script. Please run the
-Help -> System -> System Information script to get
-information about how to fix this.
-"""
- raise SystemError, errmsg
-
-BPYMENUS_FILE = bsys.join(PATHS['home'], 'Bpymenus')
-
-f = file(BPYMENUS_FILE, 'r')
-lines = f.readlines()
-f.close()
-
-AllGroups = []
-
-class Script:
-
- def __init__(self, data):
- self.name = data[0]
- self.version = data[1]
- self.fname = data[2]
- self.userdir = data[3]
- self.tip = data[4]
-
-# End of class Script
-
-
-class Group:
-
- def __init__(self, name):
- self.name = name
- self.scripts = []
-
- def add_script(self, script):
- self.scripts.append(script)
-
- def get_name(self):
- return self.name
-
- def get_scripts(self):
- return self.scripts
-
-# End of class Group
-
-
-class BPy_Info:
-
- def __init__(self, script, dict):
-
- self.script = script
-
- self.d = dict
-
- self.header = []
- self.len_header = 0
- self.content = []
- self.len_content = 0
- self.spaces = 0
- self.fix_urls()
- self.make_header()
- self.wrap_lines()
-
- def make_header(self):
-
- sc = self.script
- d = self.d
-
- header = self.header
-
- title = "Script: %s" % sc.name
- version = "Version: %s for Blender %1.2f or newer" % (d['__version__'],
- sc.version / 100.0)
-
- if len(d['__author__']) == 1:
- asuffix = ':'
- else: asuffix = 's:'
-
- authors = "%s%s %s" % ("Author", asuffix, ", ".join(d['__author__']))
-
- header.append(title)
- header.append(version)
- header.append(authors)
- self.len_header = len(header)
-
-
- def fix_urls(self):
-
- emails = self.d['__email__']
- fixed = []
- for a in emails:
- if a in DEFAULT_EMAILS.keys():
- fixed.append(DEFAULT_EMAILS[a])
- else:
- a = a.replace('*','.').replace(':','@')
- ltmp = a.split(',')
- if len(ltmp) != 2:
- ltmp = [ltmp[0], ltmp[0]]
- fixed.append(ltmp)
-
- self.d['__email__'] = fixed
-
- links = self.d['__url__']
- fixed = []
- for a in links:
- if a in DEFAULT_LINKS.keys():
- fixed.append(DEFAULT_LINKS[a])
- else:
- ltmp = a.split(',')
- if len(ltmp) != 2:
- ltmp = [ltmp[0], ltmp[0]]
- fixed.append([ltmp[0].strip(), ltmp[1].strip()])
-
- self.d['__url__'] = fixed
-
-
- def wrap_lines(self, reset = 0):
-
- lines = self.d['__bpydoc__'].split('\n')
- self.content = []
- newlines = []
- newline = []
-
- if reset:
- self.len_content = 0
- self.spaces = 0
-
- for l in lines:
- if l == '' and newline:
- newlines.append(newline)
- newline = []
- newlines.append('')
- else: newline.append(l)
- if newline: newlines.append(newline)
-
- for lst in newlines:
- wrapped = text_wrap(" ".join(lst))
- for l in wrapped:
- self.content.append(l)
- if l: self.len_content += 1
- else: self.spaces += 1
-
- if not self.content[-1]:
- self.len_content -= 1
-
-
-# End of class BPy_Info
-
-def parse_pyobj_close(closetag, lines, i):
- i += 1
- l = lines[i]
- while l.find(closetag) < 0:
- i += 1
- l = "%s%s" % (l, lines[i])
- return [l, i]
-
-def parse_pyobj(var, lines, i):
- "Bad code, was in a hurry for release"
-
- l = lines[i].replace(var, '').replace('=','',1).strip()
-
- i0 = i - 1
-
- if l[0] == '"':
- if l[1:3] == '""': # """
- if l.find('"""', 3) < 0: # multiline
- l2, i = parse_pyobj_close('"""', lines, i)
- if l[-1] == '\\': l = l[:-1]
- l = "%s%s" % (l, l2)
- elif l[-1] == '"' and l[-2] != '\\': # single line: "..."
- pass
- else:
- l = "ERROR"
-
- elif l[0] == "'":
- if l[1:3] == "''": # '''
- if l.find("'''", 3) < 0: # multiline
- l2, i = parse_pyobj_close("'''", lines, i)
- if l[-1] == '\\': l = l[:-1]
- l = "%s%s" % (l, l2)
- elif l[-1] == '\\':
- l2, i = parse_pyobj_close("'", lines, i)
- l = "%s%s" % (l, l2)
- elif l[-1] == "'" and l[-2] != '\\': # single line: '...'
- pass
- else:
- l = "ERROR"
-
- elif l[0] == '(':
- if l[-1] != ')':
- l2, i = parse_pyobj_close(')', lines, i)
- l = "%s%s" % (l, l2)
-
- elif l[0] == '[':
- if l[-1] != ']':
- l2, i = parse_pyobj_close(']', lines, i)
- l = "%s%s" % (l, l2)
-
- return [l, i - i0]
-
-# helper functions:
-
-def parse_help_info(script):
-
- global PATHS, SCRIPT_INFO
-
- if script.userdir:
- path = PATHS['uscripts']
- else:
- path = PATHS['scripts']
-
- fname = bsys.join(path, script.fname)
-
- if not bsys.exists(fname):
- Draw.PupMenu('IO Error: couldn\'t find script %s' % fname)
- return None
-
- f = file(fname, 'r')
- lines = f.readlines()
- f.close()
-
- # fix line endings:
- if lines[0].find('\r'):
- unixlines = []
- for l in lines:
- unixlines.append(l.replace('\r',''))
- lines = unixlines
-
- llen = len(lines)
- has_doc = 0
-
- doc_data = {
- '__author__': '',
- '__version__': '',
- '__url__': '',
- '__email__': '',
- '__bpydoc__': '',
- '__doc__': ''
- }
-
- i = 0
- while i < llen:
- l = lines[i]
- incr = 1
- for k in doc_data.keys():
- if l.find(k, 0, 20) == 0:
- value, incr = parse_pyobj(k, lines, i)
- exec("doc_data['%s'] = %s" % (k, value))
- has_doc = 1
- break
- i += incr
-
- # fix these to seqs, simplifies coding elsewhere
- for w in ['__author__', '__url__', '__email__']:
- val = doc_data[w]
- if val and type(val) == str:
- doc_data[w] = [doc_data[w]]
-
- if not doc_data['__bpydoc__']:
- if doc_data['__doc__']:
- doc_data['__bpydoc__'] = doc_data['__doc__']
-
- if has_doc: # any data, maybe should confirm at least doc/bpydoc
- info = BPy_Info(script, doc_data)
- SCRIPT_INFO = info
- return True
-
- else:
- return False
-
-
-def parse_script_line(l):
-
- tip = 'No tooltip'
- try:
- pieces = l.split("'")
- name = pieces[1].replace('...','')
- data = pieces[2].strip().split()
- version = data[0]
- userdir = data[-1]
- fname = data[1]
- i = 1
- while not fname.endswith('.py'):
- i += 1
- fname = '%s %s' % (fname, data[i])
- if len(pieces) > 3: tip = pieces[3]
- except:
- return None
-
- return [name, int(version), fname, int(userdir), tip]
-
-
-def parse_bpymenus(lines):
-
- global AllGroups
-
- llen = len(lines)
-
- for i in range(llen):
- l = lines[i].strip()
- if not l: continue
- if l[-1] == '{':
- group = Group(l[:-2])
- AllGroups.append(group)
- i += 1
- l = lines[i].strip()
- while l != '}':
- if l[0] != '|':
- data = parse_script_line(l)
- if data:
- script = Script(data)
- group.add_script(script)
- i += 1
- l = lines[i].strip()
-
-# AllGroups.reverse()
-
-
-def create_group_menus():
-
- global AllGroups
- menus = []
-
- for group in AllGroups:
-
- name = group.get_name()
- menu = []
- scripts = group.get_scripts()
- for s in scripts: menu.append(s.name)
- menu = "|".join(menu)
- menu = "%s%%t|%s" % (name, menu)
- menus.append([name, menu])
-
- return menus
-
-
-# Collecting data:
-fit_on_screen()
-parse_bpymenus(lines)
-GROUP_MENUS = create_group_menus()
-
-
-# GUI:
-
-from Blender import BGL
-from Blender.Window import Theme
-
-# globals:
-
-START_SCREEN = 0
-SCRIPT_SCREEN = 1
-
-SCREEN = START_SCREEN
-
-# gui buttons:
-len_gmenus = len(GROUP_MENUS)
-
-BUT_GMENU = range(len_gmenus)
-for i in range(len_gmenus):
- BUT_GMENU[i] = Draw.Create(0)
-
-# events:
-BEVT_LINK = None # range(len(SCRIPT_INFO.links))
-BEVT_EMAIL = None # range(len(SCRIPT_INFO.emails))
-BEVT_GMENU = range(100, len_gmenus + 100)
-BEVT_VIEWSOURCE = 1
-BEVT_EXIT = 2
-BEVT_BACK = 3
-BEVT_EXEC = 4 # Executes Script
-
-# gui callbacks:
-
-def gui(): # drawing the screen
-
- global SCREEN, START_SCREEN, SCRIPT_SCREEN
- global SCRIPT_INFO, AllGroups, GROUP_MENUS
- global BEVT_EMAIL, BEVT_LINK
- global BEVT_VIEWSOURCE, BEVT_EXIT, BEVT_BACK, BEVT_GMENU, BUT_GMENU, BEVT_EXEC
- global PADDING, WIN_W, WIN_H, SCROLL_DOWN, COLUMNS, FMODE
-
- theme = Theme.Get()[0]
- tui = theme.get('ui')
- ttxt = theme.get('text')
-
- COL_BG = float_colors(ttxt.back)
- COL_TXT = ttxt.text
- COL_TXTHI = ttxt.text_hi
-
- BGL.glClearColor(COL_BG[0],COL_BG[1],COL_BG[2],COL_BG[3])
- BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
- BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
-
- resize = screen_was_resized()
- if resize: fit_on_screen()
-
- if SCREEN == START_SCREEN:
- x = PADDING
- bw = 85
- bh = 25
- hincr = 50
-
- butcolumns = (WIN_W - 2*x)/ bw
- if butcolumns < 2: butcolumns = 2
- elif butcolumns > 7: butcolumns = 7
-
- len_gm = len(GROUP_MENUS)
- butlines = len_gm / butcolumns
- if len_gm % butcolumns: butlines += 1
-
- h = hincr * butlines + 20
- y = h + bh
-
- BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2])
- BGL.glRasterPos2i(x, y)
- Draw.Text('Scripts Help Browser')
-
- y -= bh
-
- BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
-
- i = 0
- j = 0
- for group_menu in GROUP_MENUS:
- BGL.glRasterPos2i(x, y)
- Draw.Text(group_menu[0]+':')
- BUT_GMENU[j] = Draw.Menu(group_menu[1], BEVT_GMENU[j],
- x, y-bh-5, bw, bh, 0,
- 'Choose a script to read its help information')
- if i == butcolumns - 1:
- x = PADDING
- i = 0
- y -= hincr
- else:
- i += 1
- x += bw + 3
- j += 1
-
- x = PADDING
- y = 10
- BGL.glRasterPos2i(x, y)
- Draw.Text('Select script for its help. Press Q or ESC to leave.')
-
- elif SCREEN == SCRIPT_SCREEN:
- if SCRIPT_INFO:
-
- if resize:
- SCRIPT_INFO.wrap_lines(1)
- SCROLL_DOWN = 0
-
- h = 18 * SCRIPT_INFO.len_content + 12 * SCRIPT_INFO.spaces
- x = PADDING
- y = WIN_H
- bw = 38
- bh = 16
-
- BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2])
- for line in SCRIPT_INFO.header:
- y -= 18
- BGL.glRasterPos2i(x, y)
- size = Draw.Text(line)
-
- for line in text_wrap('Tooltip: %s' % SCRIPT_INFO.script.tip):
- y -= 18
- BGL.glRasterPos2i(x, y)
- size = Draw.Text(line)
-
- i = 0
- y -= 28
- for data in SCRIPT_INFO.d['__url__']:
- Draw.PushButton('link %d' % (i + 1), BEVT_LINK[i],
- x + i*bw, y, bw, bh, data[0])
- i += 1
- y -= bh + 1
-
- i = 0
- for data in SCRIPT_INFO.d['__email__']:
- Draw.PushButton('email', BEVT_EMAIL[i], x + i*bw, y, bw, bh, data[0])
- i += 1
- y -= 18
-
- y0 = y
- BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2])
- for line in SCRIPT_INFO.content[SCROLL_DOWN:]:
- if line:
- line = line.replace('<br>', '')
- BGL.glRasterPos2i(x, y)
- Draw.Text(line)
- y -= 18
- else: y -= 12
- if y < PADDING + 20: # reached end, either stop or go to 2nd column
- if COLUMNS == 1: break
- elif x == PADDING: # make sure we're still in column 1
- x = 6*TEXT_WRAP + PADDING / 2
- y = y0
-
- x = PADDING
- Draw.PushButton('source', BEVT_VIEWSOURCE, x, 17, 45, bh,
- 'View this script\'s source code in the Text Editor (hotkey: S)')
- Draw.PushButton('exit', BEVT_EXIT, x + 45, 17, 45, bh,
- 'Exit from Scripts Help Browser (hotkey: Q)')
- if not FMODE:
- Draw.PushButton('back', BEVT_BACK, x + 2*45, 17, 45, bh,
- 'Back to scripts selection screen (hotkey: ESC)')
- Draw.PushButton('run script', BEVT_EXEC, x + 3*45, 17, 60, bh, 'Run this script')
-
- BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2])
- BGL.glRasterPos2i(x, 5)
- Draw.Text('use the arrow keys or the mouse wheel to scroll text', 'small')
-
-def fit_scroll():
- global SCROLL_DOWN
- if not SCRIPT_INFO:
- SCROLL_DOWN = 0
- return
- max = SCRIPT_INFO.len_content + SCRIPT_INFO.spaces - 1
- if SCROLL_DOWN > max: SCROLL_DOWN = max
- if SCROLL_DOWN < 0: SCROLL_DOWN = 0
-
-
-def event(evt, val): # input events
-
- global SCREEN, START_SCREEN, SCRIPT_SCREEN
- global SCROLL_DOWN, FMODE
-
- if not val: return
-
- if evt == Draw.ESCKEY:
- if SCREEN == START_SCREEN or FMODE: Draw.Exit()
- else:
- SCREEN = START_SCREEN
- SCROLL_DOWN = 0
- Draw.Redraw()
- return
- elif evt == Draw.QKEY:
- Draw.Exit()
- return
- elif evt in [Draw.DOWNARROWKEY, Draw.WHEELDOWNMOUSE] and SCREEN == SCRIPT_SCREEN:
- SCROLL_DOWN += 1
- fit_scroll()
- Draw.Redraw()
- return
- elif evt in [Draw.UPARROWKEY, Draw.WHEELUPMOUSE] and SCREEN == SCRIPT_SCREEN:
- SCROLL_DOWN -= 1
- fit_scroll()
- Draw.Redraw()
- return
- elif evt == Draw.SKEY:
- if SCREEN == SCRIPT_SCREEN and SCRIPT_INFO:
- load_script_text(SCRIPT_INFO.script)
- return
-
-def button_event(evt): # gui button events
-
- global SCREEN, START_SCREEN, SCRIPT_SCREEN
- global BEVT_LINK, BEVT_EMAIL, BEVT_GMENU, BUT_GMENU, SCRIPT_INFO
- global SCROLL_DOWN, FMODE
-
- if evt >= 100: # group menus
- for i in range(len(BUT_GMENU)):
- if evt == BEVT_GMENU[i]:
- group = AllGroups[i]
- index = BUT_GMENU[i].val - 1
- if index < 0: return # user didn't pick a menu entry
- script = group.get_scripts()[BUT_GMENU[i].val - 1]
- if parse_help_info(script):
- SCREEN = SCRIPT_SCREEN
- BEVT_LINK = range(20, len(SCRIPT_INFO.d['__url__']) + 20)
- BEVT_EMAIL = range(50, len(SCRIPT_INFO.d['__email__']) + 50)
- Draw.Redraw()
- else:
- res = Draw.PupMenu("No help available%t|View Source|Cancel")
- if res == 1:
- load_script_text(script)
- elif evt >= 20:
- if not WEBBROWSER:
- Draw.PupMenu('Missing standard Python module%t|You need module "webbrowser" to access the web')
- return
-
- if evt >= 50: # script screen email buttons
- email = SCRIPT_INFO.d['__email__'][evt - 50][1]
- webbrowser.open("mailto:%s" % email)
- else: # >= 20: script screen link buttons
- link = SCRIPT_INFO.d['__url__'][evt - 20][1]
- webbrowser.open(link)
- elif evt == BEVT_VIEWSOURCE:
- if SCREEN == SCRIPT_SCREEN: load_script_text(SCRIPT_INFO.script)
- elif evt == BEVT_EXIT:
- Draw.Exit()
- return
- elif evt == BEVT_BACK:
- if SCREEN == SCRIPT_SCREEN and not FMODE:
- SCREEN = START_SCREEN
- SCRIPT_INFO = None
- SCROLL_DOWN = 0
- Draw.Redraw()
- elif evt == BEVT_EXEC: # Execute script
- exec_line = ''
- if SCRIPT_INFO.script.userdir:
- exec_line = bsys.join(Blender.Get('uscriptsdir'), SCRIPT_INFO.script.fname)
- else:
- exec_line = bsys.join(Blender.Get('scriptsdir'), SCRIPT_INFO.script.fname)
-
- Blender.Run(exec_line)
-
-keepon = True
-FMODE = False # called by Blender.ShowHelp(name) API function ?
-
-KEYNAME = '__help_browser'
-rd = Registry.GetKey(KEYNAME)
-if rd:
- rdscript = rd['script']
- keepon = False
- Registry.RemoveKey(KEYNAME)
- for group in AllGroups:
- for script in group.get_scripts():
- if rdscript == script.fname:
- parseit = parse_help_info(script)
- if parseit == True:
- keepon = True
- SCREEN = SCRIPT_SCREEN
- BEVT_LINK = range(20, len(SCRIPT_INFO.d['__url__']) + 20)
- BEVT_EMAIL = range(50, len(SCRIPT_INFO.d['__email__']) + 50)
- FMODE = True
- elif parseit == False:
- Draw.PupMenu("ERROR: script doesn't have proper help data")
- break
-
-if not keepon:
- Draw.PupMenu("ERROR: couldn't find script")
-else:
- Draw.Register(gui, event, button_event)
diff --git a/release/scripts/hotkeys.py b/release/scripts/hotkeys.py
deleted file mode 100644
index 187cba964bc..00000000000
--- a/release/scripts/hotkeys.py
+++ /dev/null
@@ -1,944 +0,0 @@
-#!BPY
-# coding: utf-8
-""" Registration info for Blender menus:
-Name: 'HotKey and MouseAction Reference'
-Blender: 242
-Group: 'Help'
-Tip: 'All the hotkeys/short keys'
-"""
-
-__author__ = "Jean-Michel Soler (jms)"
-__url__ = ("blender", "blenderartist",
-"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm",
-"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "21/01/2007"
-
-__bpydoc__ = """\
-This script is a reference about all hotkeys and mouse actions in Blender.
-
-Usage:
-
-Open the script from the Help menu and select group of keys to browse.
-
-Notes:<br>
- Additional entries in the database (c) 2004 by Bart.
- Additional entries in the database for blender 2.37 --> 2.43 (c) 2003-2007/01 by jms.
-
-"""
-
-#------------------------
-# Hotkeys script
-# (c) jm soler (2003-->01/2007)
-# -----------------------
-# Page officielle :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm
-# Communiquer les problemes et les erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#---------------------------------------------
-# ce script est proposé sous licence GPL pour etre associe
-# a la distribution de Blender 2.33 et suivant
-# --------------------------------------------------------------------------
-# this script is released under GPL licence
-# for the Blender 2.33 scripts package
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) 2003, 2004: Jean-Michel Soler
-# Additionnal entries in the original data base (c) 2004 by Bart (bart@neeneenee.de)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender.Draw import *
-from Blender.BGL import *
-
-# INTERNATIONAL={0:'English','1':'French'}
-# LANGUAGE=0
-
-hotkeys={
-'Search ':[['', '']],
-'Specials 1 ':[
-[',', 'Set Bounding Box rotation scaling pivot'],
-['Ctrl-,', 'Set Median Point rotation scaling pivot'],
-['.', 'Set 3D cursor as rotation scaling pivot'],
-['.', 'Outliner : to get the current active data in center of view'],
-['Ctrl-.', 'Set Individual Object Centers as rotation scaling pivot'],
-['~', 'Display all layers (German keys: ö,french keyboard: ù)'],
-['Shift-~', 'Display all/previous layers (German keys: Shift-ö, french keyboard: shift-ù)'],
-['ENTER', 'Outliner : to open a subtree, works on entire item line. '],
-['HOME', 'Outliner : to show the entire Object hierarchy. '],
-['SHIFT+BACKSPACE',' Text edit mode: Clear text '],
-['SPACE', 'Popup menu'],
-['SPACE', '3D View: camera selected'],
-['Ctrl-SPACE', 'Manipulator (transform widget) Menu'],
-['TAB', 'Enter/exit Edit Mode'],
-['TAB', 'Edit Mode and Numerical Edit (see N key) : move to next input value'],
-['TAB', 'Sequencer: Edit meta strip'],
-['TAB', 'IPO: Edit selected'],
-['TAB', 'Text Editor : indent'],
-['TAB', 'NODE window : Edit group'], #243
-['Shift-TAB', 'Text Editor : unindent'],
-['Shift-TAB', 'Edit Mode: Toggle snaping'],
-['Ctrl-TAB', 'ARMATURE : Enter/exit Pose Mode'],
-['Ctrl-TAB','MESH : all views, enter exit weight paint mode.'],
-['Shift-TAB', 'Edit Mode : Enter Object Mode'],
-['Ctrl-Open menu /', ''],
-['Ctrl-Load Image', 'Opens a thumbnail browser instead of file browser for images'],
-['.', '...']
-],
-
-'Mouse ':[
-['Actions:', ''],
-['LMB', '3D View: Set 3D Cursor'],
-['LMB', '3D View: camera selected'],
-['LMB drag', 'Border select circle: add to selection'],
-['LMB hold down', 'Popup menu'],
-['LMB hold down drag', 'Gesture'],
-['Ctrl-LMB', 'IPO: Add key'],
-['Ctrl-LMB', '3D View: OBJECT or EDIT mode, select with the Lasso tool'],
-['Ctrl-LMB', '3D View: ARMATURE EDIT mode, add a new bone to the selected end '],
-['Shift-LMB','MANIPULATOR (transform widget): select the axe to remove in the current'],
-['Shift-LMB','MANIPULATOR transformation ( if there is a problem with small step adjustment'],
-['Shift-LMB','MANIPULATOR first select the axe or axes with LBM alone)'],
-['Shift-LMB', 'Outliner : Hold Shift while clicking on a triangle arrow to open/close the subtree below'],
-['MMB', 'Rotate'],
-['Ctrl-MMB', 'Zoom view'],
-['Ctrl-LMB', 'Outliner : Hold CTRL while clicking on a name allows you to edit a name.'],
-['Ctrl-LMB', 'Outliner : This works for all visualized data, including bones or vertex groups,'],
-['Ctrl-LMB', 'Outliner : but not for \'nameless\' items that draw the links to Hooks, Deform '],
-['Ctrl-LMB', 'Outliner : Groups or Constraints.'],
-['Shift-MMB', 'Move view'],
-['RMB', 'Select'],
-['RMB drag', 'Border select circle: subtract from selection'],
-['RMB hold down', 'Popup menu'],
-['Alt-RMB', 'Object Mode :Select but in a displayed list of objects located under the mouse cursor'],
-['Alt-RMB', 'Edit Mode: Select EDGES LOOP '],
-['Alt-Ctrl-RMB', 'Edit Mode: Select FACES LOOP'],
-['Alt-Ctrl-RMB', 'UV Image Editor: Select face'],
-['Shift-RMB', 'Add/subtract to/from selection'],
-['Wheel', 'Zoom view'],
-['Transformations:', ''],
-['Drag+Ctrl', 'Step adjustment'],
-['Drag+Ctrl-Shift', 'Small step adjustment (Transform Widget : first select the axe or axes with LBM alone)'],
-['Drag+Shift', 'Fine adjustment (Transform Widget : first select the axe or axes with LBM alone)'],
-['LMB', 'Confirm transformation'],
-['MMB', 'Toggle optional transform feature'],
-['RMB', 'Abort transformation'],
-['LMB', 'Grease Pencil: when "Draw Mode On", draw new stroke'],
-['RMB', 'Grease Pencil: when "Draw Mode On", eraser tool for stroke segments'],
-['Shift-LMB', 'Grease Pencil: draw new stroke'],
-['Alt-RMB', 'Grease Pencil: eraser tool for stroke segments'],
-['.', '...']
-],
-
-'F-Keys ':[
-['F1', 'Open File'],
-['Shift-F1', 'Library Data Select'],
-['F2', 'Save File'],
-['Shift-F2', 'Export DXF'],
-['Ctrl-F2', 'Save/export in vrml 1.0 format' ],
-['F3', 'Save image'],
-['Ctrl-F3', 'Save image : dump 3d view'],
-['Ctrl-Shift-F3', 'Save image : dump screen'],
-['F4', 'Logic Window (may change)'],
-['Shift-F4', 'Object manager Data Select '],
-['F5', 'Material Window'],
-['Shift-F5', '3D Window'],
-['F6', 'Texture Window'],
-['Shift-F6', 'IPO Window'],
-['F7', 'Object Window'],
-['Shift-F7', 'Buttons Window'],
-['F8', 'World Window'],
-['Shift-F8', 'Video Sequencer Window'],
-['F9', 'Edit Mode Window'],
-['Shift-F9', 'OOP Window'],
-['Alt-Shift-F9', 'OutLiner Window'],
-['F10', 'Render Window'],
-['Shift-F10', 'UV Image Editor'],
-['F11', 'Recall the last rendered image'],
-['Shift-F11', 'Text Editor'],
-['ctrl-F11', 'replay the last rendered animation'],
-['F12', 'Render current Scene'],
-['Ctrl-F12', 'Render animation'],
-['Ctrl-Shift-F12', 'NLA Editor'],
-['Shift-F12', 'Action Editor'],
-['Shift-F12', 'Action Editor'],
-['.', '...']
-],
-
-'Numbers ':[
-['1..2..0-=', 'Show layer 1..2..12'],
-['1..2..0-=', 'Edit Mode with Size, Grab, rotate tools : enter value'],
-['Alt-1..2..0', 'Show layer 11..12..20'],
-['Shift-1..2..0', 'Toggle layer 1..2..12'],
-['Ctrl-1..4', 'Object/Edit Mode : change subsurf level to the selected value'],
-['Shift-ALT-...', 'Toggle layer 11..12..20'],
-['Crtl-Shift-ALT-3', 'Edit Mode & Face Mode : Triangle faces'],
-['Crtl-Shift-ALT-4', 'Edit Mode & Face Mode : Quad faces'],
-['Crtl-Shift-ALT-5', 'Edit Mode & Face Mode : Non quad or triangle faces'],
-['.', '...']
-],
-
-'Numpad ':[
-['Numpad DEL', 'Zoom on object'],
-['Numpad /', 'Local view on object (hide others)'],
-['Numpad *', 'Rotate view to objects local axes'],
-['Numpad +', 'Zoom in (works everywhere)'],
-['Numpad -', 'OutLiner window, Collapse one level of the hierarchy'],
-['Alt-Numpad +', 'Proportional vertex Edit Mode: Increase range of influence'],
-['Ctrl-Numpad +', 'Edit Mode: Select More vertices'],
-['Numpad -', 'Zoom out (works everywhere)'],
-['Numpad +', 'OutLiner window, Expand one level of the hierarchy'],
-['Alt-Numpad -', 'Proportional vertex Edit Mode: Decrease range of influence'],
-['Ctrl-Numpad +', 'Edit Mode: Select Less vertices'],
-['Numpad 0', 'Set Camera view'],
-['Ctrl-Numpad 0', 'Set active object as camera'],
-['Alt-Numbad 0', 'Restore old camera'],
-['Ctrl-Alt-Numpad 0', 'Align active camera to view'],
-['Numpad 1', 'Front view'],
-['Ctrl-Numpad 1', 'Back view'],
-['Numpad 3', 'Right view'],
-['Ctrl-Numpad 3', 'Left view'],
-['Numpad 7', 'Top view'],
-['Ctrl-Numpad 7', 'Bottom view '],
-['Numpad 5', 'Toggle orthogonal/perspective view'],
-['Numpad 9', 'Redraw view'],
-['Numpad 4', 'Rotate view left'],
-['ctrl-Shift-Numpad 4', 'Previous Screen'],
-['Numpad 6', 'Rotate view right'],
-['ctrl-Shift-Numpad 6', 'Next Screen'],
-['Numpad 8', 'Rotate view up'],
-['Numpad 2', 'Rotate view down'],
-['.', '...']
-],
-
-'Arrows ':[
-['Home/Pos1', 'View all',''],
-['Home', 'OutLiner Windows, Show hierarchy'],
-['PgUp', 'Edit Mode and Proportionnal Editing Tools, increase influence'],
-['PgUp', 'Strip Editor, Move Down'],
-['PgUp', 'TimeLine: Jump to next marker'],
-['PgUp', 'IPO: Select next keyframe'],
-['Ctrl-PgUp', 'IPO: Select and jump to next keyframe'],
-['Ctrl-PgUn', 'TimeLine: Jump to next key'],
-['PgDn', 'Edit Mode and Proportionnal Editing Tools, decrease influence'],
-['PgDn', 'Strip Editor, Move Up'],
-['PgDn', 'TimeLine: Jump to prev marker'],
-['PgDn', 'IPO: Select previous keyframe'],
-['Ctrl-PgDn', 'IPO: Select and jump to previous keyframe'],
-['Ctrl-PgDn', 'TimeLine: Jump to prev key'],
-['Left', 'One frame backwards'],
-['Right', 'One frame forwards'],
-['Down', '10 frames backwards'],
-['Up', '10 frames forwards'],
-['Alt-Down', 'Blender in Window mode'],
-['Alt-Up', 'Blender in Fullscreen mode'],
-['Ctrl-Left', 'Previous screen'],
-['Ctrl-Right', 'Next screen'],
-['Ctrl-Down', 'Maximize window toggle'],
-['Ctrl-Up', 'Maximize window toggle'],
-['Shift-Arrow', 'Toggle first frame/ last frame'],
-['.', '...']
-],
-
-'Letters ':[
-{
-"A":[
-['A', 'Select all/Deselect all'],
-['A', 'Outliner : Select all/Deselect all'],
-['A', 'Ipo Editor : Object mode, Select all/Deselect all displayed Curves'], #243
-['A', 'Ipo Editor : Edit mode, Select all/Deselect all vertices'], #243
-['A', 'Render window (F12) : Display alpha plane'],
-['Alt-A', 'Play animation in current window'],
-['Ctrl-A', 'Apply objects size/rotation to object data'],
-['Ctrl-A', 'Text Editor: Select all'],
-['Ctrl-ALT-A', '3D-View: Armature Edit mode, align selected bones to active bone'],
-['Shift-A', 'Sequencer: Add menu'],
-['Shift-A', '3D-View: Add menu'],
-['Shift-A', 'Sculpt Mode: Keep the brush center anchored to the initial location'],
-['Shift-ALT-A', 'Play animation in all windows'],
-['Shift-CTRL-A', 'Apply lattice / Make dupliverts real'],
-['Shift-CTRL-A', 'Apply Deform '],
-['.', '...']
-],
-
-"B":[
-['B', 'Border select'],
-['BB', 'Circle select'],
-['Alt-B', 'Object Mode: Select visible view section in 3D space'],
-['Shift-B', 'Set render border (in active camera view)'],
-['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake (on an image in the uv editor window) the selected Meshes'], #243
-['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Full render of selected Meshes'], #243
-['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Ambient Occlusion of selected Meshes'], #243
-['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Normals of the selected Meshes'], #243
-['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Texture Only of selected Meshes'], #243
-['.', '...']
-],
-
-"C":[
-['C', 'Center view on cursor'],
-['C', 'UV Image Editor: Active Face Select toggle'],
-['C', 'Sequencer: Change content of the strip '], #243
-['C', 'IPO: Snap current frame to selected key'],
-['C', 'TimeLine: Center View'],
-['C', 'File Selector : Copy file'],
-['C', 'NODE window : Show cyclic referencies'], #243
-['Alt-C', 'Object Mode: Convert menu'],
-['Alt-C', 'Text Editor: Copy '],
-['Ctrl-Alt-C', 'Object Mode : Add Constraint'],
-['Ctrl-Shift-C', 'Text Editor: Copy selection to clipboard'],
-['Ctrl-C', 'Copy menu (Copy properties of active to selected objects)'],
-['Ctrl-C', 'UV Image Editor: Stick UVs to mesh vertex'],
-['Ctrl-C','ARMATURE : posemode, Copy pose attributes'],
-['Ctrl-Alt-C',' ARMATURE : posemode, add constraint to new empty object.'],
-['Shift-C', 'Center and zoom view on selected objects'],
-['Shift-C', 'UV Image Editor: Stick local UVs to mesh vertex'],
-['.', '...']
-],
-
-"D":[
-['D', 'Set 3d draw mode'],
-['Alt-D', 'Object Mode: Create new instance of object'],
-['Ctrl-D', 'Display alpha of image texture as wire'],
-['Ctrl-D', 'Text Editor : uncomment'],
-['Shift-D', 'Create full copy of object'],
-['Shift-D', 'NODE window : duplicate'], #243
-['CTRL-SHIFT-D', 'NLA editor : Duplicate markers'],
-['CTRL-SHIFT-D', 'Action editor : Duplicate markers'],
-['CTRL-SHIFT-D', 'IPO editor : Duplicate markers'],
-['.', '...']
-],
-
-"E":[
-['E', 'Edit Mode: Extrude'],
-['E', 'UV Image Editor: LSCM Unwrap'],
-['E', 'TimeLine: Set current frame as End '],
-['E', 'NODE window : Execute composite'], #243
-['ER', 'Edit Mode: Extrude Rotate'],
-['ES', 'Edit Mode: Extrude Scale'],
-['ESX', 'Edit Mode: Extrude Scale X axis'],
-['ESY', 'Edit Mode: Extrude Scale Y axis'],
-['ESZ', 'Edit Mode: Extrude Scale Z axis'],
-['EX', 'Edit Mode: Extrude along X axis'],
-['EY', 'Edit Mode: Extrude along Y axis'],
-['EZ', 'Edit Mode: Extrude along Z axis'],
-['Alt-E', 'Edit Mode: exit Edit Mode'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu, Mark seams'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu, Clear seams'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu, Rotate Edge CW'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu, Rotate Edge CCW'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu, Loop Cut'],
-['Ctrl-E', 'Edit Mode: Edge Specials menu, Edge Slide'],
-['Shift-E', 'Edit Mode: SubSurf Edge Sharpness'],
-['.', '...']
-],
-
-"F":[
-['F', 'Edit mode: Make edge/face'],
-['F', 'Sequencer: Set Filter Y'],
-['F', 'Object Mode: UV/Face Select mode'],
-['Alt-F', 'Edit Mode: Beautify fill'],
-['Alt-F,','Text editor : find again '],
-['Alt-Ctrl-F,','Text editor : find '],
-['Ctrl-F', 'Object Mode: Sort faces in Z direction'],
-['Ctrl-F', 'Edit Mode: Flip triangle edges'],
-['Shift-F', 'Edit Mode: Fill with triangles'],
-['Shift-F', 'Object Mode: fly mode (see header for fly mode keys)'],
-['.', '...']
-],
-
-"G":[
-['G', 'Grab (move)'],
-['G', 'Timeline : Grab (move) Marker'],
-['Alt-G', 'Clear location (this does only make sense in Object mode)'],
-['Alt-G', 'NODE window : ungroup'], #243
-['Shift-ALT-G', 'Object mode: Remove selected objects from group'],
-['Ctrl-G', 'NODE window : group'], #243
-['Ctrl-G', 'Add selected objects to group'],
-['Ctrl-G', 'IPO editor, Grab/move marker'],
-['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Grab Mode'],
-['Shift-G', 'Object mode: Selected Group menu'],
-['Shift-G', 'Object mode: Selected Group menu 1, Children'],
-['Shift-G', 'Object mode: Selected Group menu 2, Immediate Children'],
-['Shift-G', 'Object mode: Selected Group menu 3, Parent'],
-['Shift-G', 'Object mode: Selected Group menu 4, Sibling'],
-['Shift-G', 'Object mode: Selected Group menu 5, Object of same type'],
-['Shift-G', 'Object mode: Selected Group menu 6, Object in same shared layers'],
-['Shift-G', 'Object mode: Selected Group menu 7, Objects in same group'],
-['.', '...']
-],
-
-"H":[
-['H', 'Hide selected vertices/faces'],
-['H', 'Curves: Set handle type'],
-['H', 'Action editor: Handle type aligned'],
-['H', 'Action editor: Handle type free'],
-['H', 'NODE window : hide/unhide'], #243
-['Alt-H', 'Edit Mode : Show Hidden vertices/faces'],
-['Shift-H', 'Curves: Automatic handle calculation'],
-['Shift-H', 'Action editor: Handle type auto'],
-['Shift-H', 'Edit Mode : Hide deselected vertices/faces'],
-['Ctrl-H', 'Edit Mode : Add a hook on selected points or show the hook menu .'],
-['.', '...']
-],
-
-"I":[
-['I', 'Insert Keyframe menu'],
-['Alt-I','Delete Keyframe menu'],
-['Ctrl-I','Select Inverse'],
-['Shift-I','ARMATURE : add IK constraint'],
-['Ctrl-Alt-I','ARMATURE : posemode, remove IK constraints.'],
-['.', '...']
-],
-
-"J":[
-['J', 'IPO: Join menu'],
-['J', 'Mesh: Join all adjacent triangles to quads'],
-['J', 'Render Window: Swap render buffer'],
-['Alt-J,','Text editor : Jump '],
-['Ctrl-J', 'Join selected objects'],
-['Ctrl-J', 'Nurbs: Add segment'],
-['Ctrl-J', 'IPO: Join keyframes menu'],
-['.', '...']
-],
-
-"K":[
-['K', '3d Window: Show keyframe positions'],
-['K', 'Edit Mode: Loop/Cut menu'],
-['K', 'IPO: Show keyframe positions'],
-['K', 'Nurbs: Print knots'],
-['K', 'VIDEO editor : cut at current frame'], #243
-['Ctrl-K', 'Make skeleton from armature'],
-['Shift-K', 'Show and select all keyframes for object'],
-['Shift-K', 'Edit Mode: Knife Mode select'],
-['Shift-K', 'UV Face Select: Clear vertex colours'],
-['Shift-K', 'Vertex Paint: All vertex colours are erased; they are changed to the current drawing colour.'],
-['.', '...']
-],
-
-"L":[
-['L', 'Make local menu'],
-['L', 'Edit Mode: Select linked vertices (near mouse pointer)'],
-['L', 'NODE window: Select linked from '], #243
-['L', 'OOPS window: Select linked objects'],
-['L', 'UV Face Select: Select linked faces'],
-['Ctrl-L', 'Make links menu (for instance : to scene...)'],
-['Shift-L', 'Select links menu'],
-['Shift-L', 'NODE window: Select linked to '], #243
-['Ctrl-L', 'POSELIB: browse poses'],
-['Shift-L', 'POSELIB: add/replace pose'],
-['Ctrl-Shift-L', 'POSELIB: rename pose'],
-['Alt-L', 'POSELIB: remove pose'],
-['.', '...']
-],
-
-"M":[
-['M', 'Object mode : Move object to different layer'],
-['M', 'Sequencer: Make meta strip (group) from selected strips'],
-['M', 'Edit Mode: Mirros Axis menu'],
-['M', 'File Selector: rename file'],
-['M', 'Video Sequence Editor : Make Meta strip...'],
-['M', 'NLA editor: Add marker'],
-['M', 'Action editor: Add marker'],
-['M', 'IPO editor: Add marker'],
-['M', 'TimeLine: Add marker'],
-['Alt-M', 'Edit Mode: Merge vertices menu'],
-['Alt-M', 'Video Sequence Editor : Separate Meta strip...'],
-['Ctrl-M', 'Object Mode: Mirros Axis menu'],
-['Shift-M', 'TimeLine: Name marker'],
-['Shift-M', 'IPO editor : Name marker'],
-['Shift-M', 'NLA editor : Name marker'],
-['Shift-M', 'Actions editor : Name marker'],
-['.', '...']
-],
-
-"N":[
-['N', 'Transform Properties panel'] ,
-['N', 'OOPS window: Rename object'],
-['N', 'VIDEO SEQUENCE editor : display strip properties '], #243
-['Alt-N', 'Text Editor : New text '],
-['Ctrl-N', 'Armature: Recalculate bone roll angles'] ,
-['Ctrl-N', 'Edit Mode: Recalculate normals to outside'] ,
-['Ctrl-Shift-N', 'Edit Mode: Recalculate normals to inside'],
-['.', '...']
-],
-
-"O":[
-['O', 'Edit Mode/UV Image Editor: Toggle proportional vertex editing'],
-['O', 'IPO editor: Clean ipo curves (beware to the thresold needed value)'], #243
-['Alt-O', 'Clear object origin'],
-['Alt-O', 'Edit mode, 3dview with prop-edit-mode, enables/disables connected'],
-['Alt-O', 'Text Editor : Open file '],
-['Ctrl-O', 'Open a panel with the ten most recent projets files'], #243
-['Shift-O', 'Proportional vertex Edit Mode: Toggle smooth/steep falloff'],
-['Shift-O', 'Object Mode: Add a subsurf modifier to the selected mesh'],
-['Shift-O', 'IPO editor: Smooth ipo curves'], #243
-['.', '...']
-],
-
-"P":[
-['P', 'Object Mode: Start realtime engine'],
-['P', 'Edit mode: Seperate vertices to new object'],
-['Shift-P', 'Edit mode: Push-Pull'],
-['Shift-P', 'Object mode: Add a preview window in the D window'],
-['P', 'UV Image Editor: Pin selected vertices. Pinned vertices will stay in place on the UV editor when executing an LSCM unwrap.'],
-['Alt-P', 'Clear parent relationship'],
-['Alt-P', 'UV Image Editor: Unpin UVs'],
-['Alt-P', 'Text Editor : Run current script '],
-['Ctrl-P', 'Make active object parent of selected object'],
-['Ctrl-Shift-P', 'Make active object parent of selected object without inverse'],
-['Ctrl-P', 'Edit mode: Make active vertex parent of selected object'],
-['Ctrl-P', 'ARMATURE : editmode, make bone parent.'],
-['Ctrl-Alt-P', 'ARMATURE: edimode, separate bones to new object'],
-['.', '...']
-],
-
-"Q":[['Ctrl-Q', 'Quit'],
- ['.', '...']
- ],
-
-"R":[
-['R', 'FileSelector : remove file'],
-['R', 'Rotate'],
-['R', 'IPO: Record mouse movement as IPO curve'],
-['R', 'UV Face Select: Rotate menu uv coords or vertex colour'],
-['R', 'NODE window : read saved render result'], #243
-['R', 'SEQUENCER window : re-assign entries to another strip '], #243
-['RX', 'Rotate around X axis'],
-['RXX', "Rotate around object's local X axis"],
-['RY', 'Rotate around Y axis'],
-['RYY', "Rotate around object's local Y axis"],
-['RZ', 'Rotate around Z axis'],
-['RZZ', "Rotate around object's local Z axis"],
-['Alt-R', 'Clear object rotation'],
-['Alt-R', 'Text editor : reopen text.'],
-['Ctrl-R', 'Edit Mode: Knife, cut selected edges, accept left mouse/ cancel right mouse'],
-['Ctrl-Alt-R', 'MANIPULATOR (transform widget): set in Rotate Mode'],
-['Shift-R', 'Edit Mode: select Face Loop'],
-['Shift-R', 'Nurbs: Select row'],
-['.', '...']
-],
-
-"S":[
-['S', 'Scale'] ,
-['S', 'TimeLine: Set Start'],
-['SX', 'Flip around X axis'] ,
-['SY', 'Flip around Y axis'] ,
-['SZ', 'Flip around Z axis'] ,
-['SXX', 'Flip around X axis and show axis'] ,
-['SYY', 'Flip around Y axis and show axis'] ,
-['SZZ', 'Flip around Z axis and show axis'] ,
-['Alt-S', 'Edit mode: Shrink/fatten (Scale along vertex normals)'] ,
-['Alt-S', 'Text Editor : Save the current text to file '],
-['Alt-S',' ARMATURE : posemode editmode: Scale envalope.'],
-['Ctrl-Shift-S', 'Edit mode: To Sphere'] ,
-['Ctrl-Alt-Shift-S', 'Edit mode: Shear'] ,
-['Alt-S', 'Clear object size'] ,
-['Ctrl-S', 'Edit mode: Shear'] ,
-['Alt-Shift-S,','Text editor : Select the line '],
-['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Size Mode'],
-['Shift-S', 'Cursor/Grid snap menu'],
-['Shift-S', 'Sculpt Mode: Smooth Stroke.'],
-['Shift-S+1', 'VIDEO SEQUENCE editor : jump to the current frame '],
-['.', '...']
-],
-
-"T":[
-['T', 'Adjust texture space'],
-['T', 'Edit mode: Flip 3d curve'],
-['T', 'IPO: Menu Change IPO type, 1 Constant'],
-['T', 'IPO: Menu Change IPO type, 2 Linear'],
-['T', 'IPO: Menu Change IPO type, 3 Bezier'],
-['T', 'TimeLine: Show second'],
-['T', 'VIDEO SEQUENCE editor : toggle between show second andd show frame'], #243
-['Alt-T', 'Clear tracking of object'],
-['Ctrl-T', 'Make selected object track active object'],
-['Ctrl-T', 'Edit Mode: Convert to triangles'],
-['Ctrl-Alt-T', 'Benchmark'],
-['.', '...']
-],
-
-"U":[
-['U', 'Make single user menu (for import completly linked object to another scene for instance) '] ,
-['U', '3D View: Make Single user Menu'] ,
-['U', 'UV Face Select: Automatic UV calculation menu'] ,
-['U', 'Vertex-/Weightpaint mode: Undo'] ,
-['Ctrl-U', 'Save current state as user default'],
-['Shift-U', 'Edit Mode: Redo Menu'],
-['Alt-U', 'Edit Mode & Object Mode: Undo Menu'],
-['.', '...']
-],
-
-"V":[
-['V', 'Curves/Nurbs: Vector handle'],
-['V', 'Edit Mode : Rip selected vertices'],
-['V', 'Vertexpaint mode'],
-['V', 'UV Image Editor: Stitch UVs'],
-['Ctrl-V',' UV Image Editor: maximize stretch.'],
-['V', 'Action editor: Vector'],
-['Alt-V', "Scale object to match image texture's aspect ratio"],
-['Alt-V', 'Text Editor : Paste '],
-['Alt-Shift-V', 'Text Editor : View menu'],
-['Alt-Shift-V', 'Text Editor : View menu 1, Top of the file '],
-['Alt-Shift-V', 'Text Editor : View menu 2, Bottom of the file '],
-['Alt-Shift-V', 'Text Editor : View menu 3, PageUp'],
-['Alt-Shift-V', 'Text Editor : View menu 4, PageDown'],
-['Ctrl-Shift-V', 'Text Editor: Paste from clipboard'],
-['Shift-V', 'Edit mode: Align view to selected vertices'],
-['Shift-V', 'UV Image Editor: Limited Stitch UVs popup'],
-['.', '...']
-],
-
-"W":[
-['W', 'Edit Mode: Specials menu'],
-['W', 'Edit Mode: Specials menu, ARMATURE 1 Subdivide'],
-['W', 'Edit Mode: Specials menu, ARMATURE 2 Subdivide Multi'],
-['W', 'Edit Mode: Specials menu, ARMATURE 3 Switch Direction'],
-['W', 'Edit Mode: Specials menu, ARMATURE 4 Flip Left-Right Name'],
-['W', 'Edit Mode: Specials menu, ARMATURE 5 AutoName Left-Right'],
-['W', 'Edit Mode: Specials menu, ARMATURE 6 AutoName Front-Back'],
-['W', 'Edit Mode: Specials menu, ARMATURE 7 AutoName Top-Bottom'],
-['W', 'Edit Mode: Specials menu, CURVE 1 Subdivide'],
-['W', 'Edit Mode: Specials menu, CURVE 2 Swich Direction'],
-['W', 'Edit Mode: Specials menu, CURVE 3 Set Goal Weight'],
-['W', 'Edit Mode: Specials menu, CURVE 4 Set Radius'],
-['W', 'Edit Mode: Specials menu, CURVE 5 Smooth'],
-['W', 'Edit Mode: Specials menu, CURVE 6 Smooth Radius'],
-['W', 'Edit Mode: Specials menu, MESH 1 Subdivide'],
-['W', 'Edit Mode: Specials menu, MESH 2 Subdivide Multi'],
-['W', 'Edit Mode: Specials menu, MESH 3 Subdivide Multi Fractal'],
-['W', 'Edit Mode: Specials menu, MESH 4 Subdivide Smooth'],
-['W', 'Edit Mode: Specials menu, MESH 5 Merge'],
-['W', 'Edit Mode: Specials menu, MESH 6 Remove Double'],
-['W', 'Edit Mode: Specials menu, MESH 7 Hide'],
-['W', 'Edit Mode: Specials menu, MESH 8 Reveal'],
-['W', 'Edit Mode: Specials menu, MESH 9 Select Swap'],
-['W', 'Edit Mode: Specials menu, MESH 10 Flip Normal'],
-['W', 'Edit Mode: Specials menu, MESH 11 Smooth'],
-['W', 'Edit Mode: Specials menu, MESH 12 Bevel'],
-['W', 'Edit Mode: Specials menu, MESH 13 Set Smooth'],
-['W', 'Edit Mode : Specials menu, MESH 14 Set Solid'],
-['W', 'Object Mode : on MESH objects, Boolean Tools menu'],
-['W', 'Object Mode : on MESH objects, Boolean Tools 1 Intersect'],
-['W', 'Object Mode : on MESH objects, Boolean Tools 2 union'],
-['W', 'Object Mode : on MESH objects, Boolean Tools 3 difference'],
-['W', 'Object Mode : on MESH objects, Boolean Tools 4 Add an intersect Modifier'],
-['W', 'Object Mode : on MESH objects, Boolean Tools 5 Add an union Modifier'],
-['W', 'Object Mode : on MESH objects, Boolean Tools 6 Add a difference Modifier'],
-['W', 'Object mode : on TEXT object, Split characters, a new TEXT object by character in the selected string '],
-['W', 'UV Image Editor: Weld/Align'],
-['WX', 'UV Image Editor: Weld/Align X axis'],
-['WY', 'UV Image Editor: Weld/Align Y axis'],
-['Ctrl-W', 'Save current file'] ,
-['Shift-W', 'Warp/bend selected vertices around cursor'],
-['.', '...']
- ],
-
-"X":[
-['X', 'Delete menu'] ,
-['X', 'TimeLine : Remove marker'],
-['X', 'NLA : Remove marker'],
-['X', 'IPO : Remove marker'],
-['X', 'NODE window : delete'], #243
-['Alt-X', 'Text Editor : Cut '],
-['Alt-X', 'Grease Pencil: Delete menu'],
-['Ctrl-X', 'Restore default state (Erase all)'],
-['.', '...']
- ],
-
-"Y":[
-['Y', 'Edit Mode & Mesh : Split selected vertices/faces from the rest'],
-['Ctrl-Y', 'Object Mode : Redo'],
-['.', '...']
-],
-
-"Z":[
-['Z', 'Render Window: 200% zoom from mouse position'],
-['Z', 'Switch 3d draw type : solide/ wireframe (see also D)'],
-['Alt-Z', 'Switch 3d draw type : solid / textured (see also D)'],
-['Alt-Z,','Text editor : undo '],
-['Ctrl-Z', 'Object Mode : Undo'],
-['Ctrl-Z,','Text editor : undo '],
-['Ctrl-Shift-Z,','Text editor : Redo '],
-['Shift-Z', 'Switch 3d draw type : shaded / wireframe (see also D)'],
-['.', '...']
-]}]}
-
-up=128
-down=129
-UP=0
-SEARCH=131
-OLDSEARCHLINE=''
-SEARCHLINE=Create('')
-LINE=130
-FINDED=[]
-LEN=0
-
-for k in hotkeys.keys():
- hotkeys[k].append(Create(0))
-
-for k in hotkeys['Letters '][0]:
- hotkeys['Letters '][0][k].append(Create(0))
-
-hotL=hotkeys['Letters '][0].keys()
-hotL.sort()
-
-hot=hotkeys.keys()
-hot.sort()
-
-def searchfor(SEARCHLINE):
- global hotkeys, hot
- FINDLIST=[]
- for k in hot:
- if k not in ['Letters ', 'Search '] :
- for l in hotkeys[k][:-1]:
- #print 'k, l : ', k, l, l[1]
- if l[1].upper().find(SEARCHLINE.upper())!=-1:
- FINDLIST.append(l)
-
- elif k == 'Letters ':
- for l in hotL :
- for l0 in hotkeys['Letters '][0][l][:-1]:
- #print 'k, l : ',l, k, l0
- if l0[1].upper().find(SEARCHLINE.upper())!=-1:
- FINDLIST.append(l0)
- #print 'FINDLIST',FINDLIST
- FINDLIST.append(['Find list','Entry'])
- return FINDLIST
-
-
-glCr=glRasterPos2d
-glCl3=glColor3f
-glCl4=glColor4f
-glRct=glRectf
-
-cf=[0.95,0.95,0.9,0.0]
-c1=[0.95,0.95,0.9,0.0]
-c=cf
-r=[0,0,0,0]
-
-def trace_rectangle4(r,c):
- glCl4(c[0],c[1],c[2],c[3])
- glRct(r[0],r[1],r[2],r[3])
-
-def trace_rectangle3(r,c,c1):
- glCl3(c[0],c[1],c[2])
- glRct(r[0],r[1],r[2],r[3])
- glCl3(c1[0],c1[1],c1[2])
-
-def draw():
- global r,c,c1,hotkeys, hot, hotL, up, down, UP, SEARCH, SEARCHLINE,LINE
- global OLDSEARCHLINE, FINDED, SCROLL, LEN
- size=Buffer(GL_FLOAT, 4)
- glGetFloatv(GL_SCISSOR_BOX, size)
- size= size.list
-
- for s in [0,1,2,3]: size[s]=int(size[s])
-
- c=[0.75,0.75,0.75,0]
- c1=[0.6,0.6,0.6,0]
-
- r=[0,size[3],size[2],0]
- trace_rectangle4(r,c)
-
- c=[0.64,0.64,0.64,0]
- c1=[0.95,0.95,0.9,0.0]
-
- r=[0,size[3],size[2],size[3]-40]
- trace_rectangle4(r,c)
-
- c1=[0.7,0.7,0.9,0.0]
- c=[0.2,0.2,0.4,0.0]
- c2=[0.71,0.71,0.71,0.0]
-
- glColor3f(1, 1, 1)
- glRasterPos2f(42, size[3]-25)
-
- Text("HotKey and MouseAction Reference")
-
- l=0
- listed=0
- Llisted=0
- size[3]=size[3]-18
-
- BeginAlign()
- for i, k in enumerate(hot):
- hotkeys[k][-1]=Toggle(k, i+10, 78*i, size[3]-(47), 78, 24, hotkeys[k][-1].val )
- l+=len(k)
- if hotkeys[k][-1].val==1.0:
- listed= i
- EndAlign()
- l=0
- size[3]=size[3]-4
-
- if hot[listed]!='Letters ' and hot[listed]!='Search ' :
- size[3]=size[3]-8
- SCROLL=size[3]/21
- END=-1
- if SCROLL < len(hotkeys[hot[listed]][:-1]):
- BeginAlign()
- Button('/\\',up,4,size[3]+8,20,14,'Scroll up')
- Button('\\/',down,4,size[3]-8,20,14,'Scroll down')
- EndAlign()
- if (SCROLL+UP)<len(hotkeys[hot[listed]][:-1]):
- END=(UP+SCROLL)
- else:
- END=-1
- UP=len(hotkeys[hot[listed]][:-1])-SCROLL
- else :
- UP=0
- for n in hotkeys[hot[listed]][:-1][UP:END]:
- if l%2==0:
- r=[0,size[3]-(21*l+66),
- size[2], size[3]-(21*l+43)]
- trace_rectangle4(r,c2)
- glColor3f(0,0,0)
- glRasterPos2f(4+8, size[3]-(58+21*l))
- Text(n[0])
- glRasterPos2f(4+8*15, size[3]-(58+21*l))
- Text(' : '+n[1])
- l+=1
-
- elif hot[listed]=='Search ' :
- r=[0,size[3]-70,
- size[2], size[3]-44]
- trace_rectangle4(r,c2)
- SEARCHLINE=String(' ', LINE, 42, size[3]-68,200,18,SEARCHLINE.val, 256,'')
- if len(FINDED)>0:
- LEN=len(FINDED)
- size[3]=size[3]-8
- SCROLL=size[3]/21
- END=-1
-
- if SCROLL < len(FINDED):
- BeginAlign()
- Button('/\\',up,4,size[3]+8,20,14,'Scroll up')
- Button('\\/',down,4,size[3]-8,20,14,'Scroll down')
- EndAlign()
- if (SCROLL+UP)<len(FINDED):
- END=(UP+SCROLL-1)
- else:
- END=-1
- #UP=len(FINDED)-SCROLL
- else:
- UP=0
- for n in FINDED[UP:END]:
- if l%2==0:
- r=[0,size[3]-(21*l+66+24),
- size[2], size[3]-(21*l+43+24)]
- trace_rectangle4(r,c2)
- glColor3f(0,0,0)
- glRasterPos2f(4+8, size[3]-(58+24+21*l))
- Text(n[0])
- glRasterPos2f(4+8*15, size[3]-(58+24+21*l))
- Text(' : '+n[1])
- l+=1
- else:
- BeginAlign()
- for pos, k in enumerate(hotL):
- hotkeys['Letters '][0][k][-1]=Toggle(k,pos+20,pos*21, size[3]-(52+18), 21, 18, hotkeys['Letters '][0][k][-1].val )
- if hotkeys['Letters '][0][k][-1].val==1.0:
- Llisted=pos
- EndAlign()
- size[3]=size[3]-8
- SCROLL=(size[3]-88)/21
- END=-1
- if SCROLL < len(hotkeys['Letters '][0][hotL[Llisted]]):
- LEN=len(hotkeys['Letters '][0][hotL[Llisted]])
- BeginAlign()
- Button('/\\',up,4,size[3]+8,20,14,'Scroll up, you can use arrow or page keys too ')
- Button('\\/',down,4,size[3]-8,20,14,'Scroll down, you can use arrow or page keys too ')
- EndAlign()
- if (UP+SCROLL)<len(hotkeys['Letters '][0][hotL[Llisted]]):
- END=(UP+SCROLL)
- else:
- END=-1
- UP=len(hotkeys['Letters '][0][hotL[Llisted]])-SCROLL
- else :
- UP=0
-
- for n in hotkeys['Letters '][0][hotL[Llisted]][UP:END]:
- if l%2==0:
- r=[4,size[3]-(21*l+92),
- size[2], size[3]-(69+21*l+1)]
- trace_rectangle4(r,c2)
-
- glColor3f(0.1, 0.1, 0.15)
- glRasterPos2f(4+8, (size[3]-(88+21*l))+3)
- Text(n[0])
- glRasterPos2f(4+8*15, (size[3]-(88+21*l))+3)
- Text(' : '+n[1])
- l+=1
-
-def event(evt, val):
- global hotkeys, UP, SCROLL , LEN
- if (evt== QKEY or evt== ESCKEY):
- Exit()
- elif val:
- if (evt== PAGEUPKEY):
- if (UP+SCROLL)<LEN-5:
- UP+=5
- elif (evt== PAGEDOWNKEY):
- if UP>4:
- UP-=5
- elif (evt== UPARROWKEY):
- if (UP+SCROLL)<LEN-1:
- UP+=1
- elif (evt== DOWNARROWKEY):
- if UP>0:
- UP-=1
- Redraw()
-
-def bevent(evt):
- global hotkeysmhot, hotL, up,down,UP, FINDED
- global SEARCH, SEARCHLINE,LINE, OLDSEARCHLINE
-
- if (evt== 1):
- Exit()
-
- elif 9 < evt < 20:
- for i, k in enumerate(hot):
- if i+10!=evt:
- hotkeys[k][-1].val=0
- UP=0
- Blender.Window.Redraw()
-
- elif 19 < evt < 46:
- for i, k in enumerate(hotL):
- if i+20!=evt:
- hotkeys['Letters '][0][k][-1].val=0
- UP=0
- Blender.Window.Redraw()
-
- elif (evt==up):
- UP+=1
- Blender.Window.Redraw()
-
- elif (evt==down):
- if UP>0: UP-=1
- Blender.Window.Redraw()
-
- elif (evt==LINE):
- if SEARCHLINE.val!='' and SEARCHLINE.val!=OLDSEARCHLINE:
- OLDSEARCHLINE=SEARCHLINE.val
- FINDED=searchfor(OLDSEARCHLINE)
- Blender.Window.Redraw()
-
-if __name__ == '__main__':
- Register(draw, event, bevent)
diff --git a/release/scripts/image_2d_cutout.py b/release/scripts/image_2d_cutout.py
deleted file mode 100644
index 16d0805256b..00000000000
--- a/release/scripts/image_2d_cutout.py
+++ /dev/null
@@ -1,559 +0,0 @@
-#!BPY
-
-"""
-Name: '2D Cutout Image Importer'
-Blender: 249
-Group: 'Image'
-Tooltip: 'Batch UV Map images to Planes'
-"""
-
-__author__ = "Kevin Morgan (forTe)"
-__url__ = ("Home page, http://gamulabs.freepgs.com")
-__version__ = "1.2.1"
-__bpydoc__ = """\
-This Script will take an image and
-UV map it to a plane sharing the same width to height ratio as the image.
-Import options allow for the image to be a still or sequence type image
-<br><br>
-Imports can be single images or whole directories of images depending on the chosen
-option.
-"""
-
-####################################################
-#Copyright (C) 2008: Kevin Morgan
-####################################################
-#-------------GPL LICENSE BLOCK-------------
-#This program is free software: you can 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 hopes that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-#GNU 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>.
-####################################################
-####################################################
-#V1.0
-#Basic Functionality
-#Published June 28, 2007
-####################################################
-#V1.1
-#Added Support for enabling viewport transparency
-#Added more options to the UI for materials
-#Added Proportionality code (Pixels per unit)
-#Added GPL License Block
-#Published June 29, 2007
-####################################################
-#V1.2
-#Added Support for Copying Existing Materials
-#Import Images as Sequences
-#Refreshed GUI - now with more clutter :(
-#Miscellaneous and Housekeeping
-#Published June 16, 2008
-####################################################
-#V1.2.1
-#Added Extend Texture Mode option at request of a user
-#Published September 24, 2008
-####################################################
-
-import Blender
-from Blender import BGL, Draw, Image, Mesh, Material, Texture, Window
-from Blender.Mathutils import *
-import bpy
-
-# Global Constants
-DIR = 0
-SINGLE = 1
-CUROFFS = 0
-
-# GUI CONSTANTS
-NO_EVT = 0
-SINGLE_IMG = 1
-DIRECTORY_IMG = 2
-CLR_PATH = 3
-CHG_EXT = 4
-EXIT = 5
-DO_SCRIPT = 6
-
-VERSIONSTRING = '1.2.1'
-
-# Note the two parameter dicts could be combined, I just, liked them seperate...
-# GUI Buttons Dict
-GUIPARAMS = {
- 'Path': Draw.Create(''),
- 'ImageExt': Draw.Create(''),
- 'Seq': Draw.Create(0),
- 'PackImage': Draw.Create(0),
- 'PPU': Draw.Create(50),
- 'VPTransp': Draw.Create(1),
- 'XOff': Draw.Create(0.0),
- 'YOff': Draw.Create(0.0),
- 'ZOff': Draw.Create(0.0),
- 'CopyMat': Draw.Create(0),
- 'MatId': Draw.Create(0),
- 'MatCol': Draw.Create(1.0, 0.0, 0.0),
- 'Ref': Draw.Create(0.8),
- 'Spec': Draw.Create(0.5),
- 'Hard': Draw.Create(50),
- 'Alpha': Draw.Create(1.0),
- 'ZTransp': Draw.Create(1),
- 'Shadeless': Draw.Create(0),
- 'TexChan': Draw.Create(1),
- 'MPTCol': Draw.Create(1),
- 'MPTAlpha': Draw.Create(1),
- 'UseAlpha': Draw.Create(1),
- 'CalcAlpha': Draw.Create(0),
- 'ExtendMode': Draw.Create(0),
- 'AutoRefresh': Draw.Create(0),
- 'Cyclic': Draw.Create(0),
- 'Frames': Draw.Create(100),
- 'Offs': Draw.Create(0),
- 'StartFr': Draw.Create(1),
- 'RedrawImp': Draw.Create(0)
-}
-
-# Script Execution Paramaters
-PARAMS = {
- 'ImagePaths': [], # Path to images to import
- 'ImportType': SINGLE, # Import a Directory or a Single Image?
- 'ImageProp': Image.Sources.STILL, # What sources for the image, still or sequence
- 'PackImage': 0, # Pack the Image(s)?
- 'PPU': 20, # Pixels Per Blender Unit
- 'MakeTransp': 1, # Make face transparent in viewport
-
- 'NewMat': 1, # If true make a new material, otherwise duplicate an existing one, replacing appropriate attributes
- 'MaterialId': 0, # ID to take from the Materials list upon copy
- 'Materials': None, # Materials in Scene
- 'MatProps': {'Col': [1.0, 0.0, 0.0], 'Shadeless': 1, 'Ref': 0.5, 'Spec': 0.5, 'Hard': 200, 'Alpha': 1.0, 'ZTransp': 1},
-
- 'TexProps': {'UseAlpha': 1, 'CalcAlpha': 0, 'ExtendMode': 0}, # Texture Properties
- 'TexChannel': 0, # Texture Channel
- 'TexMapTo': {'Col': 1, 'Alpha': 1}, # Map to Col and/or Alpha
- 'SeqProps': {'AutoRefresh': 0, 'Cyclic': 0, 'Frames': 100, 'Offs': 0, 'StartFr': 1},
- 'ObOffset': Vector(1, 0, 0) # Offset by this vector upon creation for multifile import
-}
-
-# Get the Active Scene, of course
-scn = bpy.data.scenes.active
-
-##########################################
-# MAIN SCRIPT FUNCTIONS
-##########################################
-
-def imgImport(imgPath):
- global CUROFFS, PARAMS
- ######################################
- # Load the image
- ######################################
- try:
- img = Image.Load(imgPath)
- imgDimensions = img.getSize() # do this to ensure the data is available
- except:
- Blender.Draw.PupMenu('Error%t|Unsupported image format for "'+ imgPath.split('\\')[-1].split('/')[-1] +'"')
- return
-
- if PARAMS['PackImage']:
- img.pack()
- name = Blender.sys.makename(imgPath, strip = 1)
-
- ######################################
- # Construct the mesh
- ######################################
-
- me = Mesh.New(name)
-
- # Calculate Dimensions from Image Size
- dim = [float(i)/PARAMS['PPU'] for i in imgDimensions]
- v = [[dim[0], dim[1], 0], [-dim[0], dim[1], 0], [-dim[0], -dim[1], 0], [dim[0], -dim[1], 0]]
- me.verts.extend(v)
- me.faces.extend([0, 1, 2, 3])
-
- me.faces[0].image = img
- me.faces[0].uv = [Vector(1.0, 1.0), Vector(0.0, 1.0), Vector(0.0, 0.0), Vector(1.0, 0.0)]
-
- if PARAMS['MakeTransp']:
- me.faces[0].transp = Mesh.FaceTranspModes.ALPHA
-
- ######################################
- # Modify the Material
- ######################################
-
- mat = None
- if not PARAMS['NewMat']:
- mat = PARAMS['Materials'][PARAMS['MaterialId']].__copy__()
- mat.setName(name)
- else:
- mat = Material.New(name)
- properties = PARAMS['MatProps']
- mat.setRGBCol(properties['Col'])
- mat.setRef(properties['Ref'])
- mat.setSpec(properties['Spec'])
- mat.setHardness(properties['Hard'])
- mat.setAlpha(properties['Alpha'])
-
- if properties['Shadeless']:
- mat.mode |= Material.Modes.SHADELESS
- if properties['ZTransp']:
- mat.mode |= Material.Modes.ZTRANSP
-
- properties = PARAMS['TexProps']
-
- tex = Texture.New(name)
- tex.setType('Image')
- tex.setImage(img)
- if properties['UseAlpha']:
- tex.useAlpha = Texture.ImageFlags.USEALPHA
-
- if properties['CalcAlpha']:
- tex.calcAlpha = Texture.ImageFlags.CALCALPHA
-
- if properties['ExtendMode']:
- tex.setExtend('Extend')
-
- if PARAMS['ImageProp'] == Image.Sources.SEQUENCE:
- properties = PARAMS['SeqProps']
-
- img.source = PARAMS['ImageProp'] # Needs to be done here, otherwise an error with earlier getSize()
-
- tex.animStart = properties['StartFr']
- tex.animOffset = properties['Offs']
- tex.animFrames = properties['Frames']
- tex.autoRefresh = properties['AutoRefresh']
- tex.cyclic = properties['Cyclic']
-
- texMapSetters = Texture.TexCo.UV
-
- # PARAMS['TexMapTo']['Col'] (and alpha) will either be 0 or 1 because its from a toggle, otherwise this line doesn't work
- texChanSetters = Texture.MapTo.COL * PARAMS['TexMapTo']['Col'] | Texture.MapTo.ALPHA * PARAMS['TexMapTo']['Alpha']
-
- mat.setTexture(PARAMS['TexChannel'], tex, texMapSetters, texChanSetters)
- me.materials += [mat]
-
- ######################################
- # Object Construction
- ######################################
-
- ob = scn.objects.new(me, name)
- p = Vector(ob.getLocation()) # Should be the origin, but just to be safe, get it
- ob.setLocation((CUROFFS * PARAMS['ObOffset']) + p)
-
- return
-
-def translateParams():
- # Translates (or assigns for the most part) GUI values to those that can be read by the
- # Import Function
-
- global GUIPARAMS, PARAMS
-
- if GUIPARAMS['Seq'].val and PARAMS['ImportType'] != DIR:
- PARAMS['ImageProp'] = Image.Sources.SEQUENCE
-
- PARAMS['PackImage'] = GUIPARAMS['PackImage'].val
- PARAMS['PPU'] = GUIPARAMS['PPU'].val
- PARAMS['MakeTransp'] = GUIPARAMS['VPTransp'].val
- PARAMS['ObOffset'] = Vector(GUIPARAMS['XOff'].val, GUIPARAMS['YOff'].val, GUIPARAMS['ZOff'].val)
-
- PARAMS['NewMat'] = not GUIPARAMS['CopyMat'].val
- PARAMS['MaterialId'] = GUIPARAMS['MatId'].val
- PARAMS['MatProps']['Col'] = list(GUIPARAMS['MatCol'].val)
- PARAMS['MatProps']['Ref'] = GUIPARAMS['Ref'].val
- PARAMS['MatProps']['Spec'] = GUIPARAMS['Spec'].val
- PARAMS['MatProps']['Hard'] = GUIPARAMS['Hard'].val
- PARAMS['MatProps']['Alpha'] = GUIPARAMS['Alpha'].val
- PARAMS['MatProps']['ZTransp'] = GUIPARAMS['ZTransp'].val
- PARAMS['MatProps']['Shadeless'] = GUIPARAMS['Shadeless'].val
-
- PARAMS['TexChannel'] = GUIPARAMS['TexChan'].val - 1 #Channels are 0-9, but GUI shows 1-10
- PARAMS['TexProps']['UseAlpha'] = GUIPARAMS['UseAlpha'].val
- PARAMS['TexProps']['CalcAlpha'] = GUIPARAMS['CalcAlpha'].val
- PARAMS['TexProps']['ExtendMode'] = GUIPARAMS['ExtendMode'].val
- PARAMS['TexMapTo']['Col'] = GUIPARAMS['MPTCol'].val
- PARAMS['TexMapTo']['Alpha'] = GUIPARAMS['MPTAlpha'].val
-
- PARAMS['SeqProps']['AutoRefresh'] = GUIPARAMS['AutoRefresh'].val
- PARAMS['SeqProps']['Cyclic'] = GUIPARAMS['Cyclic'].val
- PARAMS['SeqProps']['Frames'] = GUIPARAMS['Frames'].val
- PARAMS['SeqProps']['Offs'] = GUIPARAMS['Offs'].val
- PARAMS['SeqProps']['StartFr'] = GUIPARAMS['StartFr'].val
- return
-
-def doScript():
- # Main script Function
- # Consists of choosing between 2 loops, one with a redraw, one without, see comments for why
-
- global CUROFFS
-
- translateParams()
-
- total = len(PARAMS['ImagePaths'])
- broken = 0
-
- if GUIPARAMS['RedrawImp'].val: # Reduces the need to compare on every go through the loop
- for i, path in enumerate(PARAMS['ImagePaths']):
- CUROFFS = i # Could be passed to the import Function, but I chose a global instead
- Window.DrawProgressBar(float(i)/total, "Importing %i of %i Images..." %(i+1, total))
- imgImport(path)
- Blender.Redraw()
- if Blender.Get('version') >= 246:
- if Window.TestBreak():
- broken = 1
- break
- else:
- for i, path in enumerate(PARAMS['ImagePaths']):
- CUROFFS = i
- Window.DrawProgressBar(float(i)/total, "Importing %i of %i Images..." %(i+1, total))
- imgImport(path)
- if Blender.Get('version') >= 246:
- if Window.TestBreak():
- broken = 1
- break
-
- if broken:
- Window.DrawProgressBar(1.0, "Script Execution Aborted")
- else:
- Window.DrawProgressBar(1.0, "Finished Importing")
-
- Blender.Redraw() # Force a refresh, since the user may have chosen to not refresh as they go along
-
- return
-
-##########################################
-# PATH SETTERS AND CHANGERS
-##########################################
-
-def setSinglePath(filename):
- global GUIPARAMS, PARAMS
- GUIPARAMS['Path'].val = filename
- PARAMS['ImagePaths'] = [filename]
- return
-
-def setDirPath(filename):
- global GUIPARAMS, PARAMS
-
- try:
- import os
- except:
- Draw.PupMenu('Full install of python required to be able to set Directory Paths')
- Draw.Exit()
- return
-
- path = os.path.dirname(filename) # Blender.sys.dirname fails on '/'
- GUIPARAMS['Path'].val = path
-
- ext_lower = GUIPARAMS['ImageExt'].val.lower()
- for f in os.listdir(path):
- if f.lower().endswith(ext_lower):
- PARAMS['ImagePaths'].append(os.path.join(path, f))
-
- return
-
-def changeExtension():
- global GUIPARAMS, PARAMS
-
- if PARAMS['ImportType'] == SINGLE:
- return
-
- try:
- import os
- except:
- Draw.PupMenu('Full install of python required to be able to set Directory Paths')
- Draw.Exit()
- return
-
- PARAMS['ImagePaths'] = []
-
- ext_lower = GUIPARAMS['ImageExt'].val.lower()
- for f in os.listdir(GUIPARAMS['Path'].val):
- if f.lower().endswith(ext_lower):
- PARAMS['ImagePaths'].append(os.path.join(GUIPARAMS['Path'].val, f))
-
- return
-
-##########################################
-# INTERFACE FUNCTIONS
-##########################################
-def compileMaterialList():
- # Pretty straight forward, just grabs the materials in the blend file and constructs
- # an appropriate string for use as a menu
-
- mats = [mat for mat in bpy.data.materials]
- PARAMS['Materials'] = mats
- title = 'Materials%t|'
- menStrs = [mat.name + '%x' + str(i) + '|' for i, mat in enumerate(mats)]
- return title + ''.join(menStrs)
-
-def event(evt, val):
- # Disabled, since Esc is often used from the file browser
- #if evt == Draw.ESCKEY:
- # Draw.Exit()
-
- return
-
-def bevent(evt):
- global GUIPARAMS, PARAMS
-
- if evt == NO_EVT:
- Draw.Redraw()
-
- elif evt == SINGLE_IMG:
- Window.FileSelector(setSinglePath, 'Image', Blender.sys.expandpath('//'))
- Draw.Redraw()
- PARAMS['ImportType'] = SINGLE
-
- elif evt == DIRECTORY_IMG:
- Window.FileSelector(setDirPath, 'Directory', Blender.sys.expandpath('//'))
- Draw.Redraw()
- PARAMS['ImportType'] = DIR
-
- elif evt == CLR_PATH:
- GUIPARAMS['Path'].val = ''
- PARAMS['ImagePaths'] = []
- GUIPARAMS['ImageExt'].val = ''
- Draw.Redraw()
-
- elif evt == CHG_EXT:
- changeExtension()
- Draw.Redraw()
-
- elif evt == EXIT:
- Draw.Exit()
-
- elif evt == DO_SCRIPT:
- doScript()
-
- else:
- print "ERROR: UNEXPECTED BUTTON EVENT"
-
- return
-
-# GUI Colors ######
-ScreenColor = [0.7, 0.7, 0.7]
-BackgroundColor = [0.8, 0.8, 0.8]
-TitleBG = [0.6, 0.6, 0.6]
-TitleCol = [1.0, 1.0, 1.0]
-ErrCol = [1.0, 0.0, 0.0]
-TextCol = [0.4, 0.4, 0.5]
-###################
-
-def GUI():
- global GUIPARAMS, PARAMS
-
- BGL.glClearColor(*(ScreenColor + [1.0]))
- BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
-
- minx = 5
- maxx = 500
- miny = 5
- maxy = 450
-
- lineheight = 24
- buPad = 5 # Generic Button Padding, most buttons should have 24-19 (or 5) px space around them
-
- lP = 5 # Left Padding
- rP = 5 # Right Padding
-
- # Draw Background Box
- BGL.glColor3f(*BackgroundColor)
- BGL.glRecti(minx, miny, maxx, maxy)
-
- # Draw Title
- BGL.glColor3f(*TitleBG)
- BGL.glRecti(minx, maxy - (lineheight), maxx, maxy)
- BGL.glColor3f(*TitleCol)
-
- title = "2D Cutout Image Importer v" + VERSIONSTRING
- BGL.glRasterPos2i(minx + lP, maxy - 15)
- Draw.Text(title, 'large')
-
- Draw.PushButton('Exit', EXIT, maxx-50-rP, maxy - lineheight + 2, 50, 19, "Exit Script")
-
- # Path Buttons
- if GUIPARAMS['Path'].val == '':
- Draw.PushButton('Single Image', SINGLE_IMG, minx + lP, maxy - (2*lineheight), 150, 19, "Select a Single Image to Import")
- Draw.PushButton('Directory', DIRECTORY_IMG, minx + lP + 150, maxy - (2*lineheight), 150, 19, "Select a Directory of Images to Import")
-
- else:
- Draw.PushButton('Clear', CLR_PATH, minx+lP, maxy - (2*lineheight), 50, 19, "Clear Path and Change Import Options")
-
- GUIPARAMS['Path'] = Draw.String('Path: ', NO_EVT, minx + lP, maxy - (3*lineheight), (maxx-minx-lP-rP), 19, GUIPARAMS['Path'].val, 399, 'Path to Import From')
- if PARAMS['ImportType'] == DIR:
- GUIPARAMS['ImageExt'] = Draw.String('Image Ext: ', CHG_EXT, minx + lP, maxy - (4*lineheight), 110, 19, GUIPARAMS['ImageExt'].val, 6, 'Image extension for batch directory importing (case insensitive)')
- GUIPARAMS['PackImage'] = Draw.Toggle('Pack', NO_EVT, maxx - rP - 50, maxy - (4*lineheight), 50, 19, GUIPARAMS['PackImage'].val, 'Pack Image(s) into .Blend File')
-
- # Geometry and Viewport Options
- BGL.glColor3f(*TextCol)
- BGL.glRecti(minx+lP, maxy - (5*lineheight), maxx-rP, maxy - (5*lineheight) + 1)
- BGL.glRasterPos2i(minx + lP, maxy-(5*lineheight) + 3)
- Draw.Text('Geometry and Display Options', 'small')
-
- GUIPARAMS['PPU'] = Draw.Slider('Pixels Per Unit: ', NO_EVT, minx + lP, maxy - (6*lineheight), (maxx-minx)/2 - lP, 19, GUIPARAMS['PPU'].val, 1, 5000, 0, 'Set the Number of Pixels Per Blender Unit to preserve Image Size Relations')
- GUIPARAMS['VPTransp'] = Draw.Toggle('Viewport Transparency', NO_EVT, minx + lP, maxy - (8*lineheight), (maxx-minx)/2 - lP, 2*lineheight - buPad, GUIPARAMS['VPTransp'].val, 'Display Alpha Transparency in the Viewport')
-
- GUIPARAMS['XOff'] = Draw.Slider('Offs X: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (6*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['XOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the X-Direction if Importing Multiple Images')
- GUIPARAMS['YOff'] = Draw.Slider('Offs Y: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (7*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['YOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the Y-Direction if Importing Multiple Images')
- GUIPARAMS['ZOff'] = Draw.Slider('Offs Z: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (8*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['ZOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the Z-Direction if Importing Multiple Images')
-
- # Material and Texture Options
- BGL.glColor3f(*TextCol)
- BGL.glRecti(minx+lP, maxy - (9*lineheight), maxx-rP, maxy - (9*lineheight) + 1)
- BGL.glRasterPos2i(minx + lP, maxy-(9*lineheight) + 3)
- Draw.Text('Material and Texture Options', 'small')
-
- half = (maxx-minx-lP-rP)/2
- GUIPARAMS['CopyMat'] = Draw.Toggle('Copy Existing Material', NO_EVT, minx + lP, maxy-(10*lineheight), half, 19, GUIPARAMS['CopyMat'].val, 'Copy an Existing Material')
- if GUIPARAMS['CopyMat'].val:
- menStr = compileMaterialList()
- GUIPARAMS['MatId'] = Draw.Menu(menStr, NO_EVT, minx + lP, maxy - (11*lineheight), half, 19, GUIPARAMS['MatId'].val, 'Material to Copy Settings From')
- else:
- GUIPARAMS['MatCol'] = Draw.ColorPicker(NO_EVT, minx+lP, maxy - (13*lineheight), 40, (3*lineheight) - buPad, GUIPARAMS['MatCol'].val, 'Color of Newly Created Material')
- GUIPARAMS['Ref'] = Draw.Slider('Ref: ', NO_EVT, minx +lP+45, maxy - (11*lineheight), half-45, 19, GUIPARAMS['Ref'].val, 0.0, 1.0, 0, 'Set the Ref Value for Created Materials')
- GUIPARAMS['Spec'] = Draw.Slider('Spec: ', NO_EVT, minx +lP+45, maxy - (12*lineheight), half-45, 19, GUIPARAMS['Spec'].val, 0.0, 2.0, 0, 'Set the Spec Value for Created Materials')
- GUIPARAMS['Hard'] = Draw.Slider('Hard: ', NO_EVT, minx +lP+45, maxy - (13*lineheight), half-45, 19, GUIPARAMS['Hard'].val, 1, 500, 0, 'Set the Hardness Value for Created Materials')
- GUIPARAMS['Alpha'] = Draw.Slider('A: ', NO_EVT, minx +lP, maxy - (14*lineheight), half, 19, GUIPARAMS['Alpha'].val, 0.0, 1.0, 0, 'Set the Alpha Value for Created Materials')
-
- GUIPARAMS['ZTransp'] = Draw.Toggle('ZTransparency', NO_EVT, minx + lP, maxy - (15*lineheight), half, 19, GUIPARAMS['ZTransp'].val, 'Enable ZTransparency')
- GUIPARAMS['Shadeless'] = Draw.Toggle('Shadeless', NO_EVT, minx + lP, maxy - (16*lineheight), half, 19, GUIPARAMS['Shadeless'].val, 'Enable Shadeless')
-
- GUIPARAMS['TexChan'] = Draw.Number('Texture Channel: ', NO_EVT, minx + lP+ half + buPad, maxy - (10*lineheight), half-rP, 19, GUIPARAMS['TexChan'].val, 1, 10, 'Texture Channel for Image Texture')
-
- GUIPARAMS['MPTCol'] = Draw.Toggle('Color', NO_EVT, minx + lP + half + buPad, maxy - (11*lineheight), half/2, 19, GUIPARAMS['MPTCol'].val, 'Map To Color Channel')
- GUIPARAMS['MPTAlpha'] = Draw.Toggle('Alpha', NO_EVT, minx + lP + int((1.5)*half) + buPad, maxy - (11*lineheight), half/2 - rP, 19, GUIPARAMS['MPTAlpha'].val, 'Map To Alpha Channel')
-
- third = int((maxx-minx-lP-rP)/6)
- GUIPARAMS['UseAlpha'] = Draw.Toggle('Use Alpha', NO_EVT, minx + lP + half + buPad, maxy - (12*lineheight), third, 19, GUIPARAMS['UseAlpha'].val, "Use the Images' Alpha Values")
- GUIPARAMS['CalcAlpha'] = Draw.Toggle('Calc Alpha', NO_EVT, minx + lP + half + third + buPad, maxy - (12*lineheight), third, 19, GUIPARAMS['CalcAlpha'].val, "Calculate Images' Alpha Values")
- GUIPARAMS['ExtendMode'] = Draw.Toggle('Extend', NO_EVT, minx+lP+half+third+third+buPad, maxy - (12*lineheight), third-3, 19, GUIPARAMS['ExtendMode'].val, "Use Extend texture mode. If deselected, Repeat is used")
- GUIPARAMS['Seq'] = Draw.Toggle('Sequence', NO_EVT, minx + lP + half + buPad, maxy - (13*lineheight), half-rP, 19, GUIPARAMS['Seq'].val, 'Set the Image(s) to use a Sequence instead of a Still')
-
- if GUIPARAMS['Seq'].val and not PARAMS['ImportType'] == DIR:
- GUIPARAMS['AutoRefresh'] = Draw.Toggle('Auto Refresh', NO_EVT, minx + lP + half + buPad, maxy - (14*lineheight), half/2, 19, GUIPARAMS['AutoRefresh'].val, 'Use Auto Refresh')
- GUIPARAMS['Cyclic'] = Draw.Toggle('Cyclic', NO_EVT, minx + lP + half + buPad + half/2, maxy - (14*lineheight), half/2 - rP, 19, GUIPARAMS['Cyclic'].val, 'Repeat Frames Cyclically`')
-
- GUIPARAMS['Frames'] = Draw.Number('Frames: ', NO_EVT, minx +lP + half + buPad, maxy - (15*lineheight), half - rP, 19, GUIPARAMS['Frames'].val, 1, 30000, 'Sets the Number of Images of a Movie to Use')
- GUIPARAMS['Offs'] = Draw.Number('Offs: ', NO_EVT, minx +lP + half + buPad, maxy - (16*lineheight), half/2, 19, GUIPARAMS['Offs'].val, -30000, 30000, 'Offsets the Number of the Frame to use in the Animation')
- GUIPARAMS['StartFr'] = Draw.Number('StartFr: ', NO_EVT, minx +lP + half + buPad + half/2, maxy - (16*lineheight), half/2 - rP, 19, GUIPARAMS['StartFr'].val, 1, 30000, 'Sets the Global Starting Frame of the Movie')
- elif GUIPARAMS['Seq'].val and PARAMS['ImportType'] == DIR:
- BGL.glColor3f(*ErrCol)
- BGL.glRasterPos2i(minx + lP + half + buPad + 7, maxy-(14 * lineheight) + 5)
- Draw.Text('Sequence only available for Single Image Import', 'small')
-
- # Import Options
- BGL.glColor3f(*TextCol)
- BGL.glRecti(minx+lP, maxy - (17*lineheight), maxx-rP, maxy - (17*lineheight) + 1)
- BGL.glRasterPos2i(minx + lP, maxy-(17*lineheight) + 3)
- Draw.Text('Import', 'small')
-
- if GUIPARAMS['Path'].val and GUIPARAMS['ImageExt'].val or GUIPARAMS['Path'].val and PARAMS['ImportType'] == SINGLE:
- Draw.PushButton('Import', DO_SCRIPT, minx + lP, maxy - (18*lineheight), 75, 19, "Import Image(s)")
- else:
- BGL.glColor3f(*ErrCol)
- BGL.glRasterPos2i(minx+lP, maxy - (18*lineheight) + 5)
- Draw.Text('A path and image type must be specified to import images')
-
- GUIPARAMS['RedrawImp'] = Draw.Toggle('Redraw During Import', NO_EVT, maxx - rP - 150, maxy - (18*lineheight), 150, 19, GUIPARAMS['RedrawImp'].val, 'Redraw the View as Images Import')
-
-Draw.Register(GUI, event, bevent) \ No newline at end of file
diff --git a/release/scripts/image_auto_layout.py b/release/scripts/image_auto_layout.py
deleted file mode 100644
index d19ba1da662..00000000000
--- a/release/scripts/image_auto_layout.py
+++ /dev/null
@@ -1,455 +0,0 @@
-#!BPY
-
-"""
-Name: 'Consolidate into one image'
-Blender: 243
-Group: 'Image'
-Tooltip: 'Pack all texture images into 1 image and remap faces.'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.1a 2009/04/01"
-
-__bpydoc__ = """\
-This script makes a new image from the used areas of all the images mapped to the selected mesh objects.
-Image are packed into 1 new image that is assigned to the original faces.
-This is usefull for game models where 1 image is faster then many, and saves the labour of manual texture layout in an image editor.
-
-"""
-# --------------------------------------------------------------------------
-# Auto Texture Layout v1.0 by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-# Function to find all the images we use
-import Blender as B
-from Blender.Mathutils import Vector, RotationMatrix
-from Blender.Scene import Render
-import BPyMathutils
-BIGNUM= 1<<30
-TEXMODE= B.Mesh.FaceModes.TEX
-
-def pointBounds(points):
- '''
- Takes a list of points and returns the
- area, center, bounds
- '''
- ymax= xmax= -BIGNUM
- ymin= xmin= BIGNUM
-
- for p in points:
- x= p.x
- y= p.y
-
- if x>xmax: xmax=x
- if y>ymax: ymax=y
-
- if x<xmin: xmin=x
- if y<ymin: ymin=y
-
- # area and center
- return\
- (xmax-xmin) * (ymax-ymin),\
- Vector((xmin+xmax)/2, (ymin+ymax)/2),\
- (xmin, ymin, xmax, ymax)
-
-
-def bestBoundsRotation(current_points):
- '''
- Takes a list of points and returns the best rotation for those points
- so they fit into the samllest bounding box
- '''
-
- current_area, cent, bounds= pointBounds(current_points)
-
- total_rot_angle= 0.0
- rot_angle= 45
- while rot_angle > 0.1:
- mat_pos= RotationMatrix( rot_angle, 2)
- mat_neg= RotationMatrix( -rot_angle, 2)
-
- new_points_pos= [v*mat_pos for v in current_points]
- area_pos, cent_pos, bounds_pos= pointBounds(new_points_pos)
-
- # 45d rotations only need to be tested in 1 direction.
- if rot_angle == 45:
- area_neg= area_pos
- else:
- new_points_neg= [v*mat_neg for v in current_points]
- area_neg, cent_neg, bounds_neg= pointBounds(new_points_neg)
-
-
- # Works!
- #print 'Testing angle', rot_angle, current_area, area_pos, area_neg
-
- best_area= min(area_pos, area_neg, current_area)
- if area_pos == best_area:
- current_area= area_pos
- cent= cent_pos
- bounds= bounds_pos
- current_points= new_points_pos
- total_rot_angle+= rot_angle
- elif rot_angle != 45 and area_neg == best_area:
- current_area= area_neg
- cent= cent_neg
- bounds= bounds_neg
- current_points= new_points_neg
- total_rot_angle-= rot_angle
-
- rot_angle *= 0.5
-
- # Return the optimal rotation.
- return total_rot_angle
-
-
-class faceGroup(object):
- '''
- A Group of faces that all use the same image, each group has its UVs packed into a square.
- '''
- __slots__= 'xmax', 'ymax', 'xmin', 'ymin',\
- 'image', 'faces', 'box_pack', 'size', 'ang', 'rot_mat', 'cent'\
-
- def __init__(self, mesh_list, image, size, PREF_IMAGE_MARGIN):
- self.image= image
- self.size= size
- self.faces= [f for me in mesh_list for f in me.faces if f.mode & TEXMODE and f.image == image]
-
- # Find the best rotation.
- all_points= [uv for f in self.faces for uv in f.uv]
- bountry_indicies= BPyMathutils.convexHull(all_points)
- bountry_points= [all_points[i] for i in bountry_indicies]
-
- # Pre Rotation bounds
- self.cent= pointBounds(bountry_points)[1]
-
- # Get the optimal rotation angle
- self.ang= bestBoundsRotation(bountry_points)
- self.rot_mat= RotationMatrix(self.ang, 2), RotationMatrix(-self.ang, 2)
-
- # Post rotation bounds
- bounds= pointBounds([\
- ((uv-self.cent) * self.rot_mat[0]) + self.cent\
- for uv in bountry_points])[2]
-
- # Break the bounds into useable values.
- xmin, ymin, xmax, ymax= bounds
-
- # Store the bounds, include the margin.
- # The bounds rect will need to be rotated to the rotation angle.
- self.xmax= xmax + (PREF_IMAGE_MARGIN/size[0])
- self.xmin= xmin - (PREF_IMAGE_MARGIN/size[0])
- self.ymax= ymax + (PREF_IMAGE_MARGIN/size[1])
- self.ymin= ymin - (PREF_IMAGE_MARGIN/size[1])
-
- self.box_pack=[\
- 0.0, 0.0,\
- size[0]*(self.xmax - self.xmin),\
- size[1]*(self.ymax - self.ymin),\
- image.name]
-
- '''
- # default.
- self.scale= 1.0
-
- def set_worldspace_scale(self):
- scale_uv= 0.0
- scale_3d= 0.0
- for f in self.faces:
- for i in xrange(len(f.v)):
- scale_uv+= (f.uv[i]-f.uv[i-1]).length * 0.1
- scale_3d+= (f.v[i].co-f.v[i-1].co).length * 0.1
- self.scale= scale_3d/scale_uv
- '''
-
-
-
- def move2packed(self, width, height):
- '''
- Moves the UV coords to their packed location
- using self.box_pack as the offset, scaler.
- box_pack must be set to its packed location.
- width and weight are the w/h of the overall packed area's bounds.
- '''
- # packedLs is a list of [(anyUniqueID, left, bottom, width, height)...]
- # Width and height in float pixel space.
-
- # X Is flipped :/
- #offset_x= (1-(self.box_pack[1]/d)) - (((self.xmax-self.xmin) * self.image.size[0])/d)
- offset_x= self.box_pack[0]/width
- offset_y= self.box_pack[1]/height
-
- for f in self.faces:
- for uv in f.uv:
- uv_rot= ((uv-self.cent) * self.rot_mat[0]) + self.cent
- uv.x= offset_x+ (((uv_rot.x-self.xmin) * self.size[0])/width)
- uv.y= offset_y+ (((uv_rot.y-self.ymin) * self.size[1])/height)
-
-def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_KEEP_ASPECT, PREF_IMAGE_MARGIN): #, PREF_SIZE_FROM_UV=True):
- '''
- Main packing function
-
- All meshes from mesh_list must have faceUV else this function will fail.
- '''
- face_groups= {}
-
- for me in mesh_list:
- for f in me.faces:
- if f.mode & TEXMODE:
- image= f.image
- if image:
- try:
- face_groups[image.name] # will fail if teh groups not added.
- except:
- try:
- size= image.size
- except:
- B.Draw.PupMenu('Aborting: Image cold not be loaded|' + image.name)
- return
-
- face_groups[image.name]= faceGroup(mesh_list, image, size, PREF_IMAGE_MARGIN)
-
- if not face_groups:
- B.Draw.PupMenu('No Images found in mesh(es). Aborting!')
- return
-
- if len(face_groups)<2:
- B.Draw.PupMenu('Only 1 image found|Select a mesh(es) using 2 or more images.')
- return
-
- '''
- if PREF_SIZE_FROM_UV:
- for fg in face_groups.itervalues():
- fg.set_worldspace_scale()
- '''
-
- # RENDER THE FACES.
- render_scn= B.Scene.New()
- render_scn.makeCurrent()
- render_context= render_scn.getRenderingContext()
- render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path.
-
- PREF_IMAGE_PATH_EXPAND= B.sys.expandpath(PREF_IMAGE_PATH) + '.png'
-
- # TEST THE FILE WRITING.
- try:
- # Can we write to this file???
- f= open(PREF_IMAGE_PATH_EXPAND, 'w')
- f.close()
- except:
- B.Draw.PupMenu('Error%t|Could not write to path|' + PREF_IMAGE_PATH_EXPAND)
- return
-
- render_context.imageSizeX(PREF_IMAGE_SIZE)
- render_context.imageSizeY(PREF_IMAGE_SIZE)
- render_context.enableOversampling(True)
- render_context.setOversamplingLevel(16)
- render_context.setRenderWinSize(100)
- render_context.setImageType(Render.PNG)
- render_context.enableExtensions(True)
- render_context.enablePremultiply() # No alpha needed.
- render_context.enableRGBAColor()
- render_context.threads = 2
-
- #Render.EnableDispView() # Broken??
-
- # New Mesh and Object
- render_mat= B.Material.New()
- render_mat.mode |= \
- B.Material.Modes.SHADELESS | \
- B.Material.Modes.TEXFACE | \
- B.Material.Modes.TEXFACE_ALPHA | \
- B.Material.Modes.ZTRANSP
-
- render_mat.setAlpha(0.0)
-
- render_me= B.Mesh.New()
- render_me.verts.extend([Vector(0,0,0)]) # Stupid, dummy vert, preverts errors. when assigning UV's/
- render_ob= B.Object.New('Mesh')
- render_ob.link(render_me)
- render_scn.link(render_ob)
- render_me.materials= [render_mat]
-
-
- # New camera and object
- render_cam_data= B.Camera.New('ortho')
- render_cam_ob= B.Object.New('Camera')
- render_cam_ob.link(render_cam_data)
- render_scn.link(render_cam_ob)
- render_scn.objects.camera = render_cam_ob
-
- render_cam_data.type= 'ortho'
- render_cam_data.scale= 1.0
-
-
- # Position the camera
- render_cam_ob.LocZ= 1.0
- render_cam_ob.LocX= 0.5
- render_cam_ob.LocY= 0.5
-
- # List to send to to boxpack function.
- boxes2Pack= [ fg.box_pack for fg in face_groups.itervalues()]
- packWidth, packHeight = B.Geometry.BoxPack2D(boxes2Pack)
-
- if PREF_KEEP_ASPECT:
- packWidth= packHeight= max(packWidth, packHeight)
-
-
- # packedLs is a list of [(anyUniqueID, left, bottom, width, height)...]
- # Re assign the face groups boxes to the face_group.
- for box in boxes2Pack:
- face_groups[ box[4] ].box_pack= box # box[4] is the ID (image name)
-
-
- # Add geometry to the mesh
- for fg in face_groups.itervalues():
- # Add verts clockwise from the bottom left.
- _x= fg.box_pack[0] / packWidth
- _y= fg.box_pack[1] / packHeight
- _w= fg.box_pack[2] / packWidth
- _h= fg.box_pack[3] / packHeight
-
- render_me.verts.extend([\
- Vector(_x, _y, 0),\
- Vector(_x, _y +_h, 0),\
- Vector(_x + _w, _y +_h, 0),\
- Vector(_x + _w, _y, 0),\
- ])
-
- render_me.faces.extend([\
- render_me.verts[-1],\
- render_me.verts[-2],\
- render_me.verts[-3],\
- render_me.verts[-4],\
- ])
-
- target_face= render_me.faces[-1]
- target_face.image= fg.image
- target_face.mode |= TEXMODE
-
- # Set the UV's, we need to flip them HOZ?
- target_face.uv[0].x= target_face.uv[1].x= fg.xmax
- target_face.uv[2].x= target_face.uv[3].x= fg.xmin
-
- target_face.uv[0].y= target_face.uv[3].y= fg.ymin
- target_face.uv[1].y= target_face.uv[2].y= fg.ymax
-
- for uv in target_face.uv:
- uv_rot= ((uv-fg.cent) * fg.rot_mat[1]) + fg.cent
- uv.x= uv_rot.x
- uv.y= uv_rot.y
-
- render_context.render()
- Render.CloseRenderWindow()
- render_context.saveRenderedImage(PREF_IMAGE_PATH_EXPAND)
-
- #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND):
- # raise 'Error!!!'
-
-
- # NOW APPLY THE SAVED IMAGE TO THE FACES!
- #print PREF_IMAGE_PATH_EXPAND
- try:
- target_image= B.Image.Load(PREF_IMAGE_PATH_EXPAND)
- except:
- B.Draw.PupMenu('Error: Could not render or load the image at path|' + PREF_IMAGE_PATH_EXPAND)
- return
-
- # Set to the 1 image.
- for me in mesh_list:
- for f in me.faces:
- if f.mode & TEXMODE and f.image:
- f.image= target_image
-
- for fg in face_groups.itervalues():
- fg.move2packed(packWidth, packHeight)
-
- scn.makeCurrent()
- render_me.verts= None # free a tiny amount of memory.
- B.Scene.Unlink(render_scn)
- target_image.makeCurrent()
-
-
-def main():
- scn= B.Scene.GetCurrent()
- scn_objects = scn.objects
- ob= scn_objects.active
-
- if not ob or ob.type != 'Mesh':
- B.Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- # Create the variables.
- # Filename without path or extension.
- newpath= B.Get('filename').split('/')[-1].split('\\')[-1].replace('.blend', '')
-
- PREF_IMAGE_PATH = B.Draw.Create('//%s_grp' % newpath)
- PREF_IMAGE_SIZE = B.Draw.Create(1024)
- PREF_IMAGE_MARGIN = B.Draw.Create(6)
- PREF_KEEP_ASPECT = B.Draw.Create(0)
- PREF_ALL_SEL_OBS = B.Draw.Create(0)
-
- pup_block = [\
- 'Image Path: (no ext)',\
- ('', PREF_IMAGE_PATH, 3, 100, 'Path to new Image. "//" for curent blend dir.'),\
- 'Image Options',
- ('Pixel Size:', PREF_IMAGE_SIZE, 64, 4096, 'Image Width and Height.'),\
- ('Pixel Margin:', PREF_IMAGE_MARGIN, 0, 64, 'Use a margin to stop mipmapping artifacts.'),\
- ('Keep Aspect', PREF_KEEP_ASPECT, 'If disabled, will stretch the images to the bounds of the texture'),\
- 'Texture Source',\
- ('All Sel Objects', PREF_ALL_SEL_OBS, 'Combine all selected objects into 1 texture, otherwise active object only.'),\
- ]
-
- if not B.Draw.PupBlock('Consolidate images...', pup_block):
- return
-
- PREF_IMAGE_PATH= PREF_IMAGE_PATH.val
- PREF_IMAGE_SIZE= PREF_IMAGE_SIZE.val
- PREF_IMAGE_MARGIN= float(PREF_IMAGE_MARGIN.val) # important this is a float otherwise division wont work properly
- PREF_KEEP_ASPECT= PREF_KEEP_ASPECT.val
- PREF_ALL_SEL_OBS= PREF_ALL_SEL_OBS.val
-
- if PREF_ALL_SEL_OBS:
- mesh_list= [ob.getData(mesh=1) for ob in scn_objects.context if ob.type=='Mesh']
- # Make sure we have no doubles- dict by name, then get the values back.
-
- for me in mesh_list: me.tag = False
-
- mesh_list_new = []
- for me in mesh_list:
- if me.faceUV and me.tag==False:
- me.tag = True
- mesh_list_new.append(me)
-
- # replace list with possible doubles
- mesh_list = mesh_list_new
-
- else:
- mesh_list= [ob.getData(mesh=1)]
- if not mesh_list[0].faceUV:
- B.Draw.PupMenu('Error, active mesh has no images, Aborting!')
- return
-
- consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_KEEP_ASPECT, PREF_IMAGE_MARGIN)
- B.Window.RedrawAll()
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/image_billboard.py b/release/scripts/image_billboard.py
deleted file mode 100644
index 54f0f7c5c55..00000000000
--- a/release/scripts/image_billboard.py
+++ /dev/null
@@ -1,269 +0,0 @@
-#!BPY
-"""
-Name: 'Billboard Render on Active'
-Blender: 242
-Group: 'Image'
-Tooltip: 'Selected objects and lamps to rendered faces on the act mesh'
-"""
-__author__= "Campbell Barton"
-__url__= ["blender", "blenderartist"]
-__version__= "1.0"
-
-__bpydoc__= """\
-Render Billboard Script
-This can texture a simple billboard mesh from any number of selected objects.
-
-Renders objects in the selection to quad faces on the active mesh.
-
-Usage
-* Light your model or enable the shadless flag so it is visible
-* Make a low poly mesh out of quads with 90d corners. (this will be you billboard mesh)
-* Select the model and any lamps that light it
-* Select the billboard mesh so that it is active
-* Run this script, Adjust settings such as image size or oversampling.
-* Select a place to save the PNG image.
-* Once the script has finished running return to the 3d view by pressing Shift+F5
-* To see the newly applied textures change the drawtype to 'Textured Solid'
-"""
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell J Barton 2006
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Mesh, Material, Draw
-import BPyMathutils
-import bpy
-import BPyRender
-from Blender.Scene import Render
-
-# reload(BPyRender)
-# reload(BPyMathutils)
-
-import os
-Vector= Blender.Mathutils.Vector
-
-def alpha_mat(image):
- # returns a material useable for
- mtl= bpy.data.materials.new()
- mtl.mode |= (Material.Modes.SHADELESS | Material.Modes.ZTRANSP | Material.Modes.FULLOSA | Material.Modes.TEXFACE | Material.Modes.TEXFACE_ALPHA )
- return mtl
-
-# PupBlock Settings
-GLOBALS= {}
-PREF_RES= Draw.Create(512)
-PREF_TILE_RES= Draw.Create(256)
-PREF_AA = Draw.Create(1)
-PREF_ALPHA= Draw.Create(1)
-PREF_Z_OFFSET = Draw.Create(10.0)
-PREF_IMG_PACK= Draw.Create(1)
-
-
-def save_billboard(PREF_IMAGE_PATH):
- Blender.Window.WaitCursor(1)
- # remove png, add it later
- PREF_IMAGE_PATH= PREF_IMAGE_PATH.replace('.png', '')
-
- ob_sel= GLOBALS['ob_sel']
- me_ob = GLOBALS['me_ob']
- me_data = GLOBALS['me_data']
-
- time= Blender.sys.time()
-
- me_mat= me_ob.matrixWorld
-
- # Render images for all faces
- face_data= [] # Store faces, images etc
- boxes2Pack= []
- me_data.faceUV= True
-
- for i, f in enumerate(me_data.faces):
- no= f.no
-
- # Offset the plane by the zoffset on the faces normal
- plane= [v.co * me_mat for v in f]
-
- # Horizontal stacking, make sure 0,1 and 2,3 are the longest
- if\
- (plane[0]-plane[1]).length + (plane[2]-plane[3]).length < \
- (plane[1]-plane[2]).length + (plane[3]-plane[0]).length:
- plane.append(plane.pop(0))
- rot90= True
- else:
- rot90= False
-
- no= Blender.Mathutils.QuadNormal(*plane)
- plane= [v + no*PREF_Z_OFFSET.val for v in plane]
-
- cent= (plane[0]+plane[1]+plane[2]+plane[3] ) /4.0
- camera_matrix= BPyMathutils.plane2mat(plane)
- tmp_path= '%s_%d' % (PREF_IMAGE_PATH, i)
- img= BPyRender.imageFromObjectsOrtho(ob_sel, tmp_path, PREF_TILE_RES.val, PREF_TILE_RES.val, PREF_AA.val, PREF_ALPHA.val, camera_matrix)
- img.reload()
- #img.pack() # se we can keep overwriting the path
- #img.filename= ""
-
- if rot90:
- f.uv=Vector(1,1), Vector(0,1), Vector(0,0), Vector(1,0)
- else:
- f.uv= Vector(0,1), Vector(0,0), Vector(1,0), Vector(1,1)
-
- if not PREF_IMG_PACK.val:
- f.mode |= Mesh.FaceModes.TEX
- f.image = img
-
- if PREF_ALPHA.val:
- f.transp |= Mesh.FaceTranspModes.ALPHA
- else:
- w= ((plane[0]-plane[1]).length + (plane[2]-plane[3]).length)/2
- h= ((plane[1]-plane[2]).length + (plane[3]-plane[0]).length)/2
-
- face_data.append( (f, img) )
- boxes2Pack.append( [0.0,0.0,h, w, i] )
-
- if PREF_IMG_PACK.val:
- # pack the quads into a square
- packWidth, packHeight = Blender.Geometry.BoxPack2D(boxes2Pack)
-
- render_obs= []
-
- render_mat= alpha_mat(img)
-
- # Add geometry to the mesh
- for box in boxes2Pack:
- i= box[4]
-
- orig_f, img= face_data[i]
-
- # New Mesh and Object
-
- render_me= bpy.data.meshes.new()
-
- render_ob= Blender.Object.New('Mesh')
- render_me.materials= [render_mat]
- render_ob.link(render_me)
-
- render_obs.append(render_ob)
-
- # Add verts clockwise from the bottom left.
- _x= box[0] / packWidth
- _y= box[1] / packHeight
- _w= box[2] / packWidth
- _h= box[3] / packHeight
-
-
- render_me.verts.extend([\
- Vector(_x, _y, 0),\
- Vector(_x, _y +_h, 0),\
- Vector(_x + _w, _y +_h, 0),\
- Vector(_x + _w, _y, 0),\
- ])
-
- render_me.faces.extend(list(render_me.verts))
- render_me.faceUV= True
-
- render_me.faces[0].uv = [Vector(0,0), Vector(0,1), Vector(1,1), Vector(1,0)]
- render_me.faces[0].image = img
-
- # Set the UV's, we need to flip them HOZ?
- for uv in orig_f.uv:
- uv.x = _x + (uv.x * _w)
- uv.y = _y + (uv.y * _h)
-
- target_image= BPyRender.imageFromObjectsOrtho(render_obs, PREF_IMAGE_PATH, PREF_RES.val, PREF_RES.val, PREF_AA.val, PREF_ALPHA.val, None)
- target_image.reload() # incase your overwriting an existing image.
-
- # Set to the 1 image.
- for f in me_data.faces:
- f.image= target_image
- if PREF_ALPHA.val:
- f.transp |= Mesh.FaceTranspModes.ALPHA
-
- # Free the images data and remove
- for data in face_data:
- img= data[1]
- os.remove(img.filename)
- img.reload()
-
- # Finish pack
-
- me_data.update()
- me_ob.makeDisplayList()
- Blender.Window.WaitCursor(0)
- print '%.2f secs taken' % (Blender.sys.time()-time)
-
-
-def main():
- scn= bpy.data.scenes.active
- ob_sel= list(scn.objects.context)
-
- PREF_KEEP_ASPECT= False
-
- # Error Checking
- if len(ob_sel) < 2:
- Draw.PupMenu("Error%t|Select 2 mesh objects")
- return
-
- me_ob= scn.objects.active
-
- if not me_ob:
- Draw.PupMenu("Error%t|No active mesh selected.")
-
- try:
- ob_sel.remove(me_ob)
- except:
- pass
-
- if me_ob.type != 'Mesh':
- Draw.PupMenu("Error%t|Active Object must be a mesh to write billboard images too")
- return
-
- me_data= me_ob.getData(mesh=1)
-
- for f in me_data.faces:
- if len(f) != 4:
- Draw.PupMenu("Error%t|Active mesh must have only quads")
- return
-
-
- # Get user input
- block = [\
- 'Image Pixel Size',\
- ("Packed Size: ", PREF_RES, 128, 2048, "Pixel width and height to render the billboard to"),\
- ("Tile Size: ", PREF_TILE_RES, 64, 1024, "Pixel width and height for each tile to render to"),\
- 'Render Settings',\
- ("Pack Final", PREF_IMG_PACK , "Pack the image for each face into images into a single image"),\
- ("Oversampling", PREF_AA , "Higher quality woth extra sampling"),\
- ("Alpha Clipping", PREF_ALPHA , "Render empty areas as transparent"),\
- ("Cam ZOffset: ", PREF_Z_OFFSET, 0.1, 100, "Distance to place the camera away from the quad when rendering")\
- ]
-
- if not Draw.PupBlock("Billboard Render", block):
- return
-
- # Set globals
- GLOBALS['ob_sel'] = ob_sel
- GLOBALS['me_ob'] = me_ob
- GLOBALS['me_data'] = me_data
-
- Blender.Window.FileSelector(save_billboard, 'SAVE BILLBOARD', Blender.sys.makename(ext='.png'))
- # save_billboard('/tmp/test.png')
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/image_edit.py b/release/scripts/image_edit.py
deleted file mode 100644
index cae40b74097..00000000000
--- a/release/scripts/image_edit.py
+++ /dev/null
@@ -1,158 +0,0 @@
-#!BPY
-"""
-Name: 'Edit Externally'
-Blender: 242a
-Group: 'Image'
-Tooltip: 'Open in an application for editing. (hold Shift to configure)'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ["blender", "blenderartists.org"]
-__version__ = "1.0"
-__bpydoc__ = """\
-This script opens the current image in an external application for editing.
-
-Usage:
-Choose an image for editing in the UV/Image view.
-
-To configure the application to open the image with, hold Shift as you
-click on this menu item.
-
-For first time users try running the default application for your
-operating system. If the application does not open you can type in
-the full path. You can choose that the last entered application will
-be saved as a default.
-
-* Note, default commants for opening an image are "start" for win32
-and "open" for macos. This will use the system default associated
-application.
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell J Barton 2006
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Image, sys, Draw, Registry
-
-try:
- import subprocess
- import sys as py_sys
- platform = py_sys.platform
-except:
- Draw.PupMenu('Error: Recent version of Python not installed.')
- subprocess=None
-
-def os_run(appstring, filename):
- '''
- Run the app, take into account different python versions etc
- looks like python 2.6 wants a list for
- '''
-
- # evil trick, temp replace spaces so we can allow spaces in filenames
- # also allows multiple instances of %f
- appstring = appstring.replace(' ', '\t')
- appstring = appstring.replace('%f', filename)
- appstring = appstring.split('\t')
-
- print ' '.join(appstring)
-
- try: # only python 2.6 wants a list?
- p = subprocess.Popen(appstring)
- except:
- p = subprocess.Popen(' '.join(appstring))
-
-
-def edit_extern(image=None):
-
- if not image:
- image = Image.GetCurrent()
-
- if not image: # Image is None
- Draw.PupMenu('ERROR: Please select active Image.')
- return
- if image.packed:
- Draw.PupMenu('ERROR: Image is packed, unpack before editing.')
- return
-
- imageFileName = sys.expandpath( image.filename )
-
- if not sys.exists(imageFileName):
- Draw.PupMenu('ERROR: Image path does not exist.')
- return
-
- pupblock = [imageFileName.split('/')[-1].split('\\')[-1]]
-
- new_text= False
- try:
- appstring = Registry.GetKey('ExternalImageEditor', True)
- appstring = appstring['path']
-
- # for ZanQdo if he removed the path from the textbox totaly. ;) - Cam
- if not appstring or appstring.find('%f')==-1:
- new_text= True
- except:
- new_text= True
-
- if new_text:
- pupblock.append('first time, set path.')
- if platform == 'win32':
- # Example of path to popular image editor... ;-)
- # appstring = '"C:\\Program Files\\Adobe\\Photoshop CS\\photoshop.exe" "%f"'
- # Have to add "cmd /c" to make sure we're using Windows shell.
- appstring = 'cmd /c start "" /B "%f"'
- elif platform == 'darwin':
- appstring = 'open "%f"'
- else:
- appstring = 'gimp %f'
-
- appstring_but = Draw.Create(appstring)
- save_default_but = Draw.Create(0)
-
- pupblock.append(('editor: ', appstring_but, 0, 99, 'Path to application, %f will be replaced with the image path.'))
- pupblock.append(('Set Default', save_default_but, 'Store this path in the blender registry.'))
-
- # Only configure if Shift is held,
- if Blender.Window.GetKeyQualifiers() & Blender.Window.Qual.SHIFT:
- if not Draw.PupBlock('External Image Editor...', pupblock):
- return
-
- appstring = appstring_but.val
- save_default= save_default_but.val
-
- if save_default:
- Registry.SetKey('ExternalImageEditor', {'path':appstring}, True)
-
- if appstring.find('%f') == -1:
- Draw.PupMenu('ERROR: No filename specified! ("%f")')
- return
-
- # -------------------------------
-
- os_run(appstring, imageFileName)
-
-
-
-def main():
- edit_extern()
-
-
-if __name__ == '__main__' and subprocess:
- main()
diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py
deleted file mode 100644
index b3bee11c464..00000000000
--- a/release/scripts/import_dxf.py
+++ /dev/null
@@ -1,6225 +0,0 @@
-#!BPY
-
-"""
-Name: 'Autodesk DXF (.dxf .dwg)'
-Blender: 249
-Group: 'Import'
-Tooltip: 'Import for DWG/DXF geometry data.'
-"""
-__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
-__version__ = '1.12 - 2009.06.16 by migius'
-__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
- "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
-__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
-__bpydoc__ = """\
-This script imports objects from DWG/DXF (2d/3d) into Blender.
-
-This script imports 2d and 3d geometery from DXF files.
-It supports DWG format too, with help of an external converter.
-Supported DXF format versions: from (r2.5) r12 up to r2008.
-Enhanced features are:
-- configurable object filtering and geometry manipulation,
-- configurable material pre-processing,
-- DXF-code analyze and reporting.
-
-Supported DXF r12 objects:
-LINE,
-POINT,
-SOLID,
-TRACE,
-TEXT,
-INSERT (=block),
-MINSERT (=array of blocks),
-CIRCLE,
-ARC,
-3DFACE,
-2d-POLYLINE (=in plane, incl. arc, variable-width, curve, spline),
-3d-POLYLINE (=non-plane),
-3d-POLYMESH,
-3d-POLYFACE,
-VIEW, VPORT
-XREF (External Reference).
-
-Supported DXF>r12 objects:
-ELLIPSE,
-LWPOLYLINE (LightWeight Polyline),
-SPLINE,
-(todo v1.13) MLINE,
-(todo v1.13) MTEXT
-
-Unsupported objects:
-DXF r12: DIMENSION.
-DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK
-
-Supported geometry: 2d and 3d DXF-objects.
-Curves imported as Blender curves or meshes optionally.
-
-Supported layout modes:
-"model space" is default,
-"paper space" as option (= "layout views")
-
-Supported scene definition objects produced with AVE_RENDER:
-scene: selection of lights assigned to the camera,
-lights: DIRECT, OVERHEAD, SH_SPOT,
-(wip v1.13 import of AVE_RENDER material definitions)
-
-Hierarchy:
-Entire DXF BLOCK hierarchy is preserved after import into Blender
-(BLOCKs as groups on layer19, INSERTs as dupliGroups on target layer).
-
-Supported properties:
-visibility status,
-frozen status,
-thickness,
-width,
-color,
-layer,
-(todo v1.13: XDATA, grouped status)
-It is recommended to use DXF-object properties for assign Blender materials.
-
-Notes:
-- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
-- Blocks are created on layer 19 then referenced at each insert point.
-- support for DXF-files up to 160MB on systems with 1GB RAM
-- DXF-files with over 1500 objects decrease import performance.
-The problem is not the inefficiency of python-scripting but Blenders performance
-in creating new objects in scene database - probably a database management problem.
-
-"""
-
-"""
-History:
- v1.0 - 2007/2008/2009 by migius
- planned tasks:
- -- (to see more, search for "--todo--" in script code)
- -- command-line-mode/batch-mode
- -- in-place-editing for dupliGroups
- -- support for MLINE (is exported to r12 as BLOCK*Unnamed with LINEs)
- -- support for MTEXT (is exported to r12 as TEXT???)
- -- blender_object.properties['dxf_layer_name']
- -- better support for long dxf-layer-names
- -- add configuration file.ini handles multiple material setups
- -- added f_layerFilter
- -- to-check: obj/mat/group/_mapping-idea from ideasman42
- -- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs
- -- "normalize Z" option to correct non-planar figures
- -- LINEs need "width" in 3d-space incl vGroups
- -- support width_force for LINEs/ELLIPSEs = "solidify"
- -- add better support for color_index BYLAYER=256, BYBLOCK=0
- -- bug: "oneMesh" produces irregularly errors
- -- bug: Registry recall from hd_cache ?? only win32 bug??
- -- support DXF-definitions of autoshade: scene, lights and cameras
- -- support ortho mode for VIEWs and VPORTs as cameras
-
- v1.12 - 2009.06.16 by migius
- d7 fix for ignored BLOCKs (e.g. *X) which are members of other BLOCKs
- v1.12 - 2009.05.27 by migius
- d6 bugfix negative scaled INSERTs - isLeftHand(Matrix) check
- v1.12 - 2009.05.26 by migius
- d5 changed to the new 2.49 method Vector.cross()
- d5 bugfix WORLDY(1,1,0) to (0,1,0)
- v1.12 - 2009.04.11 by migius
- d4 added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter
- v1.12 - 2009.03.14 by migius
- d3 removed all set()functions (problem with osx/python<2.4 reported by Blinkozo)
- d3 code-cleaning
- v1.12 - 2009.01.14 by migius
- d2 temp patch for noname BLOCKS (*X,*U,*D)
- v1.12 - 2008.11.16 by migius
- d1 remove try_finally: cause not supported in python <2.5
- d1 add Bezier curves bevel radius support (default 1.0)
- v1.12 - 2008.08.03 by migius
- c2 warningfix: relocating of globals: layersmap, oblist
- c2 modif UI: buttons newScene+targetLayer moved to start panel
- v1.12 - 2008.07.04 by migius
- c1 added control Curve's OrderU parameter
- c1 modif UI: preset buttons X-2D-3D moved to start panel
- b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
- b5 rebuild UI: global preset 2D for Curve-Import
- b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out
- b5 added support for SPLINEs, added control OrderU parameter
- b5 rewrote draw module for NURBS_curve and Bezier_curve
- v1.12 - 2008.06.22 by migius
- b4 change versioning system 1.0.12 -> 1.12
- b4 print at start version-info to console
- b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
- v1.0.12: 2008.05.24 by migius
- b2 added support for LWPOLYLINEs
- b2 added support for ProE in readerDXF.py
- v1.0.12: 2008.02.08 by migius
- b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
- a9 bugfix by non-existing tables views, vports, layers (Kai reported)
- v1.0.12: 2008.01.17 by migius
- a8 lately used INI-dir/filename persistently stored in Registry
- a8 lately used DXF-dir/filename persistently stored in Registry
- a7 fix missing layersmap{} for dxf-files without "section:layer"
- a6 added support for XREF external referenced BLOCKs
- a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
- a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
- a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
- a6 added try_finally: f.close() for all IO-files
- a6 added handling for TypeError raise
- a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
- a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
- a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
- a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
- a4 added to UI: BLOCK-(n): filter noname/hatch BLOCKs *X...
- a2 g_scale_as is no more GUI_A-variable
- a2 bugfix "material": negative sign color_index
- a2 added support for BLOCKs defined with origin !=(0,0,0)
- a1 added 'global.reLocation-vector' option
-
- v1.0.11: 2007.11.24 by migius
- c8 added 'curve_resolution_U' option
- c8 added context_sensitivity for some UI-buttons
- c8 bugfix ELLIPSE rotation, added closed_variant and caps
- c7 rebuild UI: new layout, grouping and meta-buttons
- c6 rewritten support for ELLIPSE mesh & curve representation
- c6 restore selector-buttons for DXF-drawTypes: LINE & Co
- c6 change header of INI/INF-files: # at begin
- c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
- c5 fixing 'material_on' option
- c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
- c3 human-formating of data in INI-Files
- c2 added "caps" for closed Bezier-curves
- c2 added "set elevation" UI-option
- c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
- b9 many bugs fixed
- b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
- b8 added "import from frozen layers" UI-option
- b8 added "import from paper space" UI-option
- b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
- b8 added meshSmooth_on for circle/arc/polyline
- b8 added vertexGroups for circle/arc
- b7 added width_force for ARCs/CIRCLEs = "thin_box" option
- b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
- b2 fixing material assignment by LAYER+COLOR
- b1 fixing Bezier curves representation of POLYLINEs-arc-segments
- b0 added global_scale_presets: "yard/feet/inch to meter"
-
- v1.0.10: 2007.10.18 by migius
- a6 bugfix CircleDrawCaps for OSX
- a5 added two "curve_res" UI-buttons for Bezier curves representation
- a5 improved Bezier curves representation of circles/arcs: correct handlers
- a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments.
- a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
- a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
- a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
- a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
- a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
-
- v1.0.beta09: 2007.09.02 by migius
- g5 redesign UI: grouping of buttons
- g3 update multi-import-mode: <*.*> button
- g- added multi-import-mode: (path/*) for importing many dxf-files at once
- g- added import into newScene
- g- redesign UI: user presets, into newScene-import
- f- cleanup code
- f- bugfix: thickness for Bezier/Bsplines into Blender-curves
- f- BlenderWiki documentation, on-line Manual
- f- added import POLYLINE-Bsplines into Blender-NURBSCurves
- f- added import POLYLINE-arc-segments into Blender-BezierCurves
- f- added import POLYLINE-Bezier-curves into Blender-Curves
- d5 rewrite: Optimization Levels, added 'directDrawing'
- d4 added: f_set_thick(controlled by ini-parameters)
- d4 bugfix: face-normals in objects with minus thickness
- d4 added: placeholder'Empty'-size in f_Insert.draw
- d3 rewrite f_Text.Draw: added support for all Text's parameters
- d2 redesign: progressbar
- e- tuning by ideasman42: better use of the Py API.
- c- tuning by ideasman42
- b- rewrite f_Text.Draw rotation/transform
- b- bugfix: POLYLINE-segment-intersection more reliable now
- b- bugfix: circle:_thic, 'Empties':no material_assignment
- b- added material assignment (from layer and/or color)
- a- added empty, cylinder and UVsphere for POINTs
- a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
- a- redesign f_Drawer for block_definitions
- a- rewrite import into Blender-Curve-Object
-
- v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
- l- bugfix: solid_vgroups, clean:scene.objects.new()
- l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
- k- bugfix UI:fileSelect() for MacOSX os.listdir()
- k- added reset/save/load for config-data
- k- redesign keywords/drawTypes/Draw.Create_Buttons
- j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
- i- rewritten Class:Settings for better config-parameter management
- h- bugfix: face-normals in objects with minus thickness
- h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
- h- beautify code, whitespace->tabs
- h- added settings.thic_force switch for forcing thickness
- h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
- Vertex-Groups(color_name) (fewer objects = better import performance)
- g- rewrote: insert-point-handle-object is a small tetrahedron
- e- bugfix: closed-polymesh3d
- - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
- - added 2d/3d-support for Polyline_Width incl. angle intersection
- beta07: 2007.06.19 by migius
- - added 3d-support for LWPolylines
- - added 2d/3d-support for Points
- beta06: 2007.06.15 by migius
- - cleanup code
- - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
- beta05: 2007.06.14 by migius
- - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
- - added Global-Scale for size control of imported scenes
- beta04: 2007.06.12 by migius
- - rewrote the f_drawBulge for correct import the arc-segments of Polylines
- beta03: 2007.06.10 by migius
- - rewrote interface
- beta02: 2007.06.09 by migius
- - added 3d-support for Arcs and Circles
- - added support for Object_Thickness(=height)
- beta01: 2007.06.08 by migius
- - added 3d-support for Blocks/Inserts within nested-structures
- - rewrote f_transform for correct 3d-location/3d-rotation
- - added 3d-support Lines, 3dFaces
- - added 2d+3d-support for Solids and Traces
-
- v0.9 - 2007.01 by kitsu: (for 2.43)
- - first draft of true POLYLINE import
- -
-
- v0.8 - 2006.12 by kitsu:
- - first draft of object space coordinates OCS import
- -
-
- v0.5b - 2006.10 by kitsu: (for 2.42a)
- - dxfReader.py
- - color_map.py
-
-"""
-
-# --------------------------------------------------------------------------
-# DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Mathutils, BezTriple, Draw, Registry, sys,\
-Text3d, Window, Mesh, Material, Group, Curve
-#from Blender.Mathutils import Vector, Matrix
-#import bpy #not used yet
-#import BPyMessages
-
-from dxfReader import readDXF
-#from dxfReader import get_name, get_layer
-from dxfReader import Object as dxfObject
-from dxfColorMap import color_map
-from math import log10, sqrt, radians, degrees, atan, cos, sin
-
-# osx-patch by Blinkozo
-#todo: avoid additional modules, prefer Blender-build-in test routines
-#import platform
-#if platform.python_version() < '2.4':
-# from sets import Set as set
-#from sys import version_info
-#ver = '%s.%s' % version_info[0:2]
-# end osx-patch
-
-import subprocess
-import os
-if os.name != 'mac':
- try:
- import psyco
- psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
- #psyco.log()
- psyco.full(memory=100)
- psyco.profile(0.05, memory=100)
- psyco.profile(0.2)
- #print 'psyco imported'
- except ImportError:
- print 'psyco not imported'
-
-print '\n\n\n'
-print 'DXF/DWG-Importer v%s *** start ***' %(__version__) #---------------------
-
-SCENE = None
-WORLDX = Mathutils.Vector((1,0,0))
-WORLDY = Mathutils.Vector((0,1,0))
-WORLDZ = Mathutils.Vector((0,0,1))
-
-G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data
-G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units
-G_ORIGIN_Y = 0.0
-G_ORIGIN_Z = 0.0
-MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex"
-ARC_RESOLUTION = 64 #(4-500) arc/circle resolution - number of segments
-ARC_RADIUS = 1.0 #(0.01-100) arc/circle radius for number of segments algorithm
-CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
-CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve
-THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments
-MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness
-MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width
-TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
-ELEVATION = 0.0 #standard elevation = coordinate Z value
-
-BYBLOCK = 0
-BYLAYER = 256
-TARGET_LAYER = 3 #target blender_layer
-GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group
-LAYER_DEF_NAME = 'AAAA' #default layer name
-LAYER_DEF_COLOR = 4 #default layer color
-E_M = 0
-LAB = ". wip .. todo" #"*) parts under construction"
-M_OBJ = 0
-
-FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
-MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001)
-INIFILE_DEFAULT_NAME = 'importDXF'
-INIFILE_EXTENSION = '.ini'
-INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
-INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
-
-AUTO = BezTriple.HandleTypes.AUTO
-FREE = BezTriple.HandleTypes.FREE
-VECT = BezTriple.HandleTypes.VECT
-ALIGN = BezTriple.HandleTypes.ALIGN
-
-UI_MODE = True #activates UI-popup-print, if not multiple files imported
-
-#---- migration to 2.49-------------------------------------------------
-if 'cross' in dir(Mathutils.Vector()):
- #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!')
- def M_CrossVecs(v1,v2):
- return v1.cross(v2) #for up2.49
- def M_DotVecs(v1,v2):
- return v1.dot(v2) #for up2.49
-else:
- def M_CrossVecs(v1,v2):
- return Mathutils.CrossVecs(v1,v2) #for pre2.49
- def M_DotVecs(v1,v2):
- return Mathutils.DotVecs(v1,v2) #for pre2.49
-
-
-#-------- DWG support ------------------------------------------
-extCONV_OK = True
-extCONV = 'DConvertCon.exe'
-extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV)
-if not os.path.isfile(extCONV_PATH):
- extCONV_OK = False
- extCONV_TEXT = 'DWG-Importer cant find external DWG-converter (%s) in Blender script directory.|\
-More details in online Help.' %extCONV
-else:
- if not os.sys.platform.startswith('win'):
- # check if Wine installed:
- if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip():
- extCONV_PATH = 'wine %s'%extCONV_PATH
- else:
- extCONV_OK = False
- extCONV_TEXT = 'The external DWG-converter (%s) needs Wine installed on your system.|\
-More details in online Help.' %extCONV
-#print 'extCONV_PATH = ', extCONV_PATH
-
-
-
-class View: #-----------------------------------------------------------------
- """Class for objects representing dxf VIEWs.
- """
- def __init__(self, obj, active=None):
- """Expects an object of type VIEW as input.
- """
- if not obj.type == 'view':
- raise TypeError, "Wrong type %s for VIEW object!" %obj.type
-
- self.type = obj.type
- self.name = obj.get_type(2)[0]
-# self.data = obj.data[:]
-
-
- self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
- self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
- self.height = obj.get_type(40)[0] #view height (in DCS)
- self.width = obj.get_type(41)[0] #view width (in DCS)
-
- self.dir = [0,0,0]
- self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
- self.dir[1] = getit(obj, 21, 0.0) #
- self.dir[2] = getit(obj, 31, 0.0) #
-
- self.target = [0,0,0]
- self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
- self.target[1] = getit(obj, 22, 0.0) #
- self.target[2] = getit(obj, 32, 0.0) #
-
- self.length = obj.get_type(42)[0] #Lens length
- self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
- self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
- self.twist = obj.get_type(50)[0] #view twist angle in degrees
-
- self.flags = getit(obj, 70, 0)
- self.paperspace = self.flags & 1 #
-
- self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
-
- def __repr__(self):
- return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
-
-
- def draw(self, settings):
- """for VIEW: generate Blender_camera.
- """
- obname = 'vw_%s' %self.name # create camera object name
- #obname = 'ca_%s' %self.name # create camera object name
- obname = obname[:MAX_NAMELENGTH]
-
- if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
- cam= Camera.New('ortho', obname)
- ob= SCENE.objects.new(cam)
- cam.type = 'ortho'
- cam.scale = 1.0 # for ortho cameras
- else:
- cam= Camera.New('persp', obname)
- ob= SCENE.objects.new(cam)
- cam.type = 'persp'
- cam.angle = 60.0 # for persp cameras
- if self.length:
- #cam.angle = 2 * atan(17.5/self.length) * 180/pi
- cam.lens = self.length #for persp cameras
- # hack to update Camera>Lens setting (inaccurate as a focal length)
- #curLens = cam.lens; cam.lens = curLens
- # AutoCAD gets clip distance from target:
- dist = Mathutils.Vector(self.dir).length
- cam.clipEnd = dist - self.clip_back
- cam.clipStart = dist - self.clip_front
-
- cam.drawLimits = 1
- cam.drawSize = 10
-
- v = Mathutils.Vector(self.dir)
-# print 'deb:view cam:', cam #------------
-# print 'deb:view self.target:', self.target #------------
-# print 'deb:view self.dir:', self.dir #------------
-# print 'deb:view self.twist:', self.twist #------------
-# print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
- transform(v.normalize(), -self.twist, ob)
- ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
- return ob
-
-
-class Vport: #-----------------------------------------------------------------
- """Class for objects representing dxf VPORTs.
- """
- def __init__(self, obj, active=None):
- """Expects an object of type VPORT as input.
- """
- if not obj.type == 'vport':
- raise TypeError, "Wrong type %s for VPORT object!" %obj.type
-
- self.type = obj.type
- self.name = obj.get_type(2)[0]
-# self.data = obj.data[:]
- #print 'deb:vport name, data:', self.name #-------
- #print 'deb:vport data:', self.data #-------
-
- self.height = obj.get_type(40)[0] #vport height (in DCS)
- self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
- self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
- self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
-
- self.dir = [0,0,0]
- self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
- self.dir[1] = getit(obj, 26, 0.0) #
- self.dir[2] = getit(obj, 36, 0.0) #
-
- self.target = [0,0,0]
- self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
- self.target[1] = getit(obj, 27, 0.0) #
- self.target[2] = getit(obj, 37, 0.0) #
-
- self.length = obj.get_type(42)[0] #Lens length
- self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
- self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
- self.twist = obj.get_type(51)[0] #view twist angle
-
- self.flags = getit(obj, 70, 0)
- self.paperspace = self.flags & 1 #
-
- self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
-
- def __repr__(self):
- return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
-
- def draw(self, settings):
- """for VPORT: generate Blender_camera.
- """
- obname = 'vp_%s' %self.name # create camera object name
- #obname = 'ca_%s' %self.name # create camera object name
- obname = obname[:MAX_NAMELENGTH]
-
- if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
- cam= Camera.New('ortho', obname)
- ob= SCENE.objects.new(cam)
- cam.type = 'ortho'
- cam.scale = 1.0 # for ortho cameras
- else:
- cam= Camera.New('persp', obname)
- ob= SCENE.objects.new(cam)
- cam.type = 'persp'
- cam.angle = 60.0 # for persp cameras
- if self.length:
- #cam.angle = 2 * atan(17.5/self.length) * 180/pi
- cam.lens = self.length #for persp cameras
- # hack to update Camera>Lens setting (inaccurate as a focal length)
- #curLens = cam.lens; cam.lens = curLens
- # AutoCAD gets clip distance from target:
- dist = Mathutils.Vector(self.dir).length
- cam.clipEnd = dist - self.clip_back
- cam.clipStart = dist - self.clip_front
-
- cam.drawLimits = 1
- cam.drawSize = 10
-
- v = Mathutils.Vector(self.dir)
-# print 'deb:view cam:', cam #------------
-# print 'deb:view self.target:', self.target #------------
-# print 'deb:view self.dir:', self.dir #------------
-# print 'deb:view self.twist:', self.twist #------------
-# print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
- transform(v.normalize(), -self.twist, ob)
- ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
- return ob
-
-
-
-class Layer: #-----------------------------------------------------------------
- """Class for objects representing dxf LAYERs.
- """
- def __init__(self, obj, name=None, color=None, frozen=None):
- """Expects an dxfobject of type layer as input.
- if no dxfobject - creates surogate layer with default parameters
- """
-
- if obj==None:
- self.type = 'layer'
- if name: self.name = name
- else: self.name = LAYER_DEF_NAME
-
- if color: self.color = color
- else: self.color = LAYER_DEF_COLOR
-
- if frozen!=None: self.frozen = frozen
- else: self.frozen = 0
- else:
- if obj.type=='layer':
- self.type = obj.type
- #self.data = obj.data[:]
- if name: self.name = name
- #self.bfname = name #--todo---see layernamesmap in f_getLayersmap ---
- else: self.name = obj.get_type(2)[0] #layer name of object
-
- if color: self.color = color
- else: self.color = obj.get_type(62)[0] #color of object
-
- if frozen!=None: self.frozen = frozen
- else:
- self.flags = obj.get_type(70)[0]
- self.frozen = self.flags & 1
-
- def __repr__(self):
- return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
-
-
-
-def getit(obj, typ, default=None): #------------------------------------------
- """Universal procedure for geting data from list/objects.
- """
- it = default
- if type(obj) == list: #if obj is a list, then searching in a list
- for item in obj:
- #print 'deb:getit item, type(item)', item, type(item)
- try:
- if item[0] == typ:
- it = item[1]
- break #as soon as the first found
- except:
- # --todo-- I found one case where item was a text instance
- # that failed with no __getitem__
- pass
- else: #else searching in Object with get_type-Methode
- item = obj.get_type(typ)
- if item:
- it = item[0]
- #print 'deb:getit:typ, it', typ, it #----------
- return it
-
-
-
-def get_extrusion(data): #-------------------------------------------------
- """Find the axis of extrusion.
-
- Used to get from object_data the objects Object_Coordinate_System (ocs).
- """
- #print 'deb:get_extrusion: data: \n', data #---------------
- vec = [0,0,1]
- vec[0] = getit(data, 210, 0) # 210 = x
- vec[1] = getit(data, 220, 0) # 220 = y
- vec[2] = getit(data, 230, 1) # 230 = z
- #print 'deb:get_extrusion: vec: ', vec #---------------
- return vec
-
-
-#------------------------------------------
-def getSceneChild(name):
- dudu = [i for i in SCENE.objects if i.name==name]
-# dudu = [i for i in SCENE.getChildren() if i.name==name]
- #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
- if dudu!=[]: return dudu[0]
- return None
-
-
-class Solid: #-----------------------------------------------------------------
- """Class for objects representing dxf SOLID or TRACE.
- """
- def __init__(self, obj):
- """Expects an entity object of type solid or trace as input.
- """
- if obj.type == 'trace':
- obj.type = 'solid'
- if not obj.type == 'solid':
- raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
-
- self.type = obj.type
-# self.data = obj.data[:]
-
- self.space = getit(obj, 67, 0)
- self.thic = getit(obj, 39, 0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.extrusion = get_extrusion(obj)
- self.points = self.get_points(obj)
-
-
-
- def get_points(self, data):
- """Gets start and end points for a solid type object.
-
- Solids have 3 or 4 points and fixed codes for each value.
- """
-
- # start x, y, z and end x, y, z = 0
- a = [0, 0, 0]
- b = [0, 0, 0]
- c = [0, 0, 0]
- d = [0, 0, 0]
- a[0] = getit(data, 10, None) # 10 = x
- a[1] = getit(data, 20, None) # 20 = y
- a[2] = getit(data, 30, 0) # 30 = z
- b[0] = getit(data, 11, None)
- b[1] = getit(data, 21, None)
- b[2] = getit(data, 31, 0)
- c[0] = getit(data, 12, None)
- c[1] = getit(data, 22, None)
- c[2] = getit(data, 32, 0)
- out = [a,b,c]
-
- d[0] = getit(data, 13, None)
- if d[0] != None:
- d[1] = getit(data, 23, None)
- d[2] = getit(data, 33, 0)
- out.append(d)
- #print 'deb:solid.vertices:---------\n', out #-----------------------
- return out
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, settings):
- """for SOLID: generate Blender_geometry.
- """
- points = self.points
- if not points: return
- edges, faces = [], []
- l = len(self.points)
-
- obname = 'so_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
-
- vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
- thic = set_thick(self.thic, settings)
- if thic != 0:
- thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
- if thic < 0.0:
- thic_points.extend(points)
- points = thic_points
- else:
- points.extend(thic_points)
-
- if l == 4:
- faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
- [1,5,7,3], [3,7,6,2], [2,6,4,0]]
- vg_left = [2,6,4,0]
- vg_right = [1,5,7,3]
- vg_top = [4,6,7,5]
- vg_bottom = [0,1,3,2]
- vg_start = [0,4,5,1]
- vg_end = [3,7,6,2]
- elif l == 3:
- faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
- vg_top = [3,4,5]
- vg_bottom = [0,1,2]
- vg_left = [2,5,3,0]
- vg_right = [1,4,5,2]
- vg_start = [0,3,4,1]
- elif l == 2: faces = [[0,1,3,2]]
- else:
- if l == 4: faces = [[0,1,3,2]]
- elif l == 3: faces = [[0,1,2]]
- elif l == 2: edges = [[0,1]]
-
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend(points) # add vertices to mesh
- if faces: me.faces.extend(faces) # add faces to the mesh
- if edges: me.edges.extend(edges) # add faces to the mesh
-
- if settings.var['vGroup_on'] and not M_OBJ:
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- replace = Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE
- if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
- if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
- if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
- if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
- if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
- if vg_end: me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', vg_end, 1.0, replace)
-
- transform(self.extrusion, 0, ob)
-
- return ob
-
-class Line: #-----------------------------------------------------------------
- """Class for objects representing dxf LINEs.
- """
- def __init__(self, obj):
- """Expects an entity object of type line as input.
- """
- if not obj.type == 'line':
- raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- self.space = getit(obj, 67, 0)
- self.thic = getit(obj, 39, 0)
- #print 'deb:self.thic: ', self.thic #---------------------
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.extrusion = get_extrusion(obj)
- self.points = self.get_points(obj)
-
-
- def get_points(self, data):
- """Gets start and end points for a line type object.
-
- Lines have a fixed number of points (two) and fixed codes for each value.
- """
- # start x,y,z and end x,y,z = 0
- a = [0, 0, 0]
- b = [0, 0, 0]
- a[0] = getit(data, 10, None) # 10 = x
- a[1] = getit(data, 20, None) # 20 = y
- a[2] = getit(data, 30, 0) # 30 = z
- b[0] = getit(data, 11, None)
- b[1] = getit(data, 21, None)
- b[2] = getit(data, 31, 0)
- out = [a,b]
- return out
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, settings):
- """for LINE: generate Blender_geometry.
- """
- # Generate the geometery
- #settings.var['curves_on']=False
-
- points = self.points
- thic = set_thick(self.thic, settings)
- width = 0.0
- if settings.var['lines_as'] == 4: # as thin_box
- thic = settings.var['thick_min']
- width = settings.var['width_min']
- elif settings.var['lines_as'] == 3: # as thin cylinder
- cyl_rad = 0.5 * settings.var['width_min']
-
- elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
- obname = 'li_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
-
- c = Curve.New(obname) # create new curve data
- curve = c.appendNurb(BezTriple.New(points[0]))
- curve.append(BezTriple.New(points[1]))
- for point in curve:
- point.handleTypes = [VECT, VECT]
- point.radius = 1.0
- curve.flagU = 0 # 0 sets the curve not cyclic=open
- c.setResolu(settings.var['curve_res'])
- c.update() #important for handles calculation
-
- ob = SCENE.objects.new(c) # create a new curve_object
-
- #if False: # --todo-- better support for 210-group
- if thic != 0.0: #hack: Blender2.45 curve-extrusion
- t = thic * 0.5
- if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
- e = self.extrusion
- c.setExt1(abs(t)) # curve-extrusion
- ob.LocX += t * e[0]
- ob.LocY += t * e[1]
- ob.LocZ += t * e[2]
- #c.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
- #ob.LocZ = t + self.loc[2]
- #ob.SizeZ *= abs(t)
- return ob
-
- else: # LINE mesh representation ------------------------------
- global activObjectLayer
- global activObjectName
- #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
-
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- if activObjectLayer == self.layer and settings.var['one_mesh_on']:
- obname = activObjectName
- #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
- ob = getSceneChild(obname) # open an existing mesh_object
- #ob = SCENE.getChildren(obname) # open an existing mesh_object
- #me = Mesh.Get(ob.name) # open objects mesh data
- me = ob.getData(name_only=False, mesh=True)
- else:
- obname = 'li_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- activObjectName = ob.name
- activObjectLayer = self.layer
- #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
-
- faces, edges = [], []
- n = len(me.verts)
-
- #if settings.var['width_force']: #--todo-----------
-
- if thic != 0:
- t, e = thic, self.extrusion
- #print 'deb:thic, extr: ', t, e #---------------------
- points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
- faces = [[0+n, 1+n, 3+n, 2+n]]
- else:
- edges = [[0+n, 1+n]]
-
- me.verts.extend(points) # adds vertices to global mesh
- if faces: me.faces.extend(faces) # add faces to the mesh
- if edges: me.edges.extend(edges) # add faces to the mesh
-
- if settings.var['vGroup_on'] and not M_OBJ:
- # entities with the same color build one vertexGroup for easier material assignment ----
- ob.link(me) # link mesh to that object
- vG_name = 'color_%s' %self.color_index
- if edges: faces = edges
- replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
- try:
- me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
- #print 'deb: existed vGroup:', vG_name #---------------------
- except:
- me.addVertGroup(vG_name)
- me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
- #print 'deb: create new vGroup:', vG_name #---------------------
-
-
- #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
- return ob
-
-
-
-class Point: #-----------------------------------------------------------------
- """Class for objects representing dxf POINTs.
- """
- def __init__(self, obj):
- """Expects an entity object of type point as input.
- """
- if not obj.type == 'point':
- raise TypeError, "Wrong type %s for point object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- self.space = getit(obj, 67, 0)
- self.thic = getit(obj, 39, 0)
- #print 'deb:self.thic: ', self.thic #---------------------
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.extrusion = get_extrusion(obj)
- self.points = self.get_points(obj)
-
-
- def get_points(self, data):
- """Gets coordinates for a point type object.
-
- Points have fixed codes for each value.
- """
- a = [0, 0, 0]
- a[0] = getit(data, 10, None) # 10 = x
- a[1] = getit(data, 20, None) # 20 = y
- a[2] = getit(data, 30, 0) # 30 = z
- out = [a]
- return out
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, settings):
- """for POINT: generate Blender_geometry.
- """
- points = self.points
- obname = 'po_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- points_as = settings.var['points_as']
- thic = settings.var['thick_min']
- if thic < settings.var['dist_min']: thic = settings.var['dist_min']
-
- if points_as in [1,3,4,5]:
- if points_as in [1,5]: # as 'empty'
- c = 'Empty'
- elif points_as == 3: # as 'thin sphere'
- res = settings.var['thin_res']
- c = Mesh.Primitives.UVsphere(res,res,thic)
- elif points_as == 4: # as 'thin box'
- c = Mesh.Primitives.Cube(thic)
- ob = SCENE.objects.new(c, obname) # create a new object
- transform(self.extrusion, 0, ob)
- ob.loc = tuple(points[0])
-
- elif points_as == 2: # as 'vertex'
- global activObjectLayer
- global activObjectName
- #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- if activObjectLayer == self.layer and settings.var['one_mesh_on']:
- obname = activObjectName
- #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
- ob = getSceneChild(obname) # open an existing mesh_object
- #ob = SCENE.getChildren(obname) # open an existing mesh_object
- me = ob.getData(name_only=False, mesh=True)
- #me = Mesh.Get(ob.name) # open objects mesh data
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- activObjectName = ob.name
- activObjectLayer = self.layer
- #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
- me.verts.extend(points) # add vertices to mesh
-
- return ob
-
-
-
-class Polyline: #-----------------------------------------------------------------
- """Class for objects representing dxf POLYLINEs.
- """
- def __init__(self, obj):
- """Expects an entity object of type polyline as input.
- """
- #print 'deb:polyline.init.START:----------------' #------------------------
- if not obj.type == 'polyline':
- raise TypeError, "Wrong type %s for polyline object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- self.space = getit(obj, 67, 0)
- self.elevation = getit(obj, 30, 0)
- #print 'deb:elevation: ', self.elevation #---------------
- self.thic = getit(obj, 39, 0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.flags = getit(obj, 70, 0)
- self.closed = self.flags & 1 # closed in the M direction
- self.curved = self.flags & 2 # Bezier-curve-fit vertices have been added
- self.spline = self.flags & 4 # NURBS-curve-fit vertices have been added
- self.poly3d = self.flags & 8 # 3D-polyline
- self.plmesh = self.flags & 16 # 3D-polygon mesh
- self.closeN = self.flags & 32 # closed in the N direction
- self.plface = self.flags & 64 # 3D-polyface mesh
- self.contin = self.flags & 128 # the linetype pattern is generated continuously
-
- self.pltype='poly2d' # default is a 2D-polyline
- if self.poly3d: self.pltype='poly3d'
- elif self.plface: self.pltype='plface'
- elif self.plmesh: self.pltype='plmesh'
-
- self.swidth = getit(obj, 40, 0) # default start width
- self.ewidth = getit(obj, 41, 0) # default end width
- #self.bulge = getit(obj, 42, None) # bulge of the segment
- self.vectorsM = getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
- self.vectorsN = getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
- #self.resolM = getit(obj, 73, None) # resolution of surface in M direction
- #self.resolN = getit(obj, 74, None) # resolution of surface in N direction
- self.curvNoFitted = False
- self.curvQuadrati = False
- self.curvCubicBsp = False
- self.curvBezier = False
- curvetype = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
- if curvetype == 0: self.curvNoFitted = True
- elif curvetype == 5: self.curvQuadrati = True
- elif curvetype == 6: self.curvCubicBsp = True
- elif curvetype == 8: self.curvBezier = True
-
- self.layer = getit(obj, 8, None)
- self.extrusion = get_extrusion(obj)
-
- self.points = [] #list with vertices coordinats
- self.faces = [] #list with vertices assigment to faces
- #print 'deb:polyline.init.ENDinit:----------------' #------------
-
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
-
- def doubles_out(self, settings, d_points):
- """routine to sort out of double.vertices-----------------------------
- """
- minimal_dist = settings.var['dist_min'] * 0.1
- dv_count = 0
- temp_points = []
- for i in xrange(len(d_points)-1):
- point = d_points[i]
- point2 = d_points[i+1]
- #print 'deb:double.vertex p1,p2', point, point2 #------------------------
- delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
- if delta.length > minimal_dist:
- temp_points.append(point)
- else:
- dv_count+=1
- #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
- temp_points.append(d_points[-1]) #------ incl. last vertex -------------
- #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
- d_points = temp_points #-----vertex.list without "double.vertices"
- #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
- return d_points
-
-
- def tribles_out(self, settings, d_points):
- """routine to sort out of three_in_place.vertices-----------------------------
- """
- minimal_dist = settings.var['dist_min'] * 0.1
- dv_count = 0
- temp_points = []
- for i in xrange(len(d_points)-2):
- point1 = d_points[i]
- point2 = d_points[i+1]
- point3 = d_points[i+2]
- #print 'deb:double.vertex p1,p2', point, point2 #------------------------
- delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
- delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
- if delta12.length < minimal_dist and delta23.length < minimal_dist:
- dv_count+=1
- else:
- temp_points.append(point1)
- #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
- point1 = d_points[-2]
- point2 = d_points[-1]
- delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
- if delta12.length > minimal_dist:
- temp_points.append(d_points[-2]) #------ incl. 2last vertex -------------
- temp_points.append(d_points[-1]) #------ incl. 1last vertex -------------
- #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
- d_points = temp_points #-----vertex.list without "double.vertices"
- #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
- return d_points
-
-
- def draw(self, settings): #-------------%%%% DRAW POLYLINE %%%---------------
- """for POLYLINE: generate Blender_geometry.
- """
- #print 'deb:drawPOLYLINE.START:----------------' #------------------------
- #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
- #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
- ob = []
- #---- 3dPolyFace - mesh with free topology
- if self.pltype=='plface' and settings.drawTypes['plmesh']:
- ob = self.drawPlFace(settings)
- #---- 3dPolyMesh - mesh with ortogonal topology
- elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
- ob = self.drawPlMesh(settings)
-
- #---- 2dPolyline - plane polyline with arc/wide/thic segments
- elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
- if settings.var['plines_as'] in [5,6]: # and self.spline:
- ob = self.drawPolyCurve(settings)
- else:
- ob = self.drawPoly2d(settings)
-
- #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
- elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
- if settings.var['plines3_as'] in [5,6]: # and self.spline:
- ob = self.drawPolyCurve(settings)
- else:
- ob = self.drawPoly2d(settings)
-
- #---- Spline - curved polyline (thin segments = without arc/wide/thic)
- elif self.pltype=='spline' and settings.drawTypes['spline']:
- if settings.var['splines_as'] in [5,6]:
- ob = self.drawPolyCurve(settings)
- else:
- ob = self.drawPoly2d(settings)
- return ob
-
-
- def drawPlFace(self, settings): #---- 3dPolyFace - mesh with free topology
- """Generate the geometery of polyface.
- """
- #print 'deb:drawPlFace.START:----------------' #------------------------
- points = []
- faces = []
- #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
- for point in self.points:
- if point.face:
- faces.append(point.face)
- else:
- points.append(point.loc)
-
- if settings.var['plmesh_flip']: # ----------------------
- for face in faces:
- face.reverse()
- face = [face[-1]] + face[:-1]
-
- #print 'deb:drawPlFace: len of points_list:\n', len(points) #-----------------------
- #print 'deb:drawPlFace: len of faces_list:\n', len(faces) #-----------------------
- #print 'deb:drawPlFace: points_list:\n', points #-----------------------
- #print 'deb:drawPlFace: faces_list:\n', faces #-----------------------
- obname = 'pf_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend(points) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
- if settings.var['normals_out']: # ----------------------
- #me.flipNormals()
- me.recalcNormals(0)
- #me.update()
- #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces) #-----------------------
-
- if settings.var['meshSmooth_on']: # ----------------------
- for i in xrange(len(me.faces)):
- me.faces[i].smooth = True
- #me.Mode(AUTOSMOOTH)
- transform(self.extrusion, 0, ob)
- #print 'deb:drawPlFace.END:----------------' #------------------------
- return ob
-
-
-
- def drawPlMesh(self, settings): #---- 3dPolyMesh - mesh with orthogonal topology
- """Generate the geometery of polymesh.
- """
- #print 'deb:polymesh.draw.START:----------------' #------------------------
- #points = []
- #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
- faces = []
- m = self.vectorsM
- n = self.vectorsN
- for j in xrange(m - 1):
- for i in xrange(n - 1):
- nn = j * n
- faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
-
- if self.closed: #mesh closed in N-direction
- nn = (m-1)*n
- for i in xrange(n - 1):
- faces.append([nn+i, nn+i+1, i+1, i])
-
- if self.closeN: #mesh closed in M-direction
- for j in xrange(m-1):
- nn = j * n
- faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
-
- if self.closed and self.closeN: #mesh closed in M/N-direction
- faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
-
- #print 'deb:len of points_list:\n', len(points) #-----------------------
- #print 'deb:faces_list:\n', faces #-----------------------
- obname = 'pm_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
- if settings.var['normals_out']: # ----------------------
- #me.flipNormals()
- me.recalcNormals(0)
- #me.update()
- if settings.var['meshSmooth_on']: # ----------------------
- for i in xrange(len(faces)):
- me.faces[i].smooth = True
- #me.Mode(AUTOSMOOTH)
-
- transform(self.extrusion, 0, ob)
- #print 'deb:polymesh.draw.END:----------------' #------------------------
- return ob
-
-
- def drawPolyCurve(self, settings): #---- Polyline - draw as Blender-curve
- """Generate the geometery of polyline as Blender-curve.
- """
- #print 'deb:polyline2dCurve.draw.START:----------------' #---
- if len(self.points) < 2:
- #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
- return
-
- if self.spline: pline_typ = 'ps' # Polyline-NURBSpline
- elif self.curved: pline_typ = 'pc' # Polyline-BezierCurve
- else: pline_typ = 'pl' # Polyline classic
- obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
- obname = obname[:MAX_NAMELENGTH]
- d_points = []
-
- if settings.var['Z_force_on']:
- self.elevation = settings.var['Z_elev']
- for point in self.points:
- point.loc[2] = self.elevation
- d_points.append(point)
- else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0
- for point in self.points:
- if point.loc[2] == None:
- point.loc[2] = self.elevation
- d_points.append(point)
-
- #d_points = self.tribles_out(settings, d_points)
- #d_points = self.doubles_out(settings, d_points)
- #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
-
- thic = set_thick(self.thic, settings)
- if thic != 0.0: #hack: Blender<2.45 curve-extrusion
- LocZ = d_points[0].loc[2]
- temp_points = []
- for point in d_points:
- point.loc[2] = 0.0
- temp_points.append(point)
- d_points = temp_points
-
- #print 'deb:polyline2dCurve.draw d_points=', d_points #---------------
- pline = Curve.New(obname) # create new curve data
- #pline.setResolu(24) #--todo-----
-
- if self.spline: # NURBSplines-----OK-----
- #print 'deb:polyline2dCurve.draw self.spline!' #---------------
- nurbs_points = []
- for d in d_points:
- pkt = d.loc
- pkt.append(d.weight)
- nurbs_points.append(pkt)
- firstpoint = nurbs_points[0]
- curve = pline.appendNurb(firstpoint)
- curve.setType(4) # set curve_type NURBS
- print 'deb: dir(curve):', dir(curve[-1]) #----------------
- for point in nurbs_points[1:]:
- curve.append(point)
- #TODO: what is the trick for bevel radius? curve[-1].radius = 1.0
- if self.closed:
- curve.flagU = 1+0 # Set curve cyclic=close and uni
- else:
- curve.flagU = 0+2 # Set curve not cyclic=open
- try: curve.orderU = 5 # works only with >2.46svn080625
- except AttributeError: pass
- #print 'deb: dir(curve):', dir(curve) #----------------
-
- elif self.curved: #--SPLINE as Bezier-curves---wip------
- #print 'deb:polyline2dCurve.draw self.curved!' #---------------
- begtangent, endtangent = None, None
- if d_points[0].tangent:
- begtangent = d_points[0]
- d_points = d_points[1:]
- if d_points[-1].tangent:
- endtangent = d_points[-1]
- d_points = d_points[:-1]
- curve = pline.appendNurb(BezTriple.New(d_points[0]))
- for p in d_points[1:]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [AUTO, AUTO]
- point.radius = 1.0
- #curve.setType(1) #Bezier curve
- if self.closed:
- curve.flagU = 5 #1 # Set curve cyclic=close
- else:
- curve.flagU = 4 #0 # Set curve not cyclic=open
- if begtangent:
- #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
- #print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
- p0h1,p0,p0h2 = curve[0].vec
- p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
- curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
- curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
- curve[0].radius = 1.0
- if endtangent:
- #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
- #print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
- p0h1,p0,p0h2 = curve[-1].vec
- p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
- #print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
- curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
- #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
- curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
- curve[-1].radius = 1.0
-
-
-
- else: #-- only straight line- and arc-segments----OK------
- #print 'deb:polyline2dCurve.draw curve:', curve #-----
- points = []
- arc_res = settings.var['curve_arc']
- prevHandleType = VECT
- #d_points.append(d_points[0]) #------ first vertex added at the end of list --------
- #curve.setType(0) #polygon_type of Blender_curve
- for i in xrange(len(d_points)):
- point1 = d_points[i]
- #point2 = d_points[i+1]
- #----- optimised Bezier-Handles calculation --------------------------------
- #print 'deb:drawPlineCurve: i:', i #---------
- if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
- if i == len(d_points)-1: point2 = d_points[0]
- else: point2 = d_points[i+1]
-
-
- # calculate additional points for bulge
- VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
-
- if prevHandleType == FREE:
- #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
- VectorTriples[0][:3] = prevHandleVect
- #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
-
- if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
- else: curve.append(BezTriple.New(VectorTriples[0]))
- curve[-1].handleTypes = [prevHandleType, FREE]
- curve[-1].radius = 1.0
-
- for p in VectorTriples[1:-1]:
- curve.append(BezTriple.New(p))
- curve[-1].handleTypes = [FREE, FREE]
- curve[-1].radius = 1.0
-
- prevHandleVect = VectorTriples[-1][:3]
- prevHandleType = FREE
- #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
- else:
- #print 'deb:drawPlineCurve: else' #----------
- if prevHandleType == FREE:
- VectorTriples = prevHandleVect + list(point1) + list(point1)
- #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
- curve.append(BezTriple.New(VectorTriples))
- curve[-1].handleTypes = [FREE, VECT]
- prevHandleType = VECT
- curve[-1].radius = 1.0
- else:
- if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
- else: curve.append(BezTriple.New(point1.loc))
- curve[-1].handleTypes = [VECT, VECT]
- curve[-1].radius = 1.0
- #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
-
- if self.closed:
- curve.flagU = 1 # Set curve cyclic=close
- if prevHandleType == FREE:
- #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
- #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
- prevHandleType2 = curve[0].handleTypes[1]
- p0h1,p0,p0h2 = curve[0].vec
- #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
- p0h1 = prevHandleVect
- #p0h1 = [0,0,0]
- #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
- #curve[0].vec = [p0h1,p0,p0h2]
- curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
-
- curve[0].handleTypes = [FREE,prevHandleType2]
- curve[0].radius = 1.0
- #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
- #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
- else:
- curve[0].handleTypes[0] = VECT
- curve[0].radius = 1.0
- else:
- curve.flagU = 0 # Set curve not cyclic=open
-
- if settings.var['fill_on']:
- pline.setFlag(6) # 2+4 set top and button caps
- else:
- pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
-
- pline.setResolu(settings.var['curve_res'])
- pline.update()
- ob = SCENE.objects.new(pline) # create a new curve_object
-
- if thic != 0.0: #hack: Blender<2.45 curve-extrusion
- thic = thic * 0.5
- pline.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
- ob.LocZ = thic + LocZ
-
- transform(self.extrusion, 0, ob)
- if thic != 0.0:
- ob.SizeZ *= abs(thic)
-
- #print 'deb:polyline2dCurve.draw.END:----------------' #-----
- return ob
-
-
- def drawPoly2d(self, settings): #---- 2dPolyline - plane lines/arcs with wide/thic
- """Generate the geometery of regular polyline.
- """
- #print 'deb:polyline2d.draw.START:----------------' #------------------------
- points = []
- d_points = []
- swidths = []
- ewidths = []
- swidth_default = self.swidth #default start width of POLYLINEs segments
- ewidth_default = self.ewidth #default end width of POLYLINEs segments
- #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
- thic = set_thick(self.thic, settings)
- if self.spline: pline_typ = 'ps'
- elif self.curved: pline_typ = 'pc'
- else: pline_typ = 'pl'
- obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
- obname = obname[:MAX_NAMELENGTH]
-
- if len(self.points) < 2:
- #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
- return
-
- if settings.var['Z_force_on']:
- self.elevation = settings.var['Z_elev']
- for point in self.points:
- point.loc[2] = self.elevation
- d_points.append(point)
- else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
- for point in self.points:
- if point.loc[2] == None:
- point.loc[2] = self.elevation
- d_points.append(point)
- #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
- #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
-
-
- #if closed polyline, add duplic of the first vertex at the end of pointslist
- if self.closed: #new_b8
- if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
- d_points.append(d_points[0])
- else:
- if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
- d_points[-1] = d_points[0]
- self.closed = True
- #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
- #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
-
- d_points = self.doubles_out(settings, d_points)
- #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
-
- #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
- if len(d_points) < 2: #if too few vertex, then return
- #print 'deb:drawPoly2d corrupted Vertices' #---------
- return
-
- # analyze of straight- and bulge-segments
- # generation of additional points for bulge segments
- arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
- wide_segment_exist = False
- bulg_points = [] # for each point set None (or center for arc-subPoints)
- for i in xrange(len(d_points)-1):
- point1 = d_points[i]
- point2 = d_points[i+1]
- #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
- #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
-
- swidth = point1.swidth
- ewidth = point1.ewidth
- #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
- if swidth == None: swidth = swidth_default
- if ewidth == None: ewidth = ewidth_default
- if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
- #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
-
- if settings.var['width_force']: # force minimal width for thin segments
- width_min = settings.var['width_min']
- if swidth < width_min: swidth = width_min
- if ewidth < width_min: ewidth = width_min
- if not settings.var['width_on']: # then force minimal width for all segments
- swidth = width_min
- ewidth = width_min
-
- #if point1.bulge and (i < (len(d_points)-1) or self.closed):
- if point1.bulge and i < (len(d_points)-1): #10_b8
- verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
- points.extend(verts)
- delta_width = (ewidth - swidth) / len(verts)
- width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
- swidths.extend(width_list[:-1])
- ewidths.extend(width_list[1:])
- bulg_list = [center for ii in xrange(len(verts))]
- #the last point in bulge has index False for better indexing of bulg_end!
- bulg_list[-1] = None
- bulg_points.extend(bulg_list)
-
- else:
- points.append(point1.loc)
- swidths.append(swidth)
- ewidths.append(ewidth)
- bulg_points.append(None)
- points.append(d_points[-1].loc)
-
-
- #--calculate width_vectors: left-side- and right-side-points ----------------
- # 1.level:IF width ---------------------------------------
- if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
- #new_b8 points.append(d_points[0].loc) #temporarly add first vertex at the end (for better loop)
- dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
-
- pointsLs = [] # list of left-start-points
- pointsLe = [] # list of left-end-points
- pointsRs = [] # list of right-start-points
- pointsRe = [] # list of right-end-points
- pointsW = [] # list of all border-points
- #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
- rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
- bulg_in = False
- last_bulg_point = False
- for i in xrange(len(points)-1):
- point1 = points[i]
- point2 = points[i+1]
- point1vec = Mathutils.Vector(point1)
- point2vec = Mathutils.Vector(point2)
- swidth05 = swidths[i] * 0.5
- ewidth05 = ewidths[i] * 0.5
- if swidth05 == 0: swidth05 = dist_min05
- if ewidth05 == 0: ewidth05 = dist_min05
- normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
- if last_bulg_point:
- last_bulg_point = False
- bulg_in = True
- elif bulg_points[i] != None:
- centerVec = Mathutils.Vector(bulg_points[i])
- if bulg_points[i+1] == None: last_bulg_point = True
- bulg_in = True
- else: bulg_in = False
-
- if bulg_in:
- #makes clean intersections for arc-segments
- radius1vec = point1vec - centerVec
- radius2vec = point2vec - centerVec
- angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
- if angle < 90.0:
- normal_vector1 = radius1vec.normalize()
- normal_vector2 = radius2vec.normalize()
- else:
- normal_vector1 = - radius1vec.normalize()
- normal_vector2 = - radius2vec.normalize()
-
- swidth05vec = swidth05 * normal_vector1
- ewidth05vec = ewidth05 * normal_vector2
- pointsLs.append(point1vec + swidth05vec) #vertex left start
- pointsRs.append(point1vec - swidth05vec) #vertex right start
- pointsLe.append(point2vec + ewidth05vec) #vertex left end
- pointsRe.append(point2vec - ewidth05vec) #vertex right end
-
- else:
- swidth05vec = swidth05 * normal_vector
- ewidth05vec = ewidth05 * normal_vector
- pointsLs.append(point1vec + swidth05vec) #vertex left start
- pointsRs.append(point1vec - swidth05vec) #vertex right start
- pointsLe.append(point2vec + ewidth05vec) #vertex left end
- pointsRe.append(point2vec - ewidth05vec) #vertex right end
-
- # additional last point is also calculated
- #pointsLs.append(pointsLs[0])
- #pointsRs.append(pointsRs[0])
- #pointsLe.append(pointsLe[0])
- #pointsRe.append(pointsRe[0])
-
- pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
-
- # 2.level:IF width and corner-trim
- if settings.var['pl_trim_on']: #optional clean corner-intersections
- # loop preset
- # set STARTpoints of the first point points[0]
- if not self.closed:
- pointsLc.append(pointsLs[0])
- pointsRc.append(pointsRs[0])
- else:
- pointsLs.append(pointsLs[0])
- pointsRs.append(pointsRs[0])
- pointsLe.append(pointsLe[0])
- pointsRe.append(pointsRe[0])
- points.append(points[0])
- vecL3, vecL4 = pointsLs[0], pointsLe[0]
- vecR3, vecR4 = pointsRs[0], pointsRe[0]
- lenL = len(pointsLs)-1
- #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
- #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
- bulg_in = False
- last_bulg_point = False
-
- # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
- for i in xrange(lenL):
- if bulg_points[i] != None:
- if bulg_points[i+1] == None: #makes clean intersections for arc-segments
- last_bulg_point = True
- if not bulg_in:
- bulg_in = True
- #pointsLc.extend((points[i], pointsLs[i]))
- #pointsRc.extend((points[i], pointsRs[i]))
- vecL1, vecL2 = vecL3, vecL4
- vecR1, vecR2 = vecR3, vecR4
- vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
- vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
- #compute left- and right-cornerpoints
- #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
- cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
- cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
- #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
- #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
-
- # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
- if cornerpointL == None or cornerpointR == None:
- if vecL2 == vecL3 and vecR2 == vecR3:
- #print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
- pointsLc.append(pointsLe[i])
- pointsRc.append(pointsRe[i])
- else:
- pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
- pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
- else:
- cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
- cornerpointR = cornerpointR[0]
- #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
- #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
- pointVec0 = Mathutils.Vector(points[i])
- pointVec = Mathutils.Vector(points[i+1])
- pointVec2 = Mathutils.Vector(points[i+2])
- #print 'deb:drawPoly2d pointVec0: ', pointVec0 #-------------
- #print 'deb:drawPoly2d pointVec: ', pointVec #-------------
- #print 'deb:drawPoly2d pointVec2: ', pointVec2 #-------------
- # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
- max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
- is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
- #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
- #print 'deb:drawPoly2d corner_angle: ', corner_angle #-------------
- #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist #-------------
- #if abs(corner_angle) < 90.0:
- # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
- if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
- # clean corner intersection
- pointsLc.append(cornerpointL)
- pointsRc.append(cornerpointR)
- else:
- pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
- pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
- if not self.closed:
- pointsLc.append(pointsLe[-1])
- pointsRc.append(pointsRe[-1])
-
- # 2.level:IF width but no-trim
- else:
- # loop preset
- # set STARTpoints of the first point points[0]
- if not self.closed:
- pointsLc.append(pointsLs[0])
- pointsRc.append(pointsRs[0])
- else:
- pointsLs.append(pointsLs[0])
- pointsRs.append(pointsRs[0])
- pointsLe.append(pointsLe[0])
- pointsRe.append(pointsRe[0])
- points.append(points[0])
- vecL3, vecL4 = pointsLs[0], pointsLe[0]
- vecR3, vecR4 = pointsRs[0], pointsRe[0]
- lenL = len(pointsLs)-1
- #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
- #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
- bulg_in = False
- last_bulg_point = False
-
- # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
- for i in xrange(lenL):
- vecL1, vecL2 = vecL3, vecL4
- vecR1, vecR2 = vecR3, vecR4
- vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
- vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
- if bulg_points[i] != None:
- #compute left- and right-cornerpoints
- cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
- cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
- pointsLc.append(cornerpointL[0])
- pointsRc.append(cornerpointR[0])
- else: # IF non-bulg
- pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
- pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
- if not self.closed:
- pointsLc.append(pointsLe[-1])
- pointsRc.append(pointsRe[-1])
-
- len1 = len(pointsLc)
- #print 'deb:drawPoly2d len1:', len1 #-----------------------
- #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc) #-----------------------
- pointsW = pointsLc + pointsRc # all_points_List = left_side + right_side
- #print 'deb:drawPoly2d pointsW():\n', pointsW #----------------
-
- # 2.level:IF width and thickness ---------------------
- if thic != 0:
- thic_pointsW = []
- thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
- if thic < 0.0:
- thic_pointsW.extend(pointsW)
- pointsW = thic_pointsW
- else:
- pointsW.extend(thic_pointsW)
- faces = []
- f_start, f_end = [], []
- f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
- f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
- f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
- f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
-
- if self.closed:
- f_bottom.append([len1-1, 0, len1, len1+len1-1]) #bottom face
- f_top.append( [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0]) #top face
- f_left.append( [0, len1-1, len1+len1+len1-1, len1+len1]) #left face
- f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1]) #right face
- else:
- f_start = [[0, len1, len1+len1+len1, len1+len1]]
- f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
-
- faces = f_left + f_right + f_bottom + f_top + f_start + f_end
- #faces = f_bottom + f_top
- #faces = f_left + f_right + f_start + f_end
- #print 'deb:faces_list:\n', faces #-----------------------
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend(pointsW) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- # The mesh must first be linked to an object so the method knows which object to update.
- # This is because vertex groups in Blender are stored in the object -- not in the mesh,
- # which may be linked to more than one object.
- if settings.var['vGroup_on'] and not M_OBJ:
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
- vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
- for v in f_left: vg_left.extend(v)
- for v in f_right: vg_right.extend(v)
- for v in f_top: vg_top.extend(v)
- for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
- me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
- if not self.closed:
- me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
- me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
-
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- #if self.spline or self.curved:
- smooth_len = len(f_left) + len(f_right)
- for i in xrange(smooth_len):
- me.faces[i].smooth = True
- #me.Modes(AUTOSMOOTH)
-
- # 2.level:IF width, but no-thickness ---------------------
- else:
- faces = []
- faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
- if self.closed:
- faces.append([len1, 0, len1-1, len1+len1-1])
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend(pointsW) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
-
- # 1.level:IF no-width, but thickness ---------------------
- elif thic != 0:
- len1 = len(points)
- thic_points = []
- thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
- if thic < 0.0:
- thic_points.extend(points)
- points = thic_points
- else:
- points.extend(thic_points)
- faces = []
- faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
- if self.closed:
- faces.append([len1-1, 0, len1, 2*len1-1])
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend(points) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- #if self.spline or self.curved:
- for i in xrange(len(faces)):
- me.faces[i].smooth = True
- #me.Modes(AUTOSMOOTH)
-
- # 1.level:IF no-width and no-thickness ---------------------
- else:
- edges = [[num, num+1] for num in xrange(len(points)-1)]
- if self.closed:
- edges.append([len(points)-1, 0])
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- transform(self.extrusion, 0, ob)
- #print 'deb:polyline.draw.END:----------------' #-----------------------
- return ob
-
-
-
-
-class Vertex(object): #-----------------------------------------------------------------
- """Generic vertex object used by POLYLINEs, (and maybe others).
- also used by class_LWPOLYLINEs but without obj-parameter
- """
-
- def __init__(self, obj=None):
- """Initializes vertex data.
-
- The optional obj arg is an entity object of type vertex.
- """
- #print 'deb:Vertex.init.START:----------------' #-----------------------
- self.loc = [0,0,0]
- self.face = []
- self.swidth = None #0
- self.ewidth = None #0
- self.bulge = 0
- self.tangent = False
- self.weight = 1.0
- if obj is not None:
- if not obj.type == 'vertex':
- raise TypeError, "Wrong type %s for vertex object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
- self.get_props(obj)
- else:
- pass
- #print 'deb:Vertex.init.END:----------------' #------------------------
-
-
- def get_props(self, data):
- """Gets coords for a VERTEX type object.
-
- Each vert can have a number of properties.
- Verts should be coded as
- 10:xvalue
- 20:yvalue
- 40:startwidth or 0
- 41:endwidth or 0
- 42:bulge or 0
- """
- self.x = getit(data, 10, None)
- self.y = getit(data, 20, None)
- self.z = getit(data, 30, None)
-
- self.flags = getit(data, 70, 0) # flags
- self.curved = self.flags&1 # Bezier-curve-fit:additional-vertex
- self.curved_t = self.flags&2 # Bezier-curve-fit:tangent exists
- self.spline = self.flags&8 # NURBSpline-fit:additional-vertex
- self.spline_c = self.flags&16 # NURBSpline-fit:control-vertex
- self.poly3d = self.flags&32 # polyline3d:control-vertex
- self.plmesh = self.flags&64 # polymesh3d:control-vertex
- self.plface = self.flags&128 # polyface
-
- # if PolyFace.Vertex with Face_definition
- if self.curved_t:
- self.curve_tangent = getit(data, 50, None) # curve_tangent
- if not self.curve_tangent==None:
- self.tangent = True
- #elif self.spline_c: # NURBSpline:control-vertex
- # self.weight = getit(data, 41, 1.0) # weight od control point
-
- elif self.plface and not self.plmesh:
- v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
- v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
- v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
- v4 = getit(data, 74, None) # polyface:Face.vertex 4.
- self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
- if v4 != None:
- if abs(v4) != abs(v1):
- self.face.append(abs(v4)-1)
- else: #--parameter for polyline2d
- self.swidth = getit(data, 40, None) # start width
- self.ewidth = getit(data, 41, None) # end width
- self.bulge = getit(data, 42, 0) # bulge of segment
-
-
- def __len__(self):
- return 3
-
-
- def __getitem__(self, key):
- return self.loc[key]
-
-
- def __setitem__(self, key, value):
- if key in [0,1,2]:
- self.loc[key]
-
-
- def __iter__(self):
- return self.loc.__iter__()
-
-
- def __str__(self):
- return str(self.loc)
-
-
- def __repr__(self):
- return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
-
-
- def getx(self):
- return self.loc[0]
- def setx(self, value):
- self.loc[0] = value
- x = property(getx, setx)
-
-
- def gety(self):
- return self.loc[1]
- def sety(self, value):
- self.loc[1] = value
- y = property(gety, sety)
-
-
- def getz(self):
- return self.loc[2]
- def setz(self, value):
- self.loc[2] = value
- z = property(getz, setz)
-
-
-
-class Spline(Polyline): #-----------------------------------------------------------------
- """Class for objects representing dxf SPLINEs.
- """
- """Expects an entity object of type spline as input.
-100 - Subclass marker (AcDbSpline)
-210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
-70 - Spline flag (bit coded):
- 1 = Closed spline
- 2 = Periodic spline
- 4 = Rational spline
- 8 = Planar
- 16 = Linear (planar bit is also set)
-71 - Degree of the spline curve
-72 - Number of knots
-73 - Number of control points
-74 - Number of fit points (if any)
-42 - Knot tolerance (default = 0.0000001)
-43 - Control-point tolerance (default = 0.0000001)
-44 - Fit tolerance (default = 0.0000000001)
-12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
-13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
-40 - Knot value (one entry per knot)
-41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
-10,20, 30 - Control points (in WCS) one entry per control point.
-DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
-11,21, 31 - Fit points (in WCS) one entry per fit point.
- X,Y,Z values of fit points (in WCS) (one entry per fit point)
- """
- def __init__(self, obj):
- #print 'deb:Spline.START:----------------' #------------------------
- if not obj.type == 'spline':
- raise TypeError, "Wrong type %s for spline object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.num_points = obj.get_type(73)[0]
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
-
- self.color_index = getit(obj, 62, BYLAYER)
-
- #self.elevation = getit(obj, 30, 0)
- self.thic = 0 # getit(obj, 39, 0)
-
- width = 0
- self.swidth = width # default start width
- self.ewidth = width # default end width
-
- self.flags = getit(obj, 70, 0)
- self.closed = self.flags & 1 # closed spline
- self.period = self.flags & 2 # Periodic spline
- self.ration = self.flags & 4 # Rational spline
- self.planar = self.flags & 8 # Planar
- self.linear = self.flags & 16 # Linear (and Planar)
-
- self.curvNoFitted = False
- self.curvQuadrati = False
- self.curvCubicBsp = False
- self.curvBezier = False
- self.degree = getit(obj, 71, 0) # Degree of the spline curve
- if self.degree == 0: self.curvNoFitted = True
- elif self.degree == 1: self.curvQuadrati = True
- elif self.degree == 2: self.curvCubicBsp = True
- #elif self.degree == 3: self.curvBezier = True
- #elif self.degree == 3: self.spline = True
-
- self.knotpk_len = getit(obj, 72, 0) # Number of knots
- self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
- self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
-
- #TODO: import SPLINE as Bezier curve directly, possible?
- #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
- #self.fit_pk_len = 0 # temp for debug
- if self.fit_pk_len and settings.var['splines_as']==5:
- self.spline = False
- self.curved = True
- else:
- self.spline = True
- self.curved = False
-
- self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
- self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
- self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
-
- self.layer = getit(obj, 8, None)
- self.extrusion = get_extrusion(obj)
-
- self.pltype = 'spline' # spline is a 2D- or 3D-polyline
-
- self.points = self.get_points(obj.data)
- #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
- #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
-
- #print 'deb:Spline obj.data:\n', obj.data #------------------------
- #print 'deb:Spline self.points:\n', self.points #------------------------
- #print 'deb:Spline.ENDinit:----------------' #------------------------
-
-
- def get_points(self, data):
- """Gets points for a spline type object.
-
- Splines have fixed number of verts, and
- each vert can have a number of properties.
- Verts should be coded as
- 10:xvalue
- 20:yvalue
- for each vert
- """
- point = None
- points = []
- pointend = None
- #point = Vertex()
- if self.spline: # NURBSpline definition
- for item in data:
- #print 'deb:Spline.get_points spilne_item:', item #------------------------
- if item[0] == 10: # control point
- if point: points.append(point)
- point = Vertex()
- point.curved = True
- point.x = item[1]
- elif item[0] == 20: # 20 = y
- point.y = item[1]
- elif item[0] == 30: # 30 = z
- point.z = item[1]
- elif item[0] == 41: # 41 = weight
- point.weight = item[1]
- #print 'deb:Spline.get_points control point:', point #------------------------
-
- elif self.curved: # Bezier definition
- for item in data:
- #print 'deb:Spline.get_points curved_item:', item #------------------------
- if item[0] == 11: # fit point
- if point: points.append(point)
- point = Vertex()
- point.tangent = False
- point.x = item[1]
- elif item[0] == 21: # 20 = y
- point.y = item[1]
- elif item[0] == 31: # 30 = z
- point.z = item[1]
- #print 'deb:Spline.get_points fit point:', point #------------------------
-
- elif item[0] == 12: # start tangent
- if point: points.append(point)
- point = Vertex()
- point.tangent = True
- point.x = item[1]
- elif item[0] == 22: # = y
- point.y = item[1]
- elif item[0] == 32: # = z
- point.z = item[1]
- #print 'deb:Spline.get_points fit begtangent:', point #------------------------
-
- elif item[0] == 13: # end tangent
- if point: points.append(point)
- pointend = Vertex()
- pointend.tangent = True
- pointend.x = item[1]
- elif item[0] == 23: # 20 = y
- pointend.y = item[1]
- elif item[0] == 33: # 30 = z
- pointend.z = item[1]
- #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
- points.append(point)
- if self.curved and pointend:
- points.append(pointend)
- #print 'deb:Spline points:\n', points #------------------------
- return points
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
-
-class LWpolyline(Polyline): #-------------------------------------------------------------
- """Class for objects representing dxf LWPOLYLINEs.
- """
- def __init__(self, obj):
- """Expects an entity object of type lwpolyline as input.
- """
- #print 'deb:LWpolyline.START:----------------' #------------------------
- if not obj.type == 'lwpolyline':
- raise TypeError, "Wrong type %s for polyline object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.num_points = obj.get_type(90)[0]
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.elevation = getit(obj, 38, 0)
- self.thic = getit(obj, 39, 0)
- self.color_index = getit(obj, 62, BYLAYER)
- width = getit(obj, 43, 0)
- self.swidth = width # default start width
- self.ewidth = width # default end width
- #print 'deb:LWpolyline width=', width #------------------------
- #print 'deb:LWpolyline elevation=', self.elevation #------------------------
-
- self.flags = getit(obj, 70, 0)
- self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
-
- self.layer = getit(obj, 8, None)
- self.extrusion = get_extrusion(obj)
-
- self.points = self.get_points(obj.data)
-
- self.pltype = 'poly2d' # LW-polyline is a 2D-polyline
- self.spline = False
- self.curved = False
-
- #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
- #print 'deb:LWpolyline.ENDinit:----------------' #------------------------
-
-
- def get_points(self, data):
- """Gets points for a polyline type object.
-
- LW-Polylines have no fixed number of verts, and
- each vert can have a number of properties.
- Verts should be coded as
- 10:xvalue
- 20:yvalue
- 40:startwidth or 0
- 41:endwidth or 0
- 42:bulge or 0
- for each vert
- """
- num = self.num_points
- point = None
- points = []
- for item in data:
- if item[0] == 10: # 10 = x
- if point:
- points.append(point)
- point = Vertex()
- point.x = item[1]
- point.z = self.elevation
- elif item[0] == 20: # 20 = y
- point.y = item[1]
- elif item[0] == 40: # 40 = start width
- point.swidth = item[1]
- elif item[0] == 41: # 41 = end width
- point.ewidth = item[1]
- elif item[0] == 42: # 42 = bulge
- point.bulge = item[1]
- points.append(point)
- return points
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
-class Text: #-----------------------------------------------------------------
- """Class for objects representing dxf TEXT.
- """
- def __init__(self, obj):
- """Expects an entity object of type text as input.
- """
- if not obj.type == 'text':
- raise TypeError, "Wrong type %s for text object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.height = 1.7 * obj.get_type(40)[0] #text.height
- self.value = obj.get_type(1)[0] #The text string value
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.color_index = getit(obj, 62, BYLAYER)
- self.thic = getit(obj, 39, 0)
-
- self.rotation = getit(obj, 50, 0) # radians
- self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
- self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
-
- #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
-
- #Text generation flags (optional, default = 0):
- #2 = backward (mirrored in X),
- #4 = upside down (mirrored in Y)
- self.flags = getit(obj, 71, 0)
- self.mirrorX, self.mirrorY = 1.0, 1.0
- if self.flags&2: self.mirrorX = - 1.0
- if self.flags&4: self.mirrorY = - 1.0
-
- # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
- self.valignment = getit(obj, 73, 0)
- #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
- #0=left, 1=center, 2=right
- #3=aligned, 4=middle, 5=fit
- self.halignment = getit(obj, 72, 0)
-
- self.layer = getit(obj, 8, None)
- self.loc1, self.loc2 = self.get_loc(obj)
- if self.loc2[0] != None and self.halignment != 5:
- self.loc = self.loc2
- else:
- self.loc = self.loc1
- self.extrusion = get_extrusion(obj)
-
-
- def get_loc(self, data):
- """Gets adjusted location for text type objects.
-
- If group 72 and/or 73 values are nonzero then the first alignment point values
- are ignored and AutoCAD calculates new values based on the second alignment
- point and the length and height of the text string itself (after applying the
- text style). If the 72 and 73 values are zero or missing, then the second
- alignment point is meaningless.
- I don't know how to calc text size...
- """
- # bottom left x, y, z and justification x, y, z = 0
- #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
- x = getit(data, 10, None) #First alignment point (in OCS).
- y = getit(data, 20, None)
- z = getit(data, 30, 0.0)
- jx = getit(data, 11, None) #Second alignment point (in OCS).
- jy = getit(data, 21, None)
- jz = getit(data, 31, 0.0)
- return [x, y, z],[jx, jy, jz]
-
-
- def __repr__(self):
- return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
-
-
- def draw(self, settings):
- """for TEXTs: generate Blender_geometry.
- """
- obname = 'tx_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- txt = Text3d.New(obname)
- ob = SCENE.objects.new(txt) # create a new text_object
-
- txt.setText(self.value)
- txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
- #txt.setSize(self.height)
- #txt.setWidth(self.bold)
- #setLineSeparation(sep)
- txt.setShear(self.oblique/90)
-
- thic = set_thick(self.thic, settings)
- if thic != 0.0:
- thic = self.thic * 0.5
- self.loc[2] += thic
- txt.setExtrudeDepth(1.0) #Blender<2.45 accepts only (0.1 - 10.0)
- if self.halignment == 0:
- align = Text3d.LEFT
- elif self.halignment == 1:
- align = Text3d.MIDDLE
- elif self.halignment == 2:
- align = Text3d.RIGHT
- else:
- align = Text3d.LEFT
- txt.setAlignment(align)
-
- if self.valignment == 1:
- txt.setYoffset(0.0)
- elif self.valignment == 2:
- txt.setYoffset(- self.height * 0.5)
- elif self.valignment == 3:
- txt.setYoffset(- self.height)
-
- # move the object center to the text location
- ob.loc = tuple(self.loc)
- transform(self.extrusion, self.rotation, ob)
-
- # flip it and scale it to the text width
- ob.SizeX *= self.height * self.width_factor * self.mirrorX
- ob.SizeY *= self.height * self.mirrorY
- if thic != 0.0: ob.SizeZ *= abs(thic)
- return ob
-
-
-
-def set_thick(thickness, settings):
- """Set thickness relative to settings variables.
-
- Set thickness relative to settings variables:
- 'thick_on','thick_force','thick_min'.
- Accepted also minus values of thickness
- python trick: sign(x)=cmp(x,0)
- """
- if settings.var['thick_force']:
- if settings.var['thick_on']:
- if abs(thickness) < settings.var['thick_min']:
- thic = settings.var['thick_min'] * cmp(thickness,0)
- else: thic = thickness
- else: thic = settings.var['thick_min']
- else:
- if settings.var['thick_on']: thic = thickness
- else: thic = 0.0
- return thic
-
-
-
-
-class Mtext: #-----------------------------------------------------------------
- """Class for objects representing dxf MTEXT.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type mtext as input.
- """
- if not obj.type == 'mtext':
- raise TypeError, "Wrong type %s for mtext object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.height = obj.get_type(40)[0]
- self.width = obj.get_type(41)[0]
- self.alignment = obj.get_type(71)[0] # alignment 1=TL, 2=TC, 3=TR, 4=ML, 5=MC, 6=MR, 7=BL, 8=BC, 9=BR
- self.value = self.get_text(obj) # The text string value
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.color_index = getit(obj, 62, BYLAYER)
- self.rotation = getit(obj, 50, 0) # radians
-
- self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
- self.line_space = getit(obj, 44, 1) # percentage of default
-
- self.layer = getit(obj, 8, None)
- self.loc = self.get_loc(obj)
- self.extrusion = get_extrusion(obj)
-
-
- def get_text(self, data):
- """Reconstructs mtext data from dxf codes.
- """
- primary = ''
- secondary = []
- for item in data:
- if item[0] == 1: # There should be only one primary...
- primary = item[1]
- elif item[0] == 3: # There may be any number of extra strings (in order)
- secondary.append(item[1])
- if not primary:
- #raise ValueError, "Empty Mtext Object!"
- string = "Empty Mtext Object!"
- if not secondary:
- string = primary.replace(r'\P', '\n')
- else:
- string = ''.join(secondary)+primary
- string = string.replace(r'\P', '\n')
- return string
-
-
- def get_loc(self, data):
- """Gets location for a mtext type objects.
-
- Mtext objects have only one point indicating
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 10, None)
- loc[1] = getit(data, 20, None)
- loc[2] = getit(data, 30, 0.0)
- return loc
-
-
- def __repr__(self):
- return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
-
-
- def draw(self, settings):
- """for MTEXTs: generate Blender_geometry.
- """
- # Now Create an object
- obname = 'tm_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- txt = Text3d.New(obname)
- ob = SCENE.objects.new(txt) # create a new text_object
-
- txt.setSize(1)
- # Blender doesn't give access to its text object width currently
- # only to the text3d's curve width...
- #txt.setWidth(text.width/10)
- txt.setLineSeparation(self.line_space)
- txt.setExtrudeDepth(0.5)
- txt.setText(self.value)
-
- # scale it to the text size
- ob.SizeX = self.height * self.width_factor
- ob.SizeY = self.height
- ob.SizeZ = self.height
-
- # move the object center to the text location
- ob.loc = tuple(self.loc)
- transform(self.extrusion, self.rotation, ob)
-
- return ob
-
-
-class Circle: #-----------------------------------------------------------------
- """Class for objects representing dxf CIRCLEs.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type circle as input.
- """
- if not obj.type == 'circle':
- raise TypeError, "Wrong type %s for circle object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.radius = obj.get_type(40)[0]
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.thic = getit(obj, 39, 0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.loc = self.get_loc(obj)
- self.extrusion = get_extrusion(obj)
-
-
-
- def get_loc(self, data):
- """Gets the center location for circle type objects.
-
- Circles have a single coord location.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 10, None)
- loc[1] = getit(data, 20, None)
- loc[2] = getit(data, 30, 0.0)
- return loc
-
-
-
- def __repr__(self):
- return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
-
-
- def draw(self, settings):
- """for CIRCLE: generate Blender_geometry.
- """
- obname = 'ci_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- radius = self.radius
-
- thic = set_thick(self.thic, settings)
- width = 0.0
- if settings.var['lines_as'] == 4: # as thin_box
- thic = settings.var['thick_min']
- width = settings.var['width_min']
- if settings.var['lines_as'] == 3: # as thin cylinder
- cyl_rad = 0.5 * settings.var['width_min']
-
- if settings.var['lines_as'] == 5: # draw CIRCLE as curve -------------
- arc_res = settings.var['curve_arc']
- #arc_res = 3
- start, end = 0.0, 360.0
- VectorTriples = calcArc(None, radius, start, end, arc_res, True)
- c = Curve.New(obname) # create new curve data
- curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
- for p in VectorTriples[1:-1]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [FREE, FREE]
- point.radius = 1.0
- curve.flagU = 1 # 1 sets the curve cyclic=closed
- if settings.var['fill_on']:
- c.setFlag(6) # 2+4 set top and button caps
- else:
- c.setFlag(c.getFlag() & ~6) # dont set top and button caps
-
- c.setResolu(settings.var['curve_res'])
- c.update()
-
- #--todo-----to check---------------------------
- ob = SCENE.objects.new(c) # create a new curve_object
- ob.loc = tuple(self.loc)
- if thic != 0.0: #hack: Blender<2.45 curve-extrusion
- thic = thic * 0.5
- c.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
- ob.LocZ = thic + self.loc[2]
- transform(self.extrusion, 0, ob)
- if thic != 0.0:
- ob.SizeZ *= abs(thic)
- return ob
-
- else: # draw CIRCLE as mesh -----------------------------------------------
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- # set a number of segments in entire circle
- arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
- start, end = 0.0 , 360.0
- verts = calcArc(None, radius, start, end, arc_res, False)
- verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
- #print 'deb:circleDraw: verts:', verts #---------------
-
- if thic != 0:
- len1 = len(verts)
- thic_verts = []
- thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
- if thic < 0.0:
- thic_verts.extend(verts)
- verts = thic_verts
- else:
- verts.extend(thic_verts)
- faces = []
- f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
- #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]
- f_band.append([len1 - 1, 0, len1, len1 + len1 -1])
- faces = f_band
- smooth_len = len(f_band)
- if settings.var['fill_on']:
- if thic < 0.0:
- verts.append([0,0,thic]) #center of top side
- verts.append([0,0,0]) #center of bottom side
- else:
- verts.append([0,0,0]) #center of bottom side
- verts.append([0,0,thic]) #center of top side
- center1 = len(verts)-2
- center2 = len(verts)-1
- f_bottom = [[num+1, num, center1] for num in xrange(len1 - 1)]
- f_bottom.append([0, len1 - 1, center1])
- f_top = [[num+len1, num+1+len1, center2] for num in xrange(len1 - 1)]
- f_top.append([len1-1+len1, 0+len1, center2])
- #print 'deb:circleDraw:verts:', verts #---------------
- faces = f_band + f_bottom + f_top
- #print 'deb:circleDraw:faces:', faces #---------------
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- for i in xrange(smooth_len):
- me.faces[i].smooth = True
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- if settings.var['vGroup_on'] and not M_OBJ:
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
- vg_band, vg_top, vg_bottom = [], [], []
- for v in f_band: vg_band.extend(v)
- me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', vg_band, 1.0, replace)
-
- if settings.var['fill_on']:
- for v in f_top: vg_top.extend(v)
- for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
-
- else: # if thic == 0
- if settings.var['fill_on']:
- len1 = len(verts)
- verts.append([0,0,0]) #center of circle
- center1 = len1
- faces = []
- faces.extend([[num, num+1, center1] for num in xrange(len1)])
- faces.append([len1-1, 0, center1])
- #print 'deb:circleDraw:verts:', verts #---------------
- #print 'deb:circleDraw:faces:', faces #---------------
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
- else:
- me.verts.extend(verts) # add vertices to mesh
- edges = [[num, num+1] for num in xrange(len(verts))]
- edges[-1][1] = 0 # it points the "new" last edge to the first vertex
- me.edges.extend(edges) # add edges to the mesh
-
- ob.loc = tuple(self.loc)
- transform(self.extrusion, 0, ob)
- return ob
-
-
-class Arc: #-----------------------------------------------------------------
- """Class for objects representing dxf ARCs.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type arc as input.
- """
- if not obj.type == 'arc':
- raise TypeError, "Wrong type %s for arc object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.radius = obj.get_type(40)[0]
- self.start_angle = obj.get_type(50)[0]
- self.end_angle = obj.get_type(51)[0]
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.thic = getit(obj, 39, 0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.loc = self.get_loc(obj)
- self.extrusion = get_extrusion(obj)
- #print 'deb:Arc__init__: center, radius, start, end:\n', self.loc, self.radius, self.start_angle, self.end_angle #---------
-
-
-
- def get_loc(self, data):
- """Gets the center location for arc type objects.
-
- Arcs have a single coord location.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 10, None)
- loc[1] = getit(data, 20, None)
- loc[2] = getit(data, 30, 0.0)
- return loc
-
-
-
- def __repr__(self):
- return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
-
-
- def draw(self, settings):
- """for ARC: generate Blender_geometry.
- """
- obname = 'ar_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
-
- center = self.loc
- radius = self.radius
- start = self.start_angle
- end = self.end_angle
- #print 'deb:calcArcPoints:\n center, radius, start, end:\n', center, radius, start, end #---------
- thic = set_thick(self.thic, settings)
- width = 0.0
- if settings.var['lines_as'] == 4: # as thin_box
- thic = settings.var['thick_min']
- width = settings.var['width_min']
- if settings.var['lines_as'] == 3: # as thin cylinder
- cyl_rad = 0.5 * settings.var['width_min']
-
- if settings.var['lines_as'] == 5: # draw ARC as curve -------------
- arc_res = settings.var['curve_arc']
- triples = True
- VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
- arc = Curve.New(obname) # create new curve data
- curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
- for p in VectorTriples[1:]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [FREE, FREE]
- point.radius = 1.0
- curve.flagU = 0 # 0 sets the curve not cyclic=open
- arc.setResolu(settings.var['curve_res'])
-
- arc.update() #important for handles calculation
-
- ob = SCENE.objects.new(arc) # create a new curve_object
- ob.loc = tuple(self.loc)
- if thic != 0.0: #hack: Blender<2.45 curve-extrusion
- thic = thic * 0.5
- arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
- ob.LocZ = thic + self.loc[2]
- transform(self.extrusion, 0, ob)
- if thic != 0.0:
- ob.SizeZ *= abs(thic)
- return ob
-
- else: # draw ARC as mesh --------------------
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- # set a number of segments in entire circle
- arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
-
- verts = calcArc(None, radius, start, end, arc_res, False)
- #verts = [list(point) for point in verts]
- len1 = len(verts)
- #print 'deb:len1:', len1 #-----------------------
- if width != 0:
- radius_out = radius + (0.5 * width)
- radius_in = radius - (0.5 * width)
- if radius_in <= 0.0:
- radius_in = settings.var['dist_min']
- #radius_in = 0.0
- verts_in = []
- verts_out = []
- for point in verts:
- pointVec = Mathutils.Vector(point)
- pointVec = pointVec.normalize()
- verts_in.append(list(radius_in * pointVec)) #vertex inside
- verts_out.append(list(radius_out * pointVec)) #vertex outside
- verts = verts_in + verts_out
-
- #print 'deb:verts:', verts #---------------------
- if thic != 0:
- thic_verts = []
- thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
- if thic < 0.0:
- thic_verts.extend(verts)
- verts = thic_verts
- else:
- verts.extend(thic_verts)
- f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
- f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
- f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
- f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
- f_start = [[0, len1, len1+len1+len1, len1+len1]]
- f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
- faces = f_left + f_right + f_bottom + f_top + f_start + f_end
-
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- smooth_len = len(f_left) + len(f_right)
- for i in xrange(smooth_len):
- me.faces[i].smooth = True
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- if settings.var['vGroup_on'] and not M_OBJ:
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
- vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
- for v in f_left: vg_left.extend(v)
- for v in f_right: vg_right.extend(v)
- for v in f_top: vg_top.extend(v)
- for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
- me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
- me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
- me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
-
-
- else: # if thick=0 - draw only flat ring
- faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- elif thic != 0:
- thic_verts = []
- thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
- if thic < 0.0:
- thic_verts.extend(verts)
- verts = thic_verts
- else:
- verts.extend(thic_verts)
- faces = []
- #print 'deb:len1:', len1 #-----------------------
- #print 'deb:verts:', verts #---------------------
- faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
-
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- for i in xrange(len(faces)):
- me.faces[i].smooth = True
-
- else:
- edges = [[num, num+1] for num in xrange(len(verts)-1)]
- me.verts.extend(verts) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- #me.update()
- #ob = SCENE.objects.new(me) # create a new arc_object
- #ob.link(me)
- ob.loc = tuple(center)
- #ob.loc = Mathutils.Vector(ob.loc)
- transform(self.extrusion, 0, ob)
- #ob.size = (1,1,1)
- return ob
-
-
-class BlockRecord: #-----------------------------------------------------------------
- """Class for objects representing dxf block_records.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type block_record as input.
- """
- if not obj.type == 'block_record':
- raise TypeError, "Wrong type %s for block_record object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.name = getit(obj, 2, None)
-
- # optional data (with defaults)
- self.insertion_units = getit(obj, 70, None)
- self.insert_units = getit(obj, 1070, None)
- """code 1070 Einfuegeeinheiten:
- 0 = Keine Einheiten; 1 = Zoll; 2 = Fuss; 3 = Meilen; 4 = Millimeter;
- 5 = Zentimeter; 6 = Meter; 7 = Kilometer; 8 = Mikrozoll;
- 9 = Mils; 10 = Yard; 11 = Angstrom; 12 = Nanometer;
- 13 = Mikrons; 14 = Dezimeter; 15 = Dekameter;
- 16 = Hektometer; 17 = Gigameter; 18 = Astronomische Einheiten;
- 19 = Lichtjahre; 20 = Parsecs
- """
-
-
- def __repr__(self):
- return "%s: name - %s, insert units - %s" %(self.__class__.__name__, self.name, self.insertion_units)
-
-
-
-
-class Block: #-----------------------------------------------------------------
- """Class for objects representing dxf BLOCKs.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type block as input.
- """
- if not obj.type == 'block':
- raise TypeError, "Wrong type %s for block object!" %obj.type
-
- self.type = obj.type
- self.name = obj.name
- self.data = obj.data[:]
-
- # required data
- self.flags = getit(obj, 70, 0)
- self.anonim = self.flags & 1 #anonymous block generated by hatching, associative dimensioning, other
- self.atrib = self.flags & 2 # has attribute definitions
- self.xref = self.flags & 4 # is an external reference (xref)
- self.xref_lay = self.flags & 8 # is an xref overlay
- self.dep_ext = self.flags & 16 # is externally dependent
- self.dep_res = self.flags & 32 # resolved external reference
- self.xref_ext = self.flags & 64 # is a referenced external reference xref
- #--todo--- if self.flag > 4: self.xref = True
-
- # optional data (with defaults)
- self.path = getit(obj, 1, '') # Xref path name
- self.discription = getit(obj, 4, '')
-
- self.entities = dxfObject('block_contents') #creates empty entities_container for this block
- self.entities.data = objectify([ent for ent in obj.data if type(ent) != list])
-
- self.layer = getit(obj, 8, None)
- self.loc = self.get_loc(obj)
-
- #print 'deb:Block %s data:\n%s' %(self.name, self.data) #------------
- #print 'deb:Block %s self.entities.data:\n%s' %(self.name, self.entities.data) #------------
-
-
-
- def get_loc(self, data):
- """Gets the insert point of the block.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 10, 0.0) # 10 = x
- loc[1] = getit(data, 20, 0.0) # 20 = y
- loc[2] = getit(data, 30, 0.0) # 30 = z
- return loc
-
-
- def __repr__(self):
- return "%s: name - %s, description - %s, xref-path - %s" %(self.__class__.__name__, self.name, self.discription, self.path)
-
-
-
-
-class Insert: #-----------------------------------------------------------------
- """Class for objects representing dxf INSERTs.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type insert as input.
- """
- if not obj.type == 'insert':
- raise TypeError, "Wrong type %s for insert object!" %obj.type
- self.type = obj.type
- self.data = obj.data[:]
- #print 'deb:Insert_init_ self.data:\n', self.data #-----------
-
- # required data
- self.name = obj.get_type(2)[0]
-
- # optional data (with defaults)
- self.rotation = getit(obj, 50, 0)
- self.space = getit(obj, 67, 0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.loc = self.get_loc(obj)
- self.scale = self.get_scale(obj)
- self.rows, self.columns = self.get_array(obj)
- self.extrusion = get_extrusion(obj)
-
- #self.flags = getit(obj.data, 66, 0) #
- #self.attrib = self.flags & 1
-
-
- def get_loc(self, data):
- """Gets the origin location of the insert.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 10, 0.0)
- loc[1] = getit(data, 20, 0.0)
- loc[2] = getit(data, 30, 0.0)
- return loc
-
-
- def get_scale(self, data):
- """Gets the x/y/z scale factors of the insert.
- """
- scale = [1, 1, 1]
- scale[0] = getit(data, 41, 1.0)
- scale[1] = getit(data, 42, 1.0)
- scale[2] = getit(data, 43, 1.0)
- return scale
-
-
- def get_array(self, data):
- """Returns the pair (row number, row spacing), (column number, column spacing).
- """
- columns = getit(data, 70, 1)
- rows = getit(data, 71, 1)
- cspace = getit(data, 44, 0.0)
- rspace = getit(data, 45, 0.0)
- return (rows, rspace), (columns, cspace)
-
-
- def get_target(self, data):
- """Gets the origin location of the insert.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 1011, 0.0)
- loc[1] = getit(data, 1021, 0.0)
- loc[2] = getit(data, 1031, 0.0)
- return loc
-
-
- def get_color(self, data):
- """Gets the origin location of the insert.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 1010, 0.0)
- loc[1] = getit(data, 1020, 0.0)
- loc[2] = getit(data, 1030, 0.0)
- return loc
-
-
- def get_ave_render(self, data):
- """Gets the origin location of the insert.
- """
- loc = [0, 0, 0]
- loc[0] = getit(data, 1010, 0.0)
- loc[1] = getit(data, 1020, 0.0)
- loc[2] = getit(data, 1030, 0.0)
- return loc
-
-
- def __repr__(self):
- return "%s: layer - %s, name - %s" %(self.__class__.__name__, self.layer, self.name)
-
-
- def draw(self, settings, deltaloc):
- """for INSERT(block): draw empty-marker for duplicated Blender_Group.
-
- Blocks are made of three objects:
- the block_record in the tables section
- the block in the blocks section
- the insert object (one or more) in the entities section
- block_record gives the insert units,
- block provides the objects drawn in the block,
- insert object gives the location/scale/rotation of the block instances.
- """
-
- name = self.name.lower()
- if name == 'ave_render':
- if settings.var['lights_on']: #if lights support activated
- a_data = get_ave_data(self.data)
- # AVE_RENDER objects:
- # 7:'Pref', 0:'Full Opt', 0:'Quick Opt', 1:'Scanl Opt', 2:'Raytr Opt', 0:'RFile Opt'
- # 0:'Fog Opt', 0:'BG Opt', 0:'SCENE1','','','','','','','','','',
- # '','','','','','','','','','','','',
-
- if a_data.key == 'SCENE': # define set of lights as blender group
- scene_lights = 1
- return
- elif name == 'ave_global':
- if settings.var['lights_on']: #if lights support activated
- return
- elif name == 'sh_spot':
- if settings.var['lights_on']: #if lights support activated
- obname = settings.blocknamesmap[self.name]
- obname = 'sp_%s' %obname # create object name from block name
- #obname = obname[:MAX_NAMELENGTH]
- # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
- li = Lamp.New('Spot', obname)
- ob = SCENE.objects.new(li)
- intensity = 2.0 #--todo-- -----------
- li.setEnergy(intensity)
- target = self.get_target(self.data)
- color = self.get_color(self.data)
- li.R = color[0]
- li.G = color[1]
- li.B = color[2]
-
- ob.loc = tuple(self.loc)
- transform(self.extrusion, 0, ob)
- return ob
-
- elif name == 'overhead':
- if settings.var['lights_on']: #if lights support activated
- obname = settings.blocknamesmap[self.name]
- obname = 'la_%s' %obname # create object name from block name
- #obname = obname[:MAX_NAMELENGTH]
- # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
- li = Lamp.New('Lamp', obname)
- ob = SCENE.objects.new(li)
- intensity = 2.0 #--todo-- -----------
- li.setEnergy(intensity)
- target = self.get_target(self.data)
- color = self.get_color(self.data)
- li.R = color[0]
- li.G = color[1]
- li.B = color[2]
-
- ob.loc = tuple(self.loc)
- transform(self.extrusion, 0, ob)
- return ob
-
- elif name == 'direct':
- if settings.var['lights_on']: #if lights support activated
- obname = settings.blocknamesmap[self.name]
- obname = 'su_%s' %obname # create object name from block name
- #obname = obname[:MAX_NAMELENGTH]
- # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
- li = Lamp.New('Sun', obname)
- ob = SCENE.objects.new(li)
- intensity = 2.0 #--todo-- -----------
- li.setEnergy(intensity)
- color = self.get_color(self.data)
- li.R = color[0]
- li.G = color[1]
- li.B = color[2]
-
- ob.loc = tuple(self.loc)
- transform(self.extrusion, 0, ob)
- return ob
-
- elif settings.drawTypes['insert']: #if insert_drawType activated
- #print 'deb:draw. settings.blocknamesmap:', settings.blocknamesmap #--------------------
- obname = settings.blocknamesmap[self.name]
- obname = 'in_%s' %obname # create object name from block name
- #obname = obname[:MAX_NAMELENGTH]
-
- # if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty
- ob = SCENE.objects.new('Empty', obname) # create a new empty_object
- empty_size = 1.0 * settings.var['g_scale']
- if empty_size < 0.01: empty_size = 0.01 #Blender limits (0.01-10.0)
- elif empty_size > 10.0: empty_size = 10.0
- ob.drawSize = empty_size
-
- # get our block_def-group
- block = settings.blocks(self.name)
- ob.DupGroup = block
- ob.enableDupGroup = True
-
- if block.name.startswith('xr_'):
- ob.name = 'xb_' + ob.name[3:]
-
- #print 'deb:draw.block.deltaloc:', deltaloc #--------------------
- ob.loc = tuple(self.loc)
- if deltaloc:
- deltaloc = rotXY_Vec(self.rotation, deltaloc)
- #print 'deb:draw.block.loc:', deltaloc #--------------------
- ob.loc = [ob.loc[0]+deltaloc[0], ob.loc[1]+deltaloc[1], ob.loc[2]+deltaloc[2]]
- transform(self.extrusion, self.rotation, ob)
- ob.size = tuple(self.scale)
- return ob
-
-
-
-
-class Ellipse: #-----------------------------------------------------------------
- """Class for objects representing dxf ELLIPSEs.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type ellipse as input.
- """
- if not obj.type == 'ellipse':
- raise TypeError, "Wrong type %s for ellipse object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # required data
- self.ratio = obj.get_type(40)[0] # Ratio of minor axis to major axis
- self.start_angle = obj.get_type(41)[0] # in radians
- self.end_angle = obj.get_type(42)[0]
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.thic = getit(obj, 39, 0.0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.loc = self.get_loc(obj)
- self.major = self.get_major(obj)
- self.extrusion = get_extrusion(obj)
-
-
- def get_loc(self, data):
- """Gets the center location for arc type objects.
-
- Arcs have a single coord location.
- """
- loc = [0.0, 0.0, 0.0]
- loc[0] = getit(data, 10, 0.0)
- loc[1] = getit(data, 20, 0.0)
- loc[2] = getit(data, 30, 0.0)
- return loc
-
-
- def get_major(self, data):
- """Gets the major axis for ellipse type objects.
-
- The ellipse major axis defines the rotation of the ellipse and its radius.
- """
- loc = [0.0, 0.0, 0.0]
- loc[0] = getit(data, 11, 0.0)
- loc[1] = getit(data, 21, 0.0)
- loc[2] = getit(data, 31, 0.0)
- return loc
-
-
- def __repr__(self):
- return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
-
-
- def draw(self, settings):
- """for ELLIPSE: generate Blender_geometry.
- """
- obname = 'el_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
-
- center = self.loc
- start = degrees(self.start_angle)
- end = degrees(self.end_angle)
- if abs(end - 360.0) < 0.00001: end = 360.0
- ellipse_closed = False
- if end - start == 360.0: ellipse_closed = True
-
- # rotation = Angle between major and WORLDX
- # doesnt work, couse produces always positive value: rotation = Mathutils.AngleBetweenVecs(major, WORLDX)
- if self.major[0] == 0:
- rotation = 90.0
- if self.major[1] < 0: rotation += 180
- else:
- rotation = degrees(atan(self.major[1] / self.major[0]))
- if self.major[0] < 0:
- rotation += 180.0
-
- major = Mathutils.Vector(self.major)
- #radius = sqrt(self.major[0]**2 + self.major[1]**2 + self.major[2]**2)
- radius = major.length
- #print 'deb:calcEllipse:\n center, radius, start, end:\n', center, radius, start, end #---------
-
- thic = set_thick(self.thic, settings)
- width = 0.0
- if settings.var['lines_as'] == 4: # as thin_box
- thic = settings.var['thick_min']
- width = settings.var['width_min']
- elif settings.var['lines_as'] == 3: # as thin cylinder
- cyl_rad = 0.5 * settings.var['width_min']
-
- elif settings.var['lines_as'] == 5: # draw ELLIPSE as curve -------------
- arc_res = settings.var['curve_arc']
- triples = True
- VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
- arc = Curve.New(obname) # create new curve data
- curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
- if ellipse_closed:
- for p in VectorTriples[1:-1]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [FREE, FREE]
- point.radius = 1.0
- curve.flagU = 1 # 0 sets the curve not cyclic=open
- if settings.var['fill_on']:
- arc.setFlag(6) # 2+4 set top and button caps
- else:
- arc.setFlag(arc.getFlag() & ~6) # dont set top and button caps
- else:
- for p in VectorTriples[1:]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [FREE, FREE]
- point.radius = 1.0
- curve.flagU = 0 # 0 sets the curve not cyclic=open
-
- arc.setResolu(settings.var['curve_res'])
- arc.update() #important for handles calculation
-
- ob = SCENE.objects.new(arc) # create a new curve_object
- ob.loc = tuple(self.loc)
- if thic != 0.0: #hack: Blender<2.45 curve-extrusion
- thic = thic * 0.5
- arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
- ob.LocZ = thic + self.loc[2]
- transform(self.extrusion, rotation, ob)
- ob.SizeY *= self.ratio
- if thic != 0.0:
- ob.SizeZ *= abs(thic)
- return ob
-
-
- else: # draw ELLIPSE as mesh --------------------------------------
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- # set a number of segments in entire circle
- arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
-
- verts = calcArc(None, radius, start, end, arc_res, False)
- #verts = [list(point) for point in verts]
- len1 = len(verts)
- #print 'deb:len1:', len1 #-----------------------
- if width != 0:
- radius_out = radius + (0.5 * width)
- radius_in = radius - (0.5 * width)
- if radius_in <= 0.0:
- radius_in = settings.var['dist_min']
- #radius_in = 0.0
- verts_in = []
- verts_out = []
- for point in verts:
- pointVec = Mathutils.Vector(point)
- pointVec = pointVec.normalize()
- verts_in.append(list(radius_in * pointVec)) #vertex inside
- verts_out.append(list(radius_out * pointVec)) #vertex outside
- verts = verts_in + verts_out
-
- #print 'deb:verts:', verts #---------------------
- if thic != 0:
- thic_verts = []
- thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
- if thic < 0.0:
- thic_verts.extend(verts)
- verts = thic_verts
- else:
- verts.extend(thic_verts)
- f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
- f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
- f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
- f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
- f_start = [[0, len1, len1+len1+len1, len1+len1]]
- f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
- faces = f_left + f_right + f_bottom + f_top + f_start + f_end
-
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- smooth_len = len(f_left) + len(f_right)
- for i in xrange(smooth_len):
- me.faces[i].smooth = True
- if settings.var['vGroup_on'] and not M_OBJ:
- # each MeshSide becomes vertexGroup for easier material assignment ---------------------
- replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
- vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
- for v in f_left: vg_left.extend(v)
- for v in f_right: vg_right.extend(v)
- for v in f_top: vg_top.extend(v)
- for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
- me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
- me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
- me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
-
-
- else: # if thick=0 - draw only flat ring
- faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- elif thic != 0:
- thic_verts = []
- thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
- if thic < 0.0:
- thic_verts.extend(verts)
- verts = thic_verts
- else:
- verts.extend(thic_verts)
- faces = []
- #print 'deb:len1:', len1 #-----------------------
- #print 'deb:verts:', verts #---------------------
- faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
-
- me.verts.extend(verts) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
- if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
- for i in xrange(len(faces)):
- me.faces[i].smooth = True
-
- else:
- edges = [[num, num+1] for num in xrange(len(verts)-1)]
- me.verts.extend(verts) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- #print 'deb:calcEllipse transform rotation: ', rotation #---------
- ob.loc = tuple(center)
- #old ob.SizeY = self.ratio
- transform(self.extrusion, rotation, ob)
- #old transform(self.extrusion, 0, ob)
- ob.SizeY *= self.ratio
-
- return ob
-
-
-
-class Face: #-----------------------------------------------------------------
- """Class for objects representing dxf 3DFACEs.
- """
-
- def __init__(self, obj):
- """Expects an entity object of type 3dfaceplot as input.
- """
- if not obj.type == '3dface':
- raise TypeError, "Wrong type %s for 3dface object!" %obj.type
- self.type = obj.type
-# self.data = obj.data[:]
-
- # optional data (with defaults)
- self.space = getit(obj, 67, 0)
- self.color_index = getit(obj, 62, BYLAYER)
-
- self.layer = getit(obj, 8, None)
- self.points = self.get_points(obj)
-
-
- def get_points(self, data):
- """Gets 3-4 points for a 3d face type object.
-
- Faces have three or optionally four verts.
- """
- a = [0, 0, 0]
- b = [0, 0, 0]
- c = [0, 0, 0]
- d = [0, 0, 0]
- a[0] = getit(data, 10, None) # 10 = x
- a[1] = getit(data, 20, None) # 20 = y
- a[2] = getit(data, 30, 0.0) # 30 = z
- b[0] = getit(data, 11, None)
- b[1] = getit(data, 21, None)
- b[2] = getit(data, 31, 0.0)
- c[0] = getit(data, 12, None)
- c[1] = getit(data, 22, None)
- c[2] = getit(data, 32, 0.0)
- out = [a,b,c]
-
- d[0] = getit(data, 13, None)
- if d[0] != None:
- d[1] = getit(data, 23, None)
- d[2] = getit(data, 33, 0.0)
- out.append(d)
-
- #if len(out) < 4: print '3dface with only 3 vertices:\n',a,b,c,d #-----------------
- return out
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, settings):
- """for 3DFACE: generate Blender_geometry.
- """
- # Generate the geometery
- points = self.points
-
- global activObjectLayer
- global activObjectName
- #print 'deb:draw:face.ob IN activObjectName: ', activObjectName #---------------------
-
- if M_OBJ: obname, me, ob = makeNewObject()
- else:
- if activObjectLayer == self.layer and settings.var['one_mesh_on']:
- obname = activObjectName
- #print 'deb:face.draw obname from activObjectName: ', obname #---------------------
- ob = getSceneChild(obname) # open an existing mesh_object
- #ob = SCENE.getChildren(obname) # open an existing mesh_object
- me = ob.getData(name_only=False, mesh=True)
- else:
- obname = 'fa_%s' %self.layer # create object name from layer name
- obname = obname[:MAX_NAMELENGTH]
- me = Mesh.New(obname) # create a new mesh
- ob = SCENE.objects.new(me) # create a new mesh_object
- activObjectName = ob.name
- activObjectLayer = self.layer
- #print ('deb:except. new face.ob+mesh:"%s" created!' %ob.name) #---------------------
-
- #me = Mesh.Get(ob.name) # open objects mesh data
- faces, edges = [], []
- n = len(me.verts)
- if len(self.points) == 4:
- faces = [[0+n,1+n,2+n,3+n]]
- elif len(self.points) == 3:
- faces = [[0+n,1+n,2+n]]
- elif len(self.points) == 2:
- edges = [[0+n,1+n]]
-
- me.verts.extend(points) # add vertices to mesh
- if faces: me.faces.extend(faces) # add faces to the mesh
- if edges: me.edges.extend(edges) # add faces to the mesh
- if settings.var['vGroup_on'] and not M_OBJ:
- # entities with the same color build one vertexGroup for easier material assignment ---------------------
- ob.link(me) # link mesh to that object
- vG_name = 'color_%s' %self.color_index
- if edges: faces = edges
- replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
- try:
- me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
- #print 'deb: existed vGroup:', vG_name #---------------------
- except:
- me.addVertGroup(vG_name)
- me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
- #print 'deb: create new vGroup:', vG_name #--------------------
-
- #print 'deb:draw:face.ob OUT activObjectName: ', activObjectName #---------------------
- return ob
-
-
-#---------------------------------------------------------------------------------------
-# type to object maping (sorted-dictionary for f_obiectify ONLY!, format={'key':Class} )
-type_map = {
- 'vport':Vport,
- 'view':View,
- 'layer':Layer,
- 'block_record':BlockRecord,
- 'block':Block,
- 'insert':Insert,
- 'point':Point,
- '3dface':Face,
- 'line':Line,
-# 'mline':MLine,
- 'polyline':Polyline,
- 'lwpolyline':LWpolyline,
- 'spline':Spline,
-# 'region':Region,
- 'trace':Solid,
- 'solid':Solid,
- 'text':Text,
- 'mtext':Mtext,
- 'circle':Circle,
- 'ellipse':Ellipse,
- 'arc':Arc
-}
-
-
-
-def objectify(data): #-----------------------------------------------------------------
- """Expects a section type object's data as input.
-
- Maps object data to the correct object type.
- """
- #print 'deb:objectify start %%%%%%%%%%%' #---------------
- objects = [] # colector for finished objects
- known_types = type_map.keys() # so we don't have to call foo.keys() every iteration
- curves_on = GUI_A['curves_on'].val
- index = 0
- while index < len(data):
- item = data[index]
- #print 'deb:objectify item: \n', item #------------
- if type(item) != list and item.type == 'table':
- item.data = objectify(item.data) # tables have sub-objects
- objects.append(item)
- elif type(item) != list and item.type == 'polyline': #remi --todo-----------
- #print 'deb:gosub Polyline\n' #-------------
- pline = Polyline(item)
- while 1:
- index += 1
- item = data[index]
- if item.type == 'vertex':
- #print 'deb:objectify gosub Vertex--------' #-------------
- v = Vertex(item)
- if pline.spline: # if NURBSpline-curve
- # then for Blender-mesh filter only additional_vertices
- # OR
- # then for Blender-curve filter only spline_control_vertices
- if (v.spline and not curves_on) or (curves_on and v.spline_c): #correct for real NURBS-import
- #if (v.spline and not curves_on) or (curves_on and not v.spline_c): #fake for Bezier-emulation of NURBS-import
- pline.points.append(v)
- elif pline.curved: # if Bezier-curve
- # then for Blender-mesh filter only curve_additional_vertices
- # OR
- # then for Blender-curve filter curve_control_vertices
- if not curves_on or (curves_on and not v.curved):
- pline.points.append(v)
- else:
- pline.points.append(v)
- elif item.type == 'seqend':
- #print 'deb:objectify it is seqEND ---------\n' #-------------
- break
- else:
- print "Error: non-vertex found before seqend!"
- index -= 1 #so go back one step
- break
- objects.append(pline)
- elif type(item) != list and item.type in ['block', 'insert']:
- if not settings.var['block_nn'] and item.name.startswith('*X'):
- #print 'deb:objectify item.type:"%s", item.name:"%s"' %(item.type, item.name) #------------
- pass
- elif settings.var['blockFilter_on'] and not settings.accepted_block(item.name):
- pass
- else:
- try:
- objects.append(type_map[item.type](item))
- except TypeError:
- pass
- elif type(item) != list and item.type in known_types:
- # proccess the object and append the resulting object
- try:
- objects.append(type_map[item.type](item))
- except TypeError:
- pass
- else:
- #we will just let the data pass un-harrased
- #objects.append(item)
- pass
- index += 1
- #print 'deb:objectify objects:\n', objects #------------
- #print 'deb:objectify END %%%%%%%%' #------------
- return objects
-
-
-
-class MatColors: #-----------------------------------------------------------------
- """A smart container for dxf-color based materials.
-
- This class is a wrapper around a dictionary mapping dxf-color indicies to materials.
- When called with a color_index
- it returns a material corresponding to that index.
- Behind the scenes it checks if that index is in its keys, and if not it creates
- a new material. It then adds the new index:material pair to its dict and returns
- the material.
- """
-
- def __init__(self):
- """Expects a map - a dictionary mapping layer names to layers.
- """
- #self.layersmap = layersmap # a dictionary of layername:layerobject
- self.colMaterials = {} # a dictionary of color_index:blender_material
- #print 'deb:init_MatColors argument.map: ', map #------------------
-
-
- def __call__(self, color=None):
- """Return the material associated with color.
-
- If a layer name is provided, the color of that layer is used.
- """
- if color == None: color = 256 # color 256=BYLAYER
- if type(color) == str: # looking for color of LAYER named "color"
- #--todo---bug with ARC from ARC-T0.DXF layer="T-3DARC-1"-----
- #print 'deb:color is string:--------: ', color
- #try:
- #color = layersmap[color].color
- #print 'deb:color=self.map[color].color:', color #------------------
- #except KeyError:
- #layer = Layer(name=color, color=256, frozen=False)
- #layersmap[color] = layer
- #color = 0
- if color in layersmap.keys():
- color = layersmap[color].color
- if color == 256: # color 256 = BYLAYER
- #--todo-- should looking for color of LAYER
- #if layersmap: color = layersmap[color].color
- color = 3
- if color == 0: # color 0 = BYBLOCK
- #--todo-- should looking for color of paret-BLOCK
- #if layersmap: color = layersmap[color].color
- color = 3
- color = abs(color) # cause the value could be nagative = means the layer is turned off
-
- if color not in self.colMaterials.keys():
- self.add(color)
- return self.colMaterials[color]
-
-
- def add(self, color):
- """Create a new material 'ColorNr-N' using the provided color index-N.
- """
- #global color_map #--todo-- has not to be global?
- mat = Material.New('ColorNr-%s' %color)
- mat.setRGBCol(color_map[color])
- #mat.mode |= Material.Modes.SHADELESS #--todo--
- #mat.mode |= Material.Modes.WIRE
-# try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug
-# except: pass
- self.colMaterials[color] = mat
-
-
-
-class MatLayers: #-----------------------------------------------------------------
- """A smart container for dxf-layer based materials.
-
- This class is a wrapper around a dictionary mapping dxf-layer names to materials.
- When called with a layer name it returns a material corrisponding to that.
- Behind the scenes it checks if that layername is in its keys, and if not it creates
- a new material. It then adds the new layername:material pair to its dict and returns
- the material.
- """
-
- def __init__(self):
- """Expects a map - a dictionary mapping layer names to layers.
- """
- #self.layersmap = layersmap # a dictionary of layername:layer
- self.layMaterials = {} # a dictionary of layer_name:blender_material
- #print 'deb:init_MatLayers argument.map: ', map #------------------
-
-
- def __call__(self, layername=None, color=None):
- """Return the material associated with dxf-layer.
-
- If a dxf-layername is not provided, create a new material
- """
- #global layernamesmap
- layername_short = layername
- if layername in layernamesmap.keys():
- layername_short = layernamesmap[layername]
- colorlayername = layername_short
- if color: colorlayername = str(color) + colorlayername
- if colorlayername not in self.layMaterials.keys():
- self.add(layername, color, colorlayername)
- return self.layMaterials[colorlayername]
-
-
- def add(self, layername, color, colorlayername):
- """Create a new material 'layername'.
- """
- try: mat = Material.Get('L-%s' %colorlayername)
- except: mat = Material.New('L-%s' %colorlayername)
- #print 'deb:MatLayers material: ', mat #----------
- #global settings
- #print 'deb:MatLayers material_from: ', settings.var['material_from'] #----------
- if settings.var['material_from'] == 3 and color:
- if color == 0 or color == 256: mat_color = 3
- else: mat_color = color
- elif layersmap and layername:
- mat_color = layersmap[layername].color
- else: mat_color = 3
- #print 'deb:MatLayers color: ', color #-----------
- #print 'deb:MatLayers mat_color: ', mat_color #-----------
- mat.setRGBCol(color_map[abs(mat_color)])
- #mat.mode |= Material.Modes.SHADELESS
- #mat.mode |= Material.Modes.WIRE
-# try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug
-# except: pass
- self.layMaterials[colorlayername] = mat
-
-
-
-
-class Blocks: #-----------------------------------------------------------------
- """A smart container for blocks.
-
- This class is a wrapper around a dictionary mapping block names to Blender data blocks.
- When called with a name string it returns a block corresponding to that name.
- Behind the scenes it checks if that name is in its keys, and if not it creates
- a new data block. It then adds the new name:block_data pair to its dict and returns
- the block.
- """
-
- def __init__(self, blocksmap, settings):
- """Expects a dictionary mapping block_name:block_data.
- """
- self.blocksmap = blocksmap #a dictionary mapping block_name:block_data
- self.settings = settings
- self.blocks = {} #container for blender groups representing blocks
-
-
- def __call__(self, name=None):
- """Return the data block associated with that block_name.
-
- If that name is not in its keys, it creates a new data block.
- If no name is provided return entire self.blocks container.
- """
- if name == None:
- return self.blocks
- if name not in self.blocks.keys():
- self.addBlock(name)
- return self.blocks[name]
-
-
- def addBlock(self, name):
- """Create a new 'block group' for the block name.
- """
- block = self.blocksmap[name]
- prefix = 'bl'
- if block.xref: prefix = 'xr'
- blender_group = Group.New('%s_%s' %(prefix,name)) # Blender groupObject contains definition of BLOCK
- block_def = [blender_group, block.loc]
- self.settings.write("\nDrawing block:\'%s\' ..." % name)
-
- if block.xref:
- obname = 'xr_%s' %name # create object name from xref block name
- #obname = obname[:MAX_NAMELENGTH]
- # if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty
- ob = SCENE.objects.new('Empty', obname) # create a new empty_object
- empty_size = 1.0 * settings.var['g_scale']
- if empty_size < 0.01: empty_size = 0.01 #Blender limits (0.01-10.0)
- elif empty_size > 10.0: empty_size = 10.0
- ob.drawSize = empty_size
- ob.loc = tuple(block.loc)
- ob.properties['xref_path'] = block.path
- ob.layers = [19]
- insertFlag=True; blockFlag=True
- global oblist
- oblist.append((ob, insertFlag, blockFlag))
- else:
- if M_OBJ:
- car_end()
- car_start()
- drawEntities(block.entities, self.settings, block_def)
- if M_OBJ: car_end()
- self.settings.write("Drawing block:\'%s\' done!" %name)
- self.blocks[name] = blender_group
-
-
-
-
-
-class Settings: #-----------------------------------------------------------------
- """A container for all the import settings and objects used by the draw functions.
-
- This is like a collection of globally accessable persistant properties and functions.
- """
- # Optimization constants
- MIN = 0
- MID = 1
- PRO = 2
- MAX = 3
-
- def __init__(self, keywords, drawTypes):
- """initialize all the important settings used by the draw functions.
- """
- self.obj_number = 1 #global object_number for progress_bar
-
- self.var = dict(keywords) #a dictionary of (key_variable:Value) control parameter
- self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type
-
- self.var['colorFilter_on'] = False #deb:remi------------
- self.acceptedColors = [0,2,3,4,5,6,7,8,9,
- 10 ]
-
- self.var['layerFilter_on'] = False #deb:remi------------
- self.acceptedLayers = ['3',
- '0'
- ]
-
- self.var['groupFilter_on'] = False #deb:remi------------
- self.acceptedLayers = ['3',
- '0'
- ]
-
- #self.var['blockFilter_on'] = 0 #deb:remi------------
- self.acceptedBlocks = ['WALL_1871',
- 'BOX02'
- ]
- self.unwantedBlocks = ['BOX05',
- 'BOX04'
- ]
-
-
- def update(self, keywords, drawTypes):
- """update all the important settings used by the draw functions.
- mostly used after loading parameters from INI-file
- """
-
- for k, v in keywords.iteritems():
- self.var[k] = v
- #print 'deb:settings_update var %s= %s' %(k, self.var[k]) #--------------
- for t, v in drawTypes.iteritems():
- self.drawTypes[t] = v
- #print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #--------------
-
- self.drawTypes['arc'] = self.drawTypes['line']
- self.drawTypes['circle'] = self.drawTypes['line']
- self.drawTypes['ellipse'] = self.drawTypes['line']
- self.drawTypes['trace'] = self.drawTypes['solid']
- self.drawTypes['insert'] = self.drawTypes['block']
- #self.drawTypes['vport'] = self.drawTypes['view']
-
- #print 'deb:self.drawTypes', self.drawTypes #---------------
-
-
- def validate(self, drawing):
- """Given the drawing, build dictionaries of Layers, Colors and Blocks.
- """
-
- global oblist
- #adjust the distance parameter to globalScale
- if self.var['g_scale'] != 1.0:
- self.var['dist_min'] = self.var['dist_min'] / self.var['g_scale']
- self.var['thick_min'] = self.var['thick_min'] / self.var['g_scale']
- self.var['width_min'] = self.var['width_min'] / self.var['g_scale']
- self.var['arc_rad'] = self.var['arc_rad'] / self.var['g_scale']
-
- self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ'])
-
- # First sort out all the section_items
- sections = dict([(item.name, item) for item in drawing.data])
-
- # The section:header may be omited
- if 'header' in sections.keys():
- self.write("found section:header")
- else:
- self.write("File contains no section:header!")
-
- if self.var['optimization'] == 0: self.var['one_mesh_on'] = 0
- # The section:tables may be partialy or completely missing.
- self.layersTable = False
- self.colMaterials = MatColors() #A container for dxf-color based materials
- self.layMaterials = MatLayers() #A container for dxf-layer based materials
- #self.collayMaterials = MatColLayers({}) #A container for dxf-color+layer based materials
- global layersmap, layernamesmap
- layersmap, layernamesmap = {}, {}
- if 'tables' in sections.keys():
- self.write("found section:tables")
- views, vports, layers = False, False, False
- for table in drawing.tables.data:
- if table.name == 'layer':
- self.write("found table:layers")
- layers = table
- elif table.name == 'view':
- print "found table:view"
- views = table
- elif table.name == 'vport':
- print "found table:vport"
- vports = table
- if layers: #----------------------------------
- # Read the layers table and get the layer colors
- layersmap, layernamesmap = getLayersmap(layers)
- #self.colMaterials = MatColors()
- #self.layMaterials = MatLayers()
- else:
- self.write("File contains no table:layers!")
-
-
- if views: #----------------------------------
- if self.var['views_on']:
- for item in views.data:
- if type(item) != list and item.type == 'view':
- #print 'deb:settings_valid views dir(item)=', dir(item) #-------------
- #print 'deb:settings_valid views item=', item #-------------
- ob = item.draw(self)
- #viewsmap[item.name] = [item.length]
- #--todo-- add to obj_list for global.Scaling
- insertFlag, blockFlag = False, False
- oblist.append((ob, insertFlag, blockFlag))
-
- else:
- self.write("File contains no table:views!")
-
-
- if vports: #----------------------------------
- if self.var['views_on']:
- for item in vports.data:
- if type(item) != list and item.type == 'vport':
- #print 'deb:settings_valid views dir(item)=', dir(item) #-------------
- #print 'deb:settings_valid views item=', item #-------------
- ob = item.draw(self)
- #viewsmap[item.name] = [item.length]
- #--todo-- add to obj_list for global.Scaling
- insertFlag, blockFlag = False, False
- oblist.append((ob, insertFlag, blockFlag))
- else:
- self.write("File contains no table:vports!")
-
-
- else:
- self.write("File contains no section:tables!")
- self.write("File contains no table:layers!")
-
-
- # The section:blocks may be omited
- if 'blocks' in sections.keys():
- self.write("found section:blocks")
- # Read the block definitions and build our block object
- if self.drawTypes['insert']: #if support for entity type 'Insert' is activated
- #Build a dictionary of blockname:block_data pairs
- blocksmap, obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on'])
- self.obj_number += obj_number
- self.blocknamesmap = getBlocknamesmap(blocksmap)
- self.blocks = Blocks(blocksmap, self) # initiates container for blocks_data
- self.usedBlocks = blocksmap.keys()
- #print 'deb:settings_valid self.usedBlocks', self.usedBlocks #----------
- else:
- self.write("ignored, because support for BLOCKs is turn off!")
- #print 'deb:settings_valid self.obj_number', self.obj_number #----------
- else:
- self.write("File contains no section:blocks!")
- self.drawTypes['insert'] = False
-
- # The section:entities
- if 'entities' in sections.keys():
- self.write("found section:entities")
- self.obj_number += len(drawing.entities.data)
- self.obj_number = 1.0 / self.obj_number
-
-
- def accepted_block(self, name):
- if name not in self.usedBlocks: return False
- if name in self.unwantedBlocks: return False
- elif name in self.acceptedBlocks: return True
- #elif (name.find('*X')+1): return False
- #elif name.startswith('3'): return True
- #elif name.endswith('H'): return False
- return True
-
-
- def write(self, text, newline=True):
- """Wraps the built-in print command in a optimization check.
- """
- if self.var['optimization'] <= self.MID:
- if newline: print text
- else: print text,
-
-
- def redraw(self):
- """Update Blender if optimization level is low enough.
- """
- if self.var['optimization'] <= self.MIN:
- Blender.Redraw()
-
-
- def progress(self, done, text):
- """Wrapper for Blender.Window.DrawProgressBar.
- """
- if self.var['optimization'] <= self.PRO:
- progressbar = done * self.obj_number
- Window.DrawProgressBar(progressbar, text)
- #print 'deb:drawer done, progressbar: ', done, progressbar #-----------------------
-
- def layer_isOff(self, layername): # no more used -------
- """Given a layer name, and return its visible status.
- """
- # if layer is off then color_index is negative
- if layersmap and layersmap[layername].color < 0: return True
- #print 'deb:layer_isOff: layer is ON' #---------------
- return False
-
-
- def layer_isFrozen(self, layername): # no more used -------
- """Given a layer name, and return its frozen status.
- """
- if layersmap and layersmap[layername].frozen: return True
- #print 'deb:layer_isFrozen: layer is not FROZEN' #---------------
- return False
-
-
-
-def analyzeDXF(dxfFile): #---------------------------------------
- """list statistics about LAYER and BLOCK dependences into textfile.INF
-
- """
- Window.WaitCursor(True) # Let the user know we are thinking
- print 'reading DXF file: %s.' % dxfFile
- time1 = sys.time() #time marker1
- drawing = readDXF(dxfFile, objectify)
- print 'finish reading in %.4f sec.' % (sys.time()-time1)
-
- # First sort out all the section_items
- sections = dict([(item.name, item) for item in drawing.data])
-
- # The section:header may be omited
- if 'header' in sections.keys(): print "found section:header"
- else: print "File contains no section:header!"
-
- # The section:tables may be partialy or completely missing.
- layersTable = False
- global layersmap
- layersmap = {}
- viewsmap = {}
- vportsmap = {}
- layersmap_str = '#File contains no table:layers!'
- viewsmap_str = '#File contains no table:views!'
- vportsmap_str = '#File contains no table:vports!'
- if 'tables' in sections.keys():
- print "found section:tables"
- views, vports, layers = False, False, False
- for table in drawing.tables.data:
- if table.name == 'layer':
- print "found table:layers"
- layers = table
- elif table.name == 'view':
- print "found table:view"
- views = table
- elif table.name == 'vport':
- print "found table:vport"
- vports = table
- if layers: #----------------------------------
- for item in layers.data:
- if type(item) != list and item.type == 'layer':
- #print dir(item)
- layersmap[item.name] = [item.color, item.frozen]
- #print 'deb:analyzeDXF: layersmap=' , layersmap #-------------
- layersmap_str = '#list of LAYERs: name, color, frozen_status ---------------------------\n'
- key_list = layersmap.keys()
- key_list.sort()
- for key in key_list:
- #for layer_name, layer_data in layersmap.iteritems():
- layer_name, layer_data = key, layersmap[key]
- layer_str = '\'%s\': col=%s' %(layer_name,layer_data[0])#-------------
- if layer_data[1]: layer_str += ', frozen'
- layersmap_str += layer_str + '\n'
- #print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #-------------
- else:
- print "File contains no table:layers!"
-
- if views: #----------------------------------
- for item in views.data:
- if type(item) != list and item.type == 'view':
- #print dir(item)
- viewsmap[item.name] = [item.length]
- #print 'deb:analyzeDXF: viewsmap=' , viewsmap #-------------
- viewsmap_str = '#list of VIEWs: name, focus_length ------------------------------------\n'
- key_list = viewsmap.keys()
- key_list.sort()
- for key in key_list:
- #for view_name, view_data in viewsmap.iteritems():
- view_name, view_data = key, viewsmap[key]
- view_str = '\'%s\': length=%s' %(view_name,view_data[0])#-------------
- #if view_data[1]: view_str += ', something'
- viewsmap_str += view_str + '\n'
- #print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #-------------
- else:
- print "File contains no table:views!"
-
- if vports: #----------------------------------
- for item in vports.data:
- if type(item) != list and item.type == 'vport':
- #print dir(item)
- vportsmap[item.name] = [item.length]
- #print 'deb:analyzeDXF: vportsmap=' , vportsmap #-------------
- vportsmap_str = '#list of VPORTs: name, focus_length -----------------------------------\n'
- key_list = vportsmap.keys()
- key_list.sort()
- for key in key_list:
- #for vport_name, vport_data in vportsmap.iteritems():
- vport_name, vport_data = key, vportsmap[key]
- vport_str = '\'%s\': length=%s' %(vport_name,vport_data[0])#-------------
- #if vport_data[1]: vport_str += ', something'
- vportsmap_str += vport_str + '\n'
- #print 'deb:analyzeDXF: vportsmap_str=\n' , vportsmap_str #-------------
- else:
- print "File contains no table:vports!"
-
- else:
- print "File contains no section:tables!"
- print "File contains no tables:layers,views,vports!"
-
- # The section:blocks may be omited
- if 'blocks' in sections.keys():
- print "found section:blocks"
- blocksmap = {}
- for item in drawing.blocks.data:
- #print 'deb:getBlocksmap item=' ,item #--------
- #print 'deb:getBlocksmap item.entities=' ,item.entities #--------
- #print 'deb:getBlocksmap item.entities.data=' ,item.entities.data #--------
- if type(item) != list and item.type == 'block':
- xref = False
- if item.xref: xref = True
- childList = []
- used = False
- for item2 in item.entities.data:
- if type(item2) != list and item2.type == 'insert':
- #print 'deb:getBlocksmap dir(item2)=', dir(item2) #----------
- item2str = [item2.name, item2.layer, item2.color_index, item2.scale, item2.space]
- childList.append(item2str)
- try: blocksmap[item.name] = [used, childList, xref]
- except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
- #print 'deb:analyzeDXF: blocksmap=' , blocksmap #-------------
-
- for item2 in drawing.entities.data:
- if type(item2) != list and item2.type == 'insert':
- if item2.name in blocksmap.keys():
- if not layersmap or (layersmap and not layersmap[item2.layer][1]): #if insert_layer is not frozen
- blocksmap[item2.name][0] = True # marked as world used BLOCK
-
- key_list = blocksmap.keys()
- key_list.reverse()
- for key in key_list:
- if blocksmap[key][0]: #if used
- for child in blocksmap[key][1]:
- if not layersmap or (layersmap and not layersmap[child[1]][1]): #if insert_layer is not frozen
- blocksmap[child[0]][0] = True # marked as used BLOCK
-
- blocksmap_str = '#list of BLOCKs: name:(unused)(xref) -[child_name, layer, color, scale, space]-------\n'
- key_list = blocksmap.keys()
- key_list.sort()
- for key in key_list:
- #for block_name, block_data in blocksmap.iteritems():
- block_name, block_data = key, blocksmap[key]
- block_str = '\'%s\': ' %(block_name) #-------------
- used = '(unused)'
- if block_data[0]: used = ''
-# else: used = '(unused)'
- xref = ''
- if block_data[2]: xref = '(xref)'
- blocksmap_str += block_str + used + xref +'\n'
- if block_data:
- for block_item in block_data[1]:
- block_data_str = ' - %s\n' %block_item
- blocksmap_str += block_data_str
- #print 'deb:analyzeDXF: blocksmap_str=\n' , blocksmap_str #-------------
- else:
- blocksmap_str = '#File contains no section:blocks!'
- print "File contains no section:blocks!"
-
- Window.WaitCursor(False)
- output_str = '%s\n%s\n%s\n%s' %(viewsmap_str, vportsmap_str, layersmap_str, blocksmap_str)
- infFile = dxfFile[:-4] + '_DXF.INF' # replace last char:'.dxf' with '_DXF.inf'
- try:
- f = file(infFile, 'w')
- f.write(INFFILE_HEADER + '\n# this is a comment line\n\n')
- f.write(output_str)
- f.close()
- Draw.PupMenu('DXF importer: report saved in INF-file:%t|' + '\'%s\'' %infFile)
- except:
- Draw.PupMenu('DXF importer: ERROR by writing report in INF-file:%t|' + '\'%s\'' %infFile)
- #finally: f.close()
-
-
-
-
-def main(dxfFile): #---------------#############################-----------
- #print 'deb:filename:', filename #--------------
- global SCENE
- global oblist
- editmode = Window.EditMode() # are we in edit mode? If so ...
- if editmode:
- Window.EditMode(0) # leave edit mode before
-
- #SCENE = bpy.data.scenes.active
- #SCENE.objects.selected = [] # deselect all
-
- global cur_COUNTER #counter for progress_bar
- cur_COUNTER = 0
-
- #try:
- if 1:
- #print "Getting settings..."
- global GUI_A, GUI_B, g_scale_as
- if not GUI_A['g_scale_on'].val:
- GUI_A['g_scale'].val = 1.0
-
- keywords = {}
- drawTypes = {}
- for k, v in GUI_A.iteritems():
- keywords[k] = v.val
- for k, v in GUI_B.iteritems():
- drawTypes[k] = v.val
- #print 'deb:startUInew keywords: ', keywords #--------------
- #print 'deb:startUInew drawTypes: ', drawTypes #--------------
-
- # The settings object controls how dxf entities are drawn
- settings.update(keywords, drawTypes)
- #print 'deb:settings.var:\n', settings.var #-----------------------
-
- if not settings:
- #Draw.PupMenu('DXF importer: EXIT!%t')
- #print '\nDXF Import: terminated by user!'
- print '\nDXF Import: terminated, cause settings failure!'
- Window.WaitCursor(False)
- if editmode: Window.EditMode(1) # and put things back how we fond them
- return None
-
- #no more used dxfFile = dxfFileName.val
- #print 'deb: dxfFile file: ', dxfFile #----------------------
- if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
- Window.WaitCursor(True) # Let the user know we are thinking
- print 'reading file: %s.' % dxfFile
- time1 = sys.time() #time marker1
- drawing = readDXF(dxfFile, objectify)
- print 'reading finished in %.4f sec.' % (sys.time()-time1)
- Window.WaitCursor(False)
- elif dxfFile.lower().endswith('.dwg') and sys.exists(dxfFile):
- if not extCONV_OK:
- Draw.PupMenu(extCONV_TEXT)
- Window.WaitCursor(False)
- if editmode: Window.EditMode(1) # and put things back how we fond them
- return None
- else:
- Window.WaitCursor(True) # Let the user know we are thinking
- #todo: issue: in DConvertCon.exe the output filename is fixed to dwg_name.dxf
-
- if 0: # works only for Windows
- dwgTemp = 'temp_01.dwg'
- dxfTemp = 'temp_01.dxf'
- os.system('copy %s %s' %(dxfFile,dwgTemp))
- else:
- dwgTemp = dxfFile
- dxfTemp = dxfFile[:-3]+'dxf'
- #print 'temp. converting: %s\n to: %s' %(dxfFile, dxfTemp)
- #os.system('%s %s -acad11 -dxf' %(extCONV_PATH, dxfFile))
- os.system('%s %s -dxf' %(extCONV_PATH, dwgTemp))
- #os.system('%s %s -dxf' %(extCONV_PATH, dxfFile_temp))
- if sys.exists(dxfTemp):
- print 'reading file: %s.' % dxfTemp
- time1 = sys.time() #time marker1
- drawing = readDXF(dxfTemp, objectify)
- #os.remove(dwgTemp)
- os.remove(dxfTemp) # clean up
- print 'reading finished in %.4f sec.' % (sys.time()-time1)
- Window.WaitCursor(False)
- else:
- if UI_MODE: Draw.PupMenu('DWG importer: nothing imported!%t|No valid DXF-representation found!')
- print 'DWG importer: nothing imported. No valid DXF-representation found.'
- Window.WaitCursor(False)
- if editmode: Window.EditMode(1) # and put things back how we fond them
- return None
- else:
- if UI_MODE: Draw.PupMenu('DXF importer: Alert!%t| no valid DXF-file selected!')
- print "DXF importer: Alert! - no valid DXF-file selected."
- Window.WaitCursor(False)
- if editmode: Window.EditMode(1) # and put things back how we fond them
- return None
-
- # Draw all the know entity types in the current scene
- oblist = [] # a list of all created AND linked objects for final f_globalScale
- time2 = sys.time() #time marker2
-
- Window.WaitCursor(True) # Let the user know we are thinking
- settings.write("\n\nDrawing entities...")
-
- settings.validate(drawing)
-
- global activObjectLayer, activObjectName
- activObjectLayer, activObjectName = None, None
-
- if M_OBJ: car_init()
-
- drawEntities(drawing.entities, settings)
-
- #print 'deb:drawEntities after: oblist:', oblist #-----------------------
- if M_OBJ: car_end()
- if oblist: # and settings.var['g_scale'] != 1:
- globalScale(oblist, settings.var['g_scale'])
-
- # Set visibility for all layers on all View3d
- #Window.ViewLayers([i+1 for i in range(18)]) # for 2.45
- SCENE.setLayers([i+1 for i in range(18)])
- SCENE.update(1)
- SCENE.objects.selected = [i[0] for i in oblist] #select only the imported objects
- #SCENE.objects.selected = SCENE.objects #select all objects in current scene
- Blender.Redraw()
-
- time_text = sys.time() - time2
- Window.WaitCursor(False)
- if settings.var['paper_space_on']: space = 'from paper space'
- else: space = 'from model space'
- ob_len = len(oblist)
- message = ' %s objects imported %s in %.4f sec. -----DONE-----' % (ob_len, space, time_text)
- settings.progress(1.0/settings.obj_number, 'DXF import done!')
- print message
- #settings.write(message)
- if UI_MODE: Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % time_text)
-
- #finally:
- # restore state even if things didn't work
- #print 'deb:drawEntities finally!' #-----------------------
- Window.WaitCursor(False)
- if editmode: Window.EditMode(1) # and put things back how we fond them
-
-
-
-def getOCS(az): #-----------------------------------------------------------------
- """An implimentation of the Arbitrary Axis Algorithm.
- """
- #decide if we need to transform our coords
- #if az[0] == 0 and az[1] == 0:
- if abs(az[0]) < 0.00001 and abs(az[1]) < 0.00001:
- if az[2] > 0.0:
- return False
- elif az[2] < 0.0:
- ax = Mathutils.Vector(-1.0, 0, 0)
- ay = Mathutils.Vector(0, 1.0, 0)
- az = Mathutils.Vector(0, 0, -1.0)
- return ax, ay, az
-
- az = Mathutils.Vector(az)
-
- cap = 0.015625 # square polar cap value (1/64.0)
- if abs(az.x) < cap and abs(az.y) < cap:
- ax = M_CrossVecs(WORLDY,az)
- else:
- ax = M_CrossVecs(WORLDZ,az)
- ax = ax.normalize()
- ay = M_CrossVecs(az, ax)
- ay = ay.normalize()
- return ax, ay, az
-
-
-
-def transform(normal, rotation, obj): #--------------------------------------------
- """Use the calculated ocs to determine the objects location/orientation in space.
-
- Quote from dxf docs:
- The elevation value stored with an entity and output in DXF files is a sum
- of the Z-coordinate difference between the UCS XY plane and the OCS XY
- plane, and the elevation value that the user specified at the time the entity
- was drawn.
- """
- ma = Mathutils.Matrix([1,0,0],[0,1,0],[0,0,1])
- o = Mathutils.Vector(obj.loc)
- ocs = getOCS(normal)
- if ocs:
- ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2])
- o = ma.invert() * o
- ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2])
-
- if rotation != 0:
- g = radians(-rotation)
- rmat = Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
- ma = rmat * ma
-
- obj.setMatrix(ma)
- obj.loc = o
- #print 'deb:new obj.matrix:\n', obj.getMatrix() #--------------------
-
-
-
-def rotXY_Vec(rotation, vec): #----------------------------------------------------
- """Rotate vector vec in XY-plane. vec must be in radians
- """
- if rotation != 0:
- o = Mathutils.Vector(vec)
- g = radians(-rotation)
- vec = o * Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
- return vec
-
-
-
-def getLayersmap(dxflayers): #------------------------------------------------------
- """Build two dictionaries: 1.layername:layer object, and 2.layername:layername_short
- gets set of layers from TABLES SECTION LAYERS
- """
- layersmap = {}
- layernamesmap = {}
- for item in dxflayers.data:
- if type(item) != list and item.type == 'layer':
- layersmap[item.name] = item
- layername_short = item.name[:MAX_NAMELENGTH-1]
- i = 0 #sufix for layernames cause Blender-objectnames-limits
- while layername_short in layernamesmap.keys():
- i += 1
- suffix = str(i) #--todo--set zero-leading number format
- layername_short = layername_short[:-2] + suffix
- layernamesmap[item.name] = layername_short
-
- #print 'deb:getLayersmap layersmap:\n', layersmap #------------
- #print 'deb:getLayersmap layernamesmap:\n', layernamesmap #------------
- return layersmap, layernamesmap
-
-
-
-def getBlocksmap(drawing, layersmap, layFrozen_on=False): #--------------------------------------------------------
- """Build a dictionary of blockname:block_data pairs
- """
- usedblocks = {}
- for item in drawing.blocks.data:
- #print 'deb:getBlocksmap item=%s\n i.entities=%s\n i.data=%s' %(item,item.entities,item.entities.data)
- if type(item) != list and item.type == 'block':
- childList = []
- used = False
- for item2 in item.entities.data:
- if type(item2) != list and item2.type == 'insert':
- #print 'deb:getBlocksmap dir(item2)=', dir(item2) #----------
- item2str = [item2.name, item2.layer]
- childList.append(item2str)
- try: usedblocks[item.name] = [used, childList]
- except KeyError: print 'Cannot find "%s" Block!' %(item.name)
- #print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
- #print 'deb:getBlocksmap: layersmap=' , layersmap #-------------
-
- for item in drawing.entities.data:
- if type(item) != list and item.type == 'insert':
- if not layersmap or (not layersmap[item.layer].frozen or layFrozen_on): #if insert_layer is not frozen
- try: usedblocks[item.name][0] = True
- except KeyError: print 'Cannot find "%s" Block!' %(item.name)
-
- key_list = usedblocks.keys()
- key_list.reverse()
- for key in key_list:
- if usedblocks[key][0]: #if parent used, then set used also all child blocks
- for child in usedblocks[key][1]:
- if not layersmap or (layersmap and not layersmap[child[1]].frozen): #if insert_layer is not frozen
- try: usedblocks[child[0]][0] = True # marked as used BLOCK
- except KeyError: print 'Cannot find "%s" Block!' %(child[0])
-
- usedblocks = [i for i in usedblocks.keys() if usedblocks[i][0]]
- #print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
- obj_number = 0
- blocksmap = {}
- for item in drawing.blocks.data:
- if type(item) != list and item.type == 'block' and item.name in usedblocks:
- #if item.name.startswith('*X'): #--todo--
- obj_number += len(item.entities.data)
- try: blocksmap[item.name] = item
- except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
-
-
- #print 'deb:getBlocksmap: blocksmap:\n', blocksmap #------------
- return blocksmap, obj_number
-
-
-def getBlocknamesmap(blocksmap): #--------------------------------------------------------
- """Build a dictionary of blockname:blockname_short pairs
- """
- #print 'deb:getBlocknamesmap blocksmap:\n', blocksmap #------------
- blocknamesmap = {}
- for n in blocksmap.keys():
- blockname_short = n[:MAX_NAMELENGTH-1]
- i = 0 #sufix for blockname cause Blender-objectnamelength-limit
- while blockname_short in blocknamesmap.keys():
- i += 1
- suffix = str(i)
- blockname_short = blockname_short[:-2] + suffix
- blocknamesmap[n] = blockname_short
- #print 'deb:getBlocknamesmap blocknamesmap:\n', blocknamesmap #------------
- return blocknamesmap
-
-
-def drawEntities(entities, settings, block_def=None): #----------------------------------------
- """Draw every kind of thing in the entity list.
-
- If provided 'block_def': the entities are to be added to the Blender 'group'.
- """
- for _type in type_map.keys():
- #print 'deb:drawEntities_type:', _type #------------------
- # for each known type get a list of that type and call the associated draw function
- entities_type = entities.get_type(_type)
- if entities_type: drawer(_type, entities_type, settings, block_def)
-
-
-def drawer(_type, entities, settings, block_def): #------------------------------------------
- """Call with a list of entities and a settings object to generate Blender geometry.
-
- If 'block_def': the entities are to be added to the Blender 'group'.
- """
- global layersmap, layersmapshort
- #print 'deb:drawer _type, entities:\n ', _type, entities #-----------------------
-
- if entities:
- # Break out early if settings says we aren't drawing the current dxf-type
- global cur_COUNTER #counter for progress_bar
- group = None
- #print 'deb:drawer.check:_type: ', _type #--------------------
- if _type == '3dface':_type = 'face' # hack, while python_variable_name can not beginn with a nummber
- if not settings.drawTypes[_type] or _type == 'block_record':
- message = 'Skipping dxf\'%ss\' entities' %_type
- settings.write(message, True)
- cur_COUNTER += len(entities)
- settings.progress(cur_COUNTER, message)
- return
- #print 'deb:drawer.todo:_type:', _type #-----------------------
- #print 'deb:drawer entities:\n ', entities #-----------------------
-
- len_temp = len(entities)
- # filtering only model-space enitities (no paper-space enitities)
- if settings.var['paper_space_on']:
- entities = [entity for entity in entities if entity.space != 0]
- else:
- entities = [entity for entity in entities if entity.space == 0]
-
- # filtering only objects with color from acceptedColorsList
- if settings.var['colorFilter_on']:
- entities = [entity for entity in entities if entity.color in settings.acceptedColors]
-
- # filtering only objects on layers from acceptedLayersList
- if settings.var['layerFilter_on']:
- #entities = [entity for entity in entities if entity.layer[0] in ['M','3','0'] and not entity.layer.endswith('H')]
- entities = [entity for entity in entities if entity.layer in settings.acceptedLayers]
-
- # patch for incomplete layer table in HL2-DXF-files
- if layersmap:
- for entity in entities:
- oblayer = entity.layer
- if oblayer not in layersmap.keys():
- layer_obj = Layer(None, name=oblayer)
- layersmap[oblayer] = layer_obj
- layername_short = oblayer[:MAX_NAMELENGTH-1]
- i = 0 #sufix for layernames cause Blender-objectnames-limits
- while layername_short in layernamesmap.keys():
- i += 1
- suffix = str(i) #--todo--set zero-leading number format
- layername_short = layername_short[:-2] + suffix
- layernamesmap[oblayer] = layername_short
-
- # filtering only objects on not-frozen layers
- if layersmap and not settings.var['layFrozen_on']:
- entities = [entity for entity in entities if not layersmap[entity.layer].frozen]
-
- global activObjectLayer, activObjectName
- activObjectLayer = ''
- activObjectName = ''
-
- message = "Drawing dxf \'%ss\'..." %_type
- cur_COUNTER += len_temp - len(entities)
- settings.write(message, False)
- settings.progress(cur_COUNTER, message)
- if len(entities) > 0.1 / settings.obj_number:
- show_progress = int(0.03 / settings.obj_number)
- else: show_progress = 0
- cur_temp = 0
-
- #print 'deb:drawer cur_COUNTER: ', cur_COUNTER #-----------------------
-
- for entity in entities: #----loop-------------------------------------
- settings.write('\b.', False)
- cur_COUNTER += 1
- if show_progress:
- cur_temp += 1
- if cur_temp == show_progress:
- settings.progress(cur_COUNTER, message)
- cur_temp = 0
- #print 'deb:drawer show_progress=',show_progress #----------------
-
- # get the layer group (just to make things a little cleaner)
- if settings.var['group_bylayer_on'] and not block_def:
- group = getGroup('l:%s' % layernamesmap[entity.layer])
-
- if _type == 'insert': #---- INSERT and MINSERT=array --------------------
- if not settings.var['block_nn']: #----turn off support for noname BLOCKs
- prefix = entity.name[:2]
- if prefix in ('*X', '*U', '*D'):
- #print 'deb:drawer entity.name:', entity.name #------------
- continue
- if settings.var['blockFilter_on'] and not settings.accepted_block(entity.name):
- continue
-
- #print 'deb:insert entity.loc:', entity.loc #----------------
- insertFlag = True
- columns = entity.columns[0]
- coldist = entity.columns[1]
- rows = entity.rows[0]
- rowdist = entity.rows[1]
- deltaloc = [0,0,0]
- #print 'deb:insert columns, rows:', columns, rows #-----------
- for col in xrange(columns):
- deltaloc[0] = col * coldist
- for row in xrange(rows):
- deltaloc[1] = row * rowdist
- #print 'deb:insert col=%s, row=%s,deltaloc=%s' %(col, row, deltaloc) #------
- ob = entity.draw(settings, deltaloc) #-----draw BLOCK----------
- if block_def:
- blockFlag = True
- bl_loc = block_def[1]
- ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
- else: blockFlag = False
- setObjectProperties(ob, group, entity, settings, block_def)
- if ob:
- if settings.var['optimization'] <= settings.MIN:
- #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
- if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale'])
- settings.redraw()
- else: oblist.append((ob, insertFlag, blockFlag))
-
- else: #---draw entities except BLOCKs/INSERTs---------------------
- insertFlag = False
- alt_obname = activObjectName
- ob = entity.draw(settings)
- if ob:
- if M_OBJ and ob.type=='Mesh': #'Curve', 'Text'
- if block_def:
- blockFlag = True
- bl_loc = block_def[1]
- ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
- car_nr()
-
- elif ob.name != alt_obname:
- if block_def:
- blockFlag = True
- bl_loc = block_def[1]
- ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
- else: blockFlag = False
- setObjectProperties(ob, group, entity, settings, block_def)
- if settings.var['optimization'] <= settings.MIN:
- #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
- if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale'])
- settings.redraw()
- else: oblist.append((ob, insertFlag, blockFlag))
-
- #print 'deb:Finished drawing:', entities[0].type #------------------------
- message = "\nDrawing dxf\'%ss\' done!" % _type
- settings.write(message, True)
-
-
-
-def globalScale(oblist, SCALE): #---------------------------------------------------------
- """Global_scale for list of all imported objects.
-
- oblist is a list of pairs (ob, insertFlag), where insertFlag=True/False
- """
- #print 'deb:globalScale.oblist: ---------%\n', oblist #---------------------
- for l in oblist:
- ob, insertFlag, blockFlag = l[0], l[1], l[2]
- globalScaleOne(ob, insertFlag, blockFlag, SCALE)
-
-
-def globalScaleOne(ob, insertFlag, blockFlag, SCALE): #---------------------------------------------------------
- """Global_scale imported object.
- """
- #print 'deb:globalScaleOne ob: ', ob #---------------------
- if settings.var['g_origin_on'] and not blockFlag:
- ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
-
- SCALE_MAT= Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1])
- if insertFlag: # by BLOCKs/INSERTs only insert-point coords must be scaled------------
- ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT
- else: # entire scaling for all other imported objects ------------
- if ob.type == 'Mesh':
- me = ob.getData(name_only=False, mesh=True)
- #me = Mesh.Get(ob.name)
- # set centers of all objects in (0,0,0)
- #me.transform(ob.matrixWorld*SCALE_MAT)
- #ob.loc = Mathutils.Vector([0,0,0])
- # preseve centers of all objects
- me.transform(SCALE_MAT)
- ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT
- else: #--todo-- also for curves: neutral scale factor after import
- ob.setMatrix(ob.matrixWorld*SCALE_MAT)
-
-
-def setObjectProperties(ob, group, entity, settings, block_def): #-----------------------
- """Link object to scene.
- """
-
- if not ob: #remi--todo-----------------------
- message = "\nObject \'%s\' not found!" %entity
- settings.write(message)
- return
-
- if group:
- setGroup(group, ob) # if object belongs to group
-
- if block_def: # if object belongs to BLOCK_def - Move it to layer nr19
- setGroup(block_def[0], ob)
- #print 'deb:setObjectProperties \'%s\' set to block_def_group!' %ob.name #---------
- ob.layers = [19]
- else:
- #ob.layers = [i+1 for i in xrange(20)] #remi--todo------------
- ob.layers = [settings.var['target_layer']]
-
- # Set material for any objects except empties
- if ob.type != 'Empty' and settings.var['material_on']:
- setMaterial_from(entity, ob, settings, block_def)
-
- # Set the visibility
- #if settings.layer_isOff(entity.layer):
- if layersmap and layersmap[entity.layer].color < 0: # color is negative if layer is off
- #ob.layers = [20] #remi--todo-------------
- ob.restrictDisplay = True
- ob.restrictRender = True
-
- #print 'deb:\n---------linking Object %s!' %ob.name #----------
-
-
-
-def getGroup(name): #-----------------------------------------------------------------
- """Returns a Blender group-object.
- """
- try:
- group = Group.Get(name)
- except: # What is the exception?
- group = Group.New(name)
- return group
-
-
-def setGroup(group, ob): #------------------------------------------------------------
- """Assigns object to Blender group.
- """
- try:
- group.objects.link(ob)
- except:
- group.objects.append(ob) #remi?---------------
-
-
-
-def setMaterial_from(entity, ob, settings, block_def): #------------------------------------------------
- """ Set Blender-material for the object controled by item.
-
- Set Blender-material for the object
- - controlled by settings.var['material_from']
- """
- if settings.var['material_from'] == 1: # 1= material from color
- if entity.color_index == BYLAYER or entity.color_index == 256:
- mat = settings.colMaterials(entity.layer)
- elif entity.color_index == BYBLOCK or entity.color_index == 0:
- #--todo-- looking for block.color_index
- #mat = settings.colMaterials(block.color_index)
- #if block_def: mat = settings.colMaterials(block_def[2])
- mat = settings.colMaterials(3)
- else:
- mat = settings.colMaterials(entity.color_index)
-
- elif settings.var['material_from'] == 2: # 2= material from layer_name
- mat = settings.layMaterials(layername=entity.layer)
-
- elif settings.var['material_from'] == 3: # 3= material from layer+color
- mat = settings.layMaterials(layername=entity.layer, color=entity.color_index)
-
-# elif settings.var['material_from'] == 4: # 4= material from block_name
-
-# elif settings.var['material_from'] == 5: # 5= material from XDATA
-
-# elif settings.var['material_from'] == 6: # 6= material from INI-file
-
- else: # set neutral material
- try:
- mat = Material.Get('dxf-neutral')
- except:
- mat = Material.New('dxf-neutral')
- mat.setRGBCol(color_map[3])
- try:mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc1-bug
- except:
- mat.mode |= Material.Modes.SHADELESS #
- mat.mode |= Material.Modes.WIRE
- try:
- #print 'deb:material mat:', mat #-----------
- ob.setMaterials([mat]) #assigns Blender-material to object
- except ValueError:
- settings.write("material error - \'%s\'!" %mat)
- ob.colbits = 0x01 # Set OB materials.
-
-
-
-def calcBulge(p1, p2, arc_res, triples=False): #-------------------------------------------------
- """given startpoint, endpoint and bulge of arc, returns points/segments of its representation.
-
- Needs to take into account bulge sign.
- negative = clockwise
- positive = counter-clockwise
-
- to find center given two points, and arc angle
- calculate radius
- Cord = sqrt(start^2 + end^2)
- S = (bulge*Cord)/2
- radius = ((Cord/2)^2+S^2)/2*S
- angle of arc = 4*atan( bulge )
- angle from p1 to center is (180-angle)/2
- get vector pointing from p1 to p2 (p2 - p1)
- normalize it and multiply by radius
- rotate around p1 by angle to center, point to center.
- start angle = angle between (center - p1) and worldX
- end angle = angle between (center - p2) and worldX
-
- calculate the center, radius, start angle, and end angle
- returns points/segments of its mesh representation
- incl.startpoint, without endpoint
- """
-
- bulge = p1.bulge
- p1 = Mathutils.Vector(p1.loc)
- p2 = Mathutils.Vector(p2.loc)
- cord = p2 - p1 # vector from p1 to p2
- clength = cord.length
- s = (bulge * clength)/2.0 # sagitta (height)
- radius = abs(((clength/2.0)**2.0 + s**2.0)/(2.0*s)) # magic formula
- angle = (degrees(4.0*atan(bulge))) # theta (included angle)
- radial = cord.normalize() * radius # a radius length vector aligned with cord
- delta = (180.0 - abs(angle))/2.0 # the angle from cord to center
- if bulge < 0: delta = -delta
- rmat = Mathutils.RotationMatrix(-delta, 3, 'Z')
- center = p1 + (rmat * radial) # rotate radial by delta degrees, then add to p1 to find center
- #length = radians(abs(angle)) * radius
- #print 'deb:calcBulge:\n angle, delta: ', angle, delta #----------------
- #print 'deb:center, radius: ', center, radius #----------------------
- startpoint = p1 - center
- endpoint = p2 - center
- #print 'deb:calcBulg: startpoint:', startpoint #---------
- #print 'deb:calcBulg: endpoint:', endpoint #---------
-
- if not triples: #IF mesh-representation -----------
- if arc_res > 1024: arc_res = 1024
- elif arc_res < 4: arc_res = 4
- pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
- if pieces < 3: pieces = 3
- else: #IF curve-representation -------------------------------
- if arc_res > 32: arc_res = 32
- elif arc_res < 3: arc_res = 3
- pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
- if pieces < 2: pieces = 2
-
- step = angle/pieces # set step so pieces * step = degrees in arc
- stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
-
- if not triples: #IF mesh-representation -----------
- points = [startpoint]
- point = startpoint
- for i in xrange(int(pieces)-1): #fast (but not so acurate as: vector * RotMatrix(-step*i,3,"Z")
- point = stepmatrix * point
- points.append(point)
- points = [ point+center for point in points]
- # vector to point convertion:
- points = [list(point) for point in points]
- return points, list(center)
-
- else: #IF curve-representation -------------------------------
- # correct Bezier curves representation for free segmented circles/arcs
- step2 = radians(step * 0.5)
- bulg = radius * (1 - cos(step2))
- deltaY = 4.0 * bulg / (3.0 * sin(step2) )
- #print 'deb:calcArcCurve: bulg, deltaY:\n', bulg, deltaY #---------
- #print 'deb:calcArcCurve: step:\n', step #---------
-
- #org handler0 = Mathutils.Vector(0.0, -deltaY, 0.0)
- #handler = startmatrix * handler0
- #endhandler = endmatrix * handler0
- rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
- handler = rotMatr90 * startpoint
- handler = - deltaY * handler.normalize()
- endhandler = rotMatr90 * endpoint
- endhandler = - deltaY * endhandler.normalize()
-
- points = [startpoint]
- handlers1 = [startpoint + handler]
- handlers2 = [startpoint - handler]
- point = Mathutils.Vector(startpoint)
- for i in xrange(int(pieces)-1):
- point = stepmatrix * point
- handler = stepmatrix * handler
- handler1 = point + handler
- handler2 = point - handler
- points.append(point)
- handlers1.append(handler1)
- handlers2.append(handler2)
- points.append(endpoint)
- handlers1.append(endpoint + endhandler)
- handlers2.append(endpoint - endhandler)
-
- points = [point + center for point in points]
- handlers1 = [point + center for point in handlers1]
- handlers2 = [point + center for point in handlers2]
-
- VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)]
- #print 'deb:calcBulgCurve: handlers1:\n', handlers1 #---------
- #print 'deb:calcBulgCurve: points:\n', points #---------
- #print 'deb:calcBulgCurve: handlers2:\n', handlers2 #---------
- #print 'deb:calcBulgCurve: VectorTriples:\n', VectorTriples #---------
- return VectorTriples
-
-
-
-
-def calcArc(center, radius, start, end, arc_res, triples): #-----------------------------------------
- """calculate Points (or BezierTriples) for ARC/CIRCLEs representation.
-
- Given parameters of the ARC/CIRCLE,
- returns points/segments (or BezierTriples) and centerPoint
- """
- # center is currently set by object
- # if start > end: start = start - 360
- if end > 360: end = end % 360.0
-
- startmatrix = Mathutils.RotationMatrix(-start, 3, "Z")
- startpoint = startmatrix * Mathutils.Vector(radius, 0, 0)
- endmatrix = Mathutils.RotationMatrix(-end, 3, "Z")
- endpoint = endmatrix * Mathutils.Vector(radius, 0, 0)
-
- if end < start: end +=360.0
- angle = end - start
- #length = radians(angle) * radius
-
- if not triples: #IF mesh-representation -----------
- if arc_res > 1024: arc_res = 1024
- elif arc_res < 4: arc_res = 4
- pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
- if pieces < 3: pieces = 3
- step = angle/pieces # set step so pieces * step = degrees in arc
- stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
-
- points = [startpoint]
- point = startpoint
- for i in xrange(int(pieces)-1):
- point = stepmatrix * point
- points.append(point)
- points.append(endpoint)
-
- if center:
- centerVec = Mathutils.Vector(center)
- #points = [point + centerVec for point in points()]
- points = [point + centerVec for point in points]
- # vector to point convertion:
- points = [list(point) for point in points]
- return points
-
- else: #IF curve-representation ---------------
- if arc_res > 32: arc_res = 32
- elif arc_res < 3: arc_res = 3
- pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
- if pieces < 2: pieces = 2
- step = angle/pieces # set step so pieces * step = degrees in arc
- stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
-
- # correct Bezier curves representation for free segmented circles/arcs
- step2 = radians(step * 0.5)
- bulg = radius * (1 - cos(step2))
- deltaY = 4.0 * bulg / (3.0 * sin(step2) )
- #print 'deb:calcArcCurve: bulg, deltaY:\n', bulg, deltaY #---------
- #print 'deb:calcArcCurve: step:\n', step #---------
- handler0 = Mathutils.Vector(0.0, -deltaY, 0.0)
-
- points = [startpoint]
- handler = startmatrix * handler0
- endhandler = endmatrix * handler0
- handlers1 = [startpoint + handler]
- handlers2 = [startpoint - handler]
- point = Mathutils.Vector(startpoint)
- for i in xrange(int(pieces)-1):
- point = stepmatrix * point
- handler = stepmatrix * handler
- handler1 = point + handler
- handler2 = point - handler
- points.append(point)
- handlers1.append(handler1)
- handlers2.append(handler2)
- points.append(endpoint)
- handlers1.append(endpoint + endhandler)
- handlers2.append(endpoint - endhandler)
- VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)]
- #print 'deb:calcArcCurve: handlers1:\n', handlers1 #---------
- #print 'deb:calcArcCurve: points:\n', points #---------
- #print 'deb:calcArcCurve: handlers2:\n', handlers2 #---------
- #print 'deb:calcArcCurve: VectorTriples:\n', VectorTriples #---------
- return VectorTriples
-
-
-def drawCurveCircle(circle): #--- no more used --------------------------------------------
- """Given a dxf circle object return a blender circle object using curves.
- """
- c = Curve.New('circle') # create new curve data
- center = circle.loc
- radius = circle.radius
-
- p1 = (0, -radius, 0)
- p2 = (radius, 0, 0)
- p3 = (0, radius, 0)
- p4 = (-radius, 0, 0)
-
- p1 = BezTriple.New(p1)
- p2 = BezTriple.New(p2)
- p3 = BezTriple.New(p3)
- p4 = BezTriple.New(p4)
-
- curve = c.appendNurb(p1)
- curve.append(p2)
- curve.append(p3)
- curve.append(p4)
- for point in curve:
- point.handleTypes = [AUTO, AUTO]
- point.radius = 1.0
- curve.flagU = 1 # Set curve cyclic
- c.update()
-
- ob = Object.New('Curve', 'circle') # make curve object
- return ob
-
-
-def drawCurveArc(self): #---- only for ELLIPSE -------------------------------------------------------------
- """Given a dxf ELLIPSE object return a blender_curve.
- """
- center = self.loc
- radius = self.radius
- start = self.start_angle
- end = self.end_angle
-
- if start > end:
- start = start - 360.0
- startmatrix = Mathutils.RotationMatrix(start, 3, "Z")
- startpoint = startmatrix * Mathutils.Vector((radius, 0, 0))
- endmatrix = Mathutils.RotationMatrix(end, 3, "Z")
- endpoint = endmatrix * Mathutils.Vector((radius, 0, 0))
- # Note: handles must be tangent to arc and of correct length...
-
- a = Curve.New('arc') # create new curve data
-
- p1 = (0, -radius, 0)
- p2 = (radius, 0, 0)
- p3 = (0, radius, 0)
- p4 = (-radius, 0, 0)
-
- p1 = BezTriple.New(p1)
- p2 = BezTriple.New(p2)
- p3 = BezTriple.New(p3)
- p4 = BezTriple.New(p4)
-
- curve = a.appendNurb(p1)
- curve.append(p2)
- curve.append(p3)
- curve.append(p4)
- for point in curve:
- point.handleTypes = [AUTO, AUTO]
- point.radius = 1.0
- curve.flagU = 1 # Set curve cyclic
- a.update()
-
- ob = Object.New('Curve', 'arc') # make curve object
- return ob
-
-
-
-
-# GUI STUFF -----#################################################-----------------
-from Blender.BGL import glColor3f, glRecti, glClear, glRasterPos2d
-
-EVENT_NONE = 1
-EVENT_START = 2
-EVENT_REDRAW = 3
-EVENT_LOAD_INI = 4
-EVENT_SAVE_INI = 5
-EVENT_RESET = 6
-EVENT_CHOOSE_INI = 7
-EVENT_CHOOSE_DXF = 8
-EVENT_HELP = 9
-EVENT_PRESETCURV = 10
-EVENT_PRESETS = 11
-EVENT_DXF_DIR = 12
-# = 13
-EVENT_LIST = 14
-EVENT_ORIGIN = 15
-EVENT_SCALE = 16
-EVENT_PRESET2D = 20
-EVENT_PRESET3D = 21
-EVENT_EXIT = 100
-GUI_EVENT = EVENT_NONE
-
-GUI_A = {} # GUI-buttons dictionary for parameter
-GUI_B = {} # GUI-buttons dictionary for drawingTypes
-
-# settings default, initialize ------------------------
-
-points_as_menu = "convert to: %t|empty %x1|mesh.vertex %x2|thin sphere %x3|thin box %x4|..curve.vertex %x5"
-lines_as_menu = "convert to: %t|..edge %x1|mesh %x2|..thin cylinder %x3|thin box %x4|Bezier-curve %x5|..NURBS-curve %x6"
-mlines_as_menu = "convert to: %t|..edge %x1|..mesh %x2|..thin cylinder %x3|..thin box %x|..curve %x5"
-plines_as_menu = "convert to: %t|..edge %x1|mesh %x2|..thin cylinder %x3|..thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
-splines_as_menu = "convert to: %t|mesh %x2|..thin cylinder %x3|..thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
-plines3_as_menu = "convert to: %t|..edge %x1|mesh %x2|..thin cylinder %x3|..thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
-plmesh_as_menu = "convert to: %t|..edge %x1|mesh %x2|..NURBS-surface %x6"
-solids_as_menu = "convert to: %t|..edge %x1|mesh %x2"
-blocks_as_menu = "convert to: %t|dupliGroup %x1|..real.Group %x2|..exploded %x3"
-texts_as_menu = "convert to: %t|text %x1|..mesh %x2|..curve %x5"
-material_from_menu= "material from: %t|..LINESTYLE %x7|COLOR %x1|LAYER %x2|..LAYER+COLOR %x3|..BLOCK %x4|..XDATA %x5|..INI-File %x6"
-g_scale_list = ''.join((
- 'scale factor: %t',
- '|user def. %x12',
- '|yard to m %x8',
- '|feet to m %x7',
- '|inch to m %x6',
- '| x 1000 %x3',
- '| x 100 %x2',
- '| x 10 %x1',
- '| x 1 %x0',
- '| x 0.1 %x-1',
- '| x 0.01 %x-2',
- '| x 0.001 %x-3',
- '| x 0.0001 %x-4',
- '| x 0.00001 %x-5'))
-
-#print 'deb: g_scale_list', g_scale_list #-----------
-
-dxfFileName = Draw.Create("")
-iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
-user_preset = 0
-config_UI = Draw.Create(0) #switch_on/off extended config_UI
-g_scale_as = Draw.Create(int(log10(G_SCALE)))
-
-
-keywords_org = {
- 'curves_on' : 0,
- 'optimization': 2,
- 'one_mesh_on': 1,
- 'vGroup_on' : 1,
- 'dummy_on' : 0,
- 'views_on' : 0,
- 'cams_on' : 0,
- 'lights_on' : 0,
- 'xref_on' : 1,
- 'block_nn': 0,
- 'blockFilter_on': 0,
- 'layerFilter_on': 0,
- 'colorFilter_on': 0,
- 'groupFilter_on': 0,
- 'newScene_on' : 1,
- 'target_layer' : TARGET_LAYER,
- 'group_bylayer_on' : GROUP_BYLAYER,
- 'g_originX' : G_ORIGIN_X,
- 'g_originY' : G_ORIGIN_Y,
- 'g_originZ' : G_ORIGIN_Z,
- 'g_origin_on': 0,
- 'g_scale' : float(G_SCALE),
-# 'g_scale_as': int(log10(G_SCALE)), # 0,
- 'g_scale_on': 0,
- 'thick_on' : 1,
- 'thick_min' : float(MIN_THICK),
- 'thick_force': 0,
- 'width_on' : 1,
- 'width_min' : float(MIN_WIDTH),
- 'width_force': 0,
- 'dist_on' : 1,
- 'dist_min' : float(MIN_DIST),
- 'dist_force': 0,
- 'material_on': 1,
- 'material_from': 2,
- 'fill_on' : 1,
- 'meshSmooth_on': 1,
- 'curve_res' : CURV_RESOLUTION,
- 'curve_arc' : CURVARC_RESOLUTION,
- 'arc_res' : ARC_RESOLUTION,
- 'arc_rad' : ARC_RADIUS,
- 'thin_res' : THIN_RESOLUTION,
- 'pl_trim_max' : TRIM_LIMIT,
- 'pl_trim_on': 1,
- 'plmesh_flip': 0,
- 'normals_out': 0,
- 'paper_space_on': 0,
- 'layFrozen_on': 0,
- 'Z_force_on': 0,
- 'Z_elev': float(ELEVATION),
- 'points_as' : 2,
- 'lines_as' : 2,
- 'mlines_as' : 2,
- 'plines_as' : 2,
- 'splines_as' : 5,
- 'plines3_as': 2,
- 'plmesh_as' : 2,
- 'solids_as' : 2,
- 'blocks_as' : 1,
- 'texts_as' : 1
- }
-
-drawTypes_org = {
- 'point' : 1,
- 'line' : 1,
- 'arc' : 1,
- 'circle': 1,
- 'ellipse': 1,
- 'mline' : 0,
- 'polyline': 1,
- 'spline': 1,
- 'plmesh': 1,
- 'pline3': 1,
- 'lwpolyline': 1,
- 'text' : 1,
- 'mtext' : 0,
- 'block' : 1,
- 'insert': 1,
- 'solid' : 1,
- 'trace' : 1,
- 'face' : 1,
-# 'view' : 0,
- }
-
-# creating of GUI-buttons
-# GUI_A - GUI-buttons dictionary for parameter
-# GUI_B - GUI-buttons dictionary for drawingTypes
-for k, v in keywords_org.iteritems():
- GUI_A[k] = Draw.Create(v)
-for k, v in drawTypes_org.iteritems():
- GUI_B[k] = Draw.Create(v)
-#print 'deb:init GUI_A: ', GUI_A #---------------
-#print 'deb:init GUI_B: ', GUI_B #---------------
-
-model_space_on = Draw.Create(1)
-
-# initialize settings-object controls how dxf entities are drawn
-settings = Settings(keywords_org, drawTypes_org)
-
-
-def update_RegistryKey(key, item): #
- """updates key in Blender.Registry
- """
- cache = True # data is also saved to a file
- rdict = Registry.GetKey('DXF_Importer', cache)
- if not rdict: rdict = {}
- if item:
- rdict[key] = item
- Registry.SetKey('DXF_Importer', rdict, cache)
- #print 'deb:update_RegistryKey rdict', rdict #---------------
-
-
-def check_RegistryKey(key):
- """ check if the key is already there (saved on a previous execution of this script)
- """
- cache = True # data is also saved to a file
- rdict = Registry.GetKey('DXF_Importer', cache)
- #print 'deb:check_RegistryKey rdict:', rdict #----------------
- if rdict: # if found, get the values saved there
- try:
- item = rdict[key]
- return item
- except:
- #update_RegistryKey() # if data isn't valid rewrite it
- pass
-
-def saveConfig(): #--todo-----------------------------------------------
- """Save settings/config/materials from GUI to INI-file.
-
- Write all config data to INI-file.
- """
- global iniFileName
-
- iniFile = iniFileName.val
- #print 'deb:saveConfig inifFile: ', inifFile #----------------------
- if iniFile.lower().endswith(INIFILE_EXTENSION):
-
- #--todo-- sort key.list for output
- #key_list = GUI_A.keys().val
- #key_list.sort()
- #for key in key_list:
- # l_name, l_data = key, GUI_A[key].val
- # list_A
-
- output_str = '[%s,%s]' %(GUI_A, GUI_B)
- if output_str =='None':
- Draw.PupMenu('DXF importer: INI-file: Alert!%t|no config-data present to save!')
- else:
- #if BPyMessages.Warning_SaveOver(iniFile): #<- remi find it too abstarct
- if sys.exists(iniFile):
- f = file(iniFile, 'r')
- header_str = f.readline()
- f.close()
- if header_str.startswith(INIFILE_HEADER[0:13]):
- if Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
- save_ok = True
- else: save_ok = False
- elif Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile +
- '|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1:
- save_ok = True
- else: save_ok = False
- else: save_ok = True
-
- if save_ok:
- # replace: ',' -> ',\n'
- # replace: '{' -> '\n{\n'
- # replace: '}' -> '\n}\n'
- output_str = ',\n'.join(output_str.split(','))
- output_str = '\n}'.join(output_str.split('}'))
- output_str = '{\n'.join(output_str.split('{'))
- try:
- f = file(iniFile, 'w')
- f.write(INIFILE_HEADER + '\n# this is a comment line\n')
- f.write(output_str)
- f.close()
- #Draw.PupMenu('DXF importer: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
- except:
- Draw.PupMenu('DXF importer: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
-
- else:
- Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid name/extension for INI-file selected!')
- print "DXF importer: Alert!: no valid INI-file selected."
- if not iniFile:
- if dxfFileName.val.lower().endswith('.dxf'):
- iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
-
-
-def loadConfig(): #remi--todo-----------------------------------------------
- """Load settings/config/materials from INI-file.
-
- Read material-assignements from config-file.
- """
- #070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
- global iniFileName, GUI_A, GUI_B
-
- iniFile = iniFileName.val
- update_RegistryKey('iniFileName', iniFile)
- #print 'deb:loadConfig iniFile: ', iniFile #----------------------
- if iniFile.lower().endswith(INIFILE_EXTENSION) and sys.exists(iniFile):
- f = file(iniFile, 'r')
- header_str = f.readline()
- if header_str.startswith(INIFILE_HEADER):
- data_str = f.read()
- f.close()
- #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #-----------------
- data = eval(data_str)
- for k, v in data[0].iteritems():
- try: GUI_A[k].val = v
- except: GUI_A[k] = Draw.Create(v)
- for k, v in data[1].iteritems():
- try: GUI_B[k].val = v
- except: GUI_B[k] = Draw.Create(v)
- else:
- f.close()
- Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
- else:
- Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid INI-file selected!')
- print "DXF importer: Alert!: no valid INI-file selected."
- if not iniFileName:
- if dxfFileName.val.lower().endswith('.dxf'):
- iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
-
-
-
-def updateConfig(keywords, drawTypes): #-----------------------------------------------
- """updates GUI_settings with given dictionaries
-
- """
- global GUI_A, GUI_B
- #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
- for k, v in keywords.iteritems():
- GUI_A[k].val = v
- for k, v in drawTypes.iteritems():
- GUI_B[k].val = v
-
-def resetDefaultConfig(): #-----------------------------------------------
- """Resets settings/config/materials to defaults.
-
- """
- #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
- updateConfig(keywords_org, drawTypes_org)
-
-
-def presetConfig_curv(activate): #-----------------------------------------------
- """Sets settings/config/materials for curve representation.
-
- """
- global GUI_A
- if activate:
- GUI_A['curves_on'].val = 1
- GUI_A['points_as'].val = 5
- GUI_A['lines_as'].val = 5
- GUI_A['mlines_as'].val = 5
- GUI_A['plines_as'].val = 5
- GUI_A['splines_as'].val = 5
- GUI_A['plines3_as'].val = 5
- else:
- GUI_A['curves_on'].val = 0
- GUI_A['points_as'].val = 2
- GUI_A['lines_as'].val = 2
- GUI_A['mlines_as'].val = 2
- GUI_A['plines_as'].val = 2
- GUI_A['splines_as'].val = 6
- GUI_A['plines3_as'].val = 2
-
-
-def resetDefaultConfig_2D(): #-----------------------------------------------
- """Sets settings/config/materials to defaults 2D.
-
- """
- presetConfig_curv(1)
- keywords2d = {
- 'views_on' : 0,
- 'cams_on' : 0,
- 'lights_on' : 0,
- 'vGroup_on' : 1,
- 'thick_on' : 0,
- 'thick_force': 0,
- 'width_on' : 1,
- 'width_force': 0,
- 'dist_on' : 1,
- 'dist_force': 0,
- 'fill_on' : 0,
- 'pl_trim_on': 1,
- 'Z_force_on': 0,
- 'meshSmooth_on': 0,
- 'solids_as' : 2,
- 'blocks_as' : 1,
- 'texts_as' : 1
- }
-
- drawTypes2d = {
- 'point' : 1,
- 'line' : 1,
- 'arc' : 1,
- 'circle': 1,
- 'ellipse': 1,
- 'mline' : 0,
- 'polyline': 1,
- 'spline': 1,
- 'plmesh': 0,
- 'pline3': 1,
- 'lwpolyline': 1,
- 'text' : 1,
- 'mtext' : 0,
- 'block' : 1,
- 'insert': 1,
- 'solid' : 1,
- 'trace' : 1,
- 'face' : 0,
-# 'view' : 0,
- }
-
- updateConfig(keywords2d, drawTypes2d)
-
-def resetDefaultConfig_3D(): #-----------------------------------------------
- """Sets settings/config/materials to defaults 3D.
-
- """
- presetConfig_curv(0)
- keywords3d = {
-# 'views_on' : 1,
-# 'cams_on' : 1,
-# 'lights_on' : 1,
- 'vGroup_on' : 1,
- 'thick_on' : 1,
- 'thick_force': 0,
- 'width_on' : 1,
- 'width_force': 0,
- 'dist_on' : 1,
- 'dist_force': 0,
- 'fill_on' : 1,
- 'pl_trim_on': 1,
- 'Z_force_on': 0,
- 'meshSmooth_on': 1,
- 'solids_as' : 2,
- 'blocks_as' : 1,
- 'texts_as' : 1
- }
-
- drawTypes3d = {
- 'point' : 1,
- 'line' : 1,
- 'arc' : 1,
- 'circle': 1,
- 'ellipse': 1,
- 'mline' : 0,
- 'polyline': 1,
- 'spline': 1,
- 'plmesh': 1,
- 'pline3': 1,
- 'lwpolyline': 1,
- 'text' : 0,
- 'mtext' : 0,
- 'block' : 1,
- 'insert': 1,
- 'solid' : 1,
- 'trace' : 1,
- 'face' : 1,
-# 'view' : 0,
- }
-
- updateConfig(keywords3d, drawTypes3d)
-
-
-def inputGlobalScale():
- """Pop-up UI-Block for global scale factor
- """
- global GUI_A
- #print 'deb:inputGlobalScale ##########' #------------
- x_scale = Draw.Create(GUI_A['g_scale'].val)
- block = []
- #block.append("global translation vector:")
- block.append(("", x_scale, 0.0, 10000000.0))
-
- retval = Draw.PupBlock("set global scale factor:", block)
-
- GUI_A['g_scale'].val = float(x_scale.val)
-
-
-def inputOriginVector():
- """Pop-up UI-Block for global translation vector
- """
- global GUI_A
- #print 'deb:inputOriginVector ##########' #------------
- x_origin = Draw.Create(GUI_A['g_originX'].val)
- y_origin = Draw.Create(GUI_A['g_originY'].val)
- z_origin = Draw.Create(GUI_A['g_originZ'].val)
- block = []
- #block.append("global translation vector:")
- block.append(("X: ", x_origin, -100000000.0, 100000000.0))
- block.append(("Y: ", y_origin, -100000000.0, 100000000.0))
- block.append(("Z: ", z_origin, -100000000.0, 100000000.0))
-
- retval = Draw.PupBlock("set global translation vector:", block)
-
- GUI_A['g_originX'].val = x_origin.val
- GUI_A['g_originY'].val = y_origin.val
- GUI_A['g_originZ'].val = z_origin.val
-
-
-def draw_UI(): #-----------------------------------------------------------------
- """ Draw startUI and setup Settings.
- """
- global GUI_A, GUI_B #__version__
- global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
- global model_space_on
-
- # This is for easy layout changes
- but_0c = 70 #button 1.column width
- but_1c = 70 #button 1.column width
- but_2c = 70 #button 2.column
- but_3c = 70 #button 3.column
- menu_margin = 10
- butt_margin = 10
- menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width
-
- simple_menu_h = 100
- extend_menu_h = 350
- y = simple_menu_h # y is menu upper.y
- if config_UI.val: y += extend_menu_h
- x = 20 #menu left.x
- but0c = x + menu_margin #buttons 0.column position.x
- but1c = but0c + but_0c + butt_margin
- but2c = but1c + but_1c + butt_margin
- but3c = but2c + but_2c + butt_margin
- but4c = but3c + but_3c
-
- # Here starts menu -----------------------------------------------------
- #glClear(GL_COLOR_BUFFER_BIT)
- #glRasterPos2d(8, 125)
-
- y += 30
- colorbox(x, y+20, x+menu_w+menu_margin*2, menu_margin)
- Draw.Label("DXF/DWG-Importer v" + __version__, but0c, y, menu_w, 20)
-
- if config_UI.val:
- b0, b0_ = but0c, but_0c + butt_margin
- b1, b1_ = but1c, but_1c
- y_top = y
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_B['point'] = Draw.Toggle('POINT', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['point'].val, "support dxf-POINT on/off")
- if GUI_B['point'].val:
- GUI_A['points_as'] = Draw.Menu(points_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['points_as'].val, "select target Blender-object")
-# Draw.Label('-->', but2c, y, but_2c, 20)
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['line'] = Draw.Toggle('LINE...etc', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['line'].val, "support dxf-LINE,ARC,CIRCLE,ELLIPSE on/off")
- if GUI_B['line'].val:
- GUI_A['lines_as'] = Draw.Menu(lines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['lines_as'].val, "select target Blender-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['mline'] = Draw.Toggle('..MLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['mline'].val, "(*todo)support dxf-MLINE on/off")
- if GUI_B['mline'].val:
- GUI_A['mlines_as'] = Draw.Menu(mlines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['mlines_as'].val, "select target Blender-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['spline'] = Draw.Toggle('SPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['spline'].val, "support dxf-SPLINE on/off")
- if GUI_B['spline'].val:
- GUI_A['splines_as'] = Draw.Menu(splines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['splines_as'].val, "select target Blender-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['polyline'] = Draw.Toggle('2D/LWPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['polyline'].val, "support dxf-2D-POLYLINE on/off")
- if GUI_B['polyline'].val:
- GUI_A['plines_as'] = Draw.Menu(plines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines_as'].val, "select target Blender-object")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['pline3'] = Draw.Toggle('3D-PLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['pline3'].val, "support dxf-3D-POLYLINE on/off")
- if GUI_B['pline3'].val:
- GUI_A['plines3_as'] = Draw.Menu(plines3_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines3_as'].val, "select target Blender-object")
- Draw.EndAlign()
-
- y_down = y
- # -----------------------------------------------
-
- y = y_top
- b0, b0_ = but2c, but_2c + butt_margin
- b1, b1_ = but3c, but_3c
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_B['plmesh'] = Draw.Toggle('PL-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_-40, 20, GUI_B['plmesh'].val, "support dxf-POLYMESH/POLYFACE on/off")
-# GUI_A['plmesh_as'] = Draw.Menu(plmesh_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plmesh_as'].val, "select target Blender-object")
- GUI_A['plmesh_flip'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-40, y, 20, 20, GUI_A['plmesh_flip'].val, "flip DXF normals on/off")
- GUI_A['normals_out'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-20, y, 20, 20, GUI_A['normals_out'].val, "force Blender normals to outside on/off")
- Draw.EndAlign()
-
- y -= 20
- GUI_B['solid'] = Draw.Toggle('SOLID', EVENT_NONE, b0, y, b0_, 20, GUI_B['solid'].val, "support dxf-SOLID and TRACE on/off")
- GUI_B['face'] = Draw.Toggle('3DFACE', EVENT_NONE, b1, y, b1_, 20, GUI_B['face'].val, "support dxf-3DFACE on/off")
-# GUI_A['solids_as'] = Draw.Menu(solids_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['solids_as'].val, "select target Blender-object")
- #print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------
-
-
- y -= 20
- GUI_B['text'] = Draw.Toggle('TEXT', EVENT_NONE, b0, y, b0_, 20, GUI_B['text'].val, "support dxf-TEXT on/off")
- GUI_B['mtext'] = Draw.Toggle('..MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*todo)support dxf-MTEXT on/off")
-# GUI_A['texts_as'] = Draw.Menu(texts_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['texts_as'].val, "select target Blender-object")
-
- y -= 20
- Draw.BeginAlign()
- GUI_B['block'] = Draw.Toggle('BLOCK', EVENT_REDRAW, b0, y, b0_-30, 20, GUI_B['block'].val, "support dxf-BLOCK and ARRAY on/off")
- GUI_B['insert'].val = GUI_B['block'].val
- if GUI_B['block'].val:
- GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "support hatch/noname BLOCKs *X... on/off")
- GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1-15, y, 35, 20, GUI_A['xref_on'].val, "support for XREF-BLOCKs (place holders) on/off")
- GUI_A['blocks_as'] = Draw.Menu(blocks_as_menu, EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['blocks_as'].val, "select target representation for imported BLOCKs")
- Draw.EndAlign()
-
-
- y -= 20
- y -= 20
-
- Draw.BeginAlign()
- GUI_A['views_on'] = Draw.Toggle('views', EVENT_NONE, b0, y, b0_-25, 20, GUI_A['views_on'].val, "imports VIEWs and VIEWPORTs as cameras on/off")
- GUI_A['cams_on'] = Draw.Toggle('..cams', EVENT_NONE, b1-25, y, b1_-25, 20, GUI_A['cams_on'].val, "(*todo) support ASHADE cameras on/off")
- GUI_A['lights_on'] = Draw.Toggle('..lights', EVENT_NONE, b1+25, y, b1_-25, 20, GUI_A['lights_on'].val, "(*todo) support AVE_RENDER lights on/off")
- Draw.EndAlign()
-
-
- if y < y_down: y_down = y
- # -----end supported objects--------------------------------------
-
- y_top = y_down
- y = y_top
- y -= 10
- y -= 20
- but_ = menu_w / 6
- b0 = but0c + (menu_w - but_*6)/2
- Draw.BeginAlign()
- GUI_A['paper_space_on'] = Draw.Toggle('paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "import only from Paper-Space on/off")
- GUI_A['layFrozen_on'] = Draw.Toggle ('frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "import also from frozen LAYERs on/off")
- GUI_A['layerFilter_on'] = Draw.Toggle('..layer', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['layerFilter_on'].val, "(*todo) LAYER filtering on/off")
- GUI_A['colorFilter_on'] = Draw.Toggle('..color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*todo) COLOR filtering on/off")
- GUI_A['groupFilter_on'] = Draw.Toggle('..group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*todo) GROUP filtering on/off")
- GUI_A['blockFilter_on'] = Draw.Toggle('..block', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['blockFilter_on'].val, "(*todo) BLOCK filtering on/off")
- #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['dummy_on'].val, "dummy on/off")
- Draw.EndAlign()
-
- # -----end filters--------------------------------------
-
- b0, b0_ = but0c, but_0c + butt_margin
- b1, b1_ = but1c, but_1c
-
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_A['g_origin_on'] = Draw.Toggle('glob.reLoc', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "global relocate all DXF objects on/off")
- if GUI_A['g_origin_on'].val:
- tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "edit relocation-vector (x,y,z in DXF units)")
- origin_str = '(%.4f, %.4f, %.4f)' % (
- GUI_A['g_originX'].val,
- GUI_A['g_originY'].val,
- GUI_A['g_originZ'].val
- )
- tmp = Draw.Label(origin_str, b1+20, y, 300, 20)
- #GUI_A['g_origin'] = Draw.String('', EVENT_ORIGIN, b1, y, b1_, 20, GUI_A['g_origin'].val, "global translation-vector (x,y,z) in DXF units")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['g_scale_on'] = Draw.Toggle('glob.Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "global scale all DXF objects on/off")
- if GUI_A['g_scale_on'].val:
- g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "factor for scaling the DXFdata")
- if g_scale_as.val == 12:
- pass
- else:
- if g_scale_as.val == 6: #scale inches to meters
- GUI_A['g_scale'].val = 0.0254000
- elif g_scale_as.val == 7: #scale feets to meters
- GUI_A['g_scale'].val = 0.3048000
- elif g_scale_as.val == 8: #scale yards to meters
- GUI_A['g_scale'].val = 0.9144000
- else:
- GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val)
- scale_float = GUI_A['g_scale'].val
- if scale_float < 0.000001 or scale_float > 1000000:
- scale_str = ' = %s' % GUI_A['g_scale'].val
- else:
- scale_str = ' = %.6f' % GUI_A['g_scale'].val
- Draw.Label(scale_str, b1+45, y, 200, 20)
- Draw.EndAlign()
-
- y_down = y
- # -----end material,translate,scale------------------------------------------
-
- b0, b0_ = but0c, but_0c + butt_margin
- b1, b1_ = but1c, but_1c
-
- y_top = y_down
- y = y_top
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_A['meshSmooth_on'] = Draw.Toggle('smooth', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['meshSmooth_on'].val, "mesh smooth for circles/arc-segments on/off")
- GUI_A['pl_trim_on'] = Draw.Toggle('trim', EVENT_NONE, b1-20, y, 32, 20, GUI_A['pl_trim_on'].val, "clean intersection of POLYLINE-wide-segments on/off")
- GUI_A['pl_trim_max'] = Draw.Number('', EVENT_NONE, b1+12, y, b1_-12, 20, GUI_A['pl_trim_max'].val, 0, 5, "threshold intersection of POLYLINE-wide-segments: 0.0-5.0")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
-# GUI_A['thin_res'] = Draw.Number('thin:', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['thin_res'].val, 4, 64, "thin cylinder resolution - number of segments (4-64)")
- GUI_A['arc_rad'] = Draw.Number('bR:', EVENT_NONE, b0, y, b0_, 20, GUI_A['arc_rad'].val, 0.01, 100, "basis radius for arc/circle resolution (0.01-100)")
- GUI_A['arc_res'] = Draw.Number('', EVENT_NONE, b1, y, b1_/2, 20, GUI_A['arc_res'].val, 3, 500, "arc/circle resolution - number of segments (3-500)")
- GUI_A['fill_on'] = Draw.Toggle('caps', EVENT_NONE, b1+b1_/2, y, b1_/2, 20, GUI_A['fill_on'].val, "draws top and bottom caps of CYLINDERs/closed curves on/off")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['curve_arc'] = Draw.Number('', EVENT_NONE, b0, y, b0_/2, 20, GUI_A['curve_arc'].val, 3, 32, "Bezier circle: amount of segments: 3-32")
- GUI_A['curve_res'] = Draw.Number('', EVENT_NONE, b0+b0_/2, y, b0_/2, 20, GUI_A['curve_res'].val, 1, 128, "Set the Curve's U-resolution value: 1-128")
- GUI_A['curves_on'] = Draw.Toggle('to Curves', EVENT_PRESETCURV, b1, y, b1_, 20, GUI_A['curves_on'].val, "set Curve as target object type on/off")
- Draw.EndAlign()
-
- y -= 20
- GUI_A['group_bylayer_on'] = Draw.Toggle('Layer', EVENT_NONE, b0, y, 30, 20, GUI_A['group_bylayer_on'].val, "DXF-entities group by layer on/off")
- GUI_A['vGroup_on'] = Draw.Toggle('vGroups', EVENT_NONE, b0+30, y, b1_-10, 20, GUI_A['vGroup_on'].val, "sort faces into VertexGroups on/off")
- GUI_A['one_mesh_on'] = Draw.Toggle('oneMesh', EVENT_NONE, b1+10, y, b1_-10, 20, GUI_A['one_mesh_on'].val, "draw DXF-entities into one mesh-object. Recommended for big DXF-files. on/off")
-
- y -= 30
- Draw.BeginAlign()
- GUI_A['material_on'] = Draw.Toggle('material', EVENT_REDRAW, b0, y, b0_-20, 20, GUI_A['material_on'].val, "support for material assignment on/off")
- if GUI_A['material_on'].val:
- GUI_A['material_from'] = Draw.Menu(material_from_menu, EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_from'].val, "material assignment from?")
- Draw.EndAlign()
-
- y_down = y
- # -----------------------------------------------
-
- b0, b0_ = but2c, but_2c + butt_margin
- b1, b1_ = but3c, but_3c
-
- y = y_top
- y -= 10
- y -= 20
- Draw.BeginAlign()
- GUI_A['Z_force_on'] = Draw.Toggle('.elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, ".set objects Z-coordinates to elevation on/off")
- if GUI_A['Z_force_on'].val:
- GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "set default elevation(Z-coordinate)")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['dist_on'] = Draw.Toggle('dist.:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['dist_on'].val, "support distance on/off")
- GUI_A['dist_force'] = Draw.Toggle('F', EVENT_NONE, b0+b0_-20, y, 20, 20, GUI_A['dist_force'].val, "force minimal distance on/off")
- GUI_A['dist_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['dist_min'].val, 0, 10, "minimal length/distance (double.vertex removing)")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['thick_on'] = Draw.Toggle('thick:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['thick_on'].val, "support thickness on/off")
- GUI_A['thick_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['thick_force'].val, "force for thickness at least limiter value on/off")
- if GUI_A['thick_force'].val:
- GUI_A['thick_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['thick_min'].val, 0, 10, "minimal value for thickness")
- Draw.EndAlign()
-
- y -= 20
- Draw.BeginAlign()
- GUI_A['width_on'] = Draw.Toggle('width:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['width_on'].val, "support width on/off")
- GUI_A['width_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['width_force'].val, "force for width at least limiter value on/off")
- if GUI_A['width_force'].val:
- GUI_A['width_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['width_min'].val, 0, 10, "minimal value for width")
- Draw.EndAlign()
-
- y -= 30
- but, but_ = but2c, 25
- Draw.BeginAlign()
- Draw.EndAlign()
-
- if y < y_down: y_down = y
- # -----end options --------------------------------------
-
-
- #--------------------------------------
- y_top = y_down
- y = y_top
- #GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved")
- y -= 30
- Draw.BeginAlign()
- Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file from project directory')
- iniFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_1c-60, 20, iniFileName.val, FILENAME_MAX, "write here the name of the INI-file")
- but = but4c-60
- Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "toggle Preset-INI-files")
- Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from ini-file: %s' % iniFileName.val)
- Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to ini-file: %s' % iniFileName.val)
- Draw.EndAlign()
-
-
- b0, b0_ = but2c, but_2c + butt_margin
- b1, b1_ = but3c, but_3c
-
- y = simple_menu_h
- bm = butt_margin/2
-
- #y -= 10
- Draw.BeginAlign()
- Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF/DWG-file for import')
- dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF/DWG-file or type *.dxf/*.dwg for multiple files")
- Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'set filter for import all files from this directory')
- Draw.EndAlign()
-
- y -= 30
- config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' )
- Draw.BeginAlign()
- but, but_ = but1c, but_1c+bm
- but_ /= 3
- Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "reset configuration to defaults")
- Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'set configuration for 2D import')
- Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'set configuration for 3D import')
- Draw.EndAlign()
-
- Draw.BeginAlign()
- GUI_A['newScene_on'] = Draw.Toggle('newScene', EVENT_NONE, but2c, y, but_2c, 20, GUI_A['newScene_on'].val, "create new Scene for each imported dxf file on/off")
- GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['target_layer'].val, 1, 18, "target Blender-layer (<19> reserved for block_definitions)")
- Draw.EndAlign()
-
- y -= 40
- Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' )
- Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'calls DXF-Importer Manual Page on Wiki.Blender.org')
- Draw.BeginAlign()
- GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/directDrawing, 1=Verbose, 2=ProgressBar, 3=SilentMode")
- Draw.EndAlign()
- Draw.BeginAlign()
- Draw.PushButton('TEST', EVENT_LIST, but2c, y, 40, 20, 'DXF-Analyze-Tool: reads data from selected dxf file and writes report in project_directory/dxf_blendname.INF')
- Draw.PushButton('START IMPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the import process. For Cancel go to console and hit Ctrl-C')
- Draw.EndAlign()
-
-
-
-
- y -= 20
- Draw.BeginAlign()
- Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
- Draw.Label(LAB, but0c, y, menu_w, 20)
- Draw.Label(' ', but0c+menu_w, y, menu_margin, 20)
- Draw.EndAlign()
-
-#-- END GUI Stuf-----------------------------------------------------
-
-def colorbox(x,y,xright,bottom):
- glColor3f(0.75, 0.75, 0.75)
- glRecti(x + 1, y + 1, xright - 1, bottom - 1)
-
-def dxf_callback(input_filename):
- global dxfFileName
- if input_filename.lower()[-3:] in ('dwg','dxf'):
- dxfFileName.val=input_filename
-# dirname == sys.dirname(Blender.Get('filename'))
-# update_RegistryKey('DirName', dirname)
-# update_RegistryKey('dxfFileName', input_filename)
-
-def ini_callback(input_filename):
- global iniFileName
- iniFileName.val=input_filename
-
-def event(evt, val):
- if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
- Draw.Exit()
-
-def bevent(evt):
-# global EVENT_NONE,EVENT_LOAD_DXF,EVENT_LOAD_INI,EVENT_SAVE_INI,EVENT_EXIT
- global config_UI, user_preset
- global GUI_A, UI_MODE
-
- ######### Manages GUI events
- if (evt==EVENT_EXIT):
- Draw.Exit()
- print 'DXF/DWG-Importer *** exit ***' #---------------------
- elif (evt==EVENT_CHOOSE_INI):
- Window.FileSelector(ini_callback, "INI-file Selection", '*.ini')
- elif (evt==EVENT_REDRAW):
- Draw.Redraw()
- elif (evt==EVENT_RESET):
- resetDefaultConfig()
- Draw.Redraw()
- elif (evt==EVENT_PRESET2D):
- resetDefaultConfig_2D()
- Draw.Redraw()
- elif (evt==EVENT_SCALE):
- if g_scale_as.val == 12:
- inputGlobalScale()
- if GUI_A['g_scale'].val < 0.00000001:
- GUI_A['g_scale'].val = 0.00000001
- Draw.Redraw()
- elif (evt==EVENT_ORIGIN):
- inputOriginVector()
- Draw.Redraw()
- elif (evt==EVENT_PRESET3D):
- resetDefaultConfig_3D()
- Draw.Redraw()
- elif (evt==EVENT_PRESETCURV):
- presetConfig_curv(GUI_A['curves_on'].val)
- Draw.Redraw()
- elif (evt==EVENT_PRESETS):
- user_preset += 1
- index = str(user_preset)
- if user_preset > 5: user_preset = 0; index = ''
- iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
- Draw.Redraw()
- elif (evt==EVENT_LIST):
- dxfFile = dxfFileName.val
- update_RegistryKey('dxfFileName', dxfFileName.val)
- if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
- analyzeDXF(dxfFile)
- else:
- Draw.PupMenu('DXF importer: Alert!%t|no valid DXF-file selected!')
- print "DXF importer: error, no valid DXF-file selected! try again"
- Draw.Redraw()
- elif (evt==EVENT_HELP):
- try:
- import webbrowser
- webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D')
- except:
- Draw.PupMenu('DXF importer: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\
-http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D')
- Draw.Redraw()
- elif (evt==EVENT_LOAD_INI):
- loadConfig()
- Draw.Redraw()
- elif (evt==EVENT_SAVE_INI):
- saveConfig()
- Draw.Redraw()
- elif (evt==EVENT_DXF_DIR):
- dxfFile = dxfFileName.val
- dxfFileExt = '*'+dxfFile.lower()[-4:] #can be .dxf or .dwg
- dxfPathName = ''
- if '/' in dxfFile:
- dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/'
- elif '\\' in dxfFile:
- dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\'
- dxfFileName.val = dxfPathName + dxfFileExt
-# dirname == sys.dirname(Blender.Get('filename'))
-# update_RegistryKey('DirName', dirname)
-# update_RegistryKey('dxfFileName', dxfFileName.val)
- GUI_A['newScene_on'].val = 1
- Draw.Redraw()
- elif (evt==EVENT_CHOOSE_DXF):
- filename = '' # '*.dxf'
- if dxfFileName.val: filename = dxfFileName.val
- Window.FileSelector(dxf_callback, "DXF/DWG-file Selection", filename)
- elif (evt==EVENT_START):
- dxfFile = dxfFileName.val
- #print 'deb: dxfFile file: ', dxfFile #----------------------
- if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode
- update_RegistryKey('dxfFileName', dxfFileName.val)
- if dxfFile.lower().endswith('*.dxf'):
- if Draw.PupMenu('DXF importer will import all DXF-files from:|%s|OK?' % dxfFile) != -1:
- UI_MODE = False
- multi_import(dxfFile)
- UI_MODE = True
- Draw.Redraw()
-
- elif dxfFile.lower().endswith('*.dwg'):
- if not extCONV_OK: Draw.PupMenu(extCONV_TEXT)
- elif Draw.PupMenu('DWG importer will import all DWG-files from:|%s|OK?' % dxfFile) != -1:
- #elif Draw.PupMenu('DWG importer will import all DWG-files from:|%s|Caution! overwrites existing DXF-files!| OK?' % dxfFile) != -1:
- UI_MODE = False
- multi_import(dxfFile)
- UI_MODE = True
- Draw.Redraw()
-
- elif sys.exists(dxfFile) and dxfFile.lower()[-4:] in ('.dxf','.dwg'):
- if dxfFile.lower().endswith('.dwg') and (not extCONV_OK):
- Draw.PupMenu(extCONV_TEXT)
- else:
- #print '\nStandard Mode: active'
- if GUI_A['newScene_on'].val:
- _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
- _dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
- _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
- global SCENE
- SCENE = Blender.Scene.New(_dxf_file)
- SCENE.makeCurrent()
- Blender.Redraw()
- #or so? Blender.Scene.makeCurrent(_dxf_file)
- #sce = bpy.data.scenes.new(_dxf_file)
- #bpy.data.scenes.active = sce
- else:
- SCENE = Blender.Scene.GetCurrent()
- SCENE.objects.selected = [] # deselect all
- main(dxfFile)
- #SCENE.objects.selected = SCENE.objects
- #Window.RedrawAll()
- #Blender.Redraw()
- #Draw.Redraw()
- else:
- Draw.PupMenu('DXF importer: nothing imported!%t|no valid DXF-file selected!')
- print "DXF importer: nothing imported, no valid DXF-file selected! try again"
- Draw.Redraw()
-
-
-
-
-def multi_import(DIR):
- """Imports all DXF-files from directory DIR.
-
- """
- global SCENE
- batchTIME = sys.time()
- #if #DIR == "": DIR = os.path.curdir
- if DIR == "":
- DIR = sys.dirname(Blender.Get('filename'))
- EXT = '.dxf'
- else:
- EXT = DIR[-4:] # get last 4 characters '.dxf'
- DIR = DIR[:-5] # cut last 5 characters '*.dxf'
- print 'importing multiple %s files from %s' %(EXT,DIR)
- files = \
- [sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith(EXT)]
- if not files:
- print '...None %s-files found. Abort!' %EXT
- return
-
- i = 0
- for dxfFile in files:
- i += 1
- print '\n%s-file' %EXT, i, 'of', len(files) #,'\nImporting', dxfFile
- if GUI_A['newScene_on'].val:
- _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
- _dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
- _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
- SCENE = Blender.Scene.New(_dxf_file)
- SCENE.makeCurrent()
- #or so? Blender.Scene.makeCurrent(_dxf_file)
- #sce = bpy.data.scenes.new(_dxf_file)
- #bpy.data.scenes.active = sce
- else:
- SCENE = Blender.Scene.GetCurrent()
- SCENE.objects.selected = [] # deselect all
- main(dxfFile)
- #Blender.Redraw()
-
- print 'TOTAL TIME: %.6f' % (sys.time() - batchTIME)
- print '\a\r', # beep when done
- Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % (sys.time() - batchTIME))
-
-
-if __name__ == "__main__":
- #Draw.PupMenu('DXF importer: Abort%t|This script version works for Blender up 2.49 only!')
- UI_MODE = True
- # recall last used DXF-file and INI-file names
- dxffilename = check_RegistryKey('dxfFileName')
- #print 'deb:start dxffilename:', dxffilename #----------------
- if dxffilename: dxfFileName.val = dxffilename
- else:
- dirname = sys.dirname(Blender.Get('filename'))
- #print 'deb:start dirname:', dirname #----------------
- dxfFileName.val = sys.join(dirname, '')
- inifilename = check_RegistryKey('iniFileName')
- if inifilename: iniFileName.val = inifilename
-
- Draw.Register(draw_UI, event, bevent)
-
-
-"""
-if 1:
- # DEBUG ONLY
- UI_MODE = False
- TIME= sys.time()
- #DIR = '/dxf_r12_testfiles/'
- DIR = '/metavr/'
- import os
- print 'Searching for files'
- os.system('find %s -iname "*.dxf" > /tmp/tempdxf_list' % DIR)
- # os.system('find /storage/ -iname "*.dxf" > /tmp/tempdxf_list')
- print '...Done'
- file= open('/tmp/tempdxf_list', 'r')
- lines= file.readlines()
- file.close()
- # sort by filesize for faster testing
- lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
- lines_size.sort()
- lines = [f[1] for f in lines_size]
-
- for i, _dxf in enumerate(lines):
- if i >= 70:
- #if 1:
- print 'Importing', _dxf, '\nNUMBER', i, 'of', len(lines)
- if True:
- _dxf_file= _dxf.split('/')[-1].split('\\')[-1]
- _dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
- _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
- sce = bpy.data.scenes.new(_dxf_file)
- bpy.data.scenes.active = sce
- dxfFileName.val = _dxf
- main(_dxf)
-
- print 'TOTAL TIME: %.6f' % (sys.time() - TIME)
-""" \ No newline at end of file
diff --git a/release/scripts/import_edl.py b/release/scripts/import_edl.py
deleted file mode 100644
index 8c5d041b34c..00000000000
--- a/release/scripts/import_edl.py
+++ /dev/null
@@ -1,961 +0,0 @@
-#!BPY
-
-"""
-Name: 'Video Sequence (.edl)...'
-Blender: 248
-Group: 'Import'
-Tooltip: 'Load a CMX formatted EDL into the sequencer'
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2009: Campbell Barton, ideasman42@gmail.com
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# --------------------------------------------------------------------------
-
-class TimeCode(object):
- '''
- Simple timecode class
- also supports conversion from other time strings used by EDL
- '''
- def __init__(self, data, fps):
- self.fps= fps
- if type(data)==str:
- self.fromString(data)
- frame = self.asFrame()
- self.fromFrame(frame)
- else:
- self.fromFrame(data)
-
- def fromString(self, text):
- # hh:mm:ss:ff
- # No dropframe support yet
-
- if text.lower().endswith('mps'): # 5.2mps
- return self.fromFrame( int( float(text[:-3]) * self.fps ) )
- elif text.lower().endswith('s'): # 5.2s
- return self.fromFrame( int( float(text[:-1]) * self.fps ) )
- elif text.isdigit(): # 1234
- return self.fromFrame( 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 "%s"' % test
- return self
-
-
- def fromFrame(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 asFrame(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 asString(self):
- self.fromFrame(int(self))
- return '%.2d:%.2d:%.2d:%.2d' % (self.hours, self.minutes, self.seconds, self.frame)
-
- def __repr__(self):
- return self.asString()
-
- # Numeric stuff, may as well have this
- def __neg__(self): return TimeCode(-int(self), self.fps)
- def __int__(self): return self.asFrame()
- 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.fromFrame(int(self)+int(other))
- def __imul__(self, other): return self.fromFrame(int(self)*int(other))
- def __idiv__(self, other): return self.fromFrame(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= { \
- '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; enum+=1 # K B
-KEY_IN= enum; enum+=1 # This is assumed if no second type is set
-KEY_OUT= enum; enum+=1 # K O
-
-
-'''
-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
-'''
-
-def editFlagsToText(flag):
- items = []
- for item, val in EDIT_DICT.items():
- if val & flag:
- items.append(item)
- return '/'.join(items)
-
-
-class EditDecision(object):
- 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 != None:
- self.read(text, fps)
-
- def __repr__(self):
- txt= 'num: %d, ' % self.number
- txt += 'reel: %s, ' % self.reel
- txt += 'edit_type: '
- txt += editFlagsToText(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('/'):
- self.edit_type |= EDIT_DICT[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 asName(self):
- cut_type = 'nil'
- for k,v in TRANSITION_DICT.iteritems():
- if v==self.transition_type:
- cut_type = k
- break
-
- return '%d_%s_%s' % (self.number, self.reel, cut_type)
-
-class M2(object):
- 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(object):
- def __init__(self):
- self.edits= []
- self.title= ''
-
- def parse(self, filename, fps):
- try:
- file= open(filename, 'rU')
- 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('*') 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
-
-
- return True
-
- def testOverlap(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 getReels(self):
- reels = {}
- for edit in self.edits:
- reels.setdefault(edit.reel, []).append(edit)
-
- return reels
-
-
-
-# from DNA
-SEQ_IMAGE= 0
-SEQ_META= 1
-SEQ_SCENE= 2
-SEQ_MOVIE= 3
-SEQ_RAM_SOUND= 4
-SEQ_HD_SOUND= 5
-SEQ_MOVIE_AND_HD_SOUND= 6
-
-SEQ_EFFECT= 8
-SEQ_CROSS= 8
-SEQ_ADD= 9
-SEQ_SUB= 10
-SEQ_ALPHAOVER= 11
-SEQ_ALPHAUNDER= 12
-SEQ_GAMCROSS= 13
-SEQ_MUL= 14
-SEQ_OVERDROP= 15
-SEQ_PLUGIN= 24
-SEQ_WIPE= 25
-SEQ_GLOW= 26
-SEQ_TRANSFORM= 27
-SEQ_COLOR= 28
-SEQ_SPEED= 29
-
-# Blender spesific stuff starts here
-import bpy
-import Blender
-
-def scale_meta_speed(seq, mov, scale):
- # Add an effect
- speed= seq.new((SEQ_SPEED, mov,), 199, mov.channel+1)
- speed.speedEffectFrameBlending = True
- meta= seq.new([mov, speed], 199, mov.channel)
-
- if scale >= 1.0:
- mov.endStill = int(mov.length * (scale - 1.0))
- else:
- speed.speedEffectGlobalSpeed = 1.0/scale
- meta.endOffset = mov.length - int(mov.length*scale)
-
- speed.update()
- meta.update()
- return meta
-
-def apply_dissolve_ipo(mov, blendin):
- len_disp = float(mov.endDisp - mov.startDisp)
-
- if len_disp <= 0.0:
- print 'Error, strip is zero length'
- return
-
- mov.ipo= ipo= bpy.data.ipos.new("fade", "Sequence")
- icu= ipo.addCurve('Fac')
-
- icu.interpolation= Blender.IpoCurve.InterpTypes.LINEAR
- icu.append((0, 0))
- icu.append(((int(blendin)/len_disp) * 100, 1))
-
- if mov.type not in (SEQ_HD_SOUND, SEQ_RAM_SOUND):
- mov.blendMode = Blender.Scene.Sequence.BlendModes.ALPHAOVER
-
-
-def replace_ext(path, ext):
- return path[:path.rfind('.')+1] + ext
-
-def load_edl(filename, reel_files, reel_offsets):
- '''
- reel_files - key:reel <--> reel:filename
- '''
-
- # For test file
- # frame_offset = -769
-
-
- sce= bpy.data.scenes.active
- fps= sce.render.fps
-
- elist= EditList()
- if not elist.parse(filename, fps):
- return 'Unable to parse "%s"' % filename
- # elist.clean()
-
-
- seq= sce.sequence
-
- track= 0
-
- edits = elist.edits[:]
- # edits.sort(key = lambda edit: int(edit.recIn))
-
- prev_edit = None
- for edit in edits:
- print edit
- 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
-
- # print src_length, rec_length, src_start
-
- if edit.m2 != None: scale = fps/float(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 == TRANSITION_CUT and (not elist.testOverlap(edit)):
- track = 1
-
- strip= None
- final_strips = []
- if edit.reel.lower()=='bw':
- strip= seq.new((0,0,0), rec_start, track+1)
- strip.length= rec_length # for color its simple
- final_strips.append(strip)
- else:
-
- path_full = reel_files[edit.reel]
- path_fileonly= path_full.split('/')[-1].split('\\')[-1] # os.path.basename(full)
- path_dironly= path_full[:-len(path_fileonly)] # os.path.dirname(full)
-
- if edit.edit_type & EDIT_VIDEO: #and edit.transition_type == TRANSITION_CUT:
-
- try:
- strip= seq.new((path_fileonly, path_dironly, path_full, 'movie'), unedited_start + offset_start, track+1)
- except:
- return 'Invalid input for movie'
-
- # Apply scaled rec in bounds
- if scale != 1.0:
- meta = scale_meta_speed(seq, strip, scale)
- final_strip = meta
- else:
- final_strip = strip
-
-
- final_strip.update()
- final_strip.startOffset= rec_start - final_strip.startDisp
- final_strip.endOffset= rec_end- final_strip.endDisp
- final_strip.update()
- final_strip.endOffset += (final_strip.endDisp - 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 != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND:
- other.endOffset += (other.endDisp - new_end)
- other.update()
-
- # Apply disolve
- if edit.transition_type == TRANSITION_DISSOLVE:
- apply_dissolve_ipo(final_strip, edit.transition_duration)
-
- if edit.transition_type == TRANSITION_WIPE:
- other_track = track + 2
- for other in prev_edit.custom_data:
- if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND:
-
- strip_wipe= seq.new((SEQ_WIPE, other, final_strip), 1, other_track)
-
- if edit.wipe_type == WIPE_0:
- strip_wipe.wipeEffectAngle = 90
- else:
- strip_wipe.wipeEffectAngle = -90
-
- other_track += 1
-
-
-
- # strip.endOffset= strip.length - int(edit.srcOut)
- #end_offset= (unedited_start+strip.length) - end
- # print start, end, end_offset
- #strip.endOffset = end_offset
-
- # break
- # print strip
-
- final_strips.append(final_strip)
-
-
- if edit.edit_type & (EDIT_AUDIO | EDIT_AUDIO_STEREO | EDIT_VIDEO_AUDIO):
-
- if scale == 1.0: # TODO - scaled audio
-
- try:
- strip= seq.new((path_fileonly, path_dironly, path_full, 'audio_hd'), unedited_start + offset_start, track+6)
- 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= seq.new((path_fileonly_wav, path_dironly, path_full_wav, 'audio_hd'), unedited_start + offset_start, track+6)
- #except:
- # return 'Invalid input for audio'
-
- final_strip = strip
-
- # Copied from above
- final_strip.update()
- final_strip.startOffset= rec_start - final_strip.startDisp
- final_strip.endOffset= rec_end- final_strip.endDisp
- final_strip.update()
- final_strip.endOffset += (final_strip.endDisp - rec_end)
- final_strip.update()
-
- if edit.transition_type == TRANSITION_DISSOLVE:
- apply_dissolve_ipo(final_strip, edit.transition_duration)
-
- final_strips.append(final_strip)
-
- # strip= seq.new((0.6, 0.6, 0.6), start, track+1)
-
- if final_strips:
- for strip in final_strips:
- # strip.length= length
- final_strip.name = edit.asName()
- edit.custom_data[:]= final_strips
- # track = not track
- prev_edit = edit
- track += 1
-
- #break
-
-
- def recursive_update(s):
- s.update(1)
- for s_kid in s:
- recursive_update(s_kid)
-
-
- for s in seq:
- recursive_update(s)
-
- return ''
-
-
-
-#load_edl('/fe/edl/EP30CMXtrk1.edl') # /tmp/test.edl
-#load_edl('/fe/edl/EP30CMXtrk2.edl') # /tmp/test.edl
-#load_edl('/fe/edl/EP30CMXtrk3.edl') # /tmp/test.edl
-#load_edl('/root/vid/rush/blender_edl.edl', ['/root/vid/rush/rushes3.avi',]) # /tmp/test.edl
-
-
-
-
-# ---------------------- Blender UI part
-from Blender import Draw, Window
-import BPyWindow
-
-if 0:
- DEFAULT_FILE_EDL = '/root/vid/rush/blender_edl.edl'
- DEFAULT_FILE_MEDIA = '/root/vid/rush/rushes3_wav.avi'
- DEFAULT_FRAME_OFFSET = -769
-else:
- DEFAULT_FILE_EDL = ''
- DEFAULT_FILE_MEDIA = ''
- DEFAULT_FRAME_OFFSET = 0
-
-B_EVENT_IMPORT = 1
-B_EVENT_RELOAD = 2
-B_EVENT_FILESEL_EDL = 3
-B_EVENT_NOP = 4
-
-B_EVENT_FILESEL = 100 # or greater
-
-class ReelItemUI(object):
- __slots__ = 'filename_but', 'offset_but', 'ui_text'
- def __init__(self):
- self.filename_but = Draw.Create(DEFAULT_FILE_MEDIA)
- self.offset_but = Draw.Create(DEFAULT_FRAME_OFFSET)
- self.ui_text = ''
-
-
-
-REEL_UI = {} # reel:ui_string
-
-
-#REEL_FILENAMES = {} # reel:filename
-#REEL_OFFSETS = {} # reel:filename
-
-PREF = {}
-
-PREF['filename'] = Draw.Create(DEFAULT_FILE_EDL)
-PREF['reel_act'] = ''
-
-def edl_reload():
- Window.WaitCursor(1)
- filename = PREF['filename'].val
- sce= bpy.data.scenes.active
- fps= sce.render.fps
-
- elist= EditList()
-
- if filename:
- if not elist.parse(filename, fps):
- Draw.PupMenu('Error%t|Could not open the file "' + filename + '"')
- reels = elist.getReels()
- else:
- reels = {}
-
- REEL_UI.clear()
- for reel_key, edits in reels.iteritems():
-
- if reel_key == 'bw':
- continue
-
- flag = 0
- for edit in edits:
- flag |= edit.edit_type
-
- reel_item = REEL_UI[reel_key] = ReelItemUI()
-
- reel_item.ui_text = '%s (%s): ' % (reel_key, editFlagsToText(flag))
-
- Window.WaitCursor(0)
-
-def edl_set_path(filename):
- PREF['filename'].val = filename
- edl_reload()
- Draw.Redraw()
-
-def edl_set_path_reel(filename):
- REEL_UI[PREF['reel_act']].filename_but.val = filename
- Draw.Redraw()
-
-def edl_reel_keys():
- reel_keys = REEL_UI.keys()
-
- if 'bw' in reel_keys:
- reel_keys.remove('bw')
-
- reel_keys.sort()
- return reel_keys
-
-def edl_draw():
-
- MARGIN = 4
- rect = BPyWindow.spaceRect()
- but_width = int((rect[2]-MARGIN*2)/4.0) # 72
- # Clamp
- if but_width>100: but_width = 100
- but_height = 17
-
- x=MARGIN
- y=rect[3]-but_height-MARGIN
- xtmp = x
-
-
-
- # ---------- ---------- ---------- ----------
- Blender.Draw.BeginAlign()
- PREF['filename'] = Draw.String('edl path: ', B_EVENT_RELOAD, xtmp, y, (but_width*3)-20, but_height, PREF['filename'].val, 256, 'EDL Path'); xtmp += (but_width*3)-20;
- Draw.PushButton('..', B_EVENT_FILESEL_EDL, xtmp, y, 20, but_height, 'Select an EDL file'); xtmp += 20;
- Blender.Draw.EndAlign()
-
- Draw.PushButton('Reload', B_EVENT_RELOAD, xtmp + MARGIN, y, but_width - MARGIN, but_height, 'Read the ID Property settings from the active curve object'); xtmp += but_width;
- y-=but_height + MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- reel_keys = edl_reel_keys()
-
-
-
- if reel_keys: text = 'Reel file list...'
- elif PREF['filename'].val == '': text = 'No EDL loaded.'
- else: text = 'No reels found!'
-
- Draw.Label(text, xtmp + MARGIN, y, but_width*4, but_height); xtmp += but_width*4;
-
- y-=but_height + MARGIN
- xtmp = x
-
- # ---------- ---------- ---------- ----------
-
-
- for i, reel_key in enumerate(reel_keys):
- reel_item = REEL_UI[reel_key]
-
- Blender.Draw.BeginAlign()
- REEL_UI[reel_key].filename_but = Draw.String(reel_item.ui_text, B_EVENT_NOP, xtmp, y, (but_width*3)-20, but_height, REEL_UI[reel_key].filename_but.val, 256, 'Select the reel path'); xtmp += (but_width*3)-20;
- Draw.PushButton('..', B_EVENT_FILESEL + i, xtmp, y, 20, but_height, 'Media path to use for this reel'); xtmp += 20;
- Blender.Draw.EndAlign()
-
- reel_item.offset_but= Draw.Number('ofs:', B_EVENT_NOP, xtmp + MARGIN, y, but_width - MARGIN, but_height, reel_item.offset_but.val, -100000, 100000, 'Start offset in frames when applying timecode'); xtmp += but_width - MARGIN;
-
- y-=but_height + MARGIN
- xtmp = x
-
- # ---------- ---------- ---------- ----------
-
- Draw.PushButton('Import CMX-EDL Sequencer Strips', B_EVENT_IMPORT, xtmp + MARGIN, MARGIN, but_width*4 - MARGIN, but_height, 'Load the EDL file into the sequencer'); xtmp += but_width*4;
- y-=but_height + MARGIN
- xtmp = x
-
-
-def edl_event(evt, val):
- pass
-
-def edl_bevent(evt):
-
- if evt == B_EVENT_NOP:
- pass
- elif evt == B_EVENT_IMPORT:
- '''
- Load the file into blender with UI settings
- '''
- filename = PREF['filename'].val
-
- reel_files = {}
- reel_offsets = {}
-
- for reel_key, reel_item in REEL_UI.iteritems():
- reel_files[reel_key] = reel_item.filename_but.val
- reel_offsets[reel_key] = reel_item.offset_but.val
-
- error = load_edl(filename, reel_files, reel_offsets)
- if error != '':
- Draw.PupMenu('Error%t|' + error)
- else:
- Window.RedrawAll()
-
- elif evt == B_EVENT_RELOAD:
- edl_reload()
- Draw.Redraw()
-
- elif evt == B_EVENT_FILESEL_EDL:
- filename = PREF['filename'].val
- if not filename: filename = Blender.sys.join(Blender.sys.expandpath('//'), '*.edl')
-
- Window.FileSelector(edl_set_path, 'Select EDL', filename)
-
- elif evt >= B_EVENT_FILESEL:
- reel_keys = edl_reel_keys()
- reel_key = reel_keys[evt - B_EVENT_FILESEL]
-
- filename = REEL_UI[reel_key].filename_but.val
- if not filename: filename = Blender.sys.expandpath('//')
-
- PREF['reel_act'] = reel_key # so file set path knows which one to set
- Window.FileSelector(edl_set_path_reel, 'Reel Media', filename)
-
-
-
-if __name__ == '__main__':
- Draw.Register(edl_draw, edl_event, edl_bevent)
- edl_reload()
-
diff --git a/release/scripts/import_lightwave_motion.py b/release/scripts/import_lightwave_motion.py
deleted file mode 100644
index 20c87dfd5c6..00000000000
--- a/release/scripts/import_lightwave_motion.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Lightwave Motion (.mot)...'
-Blender: 245
-Group: 'Import'
-Tip: 'Import Loc Rot Size chanels from a Lightwave .mot file'
-"""
-
-__author__ = "Daniel Salazar (ZanQdo)"
-__url__ = ("blender", "blenderartists.org",
-"e-mail: zanqdo@gmail.com")
-__version__ = "16/04/08"
-
-__bpydoc__ = """\
-This script loads Lightwave motion files (.mot)
-into the selected objects
-
-Usage:
-Run the script with one or more objects selected (any kind)
-Be sure to set the framerate correctly
-
-"""
-
-# $Id$
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2003, 2004: A Vanpoucke
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import math as M
-import Blender as B
-import bpy
-
-
-def FuncionPrincipal (Dir):
- B.Window.WaitCursor(1)
- ObjSelect = B.Object.GetSelected()
-
- if not ObjSelect:
- B.Draw.PupMenu('Select one or more objects, aborting.')
- return
-
-
- SC = B.Scene.GetCurrent()
- SCR = SC.getRenderingContext()
- FrameRate = float(SCR.framesPerSec())
-
-
- # Creating new IPO
-
- IPO = B.Ipo.New('Object', 'LW_Motion')
-
-
- # Creating Curves in the IPO
-
- LocX = IPO.addCurve("LocX")
- LocX.setInterpolation("Bezier")
-
- LocY = IPO.addCurve("LocY")
- LocX.setInterpolation("Bezier")
-
- LocZ = IPO.addCurve("LocZ")
- LocX.setInterpolation("Bezier")
-
- RotX = IPO.addCurve("RotX")
- LocX.setInterpolation("Bezier")
-
- RotY = IPO.addCurve("RotY")
- LocX.setInterpolation("Bezier")
-
- RotZ = IPO.addCurve("RotZ")
- LocX.setInterpolation("Bezier")
-
- ScaleX = IPO.addCurve("ScaleX")
- LocX.setInterpolation("Bezier")
-
- ScaleY = IPO.addCurve("ScaleY")
- LocX.setInterpolation("Bezier")
-
- ScaleZ = IPO.addCurve("ScaleZ")
- LocX.setInterpolation("Bezier")
-
-
- # Opening the mot file
-
- File = open (Dir, 'rU')
-
-
- # Init flags
-
- CurChannel = -1
- ScaleFlag = 0
-
- # Main file reading cycle
-
- for Line in File:
-
- '''
- # Number of channels in the file
-
- if "NumChannels" in Line:
- Line = Line.split (' ')
- NumChannels = int(Line[1])
- '''
-
- # Current Channel Flag
-
- if "Channel 0" in Line:
- CurChannel = 0
-
- elif "Channel 1" in Line:
- CurChannel = 1
-
- elif "Channel 2" in Line:
- CurChannel = 2
-
- elif "Channel 3" in Line:
- CurChannel = 3
-
- elif "Channel 4" in Line:
- CurChannel = 4
-
- elif "Channel 5" in Line:
- CurChannel = 5
-
- elif "Channel 6" in Line:
- CurChannel = 6
-
- elif "Channel 7" in Line:
- CurChannel = 7
-
- elif "Channel 8" in Line:
- CurChannel = 8
-
-
- # Getting the data and writing to IPOs
-
- if CurChannel == 0:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_0 = float (Line [3])
- TimeCh_0 = float (Line [4]) * FrameRate
- LocX.addBezier ((TimeCh_0, ValCh_0))
-
- if CurChannel == 1:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_1 = float (Line [3])
- TimeCh_1 = float (Line [4]) * FrameRate
- LocZ.addBezier ((TimeCh_1, ValCh_1))
-
- if CurChannel == 2:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_2 = float (Line [3])
- TimeCh_2 = float (Line [4]) * FrameRate
- LocY.addBezier ((TimeCh_2, ValCh_2))
-
- if CurChannel == 3:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_3 = M.degrees ( - float (Line [3]) ) / 10
- TimeCh_3 = float (Line [4]) * FrameRate
- RotZ.addBezier ((TimeCh_3, ValCh_3))
-
- if CurChannel == 4:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_4 = M.degrees ( - float (Line [3]) ) / 10
- TimeCh_4 = float (Line [4]) * FrameRate
- RotX.addBezier ((TimeCh_4, ValCh_4))
-
- if CurChannel == 5:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_5 = M.degrees ( - float (Line [3]) ) / 10
- TimeCh_5 = float (Line [4]) * FrameRate
- RotY.addBezier ((TimeCh_5, ValCh_5))
-
- if CurChannel == 6:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_6 = float (Line [3])
- TimeCh_6 = float (Line [4]) * FrameRate
- ScaleX.addBezier ((TimeCh_6, ValCh_6))
- elif ScaleFlag < 3:
- ScaleFlag += 1
- ScaleX.addBezier ((0, 1))
-
- if CurChannel == 7:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_7 = float (Line [3])
- TimeCh_7 = float (Line [4]) * FrameRate
- ScaleZ.addBezier ((TimeCh_7, ValCh_7))
- elif ScaleFlag < 3:
- ScaleFlag += 1
- ScaleZ.addBezier ((0, 1))
-
- if CurChannel == 8:
- if "Key" in Line:
- Line = Line.split (' ')
- ValCh_8 = float (Line [3])
- TimeCh_8 = float (Line [4]) * FrameRate
- ScaleY.addBezier ((TimeCh_8, ValCh_8))
- elif ScaleFlag < 3:
- ScaleFlag += 1
- ScaleY.addBezier ((0, 1))
-
-
- # Link the IPO to all selected objects
-
- for ob in ObjSelect:
- ob.setIpo(IPO)
-
- File.close()
-
- print '\nDone, the following motion file has been loaded:\n\n%s' % Dir
- B.Window.WaitCursor(0)
-
-def main():
- B.Window.FileSelector(FuncionPrincipal, "Load IPO from .mot File", B.sys.makename(ext='.mot'))
-
-if __name__=='__main__':
- main()
-
diff --git a/release/scripts/import_mdd.py b/release/scripts/import_mdd.py
deleted file mode 100644
index 1ee196ab67f..00000000000
--- a/release/scripts/import_mdd.py
+++ /dev/null
@@ -1,158 +0,0 @@
-#!BPY
-
-"""
- Name: 'Load MDD to Mesh RVKs'
- Blender: 242
- Group: 'Import'
- Tooltip: 'baked vertex animation to active mesh object.'
-"""
-__author__ = "Bill L.Nieuwendorp"
-__bpydoc__ = """\
-This script Imports Lightwaves MotionDesigner format.
-
-The .mdd format has become quite a popular Pipeline format<br>
-for moving animations from package to package.
-"""
-# mdd importer
-#
-# Warning if the vertex order or vertex count differs from the
-# origonal model the mdd was Baked out from their will be Strange
-# behavior
-#
-#
-#vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
-#A modifier to read mdd files would be Ideal but thats for another day :)
-#
-#Please send any fixes,updates,bugs to Slow67_at_Gmail.com
-#Bill Niewuendorp
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-
-
-
-try:
- from struct import unpack
-except:
- unpack = None
-
-import Blender
-from Blender import Mesh, Object, Scene
-import BPyMessages
-
-def mdd_import(filepath, ob, PREF_IPONAME, PREF_START_FRAME, PREF_JUMP):
-
- print '\n\nimporting mdd "%s"' % filepath
-
- Blender.Window.DrawProgressBar (0.0, "Importing mdd ...")
- Blender.Window.EditMode(0)
- Blender.Window.WaitCursor(1)
-
- file = open(filepath, 'rb')
- frames, points = unpack(">2i", file.read(8))
- time = unpack((">%df" % frames), file.read(frames * 4))
-
- print '\tpoints:%d frames:%d' % (points,frames)
-
- scn = Scene.GetCurrent()
- ctx = scn.getRenderingContext()
- Blender.Set("curframe", PREF_START_FRAME)
- me = ob.getData(mesh=1)
-
- def UpdateMesh(me,fr):
- for v in me.verts:
- # 12 is the size of 3 floats
- x,y,z= unpack('>3f', file.read(12))
- v.co[:] = x,z,y
- me.update()
-
- Blender.Window.DrawProgressBar (0.4, "4 Importing mdd ...")
-
-
- curfr = ctx.currentFrame()
- print'\twriting mdd data...'
- for i in xrange(frames):
- Blender.Set("curframe", i+PREF_START_FRAME)
- if len(me.verts) > 1 and (curfr >= PREF_START_FRAME) and (curfr <= PREF_START_FRAME+frames):
- UpdateMesh(me, i)
- ob.insertShapeKey()
-
- Blender.Window.DrawProgressBar (0.5, "5 Importing mdd ...")
-
- key= me.key
-
- # Add the key of its not there
- if not key:
- me.insertKey(1, 'relative')
- key= me.key
-
- key.ipo = Blender.Ipo.New('Key', PREF_IPONAME)
- ipo = key.ipo
- # block = key.getBlocks() # not used.
- all_keys = ipo.curveConsts
-
- for i in xrange(PREF_JUMP+1, len(all_keys), PREF_JUMP):
- curve = ipo.getCurve(i)
- if curve == None:
- curve = ipo.addCurve(all_keys[i])
-
- curve.append((PREF_START_FRAME+i-1,1))
- curve.append((PREF_START_FRAME+i- PREF_JUMP -1,0))
- curve.append((PREF_START_FRAME+i+ PREF_JUMP-1,0))
- curve.setInterpolation('Linear')
- curve.recalc()
-
- print 'done'
- Blender.Window.WaitCursor(0)
- Blender.Window.DrawProgressBar (1.0, '')
-
-
-def mdd_import_ui(filepath):
-
- if BPyMessages.Error_NoFile(filepath):
- return
-
- scn= Scene.GetCurrent()
- ob_act= scn.objects.active
-
- if ob_act == None or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- PREF_IPONAME = Blender.Draw.Create(filepath.split('/')[-1].split('\\')[-1].split('.')[0])
- PREF_START_FRAME = Blender.Draw.Create(1)
- PREF_JUMP = Blender.Draw.Create(1)
-
- block = [\
- ("Ipo Name: ", PREF_IPONAME, 0, 30, "Ipo name for the new shape key"),\
- ("Start Frame: ", PREF_START_FRAME, 1, 3000, "Start frame for the animation"),\
- ("Key Skip: ", PREF_JUMP, 1, 100, "KeyReduction, Skip every Nth Frame")\
- ]
-
- if not Blender.Draw.PupBlock("Import MDD", block):
- return
- orig_frame = Blender.Get('curframe')
- mdd_import(filepath, ob_act, PREF_IPONAME.val, PREF_START_FRAME.val, PREF_JUMP.val)
- Blender.Set('curframe', orig_frame)
-
-if __name__ == '__main__':
- if not unpack:
- Draw.PupMenu('Error%t|This script requires a full python install')
-
- Blender.Window.FileSelector(mdd_import_ui, 'IMPORT MDD', '*.mdd')
diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py
deleted file mode 100644
index a5547506dc7..00000000000
--- a/release/scripts/import_web3d.py
+++ /dev/null
@@ -1,2594 +0,0 @@
-#!BPY
-"""
-Name: 'X3D & VRML97 (.x3d / wrl)...'
-Blender: 248
-Group: 'Import'
-Tooltip: 'Load an X3D or VRML97 file'
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# (C) Copyright 2008 Paravizion
-# Written by Campbell Barton aka Ideasman42
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-__author__ = "Campbell Barton"
-__url__ = ['www.blender.org', 'blenderartists.org', 'http://wiki.blender.org/index.php/Scripts/Manual/Import/X3D_VRML97']
-__version__ = "0.1"
-
-__bpydoc__ = """\
-This script is an importer for the X3D and VRML97 file formats.
-"""
-
-DEBUG = False
-
-# This should work without a blender at all
-try:
- from Blender.sys import exists
-except:
- from os.path import exists
-
-def baseName(path):
- return path.split('/')[-1].split('\\')[-1]
-
-def dirName(path):
- return path[:-len(baseName(path))]
-
-def imageConvertCompat(path):
-
- try: import os
- except: return path
- if os.sep=='\\': return path # assime win32 has quicktime, dont convert
-
- if path.lower().endswith('.gif'):
- path_to = path[:-3] + 'png'
-
- '''
- if exists(path_to):
- return path_to
- '''
- # print '\n'+path+'\n'+path_to+'\n'
- os.system('convert "%s" "%s"' % (path, path_to)) # for now just hope we have image magick
-
- if exists(path_to):
- return path_to
-
- return path
-
-# notes
-# transform are relative
-# order dosnt matter for loc/size/rot
-# right handed rotation
-# angles are in radians
-# rotation first defines axis then ammount in radians
-
-
-
-# =============================== VRML Spesific
-
-
-def vrmlFormat(data):
- '''
- Keep this as a valid vrml file, but format in a way we can predict.
- '''
- # Strip all commends - # not in strings - warning multiline strings are ignored.
- def strip_comment(l):
- #l = ' '.join(l.split())
- l = l.strip()
-
- if l.startswith('#'):
- return ''
-
- i = l.find('#')
-
- if i==-1:
- return l
-
- # Most cases accounted for! if we have a comment at the end of the line do this...
- #j = l.find('url "')
- j = l.find('"')
-
- if j == -1: # simple no strings
- return l[:i].strip()
-
- q = False
- for i,c in enumerate(l):
- if c == '"':
- q = not q # invert
-
- elif c == '#':
- if q==False:
- return l[:i-1]
-
- return l
-
- data = '\n'.join([strip_comment(l) for l in data.split('\n') ]) # remove all whitespace
-
- EXTRACT_STRINGS = True # only needed when strings or filesnames containe ,[]{} chars :/
-
- if EXTRACT_STRINGS:
-
- # We need this so we can detect URL's
- data = '\n'.join([' '.join(l.split()) for l in data.split('\n')]) # remove all whitespace
-
- string_ls = []
-
- #search = 'url "'
- search = '"'
-
- ok = True
- last_i = 0
- while ok:
- ok = False
- i = data.find(search, last_i)
- if i != -1:
-
- start = i + len(search) # first char after end of search
- end = data.find('"', start)
- if end != -1:
- item = data[start:end]
- string_ls.append( item )
- data = data[:start] + data[end:]
- ok = True # keep looking
-
- last_i = (end - len(item)) + 1
- # print last_i, item, '|' + data[last_i] + '|'
-
- # done with messy extracting strings part
-
-
- # Bad, dont take strings into account
- '''
- data = data.replace('#', '\n#')
- data = '\n'.join([ll for l in data.split('\n') for ll in (l.strip(),) if not ll.startswith('#')]) # remove all whitespace
- '''
- data = data.replace('{', '\n{\n')
- data = data.replace('}', '\n}\n')
- data = data.replace('[', '\n[\n')
- data = data.replace(']', '\n]\n')
- data = data.replace(',', ' , ') # make sure comma's seperate
-
- if EXTRACT_STRINGS:
- # add strings back in
-
- search = '"' # fill in these empty strings
-
- ok = True
- last_i = 0
- while ok:
- ok = False
- i = data.find(search + '"', last_i)
- # print i
- if i != -1:
- start = i + len(search) # first char after end of search
- item = string_ls.pop(0)
- # print item
- data = data[:start] + item + data[start:]
-
- last_i = start + len(item) + 1
-
- ok = True
-
-
- # More annoying obscure cases where USE or DEF are placed on a newline
- # data = data.replace('\nDEF ', ' DEF ')
- # data = data.replace('\nUSE ', ' USE ')
-
- data = '\n'.join([' '.join(l.split()) for l in data.split('\n')]) # remove all whitespace
-
- # Better to parse the file accounting for multiline arrays
- '''
- data = data.replace(',\n', ' , ') # remove line endings with commas
- data = data.replace(']', '\n]\n') # very very annoying - but some comma's are at the end of the list, must run this again.
- '''
-
- return [l for l in data.split('\n') if l]
-
-NODE_NORMAL = 1 # {}
-NODE_ARRAY = 2 # []
-NODE_REFERENCE = 3 # USE foobar
-# NODE_PROTO = 4 #
-
-lines = []
-
-def getNodePreText(i, words):
- # print lines[i]
- use_node = False
- while len(words) < 5:
-
- if i>=len(lines):
- break
- '''
- elif lines[i].startswith('PROTO'):
- return NODE_PROTO, i+1
- '''
- elif lines[i]=='{':
- # words.append(lines[i]) # no need
- # print "OK"
- return NODE_NORMAL, i+1
- elif lines[i].count('"') % 2 != 0: # odd number of quotes? - part of a string.
- # print 'ISSTRING'
- break
- else:
- new_words = lines[i].split()
- if 'USE' in new_words:
- use_node = True
-
- words.extend(new_words)
- i += 1
-
- # Check for USE node - no {
- # USE #id - should always be on the same line.
- if use_node:
- # print 'LINE', i, words[:words.index('USE')+2]
- words[:] = words[:words.index('USE')+2]
- if lines[i] == '{' and lines[i+1] == '}':
- # USE sometimes has {} after it anyway
- i+=2
- return NODE_REFERENCE, i
-
- # print "error value!!!", words
- return 0, -1
-
-def is_nodeline(i, words):
-
- if not lines[i][0].isalpha():
- return 0, 0
-
- #if lines[i].startswith('field'):
- # return 0, 0
-
- # Is this a prototype??
- if lines[i].startswith('PROTO'):
- words[:] = lines[i].split()
- return NODE_NORMAL, i+1 # TODO - assumes the next line is a '[\n', skip that
- if lines[i].startswith('EXTERNPROTO'):
- words[:] = lines[i].split()
- return NODE_ARRAY, i+1 # TODO - assumes the next line is a '[\n', skip that
-
- '''
- proto_type, new_i = is_protoline(i, words, proto_field_defs)
- if new_i != -1:
- return proto_type, new_i
- '''
-
- # Simple "var [" type
- if lines[i+1] == '[':
- if lines[i].count('"') % 2 == 0:
- words[:] = lines[i].split()
- return NODE_ARRAY, i+2
-
- node_type, new_i = getNodePreText(i, words)
-
- if not node_type:
- if DEBUG: print "not node_type", lines[i]
- return 0, 0
-
- # Ok, we have a { after some values
- # Check the values are not fields
- for i, val in enumerate(words):
- if i != 0 and words[i-1] in ('DEF', 'USE'):
- # ignore anything after DEF, it is a ID and can contain any chars.
- pass
- elif val[0].isalpha() and val not in ('TRUE', 'FALSE'):
- pass
- else:
- # There is a number in one of the values, therefor we are not a node.
- return 0, 0
-
- #if node_type==NODE_REFERENCE:
- # print words, "REF_!!!!!!!"
- return node_type, new_i
-
-def is_numline(i):
- '''
- Does this line start with a number?
- '''
-
- # Works but too slow.
- '''
- l = lines[i]
- for w in l.split():
- if w==',':
- pass
- else:
- try:
- float(w)
- return True
-
- except:
- return False
-
- return False
- '''
-
- l = lines[i]
-
- line_start = 0
-
- if l.startswith(', '):
- line_start += 2
-
- line_end = len(l)-1
- line_end_new = l.find(' ', line_start) # comma's always have a space before them
-
- if line_end_new != -1:
- line_end = line_end_new
-
- try:
- float(l[line_start:line_end]) # works for a float or int
- return True
- except:
- return False
-
-
-class vrmlNode(object):
- __slots__ = 'id', 'fields', 'proto_node', 'proto_field_defs', 'proto_fields', 'node_type', 'parent', 'children', 'parent', 'array_data', 'reference', 'lineno', 'filename', 'blendObject', 'DEF_NAMESPACE', 'ROUTE_IPO_NAMESPACE', 'PROTO_NAMESPACE', 'x3dNode'
- def __init__(self, parent, node_type, lineno):
- self.id = None
- self.node_type = node_type
- self.parent = parent
- self.blendObject = None
- self.x3dNode = None # for x3d import only
- if parent:
- parent.children.append(self)
-
- self.lineno = lineno
-
- # This is only set from the root nodes.
- # Having a filename also denotes a root node
- self.filename = None
- self.proto_node = None # proto field definition eg: "field SFColor seatColor .6 .6 .1"
-
- # Store in the root node because each inline file needs its own root node and its own namespace
- self.DEF_NAMESPACE = None
- self.ROUTE_IPO_NAMESPACE = None
- '''
- self.FIELD_NAMESPACE = None
- '''
-
-
- self.PROTO_NAMESPACE = None
-
- self.reference = None
-
- if node_type==NODE_REFERENCE:
- # For references, only the parent and ID are needed
- # the reference its self is assigned on parsing
- return
-
- self.fields = [] # fields have no order, in some cases rool level values are not unique so dont use a dict
-
- self.proto_field_defs = [] # proto field definition eg: "field SFColor seatColor .6 .6 .1"
- self.proto_fields = [] # proto field usage "diffuseColor IS seatColor"
- self.children = []
- self.array_data = [] # use for arrays of data - should only be for NODE_ARRAY types
-
-
- # Only available from the root node
- '''
- def getFieldDict(self):
- if self.FIELD_NAMESPACE != None:
- return self.FIELD_NAMESPACE
- else:
- return self.parent.getFieldDict()
- '''
- def getProtoDict(self):
- if self.PROTO_NAMESPACE != None:
- return self.PROTO_NAMESPACE
- else:
- return self.parent.getProtoDict()
-
- def getDefDict(self):
- if self.DEF_NAMESPACE != None:
- return self.DEF_NAMESPACE
- else:
- return self.parent.getDefDict()
-
- def getRouteIpoDict(self):
- if self.ROUTE_IPO_NAMESPACE != None:
- return self.ROUTE_IPO_NAMESPACE
- else:
- return self.parent.getRouteIpoDict()
-
- def setRoot(self, filename):
- self.filename = filename
- # self.FIELD_NAMESPACE = {}
- self.DEF_NAMESPACE = {}
- self.ROUTE_IPO_NAMESPACE = {}
- self.PROTO_NAMESPACE = {}
-
- def isRoot(self):
- if self.filename == None:
- return False
- else:
- return True
-
- def getFilename(self):
- if self.filename:
- return self.filename
- elif self.parent:
- return self.parent.getFilename()
- else:
- return None
-
- def getRealNode(self):
- if self.reference:
- return self.reference
- else:
- return self
-
- def getSpec(self):
- self_real = self.getRealNode()
- try:
- return self_real.id[-1] # its possible this node has no spec
- except:
- return None
-
- def findSpecRecursive(self, spec):
- self_real = self.getRealNode()
- if spec == self_real.getSpec():
- return self
-
- for child in self_real.children:
- if child.findSpecRecursive(spec):
- return child
-
- return None
-
- def getPrefix(self):
- if self.id:
- return self.id[0]
- return None
-
- def getSpecialTypeName(self, typename):
- self_real = self.getRealNode()
- try: return self_real.id[ list(self_real.id).index(typename)+1 ]
- except: return None
-
-
- def getDefName(self):
- return self.getSpecialTypeName('DEF')
-
- def getProtoName(self):
- return self.getSpecialTypeName('PROTO')
-
- def getExternprotoName(self):
- return self.getSpecialTypeName('EXTERNPROTO')
-
- def getChildrenBySpec(self, node_spec): # spec could be Transform, Shape, Appearance
- self_real = self.getRealNode()
- # using getSpec functions allows us to use the spec of USE children that dont have their spec in their ID
- if type(node_spec) == str:
- return [child for child in self_real.children if child.getSpec()==node_spec]
- else:
- # Check inside a list of optional types
- return [child for child in self_real.children if child.getSpec() in node_spec]
-
- def getChildBySpec(self, node_spec): # spec could be Transform, Shape, Appearance
- # Use in cases where there is only ever 1 child of this type
- ls = self.getChildrenBySpec(node_spec)
- if ls: return ls[0]
- else: return None
-
- def getChildrenByName(self, node_name): # type could be geometry, children, appearance
- self_real = self.getRealNode()
- return [child for child in self_real.children if child.id if child.id[0]==node_name]
-
- def getChildByName(self, node_name):
- self_real = self.getRealNode()
- for child in self_real.children:
- if child.id and child.id[0]==node_name: # and child.id[-1]==node_spec:
- return child
-
- def getSerialized(self, results, ancestry):
- ''' Return this node and all its children in a flat list '''
- ancestry = ancestry[:] # always use a copy
-
- # self_real = self.getRealNode()
-
- results.append((self, tuple(ancestry)))
- ancestry.append(self)
- for child in self.getRealNode().children:
- if child not in ancestry:
- # We dont want to load proto's, they are only references
- # We could enforce this elsewhere
-
- # Only add this in a very special case
- # where the parent of this object is not the real parent
- # - In this case we have added the proto as a child to a node instancing it.
- # This is a bit arbitary, but its how Proto's are done with this importer.
- if child.getProtoName() == None and child.getExternprotoName() == None:
- child.getSerialized(results, ancestry)
- else:
-
- if DEBUG: print 'getSerialized() is proto:', child.getProtoName(), child.getExternprotoName(), self.getSpec()
-
- self_spec = self.getSpec()
-
- if child.getProtoName() == self_spec or child.getExternprotoName() == self_spec:
- if DEBUG: "FoundProto!"
- child.getSerialized(results, ancestry)
-
-
-
- return results
-
- def searchNodeTypeID(self, node_spec, results):
- self_real = self.getRealNode()
- # print self.lineno, self.id
- if self_real.id and self_real.id[-1]==node_spec: # use last element, could also be only element
- results.append(self_real)
- for child in self_real.children:
- child.searchNodeTypeID(node_spec, results)
- return results
-
- def getFieldName(self, field, ancestry, AS_CHILD=False):
- self_real = self.getRealNode() # incase we're an instance
-
- for f in self_real.fields:
- # print f
- if f and f[0] == field:
- # print '\tfound field', f
-
- if len(f)>=3 and f[1] == 'IS': # eg: 'diffuseColor IS legColor'
- field_id = f[2]
-
- # print "\n\n\n\n\n\nFOND IS!!!"
- f_proto_lookup = None
- f_proto_child_lookup = None
- i = len(ancestry)
- while i:
- i -= 1
- node = ancestry[i]
- node = node.getRealNode()
-
- # proto settings are stored in "self.proto_node"
- if node.proto_node:
- # Get the default value from the proto, this can be overwridden by the proto instace
- # 'field SFColor legColor .8 .4 .7'
- if AS_CHILD:
- for child in node.proto_node.children:
- #if child.id and len(child.id) >= 3 and child.id[2]==field_id:
- if child.id and ('point' in child.id or 'points' in child.id):
- f_proto_child_lookup = child
-
- else:
- for f_def in node.proto_node.proto_field_defs:
- if len(f_def) >= 4:
- if f_def[0]=='field' and f_def[2]==field_id:
- f_proto_lookup = f_def[3:]
-
- # Node instance, Will be 1 up from the proto-node in the ancestry list. but NOT its parent.
- # This is the setting as defined by the instance, including this setting is optional,
- # and will override the default PROTO value
- # eg: 'legColor 1 0 0'
- if AS_CHILD:
- for child in node.children:
- if child.id and child.id[0]==field_id:
- f_proto_child_lookup = child
- else:
- for f_def in node.fields:
- if len(f_def) >= 2:
- if f_def[0]==field_id:
- if DEBUG: print "getFieldName(), found proto", f_def
- f_proto_lookup = f_def[1:]
-
-
- if AS_CHILD:
- if f_proto_child_lookup:
- if DEBUG:
- print "getFieldName() - AS_CHILD=True, child found"
- print f_proto_child_lookup
- return f_proto_child_lookup
- else:
- return f_proto_lookup
- else:
- if AS_CHILD:
- return None
- else:
- # Not using a proto
- return f[1:]
-
- # print '\tfield not found', field
-
-
- # See if this is a proto name
- if AS_CHILD:
- child_array = None
- for child in self_real.children:
- if child.id and len(child.id) == 1 and child.id[0] == field:
- return child
-
- return None
-
- def getFieldAsInt(self, field, default, ancestry):
- self_real = self.getRealNode() # incase we're an instance
-
- f = self_real.getFieldName(field, ancestry)
- if f==None: return default
- if ',' in f: f = f[:f.index(',')] # strip after the comma
-
- if len(f) != 1:
- print '\t"%s" wrong length for int conversion for field "%s"' % (f, field)
- return default
-
- try:
- return int(f[0])
- except:
- print '\tvalue "%s" could not be used as an int for field "%s"' % (f[0], field)
- return default
-
- def getFieldAsFloat(self, field, default, ancestry):
- self_real = self.getRealNode() # incase we're an instance
-
- f = self_real.getFieldName(field, ancestry)
- if f==None: return default
- if ',' in f: f = f[:f.index(',')] # strip after the comma
-
- if len(f) != 1:
- print '\t"%s" wrong length for float conversion for field "%s"' % (f, field)
- return default
-
- try:
- return float(f[0])
- except:
- print '\tvalue "%s" could not be used as a float for field "%s"' % (f[0], field)
- return default
-
- def getFieldAsFloatTuple(self, field, default, ancestry):
- self_real = self.getRealNode() # incase we're an instance
-
- f = self_real.getFieldName(field, ancestry)
- if f==None: return default
- # if ',' in f: f = f[:f.index(',')] # strip after the comma
-
- if len(f) < 1:
- print '"%s" wrong length for float tuple conversion for field "%s"' % (f, field)
- return default
-
- ret = []
- for v in f:
- if v != ',':
- try: ret.append(float(v))
- except: break # quit of first non float, perhaps its a new field name on the same line? - if so we are going to ignore it :/ TODO
- # print ret
-
- if ret:
- return ret
- if not ret:
- print '\tvalue "%s" could not be used as a float tuple for field "%s"' % (f, field)
- return default
-
- def getFieldAsBool(self, field, default, ancestry):
- self_real = self.getRealNode() # incase we're an instance
-
- f = self_real.getFieldName(field, ancestry)
- if f==None: return default
- if ',' in f: f = f[:f.index(',')] # strip after the comma
-
- if len(f) != 1:
- print '\t"%s" wrong length for bool conversion for field "%s"' % (f, field)
- return default
-
- if f[0].upper()=='"TRUE"' or f[0].upper()=='TRUE':
- return True
- elif f[0].upper()=='"FALSE"' or f[0].upper()=='FALSE':
- return False
- else:
- print '\t"%s" could not be used as a bool for field "%s"' % (f[1], field)
- return default
-
- def getFieldAsString(self, field, default, ancestry):
- self_real = self.getRealNode() # incase we're an instance
-
- f = self_real.getFieldName(field, ancestry)
- if f==None: return default
- if len(f) < 1:
- print '\t"%s" wrong length for string conversion for field "%s"' % (f, field)
- return default
-
- if len(f) > 1:
- # String may contain spaces
- st = ' '.join(f)
- else:
- st = f[0]
-
- # X3D HACK
- if self.x3dNode:
- return st
-
- if st[0]=='"' and st[-1]=='"':
- return st[1:-1]
- else:
- print '\tvalue "%s" could not be used as a string for field "%s"' % (f[0], field)
- return default
-
- def getFieldAsArray(self, field, group, ancestry):
- '''
- For this parser arrays are children
- '''
- self_real = self.getRealNode() # incase we're an instance
-
- child_array = self_real.getFieldName(field, ancestry, True)
-
- #if type(child_array)==list: # happens occasionaly
- # array_data = child_array
-
- if child_array==None:
-
- # For x3d, should work ok with vrml too
- # for x3d arrays are fields, vrml they are nodes, annoying but not tooo bad.
- data_split = self.getFieldName(field, ancestry)
- if not data_split:
- return []
- array_data = ' '.join(data_split)
- if array_data == None:
- return []
-
- array_data = array_data.replace(',', ' ')
- data_split = array_data.split()
- try:
- array_data = [int(val) for val in data_split]
- except:
- try:
- array_data = [float(val) for val in data_split]
- except:
- print '\tWarning, could not parse array data from field'
- array_data = []
- else:
- # print child_array
- # Normal vrml
- array_data = child_array.array_data
-
-
- # print 'array_data', array_data
-
- if group==-1 or len(array_data)==0:
- return array_data
-
- # We want a flat list
- flat = True
- for item in array_data:
- if type(item) == list:
- flat = False
- break
-
- # make a flat array
- if flat:
- flat_array = array_data # we are alredy flat.
- else:
- flat_array = []
-
- def extend_flat(ls):
- for item in ls:
- if type(item)==list: extend_flat(item)
- else: flat_array.append(item)
-
- extend_flat(array_data)
-
-
- # We requested a flat array
- if group == 0:
- return flat_array
-
- new_array = []
- sub_array = []
-
- for item in flat_array:
- sub_array.append(item)
- if len(sub_array)==group:
- new_array.append(sub_array)
- sub_array = []
-
- if sub_array:
- print '\twarning, array was not aligned to requested grouping', group, 'remaining value', sub_array
-
- return new_array
-
- def getFieldAsStringArray(self, field, ancestry):
- '''
- Get a list of strings
- '''
- self_real = self.getRealNode() # incase we're an instance
-
- child_array = None
- for child in self_real.children:
- if child.id and len(child.id) == 1 and child.id[0] == field:
- child_array = child
- break
- if not child_array:
- return []
-
- # each string gets its own list, remove ""'s
- try:
- new_array = [f[0][1:-1] for f in child_array.fields]
- except:
- print '\twarning, string array could not be made'
- new_array = []
-
- return new_array
-
-
- def getLevel(self):
- # Ignore self_real
- level = 0
- p = self.parent
- while p:
- level +=1
- p = p.parent
- if not p: break
-
- return level
-
- def __repr__(self):
- level = self.getLevel()
- ind = ' ' * level
- if self.node_type==NODE_REFERENCE:
- brackets = ''
- elif self.node_type==NODE_NORMAL:
- brackets = '{}'
- else:
- brackets = '[]'
-
- if brackets:
- text = ind + brackets[0] + '\n'
- else:
- text = ''
-
- text += ind + 'ID: ' + str(self.id) + ' ' + str(level) + (' lineno %d\n' % self.lineno)
-
- if self.node_type==NODE_REFERENCE:
- text += ind + "(reference node)\n"
- return text
-
- if self.proto_node:
- text += ind + 'PROTO NODE...\n'
- text += str(self.proto_node)
- text += ind + 'PROTO NODE_DONE\n'
-
- text += ind + 'FIELDS:' + str(len(self.fields)) + '\n'
-
- for i,item in enumerate(self.fields):
- text += ind + 'FIELD:\n'
- text += ind + str(item) +'\n'
-
- text += ind + 'PROTO_FIELD_DEFS:' + str(len(self.proto_field_defs)) + '\n'
-
- for i,item in enumerate(self.proto_field_defs):
- text += ind + 'PROTO_FIELD:\n'
- text += ind + str(item) +'\n'
-
- text += ind + 'ARRAY: ' + str(len(self.array_data)) + ' ' + str(self.array_data) + '\n'
- #text += ind + 'ARRAY: ' + str(len(self.array_data)) + '[...] \n'
-
- text += ind + 'CHILDREN: ' + str(len(self.children)) + '\n'
- for i, child in enumerate(self.children):
- text += ind + ('CHILD%d:\n' % i)
- text += str(child)
-
- text += '\n' + ind + brackets[1]
-
- return text
-
- def parse(self, i, IS_PROTO_DATA=False):
- new_i = self.__parse(i, IS_PROTO_DATA)
-
- # print self.id, self.getFilename()
-
- # Check if this node was an inline or externproto
-
- url_ls = []
-
- if self.node_type == NODE_NORMAL and self.getSpec() == 'Inline':
- ancestry = [] # Warning! - PROTO's using this wont work at all.
- url = self.getFieldAsString('url', None, ancestry)
- if url:
- url_ls = [(url, None)]
- del ancestry
-
- elif self.getExternprotoName():
- # externproto
- url_ls = []
- for f in self.fields:
-
- if type(f)==str:
- f = [f]
-
- for ff in f:
- for f_split in ff.split('"'):
- # print f_split
- # "someextern.vrml#SomeID"
- if '#' in f_split:
-
- f_split, f_split_id = f_split.split('#') # there should only be 1 # anyway
-
- url_ls.append( (f_split, f_split_id) )
- else:
- url_ls.append( (f_split, None) )
-
-
- # Was either an Inline or an EXTERNPROTO
- if url_ls:
-
- # print url_ls
-
- for url, extern_key in url_ls:
- print url
- urls = []
- urls.append( url )
- urls.append( BPySys.caseInsensitivePath(urls[-1]) )
-
- urls.append( dirName(self.getFilename()) + url )
- urls.append( BPySys.caseInsensitivePath(urls[-1]) )
-
- urls.append( dirName(self.getFilename()) + baseName(url) )
- urls.append( BPySys.caseInsensitivePath(urls[-1]) )
-
- try:
- url = [url for url in urls if exists(url)][0]
- url_found = True
- except:
- url_found = False
-
- if not url_found:
- print '\tWarning: Inline URL could not be found:', url
- else:
- if url==self.getFilename():
- print '\tWarning: cant Inline yourself recursively:', url
- else:
-
- try:
- data = gzipOpen(url)
- except:
- print '\tWarning: cant open the file:', url
- data = None
-
- if data:
- # Tricky - inline another VRML
- print '\tLoading Inline:"%s"...' % url
-
- # Watch it! - backup lines
- lines_old = lines[:]
-
-
- lines[:] = vrmlFormat( data )
-
- lines.insert(0, '{')
- lines.insert(0, 'root_node____')
- lines.append('}')
- '''
- ff = open('/tmp/test.txt', 'w')
- ff.writelines([l+'\n' for l in lines])
- '''
-
- child = vrmlNode(self, NODE_NORMAL, -1)
- child.setRoot(url) # initialized dicts
- child.parse(0)
-
- # if self.getExternprotoName():
- if self.getExternprotoName():
- if not extern_key: # if none is spesified - use the name
- extern_key = self.getSpec()
-
- if extern_key:
-
- self.children.remove(child)
- child.parent = None
-
- extern_child = child.findSpecRecursive(extern_key)
-
- if extern_child:
- self.children.append(extern_child)
- extern_child.parent = self
-
- if DEBUG: print "\tEXTERNPROTO ID found!:", extern_key
- else:
- print "\tEXTERNPROTO ID not found!:", extern_key
-
- # Watch it! - restore lines
- lines[:] = lines_old
-
- return new_i
-
- def __parse(self, i, IS_PROTO_DATA=False):
- '''
- print 'parsing at', i,
- print i, self.id, self.lineno
- '''
- l = lines[i]
-
- if l=='[':
- # An anonymous list
- self.id = None
- i+=1
- else:
- words = []
-
- node_type, new_i = is_nodeline(i, words)
- if not node_type: # fail for parsing new node.
- print "Failed to parse new node"
- raise ValueError
-
- if self.node_type==NODE_REFERENCE:
- # Only assign the reference and quit
- key = words[words.index('USE')+1]
- self.id = (words[0],)
-
- self.reference = self.getDefDict()[key]
- return new_i
-
- self.id = tuple(words)
-
- # fill in DEF/USE
- key = self.getDefName()
- if key != None:
- self.getDefDict()[ key ] = self
-
- key = self.getProtoName()
- if not key: key = self.getExternprotoName()
-
- proto_dict = self.getProtoDict()
- if key != None:
- proto_dict[ key ] = self
-
- # Parse the proto nodes fields
- self.proto_node = vrmlNode(self, NODE_ARRAY, new_i)
- new_i = self.proto_node.parse(new_i)
-
- self.children.remove(self.proto_node)
-
- # print self.proto_node
-
- new_i += 1 # skip past the {
-
-
- else: # If we're a proto instance, add the proto node as our child.
- spec = self.getSpec()
- try:
- self.children.append( proto_dict[spec] )
- #pass
- except:
- pass
-
- del spec
-
- del proto_dict, key
-
- i = new_i
-
- # print self.id
- ok = True
- while ok:
- if i>=len(lines):
- return len(lines)-1
-
- l = lines[i]
- # print '\tDEBUG:', i, self.node_type, l
- if l=='':
- i+=1
- continue
-
- if l=='}':
- if self.node_type != NODE_NORMAL: # also ends proto nodes, we may want a type for these too.
- print 'wrong node ending, expected an } ' + str(i) + ' ' + str(self.node_type)
- if DEBUG:
- raise ValueError
- ### print "returning", i
- return i+1
- if l==']':
- if self.node_type != NODE_ARRAY:
- print 'wrong node ending, expected a ] ' + str(i) + ' ' + str(self.node_type)
- if DEBUG:
- raise ValueError
- ### print "returning", i
- return i+1
-
- node_type, new_i = is_nodeline(i, [])
- if node_type: # check text\n{
- child = vrmlNode(self, node_type, i)
- i = child.parse(i)
-
- elif l=='[': # some files have these anonymous lists
- child = vrmlNode(self, NODE_ARRAY, i)
- i = child.parse(i)
-
- elif is_numline(i):
- l_split = l.split(',')
-
- values = None
- # See if each item is a float?
-
- for num_type in (int, float):
- try:
- values = [num_type(v) for v in l_split ]
- break
- except:
- pass
-
-
- try:
- values = [[num_type(v) for v in segment.split()] for segment in l_split ]
- break
- except:
- pass
-
- if values == None: # dont parse
- values = l_split
-
- # This should not extend over multiple lines however it is possible
- # print self.array_data
- if values:
- self.array_data.extend( values )
- i+=1
- else:
- words = l.split()
- if len(words) > 2 and words[1] == 'USE':
- vrmlNode(self, NODE_REFERENCE, i)
- else:
-
- # print "FIELD", i, l
- #
- #words = l.split()
- ### print '\t\ttag', i
- # this is a tag/
- # print words, i, l
- value = l
- # print i
- # javastrips can exist as values.
- quote_count = l.count('"')
- if quote_count % 2: # odd number?
- # print 'MULTILINE'
- while 1:
- i+=1
- l = lines[i]
- quote_count = l.count('"')
- if quote_count % 2: # odd number?
- value += '\n'+ l[:l.rfind('"')]
- break # assume
- else:
- value += '\n'+ l
-
- value_all = value.split()
-
- def iskey(k):
- if k[0] != '"' and k[0].isalpha() and k.upper() not in ('TRUE', 'FALSE'):
- return True
- return False
-
- def split_fields(value):
- '''
- key 0.0 otherkey 1,2,3 opt1 opt1 0.0
- -> [key 0.0], [otherkey 1,2,3], [opt1 opt1 0.0]
- '''
- field_list = []
- field_context = []
-
- for j in xrange(len(value)):
- if iskey(value[j]):
- if field_context:
- # this IS a key but the previous value was not a key, ot it was a defined field.
- if (not iskey(field_context[-1])) or ((len(field_context)==3 and field_context[1]=='IS')):
- field_list.append(field_context)
-
- field_context = [value[j]]
- else:
- # The last item was not a value, multiple keys are needed in some cases.
- field_context.append(value[j])
- else:
- # Is empty, just add this on
- field_context.append(value[j])
- else:
- # Add a value to the list
- field_context.append(value[j])
-
- if field_context:
- field_list.append(field_context)
-
- return field_list
-
-
- for value in split_fields(value_all):
- # Split
-
- if value[0]=='field':
- # field SFFloat creaseAngle 4
- self.proto_field_defs.append(value)
- else:
- self.fields.append(value)
- i+=1
-
-def gzipOpen(path):
- try: import gzip
- except: gzip = None
-
- data = None
- if gzip:
- try: data = gzip.open(path, 'r').read()
- except: pass
- else:
- print '\tNote, gzip module could not be imported, compressed files will fail to load'
-
- if data==None:
- try: data = open(path, 'rU').read()
- except: pass
-
- return data
-
-def vrml_parse(path):
- '''
- Sets up the root node and returns it so load_web3d() can deal with the blender side of things.
- Return root (vrmlNode, '') or (None, 'Error String')
- '''
- data = gzipOpen(path)
-
- if data==None:
- return None, 'Failed to open file: ' + path
-
- # Stripped above
- lines[:] = vrmlFormat( data )
-
- lines.insert(0, '{')
- lines.insert(0, 'dymmy_node')
- lines.append('}')
- # Use for testing our parsed output, so we can check on line numbers.
-
- '''
- ff = open('/tmp/test.txt', 'w')
- ff.writelines([l+'\n' for l in lines])
- ff.close()
- '''
-
- # Now evaluate it
- node_type, new_i = is_nodeline(0, [])
- if not node_type:
- return None, 'Error: VRML file has no starting Node'
-
- # Trick to make sure we get all root nodes.
- lines.insert(0, '{')
- lines.insert(0, 'root_node____') # important the name starts with an ascii char
- lines.append('}')
-
- root = vrmlNode(None, NODE_NORMAL, -1)
- root.setRoot(path) # we need to set the root so we have a namespace and know the path incase of inlineing
-
- # Parse recursively
- root.parse(0)
-
- # This prints a load of text
- if DEBUG:
- print root
-
- return root, ''
-
-
-# ====================== END VRML
-
-
-
-# ====================== X3d Support
-
-# Sane as vrml but replace the parser
-class x3dNode(vrmlNode):
- def __init__(self, parent, node_type, x3dNode):
- vrmlNode.__init__(self, parent, node_type, -1)
- self.x3dNode = x3dNode
-
- def parse(self, IS_PROTO_DATA=False):
- # print self.x3dNode.tagName
-
- define = self.x3dNode.getAttributeNode('DEF')
- if define:
- self.getDefDict()[define.value] = self
- else:
- use = self.x3dNode.getAttributeNode('USE')
- if use:
- try:
- self.reference = self.getDefDict()[use.value]
- self.node_type = NODE_REFERENCE
- except:
- print '\tWarning: reference', use.value, 'not found'
- self.parent.children.remove(self)
-
- return
-
- for x3dChildNode in self.x3dNode.childNodes:
- if x3dChildNode.nodeType in (x3dChildNode.TEXT_NODE, x3dChildNode.COMMENT_NODE, x3dChildNode.CDATA_SECTION_NODE):
- continue
-
- node_type = NODE_NORMAL
- # print x3dChildNode, dir(x3dChildNode)
- if x3dChildNode.getAttributeNode('USE'):
- node_type = NODE_REFERENCE
-
- child = x3dNode(self, node_type, x3dChildNode)
- child.parse()
-
- # TODO - x3d Inline
-
- def getSpec(self):
- return self.x3dNode.tagName # should match vrml spec
-
- def getDefName(self):
- data = self.x3dNode.getAttributeNode('DEF')
- if data: data.value
- return None
-
- # Other funcs operate from vrml, but this means we can wrap XML fields, still use nice utility funcs
- # getFieldAsArray getFieldAsBool etc
- def getFieldName(self, field, ancestry, AS_CHILD=False):
- # ancestry and AS_CHILD are ignored, only used for VRML now
-
- self_real = self.getRealNode() # incase we're an instance
- field_xml = self.x3dNode.getAttributeNode(field)
- if field_xml:
- value = field_xml.value
-
- # We may want to edit. for x3d spesific stuff
- # Sucks a bit to return the field name in the list but vrml excepts this :/
- return value.split()
- else:
- return None
-
-def x3d_parse(path):
- '''
- Sets up the root node and returns it so load_web3d() can deal with the blender side of things.
- Return root (x3dNode, '') or (None, 'Error String')
- '''
-
- try:
- import xml.dom.minidom
- except:
- return None, 'Error, import XML parsing module (xml.dom.minidom) failed, install python'
-
- '''
- try: doc = xml.dom.minidom.parse(path)
- except: return None, 'Could not parse this X3D file, XML error'
- '''
-
- # Could add a try/except here, but a console error is more useful.
- data = gzipOpen(path)
-
- if data==None:
- return None, 'Failed to open file: ' + path
-
- doc = xml.dom.minidom.parseString(data)
-
-
- try:
- x3dnode = doc.getElementsByTagName('X3D')[0]
- except:
- return None, 'Not a valid x3d document, cannot import'
-
- root = x3dNode(None, NODE_NORMAL, x3dnode)
- root.setRoot(path) # so images and Inline's we load have a relative path
- root.parse()
-
- return root, ''
-
-
-
-## f = open('/_Cylinder.wrl', 'r')
-# f = open('/fe/wrl/Vrml/EGS/TOUCHSN.WRL', 'r')
-# vrml_parse('/fe/wrl/Vrml/EGS/TOUCHSN.WRL')
-#vrml_parse('/fe/wrl/Vrml/EGS/SCRIPT.WRL')
-'''
-
-import os
-files = os.popen('find /fe/wrl -iname "*.wrl"').readlines()
-files.sort()
-tot = len(files)
-for i, f in enumerate(files):
- #if i < 801:
- # continue
-
- f = f.strip()
- print f, i, tot
- vrml_parse(f)
-'''
-
-# NO BLENDER CODE ABOVE THIS LINE.
-# -----------------------------------------------------------------------------------
-import bpy
-import BPyImage
-import BPySys
-reload(BPySys)
-reload(BPyImage)
-import Blender
-from Blender import Texture, Material, Mathutils, Mesh, Types, Window
-from Blender.Mathutils import TranslationMatrix
-from Blender.Mathutils import RotationMatrix
-from Blender.Mathutils import Vector
-from Blender.Mathutils import Matrix
-
-RAD_TO_DEG = 57.29578
-
-GLOBALS = {'CIRCLE_DETAIL':16}
-
-def translateRotation(rot):
- ''' axis, angle '''
- return RotationMatrix(rot[3]*RAD_TO_DEG, 4, 'r', Vector(rot[:3]))
-
-def translateScale(sca):
- mat = Matrix() # 4x4 default
- mat[0][0] = sca[0]
- mat[1][1] = sca[1]
- mat[2][2] = sca[2]
- return mat
-
-def translateTransform(node, ancestry):
- cent = node.getFieldAsFloatTuple('center', None, ancestry) # (0.0, 0.0, 0.0)
- rot = node.getFieldAsFloatTuple('rotation', None, ancestry) # (0.0, 0.0, 1.0, 0.0)
- sca = node.getFieldAsFloatTuple('scale', None, ancestry) # (1.0, 1.0, 1.0)
- scaori = node.getFieldAsFloatTuple('scaleOrientation', None, ancestry) # (0.0, 0.0, 1.0, 0.0)
- tx = node.getFieldAsFloatTuple('translation', None, ancestry) # (0.0, 0.0, 0.0)
-
- if cent:
- cent_mat = TranslationMatrix(Vector(cent)).resize4x4()
- cent_imat = cent_mat.copy().invert()
- else:
- cent_mat = cent_imat = None
-
- if rot: rot_mat = translateRotation(rot)
- else: rot_mat = None
-
- if sca: sca_mat = translateScale(sca)
- else: sca_mat = None
-
- if scaori:
- scaori_mat = translateRotation(scaori)
- scaori_imat = scaori_mat.copy().invert()
- else:
- scaori_mat = scaori_imat = None
-
- if tx: tx_mat = TranslationMatrix(Vector(tx)).resize4x4()
- else: tx_mat = None
-
- new_mat = Matrix()
-
- mats = [tx_mat, cent_mat, rot_mat, scaori_mat, sca_mat, scaori_imat, cent_imat]
- for mtx in mats:
- if mtx:
- new_mat = mtx * new_mat
-
- return new_mat
-
-def translateTexTransform(node, ancestry):
- cent = node.getFieldAsFloatTuple('center', None, ancestry) # (0.0, 0.0)
- rot = node.getFieldAsFloat('rotation', None, ancestry) # 0.0
- sca = node.getFieldAsFloatTuple('scale', None, ancestry) # (1.0, 1.0)
- tx = node.getFieldAsFloatTuple('translation', None, ancestry) # (0.0, 0.0)
-
-
- if cent:
- # cent is at a corner by default
- cent_mat = TranslationMatrix(Vector(cent).resize3D()).resize4x4()
- cent_imat = cent_mat.copy().invert()
- else:
- cent_mat = cent_imat = None
-
- if rot: rot_mat = RotationMatrix(rot*RAD_TO_DEG, 4, 'z') # translateRotation(rot)
- else: rot_mat = None
-
- if sca: sca_mat = translateScale((sca[0], sca[1], 0.0))
- else: sca_mat = None
-
- if tx: tx_mat = TranslationMatrix(Vector(tx).resize3D()).resize4x4()
- else: tx_mat = None
-
- new_mat = Matrix()
-
- # as specified in VRML97 docs
- mats = [cent_imat, sca_mat, rot_mat, cent_mat, tx_mat]
-
- for mtx in mats:
- if mtx:
- new_mat = mtx * new_mat
-
- return new_mat
-
-
-
-def getFinalMatrix(node, mtx, ancestry):
-
- transform_nodes = [node_tx for node_tx in ancestry if node_tx.getSpec() == 'Transform']
- if node.getSpec()=='Transform':
- transform_nodes.append(node)
- transform_nodes.reverse()
-
- if mtx==None:
- mtx = Matrix()
-
- for node_tx in transform_nodes:
- mat = translateTransform(node_tx, ancestry)
- mtx = mtx * mat
-
- return mtx
-
-def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
- # print geom.lineno, geom.id, vrmlNode.DEF_NAMESPACE.keys()
-
- ccw = geom.getFieldAsBool('ccw', True, ancestry)
- ifs_colorPerVertex = geom.getFieldAsBool('colorPerVertex', True, ancestry) # per vertex or per face
- ifs_normalPerVertex = geom.getFieldAsBool('normalPerVertex', True, ancestry)
-
- # This is odd how point is inside Coordinate
-
- # VRML not x3d
- #coord = geom.getChildByName('coord') # 'Coordinate'
-
- coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml
-
- if coord: ifs_points = coord.getFieldAsArray('point', 3, ancestry)
- else: coord = []
-
- if not coord:
- print '\tWarnint: IndexedFaceSet has no points'
- return None, ccw
-
- ifs_faces = geom.getFieldAsArray('coordIndex', 0, ancestry)
-
- coords_tex = None
- if ifs_faces: # In rare cases this causes problems - no faces but UVs???
-
- # WORKS - VRML ONLY
- # coords_tex = geom.getChildByName('texCoord')
- coords_tex = geom.getChildBySpec('TextureCoordinate')
-
- if coords_tex:
- ifs_texpoints = coords_tex.getFieldAsArray('point', 2, ancestry)
- ifs_texfaces = geom.getFieldAsArray('texCoordIndex', 0, ancestry)
-
- if not ifs_texpoints:
- # IF we have no coords, then dont bother
- coords_tex = None
-
-
- # WORKS - VRML ONLY
- # vcolor = geom.getChildByName('color')
- vcolor = geom.getChildBySpec('Color')
- vcolor_spot = None # spot color when we dont have an array of colors
- if vcolor:
- # float to char
- ifs_vcol = [(0,0,0)] # EEKADOODLE - vertex start at 1
- ifs_vcol.extend([[int(c*256) for c in col] for col in vcolor.getFieldAsArray('color', 3, ancestry)])
- ifs_color_index = geom.getFieldAsArray('colorIndex', 0, ancestry)
-
- if not ifs_vcol:
- vcolor_spot = [int(c*256) for c in vcolor.getFieldAsFloatTuple('color', [], ancestry)]
-
- # Convert faces into somthing blender can use
- edges = []
-
- # All lists are aligned!
- faces = []
- faces_uv = [] # if ifs_texfaces is empty then the faces_uv will match faces exactly.
- faces_orig_index = [] # for ngons, we need to know our original index
-
- if coords_tex and ifs_texfaces:
- do_uvmap = True
- else:
- do_uvmap = False
-
- # current_face = [0] # pointer anyone
-
- def add_face(face, fuvs, orig_index):
- l = len(face)
- if l==3 or l==4:
- faces.append(face)
- # faces_orig_index.append(current_face[0])
- if do_uvmap:
- faces_uv.append(fuvs)
-
- faces_orig_index.append(orig_index)
- elif l==2: edges.append(face)
- elif l>4:
- for i in xrange(2, len(face)):
- faces.append([face[0], face[i-1], face[i]])
- if do_uvmap:
- faces_uv.append([fuvs[0], fuvs[i-1], fuvs[i]])
- faces_orig_index.append(orig_index)
- else:
- # faces with 1 verts? pfft!
- # still will affect index ordering
- pass
-
- face = []
- fuvs = []
- orig_index = 0
- for i, fi in enumerate(ifs_faces):
- # ifs_texfaces and ifs_faces should be aligned
- if fi != -1:
- # face.append(int(fi)) # in rare cases this is a float
- # EEKADOODLE!!!
- # Annoyance where faces that have a zero index vert get rotated. This will then mess up UVs and VColors
- face.append(int(fi)+1) # in rare cases this is a float, +1 because of stupid EEKADOODLE :/
-
- if do_uvmap:
- if i >= len(ifs_texfaces):
- print '\tWarning: UV Texface index out of range'
- fuvs.append(ifs_texfaces[0])
- else:
- fuvs.append(ifs_texfaces[i])
- else:
- add_face(face, fuvs, orig_index)
- face = []
- if do_uvmap:
- fuvs = []
- orig_index += 1
-
- add_face(face, fuvs, orig_index)
- del add_face # dont need this func anymore
-
- bpymesh = bpy.data.meshes.new()
-
- bpymesh.verts.extend([(0,0,0)]) # EEKADOODLE
- bpymesh.verts.extend(ifs_points)
-
- # print len(ifs_points), faces, edges, ngons
-
- try:
- bpymesh.faces.extend(faces, smooth=True, ignoreDups=True)
- except KeyError:
- print "one or more vert indicies out of range. corrupt file?"
- #for f in faces:
- # bpymesh.faces.extend(faces, smooth=True)
-
- bpymesh.calcNormals()
-
- if len(bpymesh.faces) != len(faces):
- print '\tWarning: adding faces did not work! file is invalid, not adding UVs or vcolors'
- return bpymesh, ccw
-
- # Apply UVs if we have them
- if not do_uvmap:
- faces_uv = faces # fallback, we didnt need a uvmap in the first place, fallback to the face/vert mapping.
- if coords_tex:
- #print ifs_texpoints
- # print geom
- bpymesh.faceUV = True
- for i,f in enumerate(bpymesh.faces):
- f.image = bpyima
- fuv = faces_uv[i] # uv indicies
- for j,uv in enumerate(f.uv):
- # print fuv, j, len(ifs_texpoints)
- try:
- uv[:] = ifs_texpoints[fuv[j]]
- except:
- print '\tWarning: UV Index out of range'
- uv[:] = ifs_texpoints[0]
-
- elif bpyima and len(bpymesh.faces):
- # Oh Bugger! - we cant really use blenders ORCO for for texture space since texspace dosnt rotate.
- # we have to create VRML's coords as UVs instead.
-
- # VRML docs
- '''
- If the texCoord field is NULL, a default texture coordinate mapping is calculated using the local
- coordinate system bounding box of the shape. The longest dimension of the bounding box defines the S coordinates,
- and the next longest defines the T coordinates. If two or all three dimensions of the bounding box are equal,
- ties shall be broken by choosing the X, Y, or Z dimension in that order of preference.
- The value of the S coordinate ranges from 0 to 1, from one end of the bounding box to the other.
- The T coordinate ranges between 0 and the ratio of the second greatest dimension of the bounding box to the greatest dimension.
- '''
-
- # Note, S,T == U,V
- # U gets longest, V gets second longest
- xmin, ymin, zmin = ifs_points[0]
- xmax, ymax, zmax = ifs_points[0]
- for co in ifs_points:
- x,y,z = co
- 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
-
- xlen = xmax - xmin
- ylen = ymax - ymin
- zlen = zmax - zmin
-
- depth_min = xmin, ymin, zmin
- depth_list = [xlen, ylen, zlen]
- depth_sort = depth_list[:]
- depth_sort.sort()
-
- depth_idx = [depth_list.index(val) for val in depth_sort]
-
- axis_u = depth_idx[-1]
- axis_v = depth_idx[-2] # second longest
-
- # Hack, swap these !!! TODO - Why swap??? - it seems to work correctly but should not.
- # axis_u,axis_v = axis_v,axis_u
-
- min_u = depth_min[axis_u]
- min_v = depth_min[axis_v]
- depth_u = depth_list[axis_u]
- depth_v = depth_list[axis_v]
-
- depth_list[axis_u]
-
- if axis_u == axis_v:
- # This should be safe because when 2 axies have the same length, the lower index will be used.
- axis_v += 1
-
- bpymesh.faceUV = True
-
- # HACK !!! - seems to be compatible with Cosmo though.
- depth_v = depth_u = max(depth_v, depth_u)
-
- for f in bpymesh.faces:
- f.image = bpyima
- fuv = f.uv
-
- for i,v in enumerate(f):
- co = v.co
- fuv[i][:] = (co[axis_u]-min_u) / depth_u, (co[axis_v]-min_v) / depth_v
-
- # Add vcote
- if vcolor:
- # print ifs_vcol
- bpymesh.vertexColors = True
-
- for f in bpymesh.faces:
- fcol = f.col
- if ifs_colorPerVertex:
- fv = f.verts
- for i,c in enumerate(fcol):
- color_index = fv[i].index # color index is vert index
- if ifs_color_index:
- try:
- color_index = ifs_color_index[color_index]
- except:
- print '\tWarning: per vertex color index out of range'
- continue
-
- if color_index < len(ifs_vcol):
- c.r, c.g, c.b = ifs_vcol[color_index]
- else:
- #print '\tWarning: per face color index out of range'
- pass
- else:
- if vcolor_spot: # use 1 color, when ifs_vcol is []
- for c in fcol:
- c.r, c.g, c.b = vcolor_spot
- else:
- color_index = faces_orig_index[f.index] # color index is face index
- #print color_index, ifs_color_index
- if ifs_color_index:
- if color_index <= len(ifs_color_index):
- print '\tWarning: per face color index out of range'
- color_index = 0
- else:
- color_index = ifs_color_index[color_index]
-
-
- col = ifs_vcol[color_index]
- for i,c in enumerate(fcol):
- try:
- c.r, c.g, c.b = col
- except:
- pass # incase its not between 0 and 255
-
- bpymesh.verts.delete([0,]) # EEKADOODLE
-
- return bpymesh, ccw
-
-def importMesh_IndexedLineSet(geom, ancestry):
- # VRML not x3d
- #coord = geom.getChildByName('coord') # 'Coordinate'
- coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml
- if coord: points = coord.getFieldAsArray('point', 3, ancestry)
- else: points = []
-
- if not points:
- print '\tWarning: IndexedLineSet had no points'
- return None
-
- ils_lines = geom.getFieldAsArray('coordIndex', 0, ancestry)
-
- lines = []
- line = []
-
- for il in ils_lines:
- if il==-1:
- lines.append(line)
- line = []
- else:
- line.append(int(il))
- lines.append(line)
-
- # vcolor = geom.getChildByName('color') # blender dosnt have per vertex color
-
- bpycurve = bpy.data.curves.new('IndexedCurve', 'Curve')
- bpycurve.setFlag(1)
-
- w=t=1
-
- curve_index = 0
-
- for line in lines:
- if not line:
- continue
- co = points[line[0]]
- bpycurve.appendNurb([co[0], co[1], co[2], w, t])
- bpycurve[curve_index].type= 0 # Poly Line
-
- for il in line[1:]:
- co = points[il]
- bpycurve.appendPoint(curve_index, [co[0], co[1], co[2], w])
-
-
- curve_index += 1
-
- return bpycurve
-
-
-def importMesh_PointSet(geom, ancestry):
- # VRML not x3d
- #coord = geom.getChildByName('coord') # 'Coordinate'
- coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml
- if coord: points = coord.getFieldAsArray('point', 3, ancestry)
- else: points = []
-
- # vcolor = geom.getChildByName('color') # blender dosnt have per vertex color
-
- bpymesh = bpy.data.meshes.new()
- bpymesh.verts.extend(points)
- bpymesh.calcNormals() # will just be dummy normals
- return bpymesh
-
-GLOBALS['CIRCLE_DETAIL'] = 12
-
-MATRIX_Z_TO_Y = RotationMatrix(90, 4, 'x')
-
-def importMesh_Sphere(geom, ancestry):
- # bpymesh = bpy.data.meshes.new()
- diameter = geom.getFieldAsFloat('radius', 0.5, ancestry) * 2 # * 2 for the diameter
- bpymesh = Mesh.Primitives.UVsphere(GLOBALS['CIRCLE_DETAIL'], GLOBALS['CIRCLE_DETAIL'], diameter)
- bpymesh.transform(MATRIX_Z_TO_Y)
- return bpymesh
-
-def importMesh_Cylinder(geom, ancestry):
- # bpymesh = bpy.data.meshes.new()
- diameter = geom.getFieldAsFloat('radius', 1.0, ancestry) * 2 # * 2 for the diameter
- height = geom.getFieldAsFloat('height', 2, ancestry)
- bpymesh = Mesh.Primitives.Cylinder(GLOBALS['CIRCLE_DETAIL'], diameter, height)
- bpymesh.transform(MATRIX_Z_TO_Y)
-
- # Warning - Rely in the order Blender adds verts
- # not nice design but wont change soon.
-
- bottom = geom.getFieldAsBool('bottom', True, ancestry)
- side = geom.getFieldAsBool('side', True, ancestry)
- top = geom.getFieldAsBool('top', True, ancestry)
-
- if not top: # last vert is top center of tri fan.
- bpymesh.verts.delete([(GLOBALS['CIRCLE_DETAIL']+GLOBALS['CIRCLE_DETAIL'])+1])
-
- if not bottom: # second last vert is bottom of triangle fan
- bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']+GLOBALS['CIRCLE_DETAIL']])
-
- if not side:
- # remove all quads
- bpymesh.faces.delete(1, [f for f in bpymesh.faces if len(f)==4])
-
- return bpymesh
-
-def importMesh_Cone(geom, ancestry):
- # bpymesh = bpy.data.meshes.new()
- diameter = geom.getFieldAsFloat('bottomRadius', 1.0, ancestry) * 2 # * 2 for the diameter
- height = geom.getFieldAsFloat('height', 2, ancestry)
- bpymesh = Mesh.Primitives.Cone(GLOBALS['CIRCLE_DETAIL'], diameter, height)
- bpymesh.transform(MATRIX_Z_TO_Y)
-
- # Warning - Rely in the order Blender adds verts
- # not nice design but wont change soon.
-
- bottom = geom.getFieldAsBool('bottom', True, ancestry)
- side = geom.getFieldAsBool('side', True, ancestry)
-
- if not bottom: # last vert is on the bottom
- bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']+1])
- if not side: # second last vert is on the pointy bit of the cone
- bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']])
-
- return bpymesh
-
-def importMesh_Box(geom, ancestry):
- # bpymesh = bpy.data.meshes.new()
-
- size = geom.getFieldAsFloatTuple('size', (2.0, 2.0, 2.0), ancestry)
- bpymesh = Mesh.Primitives.Cube(1.0)
-
- # Scale the box to the size set
- scale_mat = Matrix([size[0],0,0], [0, size[1], 0], [0, 0, size[2]])
- bpymesh.transform(scale_mat.resize4x4())
-
- return bpymesh
-
-def importShape(node, ancestry):
- vrmlname = node.getDefName()
- if not vrmlname: vrmlname = 'Shape'
-
- # works 100% in vrml, but not x3d
- #appr = node.getChildByName('appearance') # , 'Appearance'
- #geom = node.getChildByName('geometry') # , 'IndexedFaceSet'
-
- # Works in vrml and x3d
- appr = node.getChildBySpec('Appearance')
- geom = node.getChildBySpec(['IndexedFaceSet', 'IndexedLineSet', 'PointSet', 'Sphere', 'Box', 'Cylinder', 'Cone'])
-
- # For now only import IndexedFaceSet's
- if geom:
- bpymat = None
- bpyima = None
- texmtx = None
-
- depth = 0 # so we can set alpha face flag later
-
- if appr:
-
- #mat = appr.getChildByName('material') # 'Material'
- #ima = appr.getChildByName('texture') # , 'ImageTexture'
- #if ima and ima.getSpec() != 'ImageTexture':
- # print '\tWarning: texture type "%s" is not supported' % ima.getSpec()
- # ima = None
- # textx = appr.getChildByName('textureTransform')
-
- mat = appr.getChildBySpec('Material')
- ima = appr.getChildBySpec('ImageTexture')
-
- textx = appr.getChildBySpec('TextureTransform')
-
- if textx:
- texmtx = translateTexTransform(textx, ancestry)
-
-
-
- # print mat, ima
- if mat or ima:
-
- if not mat:
- mat = ima # This is a bit dumb, but just means we use default values for all
-
- # all values between 0.0 and 1.0, defaults from VRML docs
- bpymat = bpy.data.materials.new()
- bpymat.amb = mat.getFieldAsFloat('ambientIntensity', 0.2, ancestry)
- bpymat.rgbCol = mat.getFieldAsFloatTuple('diffuseColor', [0.8, 0.8, 0.8], ancestry)
-
- # NOTE - blender dosnt support emmisive color
- # Store in mirror color and approximate with emit.
- emit = mat.getFieldAsFloatTuple('emissiveColor', [0.0, 0.0, 0.0], ancestry)
- bpymat.mirCol = emit
- bpymat.emit = (emit[0]+emit[1]+emit[2])/3.0
-
- bpymat.hard = int(1+(510*mat.getFieldAsFloat('shininess', 0.2, ancestry))) # 0-1 -> 1-511
- bpymat.specCol = mat.getFieldAsFloatTuple('specularColor', [0.0, 0.0, 0.0], ancestry)
- bpymat.alpha = 1.0 - mat.getFieldAsFloat('transparency', 0.0, ancestry)
- if bpymat.alpha < 0.999:
- bpymat.mode |= Material.Modes.ZTRANSP
-
-
- if ima:
-
- ima_url = ima.getFieldAsString('url', None, ancestry)
-
- if ima_url==None:
- try: ima_url = ima.getFieldAsStringArray('url', ancestry)[0] # in some cases we get a list of images.
- except: ima_url = None
-
- if ima_url==None:
- print "\twarning, image with no URL, this is odd"
- else:
- bpyima= BPyImage.comprehensiveImageLoad(ima_url, dirName(node.getFilename()), PLACE_HOLDER= False, RECURSIVE= False, CONVERT_CALLBACK= imageConvertCompat)
- if bpyima:
- texture= bpy.data.textures.new()
- texture.setType('Image')
- texture.image = bpyima
-
- # Adds textures for materials (rendering)
- try: depth = bpyima.depth
- except: depth = -1
-
- if depth == 32:
- # Image has alpha
- bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA)
- texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha')
- bpymat.mode |= Material.Modes.ZTRANSP
- bpymat.alpha = 0.0
- else:
- bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
-
- ima_repS = ima.getFieldAsBool('repeatS', True, ancestry)
- ima_repT = ima.getFieldAsBool('repeatT', True, ancestry)
-
- # To make this work properly we'd need to scale the UV's too, better to ignore th
- # texture.repeat = max(1, ima_repS * 512), max(1, ima_repT * 512)
-
- if not ima_repS: bpyima.clampX = True
- if not ima_repT: bpyima.clampY = True
-
- bpydata = None
- geom_spec = geom.getSpec()
- ccw = True
- if geom_spec == 'IndexedFaceSet':
- bpydata, ccw = importMesh_IndexedFaceSet(geom, bpyima, ancestry)
- elif geom_spec == 'IndexedLineSet':
- bpydata = importMesh_IndexedLineSet(geom, ancestry)
- elif geom_spec == 'PointSet':
- bpydata = importMesh_PointSet(geom, ancestry)
- elif geom_spec == 'Sphere':
- bpydata = importMesh_Sphere(geom, ancestry)
- elif geom_spec == 'Box':
- bpydata = importMesh_Box(geom, ancestry)
- elif geom_spec == 'Cylinder':
- bpydata = importMesh_Cylinder(geom, ancestry)
- elif geom_spec == 'Cone':
- bpydata = importMesh_Cone(geom, ancestry)
- else:
- print '\tWarning: unsupported type "%s"' % geom_spec
- return
-
- if bpydata:
- vrmlname = vrmlname + geom_spec
-
- bpydata.name = vrmlname
-
- bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpydata)
-
- if type(bpydata) == Types.MeshType:
- is_solid = geom.getFieldAsBool('solid', True, ancestry)
- creaseAngle = geom.getFieldAsFloat('creaseAngle', None, ancestry)
-
- if creaseAngle != None:
- bpydata.maxSmoothAngle = 1+int(min(79, creaseAngle * RAD_TO_DEG))
- bpydata.mode |= Mesh.Modes.AUTOSMOOTH
-
- # Only ever 1 material per shape
- if bpymat: bpydata.materials = [bpymat]
-
- if bpydata.faceUV:
-
- if depth==32: # set the faces alpha flag?
- transp = Mesh.FaceTranspModes.ALPHA
- for f in bpydata.faces:
- f.transp = transp
-
- if texmtx:
- # Apply texture transform?
- uv_copy = Vector()
- for f in bpydata.faces:
- for uv in f.uv:
- uv_copy.x = uv.x
- uv_copy.y = uv.y
-
- uv.x, uv.y = (uv_copy * texmtx)[0:2]
- # Done transforming the texture
-
-
- # Must be here and not in IndexedFaceSet because it needs an object for the flip func. Messy :/
- if not ccw: bpydata.flipNormals()
-
-
- # else could be a curve for example
-
-
-
- # Can transform data or object, better the object so we can instance the data
- #bpymesh.transform(getFinalMatrix(node))
- bpyob.setMatrix( getFinalMatrix(node, None, ancestry) )
-
-
-def importLamp_PointLight(node, ancestry):
- vrmlname = node.getDefName()
- if not vrmlname: vrmlname = 'PointLight'
-
- # ambientIntensity = node.getFieldAsFloat('ambientIntensity', 0.0, ancestry) # TODO
- # attenuation = node.getFieldAsFloatTuple('attenuation', (1.0, 0.0, 0.0), ancestry) # TODO
- color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0), ancestry)
- intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher.
- location = node.getFieldAsFloatTuple('location', (0.0, 0.0, 0.0), ancestry)
- # is_on = node.getFieldAsBool('on', True, ancestry) # TODO
- radius = node.getFieldAsFloat('radius', 100.0, ancestry)
-
- bpylamp = bpy.data.lamps.new()
- bpylamp.setType('Lamp')
- bpylamp.energy = intensity
- bpylamp.dist = radius
- bpylamp.col = color
-
- mtx = TranslationMatrix(Vector(location))
-
- return bpylamp, mtx
-
-def importLamp_DirectionalLight(node, ancestry):
- vrmlname = node.getDefName()
- if not vrmlname: vrmlname = 'DirectLight'
-
- # ambientIntensity = node.getFieldAsFloat('ambientIntensity', 0.0) # TODO
- color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0), ancestry)
- direction = node.getFieldAsFloatTuple('direction', (0.0, 0.0, -1.0), ancestry)
- intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher.
- # is_on = node.getFieldAsBool('on', True, ancestry) # TODO
-
- bpylamp = bpy.data.lamps.new(vrmlname)
- bpylamp.setType('Sun')
- bpylamp.energy = intensity
- bpylamp.col = color
-
- # lamps have their direction as -z, yup
- mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4()
-
- return bpylamp, mtx
-
-# looks like default values for beamWidth and cutOffAngle were swapped in VRML docs.
-
-def importLamp_SpotLight(node, ancestry):
- vrmlname = node.getDefName()
- if not vrmlname: vrmlname = 'SpotLight'
-
- # ambientIntensity = geom.getFieldAsFloat('ambientIntensity', 0.0, ancestry) # TODO
- # attenuation = geom.getFieldAsFloatTuple('attenuation', (1.0, 0.0, 0.0), ancestry) # TODO
- beamWidth = node.getFieldAsFloat('beamWidth', 1.570796, ancestry) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher.
- color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0), ancestry)
- cutOffAngle = node.getFieldAsFloat('cutOffAngle', 0.785398, ancestry) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher.
- direction = node.getFieldAsFloatTuple('direction', (0.0, 0.0, -1.0), ancestry)
- intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher.
- location = node.getFieldAsFloatTuple('location', (0.0, 0.0, 0.0), ancestry)
- # is_on = node.getFieldAsBool('on', True, ancestry) # TODO
- radius = node.getFieldAsFloat('radius', 100.0, ancestry)
-
- bpylamp = bpy.data.lamps.new(vrmlname)
- bpylamp.setType('Spot')
- bpylamp.energy = intensity
- bpylamp.dist = radius
- bpylamp.col = color
- bpylamp.spotSize = cutOffAngle
- if beamWidth > cutOffAngle:
- bpylamp.spotBlend = 0.0
- else:
- if cutOffAngle==0.0: #@#$%^&*(!!! - this should never happen
- bpylamp.spotBlend = 0.5
- else:
- bpylamp.spotBlend = beamWidth / cutOffAngle
-
- # Convert
-
- # lamps have their direction as -z, y==up
- mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4() * TranslationMatrix(Vector(location))
-
- return bpylamp, mtx
-
-
-def importLamp(node, spec, ancestry):
- if spec=='PointLight':
- bpylamp,mtx = importLamp_PointLight(node, ancestry)
- elif spec=='DirectionalLight':
- bpylamp,mtx = importLamp_DirectionalLight(node, ancestry)
- elif spec=='SpotLight':
- bpylamp,mtx = importLamp_SpotLight(node, ancestry)
- else:
- print "Error, not a lamp"
- raise ValueError
-
- bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpylamp)
- bpyob.setMatrix( getFinalMatrix(node, mtx, ancestry) )
-
-
-def importViewpoint(node, ancestry):
- name = node.getDefName()
- if not name: name = 'Viewpoint'
-
- fieldOfView = node.getFieldAsFloat('fieldOfView', 0.785398, ancestry) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher.
- # jump = node.getFieldAsBool('jump', True, ancestry)
- orientation = node.getFieldAsFloatTuple('orientation', (0.0, 0.0, 1.0, 0.0), ancestry)
- position = node.getFieldAsFloatTuple('position', (0.0, 0.0, 0.0), ancestry)
- description = node.getFieldAsString('description', '', ancestry)
-
- bpycam = bpy.data.cameras.new(name)
-
- bpycam.angle = fieldOfView
-
- mtx = translateRotation(orientation) * TranslationMatrix(Vector(position))
-
-
- bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpycam)
- bpyob.setMatrix( getFinalMatrix(node, mtx, ancestry) )
-
-
-def importTransform(node, ancestry):
- name = node.getDefName()
- if not name: name = 'Transform'
-
- bpyob = node.blendObject = bpy.data.scenes.active.objects.new('Empty', name) # , name)
- bpyob.setMatrix( getFinalMatrix(node, None, ancestry) )
-
- # so they are not too annoying
- bpyob.emptyShape= Blender.Object.EmptyShapes.AXES
- bpyob.drawSize= 0.2
-
-
-#def importTimeSensor(node):
-
-
-def translatePositionInterpolator(node, ipo, ancestry):
- key = node.getFieldAsArray('key', 0, ancestry)
- keyValue = node.getFieldAsArray('keyValue', 3, ancestry)
-
- try:
- loc_x = ipo.addCurve('LocX')
- loc_y = ipo.addCurve('LocY')
- loc_z = ipo.addCurve('LocZ')
- except ValueError:
- return
-
- loc_x.interpolation = loc_y.interpolation = loc_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
-
- for i, time in enumerate(key):
- try: x,y,z = keyValue[i]
- except: continue
-
- loc_x.append((time,x))
- loc_y.append((time,y))
- loc_z.append((time,z))
-
-def translateOrientationInterpolator(node, ipo, ancestry):
- key = node.getFieldAsArray('key', 0, ancestry)
- keyValue = node.getFieldAsArray('keyValue', 4, ancestry)
-
- try:
- rot_x = ipo.addCurve('RotX')
- rot_y = ipo.addCurve('RotY')
- rot_z = ipo.addCurve('RotZ')
- except ValueError:
- return
-
- rot_x.interpolation = rot_y.interpolation = rot_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
-
- for i, time in enumerate(key):
- try: x,y,z,w = keyValue[i]
- except: continue
-
- mtx = translateRotation((x,y,z,w))
- eul = mtx.toEuler()
- rot_x.append((time,eul.x/10.0))
- rot_y.append((time,eul.y/10.0))
- rot_z.append((time,eul.z/10.0))
-
-# Untested!
-def translateScalarInterpolator(node, ipo, ancestry):
- key = node.getFieldAsArray('key', 0, ancestry)
- keyValue = node.getFieldAsArray('keyValue', 4, ancestry)
-
- try:
- sca_x = ipo.addCurve('ScaleX')
- sca_y = ipo.addCurve('ScaleY')
- sca_z = ipo.addCurve('ScaleZ')
- except ValueError:
- return
-
- sca_x.interpolation = sca_y.interpolation = sca_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
-
- for i, time in enumerate(key):
- try: x,y,z = keyValue[i]
- except: continue
- sca_x.append((time,x/10.0))
- sca_y.append((time,y/10.0))
- sca_z.append((time,z/10.0))
-
-def translateTimeSensor(node, ipo, ancestry):
- '''
- Apply a time sensor to an IPO, VRML has many combinations of loop/start/stop/cycle times
- to give different results, for now just do the basics
- '''
-
- time_cu = ipo.addCurve('Time')
- time_cu.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
-
- cycleInterval = node.getFieldAsFloat('cycleInterval', None, ancestry)
-
- startTime = node.getFieldAsFloat('startTime', 0.0, ancestry)
- stopTime = node.getFieldAsFloat('stopTime', 250.0, ancestry)
-
- if cycleInterval != None:
- stopTime = startTime+cycleInterval
-
- loop = node.getFieldAsBool('loop', False, ancestry)
-
- time_cu.append((1+startTime, 0.0))
- time_cu.append((1+stopTime, 1.0/10.0))# anoying, the UI uses /10
-
-
- if loop:
- time_cu.extend = Blender.IpoCurve.ExtendTypes.CYCLIC # or - EXTRAP, CYCLIC_EXTRAP, CONST,
-
-
-def importRoute(node, ancestry):
- '''
- Animation route only at the moment
- '''
-
- if not hasattr(node, 'fields'):
- return
-
- routeIpoDict = node.getRouteIpoDict()
-
- def getIpo(id):
- try: ipo = routeIpoDict[id]
- except: ipo = routeIpoDict[id] = bpy.data.ipos.new('web3d_ipo', 'Object')
- return ipo
-
- # for getting definitions
- defDict = node.getDefDict()
- '''
- Handles routing nodes to eachother
-
-ROUTE vpPI.value_changed TO champFly001.set_position
-ROUTE vpOI.value_changed TO champFly001.set_orientation
-ROUTE vpTs.fraction_changed TO vpPI.set_fraction
-ROUTE vpTs.fraction_changed TO vpOI.set_fraction
-ROUTE champFly001.bindTime TO vpTs.set_startTime
- '''
-
- #from_id, from_type = node.id[1].split('.')
- #to_id, to_type = node.id[3].split('.')
-
- #value_changed
- set_position_node = None
- set_orientation_node = None
- time_node = None
-
- for field in node.fields:
- if field and field[0]=='ROUTE':
- try:
- from_id, from_type = field[1].split('.')
- to_id, to_type = field[3].split('.')
- except:
- print "Warning, invalid ROUTE", field
- continue
-
- if from_type == 'value_changed':
- if to_type == 'set_position':
- ipo = getIpo(to_id)
- set_data_from_node = defDict[from_id]
- translatePositionInterpolator(set_data_from_node, ipo, ancestry)
-
- if to_type in ('set_orientation', 'rotation'):
- ipo = getIpo(to_id)
- set_data_from_node = defDict[from_id]
- translateOrientationInterpolator(set_data_from_node, ipo, ancestry)
-
- if to_type == 'set_scale':
- ipo = getIpo(to_id)
- set_data_from_node = defDict[from_id]
- translateScalarInterpolator(set_data_from_node, ipo, ancestry)
-
- elif from_type =='bindTime':
- ipo = getIpo(from_id)
- time_node = defDict[to_id]
- translateTimeSensor(time_node, ipo, ancestry)
-
-
-
-
-def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC = None):
-
- # Used when adding blender primitives
- GLOBALS['CIRCLE_DETAIL'] = PREF_CIRCLE_DIV
-
- #root_node = vrml_parse('/_Cylinder.wrl')
- if path.lower().endswith('.x3d'):
- root_node, msg = x3d_parse(path)
- else:
- root_node, msg = vrml_parse(path)
-
- if not root_node:
- if Blender.mode == 'background':
- print msg
- else:
- Blender.Draw.PupMenu(msg)
- return
-
-
- # fill with tuples - (node, [parents-parent, parent])
- all_nodes = root_node.getSerialized([], [])
-
- for node, ancestry in all_nodes:
- #if 'castle.wrl' not in node.getFilename():
- # continue
-
- spec = node.getSpec()
- '''
- prefix = node.getPrefix()
- if prefix=='PROTO':
- pass
- else
- '''
- if HELPER_FUNC and HELPER_FUNC(node, ancestry):
- # Note, include this function so the VRML/X3D importer can be extended
- # by an external script. - gets first pick
- pass
- if spec=='Shape':
- importShape(node, ancestry)
- elif spec in ('PointLight', 'DirectionalLight', 'SpotLight'):
- importLamp(node, spec, ancestry)
- elif spec=='Viewpoint':
- importViewpoint(node, ancestry)
- elif spec=='Transform':
- # Only use transform nodes when we are not importing a flat object hierarchy
- if PREF_FLAT==False:
- importTransform(node, ancestry)
- '''
- # These are delt with later within importRoute
- elif spec=='PositionInterpolator':
- ipo = bpy.data.ipos.new('web3d_ipo', 'Object')
- translatePositionInterpolator(node, ipo)
- '''
-
-
-
- # After we import all nodes, route events - anim paths
- for node, ancestry in all_nodes:
- importRoute(node, ancestry)
-
- for node, ancestry in all_nodes:
- if node.isRoot():
- # we know that all nodes referenced from will be in
- # routeIpoDict so no need to run node.getDefDict() for every node.
- routeIpoDict = node.getRouteIpoDict()
- defDict = node.getDefDict()
-
- for key, ipo in routeIpoDict.iteritems():
-
- # Assign anim curves
- node = defDict[key]
- if node.blendObject==None: # Add an object if we need one for animation
- node.blendObject = bpy.data.scenes.active.objects.new('Empty', 'AnimOb') # , name)
-
- node.blendObject.setIpo(ipo)
-
-
-
- # Add in hierarchy
- if PREF_FLAT==False:
- child_dict = {}
- for node, ancestry in all_nodes:
- if node.blendObject:
- blendObject = None
-
- # Get the last parent
- i = len(ancestry)
- while i:
- i-=1
- blendObject = ancestry[i].blendObject
- if blendObject:
- break
-
- if blendObject:
- # Parent Slow, - 1 liner but works
- # blendObject.makeParent([node.blendObject], 0, 1)
-
- # Parent FAST
- try: child_dict[blendObject].append(node.blendObject)
- except: child_dict[blendObject] = [node.blendObject]
-
- # Parent FAST
- for parent, children in child_dict.iteritems():
- parent.makeParent(children, 0, 1)
-
- # update deps
- bpy.data.scenes.active.update(1)
- del child_dict
-
-
-def load_ui(path):
- Draw = Blender.Draw
- PREF_HIERARCHY= Draw.Create(0)
- PREF_CIRCLE_DIV= Draw.Create(16)
-
- # Get USER Options
- pup_block= [\
- 'Import...',\
- ('Hierarchy', PREF_HIERARCHY, 'Import transform nodes as empties to create a parent/child hierarchy'),\
- ('Circle Div:', PREF_CIRCLE_DIV, 3, 128, 'Number of divisions to use for circular primitives')
- ]
-
- if not Draw.PupBlock('Import X3D/VRML...', pup_block):
- return
-
- Window.WaitCursor(1)
-
- load_web3d(path,\
- (not PREF_HIERARCHY.val),\
- PREF_CIRCLE_DIV.val,\
- )
-
- Window.WaitCursor(0)
-
-
-if __name__ == '__main__':
- Window.FileSelector(load_ui, 'Import X3D/VRML97')
-
-
-# Testing stuff
-
-# load_web3d('/test.x3d')
-# load_web3d('/_Cylinder.x3d')
-
-# Testing below
-# load_web3d('m:\\root\\Desktop\\_Cylinder.wrl')
-# load_web3d('/_Cylinder.wrl')
-# load_web3d('/fe/wrl/Vrml/EGS/BCKGD.WRL')
-
-# load_web3d('/fe/wrl/Vrml/EGS/GRNDPLNE.WRL')
-# load_web3d('/fe/wrl/Vrml/EGS/INDEXFST.WRL')
-# load_web3d('/fe/wrl/panel1c.wrl')
-# load_web3d('/test.wrl')
-# load_web3d('/fe/wrl/dulcimer.wrl')
-# load_web3d('/fe/wrl/rccad/Ju-52.wrl') # Face index out of range
-# load_web3d('/fe/wrl/16lat.wrl') # spotlight
-# load_web3d('/fe/wrl/Vrml/EGS/FOG.WRL') # spotlight
-# load_web3d('/fe/wrl/Vrml/EGS/LOD.WRL') # vcolor per face
-
-# load_web3d('/fe/wrl/new/daybreak_final.wrl') # no faces in mesh, face duplicate error
-# load_web3d('/fe/wrl/new/earth.wrl')
-# load_web3d('/fe/wrl/new/hendrix.ei.dtu.dk/vrml/talairach/fourd/TalaDruryRight.wrl') # define/use fields
-# load_web3d('/fe/wrl/new/imac.wrl') # extrusion and define/use fields, face index is a float somehow
-# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/mcastle.wrl')
-# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/tower.wrl')
-# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/temple.wrl')
-# load_web3d('/fe/wrl/brain.wrl') # field define test 'a IS b'
-# load_web3d('/fe/wrl/new/coaster.wrl') # fields that are confusing to read.
-
-# X3D
-
-# load_web3d('/fe/x3d/www.web3d.org/x3d/content/examples/Basic/StudentProjects/PlayRoom.x3d') # invalid UVs
-
-
-
-def test():
- import os
-
- files = os.popen('find /fe/wrl -iname "*.wrl"').readlines()
- # files = os.popen('find /fe/x3d -iname "*.x3d"').readlines()
- # files = os.popen('find /fe/x3d/X3dExamplesSavage -iname "*.x3d"').readlines()
-
- files.sort()
- tot = len(files)
- for i, f in enumerate(files):
- if i < 124 or i > 1000000:
- continue
-
- #if i != 1068:
- # continue
-
- #if i != 12686:
- # continue
-
- f = f.strip()
- print f, i, tot
- sce = bpy.data.scenes.new(str(i) + '_' + f.split('/')[-1])
- bpy.data.scenes.active = sce
- # Window.
- load_web3d(f, PREF_FLAT=True)
-
-# test()
diff --git a/release/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py
index 22cf1a36dbb..f0247ce532a 100644
--- a/release/io/engine_render_pov.py
+++ b/release/scripts/io/engine_render_pov.py
@@ -110,8 +110,7 @@ def write_pov(filename, scene=None, info_callback = None):
file.write('\tdiffuse 0.8\n')
file.write('\tspecular 0.2\n')
-
-
+
# This is written into the object
'''
if material and material.transparency_method=='RAYTRACE':
@@ -143,9 +142,7 @@ def write_pov(filename, scene=None, info_callback = None):
file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotationPart().toEuler()]))
file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
file.write('}\n')
-
-
-
+
def exportLamps(lamps):
# Get all lamps
for ob in lamps:
@@ -186,9 +183,7 @@ def write_pov(filename, scene=None, info_callback = None):
else:
size_y = lamp.size_y
samples_y = lamp.shadow_ray_samples_y
-
-
-
+
file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y))
if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
if lamp.jitter:
@@ -264,10 +259,7 @@ def write_pov(filename, scene=None, info_callback = None):
writeMatrix(ob.matrix)
file.write('}\n')
-
-
-
-
+
def exportMeshs(sel):
ob_num = 0
@@ -275,13 +267,13 @@ def write_pov(filename, scene=None, info_callback = None):
for ob in sel:
ob_num+= 1
- if ob.type in ('LAMP', 'CAMERA', 'EMPTY'):
+ if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META'):
continue
me = ob.data
me_materials= me.materials
- me = ob.create_render_mesh(scene)
+ me = ob.create_mesh(True, 'RENDER')
if not me:
continue
@@ -475,8 +467,7 @@ def write_pov(filename, scene=None, info_callback = None):
file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
-
-
+
file.write('\n }\n')
# normal_indices indicies
@@ -589,7 +580,6 @@ def write_pov(filename, scene=None, info_callback = None):
file.close()
-
def write_pov_ini(filename_ini, filename_pov, filename_image):
scene = bpy.data.scenes[0]
render = scene.render_data
@@ -775,9 +765,7 @@ class PovrayRender(bpy.types.RenderEngine):
# compute resolution
x= int(r.resolution_x*r.resolution_percentage*0.01)
y= int(r.resolution_y*r.resolution_percentage*0.01)
-
-
-
+
# Wait for the file to be created
while not os.path.exists(self.temp_file_out):
if self.test_break():
@@ -876,12 +864,13 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel):
COMPAT_ENGINES = set(['POVRAY_RENDER'])
def draw_header(self, context):
- layout = self.layout
scene = context.scene
- layout.itemR(scene, "pov_radio_enable", text="")
+
+ self.layout.itemR(scene, "pov_radio_enable", text="")
def draw(self, context):
layout = self.layout
+
scene = context.scene
rd = scene.render_data
@@ -890,7 +879,6 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel):
split = layout.split()
col = split.column()
-
col.itemR(scene, "pov_radio_count", text="Rays")
col.itemR(scene, "pov_radio_recursion_limit", text="Recursions")
col = split.column()
@@ -905,15 +893,12 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel):
col.itemR(scene, "pov_radio_adc_bailout", slider=True)
col.itemR(scene, "pov_radio_gray_threshold", slider=True)
col.itemR(scene, "pov_radio_low_error_factor", slider=True)
-
-
-
+
col = split.column()
col.itemR(scene, "pov_radio_brightness")
col.itemR(scene, "pov_radio_minimum_reuse", text="Min Reuse")
col.itemR(scene, "pov_radio_nearest_count")
-
-
+
split = layout.split()
col = split.column()
@@ -923,6 +908,5 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel):
col = split.column()
col.itemR(scene, "pov_radio_always_sample")
-
bpy.types.register(SCENE_PT_povray_radiosity)
diff --git a/release/scripts/3ds_export.py b/release/scripts/io/export_3ds.py
index 87680bce1b0..2c1999c3d45 100644
--- a/release/scripts/3ds_export.py
+++ b/release/scripts/io/export_3ds.py
@@ -46,14 +46,35 @@ from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode.
# Importing modules
######################################################
-import Blender
+import struct
+import os
+import time
+
import bpy
-from BPyMesh import getMeshFromObject
-from BPyObject import getDerivedObjects
-try:
- import struct
-except:
- struct = None
+
+# import Blender
+# from BPyMesh import getMeshFromObject
+# from BPyObject import getDerivedObjects
+# try:
+# import struct
+# except:
+# struct = None
+
+# also used by X3D exporter
+# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
+def create_derived_objects(ob):
+ if ob.parent and ob.parent.dupli_type != 'NONE':
+ return False, None
+
+ if ob.dupli_type != 'NONE':
+ ob.create_dupli_list()
+ return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
+ else:
+ return False, [(ob, ob.matrix)]
+
+# also used by X3D exporter
+def free_derived_objects(ob):
+ ob.free_dupli_list()
# So 3ds max can open files, limit names to 12 in length
# this is verry annoying for filenames!
@@ -85,61 +106,62 @@ def sane_name(name):
#Some of the chunks that we will export
#----- Primary Chunk, at the beginning of each file
-PRIMARY= long("0x4D4D",16)
+PRIMARY= int("0x4D4D",16)
#------ Main Chunks
-OBJECTINFO = long("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information
-VERSION = long("0x0002",16); #This gives the version of the .3ds file
-KFDATA = long("0xB000",16); #This is the header for all of the key frame info
+OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information
+VERSION = int("0x0002",16); #This gives the version of the .3ds file
+KFDATA = int("0xB000",16); #This is the header for all of the key frame info
#------ sub defines of OBJECTINFO
MATERIAL=45055 #0xAFFF // This stored the texture info
OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
#>------ sub defines of MATERIAL
-MATNAME = long("0xA000",16); # This holds the material name
-MATAMBIENT = long("0xA010",16); # Ambient color of the object/material
-MATDIFFUSE = long("0xA020",16); # This holds the color of the object/material
-MATSPECULAR = long("0xA030",16); # SPecular color of the object/material
-MATSHINESS = long("0xA040",16); # ??
-MATMAP = long("0xA200",16); # This is a header for a new material
-MATMAPFILE = long("0xA300",16); # This holds the file name of the texture
+MATNAME = int("0xA000",16); # This holds the material name
+MATAMBIENT = int("0xA010",16); # Ambient color of the object/material
+MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material
+MATSPECULAR = int("0xA030",16); # SPecular color of the object/material
+MATSHINESS = int("0xA040",16); # ??
+MATMAP = int("0xA200",16); # This is a header for a new material
+MATMAPFILE = int("0xA300",16); # This holds the file name of the texture
-RGB1= long("0x0011",16)
-RGB2= long("0x0012",16)
+RGB1= int("0x0011",16)
+RGB2= int("0x0012",16)
#>------ sub defines of OBJECT
-OBJECT_MESH = long("0x4100",16); # This lets us know that we are reading a new object
-OBJECT_LIGHT = long("0x4600",16); # This lets un know we are reading a light object
-OBJECT_CAMERA= long("0x4700",16); # This lets un know we are reading a camera object
+OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object
+OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object
+OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object
#>------ sub defines of CAMERA
-OBJECT_CAM_RANGES= long("0x4720",16); # The camera range values
+OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values
#>------ sub defines of OBJECT_MESH
-OBJECT_VERTICES = long("0x4110",16); # The objects vertices
-OBJECT_FACES = long("0x4120",16); # The objects faces
-OBJECT_MATERIAL = long("0x4130",16); # This is found if the object has a material, either texture map or color
-OBJECT_UV = long("0x4140",16); # The UV texture coordinates
-OBJECT_TRANS_MATRIX = long("0x4160",16); # The Object Matrix
+OBJECT_VERTICES = int("0x4110",16); # The objects vertices
+OBJECT_FACES = int("0x4120",16); # The objects faces
+OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color
+OBJECT_UV = int("0x4140",16); # The UV texture coordinates
+OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix
#>------ sub defines of KFDATA
-KFDATA_KFHDR = long("0xB00A",16);
-KFDATA_KFSEG = long("0xB008",16);
-KFDATA_KFCURTIME = long("0xB009",16);
-KFDATA_OBJECT_NODE_TAG = long("0xB002",16);
+KFDATA_KFHDR = int("0xB00A",16);
+KFDATA_KFSEG = int("0xB008",16);
+KFDATA_KFCURTIME = int("0xB009",16);
+KFDATA_OBJECT_NODE_TAG = int("0xB002",16);
#>------ sub defines of OBJECT_NODE_TAG
-OBJECT_NODE_ID = long("0xB030",16);
-OBJECT_NODE_HDR = long("0xB010",16);
-OBJECT_PIVOT = long("0xB013",16);
-OBJECT_INSTANCE_NAME = long("0xB011",16);
-POS_TRACK_TAG = long("0xB020",16);
-ROT_TRACK_TAG = long("0xB021",16);
-SCL_TRACK_TAG = long("0xB022",16);
+OBJECT_NODE_ID = int("0xB030",16);
+OBJECT_NODE_HDR = int("0xB010",16);
+OBJECT_PIVOT = int("0xB013",16);
+OBJECT_INSTANCE_NAME = int("0xB011",16);
+POS_TRACK_TAG = int("0xB020",16);
+ROT_TRACK_TAG = int("0xB021",16);
+SCL_TRACK_TAG = int("0xB022",16);
def uv_key(uv):
- return round(uv.x, 6), round(uv.y, 6)
+ return round(uv[0], 6), round(uv[1], 6)
+# return round(uv.x, 6), round(uv.y, 6)
# size defines:
SZ_SHORT = 2
@@ -272,7 +294,8 @@ class _3ds_rgb_color(object):
return 3
def write(self,file):
- file.write( struct.pack('<3c', chr(int(255*self.r)), chr(int(255*self.g)), chr(int(255*self.b)) ) )
+ file.write( struct.pack('<3B', int(255*self.r), int(255*self.g), int(255*self.b) ) )
+# file.write( struct.pack('<3c', chr(int(255*self.r)), chr(int(255*self.g)), chr(int(255*self.b)) ) )
def __str__(self):
return '{%f, %f, %f}' % (self.r, self.g, self.b)
@@ -343,12 +366,12 @@ class _3ds_named_variable(object):
def dump(self,indent):
if (self.value!=None):
spaces=""
- for i in xrange(indent):
+ for i in range(indent):
spaces+=" ";
if (self.name!=""):
- print spaces, self.name, " = ", self.value
+ print(spaces, self.name, " = ", self.value)
else:
- print spaces, "[unnamed]", " = ", self.value
+ print(spaces, "[unnamed]", " = ", self.value)
#the chunk class
@@ -408,9 +431,9 @@ class _3ds_chunk(object):
Dump is used for debugging purposes, to dump the contents of a chunk to the standard output.
Uses the dump function of the named variables and the subchunks to do the actual work.'''
spaces=""
- for i in xrange(indent):
+ for i in range(indent):
spaces+=" ";
- print spaces, "ID=", hex(self.ID.value), "size=", self.get_size()
+ print(spaces, "ID=", hex(self.ID.value), "size=", self.get_size())
for variable in self.variables:
variable.dump(indent+1)
for subchunk in self.subchunks:
@@ -424,14 +447,19 @@ class _3ds_chunk(object):
def get_material_images(material):
# blender utility func.
- images = []
if material:
- for mtex in material.getTextures():
- if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
- image = mtex.tex.image
- if image:
- images.append(image) # maye want to include info like diffuse, spec here.
- return images
+ return [s.texture.image for s in material.textures if s and s.texture.type == 'IMAGE' and s.texture.image]
+
+ return []
+# images = []
+# if material:
+# for mtex in material.getTextures():
+# if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
+# image = mtex.tex.image
+# if image:
+# images.append(image) # maye want to include info like diffuse, spec here.
+# return images
+
def make_material_subchunk(id, color):
'''Make a material subchunk.
@@ -454,7 +482,8 @@ def make_material_texture_chunk(id, images):
mat_sub = _3ds_chunk(id)
def add_image(img):
- filename = image.filename.split('\\')[-1].split('/')[-1]
+ filename = os.path.basename(image.filename)
+# filename = image.filename.split('\\')[-1].split('/')[-1]
mat_sub_file = _3ds_chunk(MATMAPFILE)
mat_sub_file.add_variable("mapfile", _3ds_string(sane_name(filename)))
mat_sub.add_subchunk(mat_sub_file)
@@ -482,9 +511,12 @@ def make_material_chunk(material, image):
material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, (1,1,1) ))
else:
- material_chunk.add_subchunk(make_material_subchunk(MATAMBIENT, [a*material.amb for a in material.rgbCol] ))
- material_chunk.add_subchunk(make_material_subchunk(MATDIFFUSE, material.rgbCol))
- material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, material.specCol))
+ material_chunk.add_subchunk(make_material_subchunk(MATAMBIENT, [a*material.ambient for a in material.diffuse_color] ))
+# material_chunk.add_subchunk(make_material_subchunk(MATAMBIENT, [a*material.amb for a in material.rgbCol] ))
+ material_chunk.add_subchunk(make_material_subchunk(MATDIFFUSE, material.diffuse_color))
+# material_chunk.add_subchunk(make_material_subchunk(MATDIFFUSE, material.rgbCol))
+ material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, material.specular_color))
+# material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, material.specCol))
images = get_material_images(material) # can be None
if image: images.append(image)
@@ -513,28 +545,39 @@ def extract_triangles(mesh):
If the mesh contains quads, they will be split into triangles.'''
tri_list = []
- do_uv = mesh.faceUV
+ do_uv = len(mesh.uv_textures)
+# do_uv = mesh.faceUV
- if not do_uv:
- face_uv = None
+# if not do_uv:
+# face_uv = None
img = None
- for face in mesh.faces:
- f_v = face.v
+ for i, face in enumerate(mesh.faces):
+ f_v = face.verts
+# f_v = face.v
+
+ uf = mesh.active_uv_texture.data[i] if do_uv else None
if do_uv:
- f_uv = face.uv
- img = face.image
+ f_uv = uf.uv
+ # f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3)
+# f_uv = face.uv
+ img = uf.image if uf else None
+# img = face.image
if img: img = img.name
+ # if f_v[3] == 0:
if len(f_v)==3:
- new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img)
+ new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img)
+# new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img)
if (do_uv): new_tri.faceuvs= uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2])
tri_list.append(new_tri)
else: #it's a quad
- new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img)
- new_tri_2 = tri_wrapper((f_v[0].index, f_v[2].index, f_v[3].index), face.mat, img)
+ new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img)
+# new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img)
+ new_tri_2 = tri_wrapper((f_v[0], f_v[2], f_v[3]), face.material_index, img)
+# new_tri_2 = tri_wrapper((f_v[0].index, f_v[2].index, f_v[3].index), face.mat, img)
if (do_uv):
new_tri.faceuvs= uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2])
@@ -555,11 +598,11 @@ def remove_face_uv(verts, tri_list):
# initialize a list of UniqueLists, one per vertex:
#uv_list = [UniqueList() for i in xrange(len(verts))]
- unique_uvs= [{} for i in xrange(len(verts))]
+ unique_uvs= [{} for i in range(len(verts))]
# for each face uv coordinate, add it to the UniqueList of the vertex
for tri in tri_list:
- for i in xrange(3):
+ for i in range(3):
# store the index into the UniqueList for future reference:
# offset.append(uv_list[tri.vertex_index[i]].add(_3ds_point_uv(tri.faceuvs[i])))
@@ -589,7 +632,7 @@ def remove_face_uv(verts, tri_list):
pt = _3ds_point_3d(vert.co) # reuse, should be ok
uvmap = [None] * len(unique_uvs[i])
- for ii, uv_3ds in unique_uvs[i].itervalues():
+ for ii, uv_3ds in unique_uvs[i].values():
# add a vertex duplicate to the vertex_array for every uv associated with this vertex:
vert_array.add(pt)
# add the uv coordinate to the uv array:
@@ -607,7 +650,7 @@ def remove_face_uv(verts, tri_list):
# Make sure the triangle vertex indices now refer to the new vertex list:
for tri in tri_list:
- for i in xrange(3):
+ for i in range(3):
tri.offset[i]+=index_list[tri.vertex_index[i]]
tri.vertex_index= tri.offset
@@ -626,7 +669,8 @@ def make_faces_chunk(tri_list, mesh, materialDict):
face_list = _3ds_array()
- if mesh.faceUV:
+ if len(mesh.uv_textures):
+# if mesh.faceUV:
# Gather materials used in this mesh - mat/image pairs
unique_mats = {}
for i,tri in enumerate(tri_list):
@@ -655,7 +699,7 @@ def make_faces_chunk(tri_list, mesh, materialDict):
# obj_material_faces[tri.mat].add(_3ds_short(i))
face_chunk.add_variable("faces", face_list)
- for mat_name, mat_faces in unique_mats.itervalues():
+ for mat_name, mat_faces in unique_mats.values():
obj_material_chunk=_3ds_chunk(OBJECT_MATERIAL)
obj_material_chunk.add_variable("name", mat_name)
obj_material_chunk.add_variable("face_list", mat_faces)
@@ -677,7 +721,7 @@ def make_faces_chunk(tri_list, mesh, materialDict):
obj_material_faces[tri.mat].add(_3ds_short(i))
face_chunk.add_variable("faces", face_list)
- for i in xrange(n_materials):
+ for i in range(n_materials):
obj_material_chunk=_3ds_chunk(OBJECT_MATERIAL)
obj_material_chunk.add_variable("name", obj_material_names[i])
obj_material_chunk.add_variable("face_list", obj_material_faces[i])
@@ -703,7 +747,8 @@ def make_mesh_chunk(mesh, materialDict):
# Extract the triangles from the mesh:
tri_list = extract_triangles(mesh)
- if mesh.faceUV:
+ if len(mesh.uv_textures):
+# if mesh.faceUV:
# Remove the face UVs and convert it to vertex UV:
vert_array, uv_array, tri_list = remove_face_uv(mesh.verts, tri_list)
else:
@@ -712,10 +757,13 @@ def make_mesh_chunk(mesh, materialDict):
for vert in mesh.verts:
vert_array.add(_3ds_point_3d(vert.co))
# If the mesh has vertex UVs, create an array of UVs:
- if mesh.vertexUV:
+ if len(mesh.sticky):
+# if mesh.vertexUV:
uv_array = _3ds_array()
- for vert in mesh.verts:
- uv_array.add(_3ds_point_uv(vert.uvco))
+ for uv in mesh.sticky:
+# for vert in mesh.verts:
+ uv_array.add(_3ds_point_uv(uv.co))
+# uv_array.add(_3ds_point_uv(vert.uvco))
else:
# no UV at all:
uv_array = None
@@ -862,20 +910,25 @@ def make_kf_obj_node(obj, name_to_id):
return kf_obj_node
"""
-import BPyMessages
-def save_3ds(filename):
+# import BPyMessages
+def save_3ds(filename, context):
'''Save the Blender scene to a 3ds file.'''
# Time the export
if not filename.lower().endswith('.3ds'):
filename += '.3ds'
- if not BPyMessages.Warning_SaveOver(filename):
- return
+ # XXX
+# if not BPyMessages.Warning_SaveOver(filename):
+# return
- time1= Blender.sys.time()
- Blender.Window.WaitCursor(1)
- sce= bpy.data.scenes.active
+ # XXX
+ time1 = time.clock()
+# time1= Blender.sys.time()
+# Blender.Window.WaitCursor(1)
+
+ sce = context.scene
+# sce= bpy.data.scenes.active
# Initialize the main chunk (primary):
primary = _3ds_chunk(PRIMARY)
@@ -901,22 +954,39 @@ def save_3ds(filename):
# each material is added once):
materialDict = {}
mesh_objects = []
- for ob in sce.objects.context:
- for ob_derived, mat in getDerivedObjects(ob, False):
- data = getMeshFromObject(ob_derived, None, True, False, sce)
+ for ob in [ob for ob in context.scene.objects if ob.is_visible()]:
+# for ob in sce.objects.context:
+
+ # get derived objects
+ free, derived = create_derived_objects(ob)
+
+ if derived == None: continue
+
+ for ob_derived, mat in derived:
+# for ob_derived, mat in getDerivedObjects(ob, False):
+
+ if ob.type not in ('MESH', 'CURVE', 'SURFACE', 'TEXT', 'META'):
+ continue
+
+ data = ob_derived.create_mesh(True, 'PREVIEW')
+# data = getMeshFromObject(ob_derived, None, True, False, sce)
if data:
- data.transform(mat, recalc_normals=False)
+ data.transform(mat)
+# data.transform(mat, recalc_normals=False)
mesh_objects.append((ob_derived, data))
mat_ls = data.materials
mat_ls_len = len(mat_ls)
+
# get material/image tuples.
- if data.faceUV:
+ if len(data.uv_textures):
+# if data.faceUV:
if not mat_ls:
mat = mat_name = None
- for f in data.faces:
+ for f, uf in zip(data.faces, data.active_uv_texture.data):
if mat_ls:
- mat_index = f.mat
+ mat_index = f.material_index
+# mat_index = f.mat
if mat_index >= mat_ls_len:
mat_index = f.mat = 0
mat = mat_ls[mat_index]
@@ -924,7 +994,8 @@ def save_3ds(filename):
else: mat_name = None
# else there alredy set to none
- img = f.image
+ img = uf.image
+# img = f.image
if img: img_name = img.name
else: img_name = None
@@ -938,11 +1009,17 @@ def save_3ds(filename):
# Why 0 Why!
for f in data.faces:
- if f.mat >= mat_ls_len:
- f.mat = 0
+ if f.material_index >= mat_ls_len:
+# if f.mat >= mat_ls_len:
+ f.material_index = 0
+ # f.mat = 0
+
+ if free:
+ free_derived_objects(ob)
+
# Make material chunks for all materials used in the meshes:
- for mat_and_image in materialDict.itervalues():
+ for mat_and_image in materialDict.values():
object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1]))
# Give all objects a unique ID and build a dictionary from object name to object id:
@@ -971,7 +1048,10 @@ def save_3ds(filename):
# make a kf object node for the object:
kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id))
'''
- blender_mesh.verts = None
+# if not blender_mesh.users:
+ bpy.data.remove_mesh(blender_mesh)
+# blender_mesh.verts = None
+
i+=i
# Create chunks for all empties:
@@ -1004,16 +1084,47 @@ def save_3ds(filename):
file.close()
# Debugging only: report the exporting time:
- Blender.Window.WaitCursor(0)
- print "3ds export time: %.2f" % (Blender.sys.time() - time1)
+# Blender.Window.WaitCursor(0)
+ print("3ds export time: %.2f" % (time.clock() - time1))
+# print("3ds export time: %.2f" % (Blender.sys.time() - time1))
# Debugging only: dump the chunk hierarchy:
#primary.dump()
-if __name__=='__main__':
- if struct:
- Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds'))
- else:
- Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
-# save_3ds('/test_b.3ds')
+# if __name__=='__main__':
+# if struct:
+# Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds'))
+# else:
+# Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
+# # save_3ds('/test_b.3ds')
+
+class EXPORT_OT_3ds(bpy.types.Operator):
+ '''
+ 3DS Exporter
+ '''
+ __idname__ = "export.3ds"
+ __label__ = 'Export 3DS'
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = [
+ # bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the 3DS file", maxlen= 1024, default= ""),
+ ]
+
+ def execute(self, context):
+ save_3ds(self.path, context)
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self.__operator__)
+ return ('RUNNING_MODAL',)
+
+ def poll(self, context): # Poll isnt working yet
+ print("Poll")
+ return context.active_object != None
+
+bpy.ops.add(EXPORT_OT_3ds)
diff --git a/release/scripts/export_fbx.py b/release/scripts/io/export_fbx.py
index 50357cbfa75..21b1388ebfe 100644
--- a/release/scripts/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -36,11 +36,16 @@ http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-try:
- import time
- # import os # only needed for batch export, nbot used yet
-except:
- time = None # use this to check if they have python modules installed
+import os
+import time
+import math # math.pi
+import shutil # for file copying
+
+# try:
+# import time
+# # import os # only needed for batch export, nbot used yet
+# except:
+# time = None # use this to check if they have python modules installed
# for python 2.3 support
try:
@@ -51,20 +56,21 @@ except:
except:
set = None # so it complains you dont have a !
-# os is only needed for batch 'own dir' option
-try:
- import os
-except:
- os = None
+# # os is only needed for batch 'own dir' option
+# try:
+# import os
+# except:
+# os = None
-import Blender
+# import Blender
import bpy
-from Blender.Mathutils import Matrix, Vector, RotationMatrix
+import Mathutils
+# from Blender.Mathutils import Matrix, Vector, RotationMatrix
-import BPyObject
-import BPyMesh
-import BPySys
-import BPyMessages
+# import BPyObject
+# import BPyMesh
+# import BPySys
+# import BPyMessages
## This was used to make V, but faster not to do all that
##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}'
@@ -75,7 +81,7 @@ invalid = ''.join([chr(i) for i in v])
def cleanName(name):
for ch in invalid: name = name.replace(ch, '_')
return name
-del v, i
+# del v, i
def copy_file(source, dest):
@@ -88,9 +94,10 @@ def copy_file(source, dest):
file.close()
+# XXX not used anymore, images are copied one at a time
def copy_images(dest_dir, textures):
- if not dest_dir.endswith(Blender.sys.sep):
- dest_dir += Blender.sys.sep
+ if not dest_dir.endswith(os.sep):
+ dest_dir += os.sep
image_paths = set()
for tex in textures:
@@ -103,19 +110,30 @@ def copy_images(dest_dir, textures):
# Make a name for the target path.
dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
if not Blender.sys.exists(dest_image_path): # Image isnt alredy there
- print '\tCopying "%s" > "%s"' % (image_path, dest_image_path)
+ print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
try:
copy_file(image_path, dest_image_path)
copyCount+=1
except:
- print '\t\tWarning, file failed to copy, skipping.'
+ print('\t\tWarning, file failed to copy, skipping.')
- print '\tCopied %d images' % copyCount
+ print('\tCopied %d images' % copyCount)
+
+# I guess FBX uses degrees instead of radians (Arystan).
+# Call this function just before writing to FBX.
+def eulerRadToDeg(eul):
+ ret = Mathutils.Euler()
-mtx4_identity = Matrix()
+ ret.x = 180 / math.pi * eul[0]
+ ret.y = 180 / math.pi * eul[1]
+ ret.z = 180 / math.pi * eul[2]
+
+ return ret
+
+mtx4_identity = Mathutils.Matrix()
# testing
-mtx_x90 = RotationMatrix( 90, 3, 'x') # used
+mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used
#mtx_x90n = RotationMatrix(-90, 3, 'x')
#mtx_y90 = RotationMatrix( 90, 3, 'y')
#mtx_y90n = RotationMatrix(-90, 3, 'y')
@@ -123,14 +141,14 @@ mtx_x90 = RotationMatrix( 90, 3, 'x') # used
#mtx_z90n = RotationMatrix(-90, 3, 'z')
#mtx4_x90 = RotationMatrix( 90, 4, 'x')
-mtx4_x90n = RotationMatrix(-90, 4, 'x') # used
+mtx4_x90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'x') # used
#mtx4_y90 = RotationMatrix( 90, 4, 'y')
-mtx4_y90n = RotationMatrix(-90, 4, 'y') # used
-mtx4_z90 = RotationMatrix( 90, 4, 'z') # used
-mtx4_z90n = RotationMatrix(-90, 4, 'z') # used
+mtx4_y90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'y') # used
+mtx4_z90 = Mathutils.RotationMatrix( math.pi/2, 4, 'z') # used
+mtx4_z90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'z') # used
-def strip_path(p):
- return p.split('\\')[-1].split('/')[-1]
+# def strip_path(p):
+# return p.split('\\')[-1].split('/')[-1]
# Used to add the scene name into the filename without using odd chars
sane_name_mapping_ob = {}
@@ -186,7 +204,7 @@ def sane_name(data, dct):
#name = BPySys.cleanName(name)
name = cleanName(name) # use our own
- while name in dct.itervalues(): name = increment_string(name)
+ while name in iter(dct.values()): name = increment_string(name)
if use_other: # even if other is None - orig_name_other will be a string or None
dct[orig_name, orig_name_other] = name
@@ -201,27 +219,70 @@ def sane_texname(data): return sane_name(data, sane_name_mapping_tex)
def sane_takename(data): return sane_name(data, sane_name_mapping_take)
def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
-def derived_paths(fname_orig, basepath, FORCE_CWD=False):
- '''
- fname_orig - blender path, can be relative
- basepath - fname_rel will be relative to this
- FORCE_CWD - dont use the basepath, just add a ./ to the filename.
- use when we know the file will be in the basepath.
- '''
- fname = Blender.sys.expandpath(fname_orig)
- fname_strip = strip_path(fname)
- if FORCE_CWD: fname_rel = '.' + Blender.sys.sep + fname_strip
- else: fname_rel = Blender.sys.relpath(fname, basepath)
- if fname_rel.startswith('//'): fname_rel = '.' + Blender.sys.sep + fname_rel[2:]
- return fname, fname_strip, fname_rel
+# def derived_paths(fname_orig, basepath, FORCE_CWD=False):
+# '''
+# fname_orig - blender path, can be relative
+# basepath - fname_rel will be relative to this
+# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
+# use when we know the file will be in the basepath.
+# '''
+# fname = bpy.sys.expandpath(fname_orig)
+# # fname = Blender.sys.expandpath(fname_orig)
+# fname_strip = os.path.basename(fname)
+# # fname_strip = strip_path(fname)
+# if FORCE_CWD:
+# fname_rel = '.' + os.sep + fname_strip
+# else:
+# fname_rel = bpy.sys.relpath(fname, basepath)
+# # fname_rel = Blender.sys.relpath(fname, basepath)
+# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:]
+# return fname, fname_strip, fname_rel
def mat4x4str(mat):
return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ])
+# XXX not used
+# duplicated in OBJ exporter
+def getVertsFromGroup(me, group_index):
+ ret = []
+
+ for i, v in enumerate(me.verts):
+ for g in v.groups:
+ if g.group == group_index:
+ ret.append((i, g.weight))
+
+ return ret
+
+# ob must be OB_MESH
+def BPyMesh_meshWeight2List(ob):
+ ''' 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.
+ '''
+
+ me = ob.data
+
+ # Clear the vert group.
+ groupNames= [g.name for g in ob.vertex_groups]
+ len_groupNames= len(groupNames)
+
+ if not len_groupNames:
+ # no verts? return a vert aligned empty list
+ return [[] for i in range(len(me.verts))], []
+ else:
+ vWeightList= [[0.0]*len_groupNames for i in range(len(me.verts))]
+
+ for i, v in enumerate(me.verts):
+ for g in v.groups:
+ vWeightList[i][g.group] = g.weight
+
+ return groupNames, vWeightList
+
def meshNormalizedWeights(me):
try: # account for old bad BPyMesh
- groupNames, vWeightList = BPyMesh.meshWeight2List(me)
+ groupNames, vWeightList = BPyMesh_meshWeight2List(me)
+# groupNames, vWeightList = BPyMesh.meshWeight2List(me)
except:
return [],[]
@@ -249,23 +310,23 @@ header_comment = \
# This func can be called with just the filename
def write(filename, batch_objects = None, \
+ context = None,
EXP_OBS_SELECTED = True,
EXP_MESH = True,
EXP_MESH_APPLY_MOD = True,
- EXP_MESH_HQ_NORMALS = False,
+# EXP_MESH_HQ_NORMALS = False,
EXP_ARMATURE = True,
EXP_LAMP = True,
EXP_CAMERA = True,
EXP_EMPTY = True,
EXP_IMAGE_COPY = False,
- GLOBAL_MATRIX = Matrix(),
+ GLOBAL_MATRIX = Mathutils.Matrix(),
ANIM_ENABLE = True,
ANIM_OPTIMIZE = True,
ANIM_OPTIMIZE_PRECISSION = 6,
ANIM_ACTION_ALL = False,
BATCH_ENABLE = False,
BATCH_GROUP = True,
- BATCH_SCENE = False,
BATCH_FILE_PREFIX = '',
BATCH_OWN_DIR = False
):
@@ -277,23 +338,31 @@ def write(filename, batch_objects = None, \
fbxpath = filename
# get the path component of filename
- tmp_exists = Blender.sys.exists(fbxpath)
+ tmp_exists = bpy.sys.exists(fbxpath)
+# tmp_exists = Blender.sys.exists(fbxpath)
if tmp_exists != 2: # a file, we want a path
- while fbxpath and fbxpath[-1] not in ('/', '\\'):
- fbxpath = fbxpath[:-1]
- if not filename:
- Draw.PupMenu('Error%t|Directory does not exist!')
+ fbxpath = os.path.dirname(fbxpath)
+# while fbxpath and fbxpath[-1] not in ('/', '\\'):
+# fbxpath = fbxpath[:-1]
+ if not fbxpath:
+# if not filename:
+ # XXX
+ print('Error%t|Directory does not exist!')
+# Draw.PupMenu('Error%t|Directory does not exist!')
return
-
- tmp_exists = Blender.sys.exists(fbxpath)
+
+ tmp_exists = bpy.sys.exists(fbxpath)
+# tmp_exists = Blender.sys.exists(fbxpath)
if tmp_exists != 2:
- Draw.PupMenu('Error%t|Directory does not exist!')
+ # XXX
+ print('Error%t|Directory does not exist!')
+# Draw.PupMenu('Error%t|Directory does not exist!')
return
- if not fbxpath.endswith(Blender.sys.sep):
- fbxpath += Blender.sys.sep
+ if not fbxpath.endswith(os.sep):
+ fbxpath += os.sep
del tmp_exists
@@ -303,27 +372,31 @@ def write(filename, batch_objects = None, \
data_seq = bpy.data.scenes
# call this function within a loop with BATCH_ENABLE == False
- orig_sce = bpy.data.scenes.active
+ orig_sce = context.scene
+# orig_sce = bpy.data.scenes.active
new_fbxpath = fbxpath # own dir option modifies, we need to keep an original
for data in data_seq: # scene or group
- newname = BATCH_FILE_PREFIX + BPySys.cleanName(data.name)
+ newname = BATCH_FILE_PREFIX + cleanName(data.name)
+# newname = BATCH_FILE_PREFIX + BPySys.cleanName(data.name)
if BATCH_OWN_DIR:
- new_fbxpath = fbxpath + newname + Blender.sys.sep
+ new_fbxpath = fbxpath + newname + os.sep
# path may alredy exist
# TODO - might exist but be a file. unlikely but should probably account for it.
-
- if Blender.sys.exists(new_fbxpath) == 0:
+
+ if bpy.sys.exists(new_fbxpath) == 0:
+# if Blender.sys.exists(new_fbxpath) == 0:
os.mkdir(new_fbxpath)
filename = new_fbxpath + newname + '.fbx'
- print '\nBatch exporting %s as...\n\t"%s"' % (data, filename)
-
+ print('\nBatch exporting %s as...\n\t"%s"' % (data, filename))
+
+ # XXX don't know what to do with this, probably do the same? (Arystan)
if BATCH_GROUP: #group
# group, so objects update properly, add a dummy scene.
sce = bpy.data.scenes.new()
@@ -345,10 +418,11 @@ def write(filename, batch_objects = None, \
# Call self with modified args
# Dont pass batch options since we alredy usedt them
write(filename, data.objects,
+ context,
False,
EXP_MESH,
EXP_MESH_APPLY_MOD,
- EXP_MESH_HQ_NORMALS,
+# EXP_MESH_HQ_NORMALS,
EXP_ARMATURE,
EXP_LAMP,
EXP_CAMERA,
@@ -363,7 +437,8 @@ def write(filename, batch_objects = None, \
if BATCH_GROUP:
# remove temp group scene
- bpy.data.scenes.unlink(sce)
+ bpy.data.remove_scene(sce)
+# bpy.data.scenes.unlink(sce)
bpy.data.scenes.active = orig_sce
@@ -372,7 +447,9 @@ def write(filename, batch_objects = None, \
# end batch support
# Use this for working out paths relative to the export location
- basepath = Blender.sys.dirname(filename)
+ basepath = os.path.dirname(filename) or '.'
+ basepath += os.sep
+# basepath = Blender.sys.dirname(filename)
# ----------------------------------------------
# storage classes
@@ -398,7 +475,8 @@ def write(filename, batch_objects = None, \
self.blenBone = blenBone
self.blenMeshes = {} # fbxMeshObName : mesh
self.fbxArm = fbxArm
- self.restMatrix = blenBone.matrix['ARMATURESPACE']
+ self.restMatrix = blenBone.armature_matrix
+# self.restMatrix = blenBone.matrix['ARMATURESPACE']
# not used yet
# self.restMatrixInv = self.restMatrix.copy().invert()
@@ -407,8 +485,10 @@ def write(filename, batch_objects = None, \
self.parent = None
# not public
- pose = fbxArm.blenObject.getPose()
- self.__pose_bone = pose.bones[self.blenName]
+ pose = fbxArm.blenObject.pose
+# pose = fbxArm.blenObject.getPose()
+ self.__pose_bone = pose.pose_channels[self.blenName]
+# self.__pose_bone = pose.bones[self.blenName]
# store a list if matricies here, (poseMatrix, head, tail)
# {frame:posematrix, frame:posematrix, ...}
@@ -431,8 +511,9 @@ def write(filename, batch_objects = None, \
self.__pose_bone.head.copy(),\
self.__pose_bone.tail.copy() )
'''
-
- self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy()
+
+ self.__anim_poselist[f] = self.__pose_bone.pose_matrix.copy()
+# self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy()
# get pose from frame.
def getPoseMatrix(self, f):# ----------------------------------------------
@@ -473,7 +554,8 @@ def write(filename, batch_objects = None, \
self.fbxGroupNames = []
self.fbxParent = None # set later on IF the parent is in the selection.
if matrixWorld: self.matrixWorld = matrixWorld * GLOBAL_MATRIX
- else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX
+ else: self.matrixWorld = ob.matrix * GLOBAL_MATRIX
+# else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX
self.__anim_poselist = {} # we should only access this
def parRelMatrix(self):
@@ -483,7 +565,8 @@ def write(filename, batch_objects = None, \
return self.matrixWorld
def setPoseFrame(self, f):
- self.__anim_poselist[f] = self.blenObject.matrixWorld.copy()
+ self.__anim_poselist[f] = self.blenObject.matrix.copy()
+# self.__anim_poselist[f] = self.blenObject.matrixWorld.copy()
def getAnimParRelMatrix(self, frame):
if self.fbxParent:
@@ -500,11 +583,12 @@ def write(filename, batch_objects = None, \
matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart()
# Lamps need to be rotated
- if type =='Lamp':
+ if type =='LAMP':
matrix_rot = mtx_x90 * matrix_rot
- elif ob and type =='Camera':
- y = Vector(0,1,0) * matrix_rot
- matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y)
+ elif type =='CAMERA':
+# elif ob and type =='Camera':
+ y = Mathutils.Vector(0,1,0) * matrix_rot
+ matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y)
return matrix_rot
@@ -514,14 +598,16 @@ def write(filename, batch_objects = None, \
- print '\nFBX export starting...', filename
- start_time = Blender.sys.time()
+ print('\nFBX export starting...', filename)
+ start_time = time.clock()
+# start_time = Blender.sys.time()
try:
file = open(filename, 'w')
except:
return False
-
- sce = bpy.data.scenes.active
+
+ sce = context.scene
+# sce = bpy.data.scenes.active
world = sce.world
@@ -553,7 +639,8 @@ def write(filename, batch_objects = None, \
}''' % (curtime))
file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime)
- file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version'))
+ file.write('\nCreator: "Blender3D version 2.5"')
+# file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version'))
pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way
@@ -562,16 +649,19 @@ def write(filename, batch_objects = None, \
'''
Matrix mod is so armature objects can modify their bone matricies
'''
- if isinstance(ob, Blender.Types.BoneType):
+ if isinstance(ob, bpy.types.Bone):
+# if isinstance(ob, Blender.Types.BoneType):
# we know we have a matrix
# matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod)
- matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
+ matrix = mtx4_z90 * ob.armature_matrix # dont apply armature matrix anymore
+# matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
parent = ob.parent
if parent:
#par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod)
- par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
+ par_matrix = mtx4_z90 * parent.armature_matrix # dont apply armature matrix anymore
+# par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
matrix = matrix * par_matrix.copy().invert()
matrix_rot = matrix.rotationPart()
@@ -583,7 +673,7 @@ def write(filename, batch_objects = None, \
else:
# This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore
#if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX
- if ob and not matrix: raise "error: this should never happen!"
+ if ob and not matrix: raise Exception("error: this should never happen!")
matrix_rot = matrix
#if matrix:
@@ -599,8 +689,8 @@ def write(filename, batch_objects = None, \
matrix_rot = mtx_x90 * matrix_rot
rot = tuple(matrix_rot.toEuler())
elif ob and ob.type =='Camera':
- y = Vector(0,1,0) * matrix_rot
- matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y)
+ y = Mathutils.Vector(0,1,0) * matrix_rot
+ matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y)
rot = tuple(matrix_rot.toEuler())
else:
rot = tuple(matrix_rot.toEuler())
@@ -621,7 +711,8 @@ def write(filename, batch_objects = None, \
loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod)
file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc)
- file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot)
+ file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % tuple(eulerRadToDeg(rot)))
+# file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot)
file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale)
return loc, rot, scale, matrix, matrix_rot
@@ -708,7 +799,8 @@ def write(filename, batch_objects = None, \
Property: "Show", "bool", "",1
Property: "NegativePercentShapeSupport", "bool", "",1
Property: "DefaultAttributeIndex", "int", "",0''')
- if ob and type(ob) != Blender.Types.BoneType:
+ if ob and not isinstance(ob, bpy.types.Bone):
+# if ob and type(ob) != Blender.Types.BoneType:
# Only mesh objects have color
file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
file.write('\n\t\t\tProperty: "Size", "double", "",100')
@@ -738,8 +830,9 @@ def write(filename, batch_objects = None, \
((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length)
"""
- file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\
- (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length)
+ file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %
+ (my_bone.blenBone.armature_head - my_bone.blenBone.armature_tail).length)
+# (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length)
#file.write('\n\t\t\tProperty: "LimbLength", "double", "",1')
file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8')
@@ -878,9 +971,12 @@ def write(filename, batch_objects = None, \
'''
Write a blender camera
'''
- render = sce.render
- width = render.sizeX
- height = render.sizeY
+ render = sce.render_data
+ width = render.resolution_x
+ height = render.resolution_y
+# render = sce.render
+# width = render.sizeX
+# height = render.sizeY
aspect = float(width)/height
data = my_cam.blenObject.data
@@ -894,8 +990,10 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
- file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units?
- file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto
+ file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shift_x) # not sure if this is in the correct units?
+# file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units?
+ file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shift_y) # ditto
+# file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto
file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0')
file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0')
file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1')
@@ -927,8 +1025,10 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0')
file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1')
file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0')
- file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart)
- file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart)
+ file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clip_start)
+# file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart)
+ file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clip_end)
+# file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart)
file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0')
file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0')
file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect)
@@ -975,8 +1075,8 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tTypeFlags: "Camera"')
file.write('\n\t\tGeometryVersion: 124')
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
- file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Vector(0,1,0) * matrix_rot) )
- file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Vector(0,0,-1)*matrix_rot) )
+ file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,1,0) * matrix_rot) )
+ file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,0,-1)*matrix_rot) )
#file.write('\n\t\tUp: 0,0,0' )
#file.write('\n\t\tLookAt: 0,0,0' )
@@ -1001,16 +1101,20 @@ def write(filename, batch_objects = None, \
#ePOINT,
#eDIRECTIONAL
#eSPOT
- light_type = light.type
+ light_type_items = {'POINT': 0, 'SUN': 1, 'SPOT': 2, 'HEMI': 3, 'AREA': 4}
+ light_type = light_type_items[light.type]
+# light_type = light.type
if light_type > 2: light_type = 1 # hemi and area lights become directional
-
- mode = light.mode
- if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows:
+
+# mode = light.mode
+ if light.shadow_method == 'RAY_SHADOW' or light.shadow_method == 'BUFFER_SHADOW':
+# if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows:
do_shadow = 1
else:
do_shadow = 0
-
- if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular):
+
+ if light.only_shadow or (not light.diffuse and not light.specular):
+# if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular):
do_light = 0
else:
do_light = 1
@@ -1025,11 +1129,16 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1')
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200
- file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale))
+ if light.type == 'SPOT':
+ file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spot_size * scale))
+# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale))
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
- file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col))
+ file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.color))
+# file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col))
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200
- file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale))
+#
+ # duplication? see ^ (Arystan)
+# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale))
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light)
@@ -1038,7 +1147,8 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
file.write('\n\t\t\tProperty: "DecayType", "enum", "",0')
- file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist)
+ file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.distance)
+# file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist)
file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0')
file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0')
file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0')
@@ -1084,7 +1194,8 @@ def write(filename, batch_objects = None, \
}''')
# Material Settings
- if world: world_amb = world.getAmb()
+ if world: world_amb = tuple(world.ambient_color)
+# if world: world_amb = world.getAmb()
else: world_amb = (0,0,0) # Default value
def write_material(matname, mat):
@@ -1092,22 +1203,31 @@ def write(filename, batch_objects = None, \
# Todo, add more material Properties.
if mat:
- mat_cold = tuple(mat.rgbCol)
- mat_cols = tuple(mat.specCol)
+ mat_cold = tuple(mat.diffuse_color)
+# mat_cold = tuple(mat.rgbCol)
+ mat_cols = tuple(mat.specular_color)
+# mat_cols = tuple(mat.specCol)
#mat_colm = tuple(mat.mirCol) # we wont use the mirror color
- mat_colamb = tuple([c for c in world_amb])
-
- mat_dif = mat.ref
- mat_amb = mat.amb
- mat_hard = (float(mat.hard)-1)/5.10
- mat_spec = mat.spec/2.0
+ mat_colamb = world_amb
+# mat_colamb = tuple([c for c in world_amb])
+
+ mat_dif = mat.diffuse_intensity
+# mat_dif = mat.ref
+ mat_amb = mat.ambient
+# mat_amb = mat.amb
+ mat_hard = (float(mat.specular_hardness)-1)/5.10
+# mat_hard = (float(mat.hard)-1)/5.10
+ mat_spec = mat.specular_intensity/2.0
+# mat_spec = mat.spec/2.0
mat_alpha = mat.alpha
mat_emit = mat.emit
- mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS
+ mat_shadeless = mat.shadeless
+# mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS
if mat_shadeless:
mat_shader = 'Lambert'
else:
- if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT:
+ if mat.diffuse_shader == 'LAMBERT':
+# if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT:
mat_shader = 'Lambert'
else:
mat_shader = 'Phong'
@@ -1159,7 +1279,20 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t}')
file.write('\n\t}')
-
+
+ def copy_image(image):
+
+ rel = image.get_export_path(basepath, True)
+ base = os.path.basename(rel)
+
+ if EXP_IMAGE_COPY:
+ absp = image.get_export_path(basepath, False)
+ if not os.path.exists(absp):
+ shutil.copy(image.get_abs_filename(), absp)
+
+ return (rel, base)
+
+ # tex is an Image (Arystan)
def write_video(texname, tex):
# Same as texture really!
file.write('\n\tVideo: "Video::%s", "Clip" {' % texname)
@@ -1172,7 +1305,8 @@ def write(filename, batch_objects = None, \
Property: "Width", "int", "",0
Property: "Height", "int", "",0''')
if tex:
- fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY)
+ fname_rel, fname_strip = copy_image(tex)
+# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY)
else:
fname = fname_strip = fname_rel = ''
@@ -1221,9 +1355,11 @@ def write(filename, batch_objects = None, \
Property: "UseMipMap", "bool", "",0
Property: "CurrentMappingType", "enum", "",0
Property: "UVSwap", "bool", "",0''')
-
- file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX)
- file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY)
+
+ file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clamp_x)
+# file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX)
+ file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clamp_y)
+# file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY)
file.write('''
Property: "TextureRotationPivot", "Vector3D", "",0,0,0
@@ -1234,7 +1370,8 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tMedia: "Video::%s"' % texname)
if tex:
- fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY)
+ fname_rel, fname_strip = copy_image(tex)
+# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY)
else:
fname = fname_strip = fname_rel = ''
@@ -1290,7 +1427,7 @@ def write(filename, batch_objects = None, \
# TODO - this is a bit lazy, we could have a simple write loop
# for this case because all weights are 1.0 but for now this is ok
# Parent Bones arent used all that much anyway.
- vgroup_data = [(j, 1.0) for j in xrange(len(my_mesh.blenData.verts))]
+ vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.verts))]
else:
# This bone is not a parent of this mesh object, no weights
vgroup_data = []
@@ -1358,7 +1495,8 @@ def write(filename, batch_objects = None, \
if my_mesh.blenTextures: do_textures = True
else: do_textures = False
- do_uvs = me.faceUV
+ do_uvs = len(me.uv_textures) > 0
+# do_uvs = me.faceUV
file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName)
@@ -1390,20 +1528,25 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
- fi = [v.index for v in f]
+ fi = f.verts
+ # fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3]
+# fi = [v.index for v in f]
+
# flip the last index, odd but it looks like
# this is how fbx tells one face from another
fi[-1] = -(fi[-1]+1)
fi = tuple(fi)
if i==-1:
- if len(f) == 3: file.write('%i,%i,%i' % fi )
+ if len(fi) == 3: file.write('%i,%i,%i' % fi )
+# if len(f) == 3: file.write('%i,%i,%i' % fi )
else: file.write('%i,%i,%i,%i' % fi )
i=0
else:
if i==13:
file.write('\n\t\t')
i=0
- if len(f) == 3: file.write(',%i,%i,%i' % fi )
+ if len(fi) == 3: file.write(',%i,%i,%i' % fi )
+# if len(f) == 3: file.write(',%i,%i,%i' % fi )
else: file.write(',%i,%i,%i,%i' % fi )
i+=1
@@ -1411,13 +1554,15 @@ def write(filename, batch_objects = None, \
i=-1
for ed in me.edges:
if i==-1:
- file.write('%i,%i' % (ed.v1.index, ed.v2.index))
+ file.write('%i,%i' % (ed.verts[0], ed.verts[1]))
+# file.write('%i,%i' % (ed.v1.index, ed.v2.index))
i=0
else:
if i==13:
file.write('\n\t\t')
i=0
- file.write(',%i,%i' % (ed.v1.index, ed.v2.index))
+ file.write(',%i,%i' % (ed.verts[0], ed.verts[1]))
+# file.write(',%i,%i' % (ed.v1.index, ed.v2.index))
i+=1
file.write('\n\t\tGeometryVersion: 124')
@@ -1433,11 +1578,13 @@ def write(filename, batch_objects = None, \
i=-1
for v in me.verts:
if i==-1:
- file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0
+ file.write('%.15f,%.15f,%.15f' % tuple(v.normal)); i=0
+# file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0
else:
if i==2:
file.write('\n '); i=0
- file.write(',%.15f,%.15f,%.15f' % tuple(v.no))
+ file.write(',%.15f,%.15f,%.15f' % tuple(v.normal))
+# file.write(',%.15f,%.15f,%.15f' % tuple(v.no))
i+=1
file.write('\n\t\t}')
@@ -1464,39 +1611,53 @@ def write(filename, batch_objects = None, \
# Write Edge Smoothing
file.write('''
- LayerElementSmoothing: 1 {
+ LayerElementSmoothing: 0 {
Version: 101
Name: ""
MappingInformationType: "ByEdge"
ReferenceInformationType: "Direct"
Smoothing: ''')
- SHARP = Blender.Mesh.EdgeFlags.SHARP
+# SHARP = Blender.Mesh.EdgeFlags.SHARP
i=-1
for ed in me.edges:
if i==-1:
- file.write('%i' % ((ed.flag&SHARP)!=0)); i=0
+ file.write('%i' % (ed.sharp)); i=0
+# file.write('%i' % ((ed.flag&SHARP)!=0)); i=0
else:
if i==54:
file.write('\n '); i=0
- file.write(',%i' % ((ed.flag&SHARP)!=0))
+ file.write(',%i' % (ed.sharp))
+# file.write(',%i' % ((ed.flag&SHARP)!=0))
i+=1
file.write('\n\t\t}')
- del SHARP
-
+# del SHARP
+
+ # small utility function
+ # returns a slice of data depending on number of face verts
+ # data is either a MeshTextureFace or MeshColor
+ def face_data(data, face):
+ totvert = len(f.verts)
+
+ return data[:totvert]
+
# Write VertexColor Layers
# note, no programs seem to use this info :/
collayers = []
- if me.vertexColors:
- collayers = me.getColorLayerNames()
- collayer_orig = me.activeColorLayer
+ if len(me.vertex_colors):
+# if me.vertexColors:
+ collayers = me.vertex_colors
+# collayers = me.getColorLayerNames()
+ collayer_orig = me.active_vertex_color
+# collayer_orig = me.activeColorLayer
for colindex, collayer in enumerate(collayers):
- me.activeColorLayer = collayer
+# me.activeColorLayer = collayer
file.write('\n\t\tLayerElementColor: %i {' % colindex)
file.write('\n\t\t\tVersion: 101')
- file.write('\n\t\t\tName: "%s"' % collayer)
+ file.write('\n\t\t\tName: "%s"' % collayer.name)
+# file.write('\n\t\t\tName: "%s"' % collayer)
file.write('''
MappingInformationType: "ByPolygonVertex"
@@ -1505,23 +1666,41 @@ def write(filename, batch_objects = None, \
i = -1
ii = 0 # Count how many Colors we write
-
- for f in me.faces:
- for col in f.col:
+
+ for f, cf in zip(me.faces, collayer.data):
+ colors = [cf.color1, cf.color2, cf.color3, cf.color4]
+
+ # determine number of verts
+ colors = face_data(colors, f)
+
+ for col in colors:
if i==-1:
- file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0))
+ file.write('%.4f,%.4f,%.4f,1' % tuple(col))
i=0
else:
if i==7:
file.write('\n\t\t\t\t')
i=0
- file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0))
+ file.write(',%.4f,%.4f,%.4f,1' % tuple(col))
i+=1
ii+=1 # One more Color
+
+# for f in me.faces:
+# for col in f.col:
+# if i==-1:
+# file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0))
+# i=0
+# else:
+# if i==7:
+# file.write('\n\t\t\t\t')
+# i=0
+# file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0))
+# i+=1
+# ii+=1 # One more Color
file.write('\n\t\t\tColorIndex: ')
i = -1
- for j in xrange(ii):
+ for j in range(ii):
if i == -1:
file.write('%i' % j)
i=0
@@ -1539,13 +1718,17 @@ def write(filename, batch_objects = None, \
# Write UV and texture layers.
uvlayers = []
if do_uvs:
- uvlayers = me.getUVLayerNames()
- uvlayer_orig = me.activeUVLayer
- for uvindex, uvlayer in enumerate(uvlayers):
- me.activeUVLayer = uvlayer
+ uvlayers = me.uv_textures
+# uvlayers = me.getUVLayerNames()
+ uvlayer_orig = me.active_uv_texture
+# uvlayer_orig = me.activeUVLayer
+ for uvindex, uvlayer in enumerate(me.uv_textures):
+# for uvindex, uvlayer in enumerate(uvlayers):
+# me.activeUVLayer = uvlayer
file.write('\n\t\tLayerElementUV: %i {' % uvindex)
file.write('\n\t\t\tVersion: 101')
- file.write('\n\t\t\tName: "%s"' % uvlayer)
+ file.write('\n\t\t\tName: "%s"' % uvlayer.name)
+# file.write('\n\t\t\tName: "%s"' % uvlayer)
file.write('''
MappingInformationType: "ByPolygonVertex"
@@ -1555,8 +1738,10 @@ def write(filename, batch_objects = None, \
i = -1
ii = 0 # Count how many UVs we write
- for f in me.faces:
- for uv in f.uv:
+ for uf in uvlayer.data:
+# for f in me.faces:
+ for uv in uf.uv:
+# for uv in f.uv:
if i==-1:
file.write('%.6f,%.6f' % tuple(uv))
i=0
@@ -1570,7 +1755,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tUVIndex: ')
i = -1
- for j in xrange(ii):
+ for j in range(ii):
if i == -1:
file.write('%i' % j)
i=0
@@ -1586,7 +1771,8 @@ def write(filename, batch_objects = None, \
if do_textures:
file.write('\n\t\tLayerElementTexture: %i {' % uvindex)
file.write('\n\t\t\tVersion: 101')
- file.write('\n\t\t\tName: "%s"' % uvlayer)
+ file.write('\n\t\t\tName: "%s"' % uvlayer.name)
+# file.write('\n\t\t\tName: "%s"' % uvlayer)
if len(my_mesh.blenTextures) == 1:
file.write('\n\t\t\tMappingInformationType: "AllSame"')
@@ -1610,7 +1796,8 @@ def write(filename, batch_objects = None, \
i+=1
i=-1
- for f in me.faces:
+ for f in uvlayer.data:
+# for f in me.faces:
img_key = f.image
if i==-1:
@@ -1636,7 +1823,7 @@ def write(filename, batch_objects = None, \
TextureId: ''')
file.write('\n\t\t}')
- me.activeUVLayer = uvlayer_orig
+# me.activeUVLayer = uvlayer_orig
# Done with UV/textures.
@@ -1665,13 +1852,21 @@ def write(filename, batch_objects = None, \
len_material_mapping_local = len(material_mapping_local)
mats = my_mesh.blenMaterialList
+
+ if me.active_uv_texture:
+ uv_faces = me.active_uv_texture.data
+ else:
+ uv_faces = [None] * len(me.faces)
i=-1
- for f in me.faces:
- try: mat = mats[f.mat]
+ for f, uf in zip(me.faces, uv_faces):
+# for f in me.faces:
+ try: mat = mats[f.material_index]
+# try: mat = mats[f.mat]
except:mat = None
- if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/
+ if do_uvs: tex = uf.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/
+# if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/
else: tex = None
if i==-1:
@@ -1710,7 +1905,8 @@ def write(filename, batch_objects = None, \
TypedIndex: 0
}''')
- if me.vertexColors:
+ if me.vertex_colors:
+# if me.vertexColors:
file.write('''
LayerElement: {
Type: "LayerElementColor"
@@ -1728,7 +1924,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t}')
if len(uvlayers) > 1:
- for i in xrange(1, len(uvlayers)):
+ for i in range(1, len(uvlayers)):
file.write('\n\t\tLayer: %i {' % i)
file.write('\n\t\t\tVersion: 100')
@@ -1756,7 +1952,7 @@ def write(filename, batch_objects = None, \
layer_offset = 0
if uvlayers: layer_offset = len(uvlayers)-1
- for i in xrange(layer_offset, len(collayers)+layer_offset):
+ for i in range(layer_offset, len(collayers)+layer_offset):
file.write('\n\t\tLayer: %i {' % i)
file.write('\n\t\t\tVersion: 100')
@@ -1806,7 +2002,8 @@ def write(filename, batch_objects = None, \
# if EXP_OBS_SELECTED is false, use sceens objects
if not batch_objects:
- if EXP_OBS_SELECTED: tmp_objects = sce.objects.context
+ if EXP_OBS_SELECTED: tmp_objects = context.selected_objects
+# if EXP_OBS_SELECTED: tmp_objects = sce.objects.context
else: tmp_objects = sce.objects
else:
tmp_objects = batch_objects
@@ -1815,43 +2012,63 @@ def write(filename, batch_objects = None, \
# This is needed so applying modifiers dosnt apply the armature deformation, its also needed
# ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes.
# set every armature to its rest, backup the original values so we done mess up the scene
- ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures]
+ ob_arms_orig_rest = [arm.rest_position for arm in bpy.data.armatures]
+# ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures]
for arm in bpy.data.armatures:
- arm.restPosition = True
+ arm.rest_position = True
+# arm.restPosition = True
if ob_arms_orig_rest:
for ob_base in bpy.data.objects:
#if ob_base.type == 'Armature':
- ob_base.makeDisplayList()
+ ob_base.make_display_list()
+# ob_base.makeDisplayList()
# This causes the makeDisplayList command to effect the mesh
- Blender.Set('curframe', Blender.Get('curframe'))
+ sce.set_frame(sce.current_frame)
+# Blender.Set('curframe', Blender.Get('curframe'))
for ob_base in tmp_objects:
- for ob, mtx in BPyObject.getDerivedObjects(ob_base):
- #for ob in [ob_base,]:
+
+ # ignore dupli children
+ if ob_base.parent and ob_base.parent.dupli_type != 'NONE':
+ continue
+
+ obs = [(ob_base, ob_base.matrix)]
+ if ob_base.dupli_type != 'NONE':
+ ob_base.create_dupli_list()
+ obs = [(dob.object, dob.matrix) for dob in ob_base.dupli_list]
+
+ for ob, mtx in obs:
+# for ob, mtx in BPyObject.getDerivedObjects(ob_base):
tmp_ob_type = ob.type
- if tmp_ob_type == 'Camera':
+ if tmp_ob_type == 'CAMERA':
+# if tmp_ob_type == 'Camera':
if EXP_CAMERA:
ob_cameras.append(my_object_generic(ob, mtx))
- elif tmp_ob_type == 'Lamp':
+ elif tmp_ob_type == 'LAMP':
+# elif tmp_ob_type == 'Lamp':
if EXP_LAMP:
ob_lights.append(my_object_generic(ob, mtx))
- elif tmp_ob_type == 'Armature':
+ elif tmp_ob_type == 'ARMATURE':
+# elif tmp_ob_type == 'Armature':
if EXP_ARMATURE:
# TODO - armatures dont work in dupligroups!
if ob not in ob_arms: ob_arms.append(ob)
# ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)"
- elif tmp_ob_type == 'Empty':
+ elif tmp_ob_type == 'EMPTY':
+# elif tmp_ob_type == 'Empty':
if EXP_EMPTY:
ob_null.append(my_object_generic(ob, mtx))
elif EXP_MESH:
origData = True
- if tmp_ob_type != 'Mesh':
- me = bpy.data.meshes.new()
- try: me.getFromObject(ob)
+ if tmp_ob_type != 'MESH':
+# if tmp_ob_type != 'Mesh':
+# me = bpy.data.meshes.new()
+ try: me = ob.create_mesh(True, 'PREVIEW')
+# try: me.getFromObject(ob)
except: me = None
if me:
meshes_to_clear.append( me )
@@ -1860,63 +2077,71 @@ def write(filename, batch_objects = None, \
else:
# Mesh Type!
if EXP_MESH_APPLY_MOD:
- me = bpy.data.meshes.new()
- me.getFromObject(ob)
+# me = bpy.data.meshes.new()
+ me = ob.create_mesh(True, 'PREVIEW')
+# me.getFromObject(ob)
# so we keep the vert groups
- if EXP_ARMATURE:
- orig_mesh = ob.getData(mesh=1)
- if orig_mesh.getVertGroupNames():
- ob.copy().link(me)
- # If new mesh has no vgroups we can try add if verts are teh same
- if not me.getVertGroupNames(): # vgroups were not kept by the modifier
- if len(me.verts) == len(orig_mesh.verts):
- groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh)
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
+# if EXP_ARMATURE:
+# orig_mesh = ob.getData(mesh=1)
+# if orig_mesh.getVertGroupNames():
+# ob.copy().link(me)
+# # If new mesh has no vgroups we can try add if verts are teh same
+# if not me.getVertGroupNames(): # vgroups were not kept by the modifier
+# if len(me.verts) == len(orig_mesh.verts):
+# groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh)
+# BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
# print ob, me, me.getVertGroupNames()
meshes_to_clear.append( me )
origData = False
mats = me.materials
else:
- me = ob.getData(mesh=1)
+ me = ob.data
+# me = ob.getData(mesh=1)
mats = me.materials
- # Support object colors
- tmp_colbits = ob.colbits
- if tmp_colbits:
- tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too.
- for i in xrange(16):
- if tmp_colbits & (1<<i):
- mats[i] = tmp_ob_mats[i]
- del tmp_ob_mats
- del tmp_colbits
+# # Support object colors
+# tmp_colbits = ob.colbits
+# if tmp_colbits:
+# tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too.
+# for i in xrange(16):
+# if tmp_colbits & (1<<i):
+# mats[i] = tmp_ob_mats[i]
+# del tmp_ob_mats
+# del tmp_colbits
if me:
- # This WILL modify meshes in blender if EXP_MESH_APPLY_MOD is disabled.
- # so strictly this is bad. but only in rare cases would it have negative results
- # say with dupliverts the objects would rotate a bit differently
- if EXP_MESH_HQ_NORMALS:
- BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
+# # This WILL modify meshes in blender if EXP_MESH_APPLY_MOD is disabled.
+# # so strictly this is bad. but only in rare cases would it have negative results
+# # say with dupliverts the objects would rotate a bit differently
+# if EXP_MESH_HQ_NORMALS:
+# BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
texture_mapping_local = {}
material_mapping_local = {}
- if me.faceUV:
- uvlayer_orig = me.activeUVLayer
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- for f in me.faces:
- tex = f.image
+ if len(me.uv_textures) > 0:
+# if me.faceUV:
+ uvlayer_orig = me.active_uv_texture
+# uvlayer_orig = me.activeUVLayer
+ for uvlayer in me.uv_textures:
+# for uvlayer in me.getUVLayerNames():
+# me.activeUVLayer = uvlayer
+ for f, uf in zip(me.faces, uvlayer.data):
+# for f in me.faces:
+ tex = uf.image
+# tex = f.image
textures[tex] = texture_mapping_local[tex] = None
- try: mat = mats[f.mat]
+ try: mat = mats[f.material_index]
+# try: mat = mats[f.mat]
except: mat = None
materials[mat, tex] = material_mapping_local[mat, tex] = None # should use sets, wait for blender 2.5
- me.activeUVLayer = uvlayer_orig
+# me.activeUVLayer = uvlayer_orig
else:
for mat in mats:
# 2.44 use mat.lib too for uniqueness
@@ -1925,13 +2150,16 @@ def write(filename, batch_objects = None, \
materials[None, None] = None
if EXP_ARMATURE:
- armob = BPyObject.getObjectArmature(ob)
+ armob = ob.find_armature()
blenParentBoneName = None
# parent bone - special case
- if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE:
+ if (not armob) and ob.parent and ob.parent.type == 'ARMATURE' and \
+ ob.parent_type == 'BONE':
+# if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE:
armob = ob.parent
- blenParentBoneName = ob.parentbonename
+ blenParentBoneName = ob.parent_bone
+# blenParentBoneName = ob.parentbonename
if armob and armob not in ob_arms:
@@ -1943,9 +2171,9 @@ def write(filename, batch_objects = None, \
my_mesh = my_object_generic(ob, mtx)
my_mesh.blenData = me
my_mesh.origData = origData
- my_mesh.blenMaterials = material_mapping_local.keys()
+ my_mesh.blenMaterials = list(material_mapping_local.keys())
my_mesh.blenMaterialList = mats
- my_mesh.blenTextures = texture_mapping_local.keys()
+ my_mesh.blenTextures = list(texture_mapping_local.keys())
# if only 1 null texture then empty the list
if len(my_mesh.blenTextures) == 1 and my_mesh.blenTextures[0] == None:
@@ -1955,18 +2183,26 @@ def write(filename, batch_objects = None, \
my_mesh.fbxBoneParent = blenParentBoneName # replace with my_bone instance later
ob_meshes.append( my_mesh )
-
+
+ # not forgetting to free dupli_list
+ if ob_base.dupli_list: ob_base.free_dupli_list()
+
+
if EXP_ARMATURE:
# now we have the meshes, restore the rest arm position
for i, arm in enumerate(bpy.data.armatures):
- arm.restPosition = ob_arms_orig_rest[i]
+ arm.rest_position = ob_arms_orig_rest[i]
+# arm.restPosition = ob_arms_orig_rest[i]
if ob_arms_orig_rest:
for ob_base in bpy.data.objects:
- if ob_base.type == 'Armature':
- ob_base.makeDisplayList()
+ if ob_base.type == 'ARMATURE':
+# if ob_base.type == 'Armature':
+ ob_base.make_display_list()
+# ob_base.makeDisplayList()
# This causes the makeDisplayList command to effect the mesh
- Blender.Set('curframe', Blender.Get('curframe'))
+ sce.set_frame(sce.current_frame)
+# Blender.Set('curframe', Blender.Get('curframe'))
del tmp_ob_type, tmp_objects
@@ -1977,13 +2213,18 @@ def write(filename, batch_objects = None, \
my_arm.fbxBones = []
my_arm.blenData = ob.data
- my_arm.blenAction = ob.action
+ if ob.animation_data:
+ my_arm.blenAction = ob.animation_data.action
+ else:
+ my_arm.blenAction = None
+# my_arm.blenAction = ob.action
my_arm.blenActionList = []
# fbxName, blenderObject, my_bones, blenderActions
#ob_arms[i] = fbxArmObName, ob, arm_my_bones, (ob.action, [])
- for bone in my_arm.blenData.bones.values():
+ for bone in my_arm.blenData.bones:
+# for bone in my_arm.blenData.bones.values():
my_bone = my_bone_class(bone, my_arm)
my_arm.fbxBones.append( my_bone )
ob_bones.append( my_bone )
@@ -2032,18 +2273,25 @@ def write(filename, batch_objects = None, \
# Build blenObject -> fbxObject mapping
# this is needed for groups as well as fbxParenting
- bpy.data.objects.tag = False
+# for ob in bpy.data.objects: ob.tag = False
+# bpy.data.objects.tag = False
+
+ # using a list of object names for tagging (Arystan)
+ tagged_objects = []
+
tmp_obmapping = {}
for ob_generic in ob_all_typegroups:
for ob_base in ob_generic:
- ob_base.blenObject.tag = True
+ tagged_objects.append(ob_base.blenObject.name)
+# ob_base.blenObject.tag = True
tmp_obmapping[ob_base.blenObject] = ob_base
# Build Groups from objects we export
for blenGroup in bpy.data.groups:
fbxGroupName = None
for ob in blenGroup.objects:
- if ob.tag:
+ if ob.name in tagged_objects:
+# if ob.tag:
if fbxGroupName == None:
fbxGroupName = sane_groupname(blenGroup)
groups.append((fbxGroupName, blenGroup))
@@ -2056,7 +2304,8 @@ def write(filename, batch_objects = None, \
for ob_generic in ob_all_typegroups:
for my_ob in ob_generic:
parent = my_ob.blenObject.parent
- if parent and parent.tag: # does it exist and is it in the mapping
+ if parent and parent.name in tagged_objects: # does it exist and is it in the mapping
+# if parent and parent.tag: # does it exist and is it in the mapping
my_ob.fbxParent = tmp_obmapping[parent]
@@ -2064,8 +2313,8 @@ def write(filename, batch_objects = None, \
# Finished finding groups we use
- materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.iterkeys()]
- textures = [(sane_texname(tex), tex) for tex in textures.iterkeys() if tex]
+ materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.keys()]
+ textures = [(sane_texname(tex), tex) for tex in textures.keys() if tex]
materials.sort() # sort by name
textures.sort()
@@ -2220,11 +2469,12 @@ Objects: {''')
if my_mesh.fbxBoneParent:
weights = None
else:
- weights = meshNormalizedWeights(my_mesh.blenData)
+ weights = meshNormalizedWeights(my_mesh.blenObject)
+# weights = meshNormalizedWeights(my_mesh.blenData)
#for bonename, bone, obname, bone_mesh, armob in ob_bones:
for my_bone in ob_bones:
- if me in my_bone.blenMeshes.itervalues():
+ if me in iter(my_bone.blenMeshes.values()):
write_sub_deformer_skin(my_mesh, my_bone, weights)
# Write pose's really weired, only needed when an armature and mesh are used together
@@ -2426,7 +2676,8 @@ Connections: {''')
# Needed for scene footer as well as animation
- render = sce.render
+ render = sce.render_data
+# render = sce.render
# from the FBX sdk
#define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000))
@@ -2435,8 +2686,10 @@ Connections: {''')
return int(0.5 + ((t/fps) * 46186158000))
fps = float(render.fps)
- start = render.sFrame
- end = render.eFrame
+ start = sce.start_frame
+# start = render.sFrame
+ end = sce.end_frame
+# end = render.eFrame
if end < start: start, end = end, start
if start==end: ANIM_ENABLE = False
@@ -2445,7 +2698,8 @@ Connections: {''')
if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]:
- frame_orig = Blender.Get('curframe')
+ frame_orig = sce.current_frame
+# frame_orig = Blender.Get('curframe')
if ANIM_OPTIMIZE:
ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION
@@ -2454,9 +2708,12 @@ Connections: {''')
tmp_actions = [None] # None is the default action
blenActionDefault = None
action_lastcompat = None
+
+ # instead of tagging
+ tagged_actions = []
if ANIM_ACTION_ALL:
- bpy.data.actions.tag = False
+# bpy.data.actions.tag = False
tmp_actions = list(bpy.data.actions)
@@ -2472,12 +2729,14 @@ Connections: {''')
arm_bone_names = set([my_bone.blenName for my_bone in my_arm.fbxBones])
for action in tmp_actions:
-
- action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) )
+
+ action_chan_names = arm_bone_names.intersection( set([g.name for g in action.groups]) )
+# action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) )
if action_chan_names: # at least one channel matches.
my_arm.blenActionList.append(action)
- action.tag = True
+ tagged_actions.append(action.name)
+# action.tag = True
tmp_act_count += 1
# incase there is no actions applied to armatures
@@ -2504,10 +2763,11 @@ Takes: {''')
for blenAction in tmp_actions:
# we have tagged all actious that are used be selected armatures
if blenAction:
- if blenAction.tag:
- print '\taction: "%s" exporting...' % blenAction.name
+ if blenAction.name in tagged_actions:
+# if blenAction.tag:
+ print('\taction: "%s" exporting...' % blenAction.name)
else:
- print '\taction: "%s" has no armature using it, skipping' % blenAction.name
+ print('\taction: "%s" has no armature using it, skipping' % blenAction.name)
continue
if blenAction == None:
@@ -2521,17 +2781,18 @@ Takes: {''')
file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name])
else:
file.write('\n\tTake: "%s" {' % sane_takename(blenAction))
-
- tmp = blenAction.getFrameNumbers()
- if tmp:
- act_start = min(tmp)
- act_end = max(tmp)
- del tmp
- else:
- # Fallback on this, theres not much else we can do? :/
- # when an action has no length
- act_start = start
- act_end = end
+
+ act_start, act_end = blenAction.get_frame_range()
+# tmp = blenAction.getFrameNumbers()
+# if tmp:
+# act_start = min(tmp)
+# act_end = max(tmp)
+# del tmp
+# else:
+# # Fallback on this, theres not much else we can do? :/
+# # when an action has no length
+# act_start = start
+# act_end = end
# Set the action active
for my_bone in ob_arms:
@@ -2558,7 +2819,8 @@ Takes: {''')
'''
i = act_start
while i <= act_end:
- Blender.Set('curframe', i)
+ sce.set_frame(i)
+# Blender.Set('curframe', i)
for ob_generic in ob_anim_lists:
for my_ob in ob_generic:
#Blender.Window.RedrawAll()
@@ -2585,7 +2847,7 @@ Takes: {''')
file.write('\n\t\t\tVersion: 1.1')
file.write('\n\t\t\tChannel: "Transform" {')
- context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in xrange(act_start, act_end+1) ]
+ context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in range(act_start, act_end+1) ]
# ----------------
# ----------------
@@ -2603,11 +2865,12 @@ Takes: {''')
for mtx in context_bone_anim_mats:
if prev_eul: prev_eul = mtx[1].toEuler(prev_eul)
else: prev_eul = mtx[1].toEuler()
- context_bone_anim_vecs.append(prev_eul)
+ context_bone_anim_vecs.append(eulerRadToDeg(prev_eul))
+# context_bone_anim_vecs.append(prev_eul)
file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation
- for i in xrange(3):
+ for i in range(3):
# Loop on each axis of the bone
file.write('\n\t\t\t\t\tChannel: "%s" {'% ('XYZ'[i])) # translation
file.write('\n\t\t\t\t\t\tDefault: %.15f' % context_bone_anim_vecs[0][i] )
@@ -2694,8 +2957,9 @@ Takes: {''')
my_bone.blenObject.action = my_bone.blenAction
file.write('\n}')
-
- Blender.Set('curframe', frame_orig)
+
+ sce.set_frame(frame_orig)
+# Blender.Set('curframe', frame_orig)
else:
# no animation
@@ -2713,15 +2977,21 @@ Takes: {''')
# Clear mesh data Only when writing with modifiers applied
for me in meshes_to_clear:
- me.verts = None
-
-
+ bpy.data.remove_mesh(me)
+# me.verts = None
# --------------------------- Footer
if world:
- has_mist = world.mode & 1
- mist_intense, mist_start, mist_end, mist_height = world.mist
- world_hor = world.hor
+ m = world.mist
+ has_mist = m.enabled
+# has_mist = world.mode & 1
+ mist_intense = m.intensity
+ mist_start = m.start
+ mist_end = m.depth
+ mist_height = m.height
+# mist_intense, mist_start, mist_end, mist_height = world.mist
+ world_hor = world.horizon_color
+# world_hor = world.hor
else:
has_mist = mist_intense = mist_start = mist_end = mist_height = 0
world_hor = 0,0,0
@@ -2771,17 +3041,19 @@ Takes: {''')
# copy images if enabled
- if EXP_IMAGE_COPY:
- copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ])
+# if EXP_IMAGE_COPY:
+# # copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ])
+# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath)
- print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time)
+ print('export finished in %.4f sec.' % (time.clock() - start_time))
+# print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time)
return True
# --------------------------------------------
# UI Function - not a part of the exporter.
# this is to seperate the user interface from the rest of the exporter.
-from Blender import Draw, Window
+# from Blender import Draw, Window
EVENT_NONE = 0
EVENT_EXIT = 1
EVENT_REDRAW = 2
@@ -2804,11 +3076,6 @@ def do_obs_sce(e,v):
GLOBALS['EXP_OBS_SCENE'].val = 1
GLOBALS['EXP_OBS_SELECTED'].val = 0
-def do_obs_sce(e,v):
- GLOBALS['EVENT'] = e
- GLOBALS['EXP_OBS_SCENE'].val = 1
- GLOBALS['EXP_OBS_SELECTED'].val = 0
-
def do_batch_type_grp(e,v):
GLOBALS['EVENT'] = e
GLOBALS['BATCH_GROUP'].val = 1
@@ -2837,21 +3104,21 @@ def fbx_ui_exit(e,v):
def do_help(e,v):
url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx'
- print 'Trying to open web browser with documentation at this address...'
- print '\t' + url
+ print('Trying to open web browser with documentation at this address...')
+ print('\t' + url)
try:
import webbrowser
webbrowser.open(url)
except:
Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation")
- print '...could not open a browser window.'
+ print('...could not open a browser window.')
# run when export is pressed
#def fbx_ui_write(e,v):
-def fbx_ui_write(filename):
+def fbx_ui_write(filename, context):
# Dont allow overwriting files when saving normally
if not GLOBALS['BATCH_ENABLE'].val:
@@ -2874,6 +3141,7 @@ def fbx_ui_write(filename):
ret = write(\
filename, None,\
+ context,
GLOBALS['EXP_OBS_SELECTED'].val,\
GLOBALS['EXP_MESH'].val,\
GLOBALS['EXP_MESH_APPLY_MOD'].val,\
@@ -3071,14 +3339,115 @@ def write_ui():
# GLOBALS.clear()
-#test = [write_ui]
-if __name__ == '__main__':
- # Cant call the file selector first because of a bug in the interface that crashes it.
- # Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx'))
- #write('/scratch/test.fbx')
- #write_ui('/scratch/test.fbx')
-
- if not set:
- Draw.PupMenu('Error%t|A full install of python2.3 or python 2.4+ is needed to run this script.')
- else:
- write_ui()
+
+class EXPORT_OT_fbx(bpy.types.Operator):
+ '''
+ Operator documentation text, will be used for the operator tooltip and python docs.
+ '''
+ __idname__ = "export.fbx"
+ __label__ = "Export FBX"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = [
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default= ""),
+
+ bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True),
+# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True),
+ bpy.props.FloatProperty(attr="_SCALE", name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0),
+ bpy.props.BoolProperty(attr="_XROT90", name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True),
+ bpy.props.BoolProperty(attr="_YROT90", name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False),
+ bpy.props.BoolProperty(attr="_ZROT90", name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False),
+ bpy.props.BoolProperty(attr="EXP_EMPTY", name="Empties", description="Export empty objects", default=True),
+ bpy.props.BoolProperty(attr="EXP_CAMERA", name="Cameras", description="Export camera objects", default=True),
+ bpy.props.BoolProperty(attr="EXP_LAMP", name="Lamps", description="Export lamp objects", default=True),
+ bpy.props.BoolProperty(attr="EXP_ARMATURE", name="Armatures", description="Export armature objects", default=True),
+ bpy.props.BoolProperty(attr="EXP_MESH", name="Meshes", description="Export mesh objects", default=True),
+ bpy.props.BoolProperty(attr="EXP_MESH_APPLY_MOD", name="Modifiers", description="Apply modifiers to mesh objects", default=True),
+ bpy.props.BoolProperty(attr="EXP_MESH_HQ_NORMALS", name="HQ Normals", description="Generate high quality normals", default=True),
+ bpy.props.BoolProperty(attr="EXP_IMAGE_COPY", name="Copy Image Files", description="Copy image files to the destination path", default=False),
+ # armature animation
+ bpy.props.BoolProperty(attr="ANIM_ENABLE", name="Enable Animation", description="Export keyframe animation", default=True),
+ bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True),
+ bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0),
+# bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True),
+ bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures, if false, use current action", default=False),
+ # batch
+ bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False),
+ bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False),
+ bpy.props.BoolProperty(attr="BATCH_OWN_DIR", name="Own Dir", description="Create a dir for each exported file", default=True),
+ bpy.props.StringProperty(attr="BATCH_FILE_PREFIX", name="Prefix", description="Prefix each file with this name", maxlen= 1024, default=""),
+ ]
+
+ def poll(self, context):
+ print("Poll")
+ return context.active_object != None
+
+ def execute(self, context):
+ if not self.path:
+ raise Exception("path not set")
+
+ GLOBAL_MATRIX = mtx4_identity
+ GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self._SCALE
+ if self._XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n
+ if self._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
+ if self._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
+
+ write(self.path,
+ None, # XXX
+ context,
+ self.EXP_OBS_SELECTED,
+ self.EXP_MESH,
+ self.EXP_MESH_APPLY_MOD,
+# self.EXP_MESH_HQ_NORMALS,
+ self.EXP_ARMATURE,
+ self.EXP_LAMP,
+ self.EXP_CAMERA,
+ self.EXP_EMPTY,
+ self.EXP_IMAGE_COPY,
+ GLOBAL_MATRIX,
+ self.ANIM_ENABLE,
+ self.ANIM_OPTIMIZE,
+ self.ANIM_OPTIMIZE_PRECISSION,
+ self.ANIM_ACTION_ALL,
+ self.BATCH_ENABLE,
+ self.BATCH_GROUP,
+ self.BATCH_FILE_PREFIX,
+ self.BATCH_OWN_DIR)
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self.__operator__)
+ return ('RUNNING_MODAL',)
+
+
+bpy.ops.add(EXPORT_OT_fbx)
+
+# if __name__ == "__main__":
+# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
+
+
+# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
+# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print
+# - get rid of cleanName somehow
+# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565
+# + get rid of BPyObject_getObjectArmature, move it in RNA?
+# - BATCH_ENABLE and BATCH_GROUP options: line 327
+# - implement all BPyMesh_* used here with RNA
+# - getDerivedObjects is not fully replicated with .dupli* funcs
+# - talk to Campbell, this code won't work? lines 1867-1875
+# - don't know what those colbits are, do we need them? they're said to be deprecated in DNA_object_types.h: 1886-1893
+# - no hq normals: 1900-1901
+
+# TODO
+
+# - bpy.data.remove_scene: line 366
+# - bpy.sys.time move to bpy.sys.util?
+# - new scene creation, activation: lines 327-342, 368
+# - uses bpy.sys.expandpath, *.relpath - replace at least relpath
+
+# SMALL or COSMETICAL
+# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py
new file mode 100644
index 00000000000..83b400816e3
--- /dev/null
+++ b/release/scripts/io/export_obj.py
@@ -0,0 +1,996 @@
+#!BPY
+
+"""
+Name: 'Wavefront (.obj)...'
+Blender: 248
+Group: 'Export'
+Tooltip: 'Save a Wavefront OBJ File'
+"""
+
+__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
+__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
+__version__ = "1.21"
+
+__bpydoc__ = """\
+This script is an exporter to OBJ file format.
+
+Usage:
+
+Select the objects you wish to export and run this script from "File->Export" menu.
+Selecting the default options from the popup box will be good in most cases.
+All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
+will be exported as mesh data.
+"""
+
+
+# --------------------------------------------------------------------------
+# OBJ Export v1.1 by Campbell Barton (AKA Ideasman)
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You 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 *****
+# --------------------------------------------------------------------------
+
+# import math and other in functions that use them for the sake of fast Blender startup
+# import math
+import os
+import time
+
+import bpy
+import Mathutils
+
+
+# Returns a tuple - path,extension.
+# 'hello.obj' > ('hello', '.obj')
+def splitExt(path):
+ dotidx = path.rfind('.')
+ if dotidx == -1:
+ return path, ''
+ else:
+ return path[:dotidx], path[dotidx:]
+
+def fixName(name):
+ if name == None:
+ return 'None'
+ else:
+ return name.replace(' ', '_')
+
+
+# this used to be in BPySys module
+# frankly, I don't understand how it works
+def BPySys_cleanName(name):
+
+ v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
+
+ invalid = ''.join([chr(i) for i in v])
+
+ for ch in invalid:
+ name = name.replace(ch, '_')
+ return name
+
+# A Dict of Materials
+# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
+MTL_DICT = {}
+
+def write_mtl(scene, filename, copy_images):
+
+ world = scene.world
+ worldAmb = world.ambient_color
+
+ dest_dir = os.path.dirname(filename)
+
+ def copy_image(image):
+ rel = image.get_export_path(dest_dir, True)
+
+ if copy_images:
+ abspath = image.get_export_path(dest_dir, False)
+ if not os.path.exists(abs_path):
+ shutil.copy(image.get_abs_filename(), abs_path)
+
+ return rel
+
+
+ file = open(filename, "w")
+ # XXX
+# file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1])
+ file.write('# Material Count: %i\n' % len(MTL_DICT))
+ # Write material/image combinations we have used.
+ for key, (mtl_mat_name, mat, img) in MTL_DICT.items():
+
+ # Get the Blender data for the material and the image.
+ # Having an image named None will make a bug, dont do it :)
+
+ file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
+
+ if mat:
+ file.write('Ns %.6f\n' % ((mat.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_intensity for c in mat.diffuse_color]) ) # Diffuse
+ file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_intensity for c in mat.specular_color]) ) # Specular
+ if hasattr(mat, "ior"):
+ file.write('Ni %.6f\n' % mat.ior) # Refraction index
+ else:
+ file.write('Ni %.6f\n' % 1.0)
+ file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
+
+ # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
+ if mat.shadeless:
+ file.write('illum 0\n') # ignore lighting
+ elif mat.specular_intensity == 0:
+ file.write('illum 1\n') # no specular.
+ else:
+ file.write('illum 2\n') # light normaly
+
+ else:
+ #write a dummy material here?
+ file.write('Ns 0\n')
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Kd 0.8 0.8 0.8\n')
+ file.write('Ks 0.8 0.8 0.8\n')
+ file.write('d 1\n') # No alpha
+ file.write('illum 2\n') # light normaly
+
+ # Write images!
+ if img: # We have an image on the face!
+ # write relative image path
+ rel = copy_image(img)
+ file.write('map_Kd %s\n' % rel) # Diffuse mapping image
+# file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
+
+ elif mat: # No face image. if we havea material search for MTex image.
+ for mtex in mat.textures:
+ if mtex and mtex.texture.type == 'IMAGE':
+ try:
+ filename = copy_image(mtex.texture.image)
+# filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1]
+ file.write('map_Kd %s\n' % filename) # Diffuse mapping image
+ break
+ except:
+ # Texture has no image though its an image type, best ignore.
+ pass
+
+ file.write('\n\n')
+
+ file.close()
+
+# XXX not used
+def copy_file(source, dest):
+ file = open(source, 'rb')
+ data = file.read()
+ file.close()
+
+ file = open(dest, 'wb')
+ file.write(data)
+ file.close()
+
+
+# XXX not used
+def copy_images(dest_dir):
+ if dest_dir[-1] != os.sep:
+ dest_dir += os.sep
+# if dest_dir[-1] != sys.sep:
+# dest_dir += sys.sep
+
+ # Get unique image names
+ uniqueImages = {}
+ for matname, mat, image in MTL_DICT.values(): # Only use image name
+ # Get Texface images
+ if image:
+ uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default.
+
+ # Get MTex images
+ if mat:
+ for mtex in mat.textures:
+ if mtex and mtex.texture.type == 'IMAGE':
+ image_tex = mtex.texture.image
+ if image_tex:
+ try:
+ uniqueImages[image_tex] = image_tex
+ except:
+ pass
+
+ # Now copy images
+ copyCount = 0
+
+# for bImage in uniqueImages.values():
+# image_path = bpy.sys.expandpath(bImage.filename)
+# if bpy.sys.exists(image_path):
+# # Make a name for the target path.
+# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
+# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there
+# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
+# copy_file(image_path, dest_image_path)
+# copyCount+=1
+
+# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir)
+
+ print('\tCopied %d images' % copyCount)
+# print('\tCopied %d images' % copyCount)
+
+# XXX not converted
+def test_nurbs_compat(ob):
+ if ob.type != 'Curve':
+ return False
+
+ for nu in ob.data:
+ if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier
+ return True
+
+ return False
+
+
+# XXX not converted
+def write_nurb(file, ob, ob_mat):
+ tot_verts = 0
+ cu = ob.data
+
+ # use negative indices
+ Vector = Blender.Mathutils.Vector
+ for nu in cu:
+
+ if nu.type==0: DEG_ORDER_U = 1
+ else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct
+
+ if nu.type==1:
+ print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported")
+ continue
+
+ if nu.knotsV:
+ print("\tWarning, surface:", ob.name, "only poly and nurbs curves supported")
+ continue
+
+ if len(nu) <= DEG_ORDER_U:
+ print("\tWarning, orderU is lower then vert count, skipping:", ob.name)
+ continue
+
+ pt_num = 0
+ do_closed = (nu.flagU & 1)
+ do_endpoints = (do_closed==0) and (nu.flagU & 2)
+
+ for pt in nu:
+ pt = Vector(pt[0], pt[1], pt[2]) * ob_mat
+ file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2]))
+ pt_num += 1
+ tot_verts += pt_num
+
+ file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too
+ file.write('cstype bspline\n') # not ideal, hard coded
+ file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still
+
+ curve_ls = [-(i+1) for i in range(pt_num)]
+
+ # 'curv' keyword
+ if do_closed:
+ if DEG_ORDER_U == 1:
+ pt_num += 1
+ curve_ls.append(-1)
+ else:
+ pt_num += DEG_ORDER_U
+ curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U]
+
+ file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve
+
+ # 'parm' keyword
+ tot_parm = (DEG_ORDER_U + 1) + pt_num
+ tot_parm_div = float(tot_parm-1)
+ parm_ls = [(i/tot_parm_div) for i in range(tot_parm)]
+
+ if do_endpoints: # end points, force param
+ for i in range(DEG_ORDER_U+1):
+ parm_ls[i] = 0.0
+ parm_ls[-(1+i)] = 1.0
+
+ file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] ))
+
+ file.write('end\n')
+
+ return tot_verts
+
+def write(filename, objects, scene,
+ EXPORT_TRI=False,
+ EXPORT_EDGES=False,
+ EXPORT_NORMALS=False,
+ EXPORT_NORMALS_HQ=False,
+ EXPORT_UV=True,
+ EXPORT_MTL=True,
+ EXPORT_COPY_IMAGES=False,
+ EXPORT_APPLY_MODIFIERS=True,
+ EXPORT_ROTX90=True,
+ EXPORT_BLEN_OBS=True,
+ EXPORT_GROUP_BY_OB=False,
+ EXPORT_GROUP_BY_MAT=False,
+ EXPORT_KEEP_VERT_ORDER=False,
+ EXPORT_POLYGROUPS=False,
+ EXPORT_CURVE_AS_NURBS=True):
+ '''
+ Basic write function. The context and options must be alredy set
+ This can be accessed externaly
+ eg.
+ write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
+ '''
+
+ # XXX
+ import math
+
+ def veckey3d(v):
+ return round(v.x, 6), round(v.y, 6), round(v.z, 6)
+
+ def veckey2d(v):
+ return round(v[0], 6), round(v[1], 6)
+ # return round(v.x, 6), round(v.y, 6)
+
+ def findVertexGroupName(face, vWeightMap):
+ """
+ Searches the vertexDict to see what groups is assigned to a given face.
+ We use a frequency system in order to sort out the name because a given vetex can
+ belong to two or more groups at the same time. To find the right name for the face
+ we list all the possible vertex group names with their frequency and then sort by
+ frequency in descend order. The top element is the one shared by the highest number
+ of vertices is the face's group
+ """
+ weightDict = {}
+ for vert_index in face.verts:
+# for vert in face:
+ vWeights = vWeightMap[vert_index]
+# vWeights = vWeightMap[vert]
+ for vGroupName, weight in vWeights:
+ weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight
+
+ if weightDict:
+ alist = [(weight,vGroupName) for vGroupName, weight in weightDict.items()] # sort least to greatest amount of weight
+ alist.sort()
+ return(alist[-1][1]) # highest value last
+ else:
+ return '(null)'
+
+ # TODO: implement this in C? dunno how it should be called...
+ def getVertsFromGroup(me, group_index):
+ ret = []
+
+ for i, v in enumerate(me.verts):
+ for g in v.groups:
+ if g.group == group_index:
+ ret.append((i, g.weight))
+
+ return ret
+
+
+ print('OBJ Export path: "%s"' % filename)
+ temp_mesh_name = '~tmp-mesh'
+
+ time1 = time.clock()
+# time1 = sys.time()
+# scn = Scene.GetCurrent()
+
+ file = open(filename, "w")
+
+ # Write Header
+ version = "2.5"
+ file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
+ file.write('# www.blender3d.org\n')
+
+ # Tell the obj file what material file to use.
+ if EXPORT_MTL:
+ mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1])
+ file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] ))
+
+ if EXPORT_ROTX90:
+ mat_xrot90= Mathutils.RotationMatrix(-math.pi/2, 4, 'x')
+
+ # Initialize totals, these are updated each object
+ totverts = totuvco = totno = 1
+
+ face_vert_index = 1
+
+ globalNormals = {}
+
+ # Get all meshes
+ for ob_main in objects:
+
+ # ignore dupli children
+ if ob_main.parent and ob_main.parent.dupli_type != 'NONE':
+ # XXX
+ print(ob_main.name, 'is a dupli child - ignoring')
+ continue
+
+ obs = []
+ if ob_main.dupli_type != 'NONE':
+ # XXX
+ print('creating dupli_list on', ob_main.name)
+ ob_main.create_dupli_list()
+
+ obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list]
+
+ # XXX debug print
+ print(ob_main.name, 'has', len(obs), 'dupli children')
+ else:
+ obs = [(ob_main, ob_main.matrix)]
+
+ for ob, ob_mat in obs:
+
+ # XXX postponed
+# # Nurbs curve support
+# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
+# if EXPORT_ROTX90:
+# ob_mat = ob_mat * mat_xrot90
+
+# totverts += write_nurb(file, ob, ob_mat)
+
+# continue
+# end nurbs
+
+ if ob.type != 'MESH':
+ continue
+
+ me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW')
+
+ if EXPORT_ROTX90:
+ me.transform(ob_mat * mat_xrot90)
+ else:
+ me.transform(ob_mat)
+
+# # Will work for non meshes now! :)
+# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn)
+# if not me:
+# continue
+
+ if EXPORT_UV:
+ faceuv = len(me.uv_textures) > 0
+ else:
+ faceuv = False
+
+ # XXX - todo, find a better way to do triangulation
+ # ...removed convert_to_triface because it relies on editmesh
+ '''
+ # We have a valid mesh
+ if EXPORT_TRI and me.faces:
+ # Add a dummy object to it.
+ has_quads = False
+ for f in me.faces:
+ if f.verts[3] != 0:
+ has_quads = True
+ break
+
+ if has_quads:
+ newob = bpy.data.add_object('MESH', 'temp_object')
+ newob.data = me
+ # if we forget to set Object.data - crash
+ scene.add_object(newob)
+ newob.convert_to_triface(scene)
+ # mesh will still be there
+ scene.remove_object(newob)
+ '''
+
+ # Make our own list so it can be sorted to reduce context switching
+ face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)]
+ # faces = [ f for f in me.faces ]
+
+ if EXPORT_EDGES:
+ edges = me.edges
+ else:
+ edges = []
+
+ if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write
+
+ # clean up
+ bpy.data.remove_mesh(me)
+
+ continue # dont bother with this mesh.
+
+ # XXX
+ # High Quality Normals
+ if EXPORT_NORMALS and face_index_pairs:
+ me.calc_normals()
+# if EXPORT_NORMALS_HQ:
+# BPyMesh.meshCalcNormals(me)
+# else:
+# # transforming normals is incorrect
+# # when the matrix is scaled,
+# # better to recalculate them
+# me.calcNormals()
+
+ materials = me.materials
+
+ materialNames = []
+ materialItems = [m for m in materials]
+ if materials:
+ for mat in materials:
+ if mat: # !=None
+ materialNames.append(mat.name)
+ else:
+ materialNames.append(None)
+ # Cant use LC because some materials are None.
+ # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken.
+
+ # Possible there null materials, will mess up indicies
+ # but at least it will export, wait until Blender gets fixed.
+ materialNames.extend((16-len(materialNames)) * [None])
+ materialItems.extend((16-len(materialItems)) * [None])
+
+ # Sort by Material, then images
+ # so we dont over context switch in the obj file.
+ if EXPORT_KEEP_VERT_ORDER:
+ pass
+ elif faceuv:
+ # XXX update
+ tface = me.active_uv_texture.data
+
+ # exception only raised if Python 2.3 or lower...
+ try:
+ face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth))
+ except:
+ face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth),
+ (b[0].material_index, tface[b[1]].image, b[0].smooth)))
+ elif len(materials) > 1:
+ try:
+ face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth))
+ except:
+ face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth),
+ (b[0].material_index, b[0].smooth)))
+ else:
+ # no materials
+ try:
+ face_index_pairs.sort(key = lambda a: a[0].smooth)
+ except:
+ face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth))
+# if EXPORT_KEEP_VERT_ORDER:
+# pass
+# elif faceuv:
+# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth))
+# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth)))
+# elif len(materials) > 1:
+# try: faces.sort(key = lambda a: (a.mat, a.smooth))
+# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth)))
+# else:
+# # no materials
+# try: faces.sort(key = lambda a: a.smooth)
+# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth))
+
+ faces = [pair[0] for pair in face_index_pairs]
+
+ # Set the default mat to no material and no image.
+ contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get.
+ contextSmooth = None # Will either be true or false, set bad to force initialization switch.
+
+ if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB:
+ name1 = ob.name
+ name2 = ob.data.name
+ if name1 == name2:
+ obnamestring = fixName(name1)
+ else:
+ obnamestring = '%s_%s' % (fixName(name1), fixName(name2))
+
+ if EXPORT_BLEN_OBS:
+ file.write('o %s\n' % obnamestring) # Write Object name
+ else: # if EXPORT_GROUP_BY_OB:
+ file.write('g %s\n' % obnamestring)
+
+
+ # Vert
+ for v in me.verts:
+ file.write('v %.6f %.6f %.6f\n' % tuple(v.co))
+
+ # UV
+ if faceuv:
+ uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/
+
+ uv_dict = {} # could use a set() here
+ uv_layer = me.active_uv_texture
+ for f, f_index in face_index_pairs:
+
+ tface = uv_layer.data[f_index]
+
+ uvs = tface.uv
+ # uvs = [tface.uv1, tface.uv2, tface.uv3]
+
+ # # add another UV if it's a quad
+ # if len(f.verts) == 4:
+ # uvs.append(tface.uv4)
+
+ for uv_index, uv in enumerate(uvs):
+ uvkey = veckey2d(uv)
+ try:
+ uv_face_mapping[f_index][uv_index] = uv_dict[uvkey]
+ except:
+ uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict)
+ file.write('vt %.6f %.6f\n' % tuple(uv))
+
+# uv_dict = {} # could use a set() here
+# for f_index, f in enumerate(faces):
+
+# for uv_index, uv in enumerate(f.uv):
+# uvkey = veckey2d(uv)
+# try:
+# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey]
+# except:
+# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict)
+# file.write('vt %.6f %.6f\n' % tuple(uv))
+
+ uv_unique_count = len(uv_dict)
+# del uv, uvkey, uv_dict, f_index, uv_index
+ # Only need uv_unique_count and uv_face_mapping
+
+ # NORMAL, Smooth/Non smoothed.
+ if EXPORT_NORMALS:
+ for f in faces:
+ if f.smooth:
+ for v in f:
+ noKey = veckey3d(v.normal)
+ if noKey not in globalNormals:
+ globalNormals[noKey] = totno
+ totno +=1
+ file.write('vn %.6f %.6f %.6f\n' % noKey)
+ else:
+ # Hard, 1 normal from the face.
+ noKey = veckey3d(f.normal)
+ if noKey not in globalNormals:
+ globalNormals[noKey] = totno
+ totno +=1
+ file.write('vn %.6f %.6f %.6f\n' % noKey)
+
+ if not faceuv:
+ f_image = None
+
+ # XXX
+ if EXPORT_POLYGROUPS:
+ # Retrieve the list of vertex groups
+# vertGroupNames = me.getVertGroupNames()
+
+ currentVGroup = ''
+ # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to
+ vgroupsMap = [[] for _i in range(len(me.verts))]
+# vgroupsMap = [[] for _i in xrange(len(me.verts))]
+ for g in ob.vertex_groups:
+# for vertexGroupName in vertGroupNames:
+ for vIdx, vWeight in getVertsFromGroup(me, g.index):
+# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1):
+ vgroupsMap[vIdx].append((g.name, vWeight))
+
+ for f_index, f in enumerate(faces):
+ f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts]
+
+ # if f.verts[3] == 0:
+ # f_v.pop()
+
+# f_v= f.v
+ f_smooth= f.smooth
+ f_mat = min(f.material_index, len(materialNames)-1)
+# f_mat = min(f.mat, len(materialNames)-1)
+ if faceuv:
+
+ tface = me.active_uv_texture.data[face_index_pairs[f_index][1]]
+
+ f_image = tface.image
+ f_uv = tface.uv
+ # f_uv= [tface.uv1, tface.uv2, tface.uv3]
+ # if len(f.verts) == 4:
+ # f_uv.append(tface.uv4)
+# f_image = f.image
+# f_uv= f.uv
+
+ # MAKE KEY
+ if faceuv and f_image: # Object is always true.
+ key = materialNames[f_mat], f_image.name
+ else:
+ key = materialNames[f_mat], None # No image, use None instead.
+
+ # Write the vertex group
+ if EXPORT_POLYGROUPS:
+ if len(ob.vertex_groups):
+ # find what vertext group the face belongs to
+ theVGroup = findVertexGroupName(f,vgroupsMap)
+ if theVGroup != currentVGroup:
+ currentVGroup = theVGroup
+ file.write('g %s\n' % theVGroup)
+# # Write the vertex group
+# if EXPORT_POLYGROUPS:
+# if vertGroupNames:
+# # find what vertext group the face belongs to
+# theVGroup = findVertexGroupName(f,vgroupsMap)
+# if theVGroup != currentVGroup:
+# currentVGroup = theVGroup
+# file.write('g %s\n' % theVGroup)
+
+ # CHECK FOR CONTEXT SWITCH
+ if key == contextMat:
+ pass # Context alredy switched, dont do anything
+ else:
+ if key[0] == None and key[1] == None:
+ # Write a null material, since we know the context has changed.
+ if EXPORT_GROUP_BY_MAT:
+ # can be mat_image or (null)
+ file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.data.name)) ) # can be mat_image or (null)
+ file.write('usemtl (null)\n') # mat, image
+
+ else:
+ mat_data= MTL_DICT.get(key)
+ if not mat_data:
+ # First add to global dict so we can export to mtl
+ # Then write mtl
+
+ # Make a new names from the mat and image name,
+ # converting any spaces to underscores with fixName.
+
+ # If none image dont bother adding it to the name
+ if key[1] == None:
+ mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image
+ else:
+ mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image
+
+ if EXPORT_GROUP_BY_MAT:
+ file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.data.name), mat_data[0]) ) # can be mat_image or (null)
+
+ file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null)
+
+ contextMat = key
+ if f_smooth != contextSmooth:
+ if f_smooth: # on now off
+ file.write('s 1\n')
+ contextSmooth = f_smooth
+ else: # was off now on
+ file.write('s off\n')
+ contextSmooth = f_smooth
+
+ file.write('f')
+ if faceuv:
+ if EXPORT_NORMALS:
+ if f_smooth: # Smoothed, use vertex normals
+ for vi, v in enumerate(f_v):
+ file.write( ' %d/%d/%d' % \
+ (v["index"] + totverts,
+ totuvco + uv_face_mapping[f_index][vi],
+ globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal
+
+ else: # No smoothing, face normals
+ no = globalNormals[ veckey3d(f.normal) ]
+ for vi, v in enumerate(f_v):
+ file.write( ' %d/%d/%d' % \
+ (v["index"] + totverts,
+ totuvco + uv_face_mapping[f_index][vi],
+ no) ) # vert, uv, normal
+ else: # No Normals
+ for vi, v in enumerate(f_v):
+ file.write( ' %d/%d' % (\
+ v["index"] + totverts,\
+ totuvco + uv_face_mapping[f_index][vi])) # vert, uv
+
+ face_vert_index += len(f_v)
+
+ else: # No UV's
+ if EXPORT_NORMALS:
+ if f_smooth: # Smoothed, use vertex normals
+ for v in f_v:
+ file.write( ' %d//%d' %
+ (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) )
+ else: # No smoothing, face normals
+ no = globalNormals[ veckey3d(f.normal) ]
+ for v in f_v:
+ file.write( ' %d//%d' % (v["index"] + totverts, no) )
+ else: # No Normals
+ for v in f_v:
+ file.write( ' %d' % (v["index"] + totverts) )
+
+ file.write('\n')
+
+ # Write edges.
+ if EXPORT_EDGES:
+ for ed in edges:
+ if ed.loose:
+ file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts))
+
+ # Make the indicies global rather then per mesh
+ totverts += len(me.verts)
+ if faceuv:
+ totuvco += uv_unique_count
+
+ # clean up
+ bpy.data.remove_mesh(me)
+
+ if ob_main.dupli_type != 'NONE':
+ ob_main.free_dupli_list()
+
+ file.close()
+
+
+ # Now we have all our materials, save them
+ if EXPORT_MTL:
+ write_mtl(scene, mtlfilename, EXPORT_COPY_IMAGES)
+# if EXPORT_COPY_IMAGES:
+# dest_dir = os.path.basename(filename)
+# # dest_dir = filename
+# # # Remove chars until we are just the path.
+# # while dest_dir and dest_dir[-1] not in '\\/':
+# # dest_dir = dest_dir[:-1]
+# if dest_dir:
+# copy_images(dest_dir)
+# else:
+# print('\tError: "%s" could not be used as a base for an image path.' % filename)
+
+ print("OBJ Export time: %.2f" % (time.clock() - time1))
+# print "OBJ Export time: %.2f" % (sys.time() - time1)
+
+def do_export(filename, context,
+ EXPORT_APPLY_MODIFIERS = True, # not used
+ EXPORT_ROTX90 = True, # wrong
+ EXPORT_TRI = False, # ok
+ EXPORT_EDGES = False,
+ EXPORT_NORMALS = False, # not yet
+ EXPORT_NORMALS_HQ = False, # not yet
+ EXPORT_UV = True, # ok
+ EXPORT_MTL = True,
+ EXPORT_SEL_ONLY = True, # ok
+ EXPORT_ALL_SCENES = False, # XXX not working atm
+ EXPORT_ANIMATION = False,
+ EXPORT_COPY_IMAGES = False,
+ EXPORT_BLEN_OBS = True,
+ EXPORT_GROUP_BY_OB = False,
+ EXPORT_GROUP_BY_MAT = False,
+ EXPORT_KEEP_VERT_ORDER = False,
+ EXPORT_POLYGROUPS = False,
+ EXPORT_CURVE_AS_NURBS = True):
+ # Window.EditMode(0)
+ # Window.WaitCursor(1)
+
+ base_name, ext = splitExt(filename)
+ context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension
+
+ orig_scene = context.scene
+
+# if EXPORT_ALL_SCENES:
+# export_scenes = bpy.data.scenes
+# else:
+# export_scenes = [orig_scene]
+
+ # XXX only exporting one scene atm since changing
+ # current scene is not possible.
+ # Brecht says that ideally in 2.5 we won't need such a function,
+ # allowing multiple scenes open at once.
+ export_scenes = [orig_scene]
+
+ # Export all scenes.
+ for scn in export_scenes:
+ # scn.makeCurrent() # If already current, this is not slow.
+ # context = scn.getRenderingContext()
+ orig_frame = scn.current_frame
+
+ if EXPORT_ALL_SCENES: # Add scene name into the context_name
+ context_name[1] = '_%s' % BPySys_cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied.
+
+ # Export an animation?
+ if EXPORT_ANIMATION:
+ scene_frames = range(scn.start_frame, context.end_frame+1) # Up to and including the end frame.
+ else:
+ scene_frames = [orig_frame] # Dont export an animation.
+
+ # Loop through all frames in the scene and export.
+ for frame in scene_frames:
+ if EXPORT_ANIMATION: # Add frame to the filename.
+ context_name[2] = '_%.6d' % frame
+
+ scn.current_frame = frame
+ if EXPORT_SEL_ONLY:
+ export_objects = context.selected_objects
+ else:
+ export_objects = scn.objects
+
+ full_path= ''.join(context_name)
+
+ # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad.
+ # EXPORT THE FILE.
+ write(full_path, export_objects, scn,
+ EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,
+ EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,
+ EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,
+ EXPORT_ROTX90, EXPORT_BLEN_OBS,
+ EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,
+ EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS)
+
+
+ scn.current_frame = orig_frame
+
+ # Restore old active scene.
+# orig_scene.makeCurrent()
+# Window.WaitCursor(0)
+
+
+class EXPORT_OT_obj(bpy.types.Operator):
+ '''
+ Currently the exporter lacks these features:
+ * nurbs
+ * multiple scene export (only active scene is written)
+ * particles
+ '''
+ __idname__ = "export.obj"
+ __label__ = 'Export OBJ'
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = [
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the OBJ file", maxlen= 1024, default= ""),
+
+ # context group
+ bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False),
+ bpy.props.BoolProperty(attr="use_all_scenes", name="All Scenes", description="", default= False),
+ bpy.props.BoolProperty(attr="use_animation", name="All Animation", description="", default= False),
+
+ # object group
+ bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="", default= True),
+ bpy.props.BoolProperty(attr="use_rotate90", name="Rotate X90", description="", default= True),
+
+ # extra data group
+ bpy.props.BoolProperty(attr="use_edges", name="Edges", description="", default= True),
+ bpy.props.BoolProperty(attr="use_normals", name="Normals", description="", default= False),
+ bpy.props.BoolProperty(attr="use_hq_normals", name="High Quality Normals", description="", default= True),
+ bpy.props.BoolProperty(attr="use_uvs", name="UVs", description="", default= True),
+ bpy.props.BoolProperty(attr="use_materials", name="Materials", description="", default= True),
+ bpy.props.BoolProperty(attr="copy_images", name="Copy Images", description="", default= False),
+ bpy.props.BoolProperty(attr="use_triangles", name="Triangulate", description="", default= False),
+ bpy.props.BoolProperty(attr="use_vertex_groups", name="Polygroups", description="", default= False),
+ bpy.props.BoolProperty(attr="use_nurbs", name="Nurbs", description="", default= False),
+
+ # grouping group
+ bpy.props.BoolProperty(attr="use_blen_objects", name="Objects as OBJ Objects", description="", default= True),
+ bpy.props.BoolProperty(attr="group_by_object", name="Objects as OBJ Groups ", description="", default= False),
+ bpy.props.BoolProperty(attr="group_by_material", name="Material Groups", description="", default= False),
+ bpy.props.BoolProperty(attr="keep_vertex_order", name="Keep Vertex Order", description="", default= False)
+ ]
+
+ def execute(self, context):
+
+ do_export(self.path, context,
+ EXPORT_TRI=self.use_triangles,
+ EXPORT_EDGES=self.use_edges,
+ EXPORT_NORMALS=self.use_normals,
+ EXPORT_NORMALS_HQ=self.use_hq_normals,
+ EXPORT_UV=self.use_uvs,
+ EXPORT_MTL=self.use_materials,
+ EXPORT_COPY_IMAGES=self.copy_images,
+ EXPORT_APPLY_MODIFIERS=self.use_modifiers,
+ EXPORT_ROTX90=self.use_rotate90,
+ EXPORT_BLEN_OBS=self.use_blen_objects,
+ EXPORT_GROUP_BY_OB=self.group_by_object,
+ EXPORT_GROUP_BY_MAT=self.group_by_material,
+ EXPORT_KEEP_VERT_ORDER=self.keep_vertex_order,
+ EXPORT_POLYGROUPS=self.use_vertex_groups,
+ EXPORT_CURVE_AS_NURBS=self.use_nurbs,
+ EXPORT_SEL_ONLY=self.use_selection,
+ EXPORT_ALL_SCENES=self.use_all_scenes)
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self.__operator__)
+ return ('RUNNING_MODAL',)
+
+ def poll(self, context): # Poll isnt working yet
+ print("Poll")
+ return context.active_object != None
+
+bpy.ops.add(EXPORT_OT_obj)
+
+if __name__ == "__main__":
+ bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj")
+
+# CONVERSION ISSUES
+# - matrix problem
+# - duplis - only tested dupliverts
+# - NURBS - needs API additions
+# - all scenes export
+# + normals calculation
+# - get rid of cleanName somehow
diff --git a/release/io/export_ply.py b/release/scripts/io/export_ply.py
index c293119d3c8..8e79c3741bb 100644
--- a/release/io/export_ply.py
+++ b/release/scripts/io/export_ply.py
@@ -78,7 +78,7 @@ def write(filename, scene, ob, \
#mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX
if EXPORT_APPLY_MODIFIERS:
- mesh = ob.create_render_mesh(scene)
+ mesh = ob.create_mesh(True, 'PREVIEW')
else:
mesh = ob.data
@@ -232,9 +232,7 @@ def write(filename, scene, ob, \
"""
class EXPORT_OT_ply(bpy.types.Operator):
- '''
- Operator documentatuon text, will be used for the operator tooltip and python docs.
- '''
+ '''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
__idname__ = "export.ply"
__label__ = "Export PLY"
@@ -242,7 +240,7 @@ class EXPORT_OT_ply(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
@@ -250,16 +248,15 @@ class EXPORT_OT_ply(bpy.types.Operator):
]
def poll(self, context):
- print("Poll")
return context.active_object != None
def execute(self, context):
# print("Selected: " + context.active_object.name)
- if not self.filename:
+ if not self.path:
raise Exception("filename not set")
- write(self.filename, context.scene, context.active_object,\
+ write(self.path, context.scene, context.active_object,\
EXPORT_APPLY_MODIFIERS = self.use_modifiers,
EXPORT_NORMALS = self.use_normals,
EXPORT_UV = self.use_uvs,
@@ -277,6 +274,6 @@ class EXPORT_OT_ply(bpy.types.Operator):
bpy.ops.add(EXPORT_OT_ply)
if __name__ == "__main__":
- bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
+ bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply")
diff --git a/release/scripts/x3d_export.py b/release/scripts/io/export_x3d.py
index b12ff67d8a6..db29afc7d6d 100644
--- a/release/scripts/x3d_export.py
+++ b/release/scripts/io/export_x3d.py
@@ -53,22 +53,30 @@ Known issues:<br>
# Library dependancies
####################################
-import Blender
-from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
-from Blender.Scene import Render
import math
-import BPyObject
-import BPyMesh
+import os
+
+import bpy
+import Mathutils
+
+from export_3ds import create_derived_objects, free_derived_objects
+
+# import Blender
+# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
+# from Blender.Scene import Render
+# import BPyObject
+# import BPyMesh
#
DEG2RAD=0.017453292519943295
-MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
+MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x')
####################################
# Global Variables
####################################
-filename = Blender.Get('filename')
+filename = ""
+# filename = Blender.Get('filename')
_safeOverwrite = True
extension = ''
@@ -109,7 +117,7 @@ class x3d_class:
import gzip
self.file = gzip.open(filename, "w")
except:
- print "failed to import compression modules, exporting uncompressed"
+ print("failed to import compression modules, exporting uncompressed")
self.filename = filename[:-1] # remove trailing z
if self.file == None:
@@ -161,8 +169,10 @@ class x3d_class:
self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
self.file.write("<head>\n")
- self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
- self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
+ self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % os.path.basename(bfile))
+ # self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
+ self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % '2.5')
+ # self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
self.file.write("\t<meta name=\"translator\" content=\"X3D exporter v1.55 (2006/01/17)\" />\n")
self.file.write("</head>\n")
self.file.write("<Scene>\n")
@@ -206,9 +216,12 @@ class x3d_class:
'''
def writeViewpoint(self, ob, mat, scene):
- context = scene.render
- ratio = float(context.imageSizeY())/float(context.imageSizeX())
- lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
+ context = scene.render_data
+ # context = scene.render
+ ratio = float(context.resolution_x)/float(context.resolution_y)
+ # ratio = float(context.imageSizeY())/float(context.imageSizeX())
+ lens = (360* (math.atan(ratio *16 / ob.data.lens) / math.pi))*(math.pi/180)
+ # lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
lens = min(lens, math.pi)
# get the camera location, subtract 90 degress from X to orient like X3D does
@@ -216,7 +229,8 @@ class x3d_class:
loc = self.rotatePointForVRML(mat.translationPart())
rot = mat.toEuler()
- rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
+ rot = (((rot[0]-90)), rot[1], rot[2])
+ # rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
nRot = self.rotatePointForVRML( rot )
# convert to Quaternion and to Angle Axis
Q = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2])
@@ -232,13 +246,18 @@ class x3d_class:
def writeFog(self, world):
if world:
- mtype = world.getMistype()
- mparam = world.getMist()
- grd = world.getHor()
+ mtype = world.mist.falloff
+ # mtype = world.getMistype()
+ mparam = world.mist
+ # mparam = world.getMist()
+ grd = world.horizon_color
+ # grd = world.getHor()
grd0, grd1, grd2 = grd[0], grd[1], grd[2]
else:
return
- if (mtype == 1 or mtype == 2):
+ if (mtype == 'LINEAR' or mtype == 'INVERSE_QUADRATIC'):
+ mtype = 1 if mtype == 'LINEAR' else 2
+ # if (mtype == 1 or mtype == 2):
self.file.write("<Fog fogType=\"%s\" " % self.namesFog[mtype])
self.file.write("color=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
self.file.write("visibilityRange=\"%s\" />\n\n" % round(mparam[2],self.cp))
@@ -251,7 +270,8 @@ class x3d_class:
def writeSpotLight(self, ob, mtx, lamp, world):
safeName = self.cleanStr(ob.name)
if world:
- ambi = world.amb
+ ambi = world.ambient_color
+ # ambi = world.amb
ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
else:
ambi = 0
@@ -259,7 +279,8 @@ class x3d_class:
# compute cutoff and beamwidth
intensity=min(lamp.energy/1.75,1.0)
- beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
+ beamWidth=((lamp.spot_size*math.pi)/180.0)*.37;
+ # beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
cutOffAngle=beamWidth*1.3
dx,dy,dz=self.computeDirection(mtx)
@@ -270,12 +291,14 @@ class x3d_class:
#location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
location=(mtx*MATWORLD).translationPart()
- radius = lamp.dist*math.cos(beamWidth)
+ radius = lamp.distance*math.cos(beamWidth)
+ # radius = lamp.dist*math.cos(beamWidth)
self.file.write("<SpotLight DEF=\"%s\" " % safeName)
self.file.write("radius=\"%s\" " % (round(radius,self.cp)))
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
- self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+ self.file.write("color=\"%s %s %s\" " % (round(lamp.color[0],self.cp), round(lamp.color[1],self.cp), round(lamp.color[2],self.cp)))
+ # self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
self.file.write("beamWidth=\"%s\" " % (round(beamWidth,self.cp)))
self.file.write("cutOffAngle=\"%s\" " % (round(cutOffAngle,self.cp)))
self.file.write("direction=\"%s %s %s\" " % (round(dx,3),round(dy,3),round(dz,3)))
@@ -285,7 +308,8 @@ class x3d_class:
def writeDirectionalLight(self, ob, mtx, lamp, world):
safeName = self.cleanStr(ob.name)
if world:
- ambi = world.amb
+ ambi = world.ambient_color
+ # ambi = world.amb
ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
else:
ambi = 0
@@ -295,14 +319,16 @@ class x3d_class:
(dx,dy,dz)=self.computeDirection(mtx)
self.file.write("<DirectionalLight DEF=\"%s\" " % safeName)
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
- self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+ self.file.write("color=\"%s %s %s\" " % (round(lamp.color[0],self.cp), round(lamp.color[1],self.cp), round(lamp.color[2],self.cp)))
+ # self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
self.file.write("direction=\"%s %s %s\" />\n\n" % (round(dx,4),round(dy,4),round(dz,4)))
def writePointLight(self, ob, mtx, lamp, world):
safeName = self.cleanStr(ob.name)
if world:
- ambi = world.amb
+ ambi = world.ambient_color
+ # ambi = world.amb
ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
else:
ambi = 0
@@ -313,9 +339,11 @@ class x3d_class:
self.file.write("<PointLight DEF=\"%s\" " % safeName)
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
- self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+ self.file.write("color=\"%s %s %s\" " % (round(lamp.color[0],self.cp), round(lamp.color[1],self.cp), round(lamp.color[2],self.cp)))
+ # self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
self.file.write("intensity=\"%s\" " % (round( min(lamp.energy/1.75,1.0) ,self.cp)))
- self.file.write("radius=\"%s\" " % lamp.dist )
+ self.file.write("radius=\"%s\" " % lamp.distance )
+ # self.file.write("radius=\"%s\" " % lamp.dist )
self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
'''
def writeNode(self, ob, mtx):
@@ -357,24 +385,41 @@ class x3d_class:
vColors={} # 'multi':1
meshName = self.cleanStr(ob.name)
- meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not
+ meshME = self.cleanStr(ob.data.name) # We dont care if its the mesh name or not
+ # meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not
if len(mesh.faces) == 0: return
- mode = 0
- if mesh.faceUV:
- for face in mesh.faces:
- mode |= face.mode
+ mode = []
+ # mode = 0
+ if mesh.active_uv_texture:
+ # if mesh.faceUV:
+ for face in mesh.active_uv_texture.data:
+ # for face in mesh.faces:
+ if face.halo and 'HALO' not in mode:
+ mode += ['HALO']
+ if face.billboard and 'BILLBOARD' not in mode:
+ mode += ['BILLBOARD']
+ if face.object_color and 'OBJECT_COLOR' not in mode:
+ mode += ['OBJECT_COLOR']
+ if face.collision and 'COLLISION' not in mode:
+ mode += ['COLLISION']
+ # mode |= face.mode
- if mode & Mesh.FaceModes.HALO and self.halonode == 0:
+ if 'HALO' in mode and self.halonode == 0:
+ # if mode & Mesh.FaceModes.HALO and self.halonode == 0:
self.writeIndented("<Billboard axisOfRotation=\"0 0 0\">\n",1)
self.halonode = 1
- elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0:
+ elif 'BILLBOARD' in mode and self.billnode == 0:
+ # elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0:
self.writeIndented("<Billboard axisOfRotation=\"0 1 0\">\n",1)
self.billnode = 1
- elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0:
+ elif 'OBJECT_COLOR' in mode and self.matonly == 0:
+ # elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0:
self.matonly = 1
- elif mode & Mesh.FaceModes.TILES and self.tilenode == 0:
- self.tilenode = 1
- elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0:
+ # TF_TILES is marked as deprecated in DNA_meshdata_types.h
+ # elif mode & Mesh.FaceModes.TILES and self.tilenode == 0:
+ # self.tilenode = 1
+ elif 'COLLISION' not in mode and self.collnode == 0:
+ # elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0:
self.writeIndented("<Collision enabled=\"false\">\n",1)
self.collnode = 1
@@ -383,7 +428,7 @@ class x3d_class:
if nIFSCnt > 1:
self.writeIndented("<Group DEF=\"%s%s\">\n" % ("G_", meshName),1)
- if sided.has_key('two') and sided['two'] > 0:
+ if 'two' in sided and sided['two'] > 0:
bTwoSided=1
else:
bTwoSided=0
@@ -396,34 +441,44 @@ class x3d_class:
quat = mtx.toQuat()
rot= quat.axis
- # self.writeIndented('<Transform rotation="%.6f %.6f %.6f %.6f">\n' % (rot[0], rot[1], rot[2], rot[3]))
self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
- (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) )
+ (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle) )
+ # self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
+ # (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) )
self.writeIndented("<Shape>\n",1)
maters=mesh.materials
hasImageTexture=0
issmooth=0
- if len(maters) > 0 or mesh.faceUV:
+ if len(maters) > 0 or mesh.active_uv_texture:
+ # if len(maters) > 0 or mesh.faceUV:
self.writeIndented("<Appearance>\n", 1)
# right now this script can only handle a single material per mesh.
if len(maters) >= 1:
mat=maters[0]
- matFlags = mat.getMode()
- if not matFlags & Blender.Material.Modes['TEXFACE']:
- self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world)
+ # matFlags = mat.getMode()
+ if not mat.face_texture:
+ # if not matFlags & Blender.Material.Modes['TEXFACE']:
+ self.writeMaterial(mat, self.cleanStr(mat.name,''), world)
+ # self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world)
if len(maters) > 1:
- print "Warning: mesh named %s has multiple materials" % meshName
- print "Warning: only one material per object handled"
+ print("Warning: mesh named %s has multiple materials" % meshName)
+ print("Warning: only one material per object handled")
#-- textures
- if mesh.faceUV:
- for face in mesh.faces:
- if (hasImageTexture == 0) and (face.image):
+ face = None
+ if mesh.active_uv_texture:
+ # if mesh.faceUV:
+ for face in mesh.active_uv_texture.data:
+ # for face in mesh.faces:
+ if face.image:
+ # if (hasImageTexture == 0) and (face.image):
self.writeImageTexture(face.image)
- hasImageTexture=1 # keep track of face texture
- if self.tilenode == 1:
+ # hasImageTexture=1 # keep track of face texture
+ break
+ if self.tilenode == 1 and face and face.image:
+ # if self.tilenode == 1:
self.writeIndented("<TextureTransform scale=\"%s %s\" />\n" % (face.image.xrep, face.image.yrep))
self.tilenode = 0
self.writeIndented("</Appearance>\n", -1)
@@ -433,7 +488,7 @@ class x3d_class:
# user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
ifStyle="IndexedFaceSet"
# look up mesh name, use it if available
- if self.meshNames.has_key(meshME):
+ if meshME in self.meshNames:
self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1)
self.meshNames[meshME]+=1
else:
@@ -453,11 +508,13 @@ class x3d_class:
issmooth=1
break
if issmooth==1:
- creaseAngle=(mesh.degr)*(math.pi/180.0)
+ creaseAngle=(mesh.autosmooth_angle)*(math.pi/180.0)
+ # creaseAngle=(mesh.degr)*(math.pi/180.0)
self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
#--- output textureCoordinates if UV texture used
- if mesh.faceUV:
+ if mesh.active_uv_texture:
+ # if mesh.faceUV:
if self.matonly == 1 and self.share == 1:
self.writeFaceColors(mesh)
elif hasImageTexture == 1:
@@ -471,7 +528,8 @@ class x3d_class:
self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
#--- output textureCoordinates if UV texture used
- if mesh.faceUV:
+ if mesh.active_uv_texture:
+ # if mesh.faceUV:
if hasImageTexture == 1:
self.writeTextureCoordinates(mesh)
elif self.matonly == 1 and self.share == 1:
@@ -511,16 +569,22 @@ class x3d_class:
if self.writingcoords == 0:
self.file.write('coordIndex="')
for face in mesh.faces:
- fv = face.v
+ fv = face.verts
+ # fv = face.v
- if len(face)==3:
- self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+ if len(fv)==3:
+ # if len(face)==3:
+ self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2]))
+ # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
else:
if EXPORT_TRI:
- self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
- self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index))
+ self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2]))
+ # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+ self.file.write("%i %i %i -1, " % (fv[0], fv[2], fv[3]))
+ # self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index))
else:
- self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
+ self.file.write("%i %i %i %i -1, " % (fv[0], fv[1], fv[2], fv[3]))
+ # self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
self.file.write("\">\n")
else:
@@ -538,8 +602,13 @@ class x3d_class:
texIndexList=[]
j=0
- for face in mesh.faces:
- for uv in face.uv:
+ for face in mesh.active_uv_texture.data:
+ # for face in mesh.faces:
+ uvs = face.uv
+ # uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
+
+ for uv in uvs:
+ # for uv in face.uv:
texIndexList.append(j)
texCoordList.append(uv)
j=j+1
@@ -547,7 +616,7 @@ class x3d_class:
if self.writingtexture == 0:
self.file.write("\n\t\t\ttexCoordIndex=\"")
texIndxStr=""
- for i in xrange(len(texIndexList)):
+ for i in range(len(texIndexList)):
texIndxStr = texIndxStr + "%d, " % texIndexList[i]
if texIndexList[i]==-1:
self.file.write(texIndxStr)
@@ -555,7 +624,7 @@ class x3d_class:
self.file.write("\"\n\t\t\t")
else:
self.writeIndented("<TextureCoordinate point=\"", 1)
- for i in xrange(len(texCoordList)):
+ for i in range(len(texCoordList)):
self.file.write("%s %s, " % (round(texCoordList[i][0],self.tp), round(texCoordList[i][1],self.tp)))
self.file.write("\" />")
self.writeIndented("\n", -1)
@@ -563,43 +632,61 @@ class x3d_class:
def writeFaceColors(self, mesh):
if self.writingcolor == 0:
self.file.write("colorPerVertex=\"false\" ")
- else:
+ elif mesh.active_vertex_color:
+ # else:
self.writeIndented("<Color color=\"", 1)
- for face in mesh.faces:
- if face.col:
- c=face.col[0]
- if self.verbose > 2:
- print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)
- aColor = self.rgbToFS(c)
- self.file.write("%s, " % aColor)
+ for face in mesh.active_vertex_color.data:
+ c = face.color1
+ if self.verbose > 2:
+ print("Debug: face.col r=%d g=%d b=%d" % (c[0], c[1], c[2]))
+ # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b))
+ aColor = self.rgbToFS(c)
+ self.file.write("%s, " % aColor)
+
+ # for face in mesh.faces:
+ # if face.col:
+ # c=face.col[0]
+ # if self.verbose > 2:
+ # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b))
+ # aColor = self.rgbToFS(c)
+ # self.file.write("%s, " % aColor)
self.file.write("\" />")
self.writeIndented("\n",-1)
def writeMaterial(self, mat, matName, world):
# look up material name, use it if available
- if self.matNames.has_key(matName):
+ if matName in self.matNames:
self.writeIndented("<Material USE=\"MA_%s\" />\n" % matName)
self.matNames[matName]+=1
return;
self.matNames[matName]=1
- ambient = mat.amb/3
- diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
+ ambient = mat.ambient/3
+ # ambient = mat.amb/3
+ diffuseR, diffuseG, diffuseB = tuple(mat.diffuse_color)
+ # diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
if world:
- ambi = world.getAmb()
- ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2
+ ambi = world.ambient_color
+ # ambi = world.getAmb()
+ ambi0, ambi1, ambi2 = (ambi[0]*mat.ambient)*2, (ambi[1]*mat.ambient)*2, (ambi[2]*mat.ambient)*2
+ # ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2
else:
ambi0, ambi1, ambi2 = 0, 0, 0
emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2
- shininess = mat.hard/512.0
- specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001))
- specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001))
- specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
+ shininess = mat.specular_hardness/512.0
+ # shininess = mat.hard/512.0
+ specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_intensity+0.001))
+ # specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001))
+ specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_intensity+0.001))
+ # specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001))
+ specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_intensity+0.001))
+ # specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
transp = 1-mat.alpha
- matFlags = mat.getMode()
- if matFlags & Blender.Material.Modes['SHADELESS']:
+ # matFlags = mat.getMode()
+ if mat.shadeless:
+ # if matFlags & Blender.Material.Modes['SHADELESS']:
ambient = 1
shine = 1
specR = emitR = diffuseR
@@ -617,7 +704,7 @@ class x3d_class:
def writeImageTexture(self, image):
name = image.name
filename = image.filename.split('/')[-1].split('\\')[-1]
- if self.texNames.has_key(name):
+ if name in self.texNames:
self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
self.texNames[name] += 1
return
@@ -630,10 +717,13 @@ class x3d_class:
def writeBackground(self, world, alltextures):
if world: worldname = world.name
else: return
- blending = world.getSkytype()
- grd = world.getHor()
+ blending = (world.blend_sky, world.paper_sky, world.real_sky)
+ # blending = world.getSkytype()
+ grd = world.horizon_color
+ # grd = world.getHor()
grd0, grd1, grd2 = grd[0], grd[1], grd[2]
- sky = world.getZen()
+ sky = world.zenith_color
+ # sky = world.getZen()
sky0, sky1, sky2 = sky[0], sky[1], sky[2]
mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2]
mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2
@@ -641,27 +731,32 @@ class x3d_class:
if worldname not in self.namesStandard:
self.file.write("DEF=\"%s\" " % self.secureName(worldname))
# No Skytype - just Hor color
- if blending == 0:
+ if blending == (0, 0, 0):
+ # if blending == 0:
self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
self.file.write("skyColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
# Blend Gradient
- elif blending == 1:
+ elif blending == (1, 0, 0):
+ # elif blending == 1:
self.file.write("groundColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
self.file.write("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
# Blend+Real Gradient Inverse
- elif blending == 3:
+ elif blending == (1, 0, 1):
+ # elif blending == 3:
self.file.write("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
self.file.write("skyColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
# Paper - just Zen Color
- elif blending == 4:
+ elif blending == (0, 0, 1):
+ # elif blending == 4:
self.file.write("groundColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
# Blend+Real+Paper - komplex gradient
- elif blending == 7:
+ elif blending == (1, 1, 1):
+ # elif blending == 7:
self.writeIndented("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
self.writeIndented("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
self.writeIndented("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
@@ -670,22 +765,43 @@ class x3d_class:
else:
self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+
alltexture = len(alltextures)
- for i in xrange(alltexture):
- namemat = alltextures[i].name
- pic = alltextures[i].getImage()
+
+ for i in range(alltexture):
+ tex = alltextures[i]
+
+ if tex.type != 'IMAGE' or tex.image == None:
+ continue
+
+ namemat = tex.name
+ # namemat = alltextures[i].name
+
+ pic = tex.image
+
+ # using .expandpath just in case, os.path may not expect //
+ basename = os.path.basename(pic.get_abs_filename())
+
+ pic = alltextures[i].image
+ # pic = alltextures[i].getImage()
if (namemat == "back") and (pic != None):
- self.file.write("\n\tbackUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+ self.file.write("\n\tbackUrl=\"%s\" " % basename)
+ # self.file.write("\n\tbackUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
elif (namemat == "bottom") and (pic != None):
- self.writeIndented("bottomUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+ self.writeIndented("bottomUrl=\"%s\" " % basename)
+ # self.writeIndented("bottomUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
elif (namemat == "front") and (pic != None):
- self.writeIndented("frontUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+ self.writeIndented("frontUrl=\"%s\" " % basename)
+ # self.writeIndented("frontUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
elif (namemat == "left") and (pic != None):
- self.writeIndented("leftUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+ self.writeIndented("leftUrl=\"%s\" " % basename)
+ # self.writeIndented("leftUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
elif (namemat == "right") and (pic != None):
- self.writeIndented("rightUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+ self.writeIndented("rightUrl=\"%s\" " % basename)
+ # self.writeIndented("rightUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
elif (namemat == "top") and (pic != None):
- self.writeIndented("topUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+ self.writeIndented("topUrl=\"%s\" " % basename)
+ # self.writeIndented("topUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
self.writeIndented("/>\n\n")
##########################################################
@@ -697,7 +813,7 @@ class x3d_class:
EXPORT_TRI= False,\
):
- print "Info: starting X3D export to " + self.filename + "..."
+ print("Info: starting X3D export to " + self.filename + "...")
self.writeHeader()
# self.writeScript()
self.writeNavigationInfo(scene)
@@ -706,44 +822,65 @@ class x3d_class:
self.proto = 0
- # COPIED FROM OBJ EXPORTER
- if EXPORT_APPLY_MODIFIERS:
- temp_mesh_name = '~tmp-mesh'
+ # # COPIED FROM OBJ EXPORTER
+ # if EXPORT_APPLY_MODIFIERS:
+ # temp_mesh_name = '~tmp-mesh'
- # Get the container mesh. - used for applying modifiers and non mesh objects.
- containerMesh = meshName = tempMesh = None
- for meshName in Blender.NMesh.GetNames():
- if meshName.startswith(temp_mesh_name):
- tempMesh = Mesh.Get(meshName)
- if not tempMesh.users:
- containerMesh = tempMesh
- if not containerMesh:
- containerMesh = Mesh.New(temp_mesh_name)
+ # # Get the container mesh. - used for applying modifiers and non mesh objects.
+ # containerMesh = meshName = tempMesh = None
+ # for meshName in Blender.NMesh.GetNames():
+ # if meshName.startswith(temp_mesh_name):
+ # tempMesh = Mesh.Get(meshName)
+ # if not tempMesh.users:
+ # containerMesh = tempMesh
+ # if not containerMesh:
+ # containerMesh = Mesh.New(temp_mesh_name)
# --------------------------
- for ob_main in scene.objects.context:
- for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
+ for ob_main in [o for o in scene.objects if o.is_visible()]:
+ # for ob_main in scene.objects.context:
+
+ free, derived = create_derived_objects(ob_main)
+
+ if derived == None: continue
+
+ for ob, ob_mat in derived:
+ # for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
objType=ob.type
objName=ob.name
self.matonly = 0
- if objType == "Camera":
+ if objType == "CAMERA":
+ # if objType == "Camera":
self.writeViewpoint(ob, ob_mat, scene)
- elif objType in ("Mesh", "Curve", "Surf", "Text") :
- if EXPORT_APPLY_MODIFIERS or objType != 'Mesh':
- me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene)
+ elif objType in ("MESH", "CURVE", "SURF", "TEXT") :
+ # elif objType in ("Mesh", "Curve", "Surf", "Text") :
+ if EXPORT_APPLY_MODIFIERS or objType != 'MESH':
+ # if EXPORT_APPLY_MODIFIERS or objType != 'Mesh':
+ me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW')
+ # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene)
else:
- me = ob.getData(mesh=1)
+ me = ob.data
+ # me = ob.getData(mesh=1)
self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI)
- elif objType == "Lamp":
+
+ # free mesh created with create_mesh()
+ if me != ob.data:
+ bpy.data.remove_mesh(me)
+
+ elif objType == "LAMP":
+ # elif objType == "Lamp":
data= ob.data
datatype=data.type
- if datatype == Lamp.Types.Lamp:
+ if datatype == 'POINT':
+ # if datatype == Lamp.Types.Lamp:
self.writePointLight(ob, ob_mat, data, world)
- elif datatype == Lamp.Types.Spot:
+ elif datatype == 'SPOT':
+ # elif datatype == Lamp.Types.Spot:
self.writeSpotLight(ob, ob_mat, data, world)
- elif datatype == Lamp.Types.Sun:
+ elif datatype == 'SUN':
+ # elif datatype == Lamp.Types.Sun:
self.writeDirectionalLight(ob, ob_mat, data, world)
else:
self.writeDirectionalLight(ob, ob_mat, data, world)
@@ -753,12 +890,15 @@ class x3d_class:
else:
#print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
pass
-
+
+ if free:
+ free_derived_objects(ob_main)
+
self.file.write("\n</Scene>\n</X3D>")
- if EXPORT_APPLY_MODIFIERS:
- if containerMesh:
- containerMesh.verts = None
+ # if EXPORT_APPLY_MODIFIERS:
+ # if containerMesh:
+ # containerMesh.verts = None
self.cleanup()
@@ -771,7 +911,7 @@ class x3d_class:
self.texNames={}
self.matNames={}
self.indentLevel=0
- print "Info: finished X3D export to %s\n" % self.filename
+ print("Info: finished X3D export to %s\n" % self.filename)
def cleanStr(self, name, prefix='rsvd_'):
"""cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
@@ -807,15 +947,18 @@ class x3d_class:
faceMap={}
nFaceIndx=0
- if mesh.faceUV:
- for face in mesh.faces:
+ if mesh.active_uv_texture:
+ # if mesh.faceUV:
+ for face in mesh.active_uv_texture.data:
+ # for face in mesh.faces:
sidename='';
- if face.mode & Mesh.FaceModes.TWOSIDE:
+ if face.twoside:
+ # if face.mode & Mesh.FaceModes.TWOSIDE:
sidename='two'
else:
sidename='one'
- if sided.has_key(sidename):
+ if sidename in sided:
sided[sidename]+=1
else:
sided[sidename]=1
@@ -829,56 +972,63 @@ class x3d_class:
imageMap[faceName]=[face.image.name,sidename,face]
if self.verbose > 2:
- for faceName in imageMap.iterkeys():
+ for faceName in imageMap.keys():
ifs=imageMap[faceName]
- print "Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
- (faceName, ifs[0], ifs[1], len(ifs)-2)
+ print("Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
+ (faceName, ifs[0], ifs[1], len(ifs)-2))
return len(imageMap)
def faceToString(self,face):
- print "Debug: face.flag=0x%x (bitflags)" % face.flag
+ print("Debug: face.flag=0x%x (bitflags)" % face.flag)
if face.sel:
- print "Debug: face.sel=true"
+ print("Debug: face.sel=true")
- print "Debug: face.mode=0x%x (bitflags)" % face.mode
+ print("Debug: face.mode=0x%x (bitflags)" % face.mode)
if face.mode & Mesh.FaceModes.TWOSIDE:
- print "Debug: face.mode twosided"
+ print("Debug: face.mode twosided")
- print "Debug: face.transp=0x%x (enum)" % face.transp
+ print("Debug: face.transp=0x%x (enum)" % face.transp)
if face.transp == Mesh.FaceTranspModes.SOLID:
- print "Debug: face.transp.SOLID"
+ print("Debug: face.transp.SOLID")
if face.image:
- print "Debug: face.image=%s" % face.image.name
- print "Debug: face.materialIndex=%d" % face.materialIndex
-
- def getVertexColorByIndx(self, mesh, indx):
- c = None
- for face in mesh.faces:
- j=0
- for vertex in face.v:
- if vertex.index == indx:
- c=face.col[j]
- break
- j=j+1
- if c: break
- return c
+ print("Debug: face.image=%s" % face.image.name)
+ print("Debug: face.materialIndex=%d" % face.materialIndex)
+
+ # XXX not used
+ # def getVertexColorByIndx(self, mesh, indx):
+ # c = None
+ # for face in mesh.faces:
+ # j=0
+ # for vertex in face.v:
+ # if vertex.index == indx:
+ # c=face.col[j]
+ # break
+ # j=j+1
+ # if c: break
+ # return c
def meshToString(self,mesh):
- print "Debug: mesh.hasVertexUV=%d" % mesh.vertexColors
- print "Debug: mesh.faceUV=%d" % mesh.faceUV
- print "Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()
- print "Debug: mesh.verts=%d" % len(mesh.verts)
- print "Debug: mesh.faces=%d" % len(mesh.faces)
- print "Debug: mesh.materials=%d" % len(mesh.materials)
+ # print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors)
+ print("Debug: mesh.faceUV=%d" % (len(mesh.uv_textures) > 0))
+ # print("Debug: mesh.faceUV=%d" % mesh.faceUV)
+ print("Debug: mesh.hasVertexColours=%d" % (len(mesh.vertex_colors) > 0))
+ # print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours())
+ print("Debug: mesh.verts=%d" % len(mesh.verts))
+ print("Debug: mesh.faces=%d" % len(mesh.faces))
+ print("Debug: mesh.materials=%d" % len(mesh.materials))
def rgbToFS(self, c):
- s="%s %s %s" % (
- round(c.r/255.0,self.cp),
- round(c.g/255.0,self.cp),
- round(c.b/255.0,self.cp))
+ s="%s %s %s" % (round(c[0]/255.0,self.cp),
+ round(c[1]/255.0,self.cp),
+ round(c[2]/255.0,self.cp))
+
+ # s="%s %s %s" % (
+ # round(c.r/255.0,self.cp),
+ # round(c.g/255.0,self.cp),
+ # round(c.b/255.0,self.cp))
return s
def computeDirection(self, mtx):
@@ -886,9 +1036,10 @@ class x3d_class:
ax,ay,az = (mtx*MATWORLD).toEuler()
- ax *= DEG2RAD
- ay *= DEG2RAD
- az *= DEG2RAD
+ # ax *= DEG2RAD
+ # ay *= DEG2RAD
+ # az *= DEG2RAD
+
# rot X
x1=x
y1=y*math.cos(ax)-z*math.sin(ax)
@@ -924,7 +1075,7 @@ class x3d_class:
self.indentLevel = self.indentLevel + inc
spaces=""
- for x in xrange(self.indentLevel):
+ for x in range(self.indentLevel):
spaces = spaces + "\t"
self.file.write(spaces + s)
@@ -975,11 +1126,11 @@ class x3d_class:
# Callbacks, needed before Main
##########################################################
-def x3d_export(filename, \
- EXPORT_APPLY_MODIFIERS= False,\
- EXPORT_TRI= False,\
- EXPORT_GZIP= False,\
- ):
+def x3d_export(filename,
+ context,
+ EXPORT_APPLY_MODIFIERS=False,
+ EXPORT_TRI=False,
+ EXPORT_GZIP=False):
if EXPORT_GZIP:
if not filename.lower().endswith('.x3dz'):
@@ -989,9 +1140,13 @@ def x3d_export(filename, \
filename = '.'.join(filename.split('.')[:-1]) + '.x3d'
- scene = Blender.Scene.GetCurrent()
+ scene = context.scene
+ # scene = Blender.Scene.GetCurrent()
world = scene.world
- alltextures = Blender.Texture.Get()
+
+ # XXX these are global textures while .Get() returned only scene's?
+ alltextures = bpy.data.textures
+ # alltextures = Blender.Texture.Get()
wrlexport=x3d_class(filename)
wrlexport.export(\
@@ -1045,7 +1200,41 @@ def x3d_export_ui(filename):
#########################################################
-if __name__ == '__main__':
- Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
+# if __name__ == '__main__':
+# Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
+
+class EXPORT_OT_x3d(bpy.types.Operator):
+ '''
+ X3D Exporter
+ '''
+ __idname__ = "export.x3d"
+ __label__ = 'Export X3D'
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = [
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the X3D file", maxlen= 1024, default= ""),
+
+ bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True),
+ bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False),
+ bpy.props.BoolProperty(attr="compress", name="Compress", description="GZip the resulting file, requires a full python install.", default=False),
+ ]
+
+ def execute(self, context):
+ x3d_export(self.path, context, self.apply_modifiers, self.triangulate, self.compress)
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self.__operator__)
+ return ('RUNNING_MODAL',)
+
+ def poll(self, context): # Poll isnt working yet
+ print("Poll")
+ return context.active_object != None
+bpy.ops.add(EXPORT_OT_x3d)
+# NOTES
+# - blender version is hardcoded
diff --git a/release/scripts/io/import_3ds.py b/release/scripts/io/import_3ds.py
new file mode 100644
index 00000000000..339fac839ea
--- /dev/null
+++ b/release/scripts/io/import_3ds.py
@@ -0,0 +1,1167 @@
+#!BPY
+"""
+Name: '3D Studio (.3ds)...'
+Blender: 244
+Group: 'Import'
+Tooltip: 'Import from 3DS file format (.3ds)'
+"""
+
+__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin']
+__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
+__version__= '0.996'
+__bpydoc__= '''\
+
+3ds Importer
+
+This script imports a 3ds file and the materials into Blender for editing.
+
+Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen).
+
+0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200 <br>
+ - Implemented workaround to correct association between name, geometry and materials of
+ imported meshes.
+
+ Without this patch, version 0.995 of this importer would associate to each mesh object the
+ geometry and the materials of the previously parsed mesh object. By so, the name of the
+ first mesh object would be thrown away, and the name of the last mesh object would be
+ automatically merged with a '.001' at the end. No object would desappear, however object's
+ names and materials would be completely jumbled.
+
+0.995 by Campbell Barton<br>
+- workaround for buggy mesh vert delete
+- minor tweaks
+
+0.99 by Bob Holcomb<br>
+- added support for floating point color values that previously broke on import.
+
+0.98 by Campbell Barton<br>
+- import faces and verts to lists instead of a mesh, convert to a mesh later
+- use new index mapping feature of mesh to re-map faces that were not added.
+
+0.97 by Campbell Barton<br>
+- Strip material names of spaces
+- Added import as instance to import the 3ds into its own
+ scene and add a group instance to the current scene
+- New option to scale down imported objects so they are within a limited bounding area.
+
+0.96 by Campbell Barton<br>
+- Added workaround for bug in setting UV's for Zero vert index UV faces.
+- Removed unique name function, let blender make the names unique.
+
+0.95 by Campbell Barton<br>
+- Removed workarounds for Blender 2.41
+- Mesh objects split by material- many 3ds objects used more then 16 per mesh.
+- Removed a lot of unneeded variable creation.
+
+0.94 by Campbell Barton<br>
+- Face import tested to be about overall 16x speedup over 0.93.
+- Material importing speedup.
+- Tested with more models.
+- Support some corrupt models.
+
+0.93 by Campbell Barton<br>
+- Tested with 400 3ds files from turbosquid and samples.
+- Tactfully ignore faces that used the same verts twice.
+- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading.
+- Converted from NMesh to Mesh.
+- Faster and cleaner new names.
+- Use external comprehensive image loader.
+- Re intergrated 0.92 and 0.9 changes
+- Fixes for 2.41 compat.
+- Non textured faces do not use a texture flag.
+
+0.92<br>
+- Added support for diffuse, alpha, spec, bump maps in a single material
+
+0.9<br>
+- Reorganized code into object/material block functions<br>
+- Use of Matrix() to copy matrix data<br>
+- added support for material transparency<br>
+
+0.83 2005-08-07: Campell Barton
+- Aggressive image finding and case insensitivy for posisx systems.
+
+0.82a 2005-07-22
+- image texture loading (both for face uv and renderer)
+
+0.82 - image texture loading (for face uv)
+
+0.81a (fork- not 0.9) Campbell Barton 2005-06-08
+- Simplified import code
+- Never overwrite data
+- Faster list handling
+- Leaves import selected
+
+0.81 Damien McGinnes 2005-01-09
+- handle missing images better
+
+0.8 Damien McGinnes 2005-01-08
+- copies sticky UV coords to face ones
+- handles images better
+- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
+
+'''
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Script copyright (C) Bob Holcomb
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You 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 *****
+# --------------------------------------------------------------------------
+
+# Importing modules
+
+import os
+import time
+import struct
+
+from import_obj import unpack_face_list, load_image
+
+import bpy
+import Mathutils
+
+# import Blender
+# from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils
+# from Blender.Mathutils import Vector
+# import BPyImage
+
+# import BPyMessages
+
+# try:
+# from struct import calcsize, unpack
+# except:
+# calcsize= unpack= None
+
+
+
+# # If python version is less than 2.4, try to get set stuff from module
+# try:
+# set
+# except:
+# from sets import Set as set
+
+BOUNDS_3DS = []
+
+
+#this script imports uvcoords as sticky vertex coords
+#this parameter enables copying these to face uv coords
+#which shold be more useful.
+
+def createBlenderTexture(material, name, image):
+ texture = bpy.data.textures.new(name)
+ texture.setType('Image')
+ texture.image = image
+ material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
+
+
+
+######################################################
+# Data Structures
+######################################################
+
+#Some of the chunks that we will see
+#----- Primary Chunk, at the beginning of each file
+PRIMARY = int('0x4D4D',16)
+
+#------ Main Chunks
+OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information
+VERSION = int('0x0002',16); #This gives the version of the .3ds file
+EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info
+
+#------ sub defines of OBJECTINFO
+MATERIAL = 45055 #0xAFFF // This stored the texture info
+OBJECT = 16384 #0x4000 // This stores the faces, vertices, etc...
+
+#>------ sub defines of MATERIAL
+#------ sub defines of MATERIAL_BLOCK
+MAT_NAME = int('0xA000',16) # This holds the material name
+MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material
+MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material
+MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material
+MAT_SHINESS = int('0xA040',16) # ??
+MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material
+MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material
+MAT_WIRE = int('0xA085',16) # Only render's wireframe
+
+MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map
+MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map
+MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map
+MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map
+MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map
+MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture
+
+MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats
+MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes
+
+#>------ sub defines of OBJECT
+OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object
+OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object
+OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght.
+OBJECT_LAMP_OFF = int('0x4620',16); # The light off.
+OBJECT_LAMP_ATTENUATE = int('0x4625',16);
+OBJECT_LAMP_RAYSHADE = int('0x4627',16);
+OBJECT_LAMP_SHADOWED = int('0x4630',16);
+OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16);
+OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16);
+OBJECT_LAMP_SEE_CONE = int('0x4650',16);
+OBJECT_LAMP_SPOT_RECTANGULAR = int('0x4651',16);
+OBJECT_LAMP_SPOT_OVERSHOOT = int('0x4652',16);
+OBJECT_LAMP_SPOT_PROJECTOR = int('0x4653',16);
+OBJECT_LAMP_EXCLUDE = int('0x4654',16);
+OBJECT_LAMP_RANGE = int('0x4655',16);
+OBJECT_LAMP_ROLL = int('0x4656',16);
+OBJECT_LAMP_SPOT_ASPECT = int('0x4657',16);
+OBJECT_LAMP_RAY_BIAS = int('0x4658',16);
+OBJECT_LAMP_INNER_RANGE = int('0x4659',16);
+OBJECT_LAMP_OUTER_RANGE = int('0x465A',16);
+OBJECT_LAMP_MULTIPLIER = int('0x465B',16);
+OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16);
+
+
+
+OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object
+
+#>------ sub defines of CAMERA
+OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values
+
+#>------ sub defines of OBJECT_MESH
+OBJECT_VERTICES = int('0x4110',16); # The objects vertices
+OBJECT_FACES = int('0x4120',16); # The objects faces
+OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color
+OBJECT_UV = int('0x4140',16); # The UV texture coordinates
+OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix
+
+global scn
+scn = None
+
+#the chunk class
+class chunk:
+ ID = 0
+ length = 0
+ bytes_read = 0
+
+ #we don't read in the bytes_read, we compute that
+ binary_format='<HI'
+
+ def __init__(self):
+ self.ID = 0
+ self.length = 0
+ self.bytes_read = 0
+
+ def dump(self):
+ print('ID: ', self.ID)
+ print('ID in hex: ', hex(self.ID))
+ print('length: ', self.length)
+ print('bytes_read: ', self.bytes_read)
+
+def read_chunk(file, chunk):
+ temp_data = file.read(struct.calcsize(chunk.binary_format))
+ data = struct.unpack(chunk.binary_format, temp_data)
+ chunk.ID = data[0]
+ chunk.length = data[1]
+ #update the bytes read function
+ chunk.bytes_read = 6
+
+ #if debugging
+ #chunk.dump()
+
+def read_string(file):
+ #read in the characters till we get a null character
+ s = b''
+# s = ''
+ while not s.endswith(b'\x00'):
+# while not s.endswith('\x00'):
+ s += struct.unpack('<c', file.read(1))[0]
+# s += struct.unpack( '<c', file.read(1) )[0]
+ #print 'string: ',s
+
+ s = str(s[:-1], 'ASCII')
+# print("read string", s)
+
+ #remove the null character from the string
+ return s
+# return s[:-1]
+
+######################################################
+# IMPORT
+######################################################
+def process_next_object_chunk(file, previous_chunk):
+ new_chunk = chunk()
+ temp_chunk = chunk()
+
+ while (previous_chunk.bytes_read < previous_chunk.length):
+ #read the next chunk
+ read_chunk(file, new_chunk)
+
+def skip_to_end(file, skip_chunk):
+ buffer_size = skip_chunk.length - skip_chunk.bytes_read
+ binary_format='%ic' % buffer_size
+ temp_data = file.read(struct.calcsize(binary_format))
+ skip_chunk.bytes_read += buffer_size
+
+
+def add_texture_to_material(image, texture, material, mapto):
+# if mapto=='DIFFUSE':
+# map = Texture.MapTo.COL
+# elif mapto=='SPECULAR':
+# map = Texture.MapTo.SPEC
+# elif mapto=='OPACITY':
+# map = Texture.MapTo.ALPHA
+# elif mapto=='BUMP':
+# map = Texture.MapTo.NOR
+# else:
+ if mapto not in ("COLOR", "SPECULARITY", "ALPHA", "NORMAL"):
+ print('/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name))
+ mapto = "COLOR"
+# map = Texture.MapTo.COL
+
+ if image: texture.image = image
+# if image: texture.setImage(image) # double check its an image.
+
+ material.add_texture(texture, "UV", mapto)
+# free_tex_slots = [i for i, tex in enumerate( material.getTextures() ) if tex == None]
+# if not free_tex_slots:
+# print('/tError: Cannot add "%s" map. 10 Texture slots alredy used.' % mapto)
+# else:
+# material.setTexture(free_tex_slots[0],texture,Texture.TexCo.UV,map)
+
+
+def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
+ #print previous_chunk.bytes_read, 'BYTES READ'
+ contextObName = None
+ contextLamp = [None, None] # object, Data
+ contextMaterial = None
+ contextMatrix_rot = None # Blender.Mathutils.Matrix(); contextMatrix.identity()
+ #contextMatrix_tx = None # Blender.Mathutils.Matrix(); contextMatrix.identity()
+ contextMesh_vertls = None
+ contextMesh_facels = None
+ contextMeshMaterials = {} # matname:[face_idxs]
+ contextMeshUV = None
+
+ TEXTURE_DICT = {}
+ MATDICT = {}
+# TEXMODE = Mesh.FaceModes['TEX']
+
+ # Localspace variable names, faster.
+ STRUCT_SIZE_1CHAR = struct.calcsize('c')
+ STRUCT_SIZE_2FLOAT = struct.calcsize('2f')
+ STRUCT_SIZE_3FLOAT = struct.calcsize('3f')
+ STRUCT_SIZE_UNSIGNED_SHORT = struct.calcsize('H')
+ STRUCT_SIZE_4UNSIGNED_SHORT = struct.calcsize('4H')
+ STRUCT_SIZE_4x3MAT = struct.calcsize('ffffffffffff')
+ _STRUCT_SIZE_4x3MAT = struct.calcsize('fffffffffffff')
+ # STRUCT_SIZE_4x3MAT = calcsize('ffffffffffff')
+ # print STRUCT_SIZE_4x3MAT, ' STRUCT_SIZE_4x3MAT'
+
+ def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
+
+ materialFaces = set() # faces that have a material. Can optimize?
+
+ # Now make copies with assigned materils.
+
+ def makeMeshMaterialCopy(matName, faces):
+ '''
+ Make a new mesh with only face the faces that use this material.
+ faces can be any iterable object - containing ints.
+ '''
+
+ faceVertUsers = [False] * len(myContextMesh_vertls)
+ ok = 0
+ for fIdx in faces:
+ for vindex in myContextMesh_facels[fIdx]:
+ faceVertUsers[vindex] = True
+ if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces.
+ materialFaces.add(fIdx)
+ ok = 1
+
+ if not ok:
+ return
+
+ myVertMapping = {}
+ vertMappingIndex = 0
+
+ vertsToUse = [i for i in range(len(myContextMesh_vertls)) if faceVertUsers[i]]
+ myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
+
+ tempName= '%s_%s' % (contextObName, matName) # matName may be None.
+ bmesh = bpy.data.add_mesh(tempName)
+# bmesh = bpy.data.meshes.new(tempName)
+
+ if matName == None:
+ img = None
+ else:
+ bmat = MATDICT[matName][1]
+ bmesh.add_material(bmat)
+# bmesh.materials = [bmat]
+ try: img = TEXTURE_DICT[bmat.name]
+ except: img = None
+
+# bmesh_verts = bmesh.verts
+ if len(vertsToUse):
+ bmesh.add_geometry(len(vertsToUse), 0, len(faces))
+
+ # XXX why add extra vertex?
+# bmesh_verts.extend( [Vector()] )
+ bmesh.verts.foreach_set("co", [x for tup in [myContextMesh_vertls[i] for i in vertsToUse] for x in tup])
+# bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
+
+ # +1 because of DUMMYVERT
+ bmesh.faces.foreach_set("verts_raw", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces]))
+# face_mapping = bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
+
+ if bmesh.faces and (contextMeshUV or img):
+ bmesh.add_uv_texture()
+# bmesh.faceUV = 1
+ for ii, i in enumerate(faces):
+
+ # Mapped index- faces may have not been added- if so, then map to the correct index
+ # BUGGY API - face_mapping is not always the right length
+# map_index = face_mapping[ii]
+
+ if 1:
+# if map_index != None:
+ targetFace = bmesh.faces[ii]
+# targetFace = bmesh.faces[map_index]
+
+ uf = bmesh.active_uv_texture.data[ii]
+
+ if contextMeshUV:
+ # v.index-1 because of the DUMMYVERT
+ uvs = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
+
+ if len(myContextMesh_facels[i]) == 3:
+ uf.uv1, uf.uv2, uf.uv3, uf.uv4 = uvs + [(0.0, 0.0)]
+ else:
+ uf.uv1, uf.uv2, uf.uv3, uf.uv4 = uvs
+# targetFace.uv = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
+ if img:
+ uf.image = img
+# targetFace.image = img
+
+ # bmesh.transform(contextMatrix)
+ ob = bpy.data.add_object("MESH", tempName)
+ ob.data = bmesh
+ SCN.add_object(ob)
+# ob = SCN_OBJECTS.new(bmesh, tempName)
+ '''
+ if contextMatrix_tx:
+ ob.setMatrix(contextMatrix_tx)
+ '''
+
+ if contextMatrix_rot:
+ # ob.matrix = [x for row in contextMatrix_rot for x in row]
+ ob.matrix = contextMatrix_rot
+# ob.setMatrix(contextMatrix_rot)
+
+ importedObjects.append(ob)
+ bmesh.update()
+# bmesh.calcNormals()
+
+ for matName, faces in myContextMeshMaterials.items():
+ makeMeshMaterialCopy(matName, faces)
+
+ if len(materialFaces) != len(myContextMesh_facels):
+ # Invert material faces.
+ makeMeshMaterialCopy(None, set(range(len( myContextMesh_facels ))) - materialFaces)
+ #raise 'Some UnMaterialed faces', len(contextMesh.faces)
+
+ #a spare chunk
+ new_chunk = chunk()
+ temp_chunk = chunk()
+
+ CreateBlenderObject = False
+
+ def read_float_color(temp_chunk):
+ temp_data = file.read(struct.calcsize('3f'))
+ temp_chunk.bytes_read += 12
+ return [float(col) for col in struct.unpack('<3f', temp_data)]
+
+ def read_byte_color(temp_chunk):
+ temp_data = file.read(struct.calcsize('3B'))
+ temp_chunk.bytes_read += 3
+ return [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb
+
+ def read_texture(new_chunk, temp_chunk, name, mapto):
+ new_texture = bpy.data.add_texture('Diffuse')
+ new_texture.type = 'IMAGE'
+
+ img = None
+ while (new_chunk.bytes_read < new_chunk.length):
+ #print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
+ read_chunk(file, temp_chunk)
+
+ if (temp_chunk.ID == MAT_MAP_FILENAME):
+ texture_name = read_string(file)
+ img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
+ new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
+
+ else:
+ skip_to_end(file, temp_chunk)
+
+ new_chunk.bytes_read += temp_chunk.bytes_read
+
+ # add the map to the material in the right channel
+ if img:
+ add_texture_to_material(img, new_texture, contextMaterial, mapto)
+
+ dirname = os.path.dirname(FILENAME)
+
+ #loop through all the data for this chunk (previous chunk) and see what it is
+ while (previous_chunk.bytes_read < previous_chunk.length):
+ #print '\t', previous_chunk.bytes_read, 'keep going'
+ #read the next chunk
+ #print 'reading a chunk'
+ read_chunk(file, new_chunk)
+
+ #is it a Version chunk?
+ if (new_chunk.ID == VERSION):
+ #print 'if (new_chunk.ID == VERSION):'
+ #print 'found a VERSION chunk'
+ #read in the version of the file
+ #it's an unsigned short (H)
+ temp_data = file.read(struct.calcsize('I'))
+ version = struct.unpack('<I', temp_data)[0]
+ new_chunk.bytes_read += 4 #read the 4 bytes for the version number
+ #this loader works with version 3 and below, but may not with 4 and above
+ if (version > 3):
+ print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version)
+
+ #is it an object info chunk?
+ elif (new_chunk.ID == OBJECTINFO):
+ #print 'elif (new_chunk.ID == OBJECTINFO):'
+ # print 'found an OBJECTINFO chunk'
+ process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH)
+
+ #keep track of how much we read in the main chunk
+ new_chunk.bytes_read += temp_chunk.bytes_read
+
+ #is it an object chunk?
+ elif (new_chunk.ID == OBJECT):
+
+ if CreateBlenderObject:
+ putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
+ contextMesh_vertls = []; contextMesh_facels = []
+
+ ## preparando para receber o proximo objeto
+ contextMeshMaterials = {} # matname:[face_idxs]
+ contextMeshUV = None
+ #contextMesh.vertexUV = 1 # Make sticky coords.
+ # Reset matrix
+ contextMatrix_rot = None
+ #contextMatrix_tx = None
+
+ CreateBlenderObject = True
+ tempName = read_string(file)
+ contextObName = tempName
+ new_chunk.bytes_read += len(tempName)+1
+
+ #is it a material chunk?
+ elif (new_chunk.ID == MATERIAL):
+
+# print("read material")
+
+ #print 'elif (new_chunk.ID == MATERIAL):'
+ contextMaterial = bpy.data.add_material('Material')
+# contextMaterial = bpy.data.materials.new('Material')
+
+ elif (new_chunk.ID == MAT_NAME):
+ #print 'elif (new_chunk.ID == MAT_NAME):'
+ material_name = read_string(file)
+
+# print("material name", material_name)
+
+ #plus one for the null character that ended the string
+ new_chunk.bytes_read += len(material_name)+1
+
+ contextMaterial.name = material_name.rstrip() # remove trailing whitespace
+ MATDICT[material_name]= (contextMaterial.name, contextMaterial)
+
+ elif (new_chunk.ID == MAT_AMBIENT):
+ #print 'elif (new_chunk.ID == MAT_AMBIENT):'
+ read_chunk(file, temp_chunk)
+ if (temp_chunk.ID == MAT_FLOAT_COLOR):
+ contextMaterial.mirror_color = read_float_color(temp_chunk)
+# temp_data = file.read(struct.calcsize('3f'))
+# temp_chunk.bytes_read += 12
+# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)]
+ elif (temp_chunk.ID == MAT_24BIT_COLOR):
+ contextMaterial.mirror_color = read_byte_color(temp_chunk)
+# temp_data = file.read(struct.calcsize('3B'))
+# temp_chunk.bytes_read += 3
+# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb
+ else:
+ skip_to_end(file, temp_chunk)
+ new_chunk.bytes_read += temp_chunk.bytes_read
+
+ elif (new_chunk.ID == MAT_DIFFUSE):
+ #print 'elif (new_chunk.ID == MAT_DIFFUSE):'
+ read_chunk(file, temp_chunk)
+ if (temp_chunk.ID == MAT_FLOAT_COLOR):
+ contextMaterial.diffuse_color = read_float_color(temp_chunk)
+# temp_data = file.read(struct.calcsize('3f'))
+# temp_chunk.bytes_read += 12
+# contextMaterial.rgbCol = [float(col) for col in struct.unpack('<3f', temp_data)]
+ elif (temp_chunk.ID == MAT_24BIT_COLOR):
+ contextMaterial.diffuse_color = read_byte_color(temp_chunk)
+# temp_data = file.read(struct.calcsize('3B'))
+# temp_chunk.bytes_read += 3
+# contextMaterial.rgbCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb
+ else:
+ skip_to_end(file, temp_chunk)
+
+# print("read material diffuse color", contextMaterial.diffuse_color)
+
+ new_chunk.bytes_read += temp_chunk.bytes_read
+
+ elif (new_chunk.ID == MAT_SPECULAR):
+ #print 'elif (new_chunk.ID == MAT_SPECULAR):'
+ read_chunk(file, temp_chunk)
+ if (temp_chunk.ID == MAT_FLOAT_COLOR):
+ contextMaterial.specular_color = read_float_color(temp_chunk)
+# temp_data = file.read(struct.calcsize('3f'))
+# temp_chunk.bytes_read += 12
+# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)]
+ elif (temp_chunk.ID == MAT_24BIT_COLOR):
+ contextMaterial.specular_color = read_byte_color(temp_chunk)
+# temp_data = file.read(struct.calcsize('3B'))
+# temp_chunk.bytes_read += 3
+# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb
+ else:
+ skip_to_end(file, temp_chunk)
+ new_chunk.bytes_read += temp_chunk.bytes_read
+
+ elif (new_chunk.ID == MAT_TEXTURE_MAP):
+ read_texture(new_chunk, temp_chunk, "Diffuse", "COLOR")
+# #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):'
+# new_texture= bpy.data.textures.new('Diffuse')
+# new_texture.setType('Image')
+# img = None
+# while (new_chunk.bytes_read<new_chunk.length):
+# #print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
+# read_chunk(file, temp_chunk)
+
+# if (temp_chunk.ID==MAT_MAP_FILENAME):
+# texture_name=read_string(file)
+# #img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
+# img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
+# new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
+
+# else:
+# skip_to_end(file, temp_chunk)
+
+# new_chunk.bytes_read+= temp_chunk.bytes_read
+
+# #add the map to the material in the right channel
+# if img:
+# add_texture_to_material(img, new_texture, contextMaterial, 'DIFFUSE')
+
+ elif (new_chunk.ID == MAT_SPECULAR_MAP):
+ read_texture(new_chunk, temp_chunk, "Specular", "SPECULARITY")
+# #print 'elif (new_chunk.ID == MAT_SPECULAR_MAP):'
+# new_texture = bpy.data.textures.new('Specular')
+# new_texture.setType('Image')
+# img = None
+# while (new_chunk.bytes_read < new_chunk.length):
+# read_chunk(file, temp_chunk)
+
+# if (temp_chunk.ID == MAT_MAP_FILENAME):
+# texture_name = read_string(file)
+# #img = BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
+# img = BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
+# new_chunk.bytes_read+= (len(texture_name)+1) #plus one for the null character that gets removed
+# else:
+# skip_to_end(file, temp_chunk)
+
+# new_chunk.bytes_read += temp_chunk.bytes_read
+
+# #add the map to the material in the right channel
+# if img:
+# add_texture_to_material(img, new_texture, contextMaterial, 'SPECULAR')
+
+ elif (new_chunk.ID == MAT_OPACITY_MAP):
+ read_texture(new_chunk, temp_chunk, "Opacity", "ALPHA")
+# #print 'new_texture = Blender.Texture.New('Opacity')'
+# new_texture = bpy.data.textures.new('Opacity')
+# new_texture.setType('Image')
+# img = None
+# while (new_chunk.bytes_read < new_chunk.length):
+# read_chunk(file, temp_chunk)
+
+# if (temp_chunk.ID == MAT_MAP_FILENAME):
+# texture_name = read_string(file)
+# #img = BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
+# img = BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
+# new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
+# else:
+# skip_to_end(file, temp_chunk)
+
+# new_chunk.bytes_read += temp_chunk.bytes_read
+# #add the map to the material in the right channel
+# if img:
+# add_texture_to_material(img, new_texture, contextMaterial, 'OPACITY')
+
+ elif (new_chunk.ID == MAT_BUMP_MAP):
+ read_texture(new_chunk, temp_chunk, "Bump", "NORMAL")
+# #print 'elif (new_chunk.ID == MAT_BUMP_MAP):'
+# new_texture = bpy.data.textures.new('Bump')
+# new_texture.setType('Image')
+# img = None
+# while (new_chunk.bytes_read < new_chunk.length):
+# read_chunk(file, temp_chunk)
+
+# if (temp_chunk.ID == MAT_MAP_FILENAME):
+# texture_name = read_string(file)
+# #img = BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
+# img = BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
+# new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
+# else:
+# skip_to_end(file, temp_chunk)
+
+# new_chunk.bytes_read += temp_chunk.bytes_read
+
+# #add the map to the material in the right channel
+# if img:
+# add_texture_to_material(img, new_texture, contextMaterial, 'BUMP')
+
+ elif (new_chunk.ID == MAT_TRANSPARENCY):
+ #print 'elif (new_chunk.ID == MAT_TRANSPARENCY):'
+ read_chunk(file, temp_chunk)
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
+
+ temp_chunk.bytes_read += 2
+ contextMaterial.alpha = 1-(float(struct.unpack('<H', temp_data)[0])/100)
+ new_chunk.bytes_read += temp_chunk.bytes_read
+
+
+ elif (new_chunk.ID == OBJECT_LAMP): # Basic lamp support.
+
+ temp_data = file.read(STRUCT_SIZE_3FLOAT)
+
+ x,y,z = struct.unpack('<3f', temp_data)
+ new_chunk.bytes_read += STRUCT_SIZE_3FLOAT
+
+ ob = bpy.data.add_object("LAMP", "Lamp")
+ ob.data = bpy.data.add_lamp("Lamp")
+ SCN.add_object(ob)
+
+ contextLamp[1]= ob.data
+# contextLamp[1]= bpy.data.lamps.new()
+ contextLamp[0]= ob
+# contextLamp[0]= SCN_OBJECTS.new(contextLamp[1])
+ importedObjects.append(contextLamp[0])
+
+ #print 'number of faces: ', num_faces
+ #print x,y,z
+ contextLamp[0].location = (x, y, z)
+# contextLamp[0].setLocation(x,y,z)
+
+ # Reset matrix
+ contextMatrix_rot = None
+ #contextMatrix_tx = None
+ #print contextLamp.name,
+
+ elif (new_chunk.ID == OBJECT_MESH):
+ # print 'Found an OBJECT_MESH chunk'
+ pass
+ elif (new_chunk.ID == OBJECT_VERTICES):
+ '''
+ Worldspace vertex locations
+ '''
+ # print 'elif (new_chunk.ID == OBJECT_VERTICES):'
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
+ num_verts = struct.unpack('<H', temp_data)[0]
+ new_chunk.bytes_read += 2
+
+ # print 'number of verts: ', num_verts
+ def getvert():
+ temp_data = struct.unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
+ new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
+ return temp_data
+
+ #contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed.
+ contextMesh_vertls = [getvert() for i in range(num_verts)]
+
+ #print 'object verts: bytes read: ', new_chunk.bytes_read
+
+ elif (new_chunk.ID == OBJECT_FACES):
+ # print 'elif (new_chunk.ID == OBJECT_FACES):'
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
+ num_faces = struct.unpack('<H', temp_data)[0]
+ new_chunk.bytes_read += 2
+ #print 'number of faces: ', num_faces
+
+ def getface():
+ # print '\ngetting a face'
+ temp_data = file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
+ new_chunk.bytes_read += STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
+ v1,v2,v3,dummy = struct.unpack('<4H', temp_data)
+ return v1, v2, v3
+
+ contextMesh_facels = [ getface() for i in range(num_faces) ]
+
+
+ elif (new_chunk.ID == OBJECT_MATERIAL):
+ # print 'elif (new_chunk.ID == OBJECT_MATERIAL):'
+ material_name = read_string(file)
+ new_chunk.bytes_read += len(material_name)+1 # remove 1 null character.
+
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
+ num_faces_using_mat = struct.unpack('<H', temp_data)[0]
+ new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
+
+ def getmat():
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
+ new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
+ return struct.unpack('<H', temp_data)[0]
+
+ contextMeshMaterials[material_name]= [ getmat() for i in range(num_faces_using_mat) ]
+
+ #look up the material in all the materials
+
+ elif (new_chunk.ID == OBJECT_UV):
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
+ num_uv = struct.unpack('<H', temp_data)[0]
+ new_chunk.bytes_read += 2
+
+ def getuv():
+ temp_data = file.read(STRUCT_SIZE_2FLOAT)
+ new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
+ return Mathutils.Vector( struct.unpack('<2f', temp_data) )
+# return Vector( struct.unpack('<2f', temp_data) )
+
+ contextMeshUV = [ getuv() for i in range(num_uv) ]
+
+ elif (new_chunk.ID == OBJECT_TRANS_MATRIX):
+ # How do we know the matrix size? 54 == 4x4 48 == 4x3
+ temp_data = file.read(STRUCT_SIZE_4x3MAT)
+ data = list( struct.unpack('<ffffffffffff', temp_data) )
+ new_chunk.bytes_read += STRUCT_SIZE_4x3MAT
+
+ contextMatrix_rot = Mathutils.Matrix(\
+# contextMatrix_rot = Blender.Mathutils.Matrix(\
+ data[:3] + [0],\
+ data[3:6] + [0],\
+ data[6:9] + [0],\
+ data[9:] + [1])
+
+
+ '''
+ contextMatrix_rot = Blender.Mathutils.Matrix(\
+ data[:3] + [0],\
+ data[3:6] + [0],\
+ data[6:9] + [0],\
+ [0,0,0,1])
+ '''
+
+ '''
+ contextMatrix_rot = Blender.Mathutils.Matrix(\
+ data[:3] ,\
+ data[3:6],\
+ data[6:9])
+ '''
+
+ '''
+ contextMatrix_rot = Blender.Mathutils.Matrix()
+ m = 0
+ for j in xrange(4):
+ for i in xrange(3):
+ contextMatrix_rot[j][i] = data[m]
+ m += 1
+
+ contextMatrix_rot[0][3]=0;
+ contextMatrix_rot[1][3]=0;
+ contextMatrix_rot[2][3]=0;
+ contextMatrix_rot[3][3]=1;
+ '''
+
+ #contextMatrix_rot.resize4x4()
+ #print "MTX"
+ #print contextMatrix_rot
+ contextMatrix_rot.invert()
+ #print contextMatrix_rot
+ #contextMatrix_tx = Blender.Mathutils.TranslationMatrix(0.5 * Blender.Mathutils.Vector(data[9:]))
+ #contextMatrix_tx.invert()
+
+ #tx.invert()
+
+ #contextMatrix = contextMatrix * tx
+ #contextMatrix = contextMatrix *tx
+
+ elif (new_chunk.ID == MAT_MAP_FILENAME):
+ texture_name = read_string(file)
+ try:
+ TEXTURE_DICT[contextMaterial.name]
+ except:
+ #img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
+ img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
+# img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
+
+ new_chunk.bytes_read += len(texture_name)+1 #plus one for the null character that gets removed
+
+ else: #(new_chunk.ID!=VERSION or new_chunk.ID!=OBJECTINFO or new_chunk.ID!=OBJECT or new_chunk.ID!=MATERIAL):
+ # print 'skipping to end of this chunk'
+ buffer_size = new_chunk.length - new_chunk.bytes_read
+ binary_format='%ic' % buffer_size
+ temp_data = file.read(struct.calcsize(binary_format))
+ new_chunk.bytes_read += buffer_size
+
+
+ #update the previous chunk bytes read
+ # print 'previous_chunk.bytes_read += new_chunk.bytes_read'
+ # print previous_chunk.bytes_read, new_chunk.bytes_read
+ previous_chunk.bytes_read += new_chunk.bytes_read
+ ## print 'Bytes left in this chunk: ', previous_chunk.length - previous_chunk.bytes_read
+
+ # FINISHED LOOP
+ # There will be a number of objects still not added
+ if contextMesh_facels != None:
+ putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
+
+def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, APPLY_MATRIX=False):
+ global FILENAME, SCN
+# global FILENAME, SCN_OBJECTS
+
+ # XXX
+# if BPyMessages.Error_NoFile(filename):
+# return
+
+ print('\n\nImporting 3DS: "%s"' % (filename))
+# print('\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename)))
+
+ time1 = time.clock()
+# time1 = Blender.sys.time()
+
+ FILENAME = filename
+ current_chunk = chunk()
+
+ file = open(filename,'rb')
+
+ #here we go!
+ # print 'reading the first chunk'
+ read_chunk(file, current_chunk)
+ if (current_chunk.ID!=PRIMARY):
+ print('\tFatal Error: Not a valid 3ds file: ', filename)
+ file.close()
+ return
+
+
+ # IMPORT_AS_INSTANCE = Blender.Draw.Create(0)
+# IMPORT_CONSTRAIN_BOUNDS = Blender.Draw.Create(10.0)
+# IMAGE_SEARCH = Blender.Draw.Create(1)
+# APPLY_MATRIX = Blender.Draw.Create(0)
+
+ # Get USER Options
+# pup_block = [\
+# ('Size Constraint:', IMPORT_CONSTRAIN_BOUNDS, 0.0, 1000.0, 'Scale the model by 10 until it reacehs the size constraint. Zero Disables.'),\
+# ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\
+# ('Transform Fix', APPLY_MATRIX, 'Workaround for object transformations importing incorrectly'),\
+# #('Group Instance', IMPORT_AS_INSTANCE, 'Import objects into a new scene and group, creating an instance in the current scene.'),\
+# ]
+
+# if PREF_UI:
+# if not Blender.Draw.PupBlock('Import 3DS...', pup_block):
+# return
+
+# Blender.Window.WaitCursor(1)
+
+# IMPORT_CONSTRAIN_BOUNDS = IMPORT_CONSTRAIN_BOUNDS.val
+# # IMPORT_AS_INSTANCE = IMPORT_AS_INSTANCE.val
+# IMAGE_SEARCH = IMAGE_SEARCH.val
+# APPLY_MATRIX = APPLY_MATRIX.val
+
+ if IMPORT_CONSTRAIN_BOUNDS:
+ BOUNDS_3DS[:]= [1<<30, 1<<30, 1<<30, -1<<30, -1<<30, -1<<30]
+ else:
+ BOUNDS_3DS[:]= []
+
+ ##IMAGE_SEARCH
+
+ scn = context.scene
+# scn = bpy.data.scenes.active
+ SCN = scn
+# SCN_OBJECTS = scn.objects
+# SCN_OBJECTS.selected = [] # de select all
+
+ importedObjects = [] # Fill this list with objects
+ process_next_chunk(file, current_chunk, importedObjects, IMAGE_SEARCH)
+
+
+ # Link the objects into this scene.
+ # Layers = scn.Layers
+
+ # REMOVE DUMMYVERT, - remove this in the next release when blenders internal are fixed.
+
+
+# for ob in importedObjects:
+# if ob.type == 'MESH':
+# # if ob.type=='Mesh':
+# me = ob.getData(mesh=1)
+# me.verts.delete([me.verts[0],])
+# if not APPLY_MATRIX:
+# me.transform(ob.matrixWorld.copy().invert())
+
+ # Done DUMMYVERT
+ """
+ if IMPORT_AS_INSTANCE:
+ name = filename.split('\\')[-1].split('/')[-1]
+ # Create a group for this import.
+ group_scn = Scene.New(name)
+ for ob in importedObjects:
+ group_scn.link(ob) # dont worry about the layers
+
+ grp = Blender.Group.New(name)
+ grp.objects = importedObjects
+
+ grp_ob = Object.New('Empty', name)
+ grp_ob.enableDupGroup = True
+ grp_ob.DupGroup = grp
+ scn.link(grp_ob)
+ grp_ob.Layers = Layers
+ grp_ob.sel = 1
+ else:
+ # Select all imported objects.
+ for ob in importedObjects:
+ scn.link(ob)
+ ob.Layers = Layers
+ ob.sel = 1
+ """
+
+ if 0:
+# if IMPORT_CONSTRAIN_BOUNDS!=0.0:
+ # Set bounds from objecyt bounding box
+ for ob in importedObjects:
+ if ob.type == 'MESH':
+# if ob.type=='Mesh':
+ ob.makeDisplayList() # Why dosnt this update the bounds?
+ for v in ob.getBoundBox():
+ for i in (0,1,2):
+ if v[i] < BOUNDS_3DS[i]:
+ BOUNDS_3DS[i]= v[i] # min
+
+ if v[i] > BOUNDS_3DS[i + 3]:
+ BOUNDS_3DS[i + 3]= v[i] # min
+
+ # Get the max axis x/y/z
+ max_axis = max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2])
+ # print max_axis
+ if max_axis < 1 << 30: # Should never be false but just make sure.
+
+ # Get a new scale factor if set as an option
+ SCALE = 1.0
+ while (max_axis * SCALE) > IMPORT_CONSTRAIN_BOUNDS:
+ SCALE/=10
+
+ # SCALE Matrix
+ SCALE_MAT = Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1])
+# SCALE_MAT = Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1])
+
+ for ob in importedObjects:
+ ob.setMatrix(ob.matrixWorld * SCALE_MAT)
+
+ # Done constraining to bounds.
+
+ # Select all new objects.
+ print('finished importing: "%s" in %.4f sec.' % (filename, (time.clock()-time1)))
+# print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)))
+ file.close()
+# Blender.Window.WaitCursor(0)
+
+
+DEBUG = False
+# if __name__=='__main__' and not DEBUG:
+# if calcsize == None:
+# Blender.Draw.PupMenu('Error%t|a full python installation not found')
+# else:
+# Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds')
+
+# For testing compatibility
+#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False)
+#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False)
+'''
+
+else:
+ import os
+ # DEBUG ONLY
+ TIME = Blender.sys.time()
+ import os
+ print 'Searching for files'
+ os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list')
+ # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list')
+ print '...Done'
+ file = open('/tmp/temp3ds_list', 'r')
+ lines = file.readlines()
+ file.close()
+ # sort by filesize for faster testing
+ lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
+ lines_size.sort()
+ lines = [f[1] for f in lines_size]
+
+
+ def between(v,a,b):
+ if v <= max(a,b) and v >= min(a,b):
+ return True
+ return False
+
+ for i, _3ds in enumerate(lines):
+ if between(i, 650,800):
+ #_3ds= _3ds[:-1]
+ print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines)
+ _3ds_file= _3ds.split('/')[-1].split('\\')[-1]
+ newScn = Blender.Scene.New(_3ds_file)
+ newScn.makeCurrent()
+ load_3ds(_3ds, False)
+
+ print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
+
+'''
+
+class IMPORT_OT_3ds(bpy.types.Operator):
+ '''
+ 3DS Importer
+ '''
+ __idname__ = "import.3ds"
+ __label__ = 'Import 3DS'
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = [
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= ""),
+
+# bpy.props.FloatProperty(attr="size_constraint", name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
+# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
+# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
+ ]
+
+ def execute(self, context):
+ load_3ds(self.path, context, 0.0, False, False)
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self.__operator__)
+ return ('RUNNING_MODAL',)
+ '''
+ def poll(self, context):
+ print("Poll")
+ return context.active_object != None'''
+
+bpy.ops.add(IMPORT_OT_3ds)
+
+# NOTES:
+# why add 1 extra vertex? and remove it when done?
+# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
diff --git a/release/scripts/import_obj.py b/release/scripts/io/import_obj.py
index 81230bfcf03..a762005ae7d 100644
--- a/release/scripts/import_obj.py
+++ b/release/scripts/io/import_obj.py
@@ -9,7 +9,7 @@ Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.'
__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone"
__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
-__version__= "2.13"
+__version__= "2.11"
__bpydoc__= """\
This script imports a Wavefront OBJ files to Blender.
@@ -21,8 +21,7 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo
# ***** BEGIN GPL LICENSE BLOCK *****
#
-# Script copyright (C) Campbell J Barton 2007-2009
-# - V2.12- bspline import/export added (funded by PolyDimensions GmbH)
+# Script copyright (C) Campbell J Barton 2007
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -41,14 +40,19 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-from Blender import Mesh, Draw, Window, Texture, Material, sys
+import os
+import time
import bpy
-import BPyMesh
-import BPyImage
-import BPyMessages
+import Mathutils
+import Geometry
-try: import os
-except: os= False
+# from Blender import Mesh, Draw, Window, Texture, Material, sys
+# # import BPyMesh
+# import BPyImage
+# import BPyMessages
+
+# try: import os
+# except: os= False
# Generic path functions
def stripFile(path):
@@ -56,7 +60,8 @@ def stripFile(path):
lastSlash= max(path.rfind('\\'), path.rfind('/'))
if lastSlash != -1:
path= path[:lastSlash]
- return '%s%s' % (path, sys.sep)
+ return '%s%s' % (path, os.sep)
+# return '%s%s' % (path, sys.sep)
def stripPath(path):
'''Strips the slashes from the back of a string'''
@@ -71,7 +76,215 @@ def stripExt(name): # name is a string
return name
# end path funcs
+def unpack_list(list_of_tuples):
+ l = []
+ for t in list_of_tuples:
+ l.extend(t)
+ return l
+
+# same as above except that it adds 0 for triangle faces
+def unpack_face_list(list_of_tuples):
+ l = []
+ for t in list_of_tuples:
+ face = [i for i in t]
+ if len(face) != 3 and len(face) != 4:
+ raise RuntimeError("{0} vertices in face.".format(len(face)))
+
+ # rotate indices if the 4th is 0
+ if len(face) == 4 and face[3] == 0:
+ face = [face[3], face[0], face[1], face[2]]
+
+ if len(face) == 3:
+ face.append(0)
+
+ l.extend(face)
+
+ return l
+
+def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
+ '''
+ Takes a polyline of indices (fgon)
+ and returns a list of face indicie lists.
+ Designed to be used for importers that need indices for an fgon to create from existing verts.
+
+ from_data: either a mesh, or a list/tuple of vectors.
+ indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given.
+ PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly.
+ '''
+
+ if not set: # Need sets for this, otherwise do a normal fill.
+ PREF_FIX_LOOPS= False
+
+ Vector= Mathutils.Vector
+ if not indices:
+ return []
+
+ # return []
+ def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6)
+ def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length
+
+ def vert_treplet(v, i):
+ return v, rvec(v), i, mlen(v)
+
+ def ed_key_mlen(v1, v2):
+ if v1[3] > v2[3]:
+ return v2[1], v1[1]
+ else:
+ return v1[1], v2[1]
+
+
+ if not PREF_FIX_LOOPS:
+ '''
+ Normal single concave loop filling
+ '''
+ if type(from_data) in (tuple, list):
+ verts= [Vector(from_data[i]) for ii, i in enumerate(indices)]
+ else:
+ verts= [from_data.verts[i].co for ii, i in enumerate(indices)]
+
+ for i in range(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))):
+ if verts[i][1]==verts[i-1][0]:
+ verts.pop(i-1)
+
+ fill= Geometry.PolyFill([verts])
+
+ else:
+ '''
+ Seperate this loop into multiple loops be finding edges that are used twice
+ This is used by lightwave LWO files a lot
+ '''
+
+ if type(from_data) in (tuple, list):
+ verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)]
+ else:
+ verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)]
+
+ edges= [(i, i-1) for i in range(len(verts))]
+ if edges:
+ edges[0]= (0,len(verts)-1)
+
+ if not verts:
+ return []
+
+
+ edges_used= set()
+ edges_doubles= set()
+ # We need to check if any edges are used twice location based.
+ for ed in edges:
+ edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]])
+ if edkey in edges_used:
+ edges_doubles.add(edkey)
+ else:
+ edges_used.add(edkey)
+
+ # Store a list of unconnected loop segments split by double edges.
+ # will join later
+ loop_segments= []
+
+ v_prev= verts[0]
+ context_loop= [v_prev]
+ loop_segments= [context_loop]
+
+ for v in verts:
+ if v!=v_prev:
+ # Are we crossing an edge we removed?
+ if ed_key_mlen(v, v_prev) in edges_doubles:
+ context_loop= [v]
+ loop_segments.append(context_loop)
+ else:
+ if context_loop and context_loop[-1][1]==v[1]:
+ #raise "as"
+ pass
+ else:
+ context_loop.append(v)
+
+ v_prev= v
+ # Now join loop segments
+
+ def join_seg(s1,s2):
+ if s2[-1][1]==s1[0][1]: #
+ s1,s2= s2,s1
+ elif s1[-1][1]==s2[0][1]:
+ pass
+ else:
+ return False
+
+ # If were stuill here s1 and s2 are 2 segments in the same polyline
+ s1.pop() # remove the last vert from s1
+ s1.extend(s2) # add segment 2 to segment 1
+
+ if s1[0][1]==s1[-1][1]: # remove endpoints double
+ s1.pop()
+
+ s2[:]= [] # Empty this segment s2 so we dont use it again.
+ return True
+
+ joining_segments= True
+ while joining_segments:
+ joining_segments= False
+ segcount= len(loop_segments)
+
+ for j in range(segcount-1, -1, -1): #reversed(range(segcount)):
+ seg_j= loop_segments[j]
+ if seg_j:
+ for k in range(j-1, -1, -1): # reversed(range(j)):
+ if not seg_j:
+ break
+ seg_k= loop_segments[k]
+
+ if seg_k and join_seg(seg_j, seg_k):
+ joining_segments= True
+
+ loop_list= loop_segments
+
+ for verts in loop_list:
+ while verts and verts[0][1]==verts[-1][1]:
+ verts.pop()
+
+ loop_list= [verts for verts in loop_list if len(verts)>2]
+ # DONE DEALING WITH LOOP FIXING
+
+
+ # vert mapping
+ vert_map= [None]*len(indices)
+ ii=0
+ for verts in loop_list:
+ if len(verts)>2:
+ for i, vert in enumerate(verts):
+ vert_map[i+ii]= vert[2]
+ ii+=len(verts)
+
+ fill= Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ])
+ #draw_loops(loop_list)
+ #raise 'done loop'
+ # map to original indicies
+ fill= [[vert_map[i] for i in reversed(f)] for f in fill]
+
+
+ if not fill:
+ print('Warning Cannot scanfill, fallback on a triangle fan.')
+ fill= [ [0, i-1, i] for i in range(2, len(indices)) ]
+ else:
+ # Use real scanfill.
+ # See if its flipped the wrong way.
+ flip= None
+ for fi in fill:
+ if flip != None:
+ break
+ for i, vi in enumerate(fi):
+ if vi==0 and fi[i-1]==1:
+ flip= False
+ break
+ elif vi==1 and fi[i-1]==0:
+ flip= True
+ break
+
+ if not flip:
+ for i, fi in enumerate(fill):
+ fill[i]= tuple([ii for ii in reversed(fi)])
+
+ return fill
def line_value(line_split):
'''
@@ -88,22 +301,47 @@ def line_value(line_split):
elif length > 2:
return ' '.join( line_split[1:] )
+# limited replacement for BPyImage.comprehensiveImageLoad
+def load_image(imagepath, dirname):
+
+ if os.path.exists(imagepath):
+ return bpy.data.add_image(imagepath)
+
+ variants = [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
+
+ for path in variants:
+ if os.path.exists(path):
+ return bpy.data.add_image(path)
+ else:
+ print(path, "doesn't exist")
+
+ # TODO comprehensiveImageLoad also searched in bpy.config.textureDir
+ return None
+
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
- '''
- Mainly uses comprehensiveImageLoad
- but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
- '''
-
+
if '_' in imagepath:
- image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
- if image: return image
- # Did the exporter rename the image?
- image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
+ image= load_image(imagepath.replace('_', ' '), DIR)
if image: return image
-
- # Return an image, placeholder if it dosnt exist
- image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
- return image
+
+ return load_image(imagepath, DIR)
+
+# def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
+# '''
+# Mainly uses comprehensiveImageLoad
+# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
+# '''
+
+# if '_' in imagepath:
+# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
+# if image: return image
+# # Did the exporter rename the image?
+# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
+# if image: return image
+
+# # Return an image, placeholder if it dosnt exist
+# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
+# return image
def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH):
@@ -117,69 +355,82 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
# This function sets textures defined in .mtl file #
#==================================================================================#
def load_material_image(blender_material, context_material_name, imagepath, type):
-
- texture= bpy.data.textures.new(type)
- texture.setType('Image')
+
+ texture= bpy.data.add_texture(type)
+ texture.type= 'IMAGE'
+# texture= bpy.data.textures.new(type)
+# texture.setType('Image')
# Absolute path - c:\.. etc would work here
image= obj_image_load(imagepath, DIR, IMAGE_SEARCH)
- has_data = image.has_data
- texture.image = image
+ has_data = image.has_data if image else False
- if not has_data:
- try:
- # first time using this image. We need to load it first
- image.glLoad()
- except:
- # probably the image is crashed
- pass
- else:
- has_data = image.has_data
+ if image:
+ texture.image = image
# Adds textures for materials (rendering)
if type == 'Kd':
if has_data and image.depth == 32:
# Image has alpha
- blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA)
- texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha')
- blender_material.mode |= Material.Modes.ZTRANSP
+
+ # XXX bitmask won't work?
+ blender_material.add_texture(texture, "UV", ("COLOR", "ALPHA"))
+ texture.mipmap = True
+ texture.interpolation = True
+ texture.use_alpha = True
+ blender_material.z_transparency = True
blender_material.alpha = 0.0
+
+# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA)
+# texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha')
+# blender_material.mode |= Material.Modes.ZTRANSP
+# blender_material.alpha = 0.0
else:
- blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
+ blender_material.add_texture(texture, "UV", "COLOR")
+# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
# adds textures to faces (Textured/Alt-Z mode)
# Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
unique_material_images[context_material_name]= image, has_data # set the texface image
elif type == 'Ka':
- blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
+ blender_material.add_texture(texture, "UV", "AMBIENT")
+# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
elif type == 'Ks':
- blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
+ blender_material.add_texture(texture, "UV", "SPECULARITY")
+# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
elif type == 'Bump':
- blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
+ blender_material.add_texture(texture, "UV", "NORMAL")
+# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
elif type == 'D':
- blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
- blender_material.mode |= Material.Modes.ZTRANSP
+ blender_material.add_texture(texture, "UV", "ALPHA")
+ blender_material.z_transparency = True
blender_material.alpha = 0.0
+# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
+# blender_material.mode |= Material.Modes.ZTRANSP
+# blender_material.alpha = 0.0
# Todo, unset deffuse material alpha if it has an alpha channel
elif type == 'refl':
- blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
+ blender_material.add_texture(texture, "UV", "REFLECTION")
+# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
# Add an MTL with the same name as the obj if no MTLs are spesified.
temp_mtl= stripExt(stripPath(filepath))+ '.mtl'
-
- if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs:
- material_libs.append( temp_mtl )
+
+ if os.path.exists(DIR + temp_mtl) and temp_mtl not in material_libs:
+# if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs:
+ material_libs.append( temp_mtl )
del temp_mtl
#Create new materials
for name in unique_materials: # .keys()
if name != None:
- unique_materials[name]= bpy.data.materials.new(name)
+ unique_materials[name]= bpy.data.add_material(name)
+# unique_materials[name]= bpy.data.materials.new(name)
unique_material_images[name]= None, False # assign None to all material images to start with, add to later.
unique_materials[None]= None
@@ -187,7 +438,8 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
for libname in material_libs:
mtlpath= DIR + libname
- if not sys.exists(mtlpath):
+ if not os.path.exists(mtlpath):
+# if not sys.exists(mtlpath):
#print '\tError Missing MTL: "%s"' % mtlpath
pass
else:
@@ -197,7 +449,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
for line in mtl: #.xreadlines():
if line.startswith('newmtl'):
context_material_name= line_value(line.split())
- if unique_materials.has_key(context_material_name):
+ if context_material_name in unique_materials:
context_material = unique_materials[ context_material_name ]
else:
context_material = None
@@ -207,18 +459,23 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
line_split= line.split()
line_lower= line.lower().lstrip()
if line_lower.startswith('ka'):
- context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+ context_material.mirror_color = (float(line_split[1]), float(line_split[2]), float(line_split[3]))
+# context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
elif line_lower.startswith('kd'):
- context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+ context_material.diffuse_color = (float(line_split[1]), float(line_split[2]), float(line_split[3]))
+# context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
elif line_lower.startswith('ks'):
- context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+ context_material.specular_color = (float(line_split[1]), float(line_split[2]), float(line_split[3]))
+# context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
elif line_lower.startswith('ns'):
- context_material.setHardness( int((float(line_split[1])*0.51)) )
+ context_material.specular_hardness = int((float(line_split[1])*0.51))
+# context_material.setHardness( int((float(line_split[1])*0.51)) )
elif line_lower.startswith('ni'): # Refraction index
- context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3
+ context_material.ior = max(1, min(float(line_split[1]), 3))
+# context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3
elif line_lower.startswith('d') or line_lower.startswith('tr'):
- context_material.setAlpha(float(line_split[1]))
- context_material.mode |= Material.Modes.ZTRANSP
+ context_material.alpha = float(line_split[1])
+# context_material.setAlpha(float(line_split[1]))
elif line_lower.startswith('map_ka'):
img_filepath= line_value(line.split())
if img_filepath:
@@ -322,14 +579,14 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP,
face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index
matname= face[2]
- if matname and not unique_materials_split.has_key(matname):
+ if matname and matname not in unique_materials_split:
unique_materials_split[matname] = unique_materials[matname]
faces_split.append(face)
# remove one of the itemas and reorder
- return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.iteritems()]
+ return [(value[0], value[1], value[2], key_to_name(key)) for key, value in list(face_split_dict.items())]
def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname):
@@ -342,7 +599,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
if unique_smooth_groups:
sharp_edges= {}
- smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.iterkeys() ])
+ smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in list(unique_smooth_groups.keys()) ])
context_smooth_group_old= -1
# Split fgons into tri's
@@ -353,7 +610,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
context_object= None
# reverse loop through face indicies
- for f_idx in xrange(len(faces)-1, -1, -1):
+ for f_idx in range(len(faces)-1, -1, -1):
face_vert_loc_indicies,\
face_vert_tex_indicies,\
@@ -370,7 +627,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
if CREATE_EDGES:
# generators are better in python 2.4+ but can't be used in 2.3
# edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) )
- edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] )
+ edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in range(len_face_vert_loc_indicies-1)] )
faces.pop(f_idx)
else:
@@ -382,7 +639,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
edge_dict= smooth_group_users[context_smooth_group]
context_smooth_group_old= context_smooth_group
- for i in xrange(len_face_vert_loc_indicies):
+ for i in range(len_face_vert_loc_indicies):
i1= face_vert_loc_indicies[i]
i2= face_vert_loc_indicies[i-1]
if i1>i2: i1,i2= i2,i1
@@ -395,7 +652,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# FGons into triangles
if has_ngons and len_face_vert_loc_indicies > 4:
- ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies)
+ ngon_face_indices= BPyMesh_ngon(verts_loc, face_vert_loc_indicies)
faces.extend(\
[(\
[face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\
@@ -420,7 +677,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
except KeyError:
edge_users[i1,i2]= 1
- for key, users in edge_users.iteritems():
+ for key, users in edge_users.items():
if users>1:
fgon_edges[key]= None
@@ -430,8 +687,8 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# Build sharp edges
if unique_smooth_groups:
- for edge_dict in smooth_group_users.itervalues():
- for key, users in edge_dict.iteritems():
+ for edge_dict in list(smooth_group_users.values()):
+ for key, users in list(edge_dict.items()):
if users==1: # This edge is on the boundry of a group
sharp_edges[key]= None
@@ -441,25 +698,39 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
materials= [None] * len(unique_materials)
- for name, index in material_mapping.iteritems():
+ for name, index in list(material_mapping.items()):
materials[index]= unique_materials[name]
-
- me= bpy.data.meshes.new(dataname)
-
- me.materials= materials[0:16] # make sure the list isnt too big.
+
+ me= bpy.data.add_mesh(dataname)
+# me= bpy.data.meshes.new(dataname)
+
+ # make sure the list isnt too big
+ for material in materials[0:16]:
+ me.add_material(material)
+# me.materials= materials[0:16] # make sure the list isnt too big.
#me.verts.extend([(0,0,0)]) # dummy vert
- me.verts.extend(verts_loc)
-
- face_mapping= me.faces.extend([f[0] for f in faces], indexList=True)
+
+ me.add_geometry(len(verts_loc), 0, len(faces))
+
+ # verts_loc is a list of (x, y, z) tuples
+ me.verts.foreach_set("co", unpack_list(verts_loc))
+# me.verts.extend(verts_loc)
+
+ # faces is a list of (vert_indices, texco_indices, ...) tuples
+ # XXX faces should contain either 3 or 4 verts
+ # XXX no check for valid face indices
+ me.faces.foreach_set("verts_raw", unpack_face_list([f[0] for f in faces]))
+# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True)
if verts_tex and me.faces:
- me.faceUV= 1
+ me.add_uv_texture()
+# me.faceUV= 1
# TEXMODE= Mesh.FaceModes['TEX']
context_material_old= -1 # avoid a dict lookup
mat= 0 # rare case it may be un-initialized.
me_faces= me.faces
- ALPHA= Mesh.FaceTranspModes.ALPHA
+# ALPHA= Mesh.FaceTranspModes.ALPHA
for i, face in enumerate(faces):
if len(face[0]) < 2:
@@ -468,9 +739,14 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
if CREATE_EDGES:
edges.append(face[0])
else:
- face_index_map= face_mapping[i]
- if face_index_map!=None: # None means the face wasnt added
- blender_face= me_faces[face_index_map]
+# face_index_map= face_mapping[i]
+
+ # since we use foreach_set to add faces, all of them are added
+ if 1:
+# if face_index_map!=None: # None means the face wasnt added
+
+ blender_face = me.faces[i]
+# blender_face= me_faces[face_index_map]
face_vert_loc_indicies,\
face_vert_tex_indicies,\
@@ -489,17 +765,24 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
if mat>15:
mat= 15
context_material_old= context_material
-
- blender_face.mat= mat
+
+ blender_face.material_index= mat
+# blender_face.mat= mat
- if verts_tex:
+ if verts_tex:
+
+ blender_tface= me.uv_textures[0].data[i]
+
if context_material:
image, has_data= unique_material_images[context_material]
if image: # Can be none if the material dosnt have an image.
- blender_face.image= image
- if has_data and image.depth == 32:
- blender_face.transp |= ALPHA
+ blender_tface.image= image
+# blender_face.image= image
+ if has_data:
+# if has_data and image.depth == 32:
+ blender_tface.transp = 'ALPHA'
+# blender_face.transp |= ALPHA
# BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled.
if len(face_vert_loc_indicies)==4:
@@ -511,43 +794,80 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# END EEEKADOODLE FIX
# assign material, uv's and image
- for ii, uv in enumerate(blender_face.uv):
- uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]]
+ blender_tface.uv1= verts_tex[face_vert_tex_indicies[0]]
+ blender_tface.uv2= verts_tex[face_vert_tex_indicies[1]]
+ blender_tface.uv3= verts_tex[face_vert_tex_indicies[2]]
+
+ if blender_face.verts[3] != 0:
+ blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]]
+
+# for ii, uv in enumerate(blender_face.uv):
+# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]]
del me_faces
- del ALPHA
-
- # Add edge faces.
- me_edges= me.edges
- if CREATE_FGONS and fgon_edges:
- FGON= Mesh.EdgeFlags.FGON
- for ed in me.findEdges( fgon_edges.keys() ):
- if ed!=None:
- me_edges[ed].flag |= FGON
- del FGON
-
- if unique_smooth_groups and sharp_edges:
- SHARP= Mesh.EdgeFlags.SHARP
- for ed in me.findEdges( sharp_edges.keys() ):
- if ed!=None:
- me_edges[ed].flag |= SHARP
- del SHARP
-
+# del ALPHA
+
if CREATE_EDGES:
- me_edges.extend( edges )
+
+ me.add_geometry(0, len(edges), 0)
+
+ # edges should be a list of (a, b) tuples
+ me.edges.foreach_set("verts", unpack_list(edges))
+# me_edges.extend( edges )
- del me_edges
+# del me_edges
- me.calcNormals()
+ # Add edge faces.
+# me_edges= me.edges
+
+ def edges_match(e1, e2):
+ return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])
+
+ # XXX slow
+# if CREATE_FGONS and fgon_edges:
+# for fgon_edge in fgon_edges.keys():
+# for ed in me.edges:
+# if edges_match(fgon_edge, ed.verts):
+# ed.fgon = True
+
+# if CREATE_FGONS and fgon_edges:
+# FGON= Mesh.EdgeFlags.FGON
+# for ed in me.findEdges( fgon_edges.keys() ):
+# if ed!=None:
+# me_edges[ed].flag |= FGON
+# del FGON
+
+ # XXX slow
+# if unique_smooth_groups and sharp_edges:
+# for sharp_edge in sharp_edges.keys():
+# for ed in me.edges:
+# if edges_match(sharp_edge, ed.verts):
+# ed.sharp = True
+
+# if unique_smooth_groups and sharp_edges:
+# SHARP= Mesh.EdgeFlags.SHARP
+# for ed in me.findEdges( sharp_edges.keys() ):
+# if ed!=None:
+# me_edges[ed].flag |= SHARP
+# del SHARP
+
+ me.update()
+# me.calcNormals()
- ob= scn.objects.new(me)
+ ob= bpy.data.add_object("MESH", "Mesh")
+ ob.data= me
+ scn.add_object(ob)
+# ob= scn.objects.new(me)
new_objects.append(ob)
# Create the vertex groups. No need to have the flag passed here since we test for the
# content of the vertex_groups. If the user selects to NOT have vertex groups saved then
# the following test will never run
- for group_name, group_indicies in vertex_groups.iteritems():
- me.addVertGroup(group_name)
- me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE)
+ for group_name, group_indicies in vertex_groups.items():
+ group= ob.add_vertex_group(group_name)
+# me.addVertGroup(group_name)
+ for vertex_index in group_indicies:
+ ob.add_vertex_to_group(vertex_index, group, 1.0, 'REPLACE')
+# me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE)
def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
@@ -563,16 +883,16 @@ def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
cstype = context_nurbs.get('cstype', None)
if cstype == None:
- print '\tWarning, cstype not found'
+ print('\tWarning, cstype not found')
return
if cstype != 'bspline':
- print '\tWarning, cstype is not supported (only bspline)'
+ print('\tWarning, cstype is not supported (only bspline)')
return
if not curv_idx:
- print '\tWarning, curv argument empty or not set'
+ print('\tWarning, curv argument empty or not set')
return
if len(deg) > 1 or parm_v:
- print '\tWarning, surfaces not supported'
+ print('\tWarning, surfaces not supported')
return
cu = bpy.data.curves.new(name, 'Curve')
@@ -594,7 +914,7 @@ def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
# get for endpoint flag from the weighting
if curv_range and len(parm_u) > deg[0]+1:
do_endpoints = True
- for i in xrange(deg[0]+1):
+ for i in range(deg[0]+1):
if abs(parm_u[i]-curv_range[0]) > 0.0001:
do_endpoints = False
@@ -659,28 +979,30 @@ def get_float_func(filepath):
return float
def load_obj(filepath,
- CLAMP_SIZE= 0.0,
- CREATE_FGONS= True,
- CREATE_SMOOTH_GROUPS= True,
- CREATE_EDGES= True,
- SPLIT_OBJECTS= True,
- SPLIT_GROUPS= True,
- SPLIT_MATERIALS= True,
- ROTATE_X90= True,
- IMAGE_SEARCH=True,
- POLYGROUPS=False):
+ context,
+ CLAMP_SIZE= 0.0,
+ CREATE_FGONS= True,
+ CREATE_SMOOTH_GROUPS= True,
+ CREATE_EDGES= True,
+ SPLIT_OBJECTS= True,
+ SPLIT_GROUPS= True,
+ SPLIT_MATERIALS= True,
+ ROTATE_X90= True,
+ IMAGE_SEARCH=True,
+ POLYGROUPS=False):
'''
Called by the user interface or another script.
load_obj(path) - should give acceptable results.
This function passes the file and sends the data off
to be split into objects and then converted into mesh objects
'''
- print '\nimporting obj "%s"' % filepath
+ print('\nimporting obj "%s"' % filepath)
if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS:
POLYGROUPS = False
-
- time_main= sys.time()
+
+ time_main= time.time()
+# time_main= sys.time()
verts_loc= []
verts_tex= []
@@ -717,8 +1039,9 @@ def load_obj(filepath,
# so we need to know weather
context_multi_line= ''
- print '\tparsing obj file "%s"...' % filepath,
- time_sub= sys.time()
+ print('\tparsing obj file "%s"...' % filepath)
+ time_sub= time.time()
+# time_sub= sys.time()
file= open(filepath, 'rU')
for line in file: #.xreadlines():
@@ -926,70 +1249,77 @@ def load_obj(filepath,
'''
file.close()
- time_new= sys.time()
- print '%.4f sec' % (time_new-time_sub)
+ time_new= time.time()
+# time_new= sys.time()
+ print('%.4f sec' % (time_new-time_sub))
time_sub= time_new
- print '\tloading materials and images...',
+ print('\tloading materials and images...')
create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH)
-
- time_new= sys.time()
- print '%.4f sec' % (time_new-time_sub)
+
+ time_new= time.time()
+# time_new= sys.time()
+ print('%.4f sec' % (time_new-time_sub))
time_sub= time_new
if not ROTATE_X90:
verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc]
# deselect all
- scn = bpy.data.scenes.active
- scn.objects.selected = []
+# if context.selected_objects:
+# bpy.ops.OBJECT_OT_select_all_toggle()
+
+ scene = context.scene
+# scn = bpy.data.scenes.active
+# scn.objects.selected = []
new_objects= [] # put new objects here
- print '\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ),
+ print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ))
# Split the mesh by objects/materials, may
if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True
else: SPLIT_OB_OR_GROUP = False
for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS):
# Create meshes from the data, warning 'vertex_groups' wont support splitting
- create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname)
+ create_mesh(scene, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname)
# nurbs support
- for context_nurbs in nurbs:
- create_nurbs(scn, context_nurbs, verts_loc, new_objects)
+# for context_nurbs in nurbs:
+# create_nurbs(scn, context_nurbs, verts_loc, new_objects)
axis_min= [ 1000000000]*3
axis_max= [-1000000000]*3
- if CLAMP_SIZE:
- # Get all object bounds
- for ob in new_objects:
- for v in ob.getBoundBox():
- for axis, value in enumerate(v):
- if axis_min[axis] > value: axis_min[axis]= value
- if axis_max[axis] < value: axis_max[axis]= value
+# if CLAMP_SIZE:
+# # Get all object bounds
+# for ob in new_objects:
+# for v in ob.getBoundBox():
+# for axis, value in enumerate(v):
+# if axis_min[axis] > value: axis_min[axis]= value
+# if axis_max[axis] < value: axis_max[axis]= value
- # Scale objects
- max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2])
- scale= 1.0
+# # Scale objects
+# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2])
+# scale= 1.0
- while CLAMP_SIZE < max_axis * scale:
- scale= scale/10.0
+# while CLAMP_SIZE < max_axis * scale:
+# scale= scale/10.0
- for ob in new_objects:
- ob.setSize(scale, scale, scale)
+# for ob in new_objects:
+# ob.setSize(scale, scale, scale)
# Better rotate the vert locations
#if not ROTATE_X90:
# for ob in new_objects:
# ob.RotX = -1.570796326794896558
+
+ time_new= time.time()
+# time_new= sys.time()
- time_new= sys.time()
-
- print '%.4f sec' % (time_new-time_sub)
- print 'finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main))
+ print('%.4f sec' % (time_new-time_sub))
+ print('finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)))
DEBUG= True
@@ -1082,14 +1412,14 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
def do_help(e,v):
url = __url__[0]
- print 'Trying to open web browser with documentation at this address...'
- print '\t' + url
+ print('Trying to open web browser with documentation at this address...')
+ print('\t' + url)
try:
import webbrowser
webbrowser.open(url)
except:
- print '...could not open a browser window.'
+ print('...could not open a browser window.')
def obj_ui():
ui_x, ui_y = GLOBALS['MOUSE']
@@ -1199,11 +1529,11 @@ def load_obj_ui_batch(file):
DEBUG= False
-if __name__=='__main__' and not DEBUG:
- if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT:
- Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '')
- else:
- Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
+# if __name__=='__main__' and not DEBUG:
+# if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT:
+# Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '')
+# else:
+# Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
# For testing compatibility
'''
@@ -1232,3 +1562,77 @@ else:
'''
#load_obj('/test.obj')
#load_obj('/fe/obj/mba1.obj')
+
+
+
+class IMPORT_OT_obj(bpy.types.Operator):
+ '''
+ Operator documentation text, will be used for the operator tooltip and python docs.
+ '''
+ __idname__ = "import.obj"
+ __label__ = "Import OBJ"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = [
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= ""),
+
+ bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True),
+ bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True),
+ bpy.props.BoolProperty(attr="CREATE_EDGES", name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True),
+ bpy.props.BoolProperty(attr="SPLIT_OBJECTS", name="Object", description="Import OBJ Objects into Blender Objects", default= True),
+ bpy.props.BoolProperty(attr="SPLIT_GROUPS", name="Group", description="Import OBJ Groups into Blender Objects", default= True),
+ bpy.props.BoolProperty(attr="SPLIT_MATERIALS", name="Material", description="Import each material into a seperate mesh (Avoids > 16 per mesh error)", default= True),
+ # old comment: only used for user feedback
+ # disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj
+ # bpy.props.BoolProperty(attr="KEEP_VERT_ORDER", name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True),
+ bpy.props.BoolProperty(attr="ROTATE_X90", name="-X90", description="Rotate X 90.", default= True),
+ bpy.props.FloatProperty(attr="CLAMP_SIZE", name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.01, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0),
+ bpy.props.BoolProperty(attr="POLYGROUPS", name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True),
+ bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True),
+ ]
+
+ '''
+ def poll(self, context):
+ return True '''
+
+ def execute(self, context):
+ # print("Selected: " + context.active_object.name)
+
+ load_obj(self.path,
+ context,
+ self.CLAMP_SIZE,
+ self.CREATE_FGONS,
+ self.CREATE_SMOOTH_GROUPS,
+ self.CREATE_EDGES,
+ self.SPLIT_OBJECTS,
+ self.SPLIT_GROUPS,
+ self.SPLIT_MATERIALS,
+ self.ROTATE_X90,
+ self.IMAGE_SEARCH,
+ self.POLYGROUPS)
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self.__operator__)
+ return ('RUNNING_MODAL',)
+
+
+bpy.ops.add(IMPORT_OT_obj)
+
+
+# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
+# check later: line 489
+# can convert now: edge flags, edges: lines 508-528
+# ngon (uses python module BPyMesh): 384-414
+# nurbs: 947-
+# NEXT clamp size: get bound box with RNA
+# get back to l 140 (here)
+# search image in bpy.config.textureDir - load_image
+# replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load)
+# bitmask won't work? - 132
+# uses operator bpy.ops.OBJECT_OT_select_all_toggle() to deselect all (not necessary?)
+# uses bpy.sys.time()
diff --git a/release/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py
index 1eb91abb938..4a1dd2238e3 100644
--- a/release/io/netrender/__init__.py
+++ b/release/scripts/io/netrender/__init__.py
@@ -5,7 +5,9 @@ import operators
import client
import slave
import master
+import master_html
import utils
+import balancing
import ui
# store temp data in bpy module
diff --git a/release/scripts/io/netrender/balancing.py b/release/scripts/io/netrender/balancing.py
new file mode 100644
index 00000000000..637dd5ff92e
--- /dev/null
+++ b/release/scripts/io/netrender/balancing.py
@@ -0,0 +1,94 @@
+import time
+
+from netrender.utils import *
+import netrender.model
+
+class RatingRule:
+ def rate(self, job):
+ return 0
+
+class ExclusionRule:
+ def test(self, job):
+ return False
+
+class PriorityRule:
+ def test(self, job):
+ return False
+
+class Balancer:
+ def __init__(self):
+ self.rules = []
+ self.priorities = []
+ self.exceptions = []
+
+ def addRule(self, rule):
+ self.rules.append(rule)
+
+ def addPriority(self, priority):
+ self.priorities.append(priority)
+
+ def addException(self, exception):
+ self.exceptions.append(exception)
+
+ def applyRules(self, job):
+ return sum((rule.rate(job) for rule in self.rules))
+
+ def applyPriorities(self, job):
+ for priority in self.priorities:
+ if priority.test(job):
+ return True # priorities are first
+
+ return False
+
+ def applyExceptions(self, job):
+ for exception in self.exceptions:
+ if exception.test(job):
+ return True # exceptions are last
+
+ return False
+
+ def sortKey(self, job):
+ return (1 if self.applyExceptions(job) else 0, # exceptions after
+ 0 if self.applyPriorities(job) else 1, # priorities first
+ self.applyRules(job))
+
+ def balance(self, jobs):
+ if jobs:
+ jobs.sort(key=self.sortKey)
+ return jobs[0]
+ else:
+ return None
+
+# ==========================
+
+class RatingUsage(RatingRule):
+ def rate(self, job):
+ # less usage is better
+ return job.usage / job.priority
+
+class NewJobPriority(PriorityRule):
+ def __init__(self, limit = 1):
+ self.limit = limit
+
+ def test(self, job):
+ return job.countFrames(status = DONE) < self.limit
+
+class MinimumTimeBetweenDispatchPriority(PriorityRule):
+ def __init__(self, limit = 10):
+ self.limit = limit
+
+ def test(self, job):
+ return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
+
+class ExcludeQueuedEmptyJob(ExclusionRule):
+ def test(self, job):
+ return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
+
+class ExcludeSlavesLimit(ExclusionRule):
+ def __init__(self, count_jobs, count_slaves, limit = 0.75):
+ self.count_jobs = count_jobs
+ self.count_slaves = count_slaves
+ self.limit = limit
+
+ def test(self, job):
+ return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
diff --git a/release/io/netrender/client.py b/release/scripts/io/netrender/client.py
index d059387cfcf..1897d1fd949 100644
--- a/release/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -1,14 +1,14 @@
import bpy
-import sys, os
+import sys, os, re
import http, http.client, http.server, urllib
import subprocess, shutil, time, hashlib
+import netrender.model
import netrender.slave as slave
import netrender.master as master
from netrender.utils import *
-
-def clientSendJob(conn, scene, anim = False, chunks = 5):
+def clientSendJob(conn, scene, anim = False):
netsettings = scene.network_render
job = netrender.model.RenderJob()
@@ -103,7 +103,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5):
job.priority = netsettings.priority
# try to send path first
- conn.request("POST", "job", repr(job.serialize()))
+ conn.request("POST", "/job", repr(job.serialize()))
response = conn.getresponse()
job_id = response.getheader("job-id")
@@ -112,7 +112,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5):
if response.status == http.client.ACCEPTED:
for filepath, start, end in job.files:
f = open(filepath, "rb")
- conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath})
+ conn.request("PUT", "/file", f, headers={"job-id": job_id, "job-file": filepath})
f.close()
response = conn.getresponse()
@@ -121,7 +121,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5):
return job_id
def requestResult(conn, job_id, frame):
- conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(frame)})
+ conn.request("GET", "/render", headers={"job-id": job_id, "job-frame":str(frame)})
@rnaType
class NetworkRenderEngine(bpy.types.RenderEngine):
@@ -138,12 +138,12 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
print("UNKNOWN OPERATION MODE")
def render_master(self, scene):
- server_address = (scene.network_render.server_address, scene.network_render.server_port)
- httpd = master.RenderMasterServer(server_address, master.RenderHandler, scene.network_render.path)
- httpd.timeout = 1
- httpd.stats = self.update_stats
- while not self.test_break():
- httpd.handle_request()
+ netsettings = scene.network_render
+
+ address = "" if netsettings.server_address == "[default]" else netsettings.server_address
+
+ master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
+
def render_slave(self, scene):
slave.render_slave(self, scene)
@@ -152,6 +152,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
netsettings = scene.network_render
self.update_stats("", "Network render client initiation")
+
conn = clientConnection(scene)
if conn:
@@ -173,7 +174,6 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
requestResult(conn, job_id, scene.current_frame)
while response.status == http.client.ACCEPTED and not self.test_break():
- print("waiting")
time.sleep(1)
requestResult(conn, job_id, scene.current_frame)
response = conn.getresponse()
diff --git a/release/io/netrender/master.py b/release/scripts/io/netrender/master.py
index 78e9243bc9d..be23fda7a91 100644
--- a/release/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -1,13 +1,11 @@
import sys, os
-import http, http.client, http.server, urllib
+import http, http.client, http.server, urllib, socket
import subprocess, shutil, time, hashlib
from netrender.utils import *
import netrender.model
-
-JOB_WAITING = 0 # before all data has been entered
-JOB_PAUSED = 1 # paused by user
-JOB_QUEUED = 2 # ready to be dispatched
+import netrender.balancing
+import netrender.master_html
class MRenderFile:
def __init__(self, filepath, start, end):
@@ -31,31 +29,38 @@ class MRenderSlave(netrender.model.RenderSlave):
self.last_seen = time.time()
self.job = None
- self.frame = None
+ self.job_frames = []
netrender.model.RenderSlave._slave_map[self.id] = self
def seen(self):
self.last_seen = time.time()
-
-# sorting key for jobs
-def groupKey(job):
- return (job.status, job.framesLeft() > 0, job.priority, job.credits)
+
+ def finishedFrame(self, frame_number):
+ self.job_frames.remove(frame_number)
+ if not self.job_frames:
+ self.job = None
class MRenderJob(netrender.model.RenderJob):
- def __init__(self, job_id, name, files, chunks = 1, priority = 1, credits = 100.0, blacklist = []):
+ def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []):
super().__init__()
self.id = job_id
+ self.type = job_type
self.name = name
self.files = files
self.frames = []
self.chunks = chunks
self.priority = priority
- self.credits = credits
+ self.usage = 0.0
self.blacklist = blacklist
self.last_dispatched = time.time()
+
+ # force one chunk for process jobs
+ if self.type == netrender.model.JOB_PROCESS:
+ self.chunks = 1
# special server properties
+ self.last_update = 0
self.save_path = ""
self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files}
self.status = JOB_WAITING
@@ -74,26 +79,29 @@ class MRenderJob(netrender.model.RenderJob):
self.start()
return True
+ def testFinished(self):
+ for f in self.frames:
+ if f.status == QUEUED or f.status == DISPATCHED:
+ break
+ else:
+ self.status = JOB_FINISHED
+
def start(self):
self.status = JOB_QUEUED
- def update(self):
- self.credits -= 5 # cost of one frame
- self.credits += (time.time() - self.last_dispatched) / 60
- self.last_dispatched = time.time()
+ def addLog(self, frames):
+ log_name = "_".join(("%04d" % f for f in frames)) + ".log"
+ log_path = self.save_path + log_name
+
+ for number in frames:
+ frame = self[number]
+ if frame:
+ frame.log_path = log_path
- def addFrame(self, frame_number):
- frame = MRenderFrame(frame_number)
+ def addFrame(self, frame_number, command):
+ frame = MRenderFrame(frame_number, command)
self.frames.append(frame)
return frame
-
- def framesLeft(self):
- total = 0
- for j in self.frames:
- if j.status == QUEUED:
- total += 1
-
- return total
def reset(self, all):
for f in self.frames:
@@ -103,7 +111,7 @@ class MRenderJob(netrender.model.RenderJob):
frames = []
for f in self.frames:
if f.status == QUEUED:
- self.update()
+ self.last_dispatched = time.time()
frames.append(f)
if len(frames) >= self.chunks:
break
@@ -111,12 +119,15 @@ class MRenderJob(netrender.model.RenderJob):
return frames
class MRenderFrame(netrender.model.RenderFrame):
- def __init__(self, frame):
+ def __init__(self, frame, command):
super().__init__()
self.number = frame
self.slave = None
self.time = 0
self.status = QUEUED
+ self.command = command
+
+ self.log_path = None
def reset(self, all):
if all or self.status == ERROR:
@@ -131,9 +142,9 @@ class MRenderFrame(netrender.model.RenderFrame):
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
class RenderHandler(http.server.BaseHTTPRequestHandler):
- def send_head(self, code = http.client.OK, headers = {}):
+ def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"):
self.send_response(code)
- self.send_header("Content-type", "application/octet-stream")
+ self.send_header("Content-type", content)
for key, value in headers.items():
self.send_header(key, value)
@@ -141,30 +152,24 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
self.end_headers()
def do_HEAD(self):
- print(self.path)
- if self.path == "status":
+ if self.path == "/status":
job_id = self.headers.get('job-id', "")
job_frame = int(self.headers.get('job-frame', -1))
- if job_id:
- print("status:", job_id, "\n")
+ job = self.server.getJobID(job_id)
+ if job:
+ frame = job[job_frame]
- job = self.server.getJobByID(job_id)
- if job:
- if job_frame != -1:
- frame = job[frame]
-
- if not frame:
- # no such frame
- self.send_heat(http.client.NO_CONTENT)
- return
+
+ if frame:
+ self.send_head(http.client.OK)
else:
- # no such job id
+ # no such frame
self.send_head(http.client.NO_CONTENT)
- return
-
- self.send_head()
+ else:
+ # no such job id
+ self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
@@ -173,19 +178,17 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def do_GET(self):
- print(self.path)
- if self.path == "version":
+ if self.path == "/version":
self.send_head()
- self.server.stats("", "New client connection")
+ self.server.stats("", "Version check")
self.wfile.write(VERSION)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "render":
+ elif self.path == "/render":
job_id = self.headers['job-id']
job_frame = int(self.headers['job-frame'])
- print("render:", job_id, job_frame)
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
frame = job[job_frame]
@@ -194,7 +197,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if frame.status in (QUEUED, DISPATCHED):
self.send_head(http.client.ACCEPTED)
elif frame.status == DONE:
- self.server.stats("", "Sending result back to client")
+ self.server.stats("", "Sending result to client")
f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb')
self.send_head()
@@ -211,22 +214,21 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
# no such job id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "log":
+ elif self.path == "/log":
job_id = self.headers['job-id']
job_frame = int(self.headers['job-frame'])
- print("log:", job_id, job_frame)
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
frame = job[job_frame]
if frame:
- if frame.status in (QUEUED, DISPATCHED):
+ if not frame.log_path or frame.status in (QUEUED, DISPATCHED):
self.send_head(http.client.PROCESSING)
else:
- self.server.stats("", "Sending log back to client")
- f = open(job.save_path + "%04d" % job_frame + ".log", 'rb')
+ self.server.stats("", "Sending log to client")
+ f = open(frame.log_path, 'rb')
self.send_head()
@@ -240,14 +242,13 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
# no such job id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "status":
+ elif self.path == "/status":
job_id = self.headers.get('job-id', "")
job_frame = int(self.headers.get('job-frame', -1))
if job_id:
- print("status:", job_id, "\n")
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
if job_frame != -1:
frame = job[frame]
@@ -270,21 +271,21 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
for job in self.server:
message.append(job.serialize())
+
+ self.server.stats("", "Sending status")
self.send_head()
self.wfile.write(bytes(repr(message), encoding='utf8'))
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "job":
- self.server.update()
+ elif self.path == "/job":
+ self.server.balance()
slave_id = self.headers['slave-id']
- print("slave-id", slave_id)
-
- slave = self.server.updateSlave(slave_id)
+ slave = self.server.getSeenSlave(slave_id)
if slave: # only if slave id is valid
- job, frames = self.server.getNewJob(slave_id)
+ job, frames = self.server.newDispatch(slave_id)
if job and frames:
for f in frames:
@@ -292,39 +293,44 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
f.status = DISPATCHED
f.slave = slave
+ slave.job = job
+ slave.job_frames = [f.number for f in frames]
+
self.send_head(headers={"job-id": job.id})
message = job.serialize(frames)
self.wfile.write(bytes(repr(message), encoding='utf8'))
- self.server.stats("", "Sending job frame to render node")
+ self.server.stats("", "Sending job to slave")
else:
# no job available, return error code
+ slave.job = None
+ slave.job_frames = []
+
self.send_head(http.client.ACCEPTED)
else: # invalid slave id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "file":
+ elif self.path == "/file":
slave_id = self.headers['slave-id']
- slave = self.server.updateSlave(slave_id)
+ slave = self.server.getSeenSlave(slave_id)
if slave: # only if slave id is valid
job_id = self.headers['job-id']
job_file = self.headers['job-file']
- print("job:", job_id, "\n")
- print("file:", job_file, "\n")
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
render_file = job.files_map.get(job_file, None)
if render_file:
- self.server.stats("", "Sending file to render node")
- f = open(render_file.path, 'rb')
+ self.server.stats("", "Sending file to slave")
+ f = open(render_file.filepath, 'rb')
+ self.send_head()
shutil.copyfileobj(f, self.wfile)
f.close()
@@ -337,16 +343,21 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else: # invalid slave id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "slave":
+ elif self.path == "/slaves":
message = []
+ self.server.stats("", "Sending slaves status")
+
for slave in self.server.slaves:
message.append(slave.serialize())
self.send_head()
self.wfile.write(bytes(repr(message), encoding='utf8'))
-
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ else:
+ # hand over the rest to the html section
+ netrender.master_html.get(self)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
@@ -354,12 +365,9 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def do_POST(self):
- print(self.path)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- if self.path == "job":
- print("posting job info")
- self.server.stats("", "Receiving job")
+ if self.path == "/job":
length = int(self.headers['content-length'])
@@ -367,84 +375,126 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
job_id = self.server.nextJobID()
- print(job_info.files)
-
- job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
+ job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
for frame in job_info.frames:
- frame = job.addFrame(frame.number)
+ frame = job.addFrame(frame.number, frame.command)
self.server.addJob(job)
headers={"job-id": job_id}
if job.testStart():
+ self.server.stats("", "New job, missing files")
self.send_head(headers=headers)
else:
+ self.server.stats("", "New job, started")
self.send_head(http.client.ACCEPTED, headers=headers)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "cancel":
+ elif self.path == "/cancel":
job_id = self.headers.get('job-id', "")
- if job_id:
- print("cancel:", job_id, "\n")
- self.server.removeJob(job_id)
- else: # cancel all jobs
- self.server.clear()
+
+ job = self.server.getJobID(job_id)
+
+ if job:
+ self.server.stats("", "Cancelling job")
+ self.server.removeJob(job)
+ self.send_head()
+ else:
+ # no such job id
+ self.send_head(http.client.NO_CONTENT)
+
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path == "/clear":
+ # cancel all jobs
+ self.server.stats("", "Clearing jobs")
+ self.server.clear()
self.send_head()
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "reset":
+ elif self.path == "/reset":
job_id = self.headers.get('job-id', "")
job_frame = int(self.headers.get('job-frame', "-1"))
all = bool(self.headers.get('reset-all', "False"))
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
if job_frame != -1:
- job[job_frame].reset(all)
+
+ frame = job[job_frame]
+ if frame:
+ self.server.stats("", "Reset job frame")
+ frame.reset(all)
+ self.send_head()
+ else:
+ # no such frame
+ self.send_head(http.client.NO_CONTENT)
+
else:
+ self.server.stats("", "Reset job")
job.reset(all)
+ self.send_head()
- self.send_head()
else: # job not found
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "slave":
+ elif self.path == "/slave":
length = int(self.headers['content-length'])
job_frame_string = self.headers['job-frame']
+ self.server.stats("", "New slave connected")
+
slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats)
self.send_head(headers = {"slave-id": slave_id})
-
+ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ elif self.path == "/log":
+ slave_id = self.headers['slave-id']
+
+ slave = self.server.getSeenSlave(slave_id)
+
+ if slave: # only if slave id is valid
+ length = int(self.headers['content-length'])
+
+ log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
+
+ job = self.server.getJobID(log_info.job_id)
+
+ if job:
+ self.server.stats("", "Log announcement")
+ job.addLog(log_info.frames)
+ self.send_head(http.client.OK)
+ else:
+ # no such job id
+ self.send_head(http.client.NO_CONTENT)
+ else: # invalid slave id
+ self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
def do_PUT(self):
- print(self.path)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- if self.path == "file":
- print("writing blend file")
+ if self.path == "/file":
self.server.stats("", "Receiving job")
length = int(self.headers['content-length'])
job_id = self.headers['job-id']
job_file = self.headers['job-file']
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
render_file = job.files_map.get(job_file, None)
if render_file:
- main_file = job.files[0]
+ main_file = job.files[0][0] # filename of the first file
main_path, main_name = os.path.split(main_file)
@@ -462,29 +512,30 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
f.close()
del buf
- render_file.path = file_path # set the new path
+ render_file.filepath = file_path # set the new path
if job.testStart():
- self.send_head(headers=headers)
+ self.server.stats("", "File upload, starting job")
+ self.send_head(http.client.OK)
else:
- self.send_head(http.client.ACCEPTED, headers=headers)
+ self.server.stats("", "File upload, file missings")
+ self.send_head(http.client.ACCEPTED)
else: # invalid file
self.send_head(http.client.NO_CONTENT)
else: # job not found
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "render":
- print("writing result file")
+ elif self.path == "/render":
self.server.stats("", "Receiving render result")
slave_id = self.headers['slave-id']
- slave = self.server.updateSlave(slave_id)
+ slave = self.server.getSeenSlave(slave_id)
if slave: # only if slave id is valid
job_id = self.headers['job-id']
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
job_frame = int(self.headers['job-frame'])
@@ -493,51 +544,63 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
frame = job[job_frame]
- if job_result == DONE:
- length = int(self.headers['content-length'])
- buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
- f.write(buf)
- f.close()
+ if frame:
+ if job.type == netrender.model.JOB_BLENDER:
+ if job_result == DONE:
+ length = int(self.headers['content-length'])
+ buf = self.rfile.read(length)
+ f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
+ f.write(buf)
+ f.close()
+
+ del buf
+ elif job_result == ERROR:
+ # blacklist slave on this job on error
+ job.blacklist.append(slave.id)
- del buf
- elif job_result == ERROR:
- # blacklist slave on this job on error
- job.blacklist.append(slave.id)
+ self.server.stats("", "Receiving result")
- frame.status = job_result
- frame.time = job_time
-
- self.server.updateSlave(self.headers['slave-id'])
-
- self.send_head()
+ slave.finishedFrame(job_frame)
+
+ frame.status = job_result
+ frame.time = job_time
+
+ job.testFinished()
+
+ self.send_head()
+ else: # frame not found
+ self.send_head(http.client.NO_CONTENT)
else: # job not found
self.send_head(http.client.NO_CONTENT)
else: # invalid slave id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "log":
- print("writing log file")
+ elif self.path == "/log":
self.server.stats("", "Receiving log file")
job_id = self.headers['job-id']
- job = self.server.getJobByID(job_id)
+ job = self.server.getJobID(job_id)
if job:
- length = int(self.headers['content-length'])
job_frame = int(self.headers['job-frame'])
- buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".log", 'wb')
- f.write(buf)
- f.close()
-
- del buf
-
- self.server.updateSlave(self.headers['slave-id'])
+ frame = job[job_frame]
- self.send_head()
+ if frame and frame.log_path:
+ length = int(self.headers['content-length'])
+ buf = self.rfile.read(length)
+ f = open(frame.log_path, 'ab')
+ f.write(buf)
+ f.close()
+
+ del buf
+
+ self.server.getSeenSlave(self.headers['slave-id'])
+
+ self.send_head()
+ else: # frame not found
+ self.send_head(http.client.NO_CONTENT)
else: # job not found
self.send_head(http.client.NO_CONTENT)
@@ -551,6 +614,15 @@ class RenderMasterServer(http.server.HTTPServer):
self.job_id = 0
self.path = path + "master_" + str(os.getpid()) + os.sep
+ self.slave_timeout = 2
+
+ self.balancer = netrender.balancing.Balancer()
+ self.balancer.addRule(netrender.balancing.RatingUsage())
+ self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob())
+ self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9))
+ self.balancer.addPriority(netrender.balancing.NewJobPriority())
+ self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority(limit = 2))
+
if not os.path.exists(self.path):
os.mkdir(self.path)
@@ -565,28 +637,77 @@ class RenderMasterServer(http.server.HTTPServer):
return slave.id
+ def removeSlave(self, slave):
+ self.slaves.remove(slave)
+ self.slaves_map.pop(slave.id)
+
def getSlave(self, slave_id):
return self.slaves_map.get(slave_id, None)
- def updateSlave(self, slave_id):
+ def getSeenSlave(self, slave_id):
slave = self.getSlave(slave_id)
if slave:
slave.seen()
return slave
+ def timeoutSlaves(self):
+ removed = []
+
+ t = time.time()
+
+ for slave in self.slaves:
+ if (t - slave.last_seen) / 60 > self.slave_timeout:
+ removed.append(slave)
+
+ if slave.job:
+ for f in slave.job_frames:
+ slave.job[f].status = ERROR
+
+ for slave in removed:
+ self.removeSlave(slave)
+
+ def updateUsage(self):
+ blend = 0.5
+ for job in self.jobs:
+ job.usage *= (1 - blend)
+
+ if self.slaves:
+ slave_usage = blend / self.countSlaves()
+
+ for slave in self.slaves:
+ if slave.job:
+ slave.job.usage += slave_usage
+
+
def clear(self):
- self.jobs_map = {}
- self.jobs = []
+ removed = self.jobs[:]
+
+ for job in removed:
+ self.removeJob(job)
+
+ def balance(self):
+ self.balancer.balance(self.jobs)
- def update(self):
- self.jobs.sort(key = groupKey)
+ def countJobs(self, status = JOB_QUEUED):
+ total = 0
+ for j in self.jobs:
+ if j.status == status:
+ total += 1
- def removeJob(self, id):
- job = self.jobs_map.pop(id)
-
- if job:
- self.jobs.remove(job)
+ return total
+
+ def countSlaves(self):
+ return len(self.slaves)
+
+ def removeJob(self, job):
+ self.jobs.remove(job)
+ self.jobs_map.pop(job.id)
+
+ for slave in self.slaves:
+ if slave.job == job:
+ slave.job = None
+ slave.job_frames = []
def addJob(self, job):
self.jobs.append(job)
@@ -599,17 +720,41 @@ class RenderMasterServer(http.server.HTTPServer):
job.save()
- def getJobByID(self, id):
+ def getJobID(self, id):
return self.jobs_map.get(id, None)
def __iter__(self):
for job in self.jobs:
yield job
- def getNewJob(self, slave_id):
+ def newDispatch(self, slave_id):
if self.jobs:
- for job in reversed(self.jobs):
- if job.status == JOB_QUEUED and job.framesLeft() > 0 and slave_id not in job.blacklist:
+ for job in self.jobs:
+ if not self.balancer.applyExceptions(job) and slave_id not in job.blacklist:
return job, job.getFrames()
return None, None
+
+def runMaster(address, broadcast, path, update_stats, test_break):
+ httpd = RenderMasterServer(address, RenderHandler, path)
+ httpd.timeout = 1
+ httpd.stats = update_stats
+
+ if broadcast:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+
+ start_time = time.time()
+
+ while not test_break():
+ httpd.handle_request()
+
+ if time.time() - start_time >= 10: # need constant here
+ httpd.timeoutSlaves()
+
+ httpd.updateUsage()
+
+ if broadcast:
+ print("broadcasting address")
+ s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('<broadcast>', 8000))
+ start_time = time.time()
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
new file mode 100644
index 00000000000..545659e8dc4
--- /dev/null
+++ b/release/scripts/io/netrender/master_html.py
@@ -0,0 +1,135 @@
+import re
+
+from netrender.utils import *
+
+
+def get(handler):
+ def output(text):
+ handler.wfile.write(bytes(text, encoding='utf8'))
+
+ def link(text, url):
+ return "<a href='%s'>%s</a>" % (url, text)
+
+ def startTable(border=1):
+ output("<table border='%i'>" % border)
+
+ def headerTable(*headers):
+ output("<thead><tr>")
+
+ for c in headers:
+ output("<td>" + c + "</td>")
+
+ output("</tr></thead>")
+
+ def rowTable(*data):
+ output("<tr>")
+
+ for c in data:
+ output("<td>" + str(c) + "</td>")
+
+ output("</tr>")
+
+ def endTable():
+ output("</table>")
+
+ if handler.path == "/html" or handler.path == "/":
+ handler.send_head(content = "text/html")
+ output("<html><head><title>NetRender</title></head><body>")
+
+ output("<h2>Master</h2>")
+
+ output("<h2>Slaves</h2>")
+
+ startTable()
+ headerTable("name", "address", "last seen", "stats", "job")
+
+ for slave in handler.server.slaves:
+ rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None")
+
+ endTable()
+
+ output("<h2>Jobs</h2>")
+
+ startTable()
+ headerTable(
+ "name",
+ "priority",
+ "usage",
+ "wait",
+ "length",
+ "done",
+ "dispatched",
+ "error",
+ "first",
+ "exception"
+ )
+
+ handler.server.balance()
+
+ for job in handler.server.jobs:
+ results = job.framesStatus()
+ rowTable(
+ link(job.name, "/html/job" + job.id),
+ job.priority,
+ "%0.1f%%" % (job.usage * 100),
+ "%is" % int(time.time() - job.last_dispatched),
+ len(job),
+ results[DONE],
+ results[DISPATCHED],
+ results[ERROR],
+ handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
+ )
+
+ endTable()
+
+ output("</body></html>")
+
+ elif handler.path.startswith("/html/job"):
+ handler.send_head(content = "text/html")
+ job_id = handler.path[9:]
+
+ output("<html><head><title>NetRender</title></head><body>")
+
+ job = handler.server.getJobID(job_id)
+
+ if job:
+ output("<h2>Frames</h2>")
+
+ startTable()
+ headerTable("no", "status", "render time", "slave", "log")
+
+ for frame in job.frames:
+ rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else "&nbsp;", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else "&nbsp;")
+
+ endTable()
+ else:
+ output("no such job")
+
+ output("</body></html>")
+
+ elif handler.path.startswith("/html/log"):
+ handler.send_head(content = "text/plain")
+ pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)")
+
+ match = pattern.match(handler.path[9:])
+ if match:
+ job_id = match.groups()[0]
+ frame_number = int(match.groups()[1])
+
+ job = handler.server.getJobID(job_id)
+
+ if job:
+ frame = job[frame_number]
+
+ if frame:
+ f = open(frame.log_path, 'rb')
+
+ shutil.copyfileobj(f, handler.wfile)
+
+ f.close()
+ else:
+ output("no such frame")
+ else:
+ output("no such job")
+ else:
+ output("malformed url")
diff --git a/release/io/netrender/model.py b/release/scripts/io/netrender/model.py
index 7803ad034a7..ca2a42d87f6 100644
--- a/release/io/netrender/model.py
+++ b/release/scripts/io/netrender/model.py
@@ -4,13 +4,35 @@ import subprocess, shutil, time, hashlib
from netrender.utils import *
+class LogFile:
+ def __init__(self, job_id = 0, frames = []):
+ self.job_id = job_id
+ self.frames = frames
+
+ def serialize(self):
+ return {
+ "job_id": self.job_id,
+ "frames": self.frames
+ }
+
+ @staticmethod
+ def materialize(data):
+ if not data:
+ return None
+
+ logfile = LogFile()
+ logfile.job_id = data["job_id"]
+ logfile.frames = data["frames"]
+
+ return logfile
+
class RenderSlave:
_slave_map = {}
def __init__(self):
self.id = ""
self.name = ""
- self.address = (0,0)
+ self.address = ("",0)
self.stats = ""
self.total_done = 0
self.total_error = 0
@@ -50,29 +72,49 @@ class RenderSlave:
return slave
+JOB_BLENDER = 1
+JOB_PROCESS = 2
+
+JOB_TYPES = {
+ JOB_BLENDER: "Blender",
+ JOB_PROCESS: "Process"
+ }
+
class RenderJob:
def __init__(self):
self.id = ""
+ self.type = JOB_BLENDER
self.name = ""
self.files = []
self.frames = []
self.chunks = 0
self.priority = 0
- self.credits = 0
+ self.usage = 0.0
self.blacklist = []
self.last_dispatched = 0.0
def addFile(self, file_path, start=-1, end=-1):
self.files.append((file_path, start, end))
- def addFrame(self, frame_number):
- frame = RenderFrame(frame_number)
+ def addFrame(self, frame_number, command = ""):
+ frame = RenderFrame(frame_number, command)
self.frames.append(frame)
return frame
def __len__(self):
return len(self.frames)
+ def countFrames(self, status=QUEUED):
+ total = 0
+ for f in self.frames:
+ if f.status == status:
+ total += 1
+
+ return total
+
+ def countSlaves(self):
+ return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED)))
+
def framesStatus(self):
results = {
QUEUED: 0,
@@ -105,12 +147,13 @@ class RenderJob:
max_frame = max((f.number for f in frames)) if frames else -1
return {
"id": self.id,
+ "type": self.type,
"name": self.name,
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])],
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
"chunks": self.chunks,
"priority": self.priority,
- "credits": self.credits,
+ "usage": self.usage,
"blacklist": self.blacklist,
"last_dispatched": self.last_dispatched
}
@@ -122,30 +165,36 @@ class RenderJob:
job = RenderJob()
job.id = data["id"]
+ job.type = data["type"]
job.name = data["name"]
job.files = data["files"]
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
job.chunks = data["chunks"]
job.priority = data["priority"]
- job.credits = data["credits"]
+ job.usage = data["usage"]
job.blacklist = data["blacklist"]
job.last_dispatched = data["last_dispatched"]
return job
class RenderFrame:
- def __init__(self, number = 0):
+ def __init__(self, number = 0, command = ""):
self.number = number
self.time = 0
self.status = QUEUED
self.slave = None
+ self.command = command
+
+ def statusText(self):
+ return STATUS_TEXT[self.status]
def serialize(self):
return {
"number": self.number,
"time": self.time,
"status": self.status,
- "slave": None if not self.slave else self.slave.serialize()
+ "slave": None if not self.slave else self.slave.serialize(),
+ "command": self.command
}
@staticmethod
@@ -158,5 +207,6 @@ class RenderFrame:
frame.time = data["time"]
frame.status = data["status"]
frame.slave = RenderSlave.materialize(data["slave"])
+ frame.command = data["command"]
return frame
diff --git a/release/io/netrender/operators.py b/release/scripts/io/netrender/operators.py
index ccecef670d4..42d1f6a0b86 100644
--- a/release/io/netrender/operators.py
+++ b/release/scripts/io/netrender/operators.py
@@ -1,12 +1,46 @@
import bpy
import sys, os
-import http, http.client, http.server, urllib
+import http, http.client, http.server, urllib, socket
+import webbrowser
from netrender.utils import *
import netrender.client as client
import netrender.model
@rnaOperator
+class RENDER_OT_netclientanim(bpy.types.Operator):
+ '''
+ Operator documentation text, will be used for the operator tooltip and python docs.
+ '''
+ __idname__ = "render.netclientanim"
+ __label__ = "Net Render Client Anim"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = []
+
+ def poll(self, context):
+ return True
+
+ def execute(self, context):
+ scene = context.scene
+
+ conn = clientConnection(scene)
+
+ if conn:
+ # Sending file
+ scene.network_render.job_id = client.clientSendJob(conn, scene, True)
+ conn.close()
+
+ bpy.ops.screen.render('INVOKE_AREA', animation=True)
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+@rnaOperator
class RENDER_OT_netclientsend(bpy.types.Operator):
'''
Operator documentation text, will be used for the operator tooltip and python docs.
@@ -30,6 +64,7 @@ class RENDER_OT_netclientsend(bpy.types.Operator):
if conn:
# Sending file
scene.network_render.job_id = client.clientSendJob(conn, scene, True)
+ conn.close()
return ('FINISHED',)
@@ -55,7 +90,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
conn = clientConnection(context.scene)
if conn:
- conn.request("GET", "status")
+ conn.request("GET", "/status")
response = conn.getresponse()
print( response.status, response.reason )
@@ -171,7 +206,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
conn = clientConnection(context.scene)
if conn:
- conn.request("GET", "slave")
+ conn.request("GET", "/slaves")
response = conn.getresponse()
print( response.status, response.reason )
@@ -224,10 +259,12 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
if conn:
job = bpy.data.netrender_jobs[netsettings.active_job_index]
- conn.request("POST", "cancel", headers={"job-id":job.id})
+ conn.request("POST", "/cancel", headers={"job-id":job.id})
response = conn.getresponse()
print( response.status, response.reason )
+
+ netsettings.jobs.remove(netsettings.active_job_index)
return ('FINISHED',)
@@ -235,6 +272,38 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
return self.execute(context)
@rnaOperator
+class RENDER_OT_netclientcancelall(bpy.types.Operator):
+ '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ __idname__ = "render.netclientcancelall"
+ __label__ = "Net Render Client Cancel All"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = []
+
+ def poll(self, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+ conn = clientConnection(context.scene)
+
+ if conn:
+ conn.request("POST", "/clear")
+
+ response = conn.getresponse()
+ print( response.status, response.reason )
+
+ while(len(netsettings.jobs) > 0):
+ netsettings.jobs.remove(0)
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+@rnaOperator
class netclientdownload(bpy.types.Operator):
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
__idname__ = "render.netclientdownload"
@@ -282,4 +351,73 @@ class netclientdownload(bpy.types.Operator):
return ('FINISHED',)
def invoke(self, context, event):
- return self.execute(context) \ No newline at end of file
+ return self.execute(context)
+
+@rnaOperator
+class netclientscan(bpy.types.Operator):
+ '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ __idname__ = "render.netclientscan"
+ __label__ = "Net Render Client Scan"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = []
+
+ def poll(self, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+ s.settimeout(30)
+
+ s.bind(('', 8000))
+
+ buf, address = s.recvfrom(64)
+
+ print("received:", buf)
+
+ netsettings.server_address = address[0]
+ netsettings.server_port = int(str(buf, encoding='utf8'))
+ except socket.timeout:
+ print("no server info")
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+@rnaOperator
+class netclientweb(bpy.types.Operator):
+ '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ __idname__ = "render.netclientweb"
+ __label__ = "Net Render Client Web"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = []
+
+ def poll(self, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+
+ # open connection to make sure server exists
+ conn = clientConnection(context.scene)
+
+ if conn:
+ conn.close()
+
+ webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port))
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ return self.execute(context)
diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py
new file mode 100644
index 00000000000..15ca6faf297
--- /dev/null
+++ b/release/scripts/io/netrender/slave.py
@@ -0,0 +1,224 @@
+import sys, os, platform
+import http, http.client, http.server, urllib
+import subprocess, time
+
+from netrender.utils import *
+import netrender.model
+
+CANCEL_POLL_SPEED = 2
+MAX_TIMEOUT = 10
+INCREMENT_TIMEOUT = 1
+
+if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5
+ import ctypes
+ def SetErrorMode():
+ val = ctypes.windll.kernel32.SetErrorMode(0x0002)
+ ctypes.windll.kernel32.SetErrorMode(val | 0x0002)
+ return val
+
+ def RestoreErrorMode(val):
+ ctypes.windll.kernel32.SetErrorMode(val)
+else:
+ def SetErrorMode():
+ return 0
+
+ def RestoreErrorMode(val):
+ pass
+
+def slave_Info():
+ sysname, nodename, release, version, machine, processor = platform.uname()
+ slave = netrender.model.RenderSlave()
+ slave.name = nodename
+ slave.stats = sysname + " " + release + " " + machine + " " + processor
+ return slave
+
+def testCancel(conn, job_id, frame_number):
+ conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
+ response = conn.getresponse()
+
+ # cancelled if job isn't found anymore
+ if response.status == http.client.NO_CONTENT:
+ return True
+ else:
+ return False
+
+def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None):
+ job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
+
+ if not os.path.exists(job_full_path):
+ temp_path = JOB_PREFIX + "slave.temp.blend"
+ conn.request("GET", "/file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path})
+ response = conn.getresponse()
+
+ if response.status != http.client.OK:
+ return None # file for job not returned by server, need to return an error code to server
+
+ f = open(temp_path, "wb")
+ buf = response.read(1024)
+
+ while buf:
+ f.write(buf)
+ buf = response.read(1024)
+
+ f.close()
+
+ os.renames(temp_path, job_full_path)
+
+ return job_full_path
+
+
+def render_slave(engine, scene):
+ netsettings = scene.network_render
+ timeout = 1
+
+ engine.update_stats("", "Network render node initiation")
+
+ conn = clientConnection(scene)
+
+ if conn:
+ conn.request("POST", "/slave", repr(slave_Info().serialize()))
+ response = conn.getresponse()
+
+ slave_id = response.getheader("slave-id")
+
+ NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
+ if not os.path.exists(NODE_PREFIX):
+ os.mkdir(NODE_PREFIX)
+
+ while not engine.test_break():
+
+ conn.request("GET", "/job", headers={"slave-id":slave_id})
+ response = conn.getresponse()
+
+ if response.status == http.client.OK:
+ timeout = 1 # reset timeout on new job
+
+ job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
+
+ JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
+ if not os.path.exists(JOB_PREFIX):
+ os.mkdir(JOB_PREFIX)
+
+
+ if job.type == netrender.model.JOB_BLENDER:
+ job_path = job.files[0][0] # data in files have format (path, start, end)
+ main_path, main_file = os.path.split(job_path)
+
+ job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path)
+ print("Fullpath", job_full_path)
+ print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
+ engine.update_stats("", "Render File", main_file, "for job", job.id)
+
+ for file_path, start, end in job.files[1:]:
+ print("\t", file_path)
+ testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path)
+
+ # announce log to master
+ logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames])
+ conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id})
+ response = conn.getresponse()
+
+
+ first_frame = job.frames[0].number
+
+ # start render
+ start_t = time.time()
+
+ if job.type == netrender.model.JOB_BLENDER:
+ frame_args = []
+
+ for frame in job.frames:
+ print("frame", frame.number)
+ frame_args += ["-f", str(frame.number)]
+
+ val = SetErrorMode()
+ process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ RestoreErrorMode(val)
+ elif job.type == netrender.model.JOB_PROCESS:
+ command = job.frames[0].command
+ val = SetErrorMode()
+ process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ RestoreErrorMode(val)
+
+ headers = {"job-id":job.id, "slave-id":slave_id}
+
+ cancelled = False
+ stdout = bytes()
+ run_t = time.time()
+ while process.poll() == None and not cancelled:
+ stdout += process.stdout.read(32)
+ current_t = time.time()
+ cancelled = engine.test_break()
+ if current_t - run_t > CANCEL_POLL_SPEED:
+
+ # update logs if needed
+ if stdout:
+ # (only need to update on one frame, they are linked
+ headers["job-frame"] = str(first_frame)
+ conn.request("PUT", "/log", stdout, headers=headers)
+ response = conn.getresponse()
+
+ stdout = bytes()
+
+ run_t = current_t
+ if testCancel(conn, job.id, first_frame):
+ cancelled = True
+
+ # read leftovers if needed
+ stdout += process.stdout.read()
+
+ if cancelled:
+ # kill process if needed
+ if process.poll() == None:
+ process.terminate()
+ continue # to next frame
+
+ total_t = time.time() - start_t
+
+ avg_t = total_t / len(job.frames)
+
+ status = process.returncode
+
+ print("status", status)
+
+ # flush the rest of the logs
+ if stdout:
+ # (only need to update on one frame, they are linked
+ headers["job-frame"] = str(first_frame)
+ conn.request("PUT", "/log", stdout, headers=headers)
+ response = conn.getresponse()
+
+ headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
+
+ if status == 0: # non zero status is error
+ headers["job-result"] = str(DONE)
+ for frame in job.frames:
+ headers["job-frame"] = str(frame.number)
+
+ if job.type == netrender.model.JOB_BLENDER:
+ # send image back to server
+ f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
+ conn.request("PUT", "/render", f, headers=headers)
+ f.close()
+ response = conn.getresponse()
+ elif job.type == netrender.model.JOB_PROCESS:
+ conn.request("PUT", "/render", headers=headers)
+ response = conn.getresponse()
+ else:
+ headers["job-result"] = str(ERROR)
+ for frame in job.frames:
+ headers["job-frame"] = str(frame.number)
+ # send error result back to server
+ conn.request("PUT", "/render", headers=headers)
+ response = conn.getresponse()
+ else:
+ if timeout < MAX_TIMEOUT:
+ timeout += INCREMENT_TIMEOUT
+
+ for i in range(timeout):
+ time.sleep(1)
+ if engine.test_break():
+ conn.close()
+ return
+
+ conn.close()
diff --git a/release/io/netrender/ui.py b/release/scripts/io/netrender/ui.py
index 12ac10b551f..7681d4865e9 100644
--- a/release/io/netrender/ui.py
+++ b/release/scripts/io/netrender/ui.py
@@ -39,6 +39,7 @@ class SCENE_PT_network_settings(RenderButtonsPanel):
def draw(self, context):
layout = self.layout
+
scene = context.scene
rd = scene.render_data
@@ -49,15 +50,42 @@ class SCENE_PT_network_settings(RenderButtonsPanel):
col = split.column()
col.itemR(scene.network_render, "mode")
+ col.itemR(scene.network_render, "path")
col.itemR(scene.network_render, "server_address")
col.itemR(scene.network_render, "server_port")
- col.itemR(scene.network_render, "path")
- if scene.network_render.mode == "RENDER_CLIENT":
- col.itemR(scene.network_render, "chunks")
- col.itemR(scene.network_render, "priority")
- col.itemR(scene.network_render, "job_name")
- col.itemO("render.netclientsend", text="send job to server")
+ if scene.network_render.mode == "RENDER_MASTER":
+ col.itemR(scene.network_render, "server_broadcast")
+ else:
+ col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="")
+
+@rnaType
+class SCENE_PT_network_job(RenderButtonsPanel):
+ __label__ = "Job Settings"
+ COMPAT_ENGINES = set(['NET_RENDER'])
+
+ def poll(self, context):
+ scene = context.scene
+ return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT"
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ rd = scene.render_data
+
+ layout.active = True
+
+ split = layout.split()
+
+ col = split.column()
+
+ col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network")
+ col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job")
+ col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor")
+ col.itemR(scene.network_render, "job_name")
+ col.itemR(scene.network_render, "priority")
+ col.itemR(scene.network_render, "chunks")
@rnaType
class SCENE_PT_network_slaves(RenderButtonsPanel):
@@ -157,6 +185,7 @@ class SCENE_PT_network_jobs(RenderButtonsPanel):
subcol = col.column(align=True)
subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="")
subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="")
+ subcol.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="")
subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="")
if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0:
@@ -191,7 +220,7 @@ NetRenderSettings.StringProperty( attr="server_address",
name="Server address",
description="IP or name of the master render server",
maxlen = 128,
- default = "127.0.0.1")
+ default = "[default]")
NetRenderSettings.IntProperty( attr="server_port",
name="Server port",
@@ -200,11 +229,23 @@ NetRenderSettings.IntProperty( attr="server_port",
min=1,
max=65535)
-NetRenderSettings.StringProperty( attr="path",
- name="Path",
- description="Path for temporary files",
- maxlen = 128,
- default = "/tmp/")
+NetRenderSettings.BoolProperty( attr="server_broadcast",
+ name="Broadcast server address",
+ description="broadcast server address on local network",
+ default = True)
+
+if os.name == 'nt':
+ NetRenderSettings.StringProperty( attr="path",
+ name="Path",
+ description="Path for temporary files",
+ maxlen = 128,
+ default = "C:/tmp/")
+else:
+ NetRenderSettings.StringProperty( attr="path",
+ name="Path",
+ description="Path for temporary files",
+ maxlen = 128,
+ default = "/tmp/")
NetRenderSettings.StringProperty( attr="job_name",
name="Job name",
diff --git a/release/io/netrender/utils.py b/release/scripts/io/netrender/utils.py
index db6646e6916..06393a738a0 100644
--- a/release/io/netrender/utils.py
+++ b/release/scripts/io/netrender/utils.py
@@ -8,11 +8,25 @@ import netrender.model
VERSION = b"0.5"
+# Jobs status
+JOB_WAITING = 0 # before all data has been entered
+JOB_PAUSED = 1 # paused by user
+JOB_FINISHED = 2 # finished rendering
+JOB_QUEUED = 3 # ready to be dispatched
+
+# Frames status
QUEUED = 0
DISPATCHED = 1
DONE = 2
ERROR = 3
+STATUS_TEXT = {
+ QUEUED: "Queued",
+ DISPATCHED: "Dispatched",
+ DONE: "Done",
+ ERROR: "Error"
+ }
+
def rnaType(rna_type):
bpy.types.register(rna_type)
return rna_type
@@ -22,9 +36,12 @@ def rnaOperator(rna_op):
return rna_op
def clientConnection(scene):
- netrender = scene.network_render
+ netsettings = scene.network_render
+
+ if netsettings.server_address == "[default]":
+ bpy.ops.render.netclientscan()
- conn = http.client.HTTPConnection(netrender.server_address, netrender.server_port)
+ conn = http.client.HTTPConnection(netsettings.server_address, netsettings.server_port)
if clientVerifyVersion(conn):
return conn
@@ -33,7 +50,7 @@ def clientConnection(scene):
return None
def clientVerifyVersion(conn):
- conn.request("GET", "version")
+ conn.request("GET", "/version")
response = conn.getresponse()
if response.status != http.client.OK:
@@ -56,8 +73,8 @@ def prefixPath(prefix_directory, file_path, prefix_path):
if not os.path.exists(full_path):
p, n = os.path.split(full_path)
- if main_path and p.startswith(main_path):
- directory = prefix_directory + p[len(main_path):]
+ if prefix_path and p.startswith(prefix_path):
+ directory = prefix_directory + p[len(prefix_path):]
full_path = directory + n
if not os.path.exists(directory):
os.mkdir(directory)
@@ -66,4 +83,4 @@ def prefixPath(prefix_directory, file_path, prefix_path):
else:
full_path = prefix_directory + file_path
- return full_path \ No newline at end of file
+ return full_path
diff --git a/release/scripts/lightwave_export.py b/release/scripts/lightwave_export.py
deleted file mode 100644
index bbfb9649c69..00000000000
--- a/release/scripts/lightwave_export.py
+++ /dev/null
@@ -1,707 +0,0 @@
-#!BPY
-
-"""
-Name: 'LightWave (.lwo)...'
-Blender: 243
-Group: 'Export'
-Tooltip: 'Export selected meshes to LightWave File Format (.lwo)'
-"""
-
-__author__ = "Anthony D'Agostino (Scorpius)"
-__url__ = ("blender", "blenderartists.org",
-"Author's homepage, http://www.redrival.com/scorpius")
-__version__ = "Part of IOSuite 0.5"
-
-__bpydoc__ = """\
-This script exports meshes to LightWave file format.
-
-LightWave is a full-featured commercial modeling and rendering
-application. The lwo file format is composed of 'chunks,' is well
-defined, and easy to read and write. It is similar in structure to the
-trueSpace cob format.
-
-Usage:<br>
- Select meshes to be exported and run this script from "File->Export" menu.
-
-Supported:<br>
- UV Coordinates, Meshes, Materials, Material Indices, Specular
-Highlights, and Vertex Colors. For added functionality, each object is
-placed on its own layer. Someone added the CLIP chunk and imagename support.
-
-Missing:<br>
- Not too much, I hope! :).
-
-Known issues:<br>
- Empty objects crash has been fixed.
-
-Notes:<br>
- For compatibility reasons, it also reads lwo files in the old LW
-v5.5 format.
-"""
-
-# $Id$
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | April 21, 2002 |
-# | Read and write LightWave Object File Format (*.lwo) |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-import BPyMesh
-try: import struct
-except: struct = None
-try: import cStringIO
-except: cStringIO = None
-try: import operator
-except: operator = None
-
-VCOL_NAME = "\251 Per-Face Vertex Colors"
-DEFAULT_NAME = "\251 Blender Default"
-# ==============================
-# === Write LightWave Format ===
-# ==============================
-def write(filename):
- start = Blender.sys.time()
- file = open(filename, "wb")
-
- scn = Blender.Scene.GetCurrent()
- objects = list(scn.objects.context)
-
- if not objects:
- Blender.Draw.PupMenu('Error%t|No Objects selected')
- return
-
- try: objects.sort( key = lambda a: a.name )
- except: objects.sort(lambda a,b: cmp(a.name, b.name))
-
- text = generate_text()
- desc = generate_desc()
- icon = "" #generate_icon()
-
- meshes = []
- mesh_object_name_lookup = {} # for name lookups only
-
- for obj in objects:
- mesh = BPyMesh.getMeshFromObject(obj, None, True, False, scn)
- if mesh:
- mesh.transform(obj.matrixWorld)
- meshes.append(mesh)
- mesh_object_name_lookup[mesh] = obj.name
- del obj
-
- material_names = get_used_material_names(meshes)
- tags = generate_tags(material_names)
- surfs = generate_surfs(material_names)
- chunks = [text, desc, icon, tags]
-
- meshdata = cStringIO.StringIO()
-
- layer_index = 0
-
- for mesh in meshes:
- layr = generate_layr(mesh_object_name_lookup[mesh], layer_index)
- pnts = generate_pnts(mesh)
- bbox = generate_bbox(mesh)
- pols = generate_pols(mesh)
- ptag = generate_ptag(mesh, material_names)
- clip = generate_clip(mesh, material_names)
-
- if mesh.faceUV:
- vmad_uv = generate_vmad_uv(mesh) # per face
-
- if mesh.vertexColors:
- #if meshtools.average_vcols:
- # vmap_vc = generate_vmap_vc(mesh) # per vert
- #else:
- vmad_vc = generate_vmad_vc(mesh) # per face
-
- write_chunk(meshdata, "LAYR", layr); chunks.append(layr)
- write_chunk(meshdata, "PNTS", pnts); chunks.append(pnts)
- write_chunk(meshdata, "BBOX", bbox); chunks.append(bbox)
- write_chunk(meshdata, "POLS", pols); chunks.append(pols)
- write_chunk(meshdata, "PTAG", ptag); chunks.append(ptag)
-
- if mesh.vertexColors:
- #if meshtools.average_vcols:
- # write_chunk(meshdata, "VMAP", vmap_vc)
- # chunks.append(vmap_vc)
- #else:
- write_chunk(meshdata, "VMAD", vmad_vc)
- chunks.append(vmad_vc)
-
- if mesh.faceUV:
- write_chunk(meshdata, "VMAD", vmad_uv)
- chunks.append(vmad_uv)
- write_chunk(meshdata, "CLIP", clip)
- chunks.append(clip)
-
- layer_index += 1
- mesh.verts = None # save some ram
-
- del mesh_object_name_lookup
-
- for surf in surfs:
- chunks.append(surf)
-
- write_header(file, chunks)
- write_chunk(file, "ICON", icon)
- write_chunk(file, "TEXT", text)
- write_chunk(file, "DESC", desc)
- write_chunk(file, "TAGS", tags)
- file.write(meshdata.getvalue()); meshdata.close()
- for surf in surfs:
- write_chunk(file, "SURF", surf)
- write_chunk(file, "DATE", "August 19, 2005")
-
- Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
- file.close()
- print '\a\r',
- print "Successfully exported %s in %.3f seconds" % (filename.split('\\')[-1].split('/')[-1], Blender.sys.time() - start)
-
-
-# =======================================
-# === Generate Null-Terminated String ===
-# =======================================
-def generate_nstring(string):
- if len(string)%2 == 0: # even
- string += "\0\0"
- else: # odd
- string += "\0"
- return string
-
-# ===============================
-# === Get Used Material Names ===
-# ===============================
-def get_used_material_names(meshes):
- matnames = {}
- for mesh in meshes:
- if (not mesh.materials) and mesh.vertexColors:
- # vcols only
- matnames[VCOL_NAME] = None
-
- elif mesh.materials and (not mesh.vertexColors):
- # materials only
- for material in mesh.materials:
- if material:
- matnames[material.name] = None
- elif (not mesh.materials) and (not mesh.vertexColors):
- # neither
- matnames[DEFAULT_NAME] = None
- else:
- # both
- for material in mesh.materials:
- if material:
- matnames[material.name] = None
- return matnames.keys()
-
-# =========================================
-# === Generate Tag Strings (TAGS Chunk) ===
-# =========================================
-def generate_tags(material_names):
- if material_names:
- material_names = map(generate_nstring, material_names)
- tags_data = reduce(operator.add, material_names)
- else:
- tags_data = generate_nstring('');
- return tags_data
-
-# ========================
-# === Generate Surface ===
-# ========================
-def generate_surface(name):
- #if name.find("\251 Per-") == 0:
- # return generate_vcol_surf(mesh)
- if name == DEFAULT_NAME:
- return generate_default_surf()
- else:
- return generate_surf(name)
-
-# ======================
-# === Generate Surfs ===
-# ======================
-def generate_surfs(material_names):
- return map(generate_surface, material_names)
-
-# ===================================
-# === Generate Layer (LAYR Chunk) ===
-# ===================================
-def generate_layr(name, idx):
- data = cStringIO.StringIO()
- data.write(struct.pack(">h", idx)) # layer number
- data.write(struct.pack(">h", 0)) # flags
- data.write(struct.pack(">fff", 0, 0, 0)) # pivot
- data.write(generate_nstring(name)) # name
- return data.getvalue()
-
-# ===================================
-# === Generate Verts (PNTS Chunk) ===
-# ===================================
-def generate_pnts(mesh):
- data = cStringIO.StringIO()
- for i, v in enumerate(mesh.verts):
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
- x, y, z = v.co
- data.write(struct.pack(">fff", x, z, y))
- return data.getvalue()
-
-# ==========================================
-# === Generate Bounding Box (BBOX Chunk) ===
-# ==========================================
-def generate_bbox(mesh):
- data = cStringIO.StringIO()
- # need to transform verts here
- if mesh.verts:
- nv = [v.co for v in mesh.verts]
- xx = [ co[0] for co in nv ]
- yy = [ co[1] for co in nv ]
- zz = [ co[2] for co in nv ]
- else:
- xx = yy = zz = [0.0,]
-
- data.write(struct.pack(">6f", min(xx), min(zz), min(yy), max(xx), max(zz), max(yy)))
- return data.getvalue()
-
-# ========================================
-# === Average All Vertex Colors (Fast) ===
-# ========================================
-'''
-def average_vertexcolors(mesh):
- vertexcolors = {}
- vcolor_add = lambda u, v: [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]]
- vcolor_div = lambda u, s: [u[0]/s, u[1]/s, u[2]/s, u[3]/s]
- for i, f in enumerate(mesh.faces): # get all vcolors that share this vertex
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors")
- col = f.col
- for j in xrange(len(f)):
- index = f[j].index
- color = col[j]
- r,g,b = color.r, color.g, color.b
- vertexcolors.setdefault(index, []).append([r,g,b,255])
- i = 0
- for index, value in vertexcolors.iteritems(): # average them
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
- vcolor = [0,0,0,0] # rgba
- for v in value:
- vcolor = vcolor_add(vcolor, v)
- shared = len(value)
- value[:] = vcolor_div(vcolor, shared)
- i+=1
- return vertexcolors
-'''
-
-# ====================================================
-# === Generate Per-Vert Vertex Colors (VMAP Chunk) ===
-# ====================================================
-# Blender now has all vcols per face
-"""
-def generate_vmap_vc(mesh):
- data = cStringIO.StringIO()
- data.write("RGB ") # type
- data.write(struct.pack(">H", 3)) # dimension
- data.write(generate_nstring("Blender's Vertex Colors")) # name
- vertexcolors = average_vertexcolors(mesh)
- for i in xrange(len(vertexcolors)):
- try: r, g, b, a = vertexcolors[i] # has a face user
- except: r, g, b, a = 255,255,255,255
- data.write(struct.pack(">H", i)) # vertex index
- data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0))
- return data.getvalue()
-"""
-
-# ====================================================
-# === Generate Per-Face Vertex Colors (VMAD Chunk) ===
-# ====================================================
-def generate_vmad_vc(mesh):
- data = cStringIO.StringIO()
- data.write("RGB ") # type
- data.write(struct.pack(">H", 3)) # dimension
- data.write(generate_nstring("Blender's Vertex Colors")) # name
- for i, f in enumerate(mesh.faces):
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Vertex Colors")
- col = f.col
- f_v = f.v
- for j in xrange(len(f)-1, -1, -1): # Reverse order
- r,g,b, dummy = tuple(col[j])
- data.write(struct.pack(">H", f_v[j].index)) # vertex index
- data.write(struct.pack(">H", i)) # face index
- data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0))
- return data.getvalue()
-
-# ================================================
-# === Generate Per-Face UV Coords (VMAD Chunk) ===
-# ================================================
-def generate_vmad_uv(mesh):
- layers = mesh.getUVLayerNames()
- org_uv = mesh.activeUVLayer
- for l in layers:
- mesh.activeUVLayer = l
- data = cStringIO.StringIO()
- data.write("TXUV") # type
- data.write(struct.pack(">H", 2)) # dimension
- data.write(generate_nstring(l)) # name
- for i, f in enumerate(mesh.faces):
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coordinates")
-
- uv = f.uv
- f_v = f.v
- for j in xrange(len(f)-1, -1, -1): # Reverse order
- U,V = uv[j]
- v = f_v[j].index
- data.write(struct.pack(">H", v)) # vertex index
- data.write(struct.pack(">H", i)) # face index
- data.write(struct.pack(">ff", U, V))
-
- mesh.activeUVLayer = org_uv
- return data.getvalue()
-
-# ======================================
-# === Generate Variable-Length Index ===
-# ======================================
-def generate_vx(index):
- if index < 0xFF00:
- value = struct.pack(">H", index) # 2-byte index
- else:
- value = struct.pack(">L", index | 0xFF000000) # 4-byte index
- return value
-
-# ===================================
-# === Generate Faces (POLS Chunk) ===
-# ===================================
-def generate_pols(mesh):
- data = cStringIO.StringIO()
- data.write("FACE") # polygon type
- for i,f in enumerate(mesh.faces):
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
- data.write(struct.pack(">H", len(f))) # numfaceverts
- numfaceverts = len(f)
- f_v = f.v
- for j in xrange(numfaceverts-1, -1, -1): # Reverse order
- data.write(generate_vx(f_v[j].index))
- return data.getvalue()
-
-# =================================================
-# === Generate Polygon Tag Mapping (PTAG Chunk) ===
-# =================================================
-def generate_ptag(mesh, material_names):
-
- def surf_indicies(mat):
- try:
- if mat:
- return material_names.index(mat.name)
- except:
- pass
-
- return 0
-
-
- data = cStringIO.StringIO()
- data.write("SURF") # polygon tag type
- mesh_materials = mesh.materials
- mesh_surfindicies = [surf_indicies(mat) for mat in mesh_materials]
-
- try: VCOL_NAME_SURF_INDEX = material_names.index(VCOL_NAME)
- except: VCOL_NAME_SURF_INDEX = 0
-
- try: DEFAULT_NAME_SURF_INDEX = material_names.index(DEFAULT_NAME)
- except: DEFAULT_NAME_SURF_INDEX = 0
- len_mat = len(mesh_materials)
- for i, f in enumerate(mesh.faces): # numfaces
- f_mat = f.mat
- if f_mat >= len_mat: f_mat = 0 # Rare annoying eror
-
-
- if not i%100:
- Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Surface Indices")
-
- data.write(generate_vx(i))
- if (not mesh_materials) and mesh.vertexColors: # vcols only
- surfidx = VCOL_NAME_SURF_INDEX
- elif mesh_materials and not mesh.vertexColors: # materials only
- surfidx = mesh_surfindicies[f_mat]
- elif (not mesh_materials) and (not mesh.vertexColors): # neither
- surfidx = DEFAULT_NAME_SURF_INDEX
- else: # both
- surfidx = mesh_surfindicies[f_mat]
-
- data.write(struct.pack(">H", surfidx)) # surface index
- return data.getvalue()
-
-# ===================================================
-# === Generate VC Surface Definition (SURF Chunk) ===
-# ===================================================
-def generate_vcol_surf(mesh):
- data = cStringIO.StringIO()
- if mesh.vertexColors:
- surface_name = generate_nstring(VCOL_NAME)
- data.write(surface_name)
- data.write("\0\0")
-
- data.write("COLR")
- data.write(struct.pack(">H", 14))
- data.write(struct.pack(">fffH", 1, 1, 1, 0))
-
- data.write("DIFF")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", 0.0, 0))
-
- data.write("LUMI")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", 1.0, 0))
-
- data.write("VCOL")
- data.write(struct.pack(">H", 34))
- data.write(struct.pack(">fH4s", 1.0, 0, "RGB ")) # intensity, envelope, type
- data.write(generate_nstring("Blender's Vertex Colors")) # name
-
- data.write("CMNT") # material comment
- comment = "Vertex Colors: Exported from Blender\256 243"
- comment = generate_nstring(comment)
- data.write(struct.pack(">H", len(comment)))
- data.write(comment)
- return data.getvalue()
-
-# ================================================
-# === Generate Surface Definition (SURF Chunk) ===
-# ================================================
-def generate_surf(material_name):
- data = cStringIO.StringIO()
- data.write(generate_nstring(material_name))
- data.write("\0\0")
-
- try:
- material = Blender.Material.Get(material_name)
- R,G,B = material.R, material.G, material.B
- ref = material.ref
- emit = material.emit
- spec = material.spec
- hard = material.hard
-
- except:
- material = None
-
- R=G=B = 1.0
- ref = 1.0
- emit = 0.0
- spec = 0.2
- hard = 0.0
-
-
- data.write("COLR")
- data.write(struct.pack(">H", 14))
- data.write(struct.pack(">fffH", R, G, B, 0))
-
- data.write("DIFF")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", ref, 0))
-
- data.write("LUMI")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", emit, 0))
-
- data.write("SPEC")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", spec, 0))
-
- data.write("GLOS")
- data.write(struct.pack(">H", 6))
- gloss = hard / (255/2.0)
- gloss = round(gloss, 1)
- data.write(struct.pack(">fH", gloss, 0))
-
- data.write("CMNT") # material comment
- comment = material_name + ": Exported from Blender\256 243"
- comment = generate_nstring(comment)
- data.write(struct.pack(">H", len(comment)))
- data.write(comment)
-
- # Check if the material contains any image maps
- if material:
- mtextures = material.getTextures() # Get a list of textures linked to the material
- for mtex in mtextures:
- if (mtex) and (mtex.tex.type == Blender.Texture.Types.IMAGE): # Check if the texture is of type "IMAGE"
- data.write("BLOK") # Surface BLOK header
- data.write(struct.pack(">H", 104)) # Hardcoded and ugly! Will only handle 1 image per material
-
- # IMAP subchunk (image map sub header)
- data.write("IMAP")
- data_tmp = cStringIO.StringIO()
- data_tmp.write(struct.pack(">H", 0)) # Hardcoded - not sure what it represents
- data_tmp.write("CHAN")
- data_tmp.write(struct.pack(">H", 4))
- data_tmp.write("COLR")
- data_tmp.write("OPAC") # Hardcoded texture layer opacity
- data_tmp.write(struct.pack(">H", 8))
- data_tmp.write(struct.pack(">H", 0))
- data_tmp.write(struct.pack(">f", 1.0))
- data_tmp.write(struct.pack(">H", 0))
- data_tmp.write("ENAB")
- data_tmp.write(struct.pack(">HH", 2, 1)) # 1 = texture layer enabled
- data_tmp.write("NEGA")
- data_tmp.write(struct.pack(">HH", 2, 0)) # Disable negative image (1 = invert RGB values)
- data_tmp.write("AXIS")
- data_tmp.write(struct.pack(">HH", 2, 1))
- data.write(struct.pack(">H", len(data_tmp.getvalue())))
- data.write(data_tmp.getvalue())
-
- # IMAG subchunk
- data.write("IMAG")
- data.write(struct.pack(">HH", 2, 1))
- data.write("PROJ")
- data.write(struct.pack(">HH", 2, 5)) # UV projection
-
- data.write("VMAP")
- uvname = generate_nstring("Blender's UV Coordinates")
- data.write(struct.pack(">H", len(uvname)))
- data.write(uvname)
-
- return data.getvalue()
-
-# =============================================
-# === Generate Default Surface (SURF Chunk) ===
-# =============================================
-def generate_default_surf():
- data = cStringIO.StringIO()
- material_name = DEFAULT_NAME
- data.write(generate_nstring(material_name))
- data.write("\0\0")
-
- data.write("COLR")
- data.write(struct.pack(">H", 14))
- data.write(struct.pack(">fffH", 1, 1, 1, 0))
-
- data.write("DIFF")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", 0.8, 0))
-
- data.write("LUMI")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", 0, 0))
-
- data.write("SPEC")
- data.write(struct.pack(">H", 6))
- data.write(struct.pack(">fH", 0.5, 0))
-
- data.write("GLOS")
- data.write(struct.pack(">H", 6))
- gloss = 50 / (255/2.0)
- gloss = round(gloss, 1)
- data.write(struct.pack(">fH", gloss, 0))
-
- data.write("CMNT") # material comment
- comment = material_name + ": Exported from Blender\256 243"
-
- # vals = map(chr, xrange(164,255,1))
- # keys = xrange(164,255,1)
- # keys = map(lambda x: `x`, keys)
- # comment = map(None, keys, vals)
- # comment = reduce(operator.add, comment)
- # comment = reduce(operator.add, comment)
-
- comment = generate_nstring(comment)
- data.write(struct.pack(">H", len(comment)))
- data.write(comment)
- return data.getvalue()
-
-# ============================================
-# === Generate Object Comment (TEXT Chunk) ===
-# ============================================
-def generate_text():
- comment = "Lightwave Export Script for Blender by Anthony D'Agostino"
- return generate_nstring(comment)
-
-# ==============================================
-# === Generate Description Line (DESC Chunk) ===
-# ==============================================
-def generate_desc():
- comment = "Copyright 2002 Scorpius Entertainment"
- return generate_nstring(comment)
-
-# ==================================================
-# === Generate Thumbnail Icon Image (ICON Chunk) ===
-# ==================================================
-def generate_icon():
- data = cStringIO.StringIO()
- file = open("f:/obj/radiosity/lwo2_icon.tga", "rb") # 60x60 uncompressed TGA
- file.read(18)
- icon_data = file.read(3600) # ?
- file.close()
- data.write(struct.pack(">HH", 0, 60))
- data.write(icon_data)
- #print len(icon_data)
- return data.getvalue()
-
-# ===============================================
-# === Generate CLIP chunk with STIL subchunks ===
-# ===============================================
-def generate_clip(mesh, material_names):
- data = cStringIO.StringIO()
- clipid = 1
- for i, material in enumerate(mesh.materials): # Run through list of materials used by mesh
- if material:
- mtextures = material.getTextures() # Get a list of textures linked to the material
- for mtex in mtextures:
- if (mtex) and (mtex.tex.type == Blender.Texture.Types.IMAGE): # Check if the texture is of type "IMAGE"
- pathname = mtex.tex.image.filename # If full path is needed use filename in place of name
- pathname = pathname[0:2] + pathname.replace("\\", "/")[3:] # Convert to Modo standard path
- imagename = generate_nstring(pathname)
- data.write(struct.pack(">L", clipid)) # CLIP sequence/id
- data.write("STIL") # STIL image
- data.write(struct.pack(">H", len(imagename))) # Size of image name
- data.write(imagename)
- clipid += 1
- return data.getvalue()
-
-# ===================
-# === Write Chunk ===
-# ===================
-def write_chunk(file, name, data):
- file.write(name)
- file.write(struct.pack(">L", len(data)))
- file.write(data)
-
-# =============================
-# === Write LWO File Header ===
-# =============================
-def write_header(file, chunks):
- chunk_sizes = map(len, chunks)
- chunk_sizes = reduce(operator.add, chunk_sizes)
- form_size = chunk_sizes + len(chunks)*8 + len("FORM")
- file.write("FORM")
- file.write(struct.pack(">L", form_size))
- file.write("LWO2")
-
-def fs_callback(filename):
- if not filename.lower().endswith('.lwo'): filename += '.lwo'
- write(filename)
-
-if struct and cStringIO and operator:
- Blender.Window.FileSelector(fs_callback, "Export LWO", Blender.sys.makename(ext='.lwo'))
-else:
- Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
diff --git a/release/scripts/lightwave_import.py b/release/scripts/lightwave_import.py
deleted file mode 100644
index 6d02467cef8..00000000000
--- a/release/scripts/lightwave_import.py
+++ /dev/null
@@ -1,1705 +0,0 @@
-#!BPY
-"""
-Name: 'LightWave (.lwo)...'
-Blender: 239
-Group: 'Import'
-Tooltip: 'Import LightWave Object File Format'
-"""
-
-__author__ = ["Alessandro Pirovano, Anthony D'Agostino (Scorpius)", "Campbell Barton (ideasman42)", "ZanQdo"]
-__url__ = ("www.blender.org", "blenderartist.org",
-"Anthony's homepage, http://www.redrival.com/scorpius", "Alessandro's homepage, http://uaraus.altervista.org")
-
-importername = "lwo_import 0.4.0"
-
-# +---------------------------------------------------------+
-# | Save your work before and after use. |
-# | Please report any useful comment to: |
-# | uaraus-dem@yahoo.it |
-# | Thanks |
-# +---------------------------------------------------------+
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | April 21, 2002 |
-# | Import Export Suite v0.5 |
-# +---------------------------------------------------------+
-# | Read and write LightWave Object File Format (*.lwo) |
-# +---------------------------------------------------------+
-# +---------------------------------------------------------+
-# | Alessandro Pirovano tweaked starting on March 2005 |
-# | http://uaraus.altervista.org |
-# +---------------------------------------------------------+
-# +----------------------------------------------------------
-# | GPL license block
-# |
-# | This program is free software; you can redistribute it and/or modify
-# | it under the terms of the GNU General Public License as published by
-# | the Free Software Foundation; either version 2 of the License, or
-# | (at your option) any later version.
-# |
-# | This program is distributed in the hope that it will be useful,
-# | but WITHOUT ANY WARRANTY; without even the implied warranty of
-# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# | GNU General Public License for more details.
-# |
-# | You 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
-# +----------------------------------------------------------
-# +---------------------------------------------------------+
-# | Release log: |
-# | 0.4.0 : Updated for blender 2.44 |
-# | ZanQdo - made the mesh import the right way up |
-# | Ideasman42 - Updated functions for the bew API |
-# | as well as removing the text object class |
-# | 0.2.2 : This code works with Blender 2.42 RC3 |
-# | Added a new PolyFill function for BPYMesh's |
-# | ngon() to use, checked compatibility |
-# | lightwaves ngons are imported as fgons |
-# | Checked compatibility against 1711 lwo files |
-# | 0.2.1 : This code works with Blender 2.40 RC1 |
-# | modified material mode assignment to deal with |
-# | Python API modification |
-# | Changed script license to GNU GPL |
-# | 0.2.0: This code works with Blender 2.40a2 or up |
-# | Major rewrite to deal with large meshes |
-# | - 2 pass file parsing |
-# | - lower memory foot###if DEBUG: print |
-# | (as long as python gc allows) |
-# | 2.40a2 - Removed subsurf settings patches=poly |
-# | 2.40a2 - Edge generation instead of 2vert faces |
-# | 0.1.16: fixed (try 2) texture offset calculations |
-# | added hint on axis mapping |
-# | added hint on texture blending mode |
-# | added hint on texture transparency setting |
-# | search images in original directory first |
-# | fixed texture order application |
-# | 0.1.15: added release log |
-# | fixed texture offset calculations (non-UV) |
-# | fixed reverting vertex order in face generation |
-# | associate texture on game-engine settings |
-# | vector math definitely based on mathutils |
-# | search images in "Images" and "../Images" dir |
-# | revised logging facility |
-# | fixed subsurf texture and material mappings |
-# | 0.1.14: patched missing mod_vector (not definitive) |
-# | 0.1.13: first public release |
-# +---------------------------------------------------------+
-
-#blender related import
-import Blender
-import bpy
-
-# use for comprehensiveImageLoad
-import BPyImage
-
-# Use this ngon function
-import BPyMesh
-
-import BPyMessages
-
-#python specific modules import
-try:
- import struct, chunk, cStringIO
-except:
- struct= chunk= cStringIO= None
-
-# python 2.3 has no reversed() iterator. this will only work on lists and tuples
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-### # Debuggin disabled in release.
-### # do a search replace to enabe debug prints
-### DEBUG = False
-
-# ===========================================================
-# === Utility Preamble ======================================
-# ===========================================================
-
-textname = None
-#uncomment the following line to enable logging facility to the named text object
-#textname = "lwo_log"
-
-TXMTX = Blender.Mathutils.Matrix(\
-[1, 0, 0, 0],\
-[0, 0, 1, 0],\
-[0, 1, 0, 0],\
-[0, 0, 0, 1])
-
-# ===========================================================
-# === Make sure it is a string ... deal with strange chars ==
-# ===========================================================
-def safestring(st):
- myst = ""
- for ll in xrange(len(st)):
- if st[ll] < " ":
- myst += "#"
- else:
- myst += st[ll]
- return myst
-
-# ===========================================================
-# === Main read functions ===================================
-# ===========================================================
-
-# =============================
-# === Read LightWave Format ===
-# =============================
-def read(filename):
- if BPyMessages.Error_NoFile(filename):
- return
-
- print "This is: %s" % importername
- print "Importing file:", filename
- bpy.data.scenes.active.objects.selected = []
-
- start = Blender.sys.time()
- file = open(filename, "rb")
-
- editmode = Blender.Window.EditMode() # are we in edit mode? If so ...
- if editmode: Blender.Window.EditMode(0) # leave edit mode before getting the mesh # === LWO header ===
-
- try:
- form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
- except:
- Blender.Draw.PupMenu('Error%t|This is not a lightwave file')
- return
-
- if (form_type == "LWOB"):
- read_lwob(file, filename)
- elif (form_type == "LWO2"):
- read_lwo2(file, filename)
- else:
- print "Can't read a file with the form_type: %s" % form_type
- return
-
- Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
- file.close()
- end = Blender.sys.time()
- seconds = " in %.2f %s" % (end-start, "seconds")
- if form_type == "LWO2": fmt = " (v6.0 Format)"
- if form_type == "LWOB": fmt = " (v5.5 Format)"
- print "Successfully imported " + filename.split('\\')[-1].split('/')[-1] + fmt + seconds
-
- if editmode: Blender.Window.EditMode(1) # optional, just being nice
- Blender.Redraw()
-
-# enddef read
-
-
-# =================================
-# === Read LightWave 5.5 format ===
-# =================================
-def read_lwob(file, filename):
- #This function is directly derived from the LWO2 import routine
- #dropping all the material analysis parts
-
- ###if DEBUG: print "LightWave 5.5 format"
-
- dir_part = Blender.sys.dirname(filename)
- fname_part = Blender.sys.basename(filename)
- #ask_weird = 1
-
- #first initialization of data structures
- defaultname = Blender.sys.splitext(fname_part)[0]
- tag_list = [] #tag list: global for the whole file?
- surf_list = [] #surf list: global for the whole file?
- clip_list = [] #clip list: global for the whole file?
- object_index = 0
- object_list = None
- objspec_list = None
-
- #add default material for orphaned faces, if any
- surf_list.append({'NAME': "_Orphans", 'g_MAT': bpy.data.materials.new("_Orphans")})
-
- #pass 2: effectively generate objects
- ###if DEBUG: print "Pass 1: dry import"
- file.seek(0)
- objspec_list = ["imported", {}, [], [], {}, {}, 0, {}, {}]
- # === LWO header ===
- form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
- if (form_type != "LWOB"):
- ###if DEBUG: print "??? Inconsistent file type: %s" % form_type
- return
- while 1:
- try:
- lwochunk = chunk.Chunk(file)
- except EOFError:
- break
- ###if DEBUG: print ' ',
- if lwochunk.chunkname == "LAYR":
- ###if DEBUG: print "---- LAYR",
- objname = read_layr(lwochunk)
- ###if DEBUG: print objname
- if objspec_list != None: #create the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = [objname, {}, [], [], {}, {}, 0, {}, {}]
- object_index += 1
- elif lwochunk.chunkname == "PNTS": # Verts
- ###if DEBUG: print "---- PNTS",
- verts = read_verts(lwochunk)
- objspec_list[2] = verts
- elif lwochunk.chunkname == "POLS": # Faces v5.5
- ###if DEBUG: print "-------- POLS(5.5)"
- faces = read_faces_5(lwochunk)
- flag = 0
- #flag is 0 for regular polygon, 1 for patches (= subsurf), 2 for anything else to be ignored
- if flag<2:
- if objspec_list[3] != []:
- #create immediately the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- #update with new data
- objspec_list = [objspec_list[0], #update name
- {}, #init
- objspec_list[2], #same vertexes
- faces, #give it the new faces
- {}, #no need to copy - filled at runtime
- {}, #polygon tagging will follow
- flag, #patch flag
- objspec_list[7], #same uvcoords
- {}] #no vmad mapping
- object_index += 1
- #end if already has a face list
- objspec_list[3] = faces
- objname = objspec_list[0]
- if objname == None:
- objname = defaultname
- #end if processing a valid poly type
- else: # Misc Chunks
- ###if DEBUG: print "---- %s: skipping (definitely!)" % lwochunk.chunkname
- lwochunk.skip()
- #uncomment here to log data structure as it is built
- # ###if DEBUG: print object_list
- #last object read
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = None
- surf_list = None
- clip_list = None
-
-
- ###if DEBUG: print "\nFound %d objects:" % object_index
-
-# enddef read_lwob
-
-
-# =============================
-# === Read LightWave Format ===
-# =============================
-def read_lwo2(file, filename, typ="LWO2"):
-
- ###if DEBUG: print "LightWave 6 (and above) format"
-
- dir_part = Blender.sys.dirname(filename)
- fname_part = Blender.sys.basename(filename)
- ask_weird = 1
-
- #first initialization of data structures
- defaultname = Blender.sys.splitext(fname_part)[0]
- tag_list = [] #tag list: global for the whole file?
- surf_list = [] #surf list: global for the whole file?
- clip_list = [] #clip list: global for the whole file?
- object_index = 0
- object_list = None
- objspec_list = None
- # init value is: object_list = [[None, {}, [], [], {}, {}, 0, {}, {}]]
- #0 - objname #original name
- #1 - obj_dict = {TAG} #objects created
- #2 - verts = [] #object vertexes
- #3 - faces = [] #object faces (associations poly -> vertexes)
- #4 - obj_dim_dict = {TAG} #tuples size and pos in local object coords - used for NON-UV mappings
- #5 - polytag_dict = {TAG} #tag to polygons mapping
- #6 - patch_flag #0 = surf; 1 = patch (subdivision surface) - it was the image list
- #7 - uvcoords_dict = {name} #uvmap coordinates (mixed mode per vertex/per face)
- #8 - facesuv_dict = {name} #vmad only coordinates associations poly & vertex -> uv tuples
-
- #pass 1: look in advance for materials
- ###if DEBUG: print "Starting Pass 1: hold on tight"
- while 1:
- try:
- lwochunk = chunk.Chunk(file)
- except EOFError:
- break
- ###if DEBUG: print ' ',
- if lwochunk.chunkname == "TAGS": # Tags
- ###if DEBUG: print "---- TAGS"
- tag_list.extend(read_tags(lwochunk))
- elif lwochunk.chunkname == "SURF": # surfaces
- ###if DEBUG: print "---- SURF"
- surf_list.append(read_surfs(lwochunk, surf_list, tag_list))
- elif lwochunk.chunkname == "CLIP": # texture images
- ###if DEBUG: print "---- CLIP"
- clip_list.append(read_clip(lwochunk, dir_part))
- ###if DEBUG: print "read total %s clips up to now" % len(clip_list)
- else: # Misc Chunks
- if ask_weird:
- ckname = safestring(lwochunk.chunkname)
- if "#" in ckname:
- choice = Blender.Draw.PupMenu("WARNING: file could be corrupted.%t|Import anyway|Give up")
- if choice != 1:
- ###if DEBUG: print "---- %s: Maybe file corrupted. Terminated by user" % lwochunk.chunkname
- return
- ask_weird = 0
- ###if DEBUG: print "---- %s: skipping (maybe later)" % lwochunk.chunkname
- lwochunk.skip()
-
- #add default material for orphaned faces, if any
- surf_list.append({'NAME': "_Orphans", 'g_MAT': bpy.data.materials.new("_Orphans")})
-
- #pass 2: effectively generate objects
- ###if DEBUG: print "Pass 2: now for the hard part"
- file.seek(0)
- # === LWO header ===
- form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
- if (form_type != "LWO2"):
- ###if DEBUG: print "??? Inconsistent file type: %s" % form_type
- return
- while 1:
- try:
- lwochunk = chunk.Chunk(file)
- except EOFError:
- break
- ###if DEBUG: print ' ',
- if lwochunk.chunkname == "LAYR":
- ###if DEBUG: print "---- LAYR"
- objname = read_layr(lwochunk)
- ###if DEBUG: print objname
- if objspec_list != None: #create the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = [objname, {}, [], [], {}, {}, 0, {}, {}]
- object_index += 1
- elif lwochunk.chunkname == "PNTS": # Verts
- ###if DEBUG: print "---- PNTS"
- verts = read_verts(lwochunk)
- objspec_list[2] = verts
- elif lwochunk.chunkname == "VMAP": # MAPS (UV)
- ###if DEBUG: print "---- VMAP"
- #objspec_list[7] = read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk)
- read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk)
- elif lwochunk.chunkname == "VMAD": # MAPS (UV) per-face
- ###if DEBUG: print "---- VMAD"
- #objspec_list[7], objspec_list[8] = read_vmad(objspec_list[7], objspec_list[8], len(objspec_list[3]), len(objspec_list[2]), lwochunk)
- read_vmad(objspec_list[7], objspec_list[8], len(objspec_list[3]), len(objspec_list[2]), lwochunk)
- elif lwochunk.chunkname == "POLS": # Faces v6.0
- ###if DEBUG: print "-------- POLS(6)"
- faces, flag = read_faces_6(lwochunk)
- #flag is 0 for regular polygon, 1 for patches (= subsurf), 2 for anything else to be ignored
- if flag<2:
- if objspec_list[3] != []:
- #create immediately the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- #update with new data
- objspec_list = [objspec_list[0], #update name
- {}, #init
- objspec_list[2], #same vertexes
- faces, #give it the new faces
- {}, #no need to copy - filled at runtime
- {}, #polygon tagging will follow
- flag, #patch flag
- objspec_list[7], #same uvcoords
- {}] #no vmad mapping
- object_index += 1
- #end if already has a face list
- objspec_list[3] = faces
- objname = objspec_list[0]
- if objname == None:
- objname = defaultname
- #end if processing a valid poly type
- elif lwochunk.chunkname == "PTAG": # PTags
- ###if DEBUG: print "---- PTAG"
- polytag_dict = read_ptags(lwochunk, tag_list)
- for kk, polytag_dict_val in polytag_dict.iteritems(): objspec_list[5][kk] = polytag_dict_val
- else: # Misc Chunks
- ###if DEBUG: print "---- %s: skipping (definitely!)" % lwochunk.chunkname
- lwochunk.skip()
- #uncomment here to log data structure as it is built
-
- #last object read
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = None
- surf_list = None
- clip_list = None
-
- ###if DEBUG: print "\nFound %d objects:" % object_index
-# enddef read_lwo2
-
-
-
-
-
-
-# ===========================================================
-# === File reading routines =================================
-# ===========================================================
-# ==================
-# === Read Verts ===
-# ==================
-def read_verts(lwochunk):
- #data = cStringIO.StringIO(lwochunk.read())
- numverts = lwochunk.chunksize/12
- return [struct.unpack(">fff", lwochunk.read(12)) for i in xrange(numverts)]
-# enddef read_verts
-
-
-# =================
-# === Read Name ===
-# =================
-# modified to deal with odd lenght strings
-def read_name(file):
- name = ""
- while 1:
- char = file.read(1)
- if char == "\0": break
- else: name += char
- len_name = len(name) + 1 #count the trailing zero
- if len_name%2==1:
- char = file.read(1) #remove zero padding to even lenght
- len_name += 1
- return name, len_name
-
-
-# ==================
-# === Read Layer ===
-# ==================
-def read_layr(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- idx, flags = struct.unpack(">hh", data.read(4))
- pivot = struct.unpack(">fff", data.read(12))
- layer_name, discard = read_name(data)
- if not layer_name: layer_name = "NoName"
- return layer_name
-# enddef read_layr
-
-
-# ======================
-# === Read Faces 5.5 ===
-# ======================
-def read_faces_5(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- faces = []
- i = 0
- while i < lwochunk.chunksize:
- #if not i%1000 and my_meshtools.show_progress:
- # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
-
- numfaceverts, = struct.unpack(">H", data.read(2))
- facev = [struct.unpack(">H", data.read(2))[0] for j in xrange(numfaceverts)]
- facev.reverse()
- faces.append(facev)
- surfaceindex, = struct.unpack(">H", data.read(2))
- if surfaceindex < 0:
- ###if DEBUG: print "***Error. Referencing uncorrect surface index"
- return
- i += (4+numfaceverts*2)
- return faces
-
-
-# ==================================
-# === Read Variable-Length Index ===
-# ==================================
-def read_vx(data):
- byte1, = struct.unpack(">B", data.read(1))
- if byte1 != 0xFF: # 2-byte index
- byte2, = struct.unpack(">B", data.read(1))
- index = byte1*256 + byte2
- index_size = 2
- else: # 4-byte index
- byte2, byte3, byte4 = struct.unpack(">3B", data.read(3))
- index = byte2*65536 + byte3*256 + byte4
- index_size = 4
- return index, index_size
-
-
-# ======================
-# === Read uvmapping ===
-# ======================
-def read_vmap(uvcoords_dict, maxvertnum, lwochunk):
-
- if maxvertnum == 0:
- ###if DEBUG: print "Found VMAP but no vertexes to map!"
- return uvcoords_dict
- data = cStringIO.StringIO(lwochunk.read())
- map_type = data.read(4)
- if map_type != "TXUV":
- ###if DEBUG: print "Reading VMAP: No Texture UV map Were Found. Map Type: %s" % map_type
- return uvcoords_dict
- dimension, = struct.unpack(">H", data.read(2))
- name, i = read_name(data) #i initialized with string lenght + zeros
- ###if DEBUG: print "TXUV %d %s" % (dimension, name)
- #note if there is already a VMAD it will be lost
- #it is assumed that VMAD will follow the corresponding VMAP
- Vector = Blender.Mathutils.Vector
- try: #if uvcoords_dict.has_key(name):
- my_uv_dict = uvcoords_dict[name] #update existing
- except: #else:
- my_uv_dict = {} #start a brand new: this could be made more smart
- while (i < lwochunk.chunksize - 6): #4+2 header bytes already read
- vertnum, vnum_size = read_vx(data)
- uv = struct.unpack(">ff", data.read(8))
- if vertnum >= maxvertnum:
- ###if DEBUG: print "Hem: more uvmap than vertexes? ignoring uv data for vertex %d" % vertnum
- pass
- else:
- my_uv_dict[vertnum] = Vector(uv)
- i += 8 + vnum_size
- #end loop on uv pairs
- uvcoords_dict[name] = my_uv_dict
- #this is a per-vertex mapping AND the uv tuple is vertex-ordered, so faces_uv is the same as faces
- #return uvcoords_dict
- return
-
-# ========================
-# === Read uvmapping 2 ===
-# ========================
-def read_vmad(uvcoords_dict, facesuv_dict, maxfacenum, maxvertnum, lwochunk):
- if maxvertnum == 0 or maxfacenum == 0:
- ###if DEBUG: print "Found VMAD but no vertexes to map!"
- return uvcoords_dict, facesuv_dict
- data = cStringIO.StringIO(lwochunk.read())
- map_type = data.read(4)
- if map_type != "TXUV":
- ###if DEBUG: print "Reading VMAD: No Texture UV map Were Found. Map Type: %s" % map_type
- return uvcoords_dict, facesuv_dict
- dimension, = struct.unpack(">H", data.read(2))
- name, i = read_name(data) #i initialized with string lenght + zeros
- ###if DEBUG: print "TXUV %d %s" % (dimension, name)
- try: #if uvcoords_dict.has_key(name):
- my_uv_dict = uvcoords_dict[name] #update existing
- except: #else:
- my_uv_dict = {} #start a brand new: this could be made more smart
- my_facesuv_list = []
- newindex = maxvertnum + 10 #why +10? Why not?
- #end variable initialization
- Vector = Blender.Mathutils.Vector
- while (i < lwochunk.chunksize - 6): #4+2 header bytes already read
- vertnum, vnum_size = read_vx(data)
- i += vnum_size
- polynum, vnum_size = read_vx(data)
- i += vnum_size
- uv = struct.unpack(">ff", data.read(8))
- if polynum >= maxfacenum or vertnum >= maxvertnum:
- ###if DEBUG: print "Hem: more uvmap than vertexes? ignorig uv data for vertex %d" % vertnum
- pass
- else:
- my_uv_dict[newindex] = Vector(uv)
- my_facesuv_list.append([polynum, vertnum, newindex])
- newindex += 1
- i += 8
- #end loop on uv pairs
- uvcoords_dict[name] = my_uv_dict
- facesuv_dict[name] = my_facesuv_list
- ###if DEBUG: print "updated %d vertexes data" % (newindex-maxvertnum-10)
- return
-
-
-# =================
-# === Read tags ===
-# =================
-def read_tags(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- tag_list = []
- current_tag = ""
- i = 0
- while i < lwochunk.chunksize:
- char = data.read(1)
- if char == "\0":
- tag_list.append(current_tag)
- if (len(current_tag) % 2 == 0): char = data.read(1)
- current_tag = ""
- else:
- current_tag += char
- i += 1
- ###if DEBUG: print "read %d tags, list follows: %s" % (len(tag_list), tag_list)
- return tag_list
-
-
-# ==================
-# === Read Ptags ===
-# ==================
-def read_ptags(lwochunk, tag_list):
- data = cStringIO.StringIO(lwochunk.read())
- polygon_type = data.read(4)
- if polygon_type != "SURF":
- ###if DEBUG: print "No Surf Were Found. Polygon Type: %s" % polygon_type
- return {}
- ptag_dict = {}
- i = 0
- while(i < lwochunk.chunksize-4): #4 bytes polygon type already read
- #if not i%1000 and my_meshtools.show_progress:
- # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading PTAGS")
- poln, poln_size = read_vx(data)
- i += poln_size
- tag_index, = struct.unpack(">H", data.read(2))
- if tag_index > (len(tag_list)):
- ###if DEBUG: print "Reading PTAG: Surf belonging to undefined TAG: %d. Skipping" % tag_index
- return {}
- i += 2
- tag_key = tag_list[tag_index]
- try:
- ptag_dict[tag_list[tag_index]].append(poln)
- except: #if not(ptag_dict.has_key(tag_key)):
- ptag_dict[tag_list[tag_index]] = [poln]
-
- ###if DEBUG: for i, ptag_dict_val in ptag_dict.iteritems(): print "read %d polygons belonging to TAG %s" % (len(ptag_dict_val ), i)
- return ptag_dict
-
-
-
-# ==================
-# === Read Clips ===
-# ==================
-def read_clip(lwochunk, dir_part):
-# img, IMG, g_IMG refers to blender image objects
-# ima, IMAG, g_IMAG refers to clip dictionary 'ID' entries: refer to blok and surf
- clip_dict = {}
- data = cStringIO.StringIO(lwochunk.read())
- data_str = data.read(4)
- if len(data_str) < 4: # can be zero also??? :/
- # Should not happen but lw can import so we should too
- return
-
- image_index, = struct.unpack(">L", data_str)
- clip_dict['ID'] = image_index
- i = 4
- while(i < lwochunk.chunksize):
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">H", data.read(2))
- if subchunkname == "STIL":
- ###if DEBUG: print "-------- STIL"
- clip_name, k = read_name(data)
- #now split text independently from platform
- #depend on the system where image was saved. NOT the one where the script is run
- no_sep = "\\"
- if Blender.sys.sep == no_sep: no_sep ="/"
- if (no_sep in clip_name):
- clip_name = clip_name.replace(no_sep, Blender.sys.sep)
- short_name = Blender.sys.basename(clip_name)
- if clip_name == "" or short_name == "":
- ###if DEBUG: print "Reading CLIP: Empty clip name not allowed. Skipping"
- discard = data.read(subchunklen-k)
- clip_dict['NAME'] = clip_name
- clip_dict['BASENAME'] = short_name
- elif subchunkname == "XREF": #cross reference another image
- ###if DEBUG: print "-------- XREF"
- image_index, = struct.unpack(">L", data.read(4))
- clip_name, k = read_name(data)
- clip_dict['NAME'] = clip_name
- clip_dict['XREF'] = image_index
- elif subchunkname == "NEGA": #negate texture effect
- ###if DEBUG: print "-------- NEGA"
- n, = struct.unpack(">H", data.read(2))
- clip_dict['NEGA'] = n
- else: # Misc Chunks
- ###if DEBUG: print "-------- CLIP:%s: skipping" % subchunkname
- discard = data.read(subchunklen)
- i = i + 6 + subchunklen
- #end loop on surf chunks
- ###if DEBUG: print "read image:%s" % clip_dict
- if 'XREF' in clip_dict: # has_key
- ###if DEBUG: print "Cross-reference: no image pre-allocated."
- return clip_dict
- #look for images
- #img = load_image("",clip_dict['NAME'])
- NAME= BASENAME= None
-
- try:
- NAME= clip_dict['NAME']
- BASENAME= clip_dict['BASENAME']
- except:
- clip_dict['g_IMG'] = None
- return
- # ###if DEBUG: print 'test', NAME, BASENAME
- img = BPyImage.comprehensiveImageLoad(NAME, dir_part, PLACE_HOLDER= False, RECURSIVE=False)
- if not img:
- ###if DEBUG: print "***No image %s found: trying LWO file subdir" % NAME
- img = BPyImage.comprehensiveImageLoad(BASENAME, dir_part, PLACE_HOLDER= False, RECURSIVE=False)
-
- ###if DEBUG: if not img: print "***No image %s found: giving up" % BASENAME
- #lucky we are: we have an image
- ###if DEBUG: print "Image pre-allocated."
- clip_dict['g_IMG'] = img
-
- return clip_dict
-
-
-# ===========================
-# === Read Surfaces Block ===
-# ===========================
-def read_surfblok(subchunkdata):
- lenght = len(subchunkdata)
- my_dict = {}
- my_uvname = ""
- data = cStringIO.StringIO(subchunkdata)
- ##############################################################
- # blok header sub-chunk
- ##############################################################
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">h", data.read(2))
- accumulate_i = subchunklen + 6
- if subchunkname != 'IMAP':
- ###if DEBUG: print "---------- SURF: BLOK: %s: block aborting" % subchunkname
- return {}, ""
- ###if DEBUG: print "---------- IMAP"
- ordinal, i = read_name(data)
- my_dict['ORD'] = ordinal
- #my_dict['g_ORD'] = -1
- my_dict['ENAB'] = True
- while(i < subchunklen): # ---------left 6------------------------- loop on header parameters
- sub2chunkname, = struct.unpack("4s", data.read(4))
- sub2chunklen, = struct.unpack(">h", data.read(2))
- i = i + 6 + sub2chunklen
- if sub2chunkname == "CHAN":
- ###if DEBUG: print "------------ CHAN"
- sub2chunkname, = struct.unpack("4s", data.read(4))
- my_dict['CHAN'] = sub2chunkname
- sub2chunklen -= 4
- elif sub2chunkname == "ENAB": #only present if is to be disabled
- ###if DEBUG: print "------------ ENAB"
- ena, = struct.unpack(">h", data.read(2))
- my_dict['ENAB'] = ena
- sub2chunklen -= 2
- elif sub2chunkname == "NEGA": #only present if is to be enabled
- ###if DEBUG: print "------------ NEGA"
- ena, = struct.unpack(">h", data.read(2))
- if ena == 1:
- my_dict['NEGA'] = ena
- sub2chunklen -= 2
- elif sub2chunkname == "OPAC": #only present if is to be disabled
- ###if DEBUG: print "------------ OPAC"
- opa, = struct.unpack(">h", data.read(2))
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['OPAC'] = opa
- my_dict['OPACVAL'] = s
- sub2chunklen -= 6
- elif sub2chunkname == "AXIS":
- ###if DEBUG: print "------------ AXIS"
- ena, = struct.unpack(">h", data.read(2))
- my_dict['DISPLAXIS'] = ena
- sub2chunklen -= 2
- else: # Misc Chunks
- ###if DEBUG: print "------------ SURF: BLOK: IMAP: %s: skipping" % sub2chunkname
- discard = data.read(sub2chunklen)
- #end loop on blok header subchunks
- ##############################################################
- # blok attributes sub-chunk
- ##############################################################
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">h", data.read(2))
- accumulate_i += subchunklen + 6
- if subchunkname != 'TMAP':
- ###if DEBUG: print "---------- SURF: BLOK: %s: block aborting" % subchunkname
- return {}, ""
- ###if DEBUG: print "---------- TMAP"
- i = 0
- while(i < subchunklen): # -----------left 6----------------------- loop on header parameters
- sub2chunkname, = struct.unpack("4s", data.read(4))
- sub2chunklen, = struct.unpack(">h", data.read(2))
- i = i + 6 + sub2chunklen
- if sub2chunkname == "CNTR":
- ###if DEBUG: print "------------ CNTR"
- x, y, z = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['CNTR'] = [x, y, z]
- sub2chunklen -= (12+env_size)
- elif sub2chunkname == "SIZE":
- ###if DEBUG: print "------------ SIZE"
- x, y, z = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['SIZE'] = [x, y, z]
- sub2chunklen -= (12+env_size)
- elif sub2chunkname == "ROTA":
- ###if DEBUG: print "------------ ROTA"
- x, y, z = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['ROTA'] = [x, y, z]
- sub2chunklen -= (12+env_size)
- elif sub2chunkname == "CSYS":
- ###if DEBUG: print "------------ CSYS"
- ena, = struct.unpack(">h", data.read(2))
- my_dict['CSYS'] = ena
- sub2chunklen -= 2
- else: # Misc Chunks
- ###if DEBUG: print "------------ SURF: BLOK: TMAP: %s: skipping" % sub2chunkname
- pass
- if sub2chunklen > 0:
- discard = data.read(sub2chunklen)
- #end loop on blok attributes subchunks
- ##############################################################
- # ok, now other attributes without sub_chunks
- ##############################################################
- while(accumulate_i < lenght): # ---------------------------------- loop on header parameters: lenght has already stripped the 6 bypes header
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">H", data.read(2))
- accumulate_i = accumulate_i + 6 + subchunklen
- if subchunkname == "PROJ":
- ###if DEBUG: print "---------- PROJ"
- p, = struct.unpack(">h", data.read(2))
- my_dict['PROJ'] = p
- subchunklen -= 2
- elif subchunkname == "AXIS":
- ###if DEBUG: print "---------- AXIS"
- a, = struct.unpack(">h", data.read(2))
- my_dict['MAJAXIS'] = a
- subchunklen -= 2
- elif subchunkname == "IMAG":
- ###if DEBUG: print "---------- IMAG"
- i, i_size = read_vx(data)
- my_dict['IMAG'] = i
- subchunklen -= i_size
- elif subchunkname == "WRAP":
- ###if DEBUG: print "---------- WRAP"
- ww, wh = struct.unpack(">hh", data.read(4))
- #reduce width and height to just 1 parameter for both
- my_dict['WRAP'] = max([ww,wh])
- #my_dict['WRAPWIDTH'] = ww
- #my_dict['WRAPHEIGHT'] = wh
- subchunklen -= 4
- elif subchunkname == "WRPW":
- ###if DEBUG: print "---------- WRPW"
- w, = struct.unpack(">f", data.read(4))
- my_dict['WRPW'] = w
- envelope, env_size = read_vx(data)
- subchunklen -= (env_size+4)
- elif subchunkname == "WRPH":
- ###if DEBUG: print "---------- WRPH"
- w, = struct.unpack(">f", data.read(4))
- my_dict['WRPH'] = w
- envelope, env_size = read_vx(data)
- subchunklen -= (env_size+4)
- elif subchunkname == "VMAP":
- ###if DEBUG: print "---------- VMAP"
- vmp, i = read_name(data)
- my_dict['VMAP'] = vmp
- my_uvname = vmp
- subchunklen -= i
- else: # Misc Chunks
- ###if DEBUG: print "---------- SURF: BLOK: %s: skipping" % subchunkname
- pass
- if subchunklen > 0:
- discard = data.read(subchunklen)
- #end loop on blok subchunks
- return my_dict, my_uvname
-
-
-# =====================
-# === Read Surfaces ===
-# =====================
-def read_surfs(lwochunk, surf_list, tag_list):
- my_dict = {}
- data = cStringIO.StringIO(lwochunk.read())
- surf_name, i = read_name(data)
- parent_name, j = read_name(data)
- i += j
- if (surf_name == "") or not(surf_name in tag_list):
- ###if DEBUG: print "Reading SURF: Actually empty surf name not allowed. Skipping"
- return {}
- if (parent_name != ""):
- parent_index = [x['NAME'] for x in surf_list].count(parent_name)
- if parent_index >0:
- my_dict = surf_list[parent_index-1]
- my_dict['NAME'] = surf_name
- ###if DEBUG: print "Surface data for TAG %s" % surf_name
- while(i < lwochunk.chunksize):
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">H", data.read(2))
- i = i + 6 + subchunklen #6 bytes subchunk header
- if subchunkname == "COLR": #color: mapped on color
- ###if DEBUG: print "-------- COLR"
- r, g, b = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['COLR'] = [r, g, b]
- subchunklen -= (12+env_size)
- elif subchunkname == "DIFF": #diffusion: mapped on reflection (diffuse shader)
- ###if DEBUG: print "-------- DIFF"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['DIFF'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "SPEC": #specularity: mapped to specularity (spec shader)
- ###if DEBUG: print "-------- SPEC"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['SPEC'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "REFL": #reflection: mapped on raymirror
- ###if DEBUG: print "-------- REFL"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['REFL'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "TRNL": #translucency: mapped on same param
- ###if DEBUG: print "-------- TRNL"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['TRNL'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "GLOS": #glossiness: mapped on specularity hardness (spec shader)
- ###if DEBUG: print "-------- GLOS"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['GLOS'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "TRAN": #transparency: inverted and mapped on alpha channel
- ###if DEBUG: print "-------- TRAN"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['TRAN'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "LUMI": #luminosity: mapped on emit channel
- ###if DEBUG: print "-------- LUMI"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['LUMI'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "GVAL": #glow: mapped on add channel
- ###if DEBUG: print "-------- GVAL"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['GVAL'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "SMAN": #smoothing angle
- ###if DEBUG: print "-------- SMAN"
- s, = struct.unpack(">f", data.read(4))
- my_dict['SMAN'] = s
- subchunklen -= 4
- elif subchunkname == "SIDE": #double sided?
- ###if DEBUG: print "-------- SIDE" #if 1 side do not define key
- s, = struct.unpack(">H", data.read(2))
- if s == 3:
- my_dict['SIDE'] = s
- subchunklen -= 2
- elif subchunkname == "RIND": #Refraction: mapped on IOR
- ###if DEBUG: print "-------- RIND"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['RIND'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "BLOK": #blocks
- ###if DEBUG: print "-------- BLOK"
- rr, uvname = read_surfblok(data.read(subchunklen))
- #paranoia setting: preventing adding an empty dict
- if rr: # != {}
- try:
- my_dict['BLOK'].append(rr)
- except:
- my_dict['BLOK'] = [rr]
-
- if uvname: # != "":
- my_dict['UVNAME'] = uvname #theoretically there could be a number of them: only one used per surf
- # all are dictionaries - so testing keys
- if not('g_IMAG' in my_dict) and ('CHAN' in rr) and ('OPAC' in rr) and ('IMAG' in rr):
- if (rr['CHAN'] == 'COLR') and (rr['OPAC'] == 0):
- my_dict['g_IMAG'] = rr['IMAG'] #do not set anything, just save image object for later assignment
- subchunklen = 0 #force ending
- else: # Misc Chunks
- pass
- ###if DEBUG: print "-------- SURF:%s: skipping" % subchunkname
- if subchunklen > 0:
- discard = data.read(subchunklen)
- #end loop on surf chunks
- try:#if my_dict.has_key('BLOK'):
- my_dict['BLOK'].reverse() #texture applied in reverse order with respect to reading from lwo
- except:
- pass
-
- #uncomment this if material pre-allocated by read_surf
- my_dict['g_MAT'] = bpy.data.materials.new(my_dict['NAME'])
- ###if DEBUG: print "-> Material pre-allocated."
- return my_dict
-
-# =========================
-# === Recalculate Faces ===
-# =========================
-
-def get_uvface(complete_list, facenum):
- # extract from the complete list only vertexes of the desired polygon
- '''
- my_facelist = []
- for elem in complete_list:
- if elem[0] == facenum:
- my_facelist.append(elem)
- return my_facelist
- '''
- return [elem for elem in complete_list if elem[0] == facenum]
-
-def get_newindex(polygon_list, vertnum):
- # extract from the polygon list the new index associated to a vertex
- if not polygon_list: # == []
- return -1
- for elem in polygon_list:
- if elem[1] == vertnum:
- return elem[2]
- # ###if DEBUG: print "WARNING: expected vertex %s for polygon %s. Polygon_list dump follows" % (vertnum, polygon_list[0][0])
- # ###if DEBUG: print polygon_list
- return -1
-
-def get_surf(surf_list, cur_tag):
- for elem in surf_list: # elem can be None
- if elem and elem['NAME'] == cur_tag:
- return elem
- return {}
-
-
-
-# ====================================
-# === Modified Create Blender Mesh ===
-# ====================================
-def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not_used_faces):
- #take the needed faces and update the not-used face list
- complete_vertlist = objspec_list[2]
- complete_facelist = objspec_list[3]
- uvcoords_dict = objspec_list[7]
- facesuv_dict = objspec_list[8]
- vertex_map = {} #implementation as dict
- cur_ptag_faces = []
- cur_ptag_faces_indexes = []
- maxface = len(complete_facelist)
- for ff in current_facelist:
- if ff >= maxface:
- ###if DEBUG: print "Non existent face addressed: Giving up with this object"
- return None, not_used_faces #return the created object
- cur_face = complete_facelist[ff]
- cur_ptag_faces_indexes.append(ff)
- if not_used_faces: # != []
- not_used_faces[ff] = -1
- for vv in cur_face: vertex_map[vv] = 1
- #end loop on faces
- store_edge = 0
-
- scn= bpy.data.scenes.active
- msh = bpy.data.meshes.new()
- obj = scn.objects.new(msh)
-
- mat = None
- try:
- msh.materials = [surf['g_MAT']]
- except:
- pass
-
- msh.mode |= Blender.Mesh.Modes.AUTOSMOOTH #smooth it anyway
- if 'SMAN' in surf: # has_key
- #not allowed mixed mode mesh (all the mesh is smoothed and all with the same angle)
- #only one smoothing angle will be active! => take the max one
- msh.degr = min(80, int(surf['SMAN']/3.1415926535897932384626433832795*180.0)) #lwo in radians - blender in degrees
-
- try:
- img= lookup_imag(clip_list, surf['g_IMAG'])['g_IMG']
- except:
- img= None
-
- #uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME'])) and (img != None))
- uv_flag = (('UVNAME' in surf) and (surf['UVNAME'] in uvcoords_dict))
-
- ###if DEBUG: print "\n#===================================================================#"
- ###if DEBUG: print "Processing Object: %s" % objname
- ###if DEBUG: print "#===================================================================#"
-
- if uv_flag:
- msh.verts.extend([(0.0,0.0,0.0),])
- j = 1
- else:
- j = 0
-
- def tmp_get_vert(k, i):
- vertex_map[k] = i+j # j is the dummy vert
- # ###if DEBUG: print complete_vertlist[i]
- return complete_vertlist[k]
-
-
-
- msh.verts.extend([tmp_get_vert(k, i) for i, k in enumerate(vertex_map.iterkeys())])
- msh.transform(TXMTX) # faster then applying while reading.
- #end sweep over vertexes
-
- #append faces
- FACE_TEX= Blender.Mesh.FaceModes.TEX
- FACE_ALPHA= Blender.Mesh.FaceTranspModes.ALPHA
- EDGE_DRAW_FLAG= Blender.Mesh.EdgeFlags.EDGEDRAW | Blender.Mesh.EdgeFlags.EDGERENDER
-
-
- edges = []
- face_data = [] # [(indicies, material, uvs, image), ]
- face_uvs = []
- edges_fgon = []
-
- if uv_flag:
- uvcoords_dict_context = uvcoords_dict[surf['UVNAME']]
- try: current_uvdict = facesuv_dict[surf['UVNAME']]
- except: current_uvdict = None
-
- default_uv = Blender.Mathutils.Vector(0,0)
- def tmp_get_face_uvs(cur_face, i):
- uvs = []
- if current_uvdict:
- uvface = get_uvface(current_uvdict,i)
- for vi in cur_face:
- ni = get_newindex(uvface, vi)
- if ni == -1: ni = vi
-
- try:
- uvs.append(uvcoords_dict_context[ ni ])
- except:
- ###if DEBUG: print '\tWarning, Corrupt UVs'
- uvs.append(default_uv)
- else:
- for vi in cur_face:
- try:
- uvs.append(uvcoords_dict_context[ vi ])
- except:
- ###if DEBUG: print '\tWarning, Corrupt UVs'
- uvs.append(default_uv)
-
- return uvs
- cur_face
- for i in cur_ptag_faces_indexes:
- cur_face = complete_facelist[i]
- numfaceverts = len(cur_face)
-
- if numfaceverts == 2: edges.append((vertex_map[cur_face[0]], vertex_map[cur_face[1]]))
- elif numfaceverts == 3 or numfaceverts == 4:
- rev_face = [__i for __i in reversed(cur_face)]
- face_data.append( [vertex_map[j] for j in rev_face] )
- if uv_flag: face_uvs.append(tmp_get_face_uvs(rev_face, i))
- elif numfaceverts > 4:
- meta_faces= BPyMesh.ngon(complete_vertlist, cur_face, PREF_FIX_LOOPS= True)
- edge_face_count = {}
- for mf in meta_faces:
- # These will always be tri's since they are scanfill faces
- mf = cur_face[mf[2]], cur_face[mf[1]], cur_face[mf[0]]
- face_data.append( [vertex_map[j] for j in mf] )
-
- if uv_flag: face_uvs.append(tmp_get_face_uvs(mf, i))
-
- #if USE_FGON:
- if len(meta_faces) > 1:
- mf = face_data[-1] # reuse mf
- for j in xrange(3):
- v1= mf[j]
- v2= mf[j-1]
- if v1!=v2:
- if v1>v2:
- v2,v1= v1,v2
- try:
- edge_face_count[v1,v2]+= 1
- except:
- edge_face_count[v1,v2]= 0
-
-
-
- if edge_face_count:
- edges_fgon.extend( [vert_key for vert_key, count in edge_face_count.iteritems() if count] )
-
- if edges:
- msh.edges.extend(edges)
-
- face_mapping_removed = msh.faces.extend(face_data, indexList=True)
- if 'TRAN' in surf or (mat and mat.alpha<1.0): # incase mat is null
- transp_flag = True
- else:
- transp_flag = False
-
- if uv_flag:
- msh.faceUV = True
- msh_faces= msh.faces
- for i, uvs in enumerate(face_uvs):
- i_mapped = face_mapping_removed[i]
- if i_mapped != None:
- f = msh_faces[i_mapped]
- f.uv = uvs
- if img:
- f.image = img
-
- if transp_flag: f.transp |= FACE_ALPHA
-
- if edges_fgon:
- msh_edges = msh.edges
- FGON= Blender.Mesh.EdgeFlags.FGON
- edges_fgon = msh.findEdges( edges_fgon )
- if type(edges_fgon) != list: edges_fgon = [edges_fgon]
- for ed in edges_fgon:
- if ed!=None:
- msh_edges[ed].flag |= FGON
-
- if not(uv_flag): #clear eventual UV data
- msh.faceUV = False
-
- if uv_flag:
- msh.verts.delete([0,])
-
- return obj, not_used_faces #return the created object
-
-
-# ============================================
-# === Set Subsurf attributes on given mesh ===
-# ============================================
-def set_subsurf(obj):
- mods = obj.modifiers # get the object's modifiers
- mod = mods.append(Blender.Modifier.Type.SUBSURF) # add a new subsurf modifier
- mod[Blender.Modifier.Settings.LEVELS] = 2 # set subsurf subdivision levels to 2
- mod[Blender.Modifier.Settings.RENDLEVELS] = 2 # set subsurf rendertime subdivision levels to 2
- obj.makeDisplayList()
-
-
-# =================================
-# === object size and dimension ===
-# =================================
-def obj_size_pos(obj):
- bbox = obj.getBoundBox()
- bbox_min = map(lambda *row: min(row), *bbox) #transpose & get min
- bbox_max = map(lambda *row: max(row), *bbox) #transpose & get max
- obj_size = (bbox_max[0]-bbox_min[0], bbox_max[1]-bbox_min[1], bbox_max[2]-bbox_min[2])
- obj_pos = ( (bbox_max[0]+bbox_min[0]) / 2, (bbox_max[1]+bbox_min[1]) / 2, (bbox_max[2]+bbox_min[2]) / 2)
- return (obj_size, obj_pos)
-
-
-# =========================
-# === Create the object ===
-# =========================
-def create_objects(clip_list, objspec_list, surf_list):
- nf = len(objspec_list[3])
- not_used_faces = range(nf)
- ptag_dict = objspec_list[5]
- obj_dict = {} #links tag names to object, used for material assignments
- obj_dim_dict = {}
- obj_list = [] #have it handy for parent association
- middlechar = "+"
- endchar = ""
- if (objspec_list[6] == 1):
- middlechar = endchar = "#"
- for cur_tag, ptag_dict_val in ptag_dict.iteritems():
- if ptag_dict_val != []:
- cur_surf = get_surf(surf_list, cur_tag)
- cur_obj, not_used_faces= my_create_mesh(clip_list, cur_surf, objspec_list, ptag_dict_val, objspec_list[0][:9]+middlechar+cur_tag[:9], not_used_faces)
- # Works now with new modifiers
- if objspec_list[6] == 1:
- set_subsurf(cur_obj)
- if cur_obj: # != None
- obj_dict[cur_tag] = cur_obj
- obj_dim_dict[cur_tag] = obj_size_pos(cur_obj)
- obj_list.append(cur_obj)
- #end loop on current group
- #and what if some faces not used in any named PTAG? get rid of unused faces
- orphans = []
- for tt in not_used_faces:
- if tt > -1: orphans.append(tt)
- #end sweep on unused face list
- not_used_faces = None
- if orphans: # != []
- cur_surf = get_surf(surf_list, "_Orphans")
- cur_obj, not_used_faces = my_create_mesh(clip_list, cur_surf, objspec_list, orphans, objspec_list[0][:9]+middlechar+"Orphans", [])
- if cur_obj: # != None
- if objspec_list[6] == 1:
- set_subsurf(cur_obj)
- obj_dict["_Orphans"] = cur_obj
- obj_dim_dict["_Orphans"] = obj_size_pos(cur_obj)
- obj_list.append(cur_obj)
- objspec_list[1]= obj_dict
- objspec_list[4]= obj_dim_dict
-
- return
-
-
-
-# ===========================================
-# === Lookup for image index in clip_list ===
-# ===========================================
-def lookup_imag(clip_list, ima_id):
- for ii in clip_list:
- if ii and ii['ID'] == ima_id:
- if 'XREF' in ii: # has_key
- #cross reference - recursively look for images
- return lookup_imag(clip_list, ii['XREF'])
- else:
- return ii
- return None
-
-
-# ===================================================
-# === Create and assign image mapping to material ===
-# ===================================================
-def create_blok(surf, mat, clip_list, obj_size, obj_pos):
-
- def output_size_ofs(size, pos, blok):
- #just automate repetitive task
- # 0 == X, 1 == Y, 2 == Z
- size_default = [1.0] * 3
- size2 = [1.0] * 3
- ofs_default = [0.0] * 3
- offset = [1.0] * 3
- axis_default = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z]
- axis = [1.0] * 3
- c_map_txt = [" X--", " -Y-", " --Z"]
- c_map = [0,1,2] # standard, good for Z axis projection
- if blok['MAJAXIS'] == 0:
- c_map = [1,2,0] # X axis projection
- if blok['MAJAXIS'] == 2:
- c_map = [0,2,1] # Y axis projection
-
- ###if DEBUG: print "!!!axis mapping:"
- #this is the smart way
- ###if DEBUG: for mp in c_map: print c_map_txt[mp]
-
- if blok['SIZE'][0] != 0.0: #paranoia controls
- size_default[0] = (size[0]/blok['SIZE'][0])
- ofs_default[0] = ((blok['CNTR'][0]-pos[0])/blok['SIZE'][0])
- if blok['SIZE'][1] != 0.0:
- size_default[2] = (size[2]/blok['SIZE'][1])
- ofs_default[2] = ((blok['CNTR'][1]-pos[2])/blok['SIZE'][1])
- if blok['SIZE'][2] != 0.0:
- size_default[1] = (size[1]/blok['SIZE'][2])
- ofs_default[1] = ((blok['CNTR'][2]-pos[1])/blok['SIZE'][2])
-
- for mp in xrange(3):
- axis[mp] = axis_default[c_map[mp]]
- size2[mp] = size_default[c_map[mp]]
- offset[mp] = ofs_default[c_map[mp]]
- if offset[mp]>10.0: offset[mp]-10.0
- if offset[mp]<-10.0: offset[mp]+10.0
-# size = [size_default[mp] for mp in c_map]
-
- ###if DEBUG: print "!!!texture size and offsets:"
- ###if DEBUG: print " sizeX = %.5f; sizeY = %.5f; sizeZ = %.5f" % (size[0],size[1],size[2])
- ###if DEBUG: print " ofsX = %.5f; ofsY = %.5f; ofsZ = %.5f" % (offset[0],offset[1],offset[2])
- return axis, size2, offset
-
- ti = 0
- alphaflag = 0 #switched to 1 if some tex in this block is using alpha
- lastimag = 0 #experimental ....
- for blok in surf['BLOK']:
- ###if DEBUG: print "#...................................................................#"
- ###if DEBUG: print "# Processing texture block no.%s for surf %s" % (ti,surf['NAME'])
- ###if DEBUG: print "#...................................................................#"
- # tobj.pdict (blok)
- if ti > 9: break #only 8 channels 0..7 allowed for texture mapping
- #if not blok['ENAB']:
- # ###if DEBUG: print "***Image is not ENABled! Quitting this block"
- # break
- if not('IMAG' in blok): # has_key
- ###if DEBUG: print "***No IMAGE for this block? Quitting"
- break #extract out the image index within the clip_list
- if blok['IMAG'] == 0: blok['IMAG'] = lastimag #experimental ....
- ###if DEBUG: print "looking for image number %d" % blok['IMAG']
- ima = lookup_imag(clip_list, blok['IMAG'])
- if ima == None:
- ###if DEBUG: print "***Block index image not within CLIP list? Quitting Block"
- break #safety check (paranoia setting)
- img = ima['g_IMG']
- lastimag = blok['IMAG'] #experimental ....
- if img == None:
- ###if DEBUG: print "***Failed to pre-allocate image %s found: giving up" % ima['BASENAME']
- break
- tname = str(ima['ID'])
- if blok['ENAB']:
- tname += "+"
- else:
- tname += "x" #let's signal when should not be enabled
- if 'CHAN' in blok: # has_key
- tname += blok['CHAN']
- newtex = bpy.data.textures.new(tname)
- newtex.setType('Image') # make it anu image texture
- newtex.image = img
- #how does it extends beyond borders
- if 'WRAP' in blok: # has_key
- if (blok['WRAP'] == 3) or (blok['WRAP'] == 2):
- newtex.setExtend('Extend')
- elif (blok['WRAP'] == 1):
- newtex.setExtend('Repeat')
- elif (blok['WRAP'] == 0):
- newtex.setExtend('Clip')
- ###if DEBUG: print "generated texture %s" % tname
-
- #MapTo is determined by CHAN parameter
- #assign some defaults
- colfac = 1.0
- dvar = 1.0
- norfac = 0.5
- nega = False
- mapflag = Blender.Texture.MapTo.COL #default to color
- maptype = Blender.Texture.Mappings.FLAT
- if 'CHAN' in blok: # has_key
- if blok['CHAN'] == 'COLR' and 'OPACVAL' in blok: # has_key
- colfac = blok['OPACVAL']
- # Blender needs this to be clamped
- colfac = max(0.0, min(1.0, colfac))
- ###if DEBUG: print "!!!Set Texture -> MapTo -> Col = %.3f" % colfac
- if blok['CHAN'] == 'BUMP':
- mapflag = Blender.Texture.MapTo.NOR
- if 'OPACVAL' in blok: norfac = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> Nor = %.3f" % norfac
- if blok['CHAN'] == 'LUMI':
- mapflag = Blender.Texture.MapTo.EMIT
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- if blok['CHAN'] == 'DIFF':
- mapflag = Blender.Texture.MapTo.REF
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- if blok['CHAN'] == 'SPEC':
- mapflag = Blender.Texture.MapTo.SPEC
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- if blok['CHAN'] == 'TRAN':
- mapflag = Blender.Texture.MapTo.ALPHA
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- alphaflag = 1
- nega = True
- if 'NEGA' in blok: # has_key
- ###if DEBUG: print "!!!Watch-out: effect of this texture channel must be INVERTED!"
- nega = not nega
-
- blendmode_list = ['Mix',
- 'Subtractive',
- 'Difference',
- 'Multiply',
- 'Divide',
- 'Mix with calculated alpha layer and stencil flag',
- 'Texture Displacement',
- 'Additive']
- set_blendmode = 7 #default additive
- if 'OPAC' in blok: # has_key
- set_blendmode = blok['OPAC']
- if set_blendmode == 5: #transparency
- newtex.imageFlags |= Blender.Texture.ImageFlags.CALCALPHA
- if nega: newtex.flags |= Blender.Texture.Flags.NEGALPHA
- ###if DEBUG: print "!!!Set Texture -> MapTo -> Blending Mode = %s" % blendmode_list[set_blendmode]
-
- #the TexCo flag is determined by PROJ parameter
- axis = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z]
- size = [1.0] * 3
- ofs = [0.0] * 3
- if 'PROJ' in blok: # has_key
- if blok['PROJ'] == 0: #0 - Planar
- ###if DEBUG: print "!!!Flat projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.FLAT
- elif blok['PROJ'] == 1: #1 - Cylindrical
- ###if DEBUG: print "!!!Cylindrical projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.TUBE
- elif blok['PROJ'] == 2: #2 - Spherical
- ###if DEBUG: print "!!!Spherical projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.SPHERE
- elif blok['PROJ'] == 3: #3 - Cubic
- ###if DEBUG: print "!!!Cubic projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.CUBE
- elif blok['PROJ'] == 4: #4 - Front Projection
- ###if DEBUG: print "!!!Front projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.FLAT # ??? could it be a FLAT with some other TexCo type?
- elif blok['PROJ'] == 5: #5 - UV
- ###if DEBUG: print "UVMapped"
- coordflag = Blender.Texture.TexCo.UV
- maptype = Blender.Texture.Mappings.FLAT #in case of UV default to FLAT mapping => effectively not used
- if blok['PROJ'] != 5: #This holds for any projection map except UV
- axis, size, ofs = output_size_ofs(obj_size, obj_pos, blok)
-
- # Clamp ofs and size else blender will raise an error
- for ii in xrange(3):
- ofs[ii]= min(10.0, max(-10, ofs[ii]))
- size[ii]= min(100, max(-100, size[ii]))
-
- mat.setTexture(ti, newtex, coordflag, mapflag)
- current_mtex = mat.getTextures()[ti]
- current_mtex.mapping = maptype
- current_mtex.colfac = colfac
- current_mtex.dvar = dvar
- current_mtex.norfac = norfac
- current_mtex.neg = nega
- current_mtex.xproj = axis[0]
- current_mtex.yproj = axis[1]
- current_mtex.zproj = axis[2]
- current_mtex.size = tuple(size)
- current_mtex.ofs = tuple(ofs)
- if (set_blendmode == 5): #transparency
- current_mtex.stencil = not (nega)
-
- ti += 1
- #end loop over bloks
- return alphaflag
-
-
-# ========================================
-# === Create and assign a new material ===
-# ========================================
-#def update_material(surf_list, ptag_dict, obj, clip_list, uv_dict, dir_part):
-def update_material(clip_list, objspec, surf_list):
- if (surf_list == []) or (objspec[5] == {}) or (objspec[1] == {}):
- ###if DEBUG: print "something getting wrong in update_material: dump follows ..."
- ###if DEBUG: print surf_list
- ###if DEBUG: print objspec[5]
- ###if DEBUG: print objspec[1]
- return
- obj_dict = objspec[1]
- all_faces = objspec[3]
- obj_dim_dict = objspec[4]
- ptag_dict = objspec[5]
- uvcoords_dict = objspec[7]
- facesuv_dict = objspec[8]
- for surf in surf_list:
- if surf and surf['NAME'] in ptag_dict: # in ptag_dict.keys()
- ###if DEBUG: print "#-------------------------------------------------------------------#"
- ###if DEBUG: print "Processing surface (material): %s" % surf['NAME']
- ###if DEBUG: print "#-------------------------------------------------------------------#"
- #material set up
- facelist = ptag_dict[surf['NAME']]
- #bounding box and position
- cur_obj = obj_dict[surf['NAME']]
- obj_size = obj_dim_dict[surf['NAME']][0]
- obj_pos = obj_dim_dict[surf['NAME']][1]
- ###if DEBUG: print surf
- #uncomment this if material pre-allocated by read_surf
- mat = surf['g_MAT']
- if mat == None:
- ###if DEBUG: print "Sorry, no pre-allocated material to update. Giving up for %s." % surf['NAME']
- break
- #mat = Blender.Material.New(surf['NAME'])
- #surf['g_MAT'] = mat
- if 'COLR' in surf: # has_key
- mat.rgbCol = surf['COLR']
- if 'LUMI' in surf:
- mat.setEmit(surf['LUMI'])
- if 'GVAL' in surf: # has_key
- mat.setAdd(surf['GVAL'])
- if 'SPEC' in surf: # has_key
- mat.setSpec(surf['SPEC']) #it should be * 2 but seems to be a bit higher lwo [0.0, 1.0] - blender [0.0, 2.0]
- if 'DIFF' in surf: # has_key
- mat.setRef(surf['DIFF']) #lwo [0.0, 1.0] - blender [0.0, 1.0]
- if 'GLOS' in surf: # has_key #lwo [0.0, 1.0] - blender [0, 255]
- glo = int(371.67 * surf['GLOS'] - 42.334) #linear mapping - seems to work better than exp mapping
- if glo <32: glo = 32 #clamped to 32-255
- if glo >255: glo = 255
- mat.setHardness(glo)
- if 'TRNL' in surf: # has_key
- mat.setTranslucency(surf['TRNL']) #NOT SURE ABOUT THIS lwo [0.0, 1.0] - blender [0.0, 1.0]
-
- mm = mat.mode
- mm |= Blender.Material.Modes.TRANSPSHADOW
- if 'REFL' in surf: # has_key
- mat.setRayMirr(surf['REFL']) #lwo [0.0, 1.0] - blender [0.0, 1.0]
- mm |= Blender.Material.Modes.RAYMIRROR
- if 'TRAN' in surf: # has_key
- mat.setAlpha(1.0-surf['TRAN']) #lwo [0.0, 1.0] - blender [1.0, 0.0]
- mm |= Blender.Material.Modes.RAYTRANSP
- if 'RIND' in surf: # has_key
- s = surf['RIND']
- if s < 1.0: s = 1.0
- if s > 3.0: s = 3.0
- mat.setIOR(s) #clipped to blender [1.0, 3.0]
- mm |= Blender.Material.Modes.RAYTRANSP
- if 'BLOK' in surf and surf['BLOK'] != []:
- #update the material according to texture.
- alphaflag = create_blok(surf, mat, clip_list, obj_size, obj_pos)
- if alphaflag:
- mm |= Blender.Material.Modes.RAYTRANSP
- mat.mode = mm
- #finished setting up the material
- #end if exist SURF
- #end loop on materials (SURFs)
- return
-
-
-# ======================
-# === Read Faces 6.0 ===
-# ======================
-def read_faces_6(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- faces = []
- polygon_type = data.read(4)
- subsurf = 0
- if polygon_type != "FACE" and polygon_type != "PTCH":
- ###if DEBUG: print "No FACE/PATCH Were Found. Polygon Type: %s" % polygon_type
- return "", 2
- if polygon_type == 'PTCH': subsurf = 1
- i = 0
- while(i < lwochunk.chunksize-4):
- #if not i%1000 and my_meshtools.show_progress:
- # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
- facev = []
- numfaceverts, = struct.unpack(">H", data.read(2))
- i += 2
-
- for j in xrange(numfaceverts):
- index, index_size = read_vx(data)
- i += index_size
- facev.append(index)
- faces.append(facev)
- ###if DEBUG: print "read %s faces; type of block %d (0=FACE; 1=PATCH)" % (len(faces), subsurf)
- return faces, subsurf
-
-def main():
- if not struct:
- Blender.Draw.PupMenu('This importer requires a full python install')
- return
-
- Blender.Window.FileSelector(read, "Import LWO", '*.lwo')
-
-if __name__=='__main__':
- main()
-
-
-# Cams debugging lwo loader
-"""
-TIME= Blender.sys.time()
-import os
-print 'Searching for files'
-os.system('find /fe/lwo/Objects/ -follow -iname "*.lwo" > /tmp/templwo_list')
-# os.system('find /storage/ -iname "*.lwo" > /tmp/templwo_list')
-print '...Done'
-file= open('/tmp/templwo_list', 'r')
-lines= file.readlines()
-
-# sort by filesize for faster testing
-lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
-lines_size.sort()
-lines = [f[1] for f in lines_size]
-
-file.close()
-
-def between(v,a,b):
- if v <= max(a,b) and v >= min(a,b):
- return True
-
- return False
-size= 0.0
-for i, _lwo in enumerate(lines):
- #if i==425: # SCANFILL
- #if 1:
- #if i==520: # SCANFILL CRASH
- #if i==47: # SCANFILL CRASH
- #if between(i, 525, 550):
- #if i > 1635:
- #if i != 1519: # 730
- if i>141:
- #if 1:
- # _lwo= _lwo[:-1]
- print 'Importing', _lwo, '\nNUMBER', i, 'of', len(lines)
- _lwo_file= _lwo.split('/')[-1].split('\\')[-1]
- newScn= bpy.data.scenes.new(_lwo_file)
- bpy.data.scenes.active = newScn
- size += ((os.path.getsize(_lwo)/1024.0))/ 1024.0
- read(_lwo)
- # Remove objects to save memory?
- '''
- for ob in newScn.objects:
- if ob.type=='Mesh':
- me= ob.getData(mesh=1)
- me.verts= None
- newScn.unlink(ob)
- '''
- print 'mb size so far', size
-
-print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
-""" \ No newline at end of file
diff --git a/release/scripts/md2_export.py b/release/scripts/md2_export.py
deleted file mode 100644
index f0fe6b9af40..00000000000
--- a/release/scripts/md2_export.py
+++ /dev/null
@@ -1,1271 +0,0 @@
-#!BPY
-
-"""
-Name: 'MD2 (.md2)'
-Blender: 243
-Group: 'Export'
-Tooltip: 'Export to Quake file format (.md2).'
-"""
-
-__author__ = 'Bob Holcomb'
-__version__ = '0.18.1 patch 1'
-__url__ = ["Bob's site, http://bane.servebeer.com",
- "Support forum, http://bane.servebeer.com", "blender", "blenderartists.org"]
-__email__ = ["Bob Holcomb, bob_holcomb:hotmail*com", "scripts"]
-__bpydoc__ = """\
-This script Exports a Quake 2 file (MD2).
-
- Additional help from: Shadwolf, Skandal, Rojo, Cambo<br>
- Thanks Guys!
-"""
-
-# This is a PATCHED VERSION, fixing the bug due to which animations would
-# (almost) never work. It is now also possible to output a MD2 model without
-# texture.
-# On: 23 january 2008
-# By: Boris van Schooten (schooten@cs.utwente.nl)
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C): Bob Holcomb
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-import Blender
-from Blender import *
-from Blender.Draw import *
-from Blender.BGL import *
-from Blender.Window import *
-
-import struct, string
-from types import *
-
-
-
-######################################################
-# GUI Loader
-######################################################
-
-# Export globals
-g_filename=Create("tris.md2")
-g_frame_filename=Create("default")
-
-g_filename_search=Create("")
-g_frame_search=Create("default")
-
-g_texture_path=Create("")
-
-user_frame_list=[]
-
-#Globals
-g_scale=Create(1.0)
-
-# Events
-EVENT_NOEVENT=1
-EVENT_SAVE_MD2=2
-EVENT_CHOOSE_FILENAME=3
-EVENT_CHOOSE_FRAME=4
-EVENT_EXIT=100
-
-######################################################
-# Callbacks for Window functions
-######################################################
-def filename_callback(input_filename):
- global g_filename
- g_filename.val=input_filename
-
-def frame_callback(input_frame):
- global g_frame_filename
- g_frame_filename.val=input_frame
-
-def draw_gui():
- global g_scale
- global g_filename
- global g_frame_filename
- global EVENT_NOEVENT,EVENT_SAVE_MD2,EVENT_CHOOSE_FILENAME,EVENT_CHOOSE_FRAME,EVENT_EXIT
- global g_texture_path
-
- ########## Titles
- glClear(GL_COLOR_BUFFER_BIT)
- glRasterPos2d(10, 120)
- Text("MD2 Export")
-
- ######### Parameters GUI Buttons
- ######### MD2 Filename text entry
- g_filename = String("MD2 file to save: ", EVENT_NOEVENT, 10, 75, 210, 18,
- g_filename.val, 255, "MD2 file to save")
- ########## MD2 File Search Button
- Button("Browse",EVENT_CHOOSE_FILENAME,220,75,80,18)
-
- ########## MD2 Frame List Text entry
- g_frame_filename = String("Frame List file to load: ", EVENT_NOEVENT, 10, 55, 210, 18,
- g_frame_filename.val, 255, "Frame List to load-overrides MD2 defaults")
- ########## Frame List Search Button
- Button("Browse",EVENT_CHOOSE_FRAME,220,55,80,18)
-
- ########## Texture path to append
- g_texture_path=String("Texture Path: ", EVENT_NOEVENT, 10,35,210,18,
- g_texture_path.val,255, "Texture path to prepend")
-
-
- ########## Scale slider-default is 1/8 which is a good scale for md2->blender
- g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 95, 210, 18,
- 1.0, 0.001, 10.0, 1, "Scale factor for object Model");
-
- ######### Draw and Exit Buttons
- Button("Export",EVENT_SAVE_MD2 , 10, 10, 80, 18)
- Button("Exit",EVENT_EXIT , 170, 10, 80, 18)
-
-def event(evt, val):
- if (evt == QKEY and not val):
- Exit()
-
-def bevent(evt):
- global g_filename
- global g_frame_filename
- global EVENT_NOEVENT,EVENT_SAVE_MD2,EVENT_EXIT
-
- ######### Manages GUI events
- if (evt==EVENT_EXIT):
- Blender.Draw.Exit()
- elif (evt==EVENT_CHOOSE_FILENAME):
- FileSelector(filename_callback, "MD2 File Selection")
- elif (evt==EVENT_CHOOSE_FRAME):
- FileSelector(frame_callback, "Frame Selection")
- elif (evt==EVENT_SAVE_MD2):
- save_md2(g_filename.val)
- Blender.Draw.Exit()
- return
-
-Register(draw_gui, event, bevent)
-
-######################################################
-# MD2 Model Constants
-######################################################
-MD2_MAX_TRIANGLES=4096
-MD2_MAX_VERTICES=2048
-MD2_MAX_TEXCOORDS=2048
-MD2_MAX_FRAMES=512
-MD2_MAX_SKINS=32
-MD2_MAX_FRAMESIZE=(MD2_MAX_VERTICES * 4 + 128)
-
-MD2_FRAME_NAME_LIST=(("stand",1,40),
- ("run",41,46),
- ("attack",47,54),
- ("pain1",55,58),
- ("pain2",59,62),
- ("pain3",63,66),
- ("jump",67,72),
- ("flip",73,84),
- ("salute", 85,95),
- ("taunt",96,112),
- ("wave",113,123),
- ("point",124,135),
- ("crstnd",136,154),
- ("crwalk",155,160),
- ("crattack",161,169),
- ("crpain",170,173),
- ("crdeath",174,178),
- ("death1",179,184),
- ("death2",185,190),
- ("death3",191,198))
- #198 frames
-
-MD2_NORMALS=((-0.525731, 0.000000, 0.850651),
- (-0.442863, 0.238856, 0.864188),
- (-0.295242, 0.000000, 0.955423),
- (-0.309017, 0.500000, 0.809017),
- (-0.162460, 0.262866, 0.951056),
- (0.000000, 0.000000, 1.000000),
- (0.000000, 0.850651, 0.525731),
- (-0.147621, 0.716567, 0.681718),
- (0.147621, 0.716567, 0.681718),
- (0.000000, 0.525731, 0.850651),
- (0.309017, 0.500000, 0.809017),
- (0.525731, 0.000000, 0.850651),
- (0.295242, 0.000000, 0.955423),
- (0.442863, 0.238856, 0.864188),
- (0.162460, 0.262866, 0.951056),
- (-0.681718, 0.147621, 0.716567),
- (-0.809017, 0.309017, 0.500000),
- (-0.587785, 0.425325, 0.688191),
- (-0.850651, 0.525731, 0.000000),
- (-0.864188, 0.442863, 0.238856),
- (-0.716567, 0.681718, 0.147621),
- (-0.688191, 0.587785, 0.425325),
- (-0.500000, 0.809017, 0.309017),
- (-0.238856, 0.864188, 0.442863),
- (-0.425325, 0.688191, 0.587785),
- (-0.716567, 0.681718, -0.147621),
- (-0.500000, 0.809017, -0.309017),
- (-0.525731, 0.850651, 0.000000),
- (0.000000, 0.850651, -0.525731),
- (-0.238856, 0.864188, -0.442863),
- (0.000000, 0.955423, -0.295242),
- (-0.262866, 0.951056, -0.162460),
- (0.000000, 1.000000, 0.000000),
- (0.000000, 0.955423, 0.295242),
- (-0.262866, 0.951056, 0.162460),
- (0.238856, 0.864188, 0.442863),
- (0.262866, 0.951056, 0.162460),
- (0.500000, 0.809017, 0.309017),
- (0.238856, 0.864188, -0.442863),
- (0.262866, 0.951056, -0.162460),
- (0.500000, 0.809017, -0.309017),
- (0.850651, 0.525731, 0.000000),
- (0.716567, 0.681718, 0.147621),
- (0.716567, 0.681718, -0.147621),
- (0.525731, 0.850651, 0.000000),
- (0.425325, 0.688191, 0.587785),
- (0.864188, 0.442863, 0.238856),
- (0.688191, 0.587785, 0.425325),
- (0.809017, 0.309017, 0.500000),
- (0.681718, 0.147621, 0.716567),
- (0.587785, 0.425325, 0.688191),
- (0.955423, 0.295242, 0.000000),
- (1.000000, 0.000000, 0.000000),
- (0.951056, 0.162460, 0.262866),
- (0.850651, -0.525731, 0.000000),
- (0.955423, -0.295242, 0.000000),
- (0.864188, -0.442863, 0.238856),
- (0.951056, -0.162460, 0.262866),
- (0.809017, -0.309017, 0.500000),
- (0.681718, -0.147621, 0.716567),
- (0.850651, 0.000000, 0.525731),
- (0.864188, 0.442863, -0.238856),
- (0.809017, 0.309017, -0.500000),
- (0.951056, 0.162460, -0.262866),
- (0.525731, 0.000000, -0.850651),
- (0.681718, 0.147621, -0.716567),
- (0.681718, -0.147621, -0.716567),
- (0.850651, 0.000000, -0.525731),
- (0.809017, -0.309017, -0.500000),
- (0.864188, -0.442863, -0.238856),
- (0.951056, -0.162460, -0.262866),
- (0.147621, 0.716567, -0.681718),
- (0.309017, 0.500000, -0.809017),
- (0.425325, 0.688191, -0.587785),
- (0.442863, 0.238856, -0.864188),
- (0.587785, 0.425325, -0.688191),
- (0.688191, 0.587785, -0.425325),
- (-0.147621, 0.716567, -0.681718),
- (-0.309017, 0.500000, -0.809017),
- (0.000000, 0.525731, -0.850651),
- (-0.525731, 0.000000, -0.850651),
- (-0.442863, 0.238856, -0.864188),
- (-0.295242, 0.000000, -0.955423),
- (-0.162460, 0.262866, -0.951056),
- (0.000000, 0.000000, -1.000000),
- (0.295242, 0.000000, -0.955423),
- (0.162460, 0.262866, -0.951056),
- (-0.442863, -0.238856, -0.864188),
- (-0.309017, -0.500000, -0.809017),
- (-0.162460, -0.262866, -0.951056),
- (0.000000, -0.850651, -0.525731),
- (-0.147621, -0.716567, -0.681718),
- (0.147621, -0.716567, -0.681718),
- (0.000000, -0.525731, -0.850651),
- (0.309017, -0.500000, -0.809017),
- (0.442863, -0.238856, -0.864188),
- (0.162460, -0.262866, -0.951056),
- (0.238856, -0.864188, -0.442863),
- (0.500000, -0.809017, -0.309017),
- (0.425325, -0.688191, -0.587785),
- (0.716567, -0.681718, -0.147621),
- (0.688191, -0.587785, -0.425325),
- (0.587785, -0.425325, -0.688191),
- (0.000000, -0.955423, -0.295242),
- (0.000000, -1.000000, 0.000000),
- (0.262866, -0.951056, -0.162460),
- (0.000000, -0.850651, 0.525731),
- (0.000000, -0.955423, 0.295242),
- (0.238856, -0.864188, 0.442863),
- (0.262866, -0.951056, 0.162460),
- (0.500000, -0.809017, 0.309017),
- (0.716567, -0.681718, 0.147621),
- (0.525731, -0.850651, 0.000000),
- (-0.238856, -0.864188, -0.442863),
- (-0.500000, -0.809017, -0.309017),
- (-0.262866, -0.951056, -0.162460),
- (-0.850651, -0.525731, 0.000000),
- (-0.716567, -0.681718, -0.147621),
- (-0.716567, -0.681718, 0.147621),
- (-0.525731, -0.850651, 0.000000),
- (-0.500000, -0.809017, 0.309017),
- (-0.238856, -0.864188, 0.442863),
- (-0.262866, -0.951056, 0.162460),
- (-0.864188, -0.442863, 0.238856),
- (-0.809017, -0.309017, 0.500000),
- (-0.688191, -0.587785, 0.425325),
- (-0.681718, -0.147621, 0.716567),
- (-0.442863, -0.238856, 0.864188),
- (-0.587785, -0.425325, 0.688191),
- (-0.309017, -0.500000, 0.809017),
- (-0.147621, -0.716567, 0.681718),
- (-0.425325, -0.688191, 0.587785),
- (-0.162460, -0.262866, 0.951056),
- (0.442863, -0.238856, 0.864188),
- (0.162460, -0.262866, 0.951056),
- (0.309017, -0.500000, 0.809017),
- (0.147621, -0.716567, 0.681718),
- (0.000000, -0.525731, 0.850651),
- (0.425325, -0.688191, 0.587785),
- (0.587785, -0.425325, 0.688191),
- (0.688191, -0.587785, 0.425325),
- (-0.955423, 0.295242, 0.000000),
- (-0.951056, 0.162460, 0.262866),
- (-1.000000, 0.000000, 0.000000),
- (-0.850651, 0.000000, 0.525731),
- (-0.955423, -0.295242, 0.000000),
- (-0.951056, -0.162460, 0.262866),
- (-0.864188, 0.442863, -0.238856),
- (-0.951056, 0.162460, -0.262866),
- (-0.809017, 0.309017, -0.500000),
- (-0.864188, -0.442863, -0.238856),
- (-0.951056, -0.162460, -0.262866),
- (-0.809017, -0.309017, -0.500000),
- (-0.681718, 0.147621, -0.716567),
- (-0.681718, -0.147621, -0.716567),
- (-0.850651, 0.000000, -0.525731),
- (-0.688191, 0.587785, -0.425325),
- (-0.587785, 0.425325, -0.688191),
- (-0.425325, 0.688191, -0.587785),
- (-0.425325, -0.688191, -0.587785),
- (-0.587785, -0.425325, -0.688191),
- (-0.688191, -0.587785, -0.425325))
-
-
-######################################################
-# MD2 data structures
-######################################################
-class md2_point:
- vertices=[]
- lightnormalindex=0
- binary_format="<3BB"
- def __init__(self):
- self.vertices=[0]*3
- self.lightnormalindex=0
- def save(self, file):
- temp_data=[0]*4
- temp_data[0]=self.vertices[0]
- temp_data[1]=self.vertices[1]
- temp_data[2]=self.vertices[2]
- temp_data[3]=self.lightnormalindex
- data=struct.pack(self.binary_format, temp_data[0], temp_data[1], temp_data[2], temp_data[3])
- file.write(data)
- def dump(self):
- print "MD2 Point Structure"
- print "vertex X: ", self.vertices[0]
- print "vertex Y: ", self.vertices[1]
- print "vertex Z: ", self.vertices[2]
- print "lightnormalindex: ",self.lightnormalindex
- print ""
-
-class md2_face:
- vertex_index=[]
- texture_index=[]
- binary_format="<3h3h"
- def __init__(self):
- self.vertex_index = [ 0, 0, 0 ]
- self.texture_index = [ 0, 0, 0]
- def save(self, file):
- temp_data=[0]*6
- #swap vertices around so they draw right
- temp_data[0]=self.vertex_index[0]
- temp_data[1]=self.vertex_index[2]
- temp_data[2]=self.vertex_index[1]
- #swap texture vertices around so they draw right
- temp_data[3]=self.texture_index[0]
- temp_data[4]=self.texture_index[2]
- temp_data[5]=self.texture_index[1]
- data=struct.pack(self.binary_format,temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5])
- file.write(data)
- def dump (self):
- print "MD2 Face Structure"
- print "vertex 1 index: ", self.vertex_index[0]
- print "vertex 2 index: ", self.vertex_index[1]
- print "vertex 3 index: ", self.vertex_index[2]
- print "texture 1 index: ", self.texture_index[0]
- print "texture 2 index: ", self.texture_index[1]
- print "texture 3 index: ", self.texture_index[2]
- print ""
-
-class md2_tex_coord:
- u=0
- v=0
- binary_format="<2h"
- def __init__(self):
- self.u=0
- self.v=0
- def save(self, file):
- temp_data=[0]*2
- temp_data[0]=self.u
- temp_data[1]=self.v
- data=struct.pack(self.binary_format, temp_data[0], temp_data[1])
- file.write(data)
- def dump (self):
- print "MD2 Texture Coordinate Structure"
- print "texture coordinate u: ",self.u
- print "texture coordinate v: ",self.v
- print ""
-
-class md2_GL_command:
- s=0.0
- t=0.0
- vert_index=0
- binary_format="<2fi"
-
- def __init__(self):
- self.s=0.0
- self.t=0.0
- vert_index=0
- def save(self,file):
- temp_data=[0]*3
- temp_data[0]=float(self.s)
- temp_data[1]=float(self.t)
- temp_data[2]=self.vert_index
- data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2])
- file.write(data)
- def dump (self):
- print "MD2 OpenGL Command"
- print "s: ", self.s
- print "t: ", self.t
- print "Vertex Index: ", self.vert_index
- print ""
-
-class md2_GL_cmd_list:
- num=0
- cmd_list=[]
- binary_format="<i"
-
- def __init__(self):
- self.num=0
- self.cmd_list=[]
-
- def save(self,file):
- data=struct.pack(self.binary_format, self.num)
- file.write(data)
- for cmd in self.cmd_list:
- cmd.save(file)
- def dump(self):
- print "MD2 OpenGL Command List"
- print "number: ", self.num
- for cmd in self.cmd_list:
- cmd.dump()
- print ""
-
-class md2_skin:
- name=""
- binary_format="<64s"
- def __init__(self):
- self.name=""
- def save(self, file):
- temp_data=self.name
- data=struct.pack(self.binary_format, temp_data)
- file.write(data)
- def dump (self):
- print "MD2 Skin"
- print "skin name: ",self.name
- print ""
-
-class md2_frame:
- scale=[]
- translate=[]
- name=[]
- vertices=[]
- binary_format="<3f3f16s"
-
- def __init__(self):
- self.scale=[0.0]*3
- self.translate=[0.0]*3
- self.name=""
- self.vertices=[]
- def save(self, file):
- temp_data=[0]*7
- temp_data[0]=float(self.scale[0])
- temp_data[1]=float(self.scale[1])
- temp_data[2]=float(self.scale[2])
- temp_data[3]=float(self.translate[0])
- temp_data[4]=float(self.translate[1])
- temp_data[5]=float(self.translate[2])
- temp_data[6]=self.name
- data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5],temp_data[6])
- file.write(data)
- def dump (self):
- print "MD2 Frame"
- print "scale x: ",self.scale[0]
- print "scale y: ",self.scale[1]
- print "scale z: ",self.scale[2]
- print "translate x: ",self.translate[0]
- print "translate y: ",self.translate[1]
- print "translate z: ",self.translate[2]
- print "name: ",self.name
- print ""
-
-class md2_obj:
- #Header Structure
- ident=0 #int 0 This is used to identify the file
- version=0 #int 1 The version number of the file (Must be 8)
- skin_width=0 #int 2 The skin width in pixels
- skin_height=0 #int 3 The skin height in pixels
- frame_size=0 #int 4 The size in bytes the frames are
- num_skins=0 #int 5 The number of skins associated with the model
- num_vertices=0 #int 6 The number of vertices (constant for each frame)
- num_tex_coords=0 #int 7 The number of texture coordinates
- num_faces=0 #int 8 The number of faces (polygons)
- num_GL_commands=0 #int 9 The number of gl commands
- num_frames=0 #int 10 The number of animation frames
- offset_skins=0 #int 11 The offset in the file for the skin data
- offset_tex_coords=0 #int 12 The offset in the file for the texture data
- offset_faces=0 #int 13 The offset in the file for the face data
- offset_frames=0 #int 14 The offset in the file for the frames data
- offset_GL_commands=0#int 15 The offset in the file for the gl commands data
- offset_end=0 #int 16 The end of the file offset
- binary_format="<17i" #little-endian (<), 17 integers (17i)
- #md2 data objects
- tex_coords=[]
- faces=[]
- frames=[]
- skins=[]
- GL_commands=[]
-
- def __init__ (self):
- self.tex_coords=[]
- self.faces=[]
- self.frames=[]
- self.skins=[]
- def save(self, file):
- temp_data=[0]*17
- temp_data[0]=self.ident
- temp_data[1]=self.version
- temp_data[2]=self.skin_width
- temp_data[3]=self.skin_height
- temp_data[4]=self.frame_size
- temp_data[5]=self.num_skins
- temp_data[6]=self.num_vertices
- temp_data[7]=self.num_tex_coords
- temp_data[8]=self.num_faces
- temp_data[9]=self.num_GL_commands
- temp_data[10]=self.num_frames
- temp_data[11]=self.offset_skins
- temp_data[12]=self.offset_tex_coords
- temp_data[13]=self.offset_faces
- temp_data[14]=self.offset_frames
- temp_data[15]=self.offset_GL_commands
- temp_data[16]=self.offset_end
- data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5],temp_data[6],temp_data[7],temp_data[8],temp_data[9],temp_data[10],temp_data[11],temp_data[12],temp_data[13],temp_data[14],temp_data[15],temp_data[16])
- file.write(data)
- #write the skin data
- for skin in self.skins:
- skin.save(file)
- #save the texture coordinates
- for tex_coord in self.tex_coords:
- tex_coord.save(file)
- #save the face info
- for face in self.faces:
- face.save(file)
- #save the frames
- for frame in self.frames:
- frame.save(file)
- for vert in frame.vertices:
- vert.save(file)
- #save the GL command List
- for cmd in self.GL_commands:
- cmd.save(file)
- def dump (self):
- print "Header Information"
- print "ident: ", self.ident
- print "version: ", self.version
- print "skin width: ", self.skin_width
- print "skin height: ", self.skin_height
- print "frame size: ", self.frame_size
- print "number of skins: ", self.num_skins
- print "number of texture coordinates: ", self.num_tex_coords
- print "number of faces: ", self.num_faces
- print "number of frames: ", self.num_frames
- print "number of vertices: ", self.num_vertices
- print "number of GL commands: ",self.num_GL_commands
- print "offset skins: ", self.offset_skins
- print "offset texture coordinates: ", self.offset_tex_coords
- print "offset faces: ", self.offset_faces
- print "offset frames: ",self.offset_frames
- print "offset GL Commands: ",self.offset_GL_commands
- print "offset end: ",self.offset_end
- print ""
-
-######################################################
-# Validation
-######################################################
-
-def validation(object):
- global user_frame_list
-
- #get access to the mesh data
- mesh=object.getData(False, True) #get the object (not just name) and the Mesh, not NMesh
-
- #check it's composed of only tri's
- result=0
- for face in mesh.faces:
- if len(face.verts)!=3:
- #select the face for future triangulation
- face.sel=1
- if result==0: #first time we have this problem, don't pop-up a window every time it finds a quad
- print "Model not made entirely of triangles"
- result=Blender.Draw.PupMenu("Model not made entirely out of Triangles-Convert?%t|YES|Quit")
-
- #triangulate or quit
- if result==1:
- #selecting face mode
- Blender.Mesh.Mode(3)
- editmode = Window.EditMode() # are we in edit mode? If so ...
- if editmode: Window.EditMode(0) # leave edit mode before getting the mesh
- mesh.quadToTriangle(0) #use closest verticies in breaking a quad
- elif result==2:
- return False #user will fix (I guess)
-
- #check it has UV coordinates
- if mesh.vertexUV==True:
- print "Vertex UV not supported"
- result=Blender.Draw.PupMenu("Vertex UV not suppored-Use Sticky UV%t|Quit")
- return False
-
- elif mesh.faceUV==True:
- for face in mesh.faces:
- if(len(face.uv)==3):
- pass
- else:
- print "Model's vertices do not all have UV"
- result=Blender.Draw.PupMenu("Model's vertices do not all have UV%t|Quit")
- return False
-
- else:
- print "Model does not have UV (face or vertex)"
- result=Blender.Draw.PupMenu("Model does not have UV (face or vertex)%t|Output (0,0) as UV coordinates and do not generate GL commands|Quit")
- if result==2:
- return False
-
- #check it has an associated texture map
- last_face=""
- if mesh.faceUV:
- last_face=mesh.faces[0].image
- #check if each face uses the same texture map (only one allowed)
- for face in mesh.faces:
- mesh_image=face.image
- if not mesh_image:
- print "Model has a face without a texture Map"
- result=Blender.Draw.PupMenu("Model has a face without a texture Map%t|This should never happen!")
- #return False
- if mesh_image!=last_face:
- print "Model has more than 1 texture map assigned"
- result=Blender.Draw.PupMenu("Model has more than 1 texture map assigned%t|Quit")
- #return False
- if mesh_image:
- try: size=mesh_image.getSize()
- except: size= 256,256 # No image data
- #is this really what the user wants
- if (size[0]!=256 or size[1]!=256):
- print "Texture map size is non-standard (not 256x256), it is: ",size[0],"x",size[1]
- result=Blender.Draw.PupMenu("Texture map size is non-standard (not 256x256), it is: "+str(size[0])+"x"+str(size[1])+": Continue?%t|YES|NO")
- if(result==2):
- return False
-
-
- #verify frame list data
- user_frame_list=get_frame_list()
- temp=user_frame_list[len(user_frame_list)-1]
- temp_num_frames=temp[2]
-
- #verify tri/vert/frame counts are within MD2 standard
- face_count=len(mesh.faces)
- vert_count=len(mesh.verts)
- frame_count=temp_num_frames
-
- if face_count>MD2_MAX_TRIANGLES:
- print "Number of triangles exceeds MD2 standard: ", face_count,">",MD2_MAX_TRIANGLES
- result=Blender.Draw.PupMenu("Number of triangles exceeds MD2 standard: Continue?%t|YES|NO")
- if(result==2):
- return False
- if vert_count>MD2_MAX_VERTICES:
- print "Number of verticies exceeds MD2 standard",vert_count,">",MD2_MAX_VERTICES
- result=Blender.Draw.PupMenu("Number of verticies exceeds MD2 standard: Continue?%t|YES|NO")
- if(result==2):
- return False
- if frame_count>MD2_MAX_FRAMES:
- print "Number of frames exceeds MD2 standard of",frame_count,">",MD2_MAX_FRAMES
- result=Blender.Draw.PupMenu("Number of frames exceeds MD2 standard: Continue?%t|YES|NO")
- if(result==2):
- return False
- #model is OK
- return True
-
-######################################################
-# Fill MD2 data structure
-######################################################
-def fill_md2(md2, object):
- #global defines
- global user_frame_list
- global g_texture_path
-
- Blender.Window.DrawProgressBar(0.25,"Filling MD2 Data")
-
- #get a Mesh, not NMesh
- mesh=object.getData(False, True)
- #don't forget to copy the data! -- Boris van Schooten
- mesh=mesh.__copy__();
- #load up some intermediate data structures
- tex_list={}
- tex_count=0
- #create the vertex list from the first frame
- Blender.Set("curframe", 1)
-
- has_uvs = mesh.faceUV
-
- #header information
- md2.ident=844121161
- md2.version=8
- md2.num_vertices=len(mesh.verts)
- md2.num_faces=len(mesh.faces)
-
- #get the skin information
- #use the first faces' image for the texture information
- if has_uvs:
- mesh_image=mesh.faces[0].image
- try: size=mesh_image.getSize()
- except: size= 256,256
-
- md2.skin_width=size[0]
- md2.skin_height=size[1]
- md2.num_skins=1
- #add a skin node to the md2 data structure
- md2.skins.append(md2_skin())
- md2.skins[0].name=g_texture_path.val+Blender.sys.basename(mesh_image.getFilename())
- if len(md2.skins[0].name)>64:
- print "Texture Path and name is more than 64 characters"
- result=Blender.Draw.PupMenu("Texture path and name is more than 64 characters-Quitting")
- return False
-
- #put texture information in the md2 structure
- #build UV coord dictionary (prevents double entries-saves space)
- if not has_uvs:
- t=(0,0)
-
- for face in mesh.faces:
- for i in xrange(0,3):
- if has_uvs:
- t=(face.uv[i])
-
- tex_key=(t[0],t[1])
- if not tex_list.has_key(tex_key):
- tex_list[tex_key]=tex_count
- tex_count+=1
- md2.num_tex_coords=tex_count #each vert has its own UV coord
-
- for this_tex in xrange (0, md2.num_tex_coords):
- md2.tex_coords.append(md2_tex_coord())
- for coord, index in tex_list.iteritems():
- #md2.tex_coords.append(md2_tex_coord())
- md2.tex_coords[index].u=int(coord[0]*md2.skin_width)
- md2.tex_coords[index].v=int((1-coord[1])*md2.skin_height)
-
- #put faces in the md2 structure
- #for each face in the model
-
- if not has_uvs:
- uv_coords=[(0,0)]*3
-
- for this_face in xrange(0, md2.num_faces):
- md2.faces.append(md2_face())
- mf = mesh.faces[this_face]
- mf_v = mf.v
- if has_uvs:
- uv_coords = mf.uv
-
- for i in xrange(0,3):
- #blender uses indexed vertexes so this works very well
- md2.faces[this_face].vertex_index[i] = mf_v[i].index
- #lookup texture index in dictionary
- if has_uvs:
- uv_coord = uv_coords[i]
- # otherwise we set it before
-
- tex_key=(uv_coord[0],uv_coord[1])
- tex_index=tex_list[tex_key]
- md2.faces[this_face].texture_index[i]=tex_index
-
- Blender.Window.DrawProgressBar(0.5, "Computing GL Commands")
-
- #compute GL commands
- md2.num_GL_commands=build_GL_commands(md2, mesh)
-
- #get the frame data
- #calculate 1 frame size + (1 vert size*num_verts)
- md2.frame_size=40+(md2.num_vertices*4) #in bytes
-
- #get the frame list
- user_frame_list=get_frame_list()
- if user_frame_list=="default":
- md2.num_frames=198
- else:
- temp=user_frame_list[len(user_frame_list)-1] #last item
- md2.num_frames=temp[2] #last frame number
-
-
- progress=0.5
- progressIncrement=0.25/md2.num_frames
-
- #fill in each frame with frame info and all the vertex data for that frame
- for frame_counter in xrange(0,md2.num_frames):
-
- progress+=progressIncrement
- Blender.Window.DrawProgressBar(progress, "Calculating Frame: %d of %d" % (frame_counter, md2.num_frames))
-
- #add a frame
- md2.frames.append(md2_frame())
- #update the mesh objects vertex positions for the animation
- Blender.Set("curframe", frame_counter) #set blender to the correct frame
-
-
-
-
- mesh.getFromObject(object) #update the mesh to make verts current
- mesh.transform(object.matrixWorld)
-
-#each frame has a scale and transform value that gets the vertex value between 0-255
-#since the scale and transform are the same for the all the verts in the frame, we only need
-#to figure this out once per frame
-
- #we need to start with the bounding box
- #bounding_box=object.getBoundBox() #uses the object, not the mesh data
- #initialize with the first vertex for both min and max. X and Y are swapped for MD2 format
-
- #initialize
- frame_min_x=100000.0
- frame_max_x=-100000.0
- frame_min_y=100000.0
- frame_max_y=-100000.0
- frame_min_z=100000.0
- frame_max_z=-100000.0
-
- for face in mesh.faces:
- for vert in face:
- co = vert.co
- if frame_min_x>co[1]: frame_min_x=co[1]
- if frame_max_x<co[1]: frame_max_x=co[1]
- if frame_min_y>co[0]: frame_min_y=co[0]
- if frame_max_y<co[0]: frame_max_y=co[0]
- if frame_min_z>co[2]: frame_min_z=co[2]
- if frame_max_z<co[2]: frame_max_z=co[2]
-
- #the scale is the difference between the min and max (on that axis) / 255
- frame_scale_x=(frame_max_x-frame_min_x)/255
- frame_scale_y=(frame_max_y-frame_min_y)/255
- frame_scale_z=(frame_max_z-frame_min_z)/255
-
- if frame_scale_x == 0: frame_scale_x = 1.0
- if frame_scale_y == 0: frame_scale_y = 1.0
- if frame_scale_z == 0: frame_scale_z = 1.0
-
- #translate value of the mesh to center it on the origin
- frame_trans_x=frame_min_x
- frame_trans_y=frame_min_y
- frame_trans_z=frame_min_z
-
- #fill in the data
- md2.frames[frame_counter].scale=(-frame_scale_x, frame_scale_y, frame_scale_z)
- md2.frames[frame_counter].translate=(-frame_trans_x, frame_trans_y, frame_trans_z)
-
- #now for the vertices
- for vert_counter in xrange(0, md2.num_vertices):
- #add a vertex to the md2 structure
- md2.frames[frame_counter].vertices.append(md2_point())
- #figure out the new coords based on scale and transform
- #then translates the point so it's not less than 0
- #then scale it so it's between 0..255
- #print "frame scale : ", frame_scale_x, " ", frame_scale_y, " ", frame_scale_z
- co = mesh.verts[vert_counter].co
- new_x=int((co[1]-frame_trans_x)/frame_scale_x)
- new_y=int((co[0]-frame_trans_y)/frame_scale_y)
- new_z=int((co[2]-frame_trans_z)/frame_scale_z)
- #put them in the structure
- md2.frames[frame_counter].vertices[vert_counter].vertices=(new_x, new_y, new_z)
-
- #need to add the lookup table check here
- maxdot = -999999.0;
- maxdotindex = -1;
-
-
- #swap y and x for difference in axis orientation
- no = mesh.verts[vert_counter].no
- x1= -no[1]
- y1= no[0]
- z1= no[2]
-
- for j in xrange(0,162):
- #dot = (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
- dot = (x1*MD2_NORMALS[j][0] + y1*MD2_NORMALS[j][1]+ z1*MD2_NORMALS[j][2]);
- if (dot > maxdot):
- maxdot = dot;
- maxdotindex = j;
-
- # See patch [#19206], gives good info on this line below.
- md2.frames[frame_counter].vertices[vert_counter].lightnormalindex=maxdotindex
-
- del maxdot, maxdotindex
- del new_x, new_y, new_z
- del frame_max_x, frame_max_y, frame_max_z, frame_min_x, frame_min_y, frame_min_z
- del frame_scale_x, frame_scale_y, frame_scale_z, frame_trans_x, frame_trans_y, frame_trans_z
-
-
- #output all the frame names-user_frame_list is loaded during the validation
- for frame_set in user_frame_list:
- for counter in xrange(frame_set[1]-1, frame_set[2]):
- md2.frames[counter].name=frame_set[0]+"_"+str(counter-frame_set[1]+2)
-
- #compute these after everthing is loaded into a md2 structure
- header_size=17*4 #17 integers, and each integer is 4 bytes
- skin_size=64*md2.num_skins #64 char per skin * number of skins
- tex_coord_size=4*md2.num_tex_coords #2 short * number of texture coords
- face_size=12*md2.num_faces #3 shorts for vertex index, 3 shorts for tex index
- frames_size=(((12+12+16)+(4*md2.num_vertices)) * md2.num_frames) #frame info+verts per frame*num frames
- GL_command_size=md2.num_GL_commands*4 #each is an int or float, so 4 bytes per
-
- #fill in the info about offsets
- md2.offset_skins=0+header_size
- md2.offset_tex_coords=md2.offset_skins+skin_size
- md2.offset_faces=md2.offset_tex_coords+tex_coord_size
- md2.offset_frames=md2.offset_faces+face_size
- md2.offset_GL_commands=md2.offset_frames+frames_size
- md2.offset_end=md2.offset_GL_commands+GL_command_size
-
-######################################################
-# Get Frame List
-######################################################
-def get_frame_list():
- global g_frame_filename
- frame_list=[]
-
- if g_frame_filename.val=="default":
- return MD2_FRAME_NAME_LIST
-
- else:
- #check for file
- if (Blender.sys.exists(g_frame_filename.val)==1):
- #open file and read it in
- file=open(g_frame_filename.val,"r")
- lines=file.readlines()
- file.close()
-
- #check header (first line)
- if lines[0].strip() != "# MD2 Frame Name List":
- print "its not a valid file"
- result=Blender.Draw.PupMenu("This is not a valid frame definition file-using default%t|OK")
- return MD2_FRAME_NAME_LIST
- else:
- #read in the data
- num_frames=0
- for counter in xrange(1, len(lines)):
- current_line=lines[counter].strip()
- if current_line[0]=="#":
- #found a comment
- pass
- else:
- data=current_line.split()
- frame_list.append([data[0],num_frames+1, num_frames+int(data[1])])
- num_frames+=int(data[1])
- return frame_list
- else:
- print "Cannot find file"
- result=Blender.Draw.PupMenu("Cannot find frame definion file-using default%t|OK")
- return MD2_FRAME_NAME_LIST
-
-######################################################
-# Globals for GL command list calculations
-######################################################
-used_tris=[]
-edge_dict={}
-strip_verts=[]
-strip_st=[]
-strip_tris=[]
-strip_first_run=True
-odd=False
-
-######################################################
-# Find Strip length function
-######################################################
-def find_strip_length(mesh, start_tri, edge_key):
- #print "Finding strip length"
-
- global used_tris
- global edge_dict
- global strip_tris
- global strip_st
- global strip_verts
- global strip_first_run
- global odd
-
- used_tris[start_tri]=2
-
- strip_tris.append(start_tri) #add this tri to the potential list of tri-strip
-
- #print "I am face: ", start_tri
- #print "Using edge Key: ", edge_key
-
- faces=edge_dict[edge_key] #get list of face indexes that share this edge
- if (len(faces)==0):
- #print "Cant find edge with key: ", edge_key
- pass
-
- #print "Faces sharing this edge: ", faces
- for face_index in faces:
- face=mesh.faces[face_index]
- if face_index==start_tri: #don't want to check myself
- #print "I found myself, continuing"
- pass
- else:
- if used_tris[face_index]!=0: #found a used tri-move along
- #print "Found a used tri: ", face_index
- pass
- else:
- #find non-shared vert
- for vert_counter in xrange(0,3):
- if (face.verts[vert_counter].index!=edge_key[0] and face.verts[vert_counter].index!=edge_key[1]):
- next_vert=vert_counter
-
- if(odd==False):
- #print "Found a suitable even connecting tri: ", face_index
- used_tris[face_index]=2 #mark as dirty for this rum
- odd=True
-
- #find the new edge
- if(face.verts[next_vert].index < face.verts[(next_vert+2)%3].index):
- temp_key=(face.verts[next_vert].index,face.verts[(next_vert+2)%3].index)
- else:
- temp_key=(face.verts[(next_vert+2)%3].index, face.verts[next_vert].index)
-
- #print "temp key: ", temp_key
- temp_faces=edge_dict[temp_key]
-
- if(len(temp_faces)==0):
- print "Can't find any other faces with key: ", temp_key
- else:
- #search the new edge
- #print "found other faces, searching them"
- find_strip_length(mesh, face_index, temp_key) #recursive greedy-takes first tri it finds as best
- break;
- else:
- #print "Found a suitable odd connecting tri: ", face_index
- used_tris[face_index]=2 #mark as dirty for this rum
- odd=False
-
- #find the new edge
- if(face.verts[next_vert].index < face.verts[(next_vert+1)%3].index):
- temp_key=(face.verts[next_vert].index,face.verts[(next_vert+1)%3].index)
- else:
- temp_key=(face.verts[(next_vert+1)%3].index, face.verts[next_vert].index)
- #print "temp key: ", temp_key
- temp_faces=edge_dict[temp_key]
- if(len(temp_faces)==0):
- print "Can't find any other faces with key: ", temp_key
- else:
- #search the new edge
- #print "found other faces, searching them"
- find_strip_length(mesh, face_index, temp_key) #recursive greedy-takes first tri it finds as best
- break;
-
- return len(strip_tris)
-
-
-######################################################
-# Tri-Stripify function
-######################################################
-def stripify_tri_list(mesh, edge_key):
- global edge_dict
- global strip_tris
- global strip_st
- global strip_verts
-
- shared_edge=[]
- key=[]
-
- #print "*****Stripify the triangle list*******"
- #print "strip tris: ", strip_tris
- #print "strip_tri length: ", len(strip_tris)
-
- for tri_counter in xrange(0, len(strip_tris)):
- face=mesh.faces[strip_tris[tri_counter]]
- if (tri_counter==0): #first one only
- #find non-edge vert
- for vert_counter in xrange(0,3):
- if (face.verts[vert_counter].index!=edge_key[0] and face.verts[vert_counter].index!=edge_key[1]):
- start_vert=vert_counter
- strip_verts.append(face.verts[start_vert].index)
- strip_st.append(face.uv[start_vert])
-
- strip_verts.append(face.verts[(start_vert+2)%3].index)
- strip_st.append(face.uv[(start_vert+2)%3])
-
- strip_verts.append(face.verts[(start_vert+1)%3].index)
- strip_st.append(face.uv[(start_vert+1)%3])
- else:
- for vert_counter in xrange(0,3):
- if(face.verts[vert_counter].index!=strip_verts[-1] and face.verts[vert_counter].index!=strip_verts[-2]):
- strip_verts.append(face.verts[vert_counter].index)
- strip_st.append(face.uv[vert_counter])
- break
-
-
-
-######################################################
-# Build GL command List
-######################################################
-def build_GL_commands(md2, mesh):
- # we can't output gl command structure without uv
- if not mesh.faceUV:
- print "No UV: not building GL Commands"
- return 0
-
- print "Building GL Commands"
-
- global used_tris
- global edge_dict
- global strip_verts
- global strip_tris
- global strip_st
-
- #globals initialization
- used_tris=[0]*len(mesh.faces)
- #print "Used: ", used_tris
- num_commands=0
-
- #edge dictionary generation
- edge_dict=dict([(ed.key,[]) for ed in mesh.edges])
- for face in (mesh.faces):
- for key in face.edge_keys:
- edge_dict[key].append(face.index)
-
- #print "edge Dict: ", edge_dict
-
- for tri_counter in xrange(0,len(mesh.faces)):
- if used_tris[tri_counter]!=0:
- #print "Found a used triangle: ", tri_counter
- pass
- else:
- #print "Found an unused triangle: ", tri_counter
-
- #intialization
- strip_tris=[0]*0
- strip_verts=[0]*0
- strip_st=[0]*0
- strip_first_run=True
- odd=True
-
- #find the strip length
- strip_length=find_strip_length(mesh, tri_counter, mesh.faces[tri_counter].edge_keys[0])
-
- #mark tris as used
- for used_counter in xrange(0,strip_length):
- used_tris[strip_tris[used_counter]]=1
-
- stripify_tri_list(mesh, mesh.faces[tri_counter].edge_keys[0])
-
- #create command list
- cmd_list=md2_GL_cmd_list()
- #number of commands in this list
- print "strip length: ", strip_length
- cmd_list.num=(len(strip_tris)+2) #positive for strips, fans would be negative, but not supported yet
- num_commands+=1
-
- #add s,t,vert for this command list
- for command_counter in xrange(0, len(strip_tris)+2):
- cmd=md2_GL_command()
- cmd.s=strip_st[command_counter][0]
- cmd.t=1.0-strip_st[command_counter][1] #flip upside down
- cmd.vert_index=strip_verts[command_counter]
- num_commands+=3
- cmd_list.cmd_list.append(cmd)
- print "Cmd List length: ", len(cmd_list.cmd_list)
- print "Cmd list num: ", cmd_list.num
- print "Cmd List: ", cmd_list.dump()
- md2.GL_commands.append(cmd_list)
-
- #add the null command at the end
- temp_cmdlist=md2_GL_cmd_list()
- temp_cmdlist.num=0
- md2.GL_commands.append(temp_cmdlist)
- num_commands+=1
-
- #cleanup and return
- used=strip_vert=strip_st=strip_tris=0
- return num_commands
-
-
-
-
-######################################################
-# Save MD2 Format
-######################################################
-def save_md2(filename):
- print ""
- print "***********************************"
- print "MD2 Export"
- print "***********************************"
- print ""
-
- Blender.Window.DrawProgressBar(0.0,"Begining MD2 Export")
-
- md2=md2_obj() #blank md2 object to save
-
- #get the object
- mesh_objs = Blender.Object.GetSelected()
-
- #check there is a blender object selected
- if len(mesh_objs)==0:
- print "Fatal Error: Must select a mesh to output as MD2"
- print "Found nothing"
- result=Blender.Draw.PupMenu("Must select an object to export%t|OK")
- return
-
- mesh_obj=mesh_objs[0] #this gets the first object (should be only one)
-
- #check if it's a mesh object
- if mesh_obj.getType()!="Mesh":
- print "Fatal Error: Must select a mesh to output as MD2"
- print "Found: ", mesh_obj.getType()
- result=Blender.Draw.PupMenu("Selected Object must be a mesh to output as MD2%t|OK")
- return
-
- ok=validation(mesh_obj)
- if ok==False:
- return
-
- fill_md2(md2, mesh_obj)
- md2.dump()
-
- Blender.Window.DrawProgressBar(1.0, "Writing to Disk")
-
- #actually write it to disk
- file=open(filename,"wb")
- md2.save(file)
- file.close()
-
- #cleanup
- md2=0
-
- print "Closed the file"
-
diff --git a/release/scripts/md2_import.py b/release/scripts/md2_import.py
deleted file mode 100644
index f52746259a6..00000000000
--- a/release/scripts/md2_import.py
+++ /dev/null
@@ -1,600 +0,0 @@
-#!BPY
-
-"""
-Name: 'MD2 (.md2)'
-Blender: 239
-Group: 'Import'
-Tooltip: 'Import from Quake file format (.md2).'
-"""
-
-__author__ = 'Bob Holcomb'
-__version__ = '0.16'
-__url__ = ["Bob's site, http://bane.servebeer.com",
- "Support forum, http://scourage.servebeer.com/phpbb/", "blender", "blenderartists.org"]
-__email__ = ["Bob Holcomb, bob_holcomb:hotmail*com", "scripts"]
-__bpydoc__ = """\
-This script imports a Quake 2 file (MD2), textures,
-and animations into blender for editing. Loader is based on MD2 loader from www.gametutorials.com-Thanks DigiBen! and the md3 blender loader by PhaethonH <phaethon@linux.ucla.edu><br>
-
- Additional help from: Shadwolf, Skandal, Rojo and Campbell Barton<br>
- Thanks Guys!
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Bob Holcomb
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-import Blender
-from Blender import Mesh, Object, sys
-from Blender.BGL import *
-from Blender.Draw import *
-from Blender.Window import *
-from Blender.Mathutils import Vector
-import struct
-from types import *
-
-
-######################################################
-# Main Body
-######################################################
-
-#returns the string from a null terminated string
-def asciiz (s):
- n = 0
- while (ord(s[n]) != 0):
- n = n + 1
- return s[0:n]
-
-
-######################################################
-# MD2 Model Constants
-######################################################
-MD2_MAX_TRIANGLES=4096
-MD2_MAX_VERTICES=2048
-MD2_MAX_TEXCOORDS=2048
-MD2_MAX_FRAMES=512
-MD2_MAX_SKINS=32
-MD2_MAX_FRAMESIZE=(MD2_MAX_VERTICES * 4 + 128)
-
-######################################################
-# MD2 data structures
-######################################################
-class md2_alias_triangle(object):
- __slots__ = 'vertices', 'lightnormalindex'
- binary_format="<3BB" #little-endian (<), 3 Unsigned char
-
- def __init__(self):
- self.vertices=[0]*3
- self.lightnormalindex=0
-
- def load(self, file):
- temp_data = file.read(struct.calcsize(self.binary_format))
- data = struct.unpack(self.binary_format, temp_data)
- self.vertices[0]=data[0]
- self.vertices[1]=data[1]
- self.vertices[2]=data[2]
- self.lightnormalindex=data[3]
- return self
-
- def dump(self):
- print "MD2 Alias_Triangle Structure"
- print "vertex: ", self.vertices[0]
- print "vertex: ", self.vertices[1]
- print "vertex: ", self.vertices[2]
- print "lightnormalindex: ",self.lightnormalindex
- print ""
-
-class md2_face(object):
-
- binary_format="<3h3h" #little-endian (<), 3 short, 3 short
-
- __slots__ = 'vertex_index', 'texture_index'
-
- def __init__(self):
- self.vertex_index = [ 0, 0, 0 ]
- self.texture_index = [ 0, 0, 0]
-
- def load (self, file):
- temp_data=file.read(struct.calcsize(self.binary_format))
- data=struct.unpack(self.binary_format, temp_data)
- self.vertex_index[0]=data[0]
- self.vertex_index[1]=data[1]
- self.vertex_index[2]=data[2]
- self.texture_index[0]=data[3]
- self.texture_index[1]=data[4]
- self.texture_index[2]=data[5]
- return self
-
- def dump (self):
- print "MD2 Face Structure"
- print "vertex index: ", self.vertex_index[0]
- print "vertex index: ", self.vertex_index[1]
- print "vertex index: ", self.vertex_index[2]
- print "texture index: ", self.texture_index[0]
- print "texture index: ", self.texture_index[1]
- print "texture index: ", self.texture_index[2]
- print ""
-
-class md2_tex_coord(object):
- __slots__ = 'u', 'v'
- binary_format="<2h" #little-endian (<), 2 unsigned short
-
- def __init__(self):
- self.u=0
- self.v=0
-
- def load (self, file):
- temp_data=file.read(struct.calcsize(self.binary_format))
- data=struct.unpack(self.binary_format, temp_data)
- self.u=data[0]
- self.v=data[1]
- return self
-
- def dump (self):
- print "MD2 Texture Coordinate Structure"
- print "texture coordinate u: ",self.u
- print "texture coordinate v: ",self.v
- print ""
-
-
-class md2_skin(object):
- __slots__ = 'name'
- binary_format="<64s" #little-endian (<), char[64]
-
- def __init__(self):
- self.name=""
-
- def load (self, file):
- temp_data=file.read(struct.calcsize(self.binary_format))
- data=struct.unpack(self.binary_format, temp_data)
- self.name=asciiz(data[0])
- return self
-
- def dump (self):
- print "MD2 Skin"
- print "skin name: ",self.name
- print ""
-
-class md2_alias_frame(object):
- __slots__ = 'scale', 'translate', 'name', 'vertices'
- binary_format="<3f3f16s" #little-endian (<), 3 float, 3 float char[16]
- #did not add the "3bb" to the end of the binary format
- #because the alias_vertices will be read in through
- #thier own loader
-
- def __init__(self):
- self.scale=[0.0]*3
- self.translate=[0.0]*3
- self.name=""
- self.vertices=[]
-
-
- def load (self, file):
- temp_data=file.read(struct.calcsize(self.binary_format))
- data=struct.unpack(self.binary_format, temp_data)
- self.scale[0]=data[0]
- self.scale[1]=data[1]
- self.scale[2]=data[2]
- self.translate[0]=data[3]
- self.translate[1]=data[4]
- self.translate[2]=data[5]
- self.name=asciiz(data[6])
- return self
-
- def dump (self):
- print "MD2 Alias Frame"
- print "scale x: ",self.scale[0]
- print "scale y: ",self.scale[1]
- print "scale z: ",self.scale[2]
- print "translate x: ",self.translate[0]
- print "translate y: ",self.translate[1]
- print "translate z: ",self.translate[2]
- print "name: ",self.name
- print ""
-
-class md2_obj(object):
- __slots__ =\
- 'tex_coords', 'faces', 'frames',\
- 'skins', 'ident', 'version',\
- 'skin_width', 'skin_height',\
- 'frame_size', 'num_skins', 'num_vertices',\
- 'num_tex_coords', 'num_faces', 'num_GL_commands',\
- 'num_frames', 'offset_skins', 'offset_tex_coords',\
- 'offset_faces', 'offset_frames', 'offset_GL_commands'
-
- '''
- #Header Structure
- ident=0 #int 0 This is used to identify the file
- version=0 #int 1 The version number of the file (Must be 8)
- skin_width=0 #int 2 The skin width in pixels
- skin_height=0 #int 3 The skin height in pixels
- frame_size=0 #int 4 The size in bytes the frames are
- num_skins=0 #int 5 The number of skins associated with the model
- num_vertices=0 #int 6 The number of vertices (constant for each frame)
- num_tex_coords=0 #int 7 The number of texture coordinates
- num_faces=0 #int 8 The number of faces (polygons)
- num_GL_commands=0 #int 9 The number of gl commands
- num_frames=0 #int 10 The number of animation frames
- offset_skins=0 #int 11 The offset in the file for the skin data
- offset_tex_coords=0 #int 12 The offset in the file for the texture data
- offset_faces=0 #int 13 The offset in the file for the face data
- offset_frames=0 #int 14 The offset in the file for the frames data
- offset_GL_commands=0#int 15 The offset in the file for the gl commands data
- offset_end=0 #int 16 The end of the file offset
- '''
- binary_format="<17i" #little-endian (<), 17 integers (17i)
-
- #md2 data objects
-
- def __init__ (self):
- self.tex_coords=[]
- self.faces=[]
- self.frames=[]
- self.skins=[]
-
-
- def load (self, file):
- temp_data = file.read(struct.calcsize(self.binary_format))
- data = struct.unpack(self.binary_format, temp_data)
-
- self.ident=data[0]
- self.version=data[1]
-
- if (self.ident!=844121161 or self.version!=8):
- print "Not a valid MD2 file"
- Exit()
-
- self.skin_width=data[2]
- self.skin_height=data[3]
- self.frame_size=data[4]
-
- #make the # of skin objects for model
- self.num_skins=data[5]
- for i in xrange(0,self.num_skins):
- self.skins.append(md2_skin())
-
- self.num_vertices=data[6]
-
- #make the # of texture coordinates for model
- self.num_tex_coords=data[7]
- for i in xrange(0,self.num_tex_coords):
- self.tex_coords.append(md2_tex_coord())
-
- #make the # of triangle faces for model
- self.num_faces=data[8]
- for i in xrange(0,self.num_faces):
- self.faces.append(md2_face())
-
- self.num_GL_commands=data[9]
-
- #make the # of frames for the model
- self.num_frames=data[10]
- for i in xrange(0,self.num_frames):
- self.frames.append(md2_alias_frame())
- #make the # of vertices for each frame
- for j in xrange(0,self.num_vertices):
- self.frames[i].vertices.append(md2_alias_triangle())
-
- self.offset_skins=data[11]
- self.offset_tex_coords=data[12]
- self.offset_faces=data[13]
- self.offset_frames=data[14]
- self.offset_GL_commands=data[15]
-
- #load the skin info
- file.seek(self.offset_skins,0)
- for i in xrange(0, self.num_skins):
- self.skins[i].load(file)
- #self.skins[i].dump()
-
- #load the texture coordinates
- file.seek(self.offset_tex_coords,0)
- for i in xrange(0, self.num_tex_coords):
- self.tex_coords[i].load(file)
- #self.tex_coords[i].dump()
-
- #load the face info
- file.seek(self.offset_faces,0)
- for i in xrange(0, self.num_faces):
- self.faces[i].load(file)
- #self.faces[i].dump()
-
- #load the frames
- file.seek(self.offset_frames,0)
- for i in xrange(0, self.num_frames):
- self.frames[i].load(file)
- #self.frames[i].dump()
- for j in xrange(0,self.num_vertices):
- self.frames[i].vertices[j].load(file)
- #self.frames[i].vertices[j].dump()
- return self
-
- def dump (self):
- print "Header Information"
- print "ident: ", self.ident
- print "version: ", self.version
- print "skin width: ", self.skin_width
- print "skin height: ", self.skin_height
- print "frame size: ", self.frame_size
- print "number of skins: ", self.num_skins
- print "number of texture coordinates: ", self.num_tex_coords
- print "number of faces: ", self.num_faces
- print "number of frames: ", self.num_frames
- print "number of vertices: ", self.num_vertices
- print "offset skins: ", self.offset_skins
- print "offset texture coordinates: ", self.offset_tex_coords
- print "offset faces: ", self.offset_faces
- print "offset frames: ",self.offset_frames
- print ""
-
-######################################################
-# Import functions
-######################################################
-def load_textures(md2, texture_filename):
- #did the user specify a texture they wanted to use?
- if texture_filename:
- if (Blender.sys.exists(texture_filename)):
- try: return Blender.Image.Load(texture_filename)
- except: return -1 # could not load?
-
- #does the model have textures specified with it?
- if int(md2.num_skins) > 0:
- for i in xrange(0,md2.num_skins):
- #md2.skins[i].dump()
- if (Blender.sys.exists(md2.skins[i].name)):
- try: return Blender.Image.Load(md2.skins[i].name)
- except: return -1
-
-
-def animate_md2(md2, mesh):
- ######### Animate the verts through keyframe animation
-
- # Fast access to the meshes vertex coords
- verts = [v.co for v in mesh.verts]
- scale = g_scale.val
-
- for i in xrange(1, md2.num_frames):
- frame = md2.frames[i]
- #update the vertices
- for j in xrange(md2.num_vertices):
- x=(frame.scale[0] * frame.vertices[j].vertices[0] + frame.translate[0]) * scale
- y=(frame.scale[1] * frame.vertices[j].vertices[1] + frame.translate[1]) * scale
- z=(frame.scale[2] * frame.vertices[j].vertices[2] + frame.translate[2]) * scale
-
- #put the vertex in the right spot
- verts[j][:] = y,-x,z
-
- mesh.insertKey(i,"absolute")
- # mesh.insertKey(i)
-
- #not really necissary, but I like playing with the frame counter
- Blender.Set("curframe", i)
-
-
- # Make the keys animate in the 3d view.
- key = mesh.key
- key.relative = False
-
- # Add an IPO to teh Key
- ipo = Blender.Ipo.New('Key', 'md2')
- key.ipo = ipo
- # Add a curve to the IPO
- curve = ipo.addCurve('Basis')
-
- # Add 2 points to cycle through the frames.
- curve.append((1, 0))
- curve.append((md2.num_frames, (md2.num_frames-1)/10.0))
- curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
-
-
-
-def load_md2(md2_filename, texture_filename):
- #read the file in
- file=open(md2_filename,"rb")
- WaitCursor(1)
- DrawProgressBar(0.0, 'Loading MD2')
- md2=md2_obj()
- md2.load(file)
- #md2.dump()
- file.close()
-
- ######### Creates a new mesh
- mesh = Mesh.New()
-
- uv_coord=[]
- #uv_list=[]
- verts_extend = []
- #load the textures to use later
- #-1 if there is no texture to load
- mesh_image=load_textures(md2, texture_filename)
- if mesh_image == -1 and texture_filename:
- print 'MD2 Import, Warning, texture "%s" could not load'
-
- ######### Make the verts
- DrawProgressBar(0.25,"Loading Vertex Data")
- frame = md2.frames[0]
- scale = g_scale.val
-
- def tmp_get_vertex(i):
- #use the first frame for the mesh vertices
- x=(frame.scale[0]*frame.vertices[i].vertices[0]+frame.translate[0])*scale
- y=(frame.scale[1]*frame.vertices[i].vertices[1]+frame.translate[1])*scale
- z=(frame.scale[2]*frame.vertices[i].vertices[2]+frame.translate[2])*scale
- return y,-x,z
-
- mesh.verts.extend( [tmp_get_vertex(i) for i in xrange(0,md2.num_vertices)] )
- del tmp_get_vertex
-
- ######## Make the UV list
- DrawProgressBar(0.50,"Loading UV Data")
-
- w = float(md2.skin_width)
- h = float(md2.skin_height)
- if w <= 0.0: w = 1.0
- if h <= 0.0: h = 1.0
- #for some reason quake2 texture maps are upside down, flip that
- uv_list = [Vector(co.u/w, 1-(co.v/h)) for co in md2.tex_coords]
- del w, h
-
- ######### Make the faces
- DrawProgressBar(0.75,"Loading Face Data")
- faces = []
- face_uvs = []
- for md2_face in md2.faces:
- f = md2_face.vertex_index[0], md2_face.vertex_index[2], md2_face.vertex_index[1]
- uv = uv_list[md2_face.texture_index[0]], uv_list[md2_face.texture_index[2]], uv_list[md2_face.texture_index[1]]
-
- if f[2] == 0:
- # EEKADOODLE :/
- f= f[1], f[2], f[0]
- uv= uv[1], uv[2], uv[0]
-
- #ditto in reverse order with the texture verts
- faces.append(f)
- face_uvs.append(uv)
-
-
- face_mapping = mesh.faces.extend(faces, indexList=True)
- print len(faces)
- print len(mesh.faces)
- mesh.faceUV= True #turn on face UV coordinates for this mesh
- mesh_faces = mesh.faces
- for i, uv in enumerate(face_uvs):
- if face_mapping[i] != None:
- f = mesh_faces[face_mapping[i]]
- f.uv = uv
- if (mesh_image!=-1):
- f.image=mesh_image
-
- scn= Blender.Scene.GetCurrent()
- mesh_obj= scn.objects.new(mesh)
- animate_md2(md2, mesh)
- DrawProgressBar(0.98,"Loading Animation Data")
-
- #locate the Object containing the mesh at the cursor location
- cursor_pos=Blender.Window.GetCursorPos()
- mesh_obj.setLocation(float(cursor_pos[0]),float(cursor_pos[1]),float(cursor_pos[2]))
- DrawProgressBar (1.0, "")
- WaitCursor(0)
-
-#***********************************************
-# MAIN
-#***********************************************
-
-# Import globals
-g_md2_filename=Create("*.md2")
-#g_md2_filename=Create("/d/warvet/tris.md2")
-g_texture_filename=Create('')
-# g_texture_filename=Create("/d/warvet/warvet.jpg")
-
-g_filename_search=Create("*.md2")
-g_texture_search=Create('')
-# g_texture_search=Create("/d/warvet/warvet.jpg")
-
-#Globals
-g_scale=Create(1.0)
-
-# Events
-EVENT_NOEVENT=1
-EVENT_LOAD_MD2=2
-EVENT_CHOOSE_FILENAME=3
-EVENT_CHOOSE_TEXTURE=4
-EVENT_SAVE_MD2=5
-EVENT_EXIT=100
-
-######################################################
-# Callbacks for Window functions
-######################################################
-def filename_callback(input_filename):
- global g_md2_filename
- g_md2_filename.val=input_filename
-
-def texture_callback(input_texture):
- global g_texture_filename
- g_texture_filename.val=input_texture
-
-######################################################
-# GUI Loader
-######################################################
-
-
-def draw_gui():
- global g_scale
- global g_md2_filename
- global g_texture_filename
- global EVENT_NOEVENT,EVENT_LOAD_MD2,EVENT_CHOOSE_FILENAME,EVENT_CHOOSE_TEXTURE,EVENT_EXIT
-
- ########## Titles
- glClear(GL_COLOR_BUFFER_BIT)
- glRasterPos2d(8, 125)
- Text("MD2 loader")
-
- ######### Parameters GUI Buttons
- BeginAlign()
- g_md2_filename = String("MD2 file to load: ", EVENT_NOEVENT, 10, 55, 210, 18,
- g_md2_filename.val, 255, "MD2 file to load")
- ########## MD2 File Search Button
- Button("Browse",EVENT_CHOOSE_FILENAME,220,55,80,18)
- EndAlign()
-
- BeginAlign()
- g_texture_filename = String("Texture file to load: ", EVENT_NOEVENT, 10, 35, 210, 18,
- g_texture_filename.val, 255, "Texture file to load-overrides MD2 file")
- ########## Texture Search Button
- Button("Browse",EVENT_CHOOSE_TEXTURE,220,35,80,18)
- EndAlign()
-
- ########## Scale slider-default is 1/8 which is a good scale for md2->blender
- g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 75, 210, 18,
- 1.0, 0.001, 10.0, 1, "Scale factor for obj Model");
-
- ######### Draw and Exit Buttons
- Button("Load",EVENT_LOAD_MD2 , 10, 10, 80, 18)
- Button("Exit",EVENT_EXIT , 170, 10, 80, 18)
-
-def event(evt, val):
- if (evt == QKEY and not val):
- Blender.Draw.Exit()
-
-def bevent(evt):
- global g_md2_filename
- global g_texture_filename
- global EVENT_NOEVENT,EVENT_LOAD_MD2,EVENT_SAVE_MD2,EVENT_EXIT
-
- ######### Manages GUI events
- if (evt==EVENT_EXIT):
- Blender.Draw.Exit()
- elif (evt==EVENT_CHOOSE_FILENAME):
- FileSelector(filename_callback, "MD2 File Selection")
- elif (evt==EVENT_CHOOSE_TEXTURE):
- FileSelector(texture_callback, "Texture Selection")
- elif (evt==EVENT_LOAD_MD2):
- if not Blender.sys.exists(g_md2_filename.val):
- PupMenu('Model file does not exist')
- return
- else:
- load_md2(g_md2_filename.val, g_texture_filename.val)
- Blender.Redraw()
- Blender.Draw.Exit()
- return
-
-if __name__ == '__main__':
- Register(draw_gui, event, bevent)
diff --git a/release/scripts/mesh_boneweight_copy.py b/release/scripts/mesh_boneweight_copy.py
deleted file mode 100644
index d2a477fbc0b..00000000000
--- a/release/scripts/mesh_boneweight_copy.py
+++ /dev/null
@@ -1,287 +0,0 @@
-#!BPY
-"""
-Name: 'Bone Weight Copy'
-Blender: 245
-Group: 'Object'
-Tooltip: 'Copy Bone Weights from 1 mesh, to all other selected meshes.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Bone Weight Copy
-
-This script is used to copy bone weights from 1 mesh with weights (the source mesh) to many (the target meshes).
-Weights are copied from 1 mesh to another based on how close they are together.
-
-For normal operation, select 1 source mesh with vertex weights and any number of unweighted meshes that overlap the source mesh.
-Then run this script using default options and check the new weigh.
-
-
-A differnt way to use this script is to update the weights an an alredy weighted mesh.
-this is done using the "Copy to Selected" option enabled and works a bit differently,
-With the target mesh, select the verts you want to update.
-since all meshes have weights we cant just use the weighted mesh as the source,
-so the Active Object is used for the source mesh.
-Run the script and the selected verts on all non active meshes will be updated.
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Armature, Object, Mathutils, Window, Mesh
-Vector= Mathutils.Vector
-SMALL_NUM= 0.000001
-def copy_bone_influences(_from, _to, PREF_SEL_ONLY, PREF_NO_XCROSS):
- ob_from, me_from, world_verts_from, from_groups= _from
- ob_to, me_to, world_verts_to, dummy= _to
- del dummy
-
- def getSnapIdx(seek_vec, vecs):
- '''
- Returns the closest vec to snap_points
- '''
-
- # First seek the closest Z axis vert idx/v
- seek_vec_x,seek_vec_y,seek_vec_z= seek_vec
-
- from_vec_idx= 0
-
- len_vecs= len(vecs)
-
- upidx= len_vecs-1
- loidx= 0
-
- while from_vec_idx < len_vecs and vecs[from_vec_idx][1].z < seek_vec_z:
- from_vec_idx+=1
-
- # Clamp if we overstepped.
- if from_vec_idx >= len_vecs:
- from_vec_idx-=1
-
- close_dist= (vecs[from_vec_idx][1]-seek_vec).length
- close_idx= vecs[from_vec_idx][0]
-
- upidx= from_vec_idx+1
- loidx= from_vec_idx-1
-
- # Set uselo/useup. This means we can keep seeking up/down.
- if upidx >= len_vecs: useup= False
- else: useup= True
-
- if loidx < 0: uselo= False
- else: uselo= True
-
- # Seek up/down to find the closest v to seek vec.
- while uselo or useup:
- if useup:
- if upidx >= len_vecs:
- useup= False
- else:
- i,v= vecs[upidx]
- if (not PREF_NO_XCROSS) or ((v.x >= -SMALL_NUM and seek_vec_x >= -SMALL_NUM) or (v.x <= SMALL_NUM and seek_vec_x <= SMALL_NUM)): # enfoce xcrossing
- if v.z-seek_vec_z > close_dist:
- # the verticle distance is greater then the best distance sofar. we can stop looking up.
- useup= False
- elif abs(seek_vec_y-v.y) < close_dist and abs(seek_vec_x-v.x) < close_dist:
- # This is in the limit measure it.
- l= (seek_vec-v).length
- if l<close_dist:
- close_dist= l
- close_idx= i
- upidx+=1
-
- if uselo:
-
- if loidx == 0:
- uselo= False
- else:
- i,v= vecs[loidx]
- if (not PREF_NO_XCROSS) or ((v.x >= -SMALL_NUM and seek_vec_x >= -SMALL_NUM) or (v.x <= SMALL_NUM and seek_vec_x <= SMALL_NUM)): # enfoce xcrossing
- if seek_vec_z-v.z > close_dist:
- # the verticle distance is greater then the best distance sofar. we can stop looking up.
- uselo= False
- elif abs(seek_vec_y-v.y) < close_dist and abs(seek_vec_x-v.x) < close_dist:
- # This is in the limit measure it.
- l= (seek_vec-v).length
- if l<close_dist:
- close_dist= l
- close_idx= i
- loidx-=1
-
- return close_idx
-
-
- to_groups= me_to.getVertGroupNames() # if not PREF_SEL_ONLY will always be []
- from_groups= me_from.getVertGroupNames()
-
- if PREF_SEL_ONLY: # remove selected verts from all groups.
- vsel= [v.index for v in me_to.verts if v.sel]
- for group in to_groups:
- me_to.removeVertsFromGroup(group, vsel)
- else: # Add all groups.
- for group in from_groups:
- me_to.addVertGroup(group)
-
- add_ = Mesh.AssignModes.ADD
-
- for i, co in enumerate(world_verts_to):
- if (not PREF_SEL_ONLY) or (PREF_SEL_ONLY and me_to.verts[i].sel):
-
- Window.DrawProgressBar(0.99 * (i/float(len(world_verts_to))), 'Copy "%s" -> "%s" ' % (ob_from.name, ob_to.name))
-
- from_idx= getSnapIdx(co, world_verts_from)
- from_infs= me_from.getVertexInfluences(from_idx)
-
- for group, weight in from_infs:
-
- # Add where needed.
- if PREF_SEL_ONLY and group not in to_groups:
- me_to.addVertGroup(group)
- to_groups.append(group)
-
- me_to.assignVertsToGroup(group, [i], weight, add_)
-
- me_to.update()
-
-# ZSORT return (i/co) tuples, used for fast seeking of the snapvert.
-def worldspace_verts_idx(me, ob):
- mat= ob.matrixWorld
- verts_zsort= [ (i, v.co*mat) for i, v in enumerate(me.verts) ]
-
- # Sorts along the Z Axis so we can optimize the getsnap.
- try: verts_zsort.sort(key = lambda a: a[1].z)
- except: verts_zsort.sort(lambda a,b: cmp(a[1].z, b[1].z,))
-
- return verts_zsort
-
-
-def worldspace_verts(me, ob):
- mat= ob.matrixWorld
- return [ v.co*mat for v in me.verts ]
-
-def subdivMesh(me, subdivs):
- oldmode = Mesh.Mode()
- Mesh.Mode(Mesh.SelectModes['FACE'])
- me.sel= 1
- for i in xrange(subdivs):
- me.subdivide(0)
- Mesh.Mode(oldmode)
-
-
-def main():
- print '\nStarting BoneWeight Copy...'
- scn= Blender.Scene.GetCurrent()
- contextSel= Object.GetSelected()
- if not contextSel:
- Blender.Draw.PupMenu('Error%t|2 or more mesh objects need to be selected.|aborting.')
- return
-
- PREF_QUALITY= Blender.Draw.Create(0)
- PREF_NO_XCROSS= Blender.Draw.Create(0)
- PREF_SEL_ONLY= Blender.Draw.Create(0)
-
- pup_block = [\
- ('Quality:', PREF_QUALITY, 0, 4, 'Generate interpolated verts for a higher quality result.'),\
- ('No X Crossing', PREF_NO_XCROSS, 'Do not snap across the zero X axis'),\
- '',\
- '"Update Selected" copies',\
- 'active object weights to',\
- 'selected verts on the other',\
- 'selected mesh objects.',\
- ('Update Selected', PREF_SEL_ONLY, 'Only copy new weights to selected verts on the target mesh. (use active object as source)'),\
- ]
-
-
- if not Blender.Draw.PupBlock("Copy Weights for %i Meshs" % len(contextSel), pup_block):
- return
-
- PREF_SEL_ONLY= PREF_SEL_ONLY.val
- PREF_NO_XCROSS= PREF_NO_XCROSS.val
- quality= PREF_QUALITY.val
-
- act_ob= scn.objects.active
- if PREF_SEL_ONLY and act_ob==None:
- Blender.Draw.PupMenu('Error%t|When dealing with 2 or more meshes with vgroups|There must be an active object|to be used as a source|aborting.')
- return
-
- sel=[]
- from_data= None
-
- for ob in contextSel:
- if ob.type=='Mesh':
- me= ob.getData(mesh=1)
- groups= me.getVertGroupNames()
-
- # If this is the only mesh with a group OR if its one of many, but its active.
- if groups and ((ob==act_ob and PREF_SEL_ONLY) or (not PREF_SEL_ONLY)):
- if from_data:
- Blender.Draw.PupMenu('More then 1 mesh has vertex weights, only select 1 mesh with weights. aborting.')
- return
- else:
- # This uses worldspace_verts_idx which gets (idx,co) pairs, then zsorts.
- if quality:
- for _ob in contextSel:
- _ob.sel=0
- ob.sel=1
- Object.Duplicate(mesh=1)
- ob= scn.objects.active
- me= ob.getData(mesh=1)
- # groups will be the same
- print '\tGenerating higher %ix quality weights.' % quality
- subdivMesh(me, quality)
- scn.unlink(ob)
- from_data= (ob, me, worldspace_verts_idx(me, ob), groups)
-
- else:
- data= (ob, me, worldspace_verts(me, ob), groups)
- sel.append(data)
-
- if not from_data:
- Blender.Draw.PupMenu('Error%t|No mesh with vertex groups found.')
- return
-
- if not sel:
- Blender.Draw.PupMenu('Error%t|Select 2 or more mesh objects, aborting.')
- if quality: from_data[1].verts= None
- return
-
- t= Blender.sys.time()
- Window.WaitCursor(1)
-
- # Now do the copy.
- print '\tCopying from "%s" to %i other mesh(es).' % (from_data[0].name, len(sel))
- for data in sel:
- copy_bone_influences(from_data, data, PREF_SEL_ONLY, PREF_NO_XCROSS)
-
- # We cant unlink the mesh, but at least remove its data.
- if quality:
- from_data[1].verts= None
-
- print 'Copy Complete in %.6f sec' % (Blender.sys.time()-t)
- Window.DrawProgressBar(1.0, '')
- Window.WaitCursor(0)
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/mesh_cleanup.py b/release/scripts/mesh_cleanup.py
deleted file mode 100644
index 27adca335cb..00000000000
--- a/release/scripts/mesh_cleanup.py
+++ /dev/null
@@ -1,456 +0,0 @@
-#!BPY
-"""
-Name: 'Clean Meshes'
-Blender: 245
-Group: 'Mesh'
-Tooltip: 'Clean unused data from all selected mesh objects.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-Clean Meshes
-
-Cleans unused data from selected meshes
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import *
-import bpy
-from Blender.Mathutils import TriangleArea
-
-import Blender
-import BPyMesh
-dict2MeshWeight= BPyMesh.dict2MeshWeight
-meshWeight2Dict= BPyMesh.meshWeight2Dict
-
-def rem_free_verts(me):
- vert_users= [0] * len(me.verts)
- for f in me.faces:
- for v in f:
- vert_users[v.index]+=1
-
- for e in me.edges:
- for v in e: # loop on edge verts
- vert_users[v.index]+=1
-
- verts_free= [i for i, users in enumerate(vert_users) if not users]
-
- if verts_free:
- pass
- me.verts.delete(verts_free)
- return len(verts_free)
-
-def rem_free_edges(me, limit=None):
- ''' Only remove based on limit if a limit is set, else remove all '''
-
- edgeDict= {} # will use a set when python 2.4 is standard.
-
- for f in me.faces:
- for edkey in f.edge_keys:
- edgeDict[edkey] = None
-
- edges_free= []
- for e in me.edges:
- if not edgeDict.has_key(e.key):
- edges_free.append(e)
-
- if limit != None:
- edges_free= [e for e in edges_free if e.length <= limit]
-
- me.edges.delete(edges_free)
- return len(edges_free)
-
-def rem_area_faces(me, limit=0.001):
- ''' Faces that have an area below the limit '''
- rem_faces= [f for f in me.faces if f.area <= limit]
- if rem_faces:
- me.faces.delete( 0, rem_faces )
- return len(rem_faces)
-
-def rem_perimeter_faces(me, limit=0.001):
- ''' Faces whos combine edge length is below the limit '''
- def faceEdLen(f):
- v= f.v
- if len(v) == 3:
- return\
- (v[0].co-v[1].co).length +\
- (v[1].co-v[2].co).length +\
- (v[2].co-v[0].co).length
- else: # 4
- return\
- (v[0].co-v[1].co).length +\
- (v[1].co-v[2].co).length +\
- (v[2].co-v[3].co).length +\
- (v[3].co-v[0].co).length
- rem_faces= [f for f in me.faces if faceEdLen(f) <= limit]
- if rem_faces:
- me.faces.delete( 0, rem_faces )
- return len(rem_faces)
-
-def rem_unused_materials(me):
- materials= me.materials
- len_materials= len(materials)
- if len_materials < 2:
- return 0
-
- rem_materials= 0
-
- material_users= dict( [(i,0) for i in xrange(len_materials)] )
-
- for f in me.faces:
- f_mat = f.mat
- # Make sure the face index isnt too big. this happens sometimes.
- if f_mat >= len_materials:
- f_mat = f.mat = 0
- material_users[f_mat] += 1
-
- # mat_idx_subtract= 0
- # reindex_mapping= dict( [(i,0) for i in xrange(len_materials)] )
-
- reindex_mapping_ls = range(len_materials)
- for i in range(len_materials-1, -1, -1):
- if material_users[i] == 0:
- del reindex_mapping_ls[i]
- del materials[i]
- rem_materials+=1
-
- reindex_mapping= {}
-
- for i, mat in enumerate(reindex_mapping_ls):
- reindex_mapping[mat] = i
-
- for f in me.faces:
- f.mat= reindex_mapping[f.mat]
-
- me.materials= materials
- return rem_materials
-
-
-def rem_free_groups(me, groupNames, vWeightDict):
- ''' cound how many vert users a group has and remove unused groups '''
- rem_groups = 0
- groupUserDict= dict([(group,0) for group in groupNames])
-
- for vertexWeight in vWeightDict:
- for group, weight in vertexWeight.iteritems():
- groupUserDict[group] += 1
-
- i=len(groupNames)
- while i:
- i-=1
- group= groupNames[i]
- if groupUserDict[group] == 0:
- del groupNames[i]
- print '\tremoving, vgroup', group
- rem_groups+=1
- return rem_groups
-
-def rem_zero_weights(me, limit, groupNames, vWeightDict):
- ''' remove verts from a group when their weight is zero.'''
- rem_vweight_count= 0
- for vertexWeight in vWeightDict:
- items= vertexWeight.items()
- for group, weight in items:
- if weight < limit:
- del vertexWeight[group]
- rem_vweight_count+= 1
-
- return rem_vweight_count
-
-
-def normalize_vweight(me, groupNames, vWeightDict):
- for vertexWeight in vWeightDict:
- unit= 0.0
- for group, weight in vertexWeight.iteritems():
- unit+= weight
-
- if unit != 1.0 and unit != 0.0:
- for group, weight in vertexWeight.iteritems():
- vertexWeight[group]= weight/unit
-
-def isnan(f):
- fstring = str(f).lower()
- if 'nan' in fstring:
- return True
- if 'inf' in fstring:
- return True
-
- return False
-
-def fix_nan_verts__internal(me):
- rem_nan = 0
- for v in me.verts:
- co = v.co
- for i in (0,1,2):
- if isnan(co[i]):
- co[i] = 0.0
- rem_nan += 1
- return rem_nan
-
-def fix_nan_verts(me):
- rem_nan = 0
- key = me.key
- if key:
- # Find the object, and get a mesh thats thinked to the oblink.
- # this is a bit crap but needed to set the active key.
- me_oblink = None
- for ob in bpy.data.objects:
- me_oblink = ob.getData(mesh=1)
- if me_oblink == me:
- me = me_oblink
- break
- if not me_oblink:
- ob = None
-
- if key and ob:
- blocks = key.blocks
- # print blocks
- orig_pin = ob.pinShape
- orig_shape = ob.activeShape
- orig_relative = key.relative
- ob.pinShape = True
- for i, block in enumerate(blocks):
- ob.activeShape = i+1
- ob.makeDisplayList()
- rem_nan += fix_nan_verts__internal(me)
- me.update(block.name) # get the new verts
- ob.pinShape = orig_pin
- ob.activeShape = orig_shape
- key.relative = orig_relative
-
- else: # No keys, simple operation
- rem_nan = fix_nan_verts__internal(me)
-
- return rem_nan
-
-def fix_nan_uvs(me):
- rem_nan = 0
- if me.faceUV:
- orig_uvlayer = me.activeUVLayer
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- for f in me.faces:
- for uv in f.uv:
- for i in (0,1):
- if isnan(uv[i]):
- uv[i] = 0.0
- rem_nan += 1
- me.activeUVLayer = orig_uvlayer
- return rem_nan
-
-
-def has_vcol(me):
- for f in me.faces:
- for col in f.col:
- if not (255 == col.r == col.g == col.b):
- return True
- return False
-
-def rem_white_vcol_layers(me):
- vcols_removed = 0
- if me.vertexColors:
- for col in me.getColorLayerNames():
- me.activeColorLayer = col
- if not has_vcol(me):
- me.removeColorLayer(col)
- vcols_removed += 1
-
- return vcols_removed
-
-
-def main():
- sce= bpy.data.scenes.active
- obsel= list(sce.objects.context)
- actob= sce.objects.active
-
- is_editmode= Window.EditMode()
-
- # Edit mode object is not active, add it to the list.
- if is_editmode and (not actob.sel):
- obsel.append(actob)
-
-
- #====================================#
- # Popup menu to select the functions #
- #====================================#
-
- CLEAN_ALL_DATA= Draw.Create(0)
- CLEAN_VERTS_FREE= Draw.Create(1)
- CLEAN_EDGE_NOFACE= Draw.Create(0)
- CLEAN_EDGE_SMALL= Draw.Create(0)
- CLEAN_FACE_PERIMETER= Draw.Create(0)
- CLEAN_FACE_SMALL= Draw.Create(0)
-
- CLEAN_MATERIALS= Draw.Create(0)
- CLEAN_WHITE_VCOL_LAYERS= Draw.Create(0)
- CLEAN_GROUP= Draw.Create(0)
- CLEAN_VWEIGHT= Draw.Create(0)
- CLEAN_WEIGHT_NORMALIZE= Draw.Create(0)
- limit= Draw.Create(0.01)
-
- CLEAN_NAN_VERTS= Draw.Create(0)
- CLEAN_NAN_UVS= Draw.Create(0)
-
- # Get USER Options
-
- pup_block= [\
- ('Verts: free', CLEAN_VERTS_FREE, 'Remove verts that are not used by an edge or a face.'),\
- ('Edges: free', CLEAN_EDGE_NOFACE, 'Remove edges that are not in a face.'),\
- ('Edges: short', CLEAN_EDGE_SMALL, 'Remove edges that are below the length limit.'),\
- ('Faces: small perimeter', CLEAN_FACE_PERIMETER, 'Remove faces below the perimeter limit.'),\
- ('Faces: small area', CLEAN_FACE_SMALL, 'Remove faces below the area limit (may remove faces stopping T-face artifacts).'),\
- ('limit: ', limit, 0.001, 1.0, 'Limit for the area and length tests above (a higher limit will remove more data).'),\
- ('Material Clean', CLEAN_MATERIALS, 'Remove unused materials.'),\
- ('Color Layers', CLEAN_WHITE_VCOL_LAYERS, 'Remove vertex color layers that are totaly white'),\
- ('VGroup Clean', CLEAN_GROUP, 'Remove vertex groups that have no verts using them.'),\
- ('Weight Clean', CLEAN_VWEIGHT, 'Remove zero weighted verts from groups (limit is zero threshold).'),\
- ('WeightNormalize', CLEAN_WEIGHT_NORMALIZE, 'Make the sum total of vertex weights accross vgroups 1.0 for each vertex.'),\
- 'Clean NAN values',\
- ('NAN Verts', CLEAN_NAN_VERTS, 'Make NAN or INF verts (0,0,0)'),\
- ('NAN UVs', CLEAN_NAN_UVS, 'Make NAN or INF UVs (0,0)'),\
- '',\
- ('All Mesh Data', CLEAN_ALL_DATA, 'Warning! Operate on ALL mesh objects in your Blend file. Use with care'),\
- ]
-
- if not Draw.PupBlock('Clean Selected Meshes...', pup_block):
- return
-
- CLEAN_VERTS_FREE= CLEAN_VERTS_FREE.val
- CLEAN_EDGE_NOFACE= CLEAN_EDGE_NOFACE.val
- CLEAN_EDGE_SMALL= CLEAN_EDGE_SMALL.val
- CLEAN_FACE_PERIMETER= CLEAN_FACE_PERIMETER.val
- CLEAN_FACE_SMALL= CLEAN_FACE_SMALL.val
- CLEAN_MATERIALS= CLEAN_MATERIALS.val
- CLEAN_WHITE_VCOL_LAYERS= CLEAN_WHITE_VCOL_LAYERS.val
- CLEAN_GROUP= CLEAN_GROUP.val
- CLEAN_VWEIGHT= CLEAN_VWEIGHT.val
- CLEAN_WEIGHT_NORMALIZE= CLEAN_WEIGHT_NORMALIZE.val
- limit= limit.val
- CLEAN_ALL_DATA= CLEAN_ALL_DATA.val
- CLEAN_NAN_VERTS= CLEAN_NAN_VERTS.val
- CLEAN_NAN_UVS= CLEAN_NAN_UVS.val
-
- if is_editmode: Window.EditMode(0)
-
- if CLEAN_ALL_DATA:
- if CLEAN_GROUP or CLEAN_VWEIGHT or CLEAN_WEIGHT_NORMALIZE:
- # For groups we need the objects linked to the mesh
- meshes= [ob.getData(mesh=1) for ob in bpy.data.objects if ob.type == 'Mesh' if not ob.lib]
- else:
- meshes= bpy.data.meshes
- else:
- meshes= [ob.getData(mesh=1) for ob in obsel if ob.type == 'Mesh']
-
- tot_meshes = len(meshes) # so we can decrement libdata
- rem_face_count= rem_edge_count= rem_vert_count= rem_material_count= rem_vcol_layer_count= rem_group_count= rem_vweight_count= fix_nan_vcount= fix_nan_uvcount= 0
- if not meshes:
- if is_editmode: Window.EditMode(1)
- Draw.PupMenu('No meshes to clean')
-
- Blender.Window.WaitCursor(1)
- bpy.data.meshes.tag = False
- for me in meshes:
-
- # Dont touch the same data twice
- if me.tag:
- tot_meshes -= 1
- continue
- me.tag = True
-
- if me.lib:
- tot_meshes -= 1
- continue
-
- if me.multires:
- multires_level_orig = me.multiresDrawLevel
- me.multiresDrawLevel = 1
- print 'Warning, cannot perform destructive operations on multires mesh:', me.name
- else:
- if CLEAN_FACE_SMALL:
- rem_face_count += rem_area_faces(me, limit)
-
- if CLEAN_FACE_PERIMETER:
- rem_face_count += rem_perimeter_faces(me, limit)
-
- if CLEAN_EDGE_SMALL: # for all use 2- remove all edges.
- rem_edge_count += rem_free_edges(me, limit)
-
- if CLEAN_EDGE_NOFACE:
- rem_edge_count += rem_free_edges(me)
-
- if CLEAN_VERTS_FREE:
- rem_vert_count += rem_free_verts(me)
-
- if CLEAN_MATERIALS:
- rem_material_count += rem_unused_materials(me)
-
- if CLEAN_WHITE_VCOL_LAYERS:
- rem_vcol_layer_count += rem_white_vcol_layers(me)
-
- if CLEAN_VWEIGHT or CLEAN_GROUP or CLEAN_WEIGHT_NORMALIZE:
- groupNames, vWeightDict= meshWeight2Dict(me)
-
- if CLEAN_VWEIGHT:
- rem_vweight_count += rem_zero_weights(me, limit, groupNames, vWeightDict)
-
- if CLEAN_GROUP:
- rem_group_count += rem_free_groups(me, groupNames, vWeightDict)
- pass
-
- if CLEAN_WEIGHT_NORMALIZE:
- normalize_vweight(me, groupNames, vWeightDict)
-
- # Copy back to mesh vertex groups.
- dict2MeshWeight(me, groupNames, vWeightDict)
-
- if CLEAN_NAN_VERTS:
- fix_nan_vcount = fix_nan_verts(me)
-
- if CLEAN_NAN_UVS:
- fix_nan_uvcount = fix_nan_uvs(me)
-
- # restore multires.
- if me.multires:
- me.multiresDrawLevel = multires_level_orig
-
- Blender.Window.WaitCursor(0)
- if is_editmode: Window.EditMode(0)
- stat_string= 'Removed from ' + str(tot_meshes) + ' Mesh(es)%t|'
-
- if CLEAN_VERTS_FREE: stat_string+= 'Verts: %i|' % rem_vert_count
- if CLEAN_EDGE_SMALL or CLEAN_EDGE_NOFACE: stat_string+= 'Edges: %i|' % rem_edge_count
- if CLEAN_FACE_SMALL or CLEAN_FACE_PERIMETER: stat_string+= 'Faces: %i|' % rem_face_count
- if CLEAN_MATERIALS: stat_string+= 'Materials: %i|' % rem_material_count
- if CLEAN_WHITE_VCOL_LAYERS: stat_string+= 'Color Layers: %i|' % rem_vcol_layer_count
- if CLEAN_VWEIGHT: stat_string+= 'VWeights: %i|' % rem_vweight_count
- if CLEAN_GROUP: stat_string+= 'VGroups: %i|' % rem_group_count
- if CLEAN_NAN_VERTS: stat_string+= 'Vert Nan Fix: %i|' % fix_nan_vcount
- if CLEAN_NAN_UVS: stat_string+= 'UV Nan Fix: %i|' % fix_nan_uvcount
- Draw.PupMenu(stat_string)
-
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/mesh_edges2curves.py b/release/scripts/mesh_edges2curves.py
deleted file mode 100644
index 670165dda51..00000000000
--- a/release/scripts/mesh_edges2curves.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!BPY
-""" Registration info for Blender menus:
-Name: 'Edges to Curve'
-Blender: 241
-Group: 'Mesh'
-Tip: 'Edges not used by a face are converted into polyline(s)'
-"""
-__author__ = ("Campbell Barton")
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0 2006/02/08"
-
-__bpydoc__ = """\
-Edges to Curves
-
-This script converts open and closed edge loops into curve polylines
-
-Supported:<br>
- Polylines where each vert has no more then 2 edges attached to it.
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import *
-
-def polysFromMesh(me):
- # a polyline is 2
- #polylines are a list
- polyLines = []
-
- # Get edges not used by a face
- edgeDict= dict([ (ed.key, ed) for ed in me.edges ])
- for f in me.faces:
- for key in f.edge_keys:
- try:
- del edgeDict[key]
- except:
- pass
-
- edges= edgeDict.values()
-
-
- while edges:
- currentEdge= edges.pop()
- startVert= currentEdge.v2
- endVert= currentEdge.v1
- polyLine= [startVert, endVert]
- ok= 1
- while ok:
- ok= 0
- #for i, ed in enumerate(edges):
- i=len(edges)
- while i:
- i-=1
- ed= edges[i]
- if ed.v1 == endVert:
- polyLine.append(ed.v2)
- endVert= polyLine[-1]
- ok=1
- del edges[i]
- #break
- elif ed.v2 == endVert:
- polyLine.append(ed.v1)
- endVert= polyLine[-1]
- ok=1
- del edges[i]
- #break
- elif ed.v1 == startVert:
- polyLine.insert(0, ed.v2)
- startVert= polyLine[0]
- ok=1
- del edges[i]
- #break
- elif ed.v2 == startVert:
- polyLine.insert(0, ed.v1)
- startVert= polyLine[0]
- ok=1
- del edges[i]
- #break
- polyLines.append((polyLine, polyLine[0]==polyLine[-1]))
- # print len(edges), len(polyLines)
- return polyLines
-
-
-def mesh2polys():
- scn= Scene.GetCurrent()
- scn.objects.selected = []
-
- meshOb= scn.objects.active
- if meshOb==None or meshOb.type != 'Mesh':
- Draw.PupMenu( 'ERROR: No Active Mesh Selected, Aborting' )
- return
- Window.WaitCursor(1)
- Window.EditMode(0)
- me = meshOb.getData(mesh=1)
- polygons= polysFromMesh(me)
- w = 1.0
- cu= Curve.New()
- cu.name = me.name
- cu.setFlag(1)
-
- ob = scn.objects.active = scn.objects.new(cu)
- ob.setMatrix(meshOb.matrixWorld)
-
- i=0
- for poly, closed in polygons:
- if closed:
- vIdx= 1
- else:
- vIdx= 0
-
- v= poly[vIdx]
- cu.appendNurb((v.co.x, v.co.y, v.co.z, w))
- vIdx += 1
- cu[i].type= 0 # Poly Line
-
- # Close the polyline if its closed.
- if closed:
- cu[i].setFlagU(1)
-
- # Add all the points in the polyline.
- while vIdx<len(poly):
- v= poly[vIdx]
- cu.appendPoint(i, (v.co.x, v.co.y, v.co.z, w))
- vIdx+=1
- i+=1
- Window.WaitCursor(0)
-
-# not used as yet.
-"""
-def writepolys():
- me = Scene.GetCurrent().getActiveObject().getData(mesh=1)
- polygons= polysFromMesh(me)
- file=open('/polygons.txt', 'w')
- for ply in polygons:
- file.write('polygon ')
- if ply[1]:
- file.write('closed ')
- else:
- file.write('open ')
- file.write('%i\n' % len(ply[0]))
- for pt in ply[0]:
- file.write('%.6f %.6f %.6f\n' % tuple(pt.co) )
- file.close()
-"""
-
-if __name__ == '__main__':
- mesh2polys()
diff --git a/release/scripts/mesh_mirror_tool.py b/release/scripts/mesh_mirror_tool.py
deleted file mode 100644
index 8e22e26cd53..00000000000
--- a/release/scripts/mesh_mirror_tool.py
+++ /dev/null
@@ -1,352 +0,0 @@
-#!BPY
-"""
-Name: 'Mirror Vertex Locations & Weight'
-Blender: 241
-Group: 'Mesh'
-Tooltip: 'Snap Verticies to X mirrored locations and weights.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__= '1.0'
-__bpydoc__= '''\
-This script is used to mirror vertex locations and weights
-It is useful if you have a model that was made symmetrical
-but has verts that have moved from their mirrored locations slightly,
-causing blenders X-Mirror options not to work.
-
-Weights can be mirrored too, this is useful if you want to model 1 side of a mesh, copy the mesh and flip it.
-You can then use this script to mirror to the copy, even creating new flipped vertex groups, renaming group name left to right or .L to .R
-
-Vertex positions are mirrored by doing a locational lookup,
-finding matching verts on both sides of a mesh and moving to the left/right or mid location.
-
-The vertex weights work differently, they are mirrored my location also,
-but they mirror in pairs, rather it works by finding the closest vertex on the flip side and using its weight.
-
-When a location mirror is finished, verts that have not been mirrored will remain selected.
-a good way to check both sides are mirrord is to select the mirrored parts,
-run this script with default options and then see of there are any selected verts.
-
-For details on each option read the tooltips.
-'''
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import Draw, Window, Scene, Mesh, Mathutils, sys, Object
-import BPyMesh
-
-BIGNUM= 1<<30
-
-def mesh_mirror(me, PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES):
- '''
- PREF_MIRROR_LOCATION, Will we mirror locations?
- PREF_XMID_SNAP, Should we snap verts to X-0?
- PREF_MAX_DIST, Maximum distance to test snapping verts.
- PREF_XZERO_THRESH, How close verts must be to the middle before they are considered X-Zero verts.
- PREF_MODE, 0:middle, 1: Left. 2:Right.
- PREF_SEL_ONLY, only snap the selection
- PREF_EDGE_USERS, match only verts with the same number of edge users.
- PREF_MIRROR_LOCATION,
- '''
-
-
- # Operate on all verts
- if not PREF_SEL_ONLY:
- for v in me.verts:
- v.sel=1
-
-
- if PREF_EDGE_USERS:
- edge_users= [0]*len(me.verts)
- for ed in me.edges:
- edge_users[ed.v1.index]+=1
- edge_users[ed.v2.index]+=1
-
-
-
- if PREF_XMID_SNAP: # Do we snap locations at all?
- for v in me.verts:
- if v.sel:
- if abs(v.co.x) <= PREF_XZERO_THRESH:
- v.co.x= 0
- v.sel= 0
-
- # alredy de-selected verts
- neg_vts = [v for v in me.verts if v.sel and v.co.x < 0]
- pos_vts = [v for v in me.verts if v.sel and v.co.x > 0]
-
- else:
- # Use a small margin verts must be outside before we mirror them.
- neg_vts = [v for v in me.verts if v.sel if v.co.x < -PREF_XZERO_THRESH]
- pos_vts = [v for v in me.verts if v.sel if v.co.x > PREF_XZERO_THRESH]
-
-
-
- #*Mirror Location*********************************************************#
- if PREF_MIRROR_LOCATION:
- mirror_pairs= []
- # allign the negative with the positive.
- flipvec= Mathutils.Vector()
- len_neg_vts= float(len(neg_vts))
- for i1, nv in enumerate(neg_vts):
- if nv.sel: # we may alredy be mirrored, if so well be deselected
- nv_co= nv.co
- for i2, pv in enumerate(pos_vts):
- if pv.sel:
- # Enforce edge users.
- if not PREF_EDGE_USERS or edge_users[i1]==edge_users[i2]:
- flipvec[:]= pv.co
- flipvec.x= -flipvec.x
- l= (nv_co-flipvec).length
-
- if l==0.0: # Both are alredy mirrored so we dont need to think about them.
- # De-Select so we dont use again/
- pv.sel= nv.sel= 0
-
- # Record a match.
- elif l<=PREF_MAX_DIST:
-
- # We can adjust the length by the normal, now we know the length is under the limit.
- # DISABLED, WASNT VERY USEFULL
- '''
- if PREF_NOR_WEIGHT>0:
- # Get the normal and flipm reuse flipvec
- flipvec[:]= pv.no
- flipvec.x= -flipvec.x
- try:
- ang= Mathutils.AngleBetweenVecs(nv.no, flipvec)/180.0
- except: # on rare occasions angle between vecs will fail.- zero length vec.
- ang= 0
-
- l=l*(1+(ang*PREF_NOR_WEIGHT))
- '''
- # Record the pairs for sorting to see who will get joined
- mirror_pairs.append((l, nv, pv))
-
- # Update every 20 loops
- if i1 % 10 == 0:
- Window.DrawProgressBar(0.8 * (i1/len_neg_vts), 'Mirror verts %i of %i' % (i1, len_neg_vts))
-
- Window.DrawProgressBar(0.9, 'Mirror verts: Updating locations')
-
- # Now we have a list of the pairs we might use, lets find the best and do them first.
- # de-selecting as we go. so we can makke sure not to mess it up.
- try: mirror_pairs.sort(key = lambda a: a[0])
- except: mirror_pairs.sort(lambda a,b: cmp(a[0], b[0]))
-
- for dist, v1,v2 in mirror_pairs: # dist, neg, pos
- if v1.sel and v2.sel:
- if PREF_MODE==0: # Middle
- flipvec[:]= v2.co # positive
- flipvec.x= -flipvec.x # negatve
- v2.co= v1.co= (flipvec+v1.co)*0.5 # midway
- v2.co.x= -v2.co.x
- elif PREF_MODE==2: # Left
- v2.co= v1.co
- v2.co.x= -v2.co.x
- elif PREF_MODE==1: # Right
- v1.co= v2.co
- v1.co.x= -v1.co.x
- v1.sel= v2.sel= 0
-
-
- #*Mirror Weights**********************************************************#
- if PREF_MIRROR_WEIGHTS:
-
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
- mirror_pairs_l2r= [] # Stor a list of matches for these verts.
- mirror_pairs_r2l= [] # Stor a list of matches for these verts.
-
- # allign the negative with the positive.
- flipvec= Mathutils.Vector()
- len_neg_vts= float(len(neg_vts))
-
- # Here we make a tuple to look through, if were middle well need to look through both.
- if PREF_MODE==0: # Middle
- find_set= ((neg_vts, pos_vts, mirror_pairs_l2r), (pos_vts, neg_vts, mirror_pairs_r2l))
- elif PREF_MODE==1: # Left
- find_set= ((neg_vts, pos_vts, mirror_pairs_l2r), )
- elif PREF_MODE==2: # Right
- find_set= ((pos_vts, neg_vts, mirror_pairs_r2l), )
-
-
- # Do a locational lookup again :/ - This isnt that good form but if we havnt mirrored weights well need to do it anyway.
- # The Difference with this is that we dont need to have 1:1 match for each vert- just get each vert to find another mirrored vert
- # and use its weight.
- # Use "find_set" so we can do a flipped search L>R and R>L without duplicate code.
- for vtls_A, vtls_B, pair_ls in find_set:
- for i1, vA in enumerate(vtls_A):
- best_len=1<<30 # BIGNUM
- best_idx=-1
-
- # Find the BEST match
- vA_co= vA.co
- for i2, vB in enumerate(vtls_B):
- # Enforce edge users.
- if not PREF_EDGE_USERS or edge_users[i1]==edge_users[i2]:
- flipvec[:]= vB.co
- flipvec.x= -flipvec.x
- l= (vA_co-flipvec).length
-
- if l<best_len:
- best_len=l
- best_idx=i2
-
- if best_idx != -1:
- pair_ls.append((vtls_A[i1].index, vtls_B[best_idx].index)) # neg, pos.
-
- # Now we can merge the weights
- if PREF_MODE==0: # Middle
- newVWeightDict= [vWeightDict[i] for i in xrange(len(me.verts))] # Have empty dicts just incase
- for pair_ls in (mirror_pairs_l2r, mirror_pairs_r2l):
- if PREF_FLIP_NAMES:
- for i1, i2 in pair_ls:
- flipWeight, groupNames= BPyMesh.dictWeightFlipGroups( vWeightDict[i2], groupNames, PREF_CREATE_FLIP_NAMES )
- newVWeightDict[i1]= BPyMesh.dictWeightMerge([vWeightDict[i1], flipWeight] )
- else:
- for i1, i2 in pair_ls:
- newVWeightDict[i1]= BPyMesh.dictWeightMerge([vWeightDict[i1], vWeightDict[i2]])
-
- vWeightDict= newVWeightDict
-
- elif PREF_MODE==1: # Left
- if PREF_FLIP_NAMES:
- for i1, i2 in mirror_pairs_l2r:
- vWeightDict[i2], groupNames= BPyMesh.dictWeightFlipGroups(vWeightDict[i1], groupNames, PREF_CREATE_FLIP_NAMES)
- else:
- for i1, i2 in mirror_pairs_l2r:
- vWeightDict[i2]= vWeightDict[i1] # Warning Multiple instances of the same data, its ok in this case but dont modify later.
-
- elif PREF_MODE==2: # Right
- if PREF_FLIP_NAMES:
- for i1, i2 in mirror_pairs_r2l:
- vWeightDict[i2], groupNames= BPyMesh.dictWeightFlipGroups(vWeightDict[i1], groupNames, PREF_CREATE_FLIP_NAMES)
- else:
- for i1, i2 in mirror_pairs_r2l:
- vWeightDict[i2]= vWeightDict[i1] # Warning, ditto above
-
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
-
- me.update()
-
-def main():
- scn = Scene.GetCurrent()
- act_ob= scn.getActiveObject()
- if act_ob.getType()!='Mesh':
- act_ob= None
-
- sel= [ob for ob in Object.GetSelected() if ob.getType()=='Mesh' if ob != act_ob]
- if not sel and not act_ob:
- Draw.PupMenu('Error, select a mesh as your active object')
- return
-
- # Defaults
- PREF_EDITMESH_ONLY= Draw.Create(1)
- PREF_MIRROR_LOCATION= Draw.Create(1)
- PREF_XMID_SNAP= Draw.Create(1)
- PREF_MAX_DIST= Draw.Create(0.02)
- PREF_XZERO_THRESH= Draw.Create(0.002)
-
- #PREF_MODE= Draw.Create(0) # THIS IS TOOO CONFUSING, HAVE 2 BUTTONS AND MAKE THE MODE FROM THEM.
- PREF_MODE_L2R= Draw.Create(1)
- PREF_MODE_R2L= Draw.Create(0)
-
- PREF_SEL_ONLY= Draw.Create(1)
- PREF_EDGE_USERS= Draw.Create(0)
- # Weights
- PREF_MIRROR_WEIGHTS= Draw.Create(0)
- PREF_FLIP_NAMES= Draw.Create(1)
- PREF_CREATE_FLIP_NAMES= Draw.Create(1)
-
- pup_block = [\
- ('EditMesh Only', PREF_EDITMESH_ONLY, 'If disabled, will mirror all selected meshes.'),\
- 'Left (-), Right (+)',\
- ('Left > Right', PREF_MODE_L2R, 'Copy from the Left to Right of the mesh. Enable Both for a mid loc/weight.'),\
- ('Right > Left', PREF_MODE_R2L, 'Copy from the Right to Left of the mesh. Enable Both for a mid loc/weight.'),\
- '',\
- ('MaxDist:', PREF_MAX_DIST, 0.0, 1.0, 'Generate interpolated verts so closer vert weights can be copied.'),\
- ('XZero limit:', PREF_XZERO_THRESH, 0.0, 1.0, 'Mirror verts above this distance from the middle, else lock to X/zero.'),\
- ('Sel Verts Only', PREF_SEL_ONLY, 'Only mirror selected verts. Else try and mirror all'),\
- ('Edge Users', PREF_EDGE_USERS, 'Only match up verts that have the same number of edge users.'),\
- 'Location Prefs',\
- ('Mirror Location', PREF_MIRROR_LOCATION, 'Mirror vertex locations.'),\
- ('XMidSnap Verts', PREF_XMID_SNAP, 'Snap middle verts to X Zero (uses XZero limit)'),\
- 'Weight Prefs',\
- ('Mirror Weights', PREF_MIRROR_WEIGHTS, 'Mirror vertex locations.'),\
- ('Flip Groups', PREF_FLIP_NAMES, 'Mirror flip names.'),\
- ('New Flip Groups', PREF_CREATE_FLIP_NAMES, 'Make new groups for flipped names.'),\
- ]
-
- if not Draw.PupBlock("X Mirror mesh tool", pup_block):
- return
-
- # WORK OUT THE MODE 0
- # PREF_MODE, 0:middle, 1: Left. 2:Right.
- PREF_MODE_R2L= PREF_MODE_R2L.val
- PREF_MODE_L2R= PREF_MODE_L2R.val
-
- if PREF_MODE_R2L and PREF_MODE_L2R:
- PREF_MODE= 0 # Middle
- elif not PREF_MODE_R2L and PREF_MODE_L2R:
- PREF_MODE= 1 # Left to Right
- elif PREF_MODE_R2L and not PREF_MODE_L2R:
- PREF_MODE= 2 # Right to Left
- else: # Neither Selected. Do middle anyway
- PREF_MODE= 0
-
-
- PREF_EDITMESH_ONLY= PREF_EDITMESH_ONLY.val
- PREF_MIRROR_LOCATION= PREF_MIRROR_LOCATION.val
- PREF_XMID_SNAP= PREF_XMID_SNAP.val
- PREF_MAX_DIST= PREF_MAX_DIST.val
- PREF_XZERO_THRESH= PREF_XZERO_THRESH.val
- PREF_SEL_ONLY= PREF_SEL_ONLY.val
- PREF_EDGE_USERS= PREF_EDGE_USERS.val
- # weights
- PREF_MIRROR_WEIGHTS= PREF_MIRROR_WEIGHTS.val
- PREF_FLIP_NAMES= PREF_FLIP_NAMES.val
- PREF_CREATE_FLIP_NAMES= PREF_CREATE_FLIP_NAMES.val
-
- t= sys.time()
-
- is_editmode = Window.EditMode() # Exit Editmode.
- if is_editmode: Window.EditMode(0)
- Mesh.Mode(Mesh.SelectModes['VERTEX'])
- Window.WaitCursor(1)
-
- if act_ob:
- mesh_mirror(act_ob.getData(mesh=1), PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES)
- if (not PREF_EDITMESH_ONLY) and sel:
- for ob in sel:
- mesh_mirror(ob.getData(mesh=1), PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES)
-
- if is_editmode: Window.EditMode(1)
- Window.WaitCursor(0)
- Window.DrawProgressBar(1.0, '')
- Window.RedrawAll()
-
- print 'Mirror done in %.6f sec.' % (sys.time()-t)
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/mesh_poly_reduce.py b/release/scripts/mesh_poly_reduce.py
deleted file mode 100644
index 6dfd7a90efc..00000000000
--- a/release/scripts/mesh_poly_reduce.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#!BPY
-"""
-Name: 'Poly Reducer'
-Blender: 243
-Group: 'Mesh'
-Tooltip: 'Removed polygons from a mesh while maintaining the shape, textures and weights.'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0 2006/02/07"
-
-__bpydoc__ = """\
-This script simplifies the mesh by removing faces, keeping the overall shape of the mesh.
-"""
-
-from Blender import Draw, Window, Scene, Mesh, Mathutils, sys, Object
-import BPyMesh
-# reload(BPyMesh)
-import BPyMessages
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-
-def main():
- scn = Scene.GetCurrent()
- act_ob= scn.objects.active
- if not act_ob or act_ob.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- act_me= act_ob.getData(mesh=1)
-
- if act_me.multires:
- BPyMessages.Error_NoMeshMultiresEdit()
- return
-
- act_group= act_me.activeGroup
- if not act_group: act_group= ''
-
-
- # Defaults
- PREF_REDUX= Draw.Create(0.5)
- PREF_BOUNDRY_WEIGHT= Draw.Create(5.0)
- PREF_REM_DOUBLES= Draw.Create(1)
- PREF_FACE_AREA_WEIGHT= Draw.Create(1.0)
- PREF_FACE_TRIANGULATE= Draw.Create(1)
-
- VGROUP_INF_ENABLE= Draw.Create(0)
- VGROUP_INF_REDUX= Draw.Create(act_group)
- VGROUP_INF_WEIGHT= Draw.Create(10.0)
-
- PREF_DO_UV= Draw.Create(1)
- PREF_DO_VCOL= Draw.Create(1)
- PREF_DO_WEIGHTS= Draw.Create(1)
- PREF_OTHER_SEL_OBS= Draw.Create(0)
-
- pup_block = [\
- ('Poly Reduce:', PREF_REDUX, 0.05, 0.95, 'Scale the meshes poly count by this value.'),\
- ('Boundry Weight:', PREF_BOUNDRY_WEIGHT, 0.0, 20.0, 'Weight boundry verts by this scale, 0.0 for no boundry weighting.'),\
- ('Area Weight:', PREF_FACE_AREA_WEIGHT, 0.0, 20.0, 'Collapse edges effecting lower area faces first.'),\
- ('Triangulate', PREF_FACE_TRIANGULATE, 'Convert quads to tris before reduction, for more choices of edges to collapse.'),\
- '',\
- ('VGroup Weighting', VGROUP_INF_ENABLE, 'Use a vertex group to influence the reduction, higher weights for higher quality '),\
- ('vgroup name: ', VGROUP_INF_REDUX, 0, 32, 'The name of the vertex group to use for the weight map'),\
- ('vgroup mult: ', VGROUP_INF_WEIGHT, 0.0, 100.0, 'How much to make the weight effect the reduction'),\
- ('Other Selected Obs', PREF_OTHER_SEL_OBS, 'reduce other selected objects.'),\
- '',\
- '',\
- '',\
- ('UV Coords', PREF_DO_UV, 'Interpolate UV Coords.'),\
- ('Vert Colors', PREF_DO_VCOL, 'Interpolate Vertex Colors'),\
- ('Vert Weights', PREF_DO_WEIGHTS, 'Interpolate Vertex Weights'),\
- ('Remove Doubles', PREF_REM_DOUBLES, 'Remove doubles before reducing to avoid boundry tearing.'),\
- ]
-
- if not Draw.PupBlock("Poly Reducer", pup_block):
- return
-
- PREF_REDUX= PREF_REDUX.val
- PREF_BOUNDRY_WEIGHT= PREF_BOUNDRY_WEIGHT.val
- PREF_REM_DOUBLES= PREF_REM_DOUBLES.val
- PREF_FACE_AREA_WEIGHT= PREF_FACE_AREA_WEIGHT.val
- PREF_FACE_TRIANGULATE= PREF_FACE_TRIANGULATE.val
-
- VGROUP_INF_ENABLE= VGROUP_INF_ENABLE.val
- VGROUP_INF_WEIGHT= VGROUP_INF_WEIGHT.val
-
- if VGROUP_INF_ENABLE and VGROUP_INF_WEIGHT:
- VGROUP_INF_REDUX= VGROUP_INF_REDUX.val
- else:
- VGROUP_INF_WEIGHT= 0.0
- VGROUP_INF_REDUX= None
-
-
- PREF_DO_UV= PREF_DO_UV.val
- PREF_DO_VCOL= PREF_DO_VCOL.val
- PREF_DO_WEIGHTS= PREF_DO_WEIGHTS.val
- PREF_OTHER_SEL_OBS= PREF_OTHER_SEL_OBS.val
-
-
- t= sys.time()
-
- is_editmode = Window.EditMode() # Exit Editmode.
- if is_editmode: Window.EditMode(0)
- Window.WaitCursor(1)
- print 'reducing:', act_ob.name, act_ob.getData(1)
- BPyMesh.redux(act_ob, PREF_REDUX, PREF_BOUNDRY_WEIGHT, PREF_REM_DOUBLES, PREF_FACE_AREA_WEIGHT, PREF_FACE_TRIANGULATE, PREF_DO_UV, PREF_DO_VCOL, PREF_DO_WEIGHTS, VGROUP_INF_REDUX, VGROUP_INF_WEIGHT)
-
- if PREF_OTHER_SEL_OBS:
- for ob in scn.objects.context:
- if ob.type == 'Mesh' and ob != act_ob:
- print 'reducing:', ob.name, ob.getData(1)
- BPyMesh.redux(ob, PREF_REDUX, PREF_BOUNDRY_WEIGHT, PREF_REM_DOUBLES, PREF_FACE_AREA_WEIGHT, PREF_FACE_TRIANGULATE, PREF_DO_UV, PREF_DO_VCOL, PREF_DO_WEIGHTS, VGROUP_INF_REDUX, VGROUP_INF_WEIGHT)
- Window.RedrawAll()
-
- if is_editmode: Window.EditMode(1)
- Window.WaitCursor(0)
- Window.RedrawAll()
-
- print 'Reduction done in %.6f sec.' % (sys.time()-t)
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/mesh_poly_reduce_grid.py b/release/scripts/mesh_poly_reduce_grid.py
deleted file mode 100644
index 2903909027a..00000000000
--- a/release/scripts/mesh_poly_reduce_grid.py
+++ /dev/null
@@ -1,351 +0,0 @@
-#!BPY
-"""
-Name: 'Poly Reduce Selection (Unsubsurf)'
-Blender: 245
-Group: 'Mesh'
-Tooltip: 'predictable mesh simplifaction maintaining face loops'
-"""
-
-from Blender import Scene, Mesh, Window, sys
-import BPyMessages
-import bpy
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-
-def my_mesh_util(me):
- me_verts = me.verts
-
- vert_faces = [ [] for v in me_verts]
- vert_faces_corner = [ [] for v in me_verts]
-
-
- # Ignore topology where there are not 2 faces connected to an edge.
- edge_count = {}
- for f in me.faces:
- for edkey in f.edge_keys:
- try:
- edge_count[edkey] += 1
- except:
- edge_count[edkey] = 1
-
- for edkey, count in edge_count.iteritems():
-
- # 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:
- unique_verts.add(v.index)
- return unique_verts
-
- for f in me.faces:
- for corner, v in enumerate(f):
- 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].sel and face_ls[1].sel and face_ls[2].sel and face_ls[3].sel:
- # Support triangles also
- unique_vert_count = len(faces_set_verts(face_ls))
- quads = 0
- for f in face_ls:
- if len(f) ==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].sel and face_ls[1].sel and face_ls[2].sel:
- 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(me_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[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[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.v
-
- if len(f) == 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 vi, face_ls in grid_data_dict.iteritems():
- for i, f in enumerate(face_ls):
- if len(f) == 4:
- # i == face index on vert, needed to recall which corner were on.
- v_corner = vert_faces_corner[vi][i]
- v_other = quad_diag_mapping[v_corner]
- fv =f.v
-
- #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]], fv[quad_del_vt_map[v_corner][1]], fv[quad_del_vt_map[v_corner][2]]) )
-
- del grid_data_ls
-
-
- # me.sel = 0
- def faceCombine4(vi, face_ls):
- edges = []
-
- for i, f in enumerate(face_ls):
- fv = f.v
- v_corner = vert_faces_corner[vi][i]
- if len(f)==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 vi, face_ls in grid_data_dict.iteritems():
- 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.iteritems():
- faces_remove.extend(face_ls)
- '''
-
- orig_facelen = len(me.faces)
-
- orig_faces = list(me.faces)
- me.faces.extend(new_faces, ignoreDups=True)
- new_faces = list(me.faces)[len(orig_faces):]
-
-
-
-
-
- if me.faceUV:
- uvnames = me.getUVLayerNames()
- act_uvlay = me.activeUVLayer
-
- vert_faces_uvs = []
- vert_faces_images = []
-
-
- act_uvlay = me.activeUVLayer
-
- for uvlay in uvnames:
- me.activeUVLayer = uvlay
- vert_faces_uvs[:] = [None] * len(me.verts)
- vert_faces_images[:] = vert_faces_uvs[:]
-
- for i,f in enumerate(orig_faces):
- img = f.image
- fv = f.v
- uv = f.uv
- mat = f.mat
- for i,v in enumerate(fv):
- vi = v.index
- vert_faces_uvs[vi] = uv[i] # no nice averaging
- vert_faces_images[vi] = img
-
-
- # Now copy UVs across
- for f in new_faces:
- fi = [v.index for v in f.v]
- f.image = vert_faces_images[fi[0]]
- uv = f.uv
- for i,vi in enumerate(fi):
- uv[i][:] = vert_faces_uvs[vi]
-
- if len(me.materials) > 1:
- vert_faces_mats = [None] * len(me.verts)
- for i,f in enumerate(orig_faces):
- mat = f.mat
- for i,v in enumerate(f.v):
- vi = v.index
- vert_faces_mats[vi] = mat
-
- # Now copy UVs across
- for f in new_faces:
- print vert_faces_mats[f.v[0].index]
- f.mat = vert_faces_mats[f.v[0].index]
-
-
- me.verts.delete(grid_data_dict.keys())
-
- # me.faces.delete(1, faces_remove)
-
- if me.faceUV:
- me.activeUVLayer = act_uvlay
-
- me.calcNormals()
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = bpy.data.scenes.active
-
- # Get the active object, there can only ever be 1
- # and the active object is always the editmode object.
- ob_act = sce.objects.active
-
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
-
- Window.WaitCursor(1)
- me = ob_act.getData(mesh=1) # old NMesh api is default
- t = sys.time()
-
- # Run the mesh editing function
- my_mesh_util(me)
-
- # Restore editmode if it was enabled
- if is_editmode: Window.EditMode(1)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'My Script finished in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
-
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main()
-
diff --git a/release/scripts/mesh_skin.py b/release/scripts/mesh_skin.py
deleted file mode 100644
index 4a330a516fb..00000000000
--- a/release/scripts/mesh_skin.py
+++ /dev/null
@@ -1,639 +0,0 @@
-#!BPY
-
-"""
-Name: 'Skin Faces/Edge-Loops'
-Blender: 243
-Group: 'MeshFaceKey'
-Tooltip: 'Select 2 vert loops, then run this script.'
-"""
-
-__author__ = "Campbell Barton AKA Ideasman"
-__url__ = ["blenderartists.org", "www.blender.org"]
-__version__ = "1.1 2006/12/26"
-
-__bpydoc__ = """\
-With this script vertex loops can be skinned: faces are created to connect the
-selected loops of vertices.
-
-Usage:
-
-In mesh Edit mode select the vertices of the loops (closed paths / curves of
-vertices: circles, for example) that should be skinned, then run this script.
-A pop-up will provide further options, if the results of a method are not adequate try one of the others.
-"""
-
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# Skin Selected edges 1.0 By Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-# Made by Ideasman/Campbell 2005/06/15 - cbarton@metavr.com
-
-import Blender
-import bpy
-from Blender import Window
-from Blender.Mathutils import MidpointVecs, Vector
-from Blender.Mathutils import AngleBetweenVecs as _AngleBetweenVecs_
-import BPyMessages
-
-from Blender.Draw import PupMenu
-
-BIG_NUM = 1<<30
-
-global CULL_METHOD
-CULL_METHOD = 0
-
-def AngleBetweenVecs(a1,a2):
- try:
- return _AngleBetweenVecs_(a1,a2)
- except:
- return 180.0
-
-class edge(object):
- __slots__ = 'v1', 'v2', 'co1', 'co2', 'length', 'removed', 'match', 'cent', 'angle', 'next', 'prev', 'normal', 'fake'
- def __init__(self, v1,v2):
- self.v1 = v1
- self.v2 = v2
- co1, co2= v1.co, v2.co
- self.co1= co1
- self.co2= co2
-
- # uv1 uv2 vcol1 vcol2 # Add later
- self.length = (co1 - co2).length
- self.removed = 0 # Have we been culled from the eloop
- self.match = None # The other edge were making a face with
-
- self.cent= MidpointVecs(co1, co2)
- self.angle= 0.0
- self.fake= False
-
-class edgeLoop(object):
- __slots__ = 'centre', 'edges', 'normal', 'closed', 'backup_edges'
- def __init__(self, loop, me, closed): # Vert loop
- # Use next and prev, nextDist, prevDist
-
- # Get Loops centre.
- fac= len(loop)
- verts = me.verts
- self.centre= reduce(lambda a,b: a+verts[b].co/fac, loop, Vector())
-
- # Convert Vert loop to Edges.
- self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in xrange(len(loop))]
-
- if not closed:
- self.edges[0].fake = True # fake edge option
-
- self.closed = closed
-
-
- # Assign linked list
- for eIdx in xrange(len(self.edges)-1):
- self.edges[eIdx].next = self.edges[eIdx+1]
- self.edges[eIdx].prev = self.edges[eIdx-1]
- # Now last
- self.edges[-1].next = self.edges[0]
- self.edges[-1].prev = self.edges[-2]
-
-
-
- # GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
- self.normal = Vector()
- for e in self.edges:
- n = (self.centre-e.co1).cross(self.centre-e.co2)
- # Do we realy need tot normalize?
- n.normalize()
- self.normal += n
-
- # Generate the angle
- va= e.cent - e.prev.cent
- vb= e.next.cent - e.cent
-
- e.angle= AngleBetweenVecs(va, vb)
-
- # Blur the angles
- #for e in self.edges:
- # e.angle= (e.angle+e.next.angle)/2
-
- # Blur the angles
- #for e in self.edges:
- # e.angle= (e.angle+e.prev.angle)/2
-
- self.normal.normalize()
-
- # Generate a normal for each edge.
- for e in self.edges:
-
- n1 = e.co1
- n2 = e.co2
- n3 = e.prev.co1
-
- a = n1-n2
- b = n1-n3
- normal1 = a.cross(b)
- normal1.normalize()
-
- n1 = e.co2
- n3 = e.next.co2
- n2 = e.co1
-
- a = n1-n2
- b = n1-n3
-
- normal2 = a.cross(b)
- normal2.normalize()
-
- # Reuse normal1 var
- normal1 += normal1 + normal2
- normal1.normalize()
-
- e.normal = normal1
- #print e.normal
-
-
-
- def backup(self):
- # Keep a backup of the edges
- self.backup_edges = self.edges[:]
-
- def restore(self):
- self.edges = self.backup_edges[:]
- for e in self.edges:
- e.removed = 0
-
- def reverse(self):
- self.edges.reverse()
- self.normal.negate()
-
- for e in self.edges:
- e.normal.negate()
- e.v1, e.v2 = e.v2, e.v1
- e.co1, e.co2 = e.co2, e.co1
- e.next, e.prev = e.prev, e.next
-
-
- def removeSmallest(self, cullNum, otherLoopLen):
- '''
- Removes N Smallest edges and backs up the loop,
- this is so we can loop between 2 loops as if they are the same length,
- backing up and restoring incase the loop needs to be skinned with another loop of a different length.
- '''
- global CULL_METHOD
- if CULL_METHOD == 1: # Shortest edge
- eloopCopy = self.edges[:]
-
- # Length sort, smallest first
- try: eloopCopy.sort(key = lambda e1: e1.length)
- except: eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length ))
-
- # Dont use atm
- #eloopCopy.sort(lambda e1, e2: cmp(e1.angle*e1.length, e2.angle*e2.length)) # Length sort, smallest first
- #eloopCopy.sort(lambda e1, e2: cmp(e1.angle, e2.angle)) # Length sort, smallest first
-
- remNum = 0
- for i, e in enumerate(eloopCopy):
- if not e.fake:
- e.removed = 1
- self.edges.remove( e ) # Remove from own list, still in linked list.
- remNum += 1
-
- if not remNum < cullNum:
- break
-
- else: # CULL METHOD is even
-
- culled = 0
-
- step = int(otherLoopLen / float(cullNum)) * 2
-
- currentEdge = self.edges[0]
- while culled < cullNum:
-
- # Get the shortest face in the next STEP
- step_count= 0
- bestAng= 360.0
- smallestEdge= None
- while step_count<=step or smallestEdge==None:
- step_count+=1
- if not currentEdge.removed: # 0 or -1 will not be accepted
- if currentEdge.angle<bestAng and not currentEdge.fake:
- smallestEdge= currentEdge
- bestAng= currentEdge.angle
-
- currentEdge = currentEdge.next
-
- # In that stepping length we have the smallest edge.remove it
- smallestEdge.removed = 1
- self.edges.remove(smallestEdge)
-
- # Start scanning from the edge we found? - result is over fanning- no good.
- #currentEdge= smallestEdge.next
-
- culled+=1
-
-
-# Returns face edges.
-# face must have edge data.
-
-def getSelectedEdges(me, ob):
- MESH_MODE= Blender.Mesh.Mode()
-
- if MESH_MODE & Blender.Mesh.SelectModes.EDGE or MESH_MODE & Blender.Mesh.SelectModes.VERTEX:
- Blender.Mesh.Mode(Blender.Mesh.SelectModes.EDGE)
- edges= [ ed for ed in me.edges if ed.sel ]
- # print len(edges), len(me.edges)
- Blender.Mesh.Mode(MESH_MODE)
- return edges
-
- elif MESH_MODE & Blender.Mesh.SelectModes.FACE:
- Blender.Mesh.Mode(Blender.Mesh.SelectModes.EDGE)
-
- # value is [edge, face_sel_user_in]
- '''
- try: # Python 2.4 only
- edge_dict= dict((ed.key, [ed, 0]) for ed in me.edges)
- except:
- '''
- # Cant try 2.4 syntax because python 2.3 will complain still
- edge_dict= dict([(ed.key, [ed, 0]) for ed in me.edges])
-
- for f in me.faces:
- if f.sel:
- for edkey in f.edge_keys:
- edge_dict[edkey][1] += 1
-
- Blender.Mesh.Mode(MESH_MODE)
- return [ ed_data[0] for ed_data in edge_dict.itervalues() if ed_data[1] == 1 ]
-
-
-
-def getVertLoops(selEdges, me):
- '''
- return a list of vert loops, closed and open [(loop, closed)...]
- '''
-
- mainVertLoops = []
- # second method
- tot = len(me.verts)
- vert_siblings = [[] for i in xrange(tot)]
- vert_used = [False] * tot
-
- for ed in selEdges:
- i1, i2 = ed.key
- vert_siblings[i1].append(i2)
- vert_siblings[i2].append(i1)
-
- # find the first used vert and keep looping.
- for i in xrange(tot):
- if vert_siblings[i] and not vert_used[i]:
- sbl = vert_siblings[i] # siblings
-
- if len(sbl) > 2:
- return None
-
- vert_used[i] = True
-
- # do an edgeloop seek
- if len(sbl) == 2:
- contextVertLoop= [sbl[0], i, sbl[1]] # start the vert loop
- vert_used[contextVertLoop[ 0]] = True
- vert_used[contextVertLoop[-1]] = True
- else:
- contextVertLoop= [i, sbl[0]]
- vert_used[contextVertLoop[ 1]] = True
-
- # Always seek up
- ok = True
- while ok:
- ok = False
- closed = False
- sbl = vert_siblings[contextVertLoop[-1]]
- if len(sbl) == 2:
- next = sbl[not sbl.index( contextVertLoop[-2] )]
- if vert_used[next]:
- closed = True
- # break
- else:
- contextVertLoop.append( next ) # get the vert that isnt the second last
- vert_used[next] = True
- ok = True
-
- # Seek down as long as the starting vert was not at the edge.
- if not closed and len(vert_siblings[i]) == 2:
-
- ok = True
- while ok:
- ok = False
- sbl = vert_siblings[contextVertLoop[0]]
- if len(sbl) == 2:
- next = sbl[not sbl.index( contextVertLoop[1] )]
- if vert_used[next]:
- closed = True
- else:
- contextVertLoop.insert(0, next) # get the vert that isnt the second last
- vert_used[next] = True
- ok = True
-
- mainVertLoops.append((contextVertLoop, closed))
-
-
- verts = me.verts
- # convert from indicies to verts
- # mainVertLoops = [([verts[i] for i in contextVertLoop], closed) for contextVertLoop, closed in mainVertLoops]
- # print len(mainVertLoops)
- return mainVertLoops
-
-
-
-def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE):
-
- new_faces= [] #
-
- # Make sure e1 loops is bigger then e2
- if len(eloop1.edges) != len(eloop2.edges):
- if len(eloop1.edges) < len(eloop2.edges):
- eloop1, eloop2 = eloop2, eloop1
-
- eloop1.backup() # were about to cull faces
- CULL_FACES = len(eloop1.edges) - len(eloop2.edges)
- eloop1.removeSmallest(CULL_FACES, len(eloop1.edges))
- else:
- CULL_FACES = 0
- # First make sure poly vert loops are in sync with eachother.
-
- # The vector allong which we are skinning.
- skinVector = eloop1.centre - eloop2.centre
-
- loopDist = skinVector.length
-
- # IS THE LOOP FLIPPED, IF SO FLIP BACK. we keep it flipped, its ok,
- if eloop1.closed or eloop2.closed:
- angleBetweenLoopNormals = AngleBetweenVecs(eloop1.normal, eloop2.normal)
- if angleBetweenLoopNormals > 90:
- eloop2.reverse()
-
-
- DIR= eloop1.centre - eloop2.centre
-
- # if eloop2.closed:
- bestEloopDist = BIG_NUM
- bestOffset = 0
- # Loop rotation offset to test.1
- eLoopIdxs = range(len(eloop1.edges))
- for offset in xrange(len(eloop1.edges)):
- totEloopDist = 0 # Measure this total distance for thsi loop.
-
- offsetIndexLs = eLoopIdxs[offset:] + eLoopIdxs[:offset] # Make offset index list
-
-
- # e1Idx is always from 0uu to N, e2Idx is offset.
- for e1Idx, e2Idx in enumerate(offsetIndexLs):
- e1= eloop1.edges[e1Idx]
- e2= eloop2.edges[e2Idx]
-
-
- # Include fan connections in the measurement.
- OK= True
- while OK or e1.removed:
- OK= False
-
- # Measure the vloop distance ===============
- diff= ((e1.cent - e2.cent).length) #/ nangle1
-
- ed_dir= e1.cent-e2.cent
- a_diff= AngleBetweenVecs(DIR, ed_dir)/18 # 0 t0 18
-
- totEloopDist += (diff * (1+a_diff)) / (1+loopDist)
-
- # Premeture break if where no better off
- if totEloopDist > bestEloopDist:
- break
-
- e1=e1.next
-
- if totEloopDist < bestEloopDist:
- bestOffset = offset
- bestEloopDist = totEloopDist
-
- # Modify V2 LS for Best offset
- eloop2.edges = eloop2.edges[bestOffset:] + eloop2.edges[:bestOffset]
-
- else:
- # Both are open loops, easier to calculate.
-
-
- # Make sure the fake edges are at the start.
- for i, edloop in enumerate((eloop1, eloop2)):
- # print "LOOPO"
- if edloop.edges[0].fake:
- # alredy at the start
- #print "A"
- pass
- elif edloop.edges[-1].fake:
- # put the end at the start
- edloop.edges.insert(0, edloop.edges.pop())
- #print "B"
-
- else:
- for j, ed in enumerate(edloop.edges):
- if ed.fake:
- #print "C"
- edloop.edges = edloop.edges = edloop.edges[j:] + edloop.edges[:j]
- break
- # print "DONE"
- ed1, ed2 = eloop1.edges[0], eloop2.edges[0]
-
- if not ed1.fake or not ed2.fake:
- raise "Error"
-
- # Find the join that isnt flipped (juts like detecting a bow-tie face)
- a1 = (ed1.co1 - ed2.co1).length + (ed1.co2 - ed2.co2).length
- a2 = (ed1.co1 - ed2.co2).length + (ed1.co2 - ed2.co1).length
-
- if a1 > a2:
- eloop2.reverse()
- # make the first edge the start edge still
- eloop2.edges.insert(0, eloop2.edges.pop())
-
-
-
-
- for loopIdx in xrange(len(eloop2.edges)):
- e1 = eloop1.edges[loopIdx]
- e2 = eloop2.edges[loopIdx]
-
- # Remember the pairs for fan filling culled edges.
- e1.match = e2; e2.match = e1
-
- if not (e1.fake or e2.fake):
- new_faces.append([e1.v1, e1.v2, e2.v2, e2.v1])
-
- # FAN FILL MISSING FACES.
- if CULL_FACES:
- # Culled edges will be in eloop1.
- FAN_FILLED_FACES = 0
-
- contextEdge = eloop1.edges[0] # The larger of teh 2
- while FAN_FILLED_FACES < CULL_FACES:
- while contextEdge.next.removed == 0:
- contextEdge = contextEdge.next
-
- vertFanPivot = contextEdge.match.v2
-
- while contextEdge.next.removed == 1:
- #if not contextEdge.next.fake:
- new_faces.append([contextEdge.next.v1, contextEdge.next.v2, vertFanPivot])
-
- # Should we use another var?, this will work for now.
- contextEdge.next.removed = 1
-
- contextEdge = contextEdge.next
- FAN_FILLED_FACES += 1
-
- # may need to fan fill backwards 1 for non closed loops.
-
- eloop1.restore() # Add culled back into the list.
-
- return new_faces
-
-def main():
- global CULL_METHOD
-
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
- ob = bpy.data.scenes.active.objects.active
- if ob == None or ob.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- me = ob.getData(mesh=1)
-
- if me.multires:
- BPyMessages.Error_NoMeshMultiresEdit()
- return
-
- time1 = Blender.sys.time()
- selEdges = getSelectedEdges(me, ob)
- vertLoops = getVertLoops(selEdges, me) # list of lists of edges.
- if vertLoops == None:
- PupMenu('Error%t|Selection includes verts that are a part of more then 1 loop')
- if is_editmode: Window.EditMode(1)
- return
- # print len(vertLoops)
-
-
- if len(vertLoops) > 2:
- choice = PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment')
- if choice == -1:
- if is_editmode: Window.EditMode(1)
- return
- elif len(vertLoops) < 2:
- PupMenu('Error%t|No Vertloops found!')
- if is_editmode: Window.EditMode(1)
- return
- else:
- choice = 2
-
-
- # The line below checks if any of the vert loops are differenyt in length.
- if False in [len(v[0]) == len(vertLoops[0][0]) for v in vertLoops]:
- CULL_METHOD = PupMenu('Small to large edge loop distrobution method%t|remove edges evenly|remove smallest edges')
- if CULL_METHOD == -1:
- if is_editmode: Window.EditMode(1)
- return
-
- if CULL_METHOD ==1: # RESET CULL_METHOD
- CULL_METHOD = 0 # shortest
- else:
- CULL_METHOD = 1 # even
-
-
- time1 = Blender.sys.time()
- # Convert to special edge data.
- edgeLoops = []
- for vloop, closed in vertLoops:
- edgeLoops.append(edgeLoop(vloop, me, closed))
-
-
- # VERT LOOP ORDERING CODE
- # "Build a worm" list - grow from Both ends
- edgeOrderedList = [edgeLoops.pop()]
-
- # Find the closest.
- bestSoFar = BIG_NUM
- bestIdxSoFar = None
- for edLoopIdx, edLoop in enumerate(edgeLoops):
- l =(edgeOrderedList[-1].centre - edLoop.centre).length
- if l < bestSoFar:
- bestIdxSoFar = edLoopIdx
- bestSoFar = l
-
- edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) )
-
- # Now we have the 2 closest, append to either end-
- # Find the closest.
- while edgeLoops:
- bestSoFar = BIG_NUM
- bestIdxSoFar = None
- first_or_last = 0 # Zero is first
- for edLoopIdx, edLoop in enumerate(edgeLoops):
- l1 =(edgeOrderedList[-1].centre - edLoop.centre).length
-
- if l1 < bestSoFar:
- bestIdxSoFar = edLoopIdx
- bestSoFar = l1
- first_or_last = 1 # last
-
- l2 =(edgeOrderedList[0].centre - edLoop.centre).length
- if l2 < bestSoFar:
- bestIdxSoFar = edLoopIdx
- bestSoFar = l2
- first_or_last = 0 # last
-
- if first_or_last: # add closest Last
- edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) )
- else: # Add closest First
- edgeOrderedList.insert(0, edgeLoops.pop(bestIdxSoFar) ) # First
-
- faces = []
-
- for i in xrange(len(edgeOrderedList)-1):
- faces.extend( skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0) )
- if choice == 1 and len(edgeOrderedList) > 2: # Loop
- faces.extend( skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) )
-
- # REMOVE SELECTED FACES.
- MESH_MODE= Blender.Mesh.Mode()
- if MESH_MODE & Blender.Mesh.SelectModes.EDGE or MESH_MODE & Blender.Mesh.SelectModes.VERTEX: pass
- elif MESH_MODE & Blender.Mesh.SelectModes.FACE:
- try: me.faces.delete(1, [ f for f in me.faces if f.sel ])
- except: pass
-
- me.faces.extend(faces, smooth = True)
-
- print '\nSkin done in %.4f sec.' % (Blender.sys.time()-time1)
-
-
- if is_editmode: Window.EditMode(1)
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/mesh_solidify.py b/release/scripts/mesh_solidify.py
deleted file mode 100644
index 9e11ed68c63..00000000000
--- a/release/scripts/mesh_solidify.py
+++ /dev/null
@@ -1,345 +0,0 @@
-#!BPY
-"""
-Name: 'Solidify Selection'
-Blender: 243
-Group: 'Mesh'
-Tooltip: 'Makes the mesh solid by creating a second skin.'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("www.blender.org", "blenderartists.org")
-__version__ = "1.1"
-
-__bpydoc__ = """\
-This script makes a skin from the selected faces.
-Optionaly you can skin between the original and new faces to make a watertight solid object
-"""
-
-# --------------------------------------------------------------------------
-# Solidify Selection 1.0 by Campbell Barton (AKA Ideasman42)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import *
-import bpy
-import BPyMesh
-# reload(BPyMesh)
-import BPyMessages
-# reload(BPyMessages)
-
-from BPyMathutils import angleToLength
-
-# python 2.3 has no reversed() iterator. this will only work on lists and tuples
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-def copy_facedata_multilayer(me, from_faces, to_faces):
- '''
- Tkes 2 lists of faces and copies multilayer data from 1 to another
- make sure they are aligned, cant copy from a quad to a tri, used for solidify selection.
- '''
-
- def copy_default_face(data):
- face_from, face_to = data
- face_to.mat = face_from.mat
- face_to.smooth = face_from.smooth
- face_to.sel = True
- face_from.sel = False
-
- def copy_tex_face(data):
- face_from, face_to = data
- face_to.uv = [c for c in reversed(face_from.uv)]
- face_to.mode = face_from.mode
- face_to.flag = face_from.flag
- face_to.image = face_from.image
-
- def copy_col_face(data):
- face_from, face_to = data
- face_to.col = [c for c in reversed(face_from.col)]
-
- # make a list of face_from, face_to pairs
- #face_pairs = zip(faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))])
- face_pairs = zip(from_faces, to_faces)
-
- # Copy properties from 1 set of faces to another.
- map(copy_default_face, face_pairs)
-
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- map(copy_tex_face, face_pairs)
-
- for collayer in me.getColorLayerNames():
- me.activeColorLayer = collayer
- map(copy_col_face, face_pairs)
-
- # Now add quads between if we wants
-
-
-Ang= Mathutils.AngleBetweenVecs
-SMALL_NUM=0.00001
-
-def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False, PREF_COLLAPSE_SIDES=False):
-
- # Main code function
- me_faces = me.faces
- faces_sel= [f for f in me_faces if f.sel]
-
- BPyMesh.meshCalcNormals(me)
- normals= [v.no for v in me.verts]
- vertFaces= [[] for i in xrange(len(me.verts))]
- for f in me_faces:
- no=f.no
- for v in f:
- vertFaces[v.index].append(no)
-
- # Scale the normals by the face angles from the vertex Normals.
- for i in xrange(len(me.verts)):
- length=0.0
- if vertFaces[i]:
- for fno in vertFaces[i]:
- try:
- a= Ang(fno, normals[i])
- except:
- a= 0
- if a>=90:
- length+=1
- elif a < SMALL_NUM:
- length+= 1
- else:
- length+= angleToLength(a)
-
- length= length/len(vertFaces[i])
- #print 'LENGTH %.6f' % length
- # normals[i]= (normals[i] * length) * PREF_THICK
- normals[i] *= length * PREF_THICK
-
-
-
- len_verts = len( me.verts )
- len_faces = len( me_faces )
-
- vert_mapping= [-1] * len(me.verts)
- verts= []
- for f in faces_sel:
- for v in f:
- i= v.index
- if vert_mapping[i]==-1:
- vert_mapping[i]= len_verts + len(verts)
- verts.append(v.co + normals[i])
-
- #verts= [v.co + normals[v.index] for v in me.verts]
-
- me.verts.extend( verts )
- #faces= [tuple([ me.verts[v.index+len_verts] for v in reversed(f.v)]) for f in me_faces ]
- faces= [ tuple([vert_mapping[v.index] for v in reversed(f.v)]) for f in faces_sel ]
- me_faces.extend( faces )
-
-
-
-
- # Old method before multi UVs
- """
- has_uv = me.faceUV
- has_vcol = me.vertexColors
- for i, orig_f in enumerate(faces_sel):
- new_f= me_faces[len_faces + i]
- new_f.mat = orig_f.mat
- new_f.smooth = orig_f.smooth
- orig_f.sel=False
- new_f.sel= True
- new_f = me_faces[i+len_faces]
- if has_uv:
- new_f.uv = [c for c in reversed(orig_f.uv)]
- new_f.mode = orig_f.mode
- new_f.flag = orig_f.flag
- if orig_f.image:
- new_f.image = orig_f.image
- if has_vcol:
- new_f.col = [c for c in reversed(orig_f.col)]
- """
- copy_facedata_multilayer(me, faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))])
-
- if PREF_SKIN_SIDES or PREF_COLLAPSE_SIDES:
- skin_side_faces= []
- skin_side_faces_orig= []
- # Get edges of faces that only have 1 user - so we can make walls
- edges = {}
-
- # So we can reference indicies that wrap back to the start.
- ROT_TRI_INDEX = 0,1,2,0
- ROT_QUAD_INDEX = 0,1,2,3,0
-
- for f in faces_sel:
- f_v= f.v
- for i, edgekey in enumerate(f.edge_keys):
- if edges.has_key(edgekey):
- edges[edgekey]= None
- else:
- if len(f_v) == 3:
- edges[edgekey] = f, f_v, i, ROT_TRI_INDEX[i+1]
- else:
- edges[edgekey] = f, f_v, i, ROT_QUAD_INDEX[i+1]
- del ROT_QUAD_INDEX, ROT_TRI_INDEX
-
- # So we can remove doubles with edges only.
- if PREF_COLLAPSE_SIDES:
- me.sel = False
-
- # Edges are done. extrude the single user edges.
- for edge_face_data in edges.itervalues():
- if edge_face_data: # != None
- f, f_v, i1, i2 = edge_face_data
- v1i,v2i= f_v[i1].index, f_v[i2].index
-
- if PREF_COLLAPSE_SIDES:
- # Collapse
- cv1 = me.verts[v1i]
- cv2 = me.verts[vert_mapping[v1i]]
-
- cv3 = me.verts[v2i]
- cv4 = me.verts[vert_mapping[v2i]]
-
- cv1.co = cv2.co = (cv1.co+cv2.co)/2
- cv3.co = cv4.co = (cv3.co+cv4.co)/2
-
- cv1.sel=cv2.sel=cv3.sel=cv4.sel=True
-
-
-
- else:
- # Now make a new Face
- # skin_side_faces.append( (v1i, v2i, vert_mapping[v2i], vert_mapping[v1i]) )
- skin_side_faces.append( (v2i, v1i, vert_mapping[v1i], vert_mapping[v2i]) )
- skin_side_faces_orig.append((f, len(me_faces) + len(skin_side_faces_orig), i1, i2))
-
- if PREF_COLLAPSE_SIDES:
- me.remDoubles(0.0001)
- else:
- me_faces.extend(skin_side_faces)
- # Now assign properties.
- """
- # Before MultiUVs
- for i, origfData in enumerate(skin_side_faces_orig):
- orig_f, new_f_idx, i1, i2 = origfData
- new_f= me_faces[new_f_idx]
-
- new_f.mat= orig_f.mat
- new_f.smooth= orig_f.smooth
- if has_uv:
- new_f.mode= orig_f.mode
- new_f.flag= orig_f.flag
- if orig_f.image:
- new_f.image= orig_f.image
-
- uv1= orig_f.uv[i1]
- uv2= orig_f.uv[i2]
- new_f.uv= (uv1, uv2, uv2, uv1)
-
- if has_vcol:
- col1= orig_f.col[i1]
- col2= orig_f.col[i2]
- new_f.col= (col1, col2, col2, col1)
- """
-
- for i, origfData in enumerate(skin_side_faces_orig):
- orig_f, new_f_idx, i2, i1 = origfData
- new_f= me_faces[new_f_idx]
-
- new_f.mat= orig_f.mat
- new_f.smooth= orig_f.smooth
-
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- for i, origfData in enumerate(skin_side_faces_orig):
- orig_f, new_f_idx, i2, i1 = origfData
- new_f= me_faces[new_f_idx]
-
- new_f.mode= orig_f.mode
- new_f.flag= orig_f.flag
- new_f.image= orig_f.image
-
- uv1= orig_f.uv[i1]
- uv2= orig_f.uv[i2]
- new_f.uv= (uv1, uv2, uv2, uv1)
-
- for collayer in me.getColorLayerNames():
- me.activeColorLayer = collayer
- for i, origfData in enumerate(skin_side_faces_orig):
- orig_f, new_f_idx, i2, i1 = origfData
- new_f= me_faces[new_f_idx]
-
- col1= orig_f.col[i1]
- col2= orig_f.col[i2]
- new_f.col= (col1, col2, col2, col1)
-
-
- if PREF_REM_ORIG:
- me_faces.delete(0, faces_sel)
-
-
-
-
-def main():
- scn = bpy.data.scenes.active
- ob = scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- me = ob.getData(mesh=1)
- if me.multires:
- BPyMessages.Error_NoMeshMultiresEdit()
- return
-
- # Create the variables.
- PREF_THICK = Draw.Create(-0.1)
- PREF_SKIN_SIDES= Draw.Create(1)
- PREF_COLLAPSE_SIDES= Draw.Create(0)
- PREF_REM_ORIG= Draw.Create(0)
-
- pup_block = [\
- ('Thick:', PREF_THICK, -10, 10, 'Skin thickness in mesh space.'),\
- ('Skin Sides', PREF_SKIN_SIDES, 'Skin between the original and new faces.'),\
- ('Collapse Sides', PREF_COLLAPSE_SIDES, 'Skin between the original and new faces.'),\
- ('Remove Original', PREF_REM_ORIG, 'Remove the selected faces after skinning.'),\
- ]
-
- if not Draw.PupBlock('Solid Skin Selection', pup_block):
- return
-
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
-
- Window.WaitCursor(1)
-
- me = ob.getData(mesh=1)
- solidify(me, PREF_THICK.val, PREF_SKIN_SIDES.val, PREF_REM_ORIG.val, PREF_COLLAPSE_SIDES.val)
-
-
- Window.WaitCursor(0)
- if is_editmode: Window.EditMode(1)
-
- Window.RedrawAll()
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/mesh_unfolder.py b/release/scripts/mesh_unfolder.py
deleted file mode 100644
index f5c19a92bd0..00000000000
--- a/release/scripts/mesh_unfolder.py
+++ /dev/null
@@ -1,1582 +0,0 @@
-#!BPY
-"""
-Name: 'Unfold'
-Blender: 245
-Group: 'Mesh'
-Tip: 'Unfold meshes to create nets'
-Version: v2.5
-Author: Matthew Chadwick
-"""
-import Blender
-from Blender import *
-from Blender.Mathutils import *
-try:
- import sys
- import traceback
- import math
- import re
- from math import *
- import sys
- import random
- import xml.sax, xml.sax.handler, xml.sax.saxutils
-
- # annoying but need so classes dont raise errors
- xml_sax_handler_ContentHandler = xml.sax.handler.ContentHandler
-
-except:
- Draw.PupMenu('Error%t|A full python installation is required to run this script.')
- xml = None
- xml_sax_handler_ContentHandler = type(0)
-
-__author__ = 'Matthew Chadwick'
-__version__ = '2.5 06102007'
-__url__ = ["http://celeriac.net/unfolder/", "blender", "blenderartist"]
-__email__ = ["post at cele[remove this text]riac.net", "scripts"]
-__bpydoc__ = """\
-
-Mesh Unfolder
-
-Unfolds the selected mesh onto a plane to form a net
-
-Not all meshes can be unfolded
-
-Meshes must be free of holes,
-isolated edges (not part of a face), twisted quads and other rubbish.
-Nice clean triangulated meshes unfold best
-
-This program is free software; you can distribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation; version 2
-or later, currently at http://www.gnu.org/copyleft/gpl.html
-
-The idea came while I was riding a bike.
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-# Face lookup
-class FacesAndEdges:
- def __init__(self, mesh):
- self.nfaces = 0
- # straight from the documentation
- self.edgeFaces = dict([(edge.key, []) for edge in mesh.edges])
- for face in mesh.faces:
- face.sel = False
- for key in face.edge_keys:
- self.edgeFaces[key].append(face)
- def findTakenAdjacentFace(self, bface, edge):
- return self.findAdjacentFace(bface, edge)
- # find the first untaken (non-selected) adjacent face in the list of adjacent faces for the given edge (allows for manifold meshes too)
- def findAdjacentFace(self, bface, edge):
- faces = self.edgeFaces[edge.key()]
- for i in xrange(len(faces)):
- if faces[i] == bface:
- j = (i+1) % len(faces)
- while(faces[j]!=bface):
- if faces[j].sel == False:
- return faces[j]
- j = (j+1) % len(faces)
- return None
- def returnFace(self, face):
- face.sel = False
- self.nfaces-=1
- def facesTaken(self):
- return self.nfaces
- def takeAdjacentFace(self, bface, edge):
- if (edge==None):
- return None
- face = self.findAdjacentFace(bface, edge)
- if(face!=None):
- face.sel = True
- self.nfaces+=1
- return face
- def takeFace(self, bface):
- if(bface!=None):
- bface.sel= True
- self.nfaces+=1
-
-
-# A fold between two faces with a common edge
-class Fold:
- ids = -1
- def __init__(self, parent, refPoly, poly, edge, angle=None):
- Fold.ids+=1
- self.id = Fold.ids
- self.refPoly = refPoly
- self.poly = poly
- self.srcFace = None
- self.desFace = None
- self.edge = edge
- self.foldedEdge = edge
- self.rm = None
- self.parent = parent
- self.tree = None
- if(refPoly!=None):
- self.refPolyNormal = refPoly.normal()
- self.polyNormal = poly.normal()
- if(angle==None):
- self.angle = self.calculateAngle()
- self.foldingPoly = poly.rotated(edge, self.angle)
- else:
- self.angle = angle
- self.foldingPoly = poly
- self.unfoldedEdge = self.edge
- self.unfoldedNormal = None
- self.animAngle = self.angle
- self.cr = None
- self.nancestors = None
- def reset(self):
- self.foldingPoly = self.poly.rotated(self.edge, self.dihedralAngle())
- def getID(self):
- return self.id
- def getParent(self):
- return self.parent
- def ancestors(self):
- if(self.nancestors==None):
- self.nancestors = self.computeAncestors()
- return self.nancestors
- def computeAncestors(self):
- if(self.parent==None):
- return 0
- else:
- return self.parent.ancestors()+1
- def dihedralAngle(self):
- return self.angle
- def unfoldTo(self, f):
- self.animAngle = self.angle*f
- self.foldingPoly = self.poly.rotated(self.edge, self.animAngle)
- def calculateAngle(self):
- sangle = Mathutils.AngleBetweenVecs(self.refPolyNormal, self.polyNormal)
- if(sangle!=sangle):
- sangle=0.0
- ncp = self.refPolyNormal.cross(self.polyNormal)
- dp = ncp.dot(self.edge.vector)
- if(dp>0.0):
- return +sangle
- else:
- return -sangle
- def alignWithParent(self):
- pass
- def unfoldedNormal(self):
- return self.unfoldedNormal
- def getEdge(self):
- return self.edge
- def getFace(self):
- return self.poly
- def testFace(self):
- return Poly.fromVectors([self.edge.v1, self.edge.v2, Vector([0,0,0])])
- def unfoldedFace(self):
- return self.foldingPoly
- def unfold(self):
- if(self.parent!=None):
- self.parent.foldFace(self)
- def foldFace(self, child):
- child.foldingPoly.rotate(self.edge, self.animAngle)
- if(self.parent!=None):
- self.parent.foldFace(child)
-
-class Cut(Fold):
- pass
-
-# Trees build folds by traversing the mesh according to a local measure
-class Tree:
- def __init__(self, net, parent,fold,otherConstructor=None):
- self.net = net
- self.fold = fold
- self.face = fold.srcFace
- self.poly = Poly.fromBlenderFace(self.face)
- self.generations = net.generations
- self.growing = True
- self.tooLong = False
- self.parent = parent
- self.grown = False
- if not(otherConstructor):
- self.edges = net.edgeIteratorClass(self)
- def goodness(self):
- return self.edges.goodness()
- def compare(self, other):
- if(self.goodness() > other.goodness()):
- return +1
- else:
- return -1
- def isGrowing(self):
- return self.growing
- def beGrowing(self):
- self.growing = True
- def grow(self):
- self.tooLong = self.fold.ancestors()>self.generations
- if(self.edges.hasNext() and self.growing):
- edge = self.edges.next()
- tface = self.net.facesAndEdges.takeAdjacentFace(self.face, edge)
- if(tface!=None):
- self.branch(tface, edge)
- if(self.parent==None):
- self.grow()
- else:
- self.grown = True
- def isGrown(self):
- return self.grown
- def canGrow(self):
- return (self.parent!=None and self.parent.grown)
- def getNet(self):
- return self.net
- def getFold(self):
- return self.fold
- def getFace(self):
- return self.face
- def branch(self, tface, edge):
- fold = Fold(self.fold, self.poly, Poly.fromBlenderFace(tface), edge)
- fold.srcFace = tface
- self.net.myFacesVisited+=1
- tree = Tree(self.net, self, fold)
- fold.tree = tree
- fold.unfold()
- overlaps = self.net.checkOverlaps(fold)
- nc = len(overlaps)
- self.net.overlaps+=nc
- if(nc>0 and self.net.avoidsOverlaps):
- self.handleOverlap(fold, overlaps)
- else:
- self.addFace(fold)
- def handleOverlap(self, fold, overlaps):
- self.net.facesAndEdges.returnFace(fold.srcFace)
- self.net.myFacesVisited-=1
- for cfold in overlaps:
- ttree = cfold.tree
- ttree.growing = True
- ttree.grow()
- def addFace(self, fold):
- ff = fold.unfoldedFace()
- fold.desFace = self.net.addFace(ff, fold.srcFace)
- self.net.folds.append(fold)
- self.net.addBranch(fold.tree)
- fold.tree.growing = not(self.tooLong)
- if(self.net.diffuse==False):
- fold.tree.grow()
-
-# A Net is the result of the traversal of the mesh by Trees
-class Net:
- def __init__(self, src, des):
- self.src = src
- self.des = des
- self.firstFace = None
- self.firstPoly = None
- self.refFold = None
- self.edgeIteratorClass = RandomEdgeIterator
- if(src!=None):
- self.srcFaces = src.faces
- self.facesAndEdges = FacesAndEdges(self.src)
- self.myFacesVisited = 0
- self.facesAdded = 0
- self.folds = []
- self.cuts = []
- self.branches = []
- self.overlaps = 0
- self.avoidsOverlaps = True
- self.frame = 1
- self.ff = 180.0
- self.firstFaceIndex = None
- self.trees = 0
- self.foldIPO = None
- self.perFoldIPO = None
- self.IPOCurves = {}
- self.generations = 128
- self.diffuse = True
- self.noise = 0.0
- self.grownBranches = 0
- self.assignsUV = True
- self.animates = False
- self.showProgress = False
- self.feedback = None
- def setSelectedFaces(self, faces):
- self.srcFaces = faces
- self.facesAndEdges = FacesAndEdges(self.srcFaces)
- def setShowProgress(self, show):
- self.showProgress = show
- # this method really needs work
- def unfold(self):
- selectedFaces = [face for face in self.src.faces if (self.src.faceUV and face.sel)]
- if(self.avoidsOverlaps):
- print "unfolding with overlap detection"
- if(self.firstFaceIndex==None):
- self.firstFaceIndex = random.randint(0, len(self.src.faces)-1)
- else:
- print "Using user-selected seed face ", self.firstFaceIndex
- self.firstFace = self.src.faces[self.firstFaceIndex]
- z = min([v.co.z for v in self.src.verts])-0.1
- ff = Poly.fromBlenderFace(self.firstFace)
- if(len(ff.v)<3):
- raise Exception("This mesh contains an isolated edge - it must consist only of faces")
- testFace = Poly.fromVectors( [ Vector([0.0,0.0,0.0]), Vector([0.0,1.0,0.0]), Vector([1.0,1.0,0.0]) ] )
- # hmmm. I honestly can't remember why this needs to be done, but it does.
- u=0
- v=1
- w=2
- if ff.v[u].x==ff.v[u+1].x and ff.v[u].y==ff.v[u+1].y:
- u=1
- v=2
- w=0
- # here we make a couple of folds, not part of the net, which serve to get the net into the xy plane
- xyFace = Poly.fromList( [ [ff.v[u].x,ff.v[u].y, z] , [ff.v[v].x,ff.v[v].y, z] , [ff.v[w].x+0.1,ff.v[w].y+0.1, z] ] )
- refFace = Poly.fromVectors([ ff.v[u], ff.v[v], xyFace.v[1], xyFace.v[0] ] )
- xyFold = Fold(None, xyFace, refFace, Edge(xyFace.v[0], xyFace.v[1] ))
- self.refFold = Fold(xyFold, refFace, ff, Edge(refFace.v[0], refFace.v[1] ))
- self.refFold.srcFace = self.firstFace
- # prepare to grow the trees
- trunk = Tree(self, None, self.refFold)
- trunk.generations = self.generations
- self.firstPoly = ff
- self.facesAndEdges.takeFace(self.firstFace)
- self.myFacesVisited+=1
- self.refFold.unfold()
- self.refFold.tree = trunk
- self.refFold.desFace = self.addFace(self.refFold.unfoldedFace(), self.refFold.srcFace)
- self.folds.append(self.refFold)
- trunk.grow()
- i = 0
- # keep the trees growing while they can
- while(self.myFacesVisited<len(self.src.faces) and len(self.branches) > 0):
- if self.edgeIteratorClass==RandomEdgeIterator:
- i = random.randint(0,len(self.branches)-1)
- tree = self.branches[i]
- if(tree.isGrown()):
- self.branches.pop(i)
- else:
- tree.beGrowing()
- if(tree.canGrow()):
- tree.grow()
- i = 0
- else:
- i = (i + 1) % len(self.branches)
- if self.src.faceUV:
- for face in self.src.faces:
- face.sel = False
- for face in selectedFaces:
- face.sel = True
- self.src.update()
- Window.RedrawAll()
- def assignUVs(self):
- for fold in self.folds:
- self.assignUV(fold.srcFace, fold.unfoldedFace())
- print " assigned uv to ", len(self.folds), len(self.src.faces)
- self.src.update()
- def checkOverlaps(self, fold):
- #return self.getOverlapsBetween(fold, self.folds)
- return self.getOverlapsBetweenGL(fold, self.folds)
- def getOverlapsBetween(self, fold, folds):
- if(fold.parent==None):
- return []
- mf = fold.unfoldedFace()
- c = []
- for afold in folds:
- mdf = afold.unfoldedFace()
- if(afold!=fold):
- # currently need to get agreement from both polys because
- # a touch by a vertex of one the other's edge is acceptable &
- # they disagree on that
- intersects = mf.intersects2D(mdf) and mdf.intersects2D(mf)
- inside = ( mdf.containsAnyOf(mf) or mf.containsAnyOf(mdf) )
- if( intersects or inside or mdf.overlays(mf)):
- c.append(afold)
- return c
- def getOverlapsBetweenGL(self, fold, folds):
- b = fold.unfoldedFace().bounds()
- polys = len(folds)*4+16 # the buffer is nhits, mindepth, maxdepth, name
- buffer = BGL.Buffer(BGL.GL_INT, polys)
- BGL.glSelectBuffer(polys, buffer)
- BGL.glRenderMode(BGL.GL_SELECT)
- BGL.glInitNames()
- BGL.glPushName(0)
- BGL.glPushMatrix()
- BGL.glMatrixMode(BGL.GL_PROJECTION)
- BGL.glLoadIdentity()
- BGL.glOrtho(b[0].x, b[1].x, b[1].y, b[0].y, 0.0, 10.0)
- #clip = BGL.Buffer(BGL.GL_FLOAT, 4)
- #clip.list = [0,0,0,0]
- #BGL.glClipPlane(BGL.GL_CLIP_PLANE1, clip)
- # could use clipping planes here too
- BGL.glMatrixMode(BGL.GL_MODELVIEW)
- BGL.glLoadIdentity()
- bx = (b[1].x - b[0].x)
- by = (b[1].y - b[0].y)
- cx = bx / 2.0
- cy = by / 2.0
- for f in xrange(len(folds)):
- afold = folds[f]
- if(fold!=afold):
- BGL.glLoadName(f)
- BGL.glBegin(BGL.GL_LINE_LOOP)
- for v in afold.unfoldedFace().v:
- BGL.glVertex2f(v.x, v.y)
- BGL.glEnd()
- BGL.glPopMatrix()
- BGL.glFlush()
- hits = BGL.glRenderMode(BGL.GL_RENDER)
- buffer = [buffer[i] for i in xrange(3, 4*hits, 4)]
- o = [folds[buffer[i]] for i in xrange(len(buffer))]
- return self.getOverlapsBetween(fold, o)
- def colourFace(self, face, cr):
- for c in face.col:
- c.r = int(cr[0])
- c.g = int(cr[1])
- c.b = int(cr[2])
- c.a = int(cr[3])
- self.src.update()
- def setAvoidsOverlaps(self, avoids):
- self.avoidsOverlaps = avoids
- def addBranch(self, branch):
- self.branches.append(branch)
- if self.edgeIteratorClass!=RandomEdgeIterator:
- self.branches.sort(lambda b1, b2: b1.compare(b2))
- def srcSize(self):
- return len(self.src.faces)
- def nBranches(self):
- return len(self.branches)
- def facesCreated(self):
- return len(self.des.faces)
- def facesVisited(self):
- return self.myFacesVisited
- def getOverlaps(self):
- return self.overlaps
- def sortOutIPOSource(self):
- print "Sorting out IPO"
- if self.foldIPO!=None:
- return
- o = None
- try:
- o = Blender.Object.Get("FoldRate")
- except:
- o = Blender.Object.New("Empty", "FoldRate")
- Blender.Scene.GetCurrent().objects.link(o)
- if(o.getIpo()==None):
- ipo = Blender.Ipo.New("Object", "FoldRateIPO")
- z = ipo.addCurve("RotZ")
- print " added RotZ IPO curve"
- z.addBezier((1,0))
- # again, why is this 10x out ?
- z.addBezier((180, self.ff/10.0))
- z.addBezier((361, 0.0))
- o.setIpo(ipo)
- z.recalc()
- z.setInterpolation("Bezier")
- z.setExtrapolation("Cyclic")
- self.setIPOSource(o)
- print " added IPO source"
- def setIPOSource(self, object):
- try:
- self.foldIPO = object
- for i in xrange(self.foldIPO.getIpo().getNcurves()):
- self.IPOCurves[self.foldIPO.getIpo().getCurves()[i].getName()] = i
- print " added ", self.foldIPO.getIpo().getCurves()[i].getName()
- except:
- print "Problem setting IPO object"
- print sys.exc_info()[1]
- traceback.print_exc(file=sys.stdout)
- def setFoldFactor(self, ff):
- self.ff = ff
- def sayTree(self):
- for fold in self.folds:
- if(fold.getParent()!=None):
- print fold.getID(), fold.dihedralAngle(), fold.getParent().getID()
- def report(self):
- p = int(float(self.myFacesVisited)/float(len(self.src.faces)) * 100)
- print str(p) + "% unfolded"
- print "faces created:", self.facesCreated()
- print "faces visited:", self.facesVisited()
- print "originalfaces:", len(self.src.faces)
- n=0
- if(self.avoidsOverlaps):
- print "net avoided at least ", self.getOverlaps(), " overlaps ",
- n = len(self.src.faces) - self.facesCreated()
- if(n>0):
- print "but was unable to avoid ", n, " overlaps. Incomplete net."
- else:
- print "- A complete net."
- else:
- print "net has at least ", self.getOverlaps(), " collision(s)"
- return n
- # fold all my folds to a fraction of their total fold angle
- def unfoldToCurrentFrame(self):
- self.unfoldTo(Blender.Scene.GetCurrent().getRenderingContext().currentFrame())
- def unfoldTo(self, frame):
- frames = Blender.Scene.GetCurrent().getRenderingContext().endFrame()
- if(self.foldIPO!=None and self.foldIPO.getIpo()!=None):
- f = self.foldIPO.getIpo().EvaluateCurveOn(self.IPOCurves["RotZ"],frame)
- # err, this number seems to be 10x less than it ought to be
- fff = 1.0 - (f*10.0 / self.ff)
- else:
- fff = 1.0-((frame)/(frames*1.0))
- for fold in self.folds:
- fold.unfoldTo(fff)
- for fold in self.folds:
- fold.unfold()
- tface = fold.unfoldedFace()
- bface = fold.desFace
- i = 0
- for v in bface.verts:
- v.co.x = tface.v[i].x
- v.co.y = tface.v[i].y
- v.co.z = tface.v[i].z
- i+=1
- Window.Redraw(Window.Types.VIEW3D)
- return None
- def addFace(self, poly, originalFace=None):
- originalLength = len(self.des.verts)
- self.des.verts.extend([Vector(vv.x, vv.y, vv.z) for vv in poly.v])
- self.des.faces.extend([ range(originalLength, originalLength + poly.size()) ])
- newFace = self.des.faces[len(self.des.faces)-1]
- newFace.uv = [vv for vv in poly.v]
- if(originalFace!=None and self.src.vertexColors):
- newFace.col = [c for c in originalFace.col]
- if(self.feedback!=None):
- pu = str(int(self.fractionUnfolded() * 100))+"% unfolded"
- howMuchDone = str(self.myFacesVisited)+" of "+str(len(self.src.faces))+" "+pu
- self.feedback.say(howMuchDone)
- #Window.DrawProgressBar (p, pu)
- if(self.showProgress):
- Window.Redraw(Window.Types.VIEW3D)
- return newFace
- def fractionUnfolded(self):
- return float(self.myFacesVisited)/float(len(self.src.faces))
- def assignUV(self, face, uv):
- face.uv = [Vector(v.x, v.y) for v in uv.v]
- def unfoldAll(feedback=None):
- objects = Blender.Object.Get()
- for object in objects:
- if(object.getType()=='Mesh' and not(object.getName().endswith("_net")) and len(object.getData(False, True).faces)>1):
- net = Net.createNet(object, feedback)
- net.searchForUnfolding()
- svg = SVGExporter(net, object.getName()+".svg")
- svg.export()
- unfoldAll = staticmethod(unfoldAll)
- def searchForUnfolding(self, limit=-1):
- overlaps = 1
- attempts = 0
- while(overlaps > 0 or attempts<limit):
- self.unfold()
- overlaps = self.report()
- attempts+=1
- return attempts
- def fromSelected(feedback=None, netName=None):
- return Net.createNet(Blender.Object.GetSelected()[0], feedback, netName)
- fromSelected = staticmethod(fromSelected)
- def clone(self, object=None):
- if(object==None):
- object = self.object
- net = Net.createNet(object, self.feedback)
- net.avoidsOverlaps = net.avoidsOverlaps
- return net
- def createNet(ob, feedback=None, netName=None):
- mesh = ob.getData(mesh=1)
- netObject = None
- if(netName==None):
- netName = ob.name[0:16]+"_net"
- try:
- netObject = Blender.Object.Get(netName)
- netMesh = netObject.getData(False, True)
- if(netMesh!=None):
- netMesh.verts = None # clear the mesh
- else:
- netObject = Blender.Object.New("Mesh", netName)
- except:
- if(netObject==None):
- netObject = Blender.Object.New("Mesh", netName)
- netMesh = netObject.getData(False, True) # True means "as a Mesh not an NMesh"
- try:
- Blender.Scene.GetCurrent().objects.link(netObject)
- except:
- pass
- try:
- netMesh.materials = mesh.materials
- netMesh.vertexColors = True
- except:
- print "Problem setting materials here"
- net = Net(mesh, netMesh)
- if mesh.faceUV and mesh.activeFace>=0 and (mesh.faces[mesh.activeFace].sel):
- net.firstFaceIndex = mesh.activeFace
- net.object = ob
- net.feedback = feedback
- return net
- createNet = staticmethod(createNet)
- def importNet(filename):
- netName = filename.rstrip(".svg").replace("\\","/")
- netName = netName[netName.rfind("/")+1:]
- try:
- netObject = Blender.Object.Get(netName)
- except:
- netObject = Blender.Object.New("Mesh", netName)
- netObject.getData(mesh=1).name = netName
- try:
- Blender.Scene.GetCurrent().objects.link(netObject)
- except:
- pass
- net = Net(None, netObject.getData(mesh=1))
- handler = NetHandler(net)
- xml.sax.parse(filename, handler)
- Window.Redraw(Window.Types.VIEW3D)
- return net
- importNet = staticmethod(importNet)
- def getSourceMesh(self):
- return self.src
-
-# determines the order in which to visit faces according to a local measure
-class EdgeIterator:
- def __init__(self, branch, otherConstructor=None):
- self.branch = branch
- self.bface = branch.getFace()
- self.edge = branch.getFold().getEdge()
- self.net = branch.getNet()
- self.n = len(self.bface)
- self.edges = []
- self.i = 0
- self.gooodness = 0
- self.createEdges()
- self.computeGoodness()
- if(otherConstructor==None):
- self.sequenceEdges()
- def createEdges(self):
- edge = None
- e = Edge.edgesOfBlenderFace(self.net.getSourceMesh(), self.bface)
- for edge in e:
- if not(edge.isBlenderSeam() and edge!=self.edge):
- self.edges.append(edge)
- def sequenceEdges(self):
- pass
- def next(self):
- edge = self.edges[self.i]
- self.i+=1
- return edge
- def size(self):
- return len(self.edges)
- def reset(self):
- self.i = 0
- def hasNext(self):
- return (self.i<len(self.edges))
- def goodness(self):
- return self.gooodness
- def computeGoodness(self):
- self.gooodness = 0
- def rotate(self):
- self.edges.append(self.edges.pop(0))
-
-class RandomEdgeIterator(EdgeIterator):
- def sequenceEdges(self):
- random.seed()
- random.shuffle(self.edges)
- def goodness(self):
- return random.randint(0, self.net.srcSize())
-
-
-class Largest(EdgeIterator):
- def sequenceEdges(self):
- for e in self.edges:
- f = self.net.facesAndEdges.findAdjacentFace(self.bface, e)
- if(f!=None):
- e.setGoodness(f.area)
- self.edges.sort(lambda e1, e2: -e1.compare(e2))
- def computeGoodness(self):
- self.gooodness = self.bface.area
-
-
-class Brightest(EdgeIterator):
- def sequenceEdges(self):
- for edge in self.edges:
- f = self.net.facesAndEdges.findAdjacentFace(self.bface, edge)
- if(f!=None):
- b = 0
- if self.net.src.vertexColors:
- for c in f.col:
- b+=(c.g+c.r+c.b)
- rc = float(random.randint(0, self.net.srcSize())) / float(self.net.srcSize()) / 100.0
- b+=rc
- edge.setGoodness(b)
- self.edges.sort(lambda e1, e2: e1.compare(e2))
- def computeGoodness(self):
- g = 0
- if self.net.src.vertexColors:
- for c in self.bface.col:
- g+=(c.g+c.r+c.b)
- self.gooodness = g
-
-class OddEven(EdgeIterator):
- i = True
- def sequenceEdges(self):
- OddEven.i = not(OddEven.i)
- if(OddEven.i):
- self.edges.reverse()
-
-class Curvature(EdgeIterator):
- def sequenceEdges(self):
- p1 = Poly.fromBlenderFace(self.bface)
- gg = 0.0
- for edge in self.edges:
- f = self.net.facesAndEdges.findAdjacentFace(self.bface, edge)
- if(f!=None):
- p2 = Poly.fromBlenderFace(f)
- fold = Fold(None, p1, p2, edge)
- fold.srcFace = f
- b = Tree(self.net, self.branch, fold, self)
- c = Curvature(b, False)
- g = c.goodness()
- gg+=g
- edge.setGoodness(g)
- self.edges.sort(lambda e1, e2: e1.compare(e2))
- tg = (self.gooodness + gg)
- rc = float(random.randint(0, self.net.srcSize())) / float(self.net.srcSize()) / 100.0
- if(tg!=0.0):
- self.gooodness = self.gooodness + rc / tg
- def computeGoodness(self):
- g = 0
- for edge in self.edges:
- f = self.net.facesAndEdges.findAdjacentFace(self.bface, edge)
- if(f!=None):
- p1 = Poly.fromBlenderFace(self.bface)
- p2 = Poly.fromBlenderFace(f)
- f = Fold(None, p1, p2, edge)
- g += f.dihedralAngle()
- self.gooodness = g
-
-
-class Edge:
- def __init__(self, v1=None, v2=None, mEdge=None, i=-1):
- self.idx = i
- if v1 and v2:
- self.v1 = v1.copy()
- self.v2 = v2.copy()
- else:
- self.v1 = mEdge.v1.co.copy()
- self.v2 = mEdge.v2.co.copy()
- self.v1n = -self.v1
- self.vector = self.v1-self.v2
- self.vector.resize3D()
- self.vector.normalize()
- self.bmEdge = mEdge
- self.gooodness = 0.0
- def fromBlenderFace(mesh, bface, i):
- if(i>len(bface)-1):
- return None
- if(i==len(bface)-1):
- j = 0
- else:
- j = i+1
- edge = Edge( bface.v[i].co.copy(), bface.v[j].co.copy() )
- edge.bEdge = mesh.findEdge(bface.v[i], bface.v[j])
- edge.idx = i
- return edge
- fromBlenderFace=staticmethod(fromBlenderFace)
- def edgesOfBlenderFace(mesh, bmFace):
- edges = [mesh.edges[mesh.findEdges(edge[0], edge[1])] for edge in bmFace.edge_keys]
- v = bmFace.verts
- e = []
- vi = v[0]
- i=0
- for j in xrange(1, len(bmFace)+1):
- vj = v[j%len(bmFace)]
- for ee in edges:
- if((ee.v1.index==vi.index and ee.v2.index==vj.index) or (ee.v2.index==vi.index and ee.v1.index==vj.index)):
- e.append(Edge(vi.co, vj.co, ee, i))
- i+=1
- vi = vj
- return e
- edgesOfBlenderFace=staticmethod(edgesOfBlenderFace)
- def isBlenderSeam(self):
- return (self.bmEdge.flag & Mesh.EdgeFlags.SEAM)
- def isInFGon(self):
- return (self.bmEdge.flag & Mesh.EdgeFlags.FGON)
- def mapTo(self, poly):
- if(self.idx==len(poly.v)-1):
- j = 0
- else:
- j = self.idx+1
- return Edge(poly.v[self.idx], poly.v[j])
- def isDegenerate(self):
- return self.vector.length==0
- def vertices(s):
- return [ [s.v1.x, s.v1.y, s.v1.z], [s.v2.x, s.v2.y,s.v2.z] ]
- def key(self):
- return self.bmEdge.key
- def goodness(self):
- return self.gooodness
- def setGoodness(self, g):
- self.gooodness = g
- def compare(self, other):
- if(self.goodness() > other.goodness()):
- return +1
- else:
- return -1
- # Does the given segment intersect this, for overlap detection.
- # endpoints are allowed to touch the line segment
- def intersects2D(self, s):
- if(self.matches(s)):
- return False
- else:
- i = Geometry.LineIntersect2D(self.v1, self.v2, s.v1, s.v2)
- if(i!=None):
- i.resize4D()
- i.z = self.v1.z # hack to put the point on the same plane as this edge for comparison
- return(i!=None and not(self.endsWith(i)))
- def matches(self, s):
- return ( (self.v1==s.v1 and self.v2==s.v2) or (self.v2==s.v1 and self.v1==s.v2) )
- # Is the given point on the end of this segment ? 10-5 seems to an acceptable limit for closeness in Blender
- def endsWith(self, aPoint, e=0.0001):
- return ( (self.v1-aPoint).length < e or (self.v2-aPoint).length < e )
-
-
-class Poly:
- ids = -1
- def __init__(self):
- Poly.ids+=1
- self.v = []
- self.id = Poly.ids
- self.boundz = None
- self.edges = None
- def getID(self):
- return self.id
- def normal(self):
- a =self.v[0]
- b=self.v[1]
- c=self.v[2]
- p = b-a
- p.resize3D()
- q = a-c
- q.resize3D()
- return p.cross(q)
- def makeEdges(self):
- self.edges = []
- for i in xrange(self.nPoints()):
- self.edges.append(Edge( self.v[i % self.nPoints()], self.v[ (i+1) % self.nPoints()] ))
- def edgeAt(self, i):
- if(self.edges==None):
- self.makeEdges()
- return self.edges[i]
- def intersects2D(self, poly):
- for i in xrange(self.nPoints()):
- edge = self.edgeAt(i)
- for j in xrange(poly.nPoints()):
- if edge.intersects2D(poly.edgeAt(j)):
- return True
- return False
- def isBad(self):
- badness = 0
- for vv in self.v:
- if(vv.x!=vv.x or vv.y!=vv.y or vv.z!=vv.z): # Nan check
- badness+=1
- return (badness>0)
- def midpoint(self):
- x=y=z = 0.0
- n = 0
- for vv in self.v:
- x+=vv.x
- y+=vv.y
- z+=vv.z
- n+=1
- return [ x/n, y/n, z/n ]
- def centerAtOrigin(self):
- mp = self.midpoint()
- mp = -mp
- toOrigin = TranslationMatrix(mp)
- self.v = [(vv * toOrigin) for vv in self.v]
- def move(self, tv):
- mv = TranslationMatrix(tv)
- self.v = [(vv * mv) for vv in self.v]
- def scale(self, s):
- mp = Vector(self.midpoint())
- fromOrigin = TranslationMatrix(mp)
- mp = -mp
- toOrigin = TranslationMatrix(mp)
- sm = ScaleMatrix(s, 4)
- # Todo, the 3 lines below in 1 LC
- self.v = [(vv * toOrigin) for vv in self.v]
- self.v = [(sm * vv) for vv in self.v]
- self.v = [(vv * fromOrigin) for vv in self.v]
- def nPoints(self):
- return len(self.v)
- def size(self):
- return len(self.v)
- def rotated(self, axis, angle):
- p = self.clone()
- p.rotate(axis, angle)
- return p
- def rotate(self, axis, angle):
- rotation = RotationMatrix(angle, 4, "r", axis.vector)
- toOrigin = TranslationMatrix(axis.v1n)
- fromOrigin = TranslationMatrix(axis.v1)
- # Todo, the 3 lines below in 1 LC
- self.v = [(vv * toOrigin) for vv in self.v]
- self.v = [(rotation * vv) for vv in self.v]
- self.v = [(vv * fromOrigin) for vv in self.v]
- def moveAlong(self, vector, distance):
- t = TranslationMatrix(vector)
- s = ScaleMatrix(distance, 4)
- ts = t*s
- self.v = [(vv * ts) for vv in self.v]
- def bounds(self):
- if(self.boundz == None):
- vv = [vv for vv in self.v]
- vv.sort(key=lambda v: v.x)
- minx = vv[0].x
- maxx = vv[len(vv)-1].x
- vv.sort(key=lambda v: v.y)
- miny = vv[0].y
- maxy = vv[len(vv)-1].y
- self.boundz = [Vector(minx, miny, 0), Vector(maxx, maxy, 0)]
- return self.boundz
- def fromBlenderFace(bface):
- p = Poly()
- for vv in bface.v:
- vec = Vector([vv.co[0], vv.co[1], vv.co[2] , 1.0])
- p.v.append(vec)
- return p
- fromBlenderFace = staticmethod(fromBlenderFace)
- def fromList(list):
- p = Poly()
- for vv in list:
- vec = Vector( [vvv for vvv in vv] )
- vec.resize4D()
- p.v.append(vec)
- return p
- fromList = staticmethod(fromList)
- def fromVectors(vectors):
- p = Poly()
- p.v.extend([v.copy().resize4D() for v in vectors])
- return p
- fromVectors = staticmethod(fromVectors)
- def clone(self):
- p = Poly()
- p.v.extend(self.v)
- return p
- def hasVertex(self, ttv):
- v = Mathutils.Vector(ttv)
- v.normalize()
- for tv in self.v:
- vv = Mathutils.Vector(tv)
- vv.normalize()
- t = 0.00001
- if abs(vv.x-v.x)<t and abs(vv.y-v.y)<t:
- return True
- return False
- def overlays(self, poly):
- if len(poly.v)!=len(self.v):
- return False
- c = 0
- for point in poly.v:
- if self.hasVertex(point):
- c+=1
- return c==len(self.v)
- def sharesVertexWith(self, poly):
- for point in poly.v:
- if(self.hasVertex(point)):
- return True
- return False
- def containsAnyOf(self, poly):
- for point in poly.v:
- if(not(self.hasVertex(point))):
- if self.contains(point):
- return True
- return False
- def toString(self):
- return self.v
- # This is the BEST algorithm for point-in-polygon detection.
- # It's by W. Randolph Franklin.
- # returns 1 for inside, 1 or 0 for edges
- def contains(self, tp):
- c = 0
- j = len(self.v)-1
- for i in xrange(len(self.v)):
- if(i>0): j=i-1
- cv = self.v[i]
- nv = self.v[j]
- if ((((cv.y<=tp.y) and (tp.y<nv.y)) or ((nv.y<=tp.y) and (tp.y<cv.y))) and (tp.x < (nv.x - cv.x) * (tp.y - cv.y) / (nv.y - cv.y) + cv.x)):
- c = not(c)
- return (c == 1)
-
-class SVGExporter:
- def __init__(self, net, filename):
- self.net = net
- print self.net.des.name
- self.object = self.net.object
- print "Exporting ", self.object
- self.filename = filename
- self.file = None
- self.e = None
- self.width = 1024
- self.height = 768
- def start(self):
- print "Exporting SVG to ", self.filename
- self.file = open(self.filename, 'w')
- self.e = xml.sax.saxutils.XMLGenerator(self.file, "UTF-8")
- atts = {}
- atts["width"] = "100%"
- atts["height"] = "100%"
- atts["viewBox"] = str(self.vxmin)+" "+str(self.vymin)+" "+str(self.vxmax-self.vxmin)+" "+str(self.vymax-self.vymin)
- atts["xmlns:nets"] = "http://celeriac.net/unfolder/rdf#"
- atts["xmlns:xlink"] = "http://www.w3.org/1999/xlink"
- atts["xmlns"] ="http://www.w3.org/2000/svg"
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startDocument()
- self.e.startElement("svg", a)
- self.e.startElement("defs", xml.sax.xmlreader.AttributesImpl({}))
- atts = {}
- atts["type"]="text/css"
- self.e.startElement("style", atts)
- # can't find a proper way to do this
- self.file.write("<![CDATA[")
- self.file.write("polygon.poly{fill:white;stroke:black;stroke-width: 0.001}")
- self.file.write("g#foldLines line.valley{stroke:white;stroke-width:0.01;stroke-dasharray:0.02,0.01,0.02,0.05}")
- self.file.write("g#foldLines line.mountain{stroke:white;stroke-width:0.01;stroke-dasharray:0.02,0.04}")
- self.file.write("]]>")
- self.e.endElement("style")
- self.e.endElement("defs")
- #self.addClipPath()
- self.addMeta()
- def addMeta(self):
- self.e.startElement("metadata", xml.sax.xmlreader.AttributesImpl({}))
- self.e.startElement("nets:net", xml.sax.xmlreader.AttributesImpl({}))
- for i in xrange(1, len(self.net.folds)):
- fold = self.net.folds[i]
- # AttributesNSImpl - documentation is rubbish. using this hack.
- atts = {}
- atts["nets:id"] = "fold"+str(fold.getID())
- if(fold.parent!=None):
- atts["nets:parent"] = "fold"+str(fold.parent.getID())
- else:
- atts["nets:parent"] = "null"
- atts["nets:da"] = str(fold.dihedralAngle())
- if(fold.parent!=None):
- atts["nets:ofPoly"] = "poly"+str(fold.parent.foldingPoly.getID())
- else:
- atts["nets:ofPoly"] = ""
- atts["nets:toPoly"] = "poly"+str(fold.foldingPoly.getID())
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("nets:fold", a)
- self.e.endElement("nets:fold")
- self.e.endElement("nets:net")
- self.e.endElement("metadata")
- def end(self):
- self.e.endElement("svg")
- self.e.endDocument()
- print "grown."
- def export(self):
- self.net.unfoldTo(1)
- bb = self.object.getBoundBox()
- print bb
- self.vxmin = bb[0][0]
- self.vymin = bb[0][1]
- self.vxmax = bb[7][0]
- self.vymax = bb[7][1]
- self.start()
- atts = {}
- atts["id"] = self.object.getName()
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("g", a)
- #self.addUVImage()
- self.addPolys()
- self.addFoldLines()
- #self.addCutLines()
- self.e.endElement("g")
- self.end()
- def addClipPath(self):
- atts = {}
- atts["id"] = "netClip"
- atts["clipPathUnits"] = "userSpaceOnUse"
- atts["x"] = str(self.vxmin)
- atts["y"] = str(self.vymin)
- atts["width"] = "100%"
- atts["height"] = "100%"
- self.e.startElement("clipPath", atts)
- self.addPolys()
- self.e.endElement("clipPath")
- def addUVImage(self):
- image = Blender.Image.GetCurrent() #hmm - how to determine the desired image ?
- if image==None:
- return
- ifn = image.getFilename()
- ifn = self.filename.replace(".svg", ".jpg")
- image.setFilename(ifn)
- ifn = ifn[ifn.rfind("/")+1:]
- image.save()
- atts = {}
- atts["clip-path"] = "url(#netClip)"
- atts["xlink:href"] = ifn
- self.e.startElement("image", atts)
- self.e.endElement("image")
- def addPolys(self):
- atts = {}
- atts["id"] = "polys"
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("g", a)
- for i in xrange(len(self.net.folds)):
- self.addPoly(self.net.folds[i])
- self.e.endElement("g")
- def addFoldLines(self):
- atts = {}
- atts["id"] = "foldLines"
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("g", a)
- for i in xrange( 1, len(self.net.folds)):
- self.addFoldLine(self.net.folds[i])
- self.e.endElement("g")
- def addFoldLine(self, fold):
- edge = fold.edge.mapTo(fold.parent.foldingPoly)
- if fold.dihedralAngle()>0:
- foldType="valley"
- else:
- foldType="mountain"
- atts={}
- atts["x1"] = str(edge.v1.x)
- atts["y1"] = str(edge.v1.y)
- atts["x2"] = str(edge.v2.x)
- atts["y2"] = str(edge.v2.y)
- atts["id"] = "fold"+str(fold.getID())
- atts["class"] = foldType
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("line", a)
- self.e.endElement("line")
- def addCutLines(self):
- atts = {}
- atts["id"] = "cutLines"
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("g", a)
- for i in xrange( 1, len(self.net.cuts)):
- self.addCutLine(self.net.cuts[i])
- self.e.endElement("g")
- def addCutLine(self, cut):
- edge = cut.edge.mapTo(cut.parent.foldingPoly)
- if cut.dihedralAngle()>0:
- foldType="valley"
- else:
- foldType="mountain"
- atts={}
- atts["x1"] = str(edge.v1.x)
- atts["y1"] = str(edge.v1.y)
- atts["x2"] = str(edge.v2.x)
- atts["y2"] = str(edge.v2.y)
- atts["id"] = "cut"+str(cut.getID())
- atts["class"] = foldType
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("line", a)
- self.e.endElement("line")
- def addPoly(self, fold):
- face = fold.foldingPoly
- atts = {}
- if fold.desFace.col:
- col = fold.desFace.col[0]
- rgb = "rgb("+str(col.r)+","+str(col.g)+","+str(col.b)+")"
- atts["fill"] = rgb
- atts["class"] = "poly"
- atts["id"] = "poly"+str(face.getID())
- points = ""
- first = True
- for vv in face.v:
- if(not(first)):
- points+=','
- first = False
- points+=str(vv[0])
- points+=' '
- points+=str(vv[1])
- atts["points"] = points
- a = xml.sax.xmlreader.AttributesImpl(atts)
- self.e.startElement("polygon", a)
- self.e.endElement("polygon")
- def fileSelected(filename):
- try:
- net = Registry.GetKey('unfolder')['net']
- exporter = SVGExporter(net, filename)
- exporter.export()
- except:
- print "Problem exporting SVG"
- traceback.print_exc(file=sys.stdout)
- fileSelected = staticmethod(fileSelected)
-
-# for importing nets saved by the above exporter
-class NetHandler(xml.sax.handler.ContentHandler):
- def __init__(self, net):
- self.net = net
- self.first = (41==41)
- self.currentElement = None
- self.chars = None
- self.currentAction = None
- self.foldsPending = {}
- self.polys = {}
- self.actions = {}
- self.actions["nets:fold"] = self.foldInfo
- self.actions["line"] = self.cutOrFold
- self.actions["polygon"] = self.createPoly
- def setDocumentLocator(self, locator):
- pass
- def startDocument(self):
- pass
- def endDocument(self):
- for fold in self.foldsPending.values():
- face = self.net.addFace(fold.unfoldedFace())
- fold.desFace = face
- self.net.folds.append(fold)
- self.net.addFace(self.first)
- self.foldsPending = None
- self.polys = None
- def startPrefixMapping(self, prefix, uri):
- pass
- def endPrefixMapping(self, prefix):
- pass
- def startElement(self, name, attributes):
- self.currentAction = None
- try:
- self.currentAction = self.actions[name]
- except:
- pass
- if(self.currentAction!=None):
- self.currentAction(attributes)
- def endElement(self, name):
- pass
- def startElementNS(self, name, qname, attrs):
- self.currentAction = self.actions[name]
- if(self.currentAction!=None):
- self.currentAction(attributes)
- def endElementNS(self, name, qname):
- pass
- def characters(self, content):
- pass
- def ignorableWhitespace(self):
- pass
- def processingInstruction(self, target, data):
- pass
- def skippedEntity(self, name):
- pass
- def foldInfo(self, atts):
- self.foldsPending[atts["nets:id"]] = atts
- def createPoly(self, atts):
- xy = re.split('[, ]' , atts["points"])
- vectors = []
- for i in xrange(0, len(xy)-1, 2):
- v = Vector([float(xy[i]), float(xy[i+1]), 0.0])
- vectors.append(v)
- poly = Poly.fromVectors(vectors)
- if(self.first==True):
- self.first = poly
- self.polys[atts["id"]] = poly
- def cutOrFold(self, atts):
- fid = atts["id"]
- try:
- fi = self.foldsPending[fid]
- except:
- pass
- p1 = Vector([float(atts["x1"]), float(atts["y1"]), 0.0])
- p2 = Vector([float(atts["x2"]), float(atts["y2"]), 0.0])
- edge = Edge(p1, p2)
- parent = None
- ofPoly = None
- toPoly = None
- try:
- parent = self.foldsPending[fi["nets:parent"]]
- except:
- pass
- try:
- ofPoly = self.polys[fi["nets:ofPoly"]]
- except:
- pass
- try:
- toPoly = self.polys[fi["nets:toPoly"]]
- except:
- pass
- fold = Fold(parent, ofPoly , toPoly, edge, float(fi["nets:da"]))
- self.foldsPending[fid] = fold
- def fileSelected(filename):
- try:
- net = Net.importNet(filename)
- try:
- Registry.GetKey('unfolder')['net'] = net
- except:
- Registry.SetKey('unfolder', {})
- Registry.GetKey('unfolder')['net'] = net
- Registry.GetKey('unfolder')['lastpath'] = filename
- except:
- print "Problem importing SVG"
- traceback.print_exc(file=sys.stdout)
- fileSelected = staticmethod(fileSelected)
-
-
-class GUI:
- def __init__(self):
- self.overlaps = Draw.Create(0)
- self.ani = Draw.Create(0)
- self.selectedFaces =0
- self.search = Draw.Create(0)
- self.diffuse = True
- self.ancestors = Draw.Create(0)
- self.noise = Draw.Create(0.0)
- self.shape = Draw.Create(0)
- self.nOverlaps = 1==2
- self.iterators = [RandomEdgeIterator,Brightest,Curvature,EdgeIterator,OddEven,Largest]
- self.iterator = RandomEdgeIterator
- self.overlapsText = "*"
- self.message = " "
- def makePopupGUI(self):
- useRandom = Draw.Create(0)
- pub = []
- pub.append(("Search", self.search, "Search for non-overlapping net (maybe forever)"))
- pub.append(("Random", useRandom, "Random style net"))
- ok = True
- while ok:
- ok = Blender.Draw.PupBlock("Unfold", pub)
- if ok:
- if useRandom.val:
- self.iterator = RandomEdgeIterator
- else:
- self.iterator = Curvature
- self.unfold()
- def makeStandardGUI(self):
- Draw.Register(self.draw, self.keyOrMouseEvent, self.buttonEvent)
- def installScriptLink(self):
- print "Adding script link for animation"
- s = Blender.Scene.GetCurrent().getScriptLinks("FrameChanged")
- if(s!=None and s.count("frameChanged.py")>0):
- return
- try:
- script = Blender.Text.Get("frameChanged.py")
- except:
- script = Blender.Text.New("frameChanged.py")
- script.write("import Blender\n")
- script.write("import mesh_unfolder as Unfolder\n")
- script.write("u = Blender.Registry.GetKey('unfolder')\n")
- script.write("if u!=None:\n")
- script.write("\tn = u['net']\n")
- script.write("\tif(n!=None and n.animates):\n")
- script.write("\t\tn.unfoldToCurrentFrame()\n")
- Blender.Scene.GetCurrent().addScriptLink("frameChanged.py", "FrameChanged")
- def unfold(self):
- anc = self.ancestors.val
- n = 0.0
- s = True
- self.nOverlaps = 0
- searchLimit = 10
- search = 1
- Draw.Redraw(1)
- net = None
- name = None
- try:
- self.say("Unfolding...")
- Draw.Redraw(1)
- while(s):# and search < searchLimit):
- if(net!=None):
- name = net.des.name
- net = Net.fromSelected(self, name)
- net.setAvoidsOverlaps(not(self.overlaps.val))
- print
- print "Unfolding selected object"
- net.edgeIteratorClass = self.iterator
- print "Using ", net.edgeIteratorClass
- net.animates = self.ani.val
- self.diffuse = (self.ancestors.val==0)
- net.diffuse = self.diffuse
- net.generations = self.ancestors.val
- net.noise = self.noise.val
- print "even:", net.diffuse, " depth:", net.generations
- net.unfold()
- n = net.report()
- t = "."
- if(n<1.0):
- t = "Overlaps>="+str(n)
- else:
- t = "A complete net."
- self.nOverlaps = (n>=1)
- if(self.nOverlaps):
- self.say(self.message+" - unfolding failed - try again ")
- elif(not(self.overlaps.val)):
- self.say("Success. Complete net - no overlaps ")
- else:
- self.say("Unfolding complete")
- self.ancestors.val = anc
- s = (self.search.val and n>=1.0)
- dict = Registry.GetKey('unfolder')
- if(not(dict)):
- dict = {}
- dict['net'] = net
- Registry.SetKey('unfolder', dict)
- if(s):
- net = net.clone()
- search += 1
- except(IndexError):
- self.say("Please select an object to unfold")
- except:
- self.say("Problem unfolding selected object - see console for details")
- print "Problem unfolding selected object:"
- print sys.exc_info()[1]
- traceback.print_exc(file=sys.stdout)
- if(self.ani):
- if Registry.GetKey('unfolder')==None:
- print "no net!"
- return
- Registry.GetKey('unfolder')['net'].sortOutIPOSource()
- self.installScriptLink()
- Draw.Redraw(1)
- def keyOrMouseEvent(self, evt, val):
- if (evt == Draw.ESCKEY and not val):
- Draw.Exit()
- def buttonEvent(self, evt):
- if (evt == 1):
- self.unfold()
- if (evt == 5):
- try:
- Registry.GetKey('unfolder')['net'].setAvoidsOverlaps(self.overlaps.val)
- except:
- pass
- if (evt == 2):
- print "Trying to set IPO curve"
- try:
- s = Blender.Object.GetSelected()
- if(s!=None):
- Registry.GetKey('unfolder')['net'].setIPOSource( s[0] )
- print "Set IPO curve"
- else:
- print "Please select an object to use the IPO of"
- except:
- print "Problem setting IPO source"
- Draw.Redraw(1)
- if (evt == 6):
- Draw.Exit()
- if (evt == 7):
- try:
- if (Registry.GetKey('unfolder')['net']!=None):
- Registry.GetKey('unfolder')['net'].animates = self.ani.val
- if(self.ani):
- Registry.GetKey('unfolder')['net'].sortOutIPOSource()
- self.installScriptLink()
- except:
- print sys.exc_info()[1]
- traceback.print_exc(file=sys.stdout)
- Draw.Redraw(1)
- if (evt == 19):
- pass
- if (evt == 87):
- try:
- if (Registry.GetKey('unfolder')['net']!=None):
- Registry.GetKey('unfolder')['net'].assignUVs()
- self.say("Assigned UVs")
- except:
- print sys.exc_info()[1]
- traceback.print_exc(file=sys.stdout)
- Draw.Redraw(1)
- if(evt==91):
- if( testOverlap() == True):
- self.nOverlaps = 1
- else:
- self.nOverlaps = 0
- Draw.Redraw(1)
- if(evt==233):
- f1 = Poly.fromBlenderFace(Blender.Object.GetSelected()[0].getData().faces[0])
- f2 = Poly.fromBlenderFace(Blender.Object.GetSelected()[1].getData().faces[0])
- print
- print Blender.Object.GetSelected()[0].getName()
- print Blender.Object.GetSelected()[1].getName()
- print f1.intersects2D(f2)
- print f2.intersects2D(f1)
- if(evt==714):
- Net.unfoldAll(self)
- Draw.Redraw(1)
- if(evt==713):
- self.iterator = self.iterators[self.shape.val]
- Draw.Redraw(1)
- if(evt==92):
- if( testContains() == True):
- self.nOverlaps = 1
- else:
- self.nOverlaps = 0
- Draw.Redraw(1)
- if(evt==104):
- try:
- filename = "net.svg"
- s = Blender.Object.GetSelected()
- if(s!=None and len(s)>0):
- filename = s[0].getName()+".svg"
- else:
- if (Registry.GetKey('unfolder')['net']!=None):
- filename = Registry.GetKey('unfolder')['net'].des.name
- if(filename==None):
- filename="net.svg"
- else:
- filename=filename+".svg"
- Window.FileSelector(SVGExporter.fileSelected, "Select filename", filename)
- except:
- print "Problem exporting SVG"
- traceback.print_exc(file=sys.stdout)
- if(evt==107):
- try:
- Window.FileSelector(NetHandler.fileSelected, "Select file")
- except:
- print "Problem importing SVG"
- traceback.print_exc(file=sys.stdout)
- def say(self, m):
- self.message = m
- Draw.Redraw(1)
- Window.Redraw(Window.Types.SCRIPT)
- def draw(self):
- cw = 64
- ch = 16
- l = FlowLayout(32, cw, ch, 350, 64)
- l.y = 70
- self.search = Draw.Toggle("search", 19, l.nx(), l.ny(), l.cw, l.ch, self.search.val, "Search for non-overlapping mesh (potentially indefinitely)")
- self.overlaps = Draw.Toggle("overlaps", 5, l.nx(), l.ny(), l.cw, l.ch, self.overlaps.val, "Allow overlaps / avoid overlaps - if off, will not place overlapping faces")
- self.ani = Draw.Toggle("ani", 7, l.nx(), l.ny(), l.cw, l.ch, self.ani.val, "Animate net")
- Draw.Button("uv", 87, l.nx(), l.ny(), l.cw, l.ch, "Assign net as UV to source mesh (overwriting existing UV)")
- Draw.Button("Unfold", 1, l.nx(), l.ny(), l.cw, l.ch, "Unfold selected mesh to net")
- Draw.Button("save", 104, l.nx(), l.ny(), l.cw, l.ch, "Save net as SVG")
- Draw.Button("load", 107, l.nx(), l.ny(), l.cw, l.ch, "Load net from SVG")
- #Draw.Button("test", 233, l.nx(), l.ny(), l.cw, l.ch, "test")
- # unfolding enthusiasts - try uncommenting this
- self.ancestors = Draw.Number("depth", 654, l.nx(), l.ny(), cw, ch, self.ancestors.val, 0, 9999, "depth of branching 0=diffuse")
- #self.noise = Draw.Number("noise", 631, l.nx(), l.ny(), cw, ch, self.noise.val, 0.0, 1.0, "noisyness of branching")
- #Draw.Button("UnfoldAll", 714, l.nx(), l.ny(), l.cw, l.ch, "Unfold all meshes and save their nets")
- options = "order %t|random %x0|brightest %x1|curvature %x2|winding %x3| 1010 %x4|largest %x5"
- self.shape = Draw.Menu(options, 713, l.nx(), l.ny(), cw, ch, self.shape.val, "shape of net")
- Draw.Button("exit", 6, l.nx(), l.ny(), l.cw, l.ch, "exit")
- BGL.glClearColor(0.3, 0.3, 0.3, 1)
- BGL.glColor3f(0.3,0.3,0.3)
- l.newLine()
- BGL.glRasterPos2i(32, 100)
- Draw.Text(self.message)
-
-class FlowLayout:
- def __init__(self, margin, cw, ch, w, h):
- self.x = margin-cw-4
- self.y = margin
- self.cw = cw
- self.ch = ch
- self.width = w
- self.height = h
- self.margin = margin
- def nx(self):
- self.x+=(self.cw+4)
- if(self.x>self.width):
- self.x = self.margin
- self.y-=self.ch+4
- return self.x
- def ny(self):
- return self.y
- def newLine(self):
- self.y-=self.ch+self.margin
- self.x = self.margin
-
-# if xml is None, then dont bother running the script
-if xml:
- try:
- sys.setrecursionlimit(10000)
- gui = GUI()
- gui.makeStandardGUI()
- #gui.makePopupGUI()
- except:
- traceback.print_exc(file=sys.stdout)
diff --git a/release/scripts/mesh_wire.py b/release/scripts/mesh_wire.py
deleted file mode 100644
index bd38c47a9b9..00000000000
--- a/release/scripts/mesh_wire.py
+++ /dev/null
@@ -1,290 +0,0 @@
-#!BPY
-"""
-Name: 'Solid Wireframe'
-Blender: 243
-Group: 'Mesh'
-Tooltip: 'Make a solid wireframe copy of this mesh'
-"""
-
-# --------------------------------------------------------------------------
-# Solid Wireframe1.0 by Campbell Barton (AKA Ideasman42)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-import Blender
-from Blender import Scene, Mesh, Window, sys
-from Blender.Mathutils import AngleBetweenVecs, TriangleNormal
-from BPyMesh import faceAngles # get angles for face cornders
-#import BPyMesh
-#reload(BPyMesh)
-#faceAngles = BPyMesh.faceAngles
-
-# works out the distanbce to inset the corners based on angles
-from BPyMathutils import angleToLength
-#import BPyMathutils
-#reload(BPyMathutils)
-#angleToLength = BPyMathutils.angleToLength
-
-import mesh_solidify
-
-import BPyMessages
-reload(BPyMessages)
-import bpy
-
-
-def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_SHARP, PREF_XSHARP):
- if not PREF_SHARP and PREF_XSHARP:
- PREF_XSHARP = False
-
- # This function runs out of editmode with a mesh
- # error cases are alredy checked for
-
- inset_half = PREF_THICKNESS / 2
- del PREF_THICKNESS
-
- ob = ob_orig.copy()
- me = me_orig.copy()
- ob.link(me)
- sce.objects.selected = []
- sce.objects.link(ob)
- ob.sel = True
- sce.objects.active = ob
-
- # Modify the object, should be a set
- FGON= Mesh.EdgeFlags.FGON
- edges_fgon = dict([(ed.key,None) for ed in me.edges if ed.flag & FGON])
- # edges_fgon.fromkeys([ed.key for ed in me.edges if ed.flag & FGON])
-
- del FGON
-
-
-
- # each face needs its own verts
- # orig_vert_count =len(me.verts)
- new_vert_count = len(me.faces) * 4
- for f in me.faces:
- if len(f) == 3:
- new_vert_count -= 1
-
- if PREF_SHARP == 0:
- new_faces_edge= {}
-
- def add_edge(i1,i2, ni1, ni2):
-
- if i1>i2:
- i1,i2 = i2,i1
- flip = True
- else:
- flip = False
- new_faces_edge.setdefault((i1,i2), []).append((ni1, ni2, flip))
-
-
- new_verts = []
- new_faces = []
- vert_index = len(me.verts)
-
- for f in me.faces:
- f_v_co = [v.co for v in f]
- angles = faceAngles(f_v_co)
- f_v_idx = [v.index for v in f]
-
- def new_vert(fi):
- co = f_v_co[fi]
- a = angles[fi]
- if a > 180:
- vert_inset = 1 * inset_half
- else:
- vert_inset = inset_half * angleToLength( abs((180-a) / 2) )
-
- # Calculate the inset direction
- co1 = f_v_co[fi-1]
- co2 = fi+1 # Wrap this index back to the start
- if co2 == len(f_v_co): co2 = 0
- co2 = f_v_co[co2]
-
- co1 = co1 - co
- co2 = co2 - co
- co1.normalize()
- co2.normalize()
- d = co1+co2
- # Done with inset direction
-
- d.length = vert_inset
- return co+d
-
- new_verts.extend([new_vert(i) for i in xrange(len(f_v_co))])
-
- if len(f_v_idx) == 4:
- faces = [\
- (f_v_idx[1], f_v_idx[0], vert_index, vert_index+1),\
- (f_v_idx[2], f_v_idx[1], vert_index+1, vert_index+2),\
- (f_v_idx[3], f_v_idx[2], vert_index+2, vert_index+3),\
- (f_v_idx[0], f_v_idx[3], vert_index+3, vert_index),\
- ]
- else:
- faces = [\
- (f_v_idx[1], f_v_idx[0], vert_index, vert_index+1),\
- (f_v_idx[2], f_v_idx[1], vert_index+1, vert_index+2),\
- (f_v_idx[0], f_v_idx[2], vert_index+2, vert_index),\
- ]
-
-
- if PREF_SHARP == 1:
- if not edges_fgon:
- new_faces.extend(faces)
- else:
- for nf in faces:
- i1,i2 = nf[0], nf[1]
- if i1>i2: i1,i2 = i2,i1
-
- if edges_fgon and (i1,i2) not in edges_fgon:
- new_faces.append(nf)
-
-
-
- elif PREF_SHARP == 0:
- for nf in faces:
- add_edge(*nf)
-
- vert_index += len(f_v_co)
-
- me.verts.extend(new_verts)
-
- if PREF_SHARP == 0:
- def add_tri_flipped(i1,i2,i3):
- try:
- if AngleBetweenVecs(me.verts[i1].no, TriangleNormal(me.verts[i1].co, me.verts[i2].co, me.verts[i3].co)) < 90:
- return i3,i2,i1
- else:
- return i1,i2,i3
- except:
- return i1,i2,i3
-
- # This stores new verts that use this vert
- # used for re-averaging this verts location
- # based on surrounding verts. looks better but not needed.
- vert_users = [set() for i in xrange(vert_index)]
-
- for (i1,i2), nf in new_faces_edge.iteritems():
-
- if len(nf) == 2:
- # Add the main face
- if edges_fgon and (i1,i2) not in edges_fgon:
- new_faces.append((nf[0][0], nf[0][1], nf[1][0], nf[1][1]))
-
-
- if nf[0][2]: key1 = nf[0][1],nf[0][0]
- else: key1 = nf[0][0],nf[0][1]
- if nf[1][2]: key2 = nf[1][1],nf[1][0]
- else: key2 = nf[1][0],nf[1][1]
-
- # CRAP, cont work out which way to flip so make it oppisite the verts normal.
-
- ###new_faces.append((i2, key1[0], key2[0])) # NO FLIPPING, WORKS THOUGH
- ###new_faces.append((i1, key1[1], key2[1]))
- new_faces.append(add_tri_flipped(i2, key1[0], key2[0]))
- new_faces.append(add_tri_flipped(i1, key1[1], key2[1]))
-
- # Average vert loction so its not tooo pointy
- # not realy needed but looks better
- vert_users[i2].update((key1[0], key2[0]))
- vert_users[i1].update((key1[1], key2[1]))
-
- if len(nf) == 1:
- if nf[0][2]: new_faces.append((nf[0][0], nf[0][1], i2, i1)) # flipped
- else: new_faces.append((i1,i2, nf[0][0], nf[0][1]))
-
-
- # average points now.
- for i, vusers in enumerate(vert_users):
- if vusers:
- co = me.verts[i].co
- co.zero()
-
- for ii in vusers:
- co += me.verts[ii].co
- co /= len(vusers)
-
- me.faces.delete(1, range(len(me.faces)))
-
- me.faces.extend(new_faces)
-
- # External function, solidify
- me.sel = True
- if PREF_SOLID:
- mesh_solidify.solidify(me, -inset_half*2, True, False, PREF_XSHARP)
-
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = bpy.data.scenes.active
-
- # Get the active object, there can only ever be 1
- # and the active object is always the editmode object.
- ob_act = sce.objects.active
-
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- # Saves the editmode state and go's out of
- # editmode if its enabled, we cant make
- # changes to the mesh data while in editmode.
- is_editmode = Window.EditMode()
- Window.EditMode(0)
-
- me = ob_act.getData(mesh=1) # old NMesh api is default
- if len(me.faces)==0:
- BPyMessages.Error_NoMeshFaces()
- if is_editmode: Window.EditMode(1)
- return
-
- # Create the variables.
- PREF_THICK = Blender.Draw.Create(0.005)
- PREF_SOLID = Blender.Draw.Create(1)
- PREF_SHARP = Blender.Draw.Create(1)
- PREF_XSHARP = Blender.Draw.Create(0)
-
- pup_block = [\
- ('Thick:', PREF_THICK, 0.0001, 2.0, 'Skin thickness in mesh space.'),\
- ('Solid Wire', PREF_SOLID, 'If Disabled, will use 6 sided wire segments'),\
- ('Sharp Wire', PREF_SHARP, 'Use the original mesh topology for more accurate sharp wire.'),\
- ('Extra Sharp', PREF_XSHARP, 'Use less geometry to create a sharper looking wire'),\
- ]
-
- if not Blender.Draw.PupBlock('Solid Wireframe', pup_block):
- if is_editmode: Window.EditMode(1)
- return
-
- Window.WaitCursor(1)
- t = sys.time()
-
- # Run the mesh editing function
- solid_wire(ob_act, me, sce, PREF_THICK.val, PREF_SOLID.val, PREF_SHARP.val, PREF_XSHARP.val)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'Solid Wireframe finished in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
- if is_editmode: Window.EditMode(1)
-
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/modules/autocomplete.py b/release/scripts/modules/autocomplete.py
new file mode 100644
index 00000000000..9dd489a178e
--- /dev/null
+++ b/release/scripts/modules/autocomplete.py
@@ -0,0 +1,211 @@
+
+
+def execute(bcon):
+ '''
+ This function has been taken from a BGE console autocomp I wrote a while ago
+ the dictionaty bcon is not needed but it means I can copy and paste from the old func
+ which works ok for now.
+
+ 'bcon' dictionary keys, set by the caller
+ * 'cursor' - index of the editing character (int)
+ * 'edit_text' - text string for editing (string)
+ * 'scrollback' - text to add to the scrollback, options are added here. (text)
+ * 'namespace' - namespace, (dictionary)
+
+ '''
+
+
+ def is_delimiter(ch):
+ '''
+ For skipping words
+ '''
+ if ch == '_':
+ return False
+ if ch.isalnum():
+ return False
+
+ return True
+
+ def is_delimiter_autocomp(ch):
+ '''
+ When autocompleteing will earch back and
+ '''
+ if ch in '._[] "\'':
+ return False
+ if ch.isalnum():
+ return False
+
+ return True
+
+
+ def do_autocomp(autocomp_prefix, autocomp_members):
+ '''
+ return text to insert and a list of options
+ '''
+ autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
+
+ print("AUTO: '%s'" % autocomp_prefix)
+ print("MEMBERS: '%s'" % str(autocomp_members))
+
+ if not autocomp_prefix:
+ return '', autocomp_members
+ elif len(autocomp_members) > 1:
+ # find a common string between all members after the prefix
+ # 'ge' [getA, getB, getC] --> 'get'
+
+ # get the shortest member
+ min_len = min([len(v) for v in autocomp_members])
+
+ autocomp_prefix_ret = ''
+
+ for i in range(len(autocomp_prefix), min_len):
+ char_soup = set()
+ for v in autocomp_members:
+ char_soup.add(v[i])
+
+ if len(char_soup) > 1:
+ break
+ else:
+ autocomp_prefix_ret += char_soup.pop()
+
+ return autocomp_prefix_ret, autocomp_members
+ elif len(autocomp_members) == 1:
+ if autocomp_prefix == autocomp_members[0]:
+ # the variable matched the prefix exactly
+ # add a '.' so you can quickly continue.
+ # Could try add [] or other possible extensions rather then '.' too if we had the variable.
+ return '.', []
+ else:
+ # finish off the of the word word
+ return autocomp_members[0][len(autocomp_prefix):], []
+ else:
+ return '', []
+
+
+ def BCon_PrevChar(bcon):
+ cursor = bcon['cursor']-1
+ if cursor<0:
+ return None
+
+ try:
+ return bcon['edit_text'][cursor]
+ except:
+ return None
+
+
+ def BCon_NextChar(bcon):
+ try:
+ return bcon['edit_text'][bcon['cursor']]
+ except:
+ return None
+
+ def BCon_cursorLeft(bcon):
+ bcon['cursor'] -= 1
+ if bcon['cursor'] < 0:
+ bcon['cursor'] = 0
+
+ def BCon_cursorRight(bcon):
+ bcon['cursor'] += 1
+ if bcon['cursor'] > len(bcon['edit_text']):
+ bcon['cursor'] = len(bcon['edit_text'])
+
+ def BCon_AddScrollback(bcon, text):
+
+ bcon['scrollback'] = bcon['scrollback'] + text
+
+
+ def BCon_cursorInsertChar(bcon, ch):
+ if bcon['cursor']==0:
+ bcon['edit_text'] = ch + bcon['edit_text']
+ elif bcon['cursor']==len(bcon['edit_text']):
+ bcon['edit_text'] = bcon['edit_text'] + ch
+ else:
+ bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
+
+ bcon['cursor']
+ if bcon['cursor'] > len(bcon['edit_text']):
+ bcon['cursor'] = len(bcon['edit_text'])
+ BCon_cursorRight(bcon)
+
+
+ TEMP_NAME = '___tempname___'
+
+ cursor_orig = bcon['cursor']
+
+ ch = BCon_PrevChar(bcon)
+ while ch != None and (not is_delimiter(ch)):
+ ch = BCon_PrevChar(bcon)
+ BCon_cursorLeft(bcon)
+
+ if ch != None:
+ BCon_cursorRight(bcon)
+
+ #print (cursor_orig, bcon['cursor'])
+
+ cursor_base = bcon['cursor']
+
+ autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
+
+ print("PREFIX:'%s'" % autocomp_prefix)
+
+ # Get the previous word
+ if BCon_PrevChar(bcon)=='.':
+ BCon_cursorLeft(bcon)
+ ch = BCon_PrevChar(bcon)
+ while ch != None and is_delimiter_autocomp(ch)==False:
+ ch = BCon_PrevChar(bcon)
+ BCon_cursorLeft(bcon)
+
+ cursor_new = bcon['cursor']
+
+ if ch != None:
+ cursor_new+=1
+
+ pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
+ print("AUTOCOMP EVAL: '%s'" % pytxt)
+ #try:
+ if pytxt:
+ bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
+ # print val
+ else: ##except:
+ val = None
+
+ try:
+ val = bcon['namespace'][TEMP_NAME]
+ del bcon['namespace'][TEMP_NAME]
+ except:
+ val = None
+
+ if val:
+ autocomp_members = dir(val)
+
+ autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
+
+ bcon['cursor'] = cursor_orig
+ for v in autocomp_prefix_ret:
+ BCon_cursorInsertChar(bcon, v)
+ cursor_orig = bcon['cursor']
+
+ if autocomp_members:
+ BCon_AddScrollback(bcon, ', '.join(autocomp_members))
+
+ del val
+
+ else:
+ # Autocomp global namespace
+ autocomp_members = bcon['namespace'].keys()
+
+ if autocomp_prefix:
+ autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
+
+ autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
+
+ bcon['cursor'] = cursor_orig
+ for v in autocomp_prefix_ret:
+ BCon_cursorInsertChar(bcon, v)
+ cursor_orig = bcon['cursor']
+
+ if autocomp_members:
+ BCon_AddScrollback(bcon, ', '.join(autocomp_members))
+
+ bcon['cursor'] = cursor_orig \ No newline at end of file
diff --git a/release/ui/bpy_ops.py b/release/scripts/modules/bpy_ops.py
index dff8125fca1..83c2e82bf6c 100644
--- a/release/ui/bpy_ops.py
+++ b/release/scripts/modules/bpy_ops.py
@@ -3,6 +3,7 @@ from bpy.__ops__ import add as op_add
from bpy.__ops__ import remove as op_remove
from bpy.__ops__ import dir as op_dir
from bpy.__ops__ import call as op_call
+from bpy.__ops__ import as_string as op_as_string
from bpy.__ops__ import get_rna as op_get_rna
# Keep in sync with WM_types.h
@@ -130,7 +131,10 @@ class bpy_ops_submodule_op(object):
return op_get_rna(self.idname())
- def __repr__(self):
+ def __repr__(self): # useful display, repr(op)
+ return op_as_string(self.idname())
+
+ def __str__(self): # used for print(...)
return "<function bpy.ops.%s.%s at 0x%x'>" % (self.module, self.func, id(self))
import bpy
diff --git a/release/scripts/modules/bpy_sys.py b/release/scripts/modules/bpy_sys.py
new file mode 100644
index 00000000000..e60e8b01d09
--- /dev/null
+++ b/release/scripts/modules/bpy_sys.py
@@ -0,0 +1,12 @@
+import bpy
+import os
+
+def expandpath(path):
+ if path.startswith("//"):
+ return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
+
+ return path
+
+import types
+bpy.sys = types.ModuleType("bpy.sys")
+bpy.sys.expandpath = expandpath
diff --git a/release/scripts/ms3d_import.py b/release/scripts/ms3d_import.py
deleted file mode 100644
index c1438cbfc97..00000000000
--- a/release/scripts/ms3d_import.py
+++ /dev/null
@@ -1,487 +0,0 @@
-#!BPY
-"""
-Name: 'MilkShape3D (.ms3d)...'
-Blender: 245
-Group: 'Import'
-Tooltip: 'Import from MilkShape3D file format (.ms3d)'
-"""
-#
-# Author: Markus Ilmola
-# Email: markus.ilmola@pp.inet.fi
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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.
-#
-
-# import needed stuff
-import os.path
-import math
-from math import *
-import struct
-import Blender
-from Blender import Mathutils
-from Blender.Mathutils import *
-
-
-# trims a string by removing ending 0 and everything after it
-def uku(s):
- try:
- return s[:s.index('\0')]
- except:
- return s
-
-
-# Converts ms3d euler angles to a rotation matrix
-def RM(a):
- sy = sin(a[2])
- cy = cos(a[2])
- sp = sin(a[1])
- cp = cos(a[1])
- sr = sin(a[0])
- cr = cos(a[0])
- return Matrix([cp*cy, cp*sy, -sp], [sr*sp*cy+cr*-sy, sr*sp*sy+cr*cy, sr*cp],[cr*sp*cy+-sr*-sy, cr*sp*sy+-sr*cy, cr*cp])
-
-
-# Converts ms3d euler angles to a quaternion
-def RQ(a):
- angle = a[2] * 0.5;
- sy = sin(angle);
- cy = cos(angle);
- angle = a[1] * 0.5;
- sp = sin(angle);
- cp = cos(angle);
- angle = a[0] * 0.5;
- sr = sin(angle);
- cr = cos(angle);
- return Quaternion(cr*cp*cy+sr*sp*sy, sr*cp*cy-cr*sp*sy, cr*sp*cy+sr*cp*sy, cr*cp*sy-sr*sp*cy)
-
-
-# takes a texture filename and tries to load it
-def loadImage(path, filename):
- image = None
- try:
- image = Blender.Image.Load(os.path.abspath(filename))
- except IOError:
- print "Warning: Failed to load image: " + filename + ". Trying short path instead...\n"
- try:
- image = Blender.Image.Load(os.path.dirname(path) + "/" + os.path.basename(filename))
- except IOError:
- print "Warning: Failed to load image: " + os.path.basename(filename) + "!\n"
- return image
-
-
-# imports a ms3d file to the current scene
-def import_ms3d(path):
- # get scene
- scn = Blender.Scene.GetCurrent()
- if scn == None:
- return "No scene to import to!"
-
- # open the file
- try:
- file = open(path, 'rb')
- except IOError:
- return "Failed to open the file!"
-
- # get the file size
- file.seek(0, os.SEEK_END);
- fileSize = file.tell();
- file.seek(0, os.SEEK_SET);
-
- # read id to check if the file is a MilkShape3D file
- id = file.read(10)
- if id!="MS3D000000":
- return "The file is not a MS3D file!"
-
- # read version
- version = struct.unpack("i", file.read(4))[0]
- if version!=4:
- return "The file has invalid version!"
-
- # Create the mesh
- scn.objects.selected = []
- mesh = Blender.Mesh.New("MilkShape3D Mesh")
- meshOb = scn.objects.new(mesh)
-
- # read the number of vertices
- numVertices = struct.unpack("H", file.read(2))[0]
-
- # read vertices
- coords = []
- boneIds = []
- for i in xrange(numVertices):
- # skip flags
- file.read(1)
-
- # read coords
- coords.append(struct.unpack("fff", file.read(3*4)))
-
- # read bone ids
- boneIds.append(struct.unpack("b", file.read(1))[0])
-
- # skip refcount
- file.read(1)
-
- # add the vertices to the mesh
- mesh.verts.extend(coords)
-
- # read number of triangles
- numTriangles = struct.unpack("H", file.read(2))[0]
-
- # read triangles
- faces = []
- uvs = []
- for i in xrange(numTriangles):
- # skip flags
- file.read(2)
-
- # read indices (faces)
- faces.append(struct.unpack("HHH", file.read(3*2)))
-
- # read normals
- normals = struct.unpack("fffffffff", file.read(3*3*4))
-
- # read texture coordinates
- s = struct.unpack("fff", file.read(3*4))
- t = struct.unpack("fff", file.read(3*4))
-
- # store texture coordinates
- uvs.append([[s[0], 1-t[0]], [s[1], 1-t[1]], [s[2], 1-t[2]]])
-
- if faces[-1][2] == 0: # Cant have zero at the third index
- faces[-1] = faces[-1][1], faces[-1][2], faces[-1][0]
- uvs[-1] = uvs[-1][1], uvs[-1][2], uvs[-1][0]
-
- # skip smooth group
- file.read(1)
-
- # skip group
- file.read(1)
-
- # add the faces to the mesh
- mesh.faces.extend(faces)
-
- # set texture coordinates
- for i in xrange(numTriangles):
- mesh.faces[i].uv = [Vector(uvs[i][0]), Vector(uvs[i][1]), Vector(uvs[i][2])]
-
- # read number of groups
- numGroups = struct.unpack("H", file.read(2))[0]
-
- # read groups
- for i in xrange(numGroups):
- # skip flags
- file.read(1)
-
- # skip name
- file.read(32)
-
- # read the number of triangles in the group
- numGroupTriangles = struct.unpack("H", file.read(2))[0]
-
- # read the group triangles
- if numGroupTriangles > 0:
- triangleIndices = struct.unpack(str(numGroupTriangles) + "H", file.read(2*numGroupTriangles));
-
- # read material
- material = struct.unpack("b", file.read(1))[0]
- if material>=0:
- for j in xrange(numGroupTriangles):
- mesh.faces[triangleIndices[j]].mat = material
-
- # read the number of materials
- numMaterials = struct.unpack("H", file.read(2))[0]
-
- # read materials
- for i in xrange(numMaterials):
- # read name
- name = uku(file.read(32))
-
- # create the material
- mat = Blender.Material.New(name)
- mesh.materials += [mat]
-
- # read ambient color
- ambient = struct.unpack("ffff", file.read(4*4))[0:3]
- mat.setAmb((ambient[0]+ambient[1]+ambient[2])/3)
-
- # read diffuse color
- diffuse = struct.unpack("ffff", file.read(4*4))[0:3]
- mat.setRGBCol(diffuse)
-
- # read specular color
- specular = struct.unpack("ffff", file.read(4*4))[0:3]
- mat.setSpecCol(specular)
-
- # read emissive color
- emissive = struct.unpack("ffff", file.read(4*4))[0:3]
- mat.setEmit((emissive[0]+emissive[1]+emissive[2])/3)
-
- # read shininess
- shininess = struct.unpack("f", file.read(4))[0]
-
- # read transparency
- transparency = struct.unpack("f", file.read(4))[0]
- mat.setAlpha(transparency)
- if transparency < 1:
- mat.mode |= Blender.Material.Modes.ZTRANSP
-
- # read mode
- mode = struct.unpack("B", file.read(1))[0]
-
- # read texturemap
- texturemap = uku(file.read(128))
- if len(texturemap)>0:
- colorTexture = Blender.Texture.New(name + "_texture")
- colorTexture.setType('Image')
- colorTexture.setImage(loadImage(path, texturemap))
- mat.setTexture(0, colorTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.COL)
-
- # read alphamap
- alphamap = uku(file.read(128))
- if len(alphamap)>0:
- alphaTexture = Blender.Texture.New(name + "_alpha")
- alphaTexture.setType('Image')
- alphaTexture.setImage(loadImage(path, alphamap))
- mat.setTexture(1, alphaTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.ALPHA)
-
- # read animation
- fps = struct.unpack("f", file.read(4))[0]
- time = struct.unpack("f", file.read(4))[0]
- frames = struct.unpack("i", file.read(4))[0]
-
- # read the number of joints
- numJoints = struct.unpack("H", file.read(2))[0]
-
- # create the armature
- armature = 0
- armOb = 0
- if numJoints > 0:
- armOb = Blender.Object.New('Armature', "MilkShape3D Skeleton")
- armature = Blender.Armature.New("MilkShape3D Skeleton")
- armature.drawType = Blender.Armature.STICK
- armOb.link(armature)
- scn.objects.link(armOb)
- armOb.makeParentDeform([meshOb])
- armature.makeEditable()
-
- # read joints
- joints = []
- rotKeys = {}
- posKeys = {}
- for i in xrange(numJoints):
- # skip flags
- file.read(1)
-
- # read name
- name = uku(file.read(32))
- joints.append(name)
-
- # create the bone
- bone = Blender.Armature.Editbone()
- armature.bones[name] = bone
-
- # read parent
- parent = uku(file.read(32))
- if len(parent)>0:
- bone.parent = armature.bones[parent]
-
- # read orientation
- rot = struct.unpack("fff", file.read(3*4))
-
- # read position
- pos = struct.unpack("fff", file.read(3*4))
-
- # set head
- if bone.hasParent():
- bone.head = Vector(pos) * bone.parent.matrix + bone.parent.head
- tempM = RM(rot) * bone.parent.matrix
- tempM.transpose;
- bone.matrix = tempM
- else:
- bone.head = Vector(pos)
- bone.matrix = RM(rot)
-
- # set tail
- bvec = bone.tail - bone.head
- bvec.normalize()
- bone.tail = bone.head + 0.01 * bvec
-
- # Create vertex group for this bone
- mesh.addVertGroup(name)
- vgroup = []
- for index, v in enumerate(boneIds):
- if v==i:
- vgroup.append(index)
- mesh.assignVertsToGroup(name, vgroup, 1.0, 1)
-
- # read the number of rotation keys
- numKeyFramesRot = struct.unpack("H", file.read(2))[0]
-
- # read the number of postions keys
- numKeyFramesPos = struct.unpack("H", file.read(2))[0]
-
- # read rotation keys
- rotKeys[name] = []
- for j in xrange(numKeyFramesRot):
- # read time
- time = fps * struct.unpack("f", file.read(4))[0]
- # read data
- rotKeys[name].append([time, struct.unpack("fff", file.read(3*4))])
-
- # read position keys
- posKeys[name] = []
- for j in xrange(numKeyFramesPos):
- # read time
- time = fps * struct.unpack("f", file.read(4))[0]
- # read data
- posKeys[name].append([time, struct.unpack("fff", file.read(3*4))])
-
- # create action and pose
- action = 0
- pose = 0
- if armature!=0:
- armature.update()
- pose = armOb.getPose()
- action = armOb.getAction()
- if not action:
- action = Blender.Armature.NLA.NewAction()
- action.setActive(armOb)
-
- # create animation key frames
- for name, pbone in pose.bones.items():
- # create position keys
- for key in posKeys[name]:
- pbone.loc = Vector(key[1])
- pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.LOC, True)
-
- # create rotation keys
- for key in rotKeys[name]:
- pbone.quat = RQ(key[1])
- pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.ROT, True)
-
- # The old format ends here. If there is more data then the file is newer version
-
- # check to see if there are any comments
- if file.tell()<fileSize:
-
- # read sub version
- subVersion = struct.unpack("i", file.read(4))[0]
-
- # Is the sub version a supported one
- if subVersion==1:
-
- # Group comments
- numComments = struct.unpack("i", file.read(4))[0]
- for i in range(numComments):
- file.read(4) # index
- size = struct.unpack("i", file.read(4))[0] # comment size
- if size>0:
- print "Group comment: " + file.read(size)
-
- # Material comments
- numComments = struct.unpack("i", file.read(4))[0]
- for i in range(numComments):
- file.read(4) # index
- size = struct.unpack("i", file.read(4))[0] # comment size
- if size>0:
- print "Material comment: " + file.read(size)
-
- # Joint comments
- numComments = struct.unpack("i", file.read(4))[0]
- for i in range(numComments):
- file.read(4) # index
- size = struct.unpack("i", file.read(4))[0] # comment size
- if size>0:
- print "Joint comment: " + file.read(size)
-
- # Model comments
- numComments = struct.unpack("i", file.read(4))[0]
- for i in range(numComments):
- file.read(4) # index
- size = struct.unpack("i", file.read(4))[0] # comment size
- if size>0:
- print "Model comment: " + file.read(size)
-
- # Unknown version give a warning
- else:
- print "Warning: Unknown version!"
-
-
- # check to see if there is any extra vertex data
- if file.tell()<fileSize:
-
- # read the subversion
- subVersion = struct.unpack("i", file.read(4))[0]
-
- # is the version supported
- if subVersion==2:
- # read the extra data for each vertex
- for i in xrange(numVertices):
- # bone ids
- ids = struct.unpack("bbb", file.read(3))
- # weights
- weights = struct.unpack("BBB", file.read(3))
- # extra
- extra = struct.unpack("I", file.read(4))
- # add extra vertices with weights to deform groups
- if ids[0]>=0 or ids[1]>=0 or ids[2]>=0:
- mesh.assignVertsToGroup(joints[boneIds[i]], [i], 0.01*weights[0], 1)
- if ids[0]>=0:
- mesh.assignVertsToGroup(joints[ids[0]], [i], 0.01*weights[1], 1)
- if ids[1]>=0:
- mesh.assignVertsToGroup(joints[ids[1]], [i], 0.01*weights[2], 1)
- if ids[2]>=0:
- mesh.assignVertsToGroup(joints[ids[2]], [i], 0.01*(100-(weights[0]+weights[1]+weights[2])), 1)
-
- elif subVersion==1:
- # read extra data for each vertex
- for i in xrange(numVertices):
- # bone ids
- ids = struct.unpack("bbb", file.read(3))
- # weights
- weights = struct.unpack("BBB", file.read(3))
- # add extra vertices with weights to deform groups
- if ids[0]>=0 or ids[1]>=0 or ids[2]>=0:
- mesh.assignVertsToGroup(joints[boneIds[i]], [i], 0.01*weights[0], 1)
- if ids[0]>=0:
- mesh.assignVertsToGroup(joints[ids[0]], [i], 0.01*weights[1], 1)
- if ids[1]>=0:
- mesh.assignVertsToGroup(joints[ids[1]], [i], 0.01*weights[2], 1)
- if ids[2]>=0:
- mesh.assignVertsToGroup(joints[ids[2]], [i], 0.01*(100-(weights[0]+weights[1]+weights[2])), 1)
-
- # non supported subversion give a warning
- else:
- print "Warning: Unknown subversion!"
-
- # rest of the extra data in the file is not imported/used
-
- # refresh the view
- Blender.Redraw()
-
- # close the file
- file.close()
-
- # succes return empty error string
- return ""
-
-
-# load the model
-def fileCallback(filename):
- error = import_ms3d(filename)
- if error!="":
- Blender.Draw.PupMenu("An error occured during import: " + error + "|Not all data might have been imported succesfully.", 2)
-
-Blender.Window.FileSelector(fileCallback, 'Import')
diff --git a/release/scripts/ms3d_import_ascii.py b/release/scripts/ms3d_import_ascii.py
deleted file mode 100644
index d8c22a1ec99..00000000000
--- a/release/scripts/ms3d_import_ascii.py
+++ /dev/null
@@ -1,479 +0,0 @@
-#!BPY
-"""
-Name: 'MilkShape3D ASCII (.txt)...'
-Blender: 245
-Group: 'Import'
-Tooltip: 'Import from a MilkShape3D ASCII file format (.txt)'
-"""
-#
-# Author: Markus Ilmola
-# Email: markus.ilmola@pp.inet.fi
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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.
-#
-
-# import needed stuff
-import os.path
-import re
-import math
-from math import *
-import Blender
-from Blender import Mathutils
-from Blender.Mathutils import *
-
-
-
-# Converts ms3d euler angles to a rotation matrix
-def RM(a):
- sy = sin(a[2])
- cy = cos(a[2])
- sp = sin(a[1])
- cp = cos(a[1])
- sr = sin(a[0])
- cr = cos(a[0])
- return Matrix([cp*cy, cp*sy, -sp], [sr*sp*cy+cr*-sy, sr*sp*sy+cr*cy, sr*cp],[cr*sp*cy+-sr*-sy, cr*sp*sy+-sr*cy, cr*cp])
-
-
-# Converts ms3d euler angles to a quaternion
-def RQ(a):
- angle = a[2] * 0.5;
- sy = sin(angle);
- cy = cos(angle);
- angle = a[1] * 0.5;
- sp = sin(angle);
- cp = cos(angle);
- angle = a[0] * 0.5;
- sr = sin(angle);
- cr = cos(angle);
- return Quaternion(cr*cp*cy+sr*sp*sy, sr*cp*cy-cr*sp*sy, cr*sp*cy+sr*cp*sy, cr*cp*sy-sr*sp*cy)
-
-
-# takes a texture filename and tries to load it
-def loadImage(path, filename):
- image = None
- try:
- image = Blender.Image.Load(os.path.abspath(filename))
- except IOError:
- print "Warning: Failed to load image: " + filename + ". Trying short path instead...\n"
- try:
- image = Blender.Image.Load(os.path.dirname(path) + "/" + os.path.basename(filename))
- except IOError:
- print "Warning: Failed to load image: " + os.path.basename(filename) + "!\n"
- return image
-
-
-
-# returns the next non-empty, non-comment line from the file
-def getNextLine(file):
- ready = False
- while ready==False:
- line = file.readline()
- if len(line)==0:
- print "Warning: End of file reached."
- return line
- ready = True
- line = line.strip()
- if len(line)==0 or line.isspace():
- ready = False
- if len(line)>=2 and line[0]=='/' and line[1]=='/':
- ready = False
- return line
-
-
-
-# imports a MilkShape3D ascii file to the current scene
-def import_ms3d_ascii(path):
- # limits
- MAX_NUMMESHES = 1000
- MAX_NUMVERTS = 100000
- MAX_NUMNORMALS = 100000
- MAX_NUMTRIS = 100000
- MAX_NUMMATS = 16
- MAX_NUMBONES = 100
- MAX_NUMPOSKEYS = 1000
- MAX_NUMROTKEYS = 1000
-
- # get scene
- scn = Blender.Scene.GetCurrent()
- if scn==None:
- return "No scene to import to!"
-
- # open the file
- try:
- file = open(path, 'r')
- except IOError:
- return "Failed to open the file!"
-
- # Read frame info
- try:
- lines = getNextLine(file).split()
- if len(lines) != 2 or lines[0] != "Frames:":
- raise ValueError
- lines = getNextLine(file).split()
- if len(lines) != 2 or lines[0] != "Frame:":
- raise ValueError
- except ValueError:
- return "Frame information is invalid!"
-
- # Create the mesh
- meshOb = Blender.Object.New('Mesh', "MilkShape3D Object")
- mesh = Blender.Mesh.New("MilkShape3D Mesh")
- meshOb.link(mesh)
- scn.objects.link(meshOb)
-
- # read the number of meshes
- try:
- lines = getNextLine(file).split()
- if len(lines)!=2 or lines[0]!="Meshes:":
- raise ValueError
- numMeshes = int(lines[1])
- if numMeshes < 0 or numMeshes > MAX_NUMMESHES:
- raise ValueError
- except ValueError:
- return "Number of meshes is invalid!"
-
- # read meshes
- vertBase = 0
- faceBase = 0
- boneIds = []
- for i in range(numMeshes):
- # read name, flags and material
- try:
- lines = re.findall(r'\".*\"|[^ ]+', getNextLine(file))
- if len(lines)!=3:
- raise ValueError
- material = int(lines[2])
- except ValueError:
- return "Name, flags or material in mesh " + str(i+1) + " are invalid!"
-
- # read the number of vertices
- try:
- numVerts = int(getNextLine(file))
- if numVerts < 0 or numVerts > MAX_NUMVERTS:
- raise ValueError
- except ValueError:
- return "Number of vertices in mesh " + str(i+1) + " is invalid!"
-
- # read vertices
- coords = []
- uvs = []
- for j in xrange(numVerts):
- try:
- lines = getNextLine(file).split()
- if len(lines)!=7:
- raise ValueError
- coords.append([float(lines[1]), float(lines[2]), float(lines[3])])
- uvs.append([float(lines[4]), 1-float(lines[5])])
- boneIds.append(int(lines[6]))
- except ValueError:
- return "Vertex " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
- mesh.verts.extend(coords)
-
- # read number of normals
- try:
- numNormals = int(getNextLine(file))
- if numNormals < 0 or numNormals > MAX_NUMNORMALS:
- raise ValueError
- except ValueError:
- return "Number of normals in mesh " + str(i+1) + " is invalid!"
-
- # read normals
- normals = []
- for j in xrange(numNormals):
- try:
- lines = getNextLine(file).split()
- if len(lines)!=3:
- raise ValueError
- normals.append([float(lines[0]), float(lines[1]), float(lines[2])])
- except ValueError:
- return "Normal " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
-
- # read the number of triangles
- try:
- numTris = int(getNextLine(file))
- if numTris < 0 or numTris > MAX_NUMTRIS:
- raise ValueError
- except ValueError:
- return "Number of triangles in mesh " + str(i+1) + " is invalid!"
-
- # read triangles
- faces = []
- for j in xrange(numTris):
- # read the triangle
- try:
- lines = getNextLine(file).split()
- if len(lines)!=8:
- raise ValueError
- v1 = int(lines[1])
- v2 = int(lines[2])
- v3 = int(lines[3])
- faces.append([v1+vertBase, v2+vertBase, v3+vertBase])
- except ValueError:
- return "Triangle " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
- mesh.faces.extend(faces)
-
- # set texture coordinates and material
- for j in xrange(faceBase, len(mesh.faces)):
- face = mesh.faces[j]
- face.uv = [Vector(uvs[face.verts[0].index-vertBase]), Vector(uvs[face.verts[1].index-vertBase]), Vector(uvs[face.verts[2].index-vertBase])]
- if material>=0:
- face.mat = material
-
- # increase vertex and face base
- vertBase = len(mesh.verts)
- faceBase = len(mesh.faces)
-
- # read the number of materials
- try:
- lines = getNextLine(file).split()
- if len(lines)!=2 or lines[0]!="Materials:":
- raise ValueError
- numMats = int(lines[1])
- if numMats < 0 or numMats > MAX_NUMMATS:
- raise ValueError
- except ValueError:
- return "Number of materials is invalid!"
-
- # read the materials
- for i in range(numMats):
- # read name
- name = getNextLine(file)[1:-1]
-
- # create the material
- mat = Blender.Material.New(name)
- mesh.materials += [mat]
-
- # read ambient color
- try:
- lines = getNextLine(file).split()
- if len(lines)!=4:
- raise ValueError
- amb = (float(lines[0])+float(lines[1])+float(lines[2]))/3
- mat.setAmb(amb)
- except ValueError:
- return "Ambient color in material " + str(i+1) + " is invalid!"
-
- # read diffuse color
- try:
- lines = getNextLine(file).split()
- if len(lines)!=4:
- raise ValueError
- mat.setRGBCol([float(lines[0]), float(lines[1]), float(lines[2])])
- except ValueError:
- return "Diffuse color in material " + str(i+1) + " is invalid!"
-
- # read specular color
- try:
- lines = getNextLine(file).split()
- if len(lines)!=4:
- raise ValueError
- mat.setSpecCol([float(lines[0]), float(lines[1]), float(lines[2])])
- except ValueError:
- return "Specular color in material " + str(i+1) + " is invalid!"
-
- # read emissive color
- try:
- lines = getNextLine(file).split()
- if len(lines)!=4:
- raise ValueError
- emit = (float(lines[0])+float(lines[1])+float(lines[2]))/3
- mat.setEmit(emit)
- except ValueError:
- return "Emissive color in material " + str(i+1) + " is invalid!"
-
- # read shininess
- try:
- shi = float(getNextLine(file))
- #mat.setHardness(int(shi))
- except ValueError:
- return "Shininess in material " + str(i+1) + " is invalid!"
-
- # read transparency
- try:
- alpha = float(getNextLine(file))
- mat.setAlpha(alpha)
- if alpha < 1:
- mat.mode |= Blender.Material.Modes.ZTRANSP
- except ValueError:
- return "Transparency in material " + str(i+1) + " is invalid!"
-
- # read texturemap
- texturemap = getNextLine(file)[1:-1]
- if len(texturemap)>0:
- colorTexture = Blender.Texture.New(name + "_texture")
- colorTexture.setType('Image')
- colorTexture.setImage(loadImage(path, texturemap))
- mat.setTexture(0, colorTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.COL)
-
- # read alphamap
- alphamap = getNextLine(file)[1:-1]
- if len(alphamap)>0:
- alphaTexture = Blender.Texture.New(name + "_alpha")
- alphaTexture.setType('Image')
- alphaTexture.setImage(loadImage(path, alphamap))
- mat.setTexture(1, alphaTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.ALPHA)
-
- # read the number of bones
- try:
- lines = getNextLine(file).split()
- if len(lines)!=2 or lines[0]!="Bones:":
- raise ValueError
- numBones = int(lines[1])
- if numBones < 0 or numBones > MAX_NUMBONES:
- raise ValueError
- except:
- return "Number of bones is invalid!"
-
- # create the armature
- armature = None
- armOb = None
- if numBones > 0:
- armOb = Blender.Object.New('Armature', "MilkShape3D Skeleton")
- armature = Blender.Armature.New("MilkShape3D Skeleton")
- armature.drawType = Blender.Armature.STICK
- armOb.link(armature)
- scn.objects.link(armOb)
- armOb.makeParentDeform([meshOb])
- armature.makeEditable()
-
- # read bones
- posKeys = {}
- rotKeys = {}
- for i in range(numBones):
- # read name
- name = getNextLine(file)[1:-1]
-
- # create the bone
- bone = Blender.Armature.Editbone()
- armature.bones[name] = bone
-
- # read parent
- parent = getNextLine(file)[1:-1]
- if len(parent)>0:
- bone.parent = armature.bones[parent]
-
- # read position and rotation
- try:
- lines = getNextLine(file).split()
- if len(lines) != 7:
- raise ValueError
- pos = [float(lines[1]), float(lines[2]), float(lines[3])]
- rot = [float(lines[4]), float(lines[5]), float(lines[6])]
- except ValueError:
- return "Invalid position or orientation in a bone!"
-
- # set position and orientation
- if bone.hasParent():
- bone.head = Vector(pos) * bone.parent.matrix + bone.parent.head
- bone.tail = bone.head + Vector([1,0,0])
- tempM = RM(rot) * bone.parent.matrix
- tempM.transpose;
- bone.matrix = tempM
- else:
- bone.head = Vector(pos)
- bone.tail = bone.head + Vector([1,0,0])
- bone.matrix = RM(rot)
-
- # Create vertex group for this bone
- mesh.addVertGroup(name)
- vgroup = []
- for index, v in enumerate(boneIds):
- if v==i:
- vgroup.append(index)
- mesh.assignVertsToGroup(name, vgroup, 1.0, 1)
-
- # read the number of position key frames
- try:
- numPosKeys = int(getNextLine(file))
- if numPosKeys < 0 or numPosKeys > MAX_NUMPOSKEYS:
- raise ValueError
- except ValueError:
- return "Invalid number of position key frames!"
-
- # read position key frames
- posKeys[name] = []
- for j in range(numPosKeys):
- # read time and position
- try:
- lines = getNextLine(file).split()
- if len(lines) != 4:
- raise ValueError
- time = float(lines[0])
- pos = [float(lines[1]), float(lines[2]), float(lines[3])]
- posKeys[name].append([time, pos])
- except ValueError:
- return "Invalid position key frame!"
-
- # read the number of rotation key frames
- try:
- numRotKeys = int(getNextLine(file))
- if numRotKeys < 0 or numRotKeys > MAX_NUMROTKEYS:
- raise ValueError
- except ValueError:
- return "Invalid number of rotation key frames!"
-
- # read rotation key frames
- rotKeys[name] = []
- for j in range(numRotKeys):
- # read time and rotation
- try:
- lines = getNextLine(file).split()
- if len(lines) != 4:
- raise ValueError
- time = float(lines[0])
- rot = [float(lines[1]), float(lines[2]), float(lines[3])]
- rotKeys[name].append([time, rot])
- except ValueError:
- return "Invalid rotation key frame!"
-
- # create action and pose
- action = None
- pose = None
- if armature != None:
- armature.update()
- pose = armOb.getPose()
- action = armOb.getAction()
- if not action:
- action = Blender.Armature.NLA.NewAction()
- action.setActive(armOb)
-
- # create animation key frames
- for name, pbone in pose.bones.items():
- # create position keys
- for key in posKeys[name]:
- pbone.loc = Vector(key[1])
- pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.LOC, True)
-
- # create rotation keys
- for key in rotKeys[name]:
- pbone.quat = RQ(key[1])
- pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.ROT, True)
-
- # set the imported object to be the selected one
- scn.objects.selected = []
- meshOb.sel= 1
- Blender.Redraw()
-
- # The import was a succes!
- return ""
-
-
-# load the model
-def fileCallback(filename):
- error = import_ms3d_ascii(filename)
- if error!="":
- Blender.Draw.PupMenu("An error occured during import: " + error + "|Not all data might have been imported succesfully.", 2)
-
-Blender.Window.FileSelector(fileCallback, 'Import')
diff --git a/release/scripts/obdatacopier.py b/release/scripts/obdatacopier.py
deleted file mode 100644
index 2f5617951de..00000000000
--- a/release/scripts/obdatacopier.py
+++ /dev/null
@@ -1,215 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Data Copier'
-Blender: 232
-Group: 'Object'
-Tip: 'Copy data from active object to other selected ones.'
-"""
-
-__author__ = "Jean-Michel Soler (jms), Campbell Barton (Ideasman42)"
-__url__ = ("blender", "blenderartists.org",
-"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm",
-"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "0.1.2"
-
-__bpydoc__ = """\
-Use "Data Copier" to copy attributes from the active object to other selected ones of
-its same type.
-
-This script is still in an early version but is already useful for copying
-attributes for some types of objects like lamps and cameras.
-
-Usage:
-
-Select the objects that will be updated, select the object whose data will
-be copied (they must all be of the same type, of course), then run this script.
-Toggle the buttons representing the attributes to be copied and press "Copy".
-"""
-
-# ----------------------------------------------------------
-# Object DATA copier 0.1.2
-# (c) 2004 jean-michel soler
-# -----------------------------------------------------------
-#----------------------------------------------
-# Page officielle/official page du blender python Object DATA copier:
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm
-# Communiquer les problemes et erreurs sur:
-# To Communicate problems and errors on:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#---------------------------------------------
-# Blender Artistic License
-# http://download.blender.org/documentation/html/x21254.html
-#---------------------------------------------
-
-import Blender
-from Blender import *
-from Blender.Draw import *
-from Blender.BGL import *
-
-
-scn= Blender.Scene.GetCurrent()
-
-type_func_method= type(dir)
-type_func= type(lambda:i)
-type_dict= type({})
-# type_list= type([])
-
-IGNORE_VARS = 'users', 'fakeUser', 'edges', 'faces', 'verts', 'elements'
-
-def renew():
- scn= Blender.Scene.GetCurrent()
- act_ob= scn.objects.active
- if act_ob==None:
- return {}
-
- act_ob_type= act_ob.getType()
- act_ob_data= act_ob.getData(mesh=1)
-
- if act_ob_data==None: # Surf?
- return {}
-
- PARAM={}
- evt=4
- doc='doc'
-
- for prop_name in dir(act_ob_data):
- if not prop_name.startswith('__') and prop_name not in IGNORE_VARS:
- # Get the type
- try: exec 'prop_type= type(act_ob_data.%s)' % prop_name
- except: prop_type= None
-
- if prop_type != None and prop_type not in (type_func_method, type_func, type_dict):
-
- # Now we know that the attribute can be listed in the UI Create a button and tooltip.
-
- # Tooltip
- try:
- if prop_name=='mode':
- try:
- exec "doc=str(%s.Modes)+' ; value : %s'"%( act_ob_type, str(act_ob_data.mode) )
- except:
- exec """doc= '%s'+' value = '+ str(act_ob.getData(mesh=1).%s)"""%(prop_name, prop_name)
- elif prop_name=='type':
- try:
- exec "doc=str(%s.Types)+' ; value : %s'"%( act_ob_type, str(act_ob_data.type) )
- except:
- exec """doc= '%s'+' value = '+ str(act_ob.getData(mesh=1).%s)"""%(prop_name, prop_name)
- else:
- exec """doc= '%s'+' value = '+ str(act_ob_data.%s)"""%(prop_name, prop_name)
- if doc.find('built-in')!=-1:
- exec """doc= 'This is a function ! Doc = '+ str(act_ob_data.%s.__doc__)"""% prop_name
- except:
- doc='Doc...'
-
- # Button
- PARAM[prop_name]= [Create(0), evt, doc]
- evt+=1
-
- return PARAM
-
-def copy():
- global PARAM
-
- scn= Blender.Scene.GetCurrent()
- act_ob= scn.getActiveObject()
- if act_ob==None:
- Blender.Draw.PupMenu('Error|No Active Object.')
- return
-
- act_ob_type= act_ob.getType()
-
- if act_ob_type in ('Empty', 'Surf'):
- Blender.Draw.PupMenu('Error|Copying Empty or Surf object data isnt supported.')
- return
-
- act_ob_data= act_ob.getData(mesh=1)
-
- print '\n\nStarting copy for object "%s"' % act_ob.name
- some_errors= False
- for ob in scn.objects.context:
- if ob != act_ob and ob.getType() == act_ob_type:
- ob_data= None
- for prop_name, value in PARAM.iteritems():
- if value[0].val==1:
-
- # Init the object data if we havnt alredy
- if ob_data==None:
- ob_data= ob.getData(mesh=1)
-
- try:
- exec "ob_data.%s = act_ob_data.%s"%(prop_name, prop_name)
- except:
- some_errors= True
- print 'Cant copy property "%s" for type "%s"' % (prop_name, act_ob_type)
- if some_errors:
- Blender.Draw.PupMenu('Some attributes could not be copied, see console for details.')
-
-PARAM= renew()
-
-def EVENT(evt,val):
- pass
-
-def BUTTON(evt):
- global PARAM
- if (evt==1):
- Exit()
-
- if (evt==2):
- copy()
- Blender.Redraw()
-
- if (evt==3):
- PARAM= renew()
- Blender.Redraw()
-
-def DRAW():
- global PARAM
-
- scn= Blender.Scene.GetCurrent()
- act_ob= scn.objects.active
-
- glColor3f(0.7, 0.7, 0.7)
- glClear(GL_COLOR_BUFFER_BIT)
- glColor3f(0.1, 0.1, 0.15)
-
- size=Buffer(GL_FLOAT, 4)
- glGetFloatv(GL_SCISSOR_BOX, size)
- size= size.list
- for s in [0,1,2,3]: size[s]=int(size[s])
- ligne=20
-
- Button("Exit",1,20,4,80,ligne)
- Button("Copy",2,102,4,80,ligne)
- Button("Renew",3,184,4,80,ligne)
-
- glRasterPos2f(20, ligne*2-8)
- if act_ob:
- Text(act_ob.getType()+" DATA copier")
- else:
- Text("Please select an object")
-
-
- max=size[3] / 22 -2
- pos = 0
- decal = 20
- key=PARAM.keys()
- key.sort()
- for p in key:
- if pos==max:
- decal+=102
- pos=1
- else:
- pos+=1
-
- PARAM[p][0]=Toggle(p,
- PARAM[p][1],
- decal,
- pos*22+22,
- 100,
- 20,
- PARAM[p][0].val,
- str(PARAM[p][2]))
-
-
-Register(DRAW,EVENT,BUTTON)
diff --git a/release/scripts/object_active_to_other.py b/release/scripts/object_active_to_other.py
deleted file mode 100644
index 68aa6a3a039..00000000000
--- a/release/scripts/object_active_to_other.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!BPY
-"""
-Name: 'Copy Active to Selected'
-Blender: 249
-Group: 'Object'
-Tooltip: 'For every selected object, copy the active to their loc/size/rot'
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import Window, sys, Draw
-import bpy
-
-def my_object_util(sce):
- ob_act = sce.objects.active
-
- if not ob_act:
- Draw.PupMenu('Error%t|No active object selected')
- return
-
- mats = [(ob, ob.matrixWorld) for ob in sce.objects.context if ob != ob_act]
-
- for ob, m in mats:
- ob_copy = ob_act.copy()
- sce.objects.link(ob_copy)
- ob_copy.setMatrix(m)
- ob_copy.Layers = ob.Layers & (1<<20)-1
-
-
-def main():
- sce = bpy.data.scenes.active
-
- Window.WaitCursor(1)
- my_object_util(sce)
- Window.WaitCursor(0)
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/object_apply_def.py b/release/scripts/object_apply_def.py
deleted file mode 100644
index 006e97463d8..00000000000
--- a/release/scripts/object_apply_def.py
+++ /dev/null
@@ -1,178 +0,0 @@
-#!BPY
-
-"""
-Name: 'Apply Deformation'
-Blender: 242
-Group: 'Object'
-Tooltip: 'Make copys of all the selected objects with modifiers, softbodies and fluid baked into a mesh'
-"""
-
-__author__ = "Martin Poirier (theeth), Jean-Michel Soler (jms), Campbell Barton (ideasman)"
-# This script is the result of merging the functionalities of two other:
-# Martin Poirier's Apply_Def.py and
-# Jean-Michel Soler's Fix From Everything
-
-__url__ = ("http://www.blender.org", "http://blenderartists.org", "http://jmsoler.free.fr")
-__version__ = "1.6 07/07/2006"
-
-__bpydoc__ = """\
-This script creates "raw" copies of deformed meshes.
-
-Usage:
-
-Select any number of Objects and run this script. A fixed copy of each selected object
-will be created, with the word "_def" appended to its name. If an object with
-the same name already exists, it appends a number at the end as Blender itself does.
-
-Objects in Blender can be deformed by armatures, lattices, curve objects and subdivision,
-but this will only change its appearance on screen and rendered
-images -- the actual mesh data is still simpler, with vertices in an original
-"rest" position and less vertices than the subdivided version.
-
-Use this script if you want a "real" version of the deformed mesh, so you can
-directly manipulate or export its data.
-
-This script will work with object types: Mesh, Metaballs, Text3d, Curves and Nurbs Surface.
-"""
-
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2003: Martin Poirier, theeth@yahoo.com
-#
-# Thanks to Jonathan Hudson for help with the vertex groups part
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-
-import Blender
-import bpy
-import BPyMesh
-
-def copy_vgroups(source_ob, target_ob):
-
- source_me = source_ob.getData(mesh=1)
-
- vgroups= source_me.getVertGroupNames()
- if vgroups:
- ADD= Blender.Mesh.AssignModes.ADD
- target_me = target_ob.getData(mesh=1)
- for vgroupname in vgroups:
- target_me.addVertGroup(vgroupname)
- if len(target_me.verts) == len(source_me.verts):
- try: # in rare cases this can raise an 'no deform groups assigned to mesh' error
- vlist = source_me.getVertsFromGroup(vgroupname, True)
- except:
- vlist = []
-
- try:
- for vpair in vlist:
- target_me.assignVertsToGroup(vgroupname, [vpair[0]], vpair[1], ADD)
- except:
- pass
-
-
-def apply_deform():
- scn= bpy.data.scenes.active
- #Blender.Window.EditMode(0)
-
- NAME_LENGTH = 19
- SUFFIX = "_def"
- SUFFIX_LENGTH = len(SUFFIX)
- # Get all object and mesh names
-
-
- ob_list = list(scn.objects.context)
- ob_act = scn.objects.active
-
- # Assume no soft body
- has_sb= False
-
- # reverse loop so we can remove objects (metaballs in this case)
- for ob_idx in xrange(len(ob_list)-1, -1, -1):
- ob= ob_list[ob_idx]
-
- ob.sel = 0 # deselect while where checking the metaballs
-
- # Test for a softbody
- if not has_sb and ob.isSB():
- has_sb= True
-
- # Remove all numbered metaballs because their disp list is only on the main metaball (un numbered)
- if ob.type == 'MBall':
- name= ob.name
- # is this metaball numbered?
- dot_idx= name.rfind('.') + 1
- if name[dot_idx:].isdigit():
- # Not the motherball, ignore it.
- del ob_list[ob_idx]
-
-
- if not ob_list:
- Blender.Draw.PupMenu('No objects selected, nothing to do.')
- return
-
-
- if has_sb:
- curframe=Blender.Get('curframe')
- for f in xrange(curframe):
- Blender.Set('curframe',f+1)
- Blender.Window.RedrawAll()
-
- used_names = [ob.name for ob in Blender.Object.Get()]
- used_names.extend(Blender.NMesh.GetNames())
-
-
- deformedList = []
- for ob in ob_list:
-
- # Get the mesh data
- new_me= BPyMesh.getMeshFromObject(ob, vgroups=False)
-
- if not new_me:
- continue # Object has no display list
-
-
- name = ob.name
- new_name = "%s_def" % name[:NAME_LENGTH-SUFFIX_LENGTH]
- num = 0
-
- while new_name in used_names:
- new_name = "%s_def.%.3i" % (name[:NAME_LENGTH-(SUFFIX_LENGTH+SUFFIX_LENGTH)], num)
- num += 1
- used_names.append(new_name)
-
- new_me.name= new_name
-
- new_ob= scn.objects.new(new_me)
- new_ob.setMatrix(ob.matrixWorld)
-
- # Make the active duplicate also active
- if ob == ob_act:
- scn.objects.active = new_ob
-
- # Original object was a mesh? see if we can copy any vert groups.
- if ob.type =='Mesh':
- copy_vgroups(ob, new_ob)
-
- Blender.Window.RedrawAll()
-
-if __name__=='__main__':
- apply_deform()
diff --git a/release/scripts/object_batch_name_edit.py b/release/scripts/object_batch_name_edit.py
deleted file mode 100644
index 4db3a6210db..00000000000
--- a/release/scripts/object_batch_name_edit.py
+++ /dev/null
@@ -1,274 +0,0 @@
-#!BPY
-"""
-Name: 'Batch Object Name Edit'
-Blender: 240
-Group: 'Object'
-Tooltip: 'Apply the chosen rule to rename all selected objects at once.'
-"""
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0"
-
-__bpydoc__ = """\
-"Batch Object Name Edit" allows you to change multiple names of Blender
-objects at once. It provides options to define if you want to: replace text
-in the current names, truncate their beginnings or endings or prepend / append
-strings to them.
-
-Usage:
-Select the objects to be renamed and run this script from the Object->Scripts
-menu of the 3d View.
-"""
-# $Id$
-#
-# --------------------------------------------------------------------------
-# Batch Name Edit by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-from Blender import *
-import bpy
-
-global renameCount
-renameCount = 0
-obsel = [ob for ob in bpy.data.scenes.active.objects.context if not ob.lib]
-
-def setDataNameWrapper(ob, newname):
- if ob.getData(name_only=1) == newname:
- return False
-
- data= ob.getData(mesh=1)
-
- if data and not data.lib:
- data.name= newname
- return True
- return False
-
-def main():
- global renameCount
- # Rename the datablocks that are used by the object.
- def renameLinkedDataFromObject():
-
- # Result 1, we want to rename data
- for ob in obsel:
- if ob.name == ob.getData(name_only=1):
- return # Alredy the same name, dont bother.
-
- data = ob.getData(mesh=1) # use mesh so we dont have to update the nmesh.
- if data and not data.lib:
- data.name = ob.name
-
-
- def new():
- global renameCount
- NEW_NAME_STRING = Draw.Create('')
- RENAME_LINKED = Draw.Create(0)
- pup_block = [\
- ('New Name: ', NEW_NAME_STRING, 19, 19, 'New Name'),\
- ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\
- ]
-
- if not Draw.PupBlock('Replace in name...', pup_block):
- return 0
-
- NEW_NAME_STRING= NEW_NAME_STRING.val
-
- Window.WaitCursor(1)
- for ob in obsel:
- if ob.name != NEW_NAME_STRING:
- ob.name = NEW_NAME_STRING
- renameCount+=1
-
- return RENAME_LINKED.val
-
- def replace():
- global renameCount
- REPLACE_STRING = Draw.Create('')
- WITH_STRING = Draw.Create('')
- RENAME_LINKED = Draw.Create(0)
-
- pup_block = [\
- ('Replace: ', REPLACE_STRING, 19, 19, 'Text to find'),\
- ('With:', WITH_STRING, 19, 19, 'Text to replace with'),\
- ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\
- ]
-
- if not Draw.PupBlock('Replace in name...', pup_block) or\
- ((not REPLACE_STRING.val) and (not WITH_STRING)):
- return 0
-
- REPLACE_STRING = REPLACE_STRING.val
- WITH_STRING = WITH_STRING.val
-
- Window.WaitCursor(1)
- for ob in obsel:
- newname = ob.name.replace(REPLACE_STRING, WITH_STRING)
- if ob.name != newname:
- ob.name = newname
- renameCount+=1
- return RENAME_LINKED.val
-
-
- def prefix():
- global renameCount
- PREFIX_STRING = Draw.Create('')
- RENAME_LINKED = Draw.Create(0)
-
- pup_block = [\
- ('Prefix: ', PREFIX_STRING, 19, 19, 'Name prefix'),\
- ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\
- ]
-
- if not Draw.PupBlock('Prefix...', pup_block) or\
- not PREFIX_STRING.val:
- return 0
-
- PREFIX_STRING = PREFIX_STRING.val
-
- Window.WaitCursor(1)
- for ob in obsel:
- ob.name = PREFIX_STRING + ob.name
- renameCount+=1 # we knows these are different.
- return RENAME_LINKED.val
-
- def suffix():
- global renameCount
- SUFFIX_STRING = Draw.Create('')
- RENAME_LINKED = Draw.Create(0)
-
- pup_block = [\
- ('Suffix: ', SUFFIX_STRING, 19, 19, 'Name suffix'),\
- ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\
- ]
-
- if not Draw.PupBlock('Suffix...', pup_block) or\
- not SUFFIX_STRING.val:
- return 0
-
- SUFFIX_STRING = SUFFIX_STRING.val
-
- Window.WaitCursor(1)
- for ob in obsel:
- ob.name = ob.name + SUFFIX_STRING
- renameCount+=1 # we knows these are different.
- return RENAME_LINKED.val
-
- def truncate_start():
- global renameCount
- TRUNCATE_START = Draw.Create(0)
- RENAME_LINKED = Draw.Create(0)
-
- pup_block = [\
- ('Truncate Start: ', TRUNCATE_START, 0, 19, 'Truncate chars from the start of the name'),\
- ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\
- ]
-
- if not Draw.PupBlock('Truncate Start...', pup_block) or\
- not TRUNCATE_START.val:
- return 0
-
- Window.WaitCursor(1)
- TRUNCATE_START = TRUNCATE_START.val
- for ob in obsel:
- newname = ob.name[TRUNCATE_START: ]
- ob.name = newname
- renameCount+=1
-
- return RENAME_LINKED.val
-
- def truncate_end():
- global renameCount
- TRUNCATE_END = Draw.Create(0)
- RENAME_LINKED = Draw.Create(0)
-
- pup_block = [\
- ('Truncate End: ', TRUNCATE_END, 0, 19, 'Truncate chars from the end of the name'),\
- ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\
- ]
-
- if not Draw.PupBlock('Truncate End...', pup_block) or\
- not TRUNCATE_END.val:
- return 0
-
- Window.WaitCursor(1)
- TRUNCATE_END = TRUNCATE_END.val
- for ob in obsel:
- newname = ob.name[: -TRUNCATE_END]
- ob.name = newname
- renameCount+=1
-
- return RENAME_LINKED.val
-
- def renameObjectFromLinkedData():
- global renameCount
- Window.WaitCursor(1)
-
- for ob in obsel:
- newname = ob.getData(name_only=1)
- if newname != None and ob.name != newname:
- ob.name = newname
- renameCount+=1
- return 0
-
- def renameObjectFromDupGroup():
- global renameCount
- Window.WaitCursor(1)
-
- for ob in obsel:
- group= ob.DupGroup
- if group != None:
- newname= group.name
- if newname != ob.name:
- ob.name = newname
- renameCount+=1
- return 0
-
- def renameLinkedDataFromObject():
- global renameCount
- Window.WaitCursor(1)
-
- for ob in obsel:
- if setDataNameWrapper(ob, ob.name):
- renameCount+=1
- return 0
-
- name = "Selected Object Names%t|New Name|Replace Text|Add Prefix|Add Suffix|Truncate Start|Truncate End|Rename Objects to Data Names|Rename Objects to DupGroup Names|Rename Data to Object Names"
- result = Draw.PupMenu(name)
- renLinked = 0 # Rename linked data to the object name?
- if result == -1:
- return
- elif result == 1: renLinked= new()
- elif result == 2: renLinked= replace()
- elif result == 3: renLinked= prefix()
- elif result == 4: renLinked= suffix()
- elif result == 5: renLinked= truncate_start()
- elif result == 6: renLinked= truncate_end()
- elif result == 7: renameObjectFromLinkedData()
- elif result == 8: renameObjectFromDupGroup()
- elif result == 9: renameLinkedDataFromObject()
-
- if renLinked:
- renameLinkedDataFromObject()
-
- Window.WaitCursor(0)
-
- Draw.PupMenu('renamed: %d objects.' % renameCount)
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/object_cookie_cutter.py b/release/scripts/object_cookie_cutter.py
deleted file mode 100644
index 4950c18c0f4..00000000000
--- a/release/scripts/object_cookie_cutter.py
+++ /dev/null
@@ -1,667 +0,0 @@
-#!BPY
-"""
-Name: 'Cookie Cut from View'
-Blender: 234
-Group: 'Object'
-Tooltip: 'Cut from the view axis, (Sel 3d Curves and Meshes (only edges) into other meshes with faces)'
-"""
-__author__= "Campbell Barton"
-__url__= ["blender", "blenderartist"]
-__version__= "1.0"
-
-__bpydoc__= """\
-This script takes the selected mesh objects, divides them into 2 groups
-Cutters and The objects to be cut.
-
-Cutters are meshes with no faces, just edge loops. and any meshes with faces will be cut.
-
-Usage:
-
-Select 2 or more meshes, one with no faces (a closed polyline) and one with faces to cut.
-
-Align the view on the axis you want to cut.
-For shapes that have overlapping faces (from the view), hide any backfacing faces so they will be ignored during the cut.
-Run the script.
-
-You can choose to make the cut verts lie on the face that they were cut from or on the edge that cut them.
-This script supports UV coordinates and images.
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from math import sqrt
-import BPyMesh
-Vector= Blender.Mathutils.Vector
-LineIntersect2D= Blender.Geometry.LineIntersect2D
-PointInTriangle2D= Blender.Geometry.PointInTriangle2D
-
-# Auto class
-def auto_class(slots):
- exec('class container_class(object): __slots__=%s' % slots)
- return container_class
-
-
-bignum= 1<<30
-def bounds_xy(iter_item):
- '''
- Works with types
- MMesh.verts
- MFace
- MEdge
- '''
- xmin= ymin= bignum
- xmax= ymax= -bignum
- for v in iter_item:
- x= v.co.x
- y= v.co.y
- if x<xmin: xmin= x
- if y<ymin: ymin= y
- if x>xmax: xmax= x
- if y>ymax: ymax= y
-
- return xmin, ymin, xmax, ymax
-
-def bounds_intersect(a,b):
- '''
- each tuple is
- xmin, ymin, xmax, ymax
- '''
- if\
- a[0]>b[2] or\
- a[1]>b[3] or\
- a[2]<b[0] or\
- a[3]<b[1]:
- return False
- else:
- return True
-
-def point_in_bounds(pt, bounds):
- '''
- each tuple is
- xmin, ymin, xmax, ymax
- '''
- if bounds[0] < pt.x < bounds[2] and bounds[1] < pt.y < bounds[3]:
- return True
- else:
- return False
-
-def point_in_poly2d(pt, fvco):
- if PointInTriangle2D(pt, fvco[0], fvco[1], fvco[2]):
- return True
- if len(fvco) == 4:
- if PointInTriangle2D(pt, fvco[0], fvco[2], fvco[3]):
- return True
- return False
-
-# reuse me more.
-def sorted_edge_indicies(ed):
- i1= ed.v1.index
- i2= ed.v2.index
- if i1>i2:
- i1,i2= i2,i1
- return i1, i2
-
-def sorted_indicies(i1, i2):
- if i1>i2:
- i1,i2= i2,i1
- return i1, i2
-
-def fake_length2d(pt1, pt2):
- '''
- Only used for comparison so don't sqrt
- '''
- #return math.sqrt(abs(pow(x1-x2, 2)+ pow(y1-y2, 2)))
- return pow(pt1[0]-pt2[0], 2) + pow(pt1[1]- pt2[1], 2)
-
-def length2d(pt1, pt2):
- '''
- Only used for comparison so don't sqrt
- '''
- #return math.sqrt(abs(pow(x1-x2, 2)+ pow(y1-y2, 2)))
- return sqrt(pow(pt1[0]-pt2[0], 2) + pow(pt1[1]- pt2[1], 2))
-
-
-
-def tri_area_2d(v1, v2, v3):
- e1 = length2d(v1, v2)
- e2 = length2d(v2, v3)
- e3 = length2d(v3, v1)
- p = e1+e2+e3
- return 0.25 * sqrt(abs(p*(p-2*e1)*(p-2*e2)*(p-2*e3)))
-
-def tri_pt_find_z_2d(pt, tri):
- """ Takes a face and 3d vector and assigns the vectors Z to its on the face"""
-
- l1= tri_area_2d(tri[1], tri[2], pt)
- l2= tri_area_2d(tri[0], tri[2], pt)
- l3= tri_area_2d(tri[0], tri[1], pt)
-
- tot= l1+l2+l3
- # Normalize
- l1=l1/tot
- l2=l2/tot
- l3=l3/tot
-
- z1= tri[0].z*l1
- z2= tri[1].z*l2
- z3= tri[2].z*l3
-
- return z1+z2+z3
-
-
-def tri_pt_find_uv_2d(pt, tri, uvs):
- """ Takes a face and 3d vector and assigns the vectors Z to its on the face"""
-
- l1= tri_area_2d(tri[1], tri[2], pt)
- l2= tri_area_2d(tri[0], tri[2], pt)
- l3= tri_area_2d(tri[0], tri[1], pt)
-
- tot= l1+l2+l3
- if not tot: # No area, just return the first uv
- return Vector(uvs[0])
-
- # Normalize
- l1=l1/tot
- l2=l2/tot
- l3=l3/tot
-
- uv1= uvs[0]*l1
- uv2= uvs[1]*l2
- uv3= uvs[2]*l3
-
- return uv1+uv2+uv3
-
-
-
-
-def mesh_edge_dict(me):
- ed_dict= {}
- for f in me.faces:
- if not f.hide:
- for edkey in f.edge_keys:
- ed_dict.setdefault(edkey, []).append(f)
-
- return ed_dict
-
-
-
-def terrain_cut_2d(t, c, PREF_Z_LOC):
- '''
- t is the terrain
- c is the cutter
-
- PREF_Z_LOC: 0 - from terrain face
- 1 - from cutter edge
-
- returns nothing
- '''
-
- # do we have a 2d intersection
- if not bounds_intersect(t.bounds, c.bounds):
- return
-
- # Local vars
- me_t= t.mesh
- me_c= c.mesh
-
- has_uv= me_t.faceUV
-
- Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX'])
- '''
- first assign a face terrain face for each cutter verticie
- '''
- cut_verts_temp= list(me_c.verts)
- cut_vert_terrain_faces= [None] * len(me_c.verts)
- vert_z_level= [-10.0] * len(me_c.verts)
-
- for v in me_c.verts:
- v_index= v.index
- v_co= v.co
- for fidx, f in enumerate(me_t.faces):
- if not f.hide:
- if point_in_bounds(v_co, t.face_bounds[fidx]):
- f_v= [vv.co for vv in f]
- if point_in_poly2d(v_co, f_v):
-
-
- if PREF_Z_LOC==0:
- '''
- Get the z location from the face.
- '''
-
- if len(f_v)==3:
- vert_z_level[v_index]= tri_pt_find_z_2d(v_co, (f_v[0], f_v[1], f_v[2]) )
- else:
- # Quad, which side are we on?
- a1= tri_area_2d(f_v[0], f_v[1], v_co)
- a2= tri_area_2d(f_v[1], f_v[2], v_co)
-
- a3= tri_area_2d(f_v[0], f_v[1], f_v[2])
-
- if a1+a2<a3:
- vert_z_level[v_index]= tri_pt_find_z_2d(v_co, (f_v[0], f_v[1], f_v[2]) )
- else:
- vert_z_level[v_index]= tri_pt_find_z_2d(v_co, (f_v[0], f_v[2], f_v[3]) )
-
- else: # PREF_Z_LOC==1
- '''
- Get the z location from the vert
- '''
- vert_z_level[v_index]= v_co.z
-
- # Non overlapping faces in terrain mean we can break
- cut_vert_terrain_faces[v_index]= f
- break
-
- del cut_verts_temp
-
-
-
- edge_intersections= []
- edge_isect_type= auto_class(['point', 'ed_terrain', 'ed_cut'])
-
- # intersect cutter faces with terrain edges.
- for ei_t, ed_t in enumerate(me_t.edges):
-
- eb_t= t.edge_bounds[ei_t]
- if bounds_intersect(eb_t, c.bounds): # face/cutter bounds intersect?
- # Loop through the cutter edges.
- for ei_c, ed_c in enumerate(me_c.edges):
- # If the cutter edge has 2 verts inside the same face then we can ignore it
- # Both are different faces or None
- if cut_vert_terrain_faces[ed_c.v1.index] != cut_vert_terrain_faces[ed_c.v2.index] or\
- cut_vert_terrain_faces[ed_c.v1.index] == cut_vert_terrain_faces[ed_c.v2.index] == None:
- eb_c= c.edge_bounds[ei_c]
- if bounds_intersect(eb_t, eb_c): # face/edge bounds intersect?
- # Now we know the 2 edges might intersect, we'll do a proper test
-
- x= LineIntersect2D(ed_t.v1.co, ed_t.v2.co, ed_c.v1.co, ed_c.v2.co)
- if x:
- ed_isect= edge_isect_type()
- ed_isect.point= x.resize3D() # fake 3d
-
- # Find the interpolation Z point
-
- if PREF_Z_LOC==0:
- '''
- Terrains edge
- '''
- l1= length2d(ed_isect.point, ed_t.v1.co)
- l2= length2d(ed_isect.point, ed_t.v2.co)
- ed_isect.point.z= ((l2*ed_t.v1.co.z) + (l1*ed_t.v2.co.z)) / (l1+l2)
- else:
- '''
- Cutters edge
- '''
- l1= length2d(ed_isect.point, ed_c.v1.co)
- l2= length2d(ed_isect.point, ed_c.v2.co)
- ed_isect.point.z= ((l2*ed_c.v1.co.z) + (l1*ed_c.v2.co.z)) / (l1+l2)
-
- ed_isect.ed_terrain= ed_t
- ed_isect.ed_cut= ed_c
-
- edge_intersections.append(ed_isect)
-
- if not edge_intersections:
- return
-
- # Now we have collected intersections we need to apply them
-
- # Find faces that have intersections, these faces will need to be cut.
- faces_intersecting= {} # face index as key, list of edges as values
- for ed_isect in edge_intersections:
-
- try:
- faces= t.edge_dict[ sorted_edge_indicies(ed_isect.ed_terrain) ]
- except:
- # If the faces are hidden then the faces wont exist.
- faces= []
-
- for f in faces:
- faces_intersecting.setdefault(f.index, []).append(ed_isect)
-
- # this list is used to store edges that are totally inside a face ( no intersections with terrain)
- # we can remove these as we
- face_containing_edges= [[] for i in xrange(len(me_t.faces))]
- for ed_c in me_c.edges:
- if cut_vert_terrain_faces[ed_c.v1.index]==cut_vert_terrain_faces[ed_c.v2.index] != None:
- # were inside a face.
- face_containing_edges[cut_vert_terrain_faces[ed_c.v1.index].index].append(ed_c)
-
- # New Mesh for filling faces only
- new_me= Blender.Mesh.New()
- scn= Blender.Scene.GetCurrent()
- ob= Blender.Object.New('Mesh')
- ob.link(new_me)
- scn.link(ob)
- ob.sel= True
-
- new_faces= []
- new_faces_props= []
- new_uvs= []
- new_verts= []
-
- # Loop through inter
- for fidx_t, isect_edges in faces_intersecting.iteritems():
- f= me_t.faces[fidx_t]
- f_v= f.v
- fidxs_s= [v.index for v in f_v]
-
- # Make new fake edges for each edge, each starts as a list of 2 verts, but more verts can be added
- # This list will then be sorted so the edges are in order from v1 to v2 of the edge.
- face_new_verts= [ (f_v[i], [], f_v[i-1]) for i in xrange(len(f_v)) ]
- # if len(face_new_verts) < 3: raise 'weirdo'
-
- face_edge_dict = dict( [(sorted_indicies(fidxs_s[i], fidxs_s[i-1]), i) for i in xrange(len(f_v))] )
-
- for ed_isect in isect_edges:
- edge_index_in_face = face_edge_dict[ sorted_edge_indicies(ed_isect.ed_terrain) ]
- # Add this intersection to the face
- face_new_verts[edge_index_in_face][1].append(ed_isect)
-
- # Now sort the intersections
- for new_edge in face_new_verts:
- if len(new_edge[1]) > 1:
- # We have 2+ verts to sort
- edv1= tuple(new_edge[0].co) # 3d but well only use the 2d part
- new_edge[1].sort(lambda a,b: cmp(fake_length2d(a.point, edv1), fake_length2d(b.point, edv1) ))
-
- # now build up a new face by getting edges
- random_face_edges= []
- unique_verts= [] # store vert
- rem_double_edges= {}
-
- def add_edge(p1, p2):
- k1= tuple(p1)
- k2= tuple(p2)
-
- # Adds new verts where needed
- try:
- i1= rem_double_edges[k1]
- except:
- i1= rem_double_edges[k1]= len(rem_double_edges)
- unique_verts.append(k1)
-
- try:
- i2= rem_double_edges[k2]
- except:
- i2= rem_double_edges[k2]= len(rem_double_edges)
- unique_verts.append(k2)
-
- random_face_edges.append( (i1, i2) )
-
-
-
- # edges that don't have a vert in the face have to span between to intersection points
- # since we don't know the other point at any 1 time we need to remember edges that
- # span a face and add them once we'v collected both
- # first add outline edges
- edge_span_face= {}
- for new_edge in face_new_verts:
- new_edge_subdiv= len(new_edge[1])
- if new_edge_subdiv==0:
- # no subdiv edges, just add
- add_edge(new_edge[0].co, new_edge[2].co)
- elif new_edge_subdiv==1:
- add_edge(new_edge[0].co, new_edge[1][0].point)
- add_edge(new_edge[1][0].point, new_edge[2].co)
- else:
- # 2 or more edges
- add_edge(new_edge[0].co, new_edge[1][0].point)
- add_edge(new_edge[1][-1].point, new_edge[2].co)
-
- # now add multiple
- for i in xrange(new_edge_subdiv-1):
- add_edge(new_edge[1][i].point, new_edge[1][i+1].point)
-
- # done adding outline
- # while looping through the edge subdivs, add the edges that intersect
-
-
- for ed_isect in new_edge[1]:
- ed_cut= ed_isect.ed_cut
- if cut_vert_terrain_faces[ed_cut.v1.index]==f:
- # our first vert is inside the face
- point= Vector(ed_cut.v1.co)
- point.z= vert_z_level[ed_cut.v1.index]
-
- add_edge(point, ed_isect.point)
- elif cut_vert_terrain_faces[ed_cut.v2.index]==f:
- # assume second vert is inside the face
- point= Vector(ed_cut.v2.co)
- point.z= vert_z_level[ed_cut.v2.index]
- add_edge(point, ed_isect.point)
- else:
- # this edge has no verts in the face so it will need to be clipped in 2 places
- try:
- point= edge_span_face[ed_cut]
-
- # if were here it worked ;)
- add_edge(point, ed_isect.point)
-
- except:
- # add the first intersecting point
- edge_span_face[ed_cut]= ed_isect.point
-
- # now add all edges that are inside the the face
- for ed_c in face_containing_edges[fidx_t]:
- point1= Vector(ed_c.v1.co)
- point2= Vector(ed_c.v2.co)
- point1.z= vert_z_level[ed_c.v1.index]
- point2.z= vert_z_level[ed_c.v2.index]
- add_edge(point1, point2)
-
- new_me.verts.extend(unique_verts)
- new_me.edges.extend(random_face_edges)
- new_me.sel= 1
-
- # backup the z values, fill and restore
-
- backup_z= [v.co.z for v in new_me.verts]
- for v in new_me.verts: v.co.z= 0
- #raise 'as'
- new_me.fill()
- for i, v in enumerate(new_me.verts): v.co.z= backup_z[i]
-
-
- # ASSIGN UV's
- if has_uv:
- f_uv= f_uv_mod= f.uv
- f_vco= f_vco_mod= [v.co for v in f]
-
- # f is the face, get the uv's from that.
-
- uvs= [None] * len(new_me.verts)
- for i, v in enumerate(new_me.verts):
- v_co= v.co
- f_uv_mod= f_uv
- f_vco_mod= f_vco
-
- if len(f_v)==4:
- # Quad, which side are we on?
- a1= tri_area_2d(f_vco[0], f_vco[1], v_co)
- a2= tri_area_2d(f_vco[1], f_vco[2], v_co)
-
- a3= tri_area_2d(f_vco[0], f_vco[1], f_vco[2])
- if a1+a2 > a3:
- # 0,2,3
- f_uv_mod= f_uv[0], f_uv[2], f_uv[3]
- f_vco_mod= f_vco[0], f_vco[2], f_vco[3]
- # else - side of 0,1,2 - don't modify the quad
-
- uvs[i]= tri_pt_find_uv_2d(v_co, f_vco_mod, f_uv_mod)
-
- new_uvs.extend(uvs)
- new_faces_props.extend( [f.image] * len(new_me.faces) )
-
- # collect the fill results
- new_verts_len= len(new_verts) + len(me_t.verts)
- new_faces.extend( [[v.index+new_verts_len for v in ff] for ff in new_me.faces] )
-
-
-
- new_verts.extend(unique_verts)
-
- new_me.verts= None
- #raise 'error'
-
- # Finished filling
- scn.unlink(ob)
-
-
- # Remove faces
- face_len = len(me_t.faces)
- verts_len = len(me_t.verts)
- me_t.verts.extend(new_verts)
- me_t.faces.extend(new_faces)
-
- for i in xrange(len(new_faces)):
- f= me_t.faces[face_len+i]
-
- if has_uv:
- img= new_faces_props[i]
- if img: f.image= img
-
- f_uv= f.uv
- for ii, v in enumerate(f):
- v_index= v.index-verts_len
- new_uv= new_uvs[v_index]
- uv= f_uv[ii]
- uv.x= new_uv.x
- uv.y= new_uv.y
-
- me_t.faces.delete(1, faces_intersecting.keys())
- me_t.sel= 1
- me_t.remDoubles(0.0000001)
-
-
-def main():
- PREF_Z_LOC= Blender.Draw.PupMenu('Cut Z Location%t|Original Faces|Cutting Polyline')
-
- if PREF_Z_LOC==-1:
- return
- PREF_Z_LOC-=1
-
- Blender.Window.WaitCursor(1)
-
- print '\nRunning Cookie Cutter'
- time= Blender.sys.time()
- scn = Blender.Scene.GetCurrent()
- obs= [ob for ob in scn.objects.context if ob.type in ('Mesh', 'Curve')]
- MULTIRES_ERROR = False
-
- # Divide into 2 lists- 1 with faces, one with only edges
- terrains= [] #[me for me in mes if me.faces]
- cutters= [] #[me for me in mes if not me.faces]
-
- terrain_type= auto_class(['mesh', 'bounds', 'face_bounds', 'edge_bounds', 'edge_dict', 'cutters', 'matrix'])
-
- for ob in obs:
- if ob.type == 'Mesh':
- me= ob.getData(mesh=1)
- elif ob.data.flag & 1: # Is the curve 3D? else don't use.
- me= BPyMesh.getMeshFromObject(ob) # get the curve
- else:
- continue
-
- # a new terrain instance
- if me.multires:
- MULTIRES_ERROR = True
- else:
- t= terrain_type()
-
- t.matrix= ob.matrixWorld * Blender.Window.GetViewMatrix()
-
- # Transform the object by its matrix
- me.transform(t.matrix)
-
- # Set the terrain bounds
- t.bounds= bounds_xy(me.verts)
- t.edge_bounds= [bounds_xy(ed) for ed in me.edges]
- t.mesh= me
-
- if me.faces: # Terrain.
- t.edge_dict= mesh_edge_dict(me)
- t.face_bounds= [bounds_xy(f) for f in me.faces]
- t.cutters= [] # Store cutting objects that cut us here
- terrains.append(t)
- elif len(me.edges)>2: # Cutter
- cutters.append(t)
-
- totcuts= len(terrains)*len(cutters)
- if not totcuts:
- Blender.Window.WaitCursor(0)
- Blender.Draw.PupMenu('ERROR%t|Select at least 1 closed loop mesh (edges only)|as the cutter...|and 1 or more meshes to cut into')
-
- crazy_point= Vector(100000, 100000)
-
- for t in terrains:
- for c in cutters:
- # Main curring function
- terrain_cut_2d(t, c, PREF_Z_LOC)
-
- # Was the terrain touched?
- if len(t.face_bounds) != len(t.mesh.faces):
- t.edge_dict= mesh_edge_dict(t.mesh)
- # remake the bounds
- t.edge_bounds= [bounds_xy(ed) for ed in t.mesh.edges]
- t.face_bounds= [bounds_xy(f) for f in t.mesh.faces]
- t.cutters.append(c)
-
- print '\t%i remaining' % totcuts
- totcuts-=1
-
- # SELECT INTERNAL FACES ONCE THIS TERRAIN IS CUT
- Blender.Mesh.Mode(Blender.Mesh.SelectModes['FACE'])
- t.mesh.sel= 0
- for c in t.cutters:
- edge_verts_c= [(ed_c.v1.co, ed_c.v2.co) for ed_c in c.mesh.edges]
- for f in t.mesh.faces:
- # How many edges do we intersect on our way to the faces center
- if not f.hide and not f.sel: # Not alredy selected
- c= f.cent
- if point_in_bounds(c, t.bounds):
- isect_count= 0
- for edv1, edv2 in edge_verts_c:
- isect_count += (LineIntersect2D(c, crazy_point, edv1, edv2) != None)
-
- if isect_count%2:
- f.sel= 1
- Blender.Mesh.Mode(Blender.Mesh.SelectModes['FACE'])
-
- # Restore the transformation
- for data in (terrains, cutters):
- for t in data:
- if t.mesh.users: # it may have been a temp mesh from a curve.
- t.mesh.transform(t.matrix.copy().invert())
-
- Blender.Window.WaitCursor(0)
-
- if MULTIRES_ERROR:
- Blender.Draw.PupMenu('Error%t|One or more meshes meshes not cut because they are multires.')
-
- print 'terrains:%i cutters %i %.2f secs taken' % (len(terrains), len(cutters), Blender.sys.time()-time)
-
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/object_drop.py b/release/scripts/object_drop.py
deleted file mode 100644
index 19cc1f8d15a..00000000000
--- a/release/scripts/object_drop.py
+++ /dev/null
@@ -1,253 +0,0 @@
-#!BPY
-"""
-Name: 'Drop Onto Ground'
-Blender: 249
-Group: 'Object'
-Tooltip: 'Drop the selected objects onto "ground" objects'
-"""
-__author__= "Campbell Barton"
-__url__= ["blender.org", "blenderartists.org"]
-__version__= "1.1"
-
-__bpydoc__= """
-"""
-
-# --------------------------------------------------------------------------
-# Drop Objects v1.0 by Campbell Barton (AKA Ideasman42)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import Draw, Geometry, Mathutils, Window
-from Blender.Mathutils import Vector, AngleBetweenVecs, RotationMatrix
-import bpy
-
-
-GLOBALS = {}
-GLOBALS['GROUND_SOURCE'] = [Draw.Create(1), Draw.Create(0)]
-GLOBALS['GROUND_GROUP_NAME'] = Draw.Create('terrain')
-GLOBALS['DROP_AXIS'] = [Draw.Create(1), Draw.Create(0)] # on what axis will we drop?
-GLOBALS['DROP_OVERLAP_CHECK'] = Draw.Create(1) # is the terrain a single skin?
-GLOBALS['DROP_ORIENT'] = Draw.Create(1)
-GLOBALS['DROP_ORIENT_VALUE'] = Draw.Create(100.0)
-GLOBALS['EVENT'] = 2
-GLOBALS['MOUSE'] = None
-
-def collect_terrain_triangles(obs_terrain):
- terrain_tris = []
- me = bpy.data.meshes.new()
-
- for ob in obs_terrain:
- def blend_face_to_terrain_tris(f):
- no = f.no
- cos = [v.co for v in f]
- if len(cos) == 4: return [(cos[0], cos[1], cos[2], no), (cos[0], cos[2], cos[3], no)]
- else: return [(cos[0], cos[1], cos[2], no), ]
-
- # Clear
- me.verts = None
- try: me.getFromObject(ob)
- except: pass
-
- me.transform(ob.matrixWorld)
- for f in me.faces: # may be [], thats ok
- terrain_tris.extend( blend_face_to_terrain_tris(f) )
-
- me.verts = None # clear to save ram
- return terrain_tris
-
-def calc_drop_loc(ob, terrain_tris, axis):
- pt = Vector(ob.loc)
-
- isect = None
- isect_best = None
- isect_best_no = None
- isect_best_len = 0.0
-
- for t1,t2,t3, no in terrain_tris:
- #if Geometry.PointInTriangle2D(pt, t1,t2,t3):
- isect = Mathutils.Intersect(t1, t2, t3, axis, pt, 1) # 1==clip
- if isect:
- if not GLOBALS['DROP_OVERLAP_CHECK'].val:
- # Find the first location
- return isect, no
- else:
- if isect_best:
- isect_len = (pt-isect).length
- if isect_len < isect_best_len:
- isect_best_len = isect_len
- isect_best = isect
- isect_best_no = no
-
- else:
- isect_best_len = (pt-isect).length
- isect_best = isect;
- isect_best_no = no
-
- return isect_best, isect_best_no
-
-
-def error_nogroup():
- Draw.PupMenu('The Group name does not exist')
-def error_noact():
- Draw.PupMenu('There is no active object')
-def error_noground():
- Draw.PupMenu('No triangles could be found to drop the objects onto')
-def error_no_obs():
- Draw.PupMenu('No objects selected to drop')
-
-# event and value arnt used
-def terrain_clamp(event, value):
-
- sce = bpy.data.scenes.active
- if GLOBALS['GROUND_SOURCE'][0].val:
- obs_terrain = [sce.objects.active]
- if not obs_terrain[0]:
- error_noact()
- return
- else:
- try: obs_terrain = bpy.data.groups[ GLOBALS['GROUND_GROUP_NAME'].val ].objects
- except:
- error_nogroup()
- return
-
- obs_clamp = [ob for ob in sce.objects.context if ob not in obs_terrain and not ob.lib]
- if not obs_clamp:
- error_no_obs()
- return
-
- terrain_tris = collect_terrain_triangles(obs_terrain)
- if not terrain_tris:
- error_noground()
- return
-
-
-
- if GLOBALS['DROP_AXIS'][0].val:
- axis = Vector(0,0,-1)
- else:
- axis = Vector(Window.GetViewVector())
-
- do_orient = GLOBALS['DROP_ORIENT'].val
- do_orient_val = GLOBALS['DROP_ORIENT_VALUE'].val/100.0
- if not do_orient_val: do_orient = False
-
- for ob in obs_clamp:
- loc, no = calc_drop_loc(ob, terrain_tris, axis)
- if loc:
- if do_orient:
- try: ang = AngleBetweenVecs(no, axis)
- except:ang = 0.0
- if ang > 90.0:
- no = -no
- ang = 180.0-ang
-
- if ang > 0.0001:
- ob_matrix = ob.matrixWorld * RotationMatrix(ang * do_orient_val, 4, 'r', axis.cross(no))
- ob.setMatrix(ob_matrix)
-
- ob.loc = loc
-
- # to make the while loop exist
- GLOBALS['EVENT'] = EVENT_EXIT
-
-
-# UI STUFF ------------------------
-def do_axis_z(e,v):
- GLOBALS['DROP_AXIS'][0].val = 1
- GLOBALS['DROP_AXIS'][1].val = 0
- GLOBALS['EVENT'] = e
-
-def do_axis_view(e,v):
- GLOBALS['DROP_AXIS'][0].val = 0
- GLOBALS['DROP_AXIS'][1].val = 1
- GLOBALS['EVENT'] = e
-
-def do_ground_source_act(e,v):
- GLOBALS['GROUND_SOURCE'][0].val = 1
- GLOBALS['GROUND_SOURCE'][1].val = 0
- GLOBALS['EVENT'] = e
-
-def do_ground_source_group(e,v):
- GLOBALS['GROUND_SOURCE'][0].val = 0
- GLOBALS['GROUND_SOURCE'][1].val = 1
- GLOBALS['EVENT'] = e
-
-def do_ground_group_name(e,v):
- try: g = bpy.data.groups[v]
- except: g = None
- if not g: error_nogroup()
- GLOBALS['EVENT'] = e
-
-def do_dummy(e,v):
- GLOBALS['EVENT'] = e
-
-EVENT_NONE = 0
-EVENT_EXIT = 1
-EVENT_REDRAW = 2
-def terain_clamp_ui():
-
- # Only to center the UI
- x,y = GLOBALS['MOUSE']
- x-=40
- y-=70
-
- Draw.Label('Drop Axis', x-70,y+120, 60, 20)
- Draw.BeginAlign()
- GLOBALS['DROP_AXIS'][0] = Draw.Toggle('Z', EVENT_REDRAW, x+20, y+120, 30, 20, GLOBALS['DROP_AXIS'][0].val, 'Drop down on the global Z axis', do_axis_z)
- GLOBALS['DROP_AXIS'][1] = Draw.Toggle('View Z', EVENT_REDRAW, x+50, y+120, 70, 20, GLOBALS['DROP_AXIS'][1].val, 'Drop allong the view vector', do_axis_view)
- Draw.EndAlign()
-
- # Source
- Draw.Label('Drop on to...', x-70,y+90, 120, 20)
- Draw.BeginAlign()
- GLOBALS['GROUND_SOURCE'][0] = Draw.Toggle('Active Object', EVENT_REDRAW, x-70, y+70, 110, 20, GLOBALS['GROUND_SOURCE'][0].val, '', do_ground_source_act)
- GLOBALS['GROUND_SOURCE'][1] = Draw.Toggle('Group', EVENT_REDRAW, x+40, y+70, 80, 20, GLOBALS['GROUND_SOURCE'][1].val, '', do_ground_source_group)
- if GLOBALS['GROUND_SOURCE'][1].val:
- GLOBALS['GROUND_GROUP_NAME'] = Draw.String('GR:', EVENT_REDRAW+1001, x-70, y+50, 190, 20, GLOBALS['GROUND_GROUP_NAME'].val, 21, '', do_ground_group_name)
- Draw.EndAlign()
-
- GLOBALS['DROP_OVERLAP_CHECK'] = Draw.Toggle('Overlapping Terrain', EVENT_NONE, x-70, y+20, 190, 20, GLOBALS['DROP_OVERLAP_CHECK'].val, "Check all terrain triangles and use the top most (slow)")
-
- Draw.BeginAlign()
- GLOBALS['DROP_ORIENT'] = Draw.Toggle('Orient Normal', EVENT_REDRAW, x-70, y-10, 110, 20, GLOBALS['DROP_ORIENT'].val, "Rotate objects to the face normal", do_dummy)
- if GLOBALS['DROP_ORIENT'].val:
- GLOBALS['DROP_ORIENT_VALUE'] = Draw.Number('', EVENT_NONE, x+40, y-10, 80, 20, GLOBALS['DROP_ORIENT_VALUE'].val, 0.0, 100.0, "Percentage to orient 0.0 - 100.0")
- Draw.EndAlign()
-
- Draw.PushButton('Drop Objects', EVENT_EXIT, x+20, y-40, 100, 20, 'Drop the selected objects', terrain_clamp)
-
- # So moving the mouse outside the popup exits the while loop
- GLOBALS['EVENT'] = EVENT_EXIT
-
-def main():
-
- # This is to set the position if the popup
- GLOBALS['MOUSE'] = Window.GetMouseCoords()
-
- # hack so the toggle buttons redraw. this is not nice at all
- while GLOBALS['EVENT'] == EVENT_REDRAW:
- Draw.UIBlock(terain_clamp_ui, 0)
-
-if __name__ == '__main__':
- main()
-
-GLOBALS.clear()
-
diff --git a/release/scripts/object_find.py b/release/scripts/object_find.py
deleted file mode 100644
index f12af07e3e4..00000000000
--- a/release/scripts/object_find.py
+++ /dev/null
@@ -1,222 +0,0 @@
-#!BPY
-"""
-Name: 'Find by Data Use'
-Blender: 242
-Group: 'Object'
-Tooltip: 'Find an object by the data it uses'
-"""
-__author__= "Campbell Barton"
-__url__= ["blender.org", "blenderartists.org"]
-__version__= "1.0"
-
-__bpydoc__= """
-"""
-
-# --------------------------------------------------------------------------
-# Find by Data Use v0.1 by Campbell Barton (AKA Ideasman42)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Image, sys, Draw, Window, Scene, Group
-import bpy
-import BPyMessages
-
-
-def get_object_images(ob):
- # Could optimize this
- if ob.type != 'Mesh':
- return []
-
- me = ob.getData(mesh=1)
-
- if not me.faceUV:
- return []
-
- unique_images = {}
-
- orig_uvlayer = me.activeUVLayer
-
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- for f in me.faces:
- i = f.image
- if i: unique_images[i.name] = i
-
- me.activeUVLayer = orig_uvlayer
-
-
- # Now get material images
- for mat in me.materials:
- if mat:
- for mtex in mat.getTextures():
- if mtex:
- tex = mtex.tex
- i = tex.getImage()
- if i: unique_images[i.name] = i
-
- return unique_images.values()
-
-
-
- # Todo, support other object types, materials
- return []
-
-
-
-def main():
-
- NAME_DATA= Draw.Create('')
- NAME_INGROUP= Draw.Create('')
- NAME_DUPGROUP= Draw.Create('')
- NAME_IMAGE= Draw.Create('')
- NAME_MATERIAL= Draw.Create('')
- NAME_TEXTURE= Draw.Create('')
-
-
- PREF_CASESENS= Draw.Create(False)
- PREF_PART_MATCH= Draw.Create(True)
-
-
- # Get USER Options
- pup_block= [\
- ('ObData:', NAME_DATA, 0, 32, 'Match with the objects data name'),\
- ('InGroup:', NAME_INGROUP, 0, 32, 'Match with the group name to find one of its objects'),\
- ('DupGroup:', NAME_DUPGROUP, 0, 32, 'Match with the group name to find an object that instances this group'),\
- ('Image:', NAME_IMAGE, 0, 32, 'Match with the image name to find an object that uses this image'),\
- ('Material:', NAME_MATERIAL, 0, 32, 'Match with the material name to find an object that uses this material'),\
- ('Texture:', NAME_TEXTURE, 0, 32, 'Match with the texture name to find an object that uses this texture'),\
- ('Case Sensitive', PREF_CASESENS, 'Do a case sensitive comparison?'),\
- ('Partial Match', PREF_PART_MATCH, 'Match when only a part of the text is in the data name'),\
- ]
-
- if not Draw.PupBlock('Find object using dataname...', pup_block):
- return
-
- NAME_DATA = NAME_DATA.val
- NAME_INGROUP = NAME_INGROUP.val
- NAME_DUPGROUP = NAME_DUPGROUP.val
- NAME_IMAGE = NAME_IMAGE.val
- NAME_MATERIAL = NAME_MATERIAL.val
- NAME_TEXTURE = NAME_TEXTURE.val
-
- PREF_CASESENS = PREF_CASESENS.val
- PREF_PART_MATCH = PREF_PART_MATCH.val
-
- if not PREF_CASESENS:
- NAME_DATA = NAME_DATA.lower()
- NAME_INGROUP = NAME_INGROUP.lower()
- NAME_DUPGROUP = NAME_DUPGROUP.lower()
- NAME_IMAGE = NAME_IMAGE.lower()
- NAME_MATERIAL = NAME_MATERIAL.lower()
- NAME_TEXTURE = NAME_TEXTURE.lower()
-
- def activate(ob, scn):
- bpy.data.scenes.active = scn
- scn.objects.selected = []
- scn.Layers = ob.Layers & (1<<20)-1
- ob.sel = 1
-
- def name_cmp(name_search, name_found):
- if name_found == None: return False
- if not PREF_CASESENS: name_found = name_found.lower()
- if PREF_PART_MATCH:
- if name_search in name_found:
- # print name_found, name_search
- return True
- else:
- if name_found == name_search:
- # print name_found, name_search
- return True
-
- return False
-
-
- if NAME_INGROUP:
- # Best we speed this up.
- bpy.data.objects.tag = False
-
- ok = False
- for group in bpy.data.groups:
- if name_cmp(NAME_INGROUP, group.name):
- for ob in group.objects:
- ob.tag = True
- ok = True
- if not ok:
- Draw.PupMenu('No Objects Found')
- return
-
- for scn in bpy.data.scenes:
- for ob in scn.objects:
- if NAME_DATA:
- if name_cmp(NAME_DATA, ob.getData(1)):
- activate(ob, scn)
- return
- if NAME_INGROUP:
- # Crap and slow but not much we can do about that
- '''
- for group in bpy.data.groups:
- if name_cmp(NAME_INGROUP, group.name):
- for ob_group in group.objects:
- if ob == ob_group:
- activate(ob, scn)
- return
- '''
- # Use speedup, this is in a group whos name matches.
- if ob.tag:
- activate(ob, scn)
- return
-
- if NAME_DUPGROUP:
- if ob.DupGroup and name_cmp(NAME_DUPGROUP, ob.DupGroup.name):
- activate(ob, scn)
- return
-
- if NAME_IMAGE:
- for img in get_object_images(ob):
- if name_cmp(NAME_IMAGE, img.name) or name_cmp(NAME_IMAGE, img.filename.split('\\')[-1].split('/')[-1]):
- activate(ob, scn)
- return
- if NAME_MATERIAL or NAME_TEXTURE:
- try: materials = ob.getData(mesh=1).materials
- except: materials = []
-
- # Add object materials
- materials.extend(ob.getMaterials())
-
- for mat in materials:
- if mat:
- if NAME_MATERIAL:
- if name_cmp(NAME_MATERIAL, mat.name):
- activate(ob, scn)
- return
- if NAME_TEXTURE:
- for mtex in mat.getTextures():
- if mtex:
- tex = mtex.tex
- if tex:
- if name_cmp(NAME_TEXTURE, tex.name):
- activate(ob, scn)
- return
-
-
- Draw.PupMenu('No Objects Found')
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/object_random_loc_sz_rot.py b/release/scripts/object_random_loc_sz_rot.py
deleted file mode 100644
index 1af0dc7218a..00000000000
--- a/release/scripts/object_random_loc_sz_rot.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!BPY
-
-"""
-Name: 'Randomize Loc Size Rot'
-Blender: 241
-Group: 'Object'
-Tooltip: 'Randomize the selected objects Loc Size Rot'
-"""
-
-__bpydoc__=\
-'''
-This script randomizes the selected objects location/size/rotation.
-'''
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-'''
-30 Jun 07 - ZanQdo:
- - Properly coded axis toggles for Loc random (didn't work at all)
- - Made Rot input values meaningful (45 will give max 45 degres of rotation)
- - Pumped up the Scale value limit
- - Made Scale input values meaningful (15 will give max 15 units bigger model)
-'''
-
-from Blender import Draw, Scene
-from Blender.Mathutils import Rand
-
-def rnd(flag):
- Random = Rand()
- if flag == "LOC":
- return (Random - 0.5) * 2
- elif flag == "ROT":
- return (Random - 0.5) * 0.035
- elif flag == "SIZE":
- return (Random - 0.5) * 1.8
-
-def randomize(sel, PREF_LOC, PREF_SIZE, PREF_ROT, PREF_LINK_AXIS, PREF_X_AXIS, PREF_Y_AXIS, PREF_Z_AXIS):
- for ob in sel:
- if PREF_LOC:
- if PREF_LINK_AXIS:
- rand = PREF_LOC*rnd("LOC")
- ob.loc = (ob.LocX+(rand*PREF_X_AXIS), ob.LocY+(rand*PREF_Y_AXIS), ob.LocZ+(rand*PREF_Z_AXIS))
- else:
- if PREF_X_AXIS: x= PREF_LOC*rnd("LOC")
- else: x= 0
- if PREF_Y_AXIS: y= PREF_LOC*rnd("LOC")
- else: y= 0
- if PREF_Z_AXIS: z= PREF_LOC*rnd("LOC")
- else: z= 0
- ob.loc = (ob.LocX+x, ob.LocY+y, ob.LocZ+z)
-
- if PREF_SIZE:
- if PREF_LINK_AXIS:
- rand = PREF_SIZE*rnd("SIZE")
- if PREF_X_AXIS: x= rand
- else: x= 0
- if PREF_Y_AXIS: y= rand
- else: y= 0
- if PREF_Z_AXIS: z= rand
- else: z= 0
-
- else:
- if PREF_X_AXIS: x= PREF_SIZE*rnd("SIZE")
- else: x= 0
- if PREF_Y_AXIS: y= PREF_SIZE*rnd("SIZE")
- else: y= 0
- if PREF_Z_AXIS: z= PREF_SIZE*rnd("SIZE")
- else: z= 0
-
- ob.size = (abs(ob.SizeX+x), abs(ob.SizeY+y), abs(ob.SizeZ+z))
-
- if PREF_ROT:
- if PREF_LINK_AXIS:
- rand = PREF_ROT*rnd("ROT")
- ob.rot = (ob.RotX+rand, ob.RotY+rand, ob.RotZ+rand)
- else:
- ob.rot = (ob.RotX+(PREF_X_AXIS*PREF_ROT*rnd("ROT")), ob.RotY+(PREF_Y_AXIS*PREF_ROT*rnd("ROT")), ob.RotZ+(PREF_Z_AXIS*PREF_ROT*rnd("ROT")))
-
-
-def main():
- scn = Scene.GetCurrent()
- if not scn.objects.context:
- return
-
- PREF_LOC= Draw.Create(0.0)
- PREF_SIZE= Draw.Create(0.0)
- PREF_ROT= Draw.Create(0.0)
- PREF_LINK_AXIS= Draw.Create(0)
- PREF_X_AXIS= Draw.Create(1)
- PREF_Y_AXIS= Draw.Create(1)
- PREF_Z_AXIS= Draw.Create(1)
-
- pup_block = [\
- ('loc:', PREF_LOC, 0.0, 100.0, 'Amount to randomize the location'),\
- ('size:', PREF_SIZE, 0.0, 100.0, 'Amount to randomize the size'),\
- ('rot:', PREF_ROT, 0.0, 360.0, 'Amount to randomize the rotation'),\
- '',\
- ('Link Axis', PREF_LINK_AXIS, 'Use the same random value for each objects XYZ'),\
- ('X Axis', PREF_X_AXIS, 'Enable X axis randomization'),\
- ('Y Axis', PREF_Y_AXIS, 'Enable Y axis randomization'),\
- ('Z Axis', PREF_Z_AXIS, 'Enable Z axis randomization'),\
- ]
-
- if not Draw.PupBlock('Object Randomize', pup_block):
- return
-
- randomize(scn.objects.context, PREF_LOC.val, PREF_SIZE.val, PREF_ROT.val, PREF_LINK_AXIS.val, PREF_X_AXIS.val, PREF_Y_AXIS.val, PREF_Z_AXIS.val)
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/object_sel2dupgroup.py b/release/scripts/object_sel2dupgroup.py
deleted file mode 100644
index 1b8067e07fb..00000000000
--- a/release/scripts/object_sel2dupgroup.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#!BPY
-
-"""
-Name: 'Selection to DupliGroup'
-Blender: 243
-Group: 'Object'
-Tooltip: 'Turn the selection into a dupliGroup using the active objects transformation, objects are moved into a new scene'
-"""
-
-__bpydoc__=\
-'''
-'''
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import *
-
-def main():
- scn = Scene.GetCurrent()
- ob_act = scn.objects.active
-
- if not ob_act:
- Draw.PupMenu('Error%t|No active object')
-
- dup_name = ob_act.name
-
- obsel = list(scn.objects.context)
-
- # Sanity check
- for ob in obsel:
- parent = ob.parent
- if parent:
- if not parent.sel or parent not in obsel:
- Draw.PupMenu('Error%t|Objects "'+ob.name+'" parent "'+parent.name+'" is not in the selection')
- return
-
- mat_act = ob_act.matrixWorld
-
- # new group
- grp = Group.New(dup_name)
- grp.objects = obsel
-
- # Create the new empty object to be the dupli
- ob_dup = scn.objects.new('Empty')
- ob_dup.setMatrix(mat_act)
- ob_dup.name = dup_name + '_dup'
-
- ob_dup.enableDupGroup = True
- ob_dup.DupGroup = grp
-
- scn_new = Scene.New(dup_name)
-
- # Transform the objects to remove the active objects matrix.
- mat_act_inv = mat_act.copy().invert()
- for ob in obsel:
- if not ob.parent:
- ob.setMatrix(ob.matrixWorld * mat_act_inv)
-
- scn_new.objects.link(ob)
- scn.objects.unlink(ob)
-
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/object_timeofs_follow_act.py b/release/scripts/object_timeofs_follow_act.py
deleted file mode 100644
index 83863da7d8f..00000000000
--- a/release/scripts/object_timeofs_follow_act.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!BPY
-"""
-Name: 'TimeOffset follow Active'
-Blender: 245
-Group: 'Object'
-Tooltip: 'ActObs animated loc sets TimeOffset on other objects at closest frame'
-"""
-__author__= "Campbell Barton"
-__url__= ["blender.org", "blenderartists.org"]
-__version__= "1.0"
-
-__bpydoc__= """
-"""
-
-# --------------------------------------------------------------------------
-# TimeOffset follow Active v1.0 by Campbell Barton (AKA Ideasman42)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender import Image, sys, Draw, Window, Scene, Group
-import bpy
-import BPyMessages
-
-
-def main():
-
- sce = Scene.GetCurrent()
-
- ob_act = sce.objects.active
-
- if not ob_act:
- Draw.PupMenu("Error%t|no active object")
- return
-
- objects = list(sce.objects.context)
-
- try: objects.remove(ob_act)
- except: pass
-
- if not objects:
- Draw.PupMenu("Error%t|no objects selected")
- return
-
- curframe = Blender.Get('curframe')
-
- FRAME_START= Draw.Create( Blender.Get('staframe') )
- FRAME_END= Draw.Create( Blender.Get('endframe') )
-
- # Get USER Options
- pup_block= [\
- ('Start:', FRAME_START, 1, 300000, 'Use the active objects position starting at this frame'),\
- ('End:', FRAME_END, 1, 300000, 'Use the active objects position starting at this frame'),\
- ]
-
- if not Draw.PupBlock('Set timeoffset...', pup_block):
- return
-
- FRAME_START = FRAME_START.val
- FRAME_END = FRAME_END.val
-
- if FRAME_START >= FRAME_END:
- Draw.PupMenu("Error%t|frames are not valid")
-
-
- # Ok - all error checking
- locls_act = []
- for f in xrange((FRAME_END-FRAME_START)):
- i = FRAME_START+f
- Blender.Set('curframe', i)
- locls_act.append(ob_act.matrixWorld.translationPart())
-
- for ob in objects:
- loc = ob.matrixWorld.translationPart()
- best_frame = -1
- best_dist = 100000000
- for i, loc_act in enumerate(locls_act):
- dist = (loc_act-loc).length
- if dist < best_dist:
- best_dist = dist
- best_frame = i + FRAME_START
-
- ob.timeOffset = float(best_frame)
-
- # Set the original frame
- Blender.Set('curframe', curframe)
-
-if __name__ == '__main__':
- main()
-
diff --git a/release/scripts/off_export.py b/release/scripts/off_export.py
deleted file mode 100644
index 6aac3ff885b..00000000000
--- a/release/scripts/off_export.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!BPY
-
-"""
-Name: 'DEC Object File Format (.off)...'
-Blender: 232
-Group: 'Export'
-Tooltip: 'Export selected mesh to DEC Object File Format (*.off)'
-"""
-
-__author__ = "Anthony D'Agostino (Scorpius)"
-__url__ = ("blender", "blenderartists.org",
-"Author's homepage, http://www.redrival.com/scorpius")
-__version__ = "Part of IOSuite 0.5"
-
-__bpydoc__ = """\
-This script exports meshes to DEC Object File Format.
-
-The DEC (Digital Equipment Corporation) OFF format is very old and
-almost identical to Wavefront's OBJ. I wrote this so I could get my huge
-meshes into Moonlight Atelier. (DXF can also be used but the file size
-is five times larger than OFF!) Blender/Moonlight users might find this
-script to be very useful.
-
-Usage:<br>
- Select meshes to be exported and run this script from "File->Export" menu.
-
-Notes:<br>
- Only exports a single selected mesh.
-"""
-
-# $Id:
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | February 3, 2001 |
-# | Read and write Object File Format (*.off) |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-import BPyMessages
-
-# Python 2.3 has no reversed.
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-# ==============================
-# ====== Write OFF Format ======
-# ==============================
-def write(filename):
- file = open(filename, 'wb')
- scn= Blender.Scene.GetCurrent()
- object= scn.objects.active
- if not object or object.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- Blender.Window.WaitCursor(1)
- mesh = object.getData(mesh=1)
-
- # === OFF Header ===
- file.write('OFF\n')
- file.write('%d %d %d\n' % (len(mesh.verts), len(mesh.faces), 0))
-
- # === Vertex List ===
- for i, v in enumerate(mesh.verts):
- file.write('%.6f %.6f %.6f\n' % tuple(v.co))
-
- # === Face List ===
- for i, f in enumerate(mesh.faces):
- file.write('%i' % len(f))
- for v in reversed(f.v):
- file.write(' %d' % v.index)
- file.write('\n')
-
- file.close()
- Blender.Window.WaitCursor(0)
- message = 'Successfully exported "%s"' % Blender.sys.basename(filename)
-
-
-def fs_callback(filename):
- if not filename.lower().endswith('.off'): filename += '.off'
- write(filename)
-
-Blender.Window.FileSelector(fs_callback, "Export OFF", Blender.sys.makename(ext='.off'))
diff --git a/release/scripts/off_import.py b/release/scripts/off_import.py
deleted file mode 100644
index e8ab96c51c5..00000000000
--- a/release/scripts/off_import.py
+++ /dev/null
@@ -1,177 +0,0 @@
-#!BPY
-
-"""
-Name: 'DEC Object File Format (.off)...'
-Blender: 242
-Group: 'Import'
-Tooltip: 'Import DEC Object File Format (*.off)'
-"""
-
-__author__ = "Anthony D'Agostino (Scorpius), Campbell Barton (Ideasman)"
-__url__ = ("blender", "blenderartists.org",
-"Author's homepage, http://www.redrival.com/scorpius")
-__version__ = "Part of IOSuite 0.5"
-
-__bpydoc__ = """\
-This script imports DEC Object File Format files to Blender.
-
-The DEC (Digital Equipment Corporation) OFF format is very old and
-almost identical to Wavefront's OBJ. I wrote this so I could get my huge
-meshes into Moonlight Atelier. (DXF can also be used but the file size
-is five times larger than OFF!) Blender/Moonlight users might find this
-script to be very useful.
-
-Usage:<br>
- Execute this script from the "File->Import" menu and choose an OFF file to
-open.
-
-Notes:<br>
- UV Coordinate support has been added. - Scorpius
- FGON support has been added. - Cam
- New Mesh module now used. - Cam
-"""
-
-# $Id:
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | February 3, 2001 |
-# | Read and write Object File Format (*.off) |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-
-
-# =============================
-# ====== Read OFF Format ======
-# =============================
-def read(filename):
- start = Blender.sys.time()
- file = open(filename, "rb")
-
- verts = [] # verts and uvs are aligned
- uvs = []
-
- faces = []
-
- # === OFF Header ===
- # Skip the comments
- offheader= file.readline()
- while offheader.startswith('#') or offheader.lower().startswith('off'):
- offheader = file.readline()
-
- numverts, numfaces, numedges= map(int, offheader.split())
- if offheader.find('ST') >= 0:
- has_uv = True
- Vector= Mathutils.Vector
- else:
- has_uv = False
-
- # === Vertex List ===
- for i in xrange(numverts):
- if has_uv:
- x, y, z, u, v = map(float, file.readline().split())
- uvs.append(Vector(u, v))
- else:
- x, y, z = map(float, file.readline().split())
- verts.append((x, y, z))
-
- # === Face List ===
- def fan_face(face):
- # 'Elp, Only fan fill- if were keen we could use our trusty BPyMesh.ngon function
- # So far I havnt seen any big ngons in on off file - Cam
- return [ (face[0], face[i-1], face[i]) for i in xrange(2,len(face))]
-
- for i in xrange(numfaces):
- line = file.readline().split() # ignore the first value, its just the face count but we can work that out anyway
-
- # appends all the indicies in reverse order except 0
- # xrange(len(line)-1, -1, -1) # normal reverse loop
- # xrange(len(line)-1, 0, -1) # ignoring index 0 because its only a count
- # face= [int(line[j]) for j in xrange(len(line)-1, 0, -1)]
-
- # Some OFF files have floats on the end of the face. what are these for?
- face= [int(line[j]) for j in xrange(int(line[0]), 0, -1)]
-
-
- if len(face)>4:
- faces.extend( fan_face(face) )
- else:
- faces.append(face)
-
- scn= Blender.Scene.GetCurrent()
- name= filename.split('/')[-1].split('\\')[-1].split('.')[0]
- me= Blender.Mesh.New(name)
- me.verts.extend(verts)
- me.faces.extend(faces)
-
- # Now edges if we have them, render fgon
- if numedges:
- FGON_FLAG= Blender.Mesh.EdgeFlags.FGON
-
- edge_dict= {}
- # Set all edges to be fgons by default
- for ed in me.edges:
- ed.flag |= FGON_FLAG
- edge_dict[ed.key]= ed
-
- # Now make known edges visible
- has_edges = True
- for i in xrange(numedges):
- try:
- i1,i2= file.readline().split()
- except:
- has_edges = False
- break # some files dont define edges :/
-
- i1= int(i1)
- i2= int(i2)
- if i1>i2:
- i1,i2= i2,i1
-
- # We know this edge is seen so unset the fgon flag
- edge_dict[i1,i2].flag &= ~FGON_FLAG
-
- if not has_edges:
- # dang, we'v turned all the edges into fgons and then the file didnt define any edges.
- # oh well, just enable them all
- for ed in me.edges:
- ed.flag &= ~FGON_FLAG
-
- # Assign uvs from vert index
- if has_uv:
- for f in me.faces:
- f_uv= f.uv
- for i, v in enumerate(f): # same as f.v
- f_uv[i]= uvs[v.index]
-
- for ob in scn.objects:
- ob.sel=0
-
- scn.objects.active = scn.objects.new(me, name)
- Blender.Window.RedrawAll()
- print 'Off "%s" imported in %.4f seconds.' % (name, Blender.sys.time()-start)
-
-
-if __name__=='__main__':
- Blender.Window.FileSelector(read, 'Import OFF', '*.off')
diff --git a/release/scripts/paths_import.py b/release/scripts/paths_import.py
deleted file mode 100644
index b35d7fe5c65..00000000000
--- a/release/scripts/paths_import.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!BPY
-# coding: utf-8
-"""
-Name: 'Paths (.svg, .ps, .eps, .ai, Gimp)'
-Blender: 233
-Group: 'Import'
-Submenu: 'Gimp 1.0 - 1.2.5' Gimp_1_0
-Submenu: 'Gimp 2.0' Gimp_2_0
-Submenu: 'Illustrator (.ai) PS-Adobe-2.0' AI
-Submenu: 'InkScape (.svg)' SVG
-Submenu: 'Postscript (.eps/.ps) PS-Adobe-2.0' EPS
-Tip: 'Import a path from any of a set of formats (still experimental)'
-"""
-
-__author__ = "Jean-Michel Soler (jms)"
-__url__ = ("blender", "blenderartists.org",
-"AI importer's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_ai.htm",
-"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "0.1.1"
-
-__bpydoc__ = """\
-Paths Import imports paths from a selection of different formats:
-
-- Gimp 1.0 -> 1.2.5;<br>
-- Gimp 2.0;<br>
-- AI PS-Adobe 2.0;<br>
-- Inkscape (svg);<br>
-- Postscript (ps/eps)
-
-Usage:
- Run the script from "File->Import", select the desired format from the
-pop-up menu and select the file to open.
-
-Notes:<br>
- If the imported curve looks "messy", you may need to enter edit mode with the imported curve selected and toggle cyclic mode for it, by selecting all its points and pressing "c" or using the Curve menu in the 3d view header.
-"""
-
-#----------------------------------------------
-# (c) jm soler juillet 2004, released under GPL
-# for the Blender 2.45 Python Scripts Bundle.
-#----------------------------------------------
-"""
-Ce programme est libre, vous pouvez le redistribuer et/ou
-le modifier selon les termes de la Licence Publique Générale GNU
-publiée par la Free Software Foundation (version 2 ou bien toute
-autre version ultérieure choisie par vous).
-
-Ce programme est distribué car potentiellement utile, mais SANS
-AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties
-de commercialisation ou d'adaptation dans un but spécifique.
-Reportez-vous à la Licence Publique Générale GNU pour plus de détails.
-
-Vous devez avoir reçu une copie de la Licence Publique Générale GNU
-en même temps que ce programme ; si ce n'est pas le cas, écrivez à la
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307, États-Unis.
-
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-"""
-import Blender
-
-argv=__script__['arg']
-
-if argv=='SVG':
- from paths_svg2obj import *
- fonctionSELECT = functionSELECT # can they all be called function?
-
-elif argv=='AI':
- from paths_ai2obj import *
-
-elif argv=='EPS':
- from paths_eps2obj import *
-
-elif argv=='Gimp_1_0':
- from paths_gimp2obj import *
-
-elif argv=='Gimp_2_0':
- from paths_svg2obj import *
- fonctionSELECT = functionSELECT # can they all be called function?
-
-text = 'Import %s' % argv
-Blender.Window.FileSelector (fonctionSELECT, text)
-
diff --git a/release/scripts/ply_import.py b/release/scripts/ply_import.py
deleted file mode 100644
index 29e8ce48361..00000000000
--- a/release/scripts/ply_import.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#!BPY
-
-"""
-Name: 'Stanford PLY (*.ply)...'
-Blender: 248
-Group: 'Import'
-Tip: 'Import a Stanford PLY file'
-"""
-
-__author__ = 'Bruce Merry'
-__version__ = '0.93'
-__bpydoc__ = """\
-This script imports Stanford PLY files into Blender. It supports per-vertex
-normals, and per-face colours and texture coordinates.
-
-Usage:
-
-Run this script from "File->Import" and select the desired PLY file.
-"""
-
-# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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.
-
-
-# 20th Oct 2008, 0.93 - Updated by Campbell Barton AKA ideasman42, use Mesh rather then NMesh, dont import normals, vcolors work again.
-# Updated by Campbell Barton AKA Ideasman42, 10% faster code.
-
-# Portions of this code are taken from mod_meshtools.py in Blender
-# 2.32.
-
-import Blender
-try:
- import re, struct
-except:
- struct= None
-
-class element_spec(object):
- __slots__ = 'name', 'count', 'properties'
- def __init__(self, name, count):
- self.name = name
- self.count = count
- self.properties = []
-
- def load(self, format, stream):
- if format == 'ascii':
- stream = re.split('\s+', stream.readline())
- return map(lambda x: x.load(format, stream), self.properties)
-
- def index(self, name):
- for i, p in enumerate(self.properties):
- if p.name == name: return i
- return -1
-
-class property_spec(object):
- __slots__ = 'name', 'list_type', 'numeric_type'
- def __init__(self, name, list_type, numeric_type):
- self.name = name
- self.list_type = list_type
- self.numeric_type = numeric_type
-
- def read_format(self, format, count, num_type, stream):
- if format == 'ascii':
- if (num_type == 's'):
- ans = []
- for i in xrange(count):
- s = stream[i]
- if len(s) < 2 or s[0] != '"' or s[-1] != '"':
- print 'Invalid string', s
- print 'Note: ply_import.py does not handle whitespace in strings'
- return None
- ans.append(s[1:-1])
- stream[:count] = []
- return ans
- if (num_type == 'f' or num_type == 'd'):
- mapper = float
- else:
- mapper = int
- ans = map(lambda x: mapper(x), stream[:count])
- stream[:count] = []
- return ans
- else:
- if (num_type == 's'):
- ans = []
- for i in xrange(count):
- fmt = format + 'i'
- data = stream.read(struct.calcsize(fmt))
- length = struct.unpack(fmt, data)[0]
- fmt = '%s%is' % (format, length)
- data = stream.read(struct.calcsize(fmt))
- s = struct.unpack(fmt, data)[0]
- ans.append(s[:-1]) # strip the NULL
- return ans
- else:
- fmt = '%s%i%s' % (format, count, num_type)
- data = stream.read(struct.calcsize(fmt));
- return struct.unpack(fmt, data)
-
- def load(self, format, stream):
- if (self.list_type != None):
- count = int(self.read_format(format, 1, self.list_type, stream)[0])
- return self.read_format(format, count, self.numeric_type, stream)
- else:
- return self.read_format(format, 1, self.numeric_type, stream)[0]
-
-class object_spec(object):
- __slots__ = 'specs'
- 'A list of element_specs'
- def __init__(self):
- self.specs = []
-
- def load(self, format, stream):
- return dict([(i.name,[i.load(format, stream) for j in xrange(i.count) ]) for i in self.specs])
-
- '''
- # Longhand for above LC
- answer = {}
- for i in self.specs:
- answer[i.name] = []
- for j in xrange(i.count):
- if not j % 100 and meshtools.show_progress:
- Blender.Window.DrawProgressBar(float(j) / i.count, 'Loading ' + i.name)
- answer[i.name].append(i.load(format, stream))
- return answer
- '''
-
-
-def read(filename):
- format = ''
- version = '1.0'
- format_specs = {'binary_little_endian': '<',
- 'binary_big_endian': '>',
- 'ascii': 'ascii'}
- type_specs = {'char': 'b',
- 'uchar': 'B',
- 'int8': 'b',
- 'uint8': 'B',
- 'int16': 'h',
- 'uint16': 'H',
- 'ushort': 'H',
- 'int': 'i',
- 'int32': 'i',
- 'uint': 'I',
- 'uint32': 'I',
- 'float': 'f',
- 'float32': 'f',
- 'float64': 'd',
- 'double': 'd',
- 'string': 's'}
- obj_spec = object_spec()
-
- try:
- file = open(filename, 'rU') # Only for parsing the header, not binary data
- signature = file.readline()
-
- if not signature.startswith('ply'):
- print 'Signature line was invalid'
- return None
-
- while 1:
- tokens = re.split(r'[ \n]+', file.readline())
-
- if (len(tokens) == 0):
- continue
- if (tokens[0] == 'end_header'):
- break
- elif (tokens[0] == 'comment' or tokens[0] == 'obj_info'):
- continue
- elif (tokens[0] == 'format'):
- if (len(tokens) < 3):
- print 'Invalid format line'
- return None
- if (tokens[1] not in format_specs): # .keys()): # keys is implicit
- print 'Unknown format', tokens[1]
- return None
- if (tokens[2] != version):
- print 'Unknown version', tokens[2]
- return None
- format = tokens[1]
- elif (tokens[0] == 'element'):
- if (len(tokens) < 3):
- print 'Invalid element line'
- return None
- obj_spec.specs.append(element_spec(tokens[1], int(tokens[2])))
- elif (tokens[0] == 'property'):
- if (not len(obj_spec.specs)):
- print 'Property without element'
- return None
- if (tokens[1] == 'list'):
- obj_spec.specs[-1].properties.append(property_spec(tokens[4], type_specs[tokens[2]], type_specs[tokens[3]]))
- else:
- obj_spec.specs[-1].properties.append(property_spec(tokens[2], None, type_specs[tokens[1]]))
-
- if format != 'ascii':
- file.close() # was ascii, now binary
- file = open(filename, 'rb')
-
- # skip the header...
- while not file.readline().startswith('end_header'):
- pass
-
- obj = obj_spec.load(format_specs[format], file)
-
- except IOError, (errno, strerror):
- try: file.close()
- except: pass
-
- return None
- try: file.close()
- except: pass
-
- return (obj_spec, obj);
-
-def load_ply(filename):
- t = Blender.sys.time()
- obj_spec, obj = read(filename)
- if obj == None:
- print 'Invalid file'
- return
-
- uvindices = colindices = None
- # noindices = None # Ignore normals
-
- for el in obj_spec.specs:
- if el.name == 'vertex':
- vindices = vindices_x, vindices_y, vindices_z = (el.index('x'), el.index('y'), el.index('z'))
- # noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
- # if -1 in noindices: noindices = None
- uvindices = (el.index('s'), el.index('t'))
- if -1 in uvindices: uvindices = None
- colindices = (el.index('red'), el.index('green'), el.index('blue'))
- if -1 in colindices: colindices = None
- elif el.name == 'face':
- findex = el.index('vertex_indices')
-
- mesh_faces = []
- mesh_uvs = []
- mesh_colors = []
-
- def add_face(vertices, indices, uvindices, colindices):
- mesh_faces.append(indices)
- if uvindices: mesh_uvs.append([ (vertices[index][uvindices[0]], 1.0 - vertices[index][uvindices[1]]) for index in indices])
- if colindices: mesh_colors.append([ (vertices[index][colindices[0]], vertices[index][colindices[1]], vertices[index][colindices[2]]) for index in indices])
-
-
- if uvindices or colindices:
- # If we have Cols or UVs then we need to check the face order.
- add_face_simple = add_face
-
- # EVIL EEKADOODLE - face order annoyance.
- def add_face(vertices, indices, uvindices, colindices):
- if len(indices)==4:
- if indices[2]==0 or indices[3]==0:
- indices= indices[2], indices[3], indices[0], indices[1]
- elif len(indices)==3:
- if indices[2]==0:
- indices= indices[1], indices[2], indices[0]
-
- add_face_simple(vertices, indices, uvindices, colindices)
-
- verts = obj['vertex']
-
- if 'face' in obj:
- for f in obj['face']:
- ind = f[findex]
- len_ind = len(ind)
- if len_ind <= 4:
- add_face(verts, ind, uvindices, colindices)
- else:
- # Fan fill the face
- for j in xrange(len_ind - 2):
- add_face(verts, (ind[0], ind[j + 1], ind[j + 2]), uvindices, colindices)
-
- mesh = Blender.Mesh.New()
-
- mesh.verts.extend([(v[vindices_x], v[vindices_y], v[vindices_z]) for v in obj['vertex']])
-
- if mesh_faces:
- mesh.faces.extend(mesh_faces, smooth=True, ignoreDups=True)
-
- if uvindices or colindices:
- if uvindices: mesh.faceUV = True
- if colindices: mesh.vertexColors = True
-
- for i, f in enumerate(mesh.faces):
- if uvindices:
- ply_uv = mesh_uvs[i]
- for j, uv in enumerate(f.uv):
- uv[:] = ply_uv[j]
-
- if colindices:
- ply_col = mesh_colors[i]
- for j, col in enumerate(f.col):
- col.r, col.g, col.b = ply_col[j]
-
- mesh.calcNormals()
-
-
- objname = Blender.sys.splitext(Blender.sys.basename(filename))[0]
- scn= Blender.Scene.GetCurrent()
- scn.objects.selected = []
-
- mesh.name= objname
- scn.objects.active = scn.objects.new(mesh)
-
- Blender.Redraw()
- Blender.Window.DrawProgressBar(1.0, '')
- print '\nSuccessfully imported "%s" in %.3f sec' % (filename, Blender.sys.time()-t)
-
-def main():
- if not struct:
- msg = 'This importer requires a full python install'
- if Blender.mode == 'background': print msg
- else: Blender.Draw.PupMenu(msg)
- return
-
- Blender.Window.FileSelector(load_ply, 'Import PLY', '*.ply')
-
-if __name__=='__main__':
- main()
-
-'''
-import bpy
-import os
-files = os.popen('find /fe/ply -iname "*.ply"').readlines()
-
-
-files.sort()
-tot = len(files)
-for i, f in enumerate(files):
- if i < 26 or i > 1000000:
- continue
- #if i != 12686:
- # continue
-
- f = f.strip()
- print f, i, tot
- sce = bpy.data.scenes.new(f.split('/')[-1])
- bpy.data.scenes.active = sce
- # Window.
- load_ply(f)
-''' \ No newline at end of file
diff --git a/release/scripts/raw_export.py b/release/scripts/raw_export.py
deleted file mode 100644
index e3c588cac10..00000000000
--- a/release/scripts/raw_export.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#!BPY
-
-"""
-Name: 'Raw Faces (.raw)...'
-Blender: 245
-Group: 'Export'
-Tooltip: 'Export selected mesh to Raw Format (.raw)'
-"""
-
-__author__ = "Anthony D'Agostino (Scorpius)"
-__url__ = ("blender", "blenderartists.org",
-"Author's homepage, http://www.redrival.com/scorpius")
-__version__ = "Part of IOSuite 0.5"
-
-__bpydoc__ = """\
-This script exports meshes to Raw file format.
-
-The raw triangle format is very simple; it has no verts or faces lists.
-It's just a simple ascii text file with the vertices of each triangle or quad
-listed on each line. There were some very old utilities (when the PovRay
-forum was in existence on CompuServe) that preformed operations on these
-files.
-
-Usage:<br>
- Select meshes to be exported and run this script from "File->Export" menu.
-"""
-
-# $Id$
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | April 28, 2002 |
-# | Read and write RAW Triangle File Format (*.raw) |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-import BPyMesh
-
-# =================================
-# === Write RAW Triangle Format ===
-# =================================
-def write(filename):
- start = Blender.sys.time()
- if not filename.lower().endswith('.raw'):
- filename += '.raw'
-
- scn= Blender.Scene.GetCurrent()
- ob= scn.objects.active
- if not ob:
- Blender.Draw.PupMenu('Error%t|Select 1 active object')
- return
-
- file = open(filename, 'wb')
-
- mesh = BPyMesh.getMeshFromObject(ob, None, True, False, scn)
- if not mesh:
- Blender.Draw.PupMenu('Error%t|Could not get mesh data from active object')
- return
-
- mesh.transform(ob.matrixWorld)
-
-
- file = open(filename, "wb")
- for f in mesh.faces:
- for v in f:
- file.write('%.6f %.6f %.6f ' % tuple(v.co))
- file.write('\n')
- file.close()
-
- end = Blender.sys.time()
- message = 'Successfully exported "%s" in %.4f seconds' % ( Blender.sys.basename(filename), end-start)
- print message
-
-
-def main():
- Blender.Window.FileSelector(write, 'RAW Export', Blender.sys.makename(ext='.raw'))
-
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/raw_import.py b/release/scripts/raw_import.py
deleted file mode 100644
index 76c03c77337..00000000000
--- a/release/scripts/raw_import.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!BPY
-
-"""
-Name: 'Raw Faces (.raw)...'
-Blender: 242
-Group: 'Import'
-Tooltip: 'Import Raw Triangle File Format (.raw)'
-"""
-
-__author__ = "Anthony D'Agostino (Scorpius)"
-__url__ = ("blender", "blenderartists.org",
-"Author's homepage, http://www.redrival.com/scorpius")
-__version__ = "Part of IOSuite 0.5"
-
-__bpydoc__ = """\
-This script imports Raw Triangle File format files to Blender.
-
-The raw triangle format is very simple; it has no verts or faces lists.
-It's just a simple ascii text file with the vertices of each triangle
-listed on each line. There were some very old utilities (when the PovRay
-forum was in existence on CompuServe) that preformed operations on these
-files.
-
-Usage:<br>
- Execute this script from the "File->Import" menu and choose a Raw file to
-open.
-
-Notes:<br>
- Generates the standard verts and faces lists, but without duplicate
-verts. Only *exact* duplicates are removed, there is no way to specify a
-tolerance.
-"""
-
-# $Id$
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | April 28, 2002 |
-# | Read and write RAW Triangle File Format (*.raw) |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-
-# ================================
-# === Read RAW Triangle Format ===
-# ================================
-def read(filename):
- t = Blender.sys.time()
- file = open(filename, "rb")
-
- # Collect data from RAW format
- def line_to_face(line):
- # Each triplet is an xyz float
- line_split= map(float, line.split())
- if len(line_split)==9: # Tri
- f1, f2, f3, f4, f5, f6, f7, f8, f9 = line_split
- return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9)]
- if len(line_split)==12: # Quad
- f1, f2, f3, f4, f5, f6, f7, f8, f9, A, B, C = line_split
- return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9), (A, B, C)]
-
- faces = [ line_to_face(line) for line in file.readlines()]
- file.close()
-
- # Generate verts and faces lists, without duplicates
- verts = []
- coords = {}
- index = 0
-
- for f in faces:
- if f: # Line might be blank
- for i, v in enumerate(f):
- try:
- f[i]= coords[v]
- except:
- f[i]= coords[v] = index
- index += 1
- verts.append(v)
-
- me= Blender.Mesh.New()
- me.verts.extend(verts)
- me.faces.extend(faces)
-
-
- scn= Blender.Scene.GetCurrent()
- for obj in scn.objects:
- obj.sel= 0
-
- me.name= Blender.sys.splitext(Blender.sys.basename(filename))[0]
- ob = scn.objects.new(me)
- Blender.Redraw()
-
- print 'Successfully imported "%s" in %.4f seconds' % (Blender.sys.basename(filename), Blender.sys.time()-t)
-
-
-def main():
- Blender.Window.FileSelector(read, 'RAW Import', Blender.sys.makename(ext='.raw'))
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/renameobjectbyblock.py b/release/scripts/renameobjectbyblock.py
deleted file mode 100644
index eeea815c650..00000000000
--- a/release/scripts/renameobjectbyblock.py
+++ /dev/null
@@ -1,178 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Object Name Editor'
-Blender: 232
-Group: 'Object'
-Tip: 'GUI to select and rename objects.'
-"""
-
-__author__ = "Jean-Michel Soler (jms)"
-__url__ = ("blender", "blenderartists.org",
-"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_renameobjectgui.htm",
-"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "233"
-
-__bpydoc__ = """\
-This script offers a GUI to rename selected objects according to a given
-rule.
-
-Usage:
-
-Open it from the 3d View's "Object->Scripts" menu and select the objects to
-rename and the rule from the buttons in its GUI.
-"""
-
-# ----------------------------------------------------------
-# Name OBJECT changer
-# (c) 2004 jean-michel soler
-# -----------------------------------------------------------
-#----------------------------------------------
-# Page officielle/offcial page du blender python Name OBJECT changer:
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_renameobjectgui.htm
-# Communiquer les problemes et erreurs sur:
-# To Communicate problems and errors on:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#---------------------------------------------
-# Blender Artistic License
-# http://download.blender.org/documentation/html/x21254.html
-#---------------------------------------------
-
-CVS=0
-
-import Blender
-from Blender import *
-from Blender.Draw import *
-from Blender.BGL import *
-
-
-
-O = list(Scene.GetCurrent().objects)
-stringlist=[[],[]]
-
-
-def renew():
- global O
-
- #O = Object.Get()
- O = list(Scene.GetCurrent().objects)
- #param= [ [p.name, i, p.getType()] for i, p in enumerate(O) ]
-
- PARAM={}
- evt=9
- stringlist=[[],[],[]]
- for i, ob in enumerate(O):
- obname= ob.name
- PARAM[obname] = [Create(ob.sel), evt, i, ob.getType(), Create(obname), evt+1, ob]
-
- stringlist[0].append(evt+1)
- stringlist[1].append(obname)
- stringlist[2].append(evt)
- evt+=2
- return PARAM,stringlist
-
-NEWNAME=Create('Name')
-
-alignment={'BEGIN' : [Create(1),5],
- 'END' : [Create(0),6],
- 'POINT' : [Create(0),7],
- 'FULL' : [Create(0),8]}
-
-def rename():
- global NEWNAME, alignment, O, PARAM, stringlist
- newname= NEWNAME.val
- for obname, value in PARAM.iteritems():
- if value[0].val: # Selected
- if alignment['END'][0].val:
- value[6].setName(obname+newname)
- elif alignment['BEGIN'][0].val:
- value[6].setName(newname+obname)
- elif alignment['FULL'][0].val:
- value[6].setName(newname)
- PARAM, stringlist = renew()
-
-PARAM, stringlist = renew()
-
-def EVENT(evt,val):
- pass
-
-def BUTTON(evt):
- global PARAM , alignment, O, stringlist, CVS
- if (evt==1):
- Exit()
- elif (evt==2):
- rename()
- elif (evt==3):
- PARAM, stringlist = renew()
-
- elif (evt in [5,6,7,8]):
- for k in alignment.iterkeys():
- if alignment[k][1]!=evt:
- alignment[k][0].val=0
-
-
- elif (evt in stringlist[0]):
- O[PARAM[stringlist[1][(evt-9)/2]][2]].setName(PARAM[stringlist[1][(evt-9)/2]][4].val)
- PARAM, stringlist = renew()
-
- elif (evt in stringlist[2]):
- try:
- O[PARAM[stringlist[1][(evt-9)/2]][2]].select(PARAM[stringlist[1][(evt-9)/2]][0].val)
- except:
- pass
-
- Blender.Redraw()
-
-def DRAW():
- global PARAM, O, NEWNAME, alignment
-
-
- #glColor3f(0.7, 0.7, 0.7)
- glClear(GL_COLOR_BUFFER_BIT)
- glColor3f(0.1, 0.1, 0.15)
-
- size=Buffer(GL_FLOAT, 4)
- glGetFloatv(GL_SCISSOR_BOX, size)
- size= size.list
- for s in [0,1,2,3]: size[s]=int(size[s])
- ligne=20
-
- Button ("Exit",1,20,1,80,ligne)
- Button ("Rename",2,102,1,80,ligne)
- Button ("Renew",3,184,1,80,ligne)
-
- glRasterPos2f(20, ligne*2-10)
- Text("Object Name Editor")
- NEWNAME=String('Add String: ', 4, 150, ligne*2-16, 150, 18, NEWNAME.val,120 )
-
- key= alignment.keys()
- key.sort()
- n=150+150+4
- for k in key:
- alignment[k][0]= Toggle(k,alignment[k][1],n,ligne*2-16, 40, 18, alignment[k][0].val)
- n+=40+4
-
- max=size[3] / 22 -2
- pos = 0
- decal = 20
-
- keys=[[PARAM[k][1],k] for k in PARAM.iterkeys()]
- keys.sort()
-
-
- for p_ in keys:
- p=p_[1]
- if pos==max:
- decal+=152
- pos=1
- else:
- pos+=1
- PARAM[p][0]=Toggle('S',PARAM[p][1],decal,pos*22+22,20,20, PARAM[p][0].val,"Select this one for a group renaming")
- PARAM[p][4]=String('',PARAM[p][5],decal+20,pos*22+22,90,20, PARAM[p][4].val,200, "string button to rename immediately but only this object")
-
- glRasterPos2f(decal+115,pos*22+24)
- Text(PARAM[p][3][:4])
-
-if __name__=='__main__':
- Register(DRAW,EVENT,BUTTON)
-
diff --git a/release/scripts/render_save_layers.py b/release/scripts/render_save_layers.py
deleted file mode 100644
index c91fcce7948..00000000000
--- a/release/scripts/render_save_layers.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!BPY
-
-"""
-Name: 'Save Render Layers...'
-Blender: 245
-Group: 'Render'
-Tooltip: 'Save current renderlayers as a BPython script'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0"
-
-__bpydoc__ = """\
-"""
-
-# --------------------------------------------------------------------------
-# The scripts generated by this script are put under Public Domain by
-# default, but you are free to edit the ones you generate with this script
-# and change their license to another one of your choice.
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender.Window import Theme, FileSelector
-from Blender import Scene
-
-sce = Scene.GetCurrent()
-rend = sce.render
-
-# default filename: filename + scenename + '_renderlayer.py' in user's scripts dir:
-default_fname = Blender.Get("scriptsdir")
-if not default_fname:
- default_fname = Blender.Get("uscriptsdir")
-
-if default_fname:
- default_fname = Blender.sys.join(default_fname, sce.name + '_renderlayer.py')
- default_fname = default_fname.replace(' ','_')
-
-def write_renderlayers(filename):
- "Write the current renderlayer as a bpython script"
-
- if not filename.endswith('.py'): filename += '.py'
-
- fout = file(filename, "w")
-
- fout.write("""#!BPY
-
-# \"\"\"
-# Name: '%s'
-# Blender: 245
-# Group: 'Render'
-# Tooltip: ''
-# \"\"\"
-
-__%s__ = "????"
-__%s__ = "2.43"
-__%s__ = ["blender"]
-__%s__ = \"\"\"\\
-You can edit this section to write something about your script that can
-be read then with the Scripts Help Browser script in Blender.
-
-Remember to also set author, version and possibly url(s) above. You can also
-define an __email__ tag, check some bundled script's source for examples.
-\"\"\"
-
-# This script was automatically generated by the render_save_layers.py bpython script.
-# By default, these generated scripts are released as Public Domain, but you
-# are free to change the license of the scripts you generate with
-# render_save_layers.py before releasing them.
-
-import Blender
-from Blender import Scene
-
-sce = Scene.GetCurrent()
-rend = sce.render
-""" % (sce.name, "author", "version", "url", "bpydoc"))
-
- for lay in rend.renderLayers: #
- fout.write("\nlay = rend.addRenderLayer()\n")
- fout.write("lay.name = \"%s\"\n" % lay.name)
-
- exec("vars = dir(lay)")
-
- for var in vars:
- if var.startswith('_'):
- continue
-
- v = "lay.%s" % var
- exec("value = %s" % v)
- if type(value) == str:
- fout.write("%s = '%s'\n" % (v, value))
- else:
- fout.write("%s = %s\n" % (v, value))
-
- fout.write('\nBlender.Redraw(-1)')
- fout.close()
- try:
- Blender.UpdateMenus()
- except:
- Blender.Draw.PupMenu("Warning - check console!%t|Menus could not be automatically updated")
-
-FileSelector(write_renderlayers, "Save RenderLayers", default_fname)
diff --git a/release/scripts/rvk1_torvk2.py b/release/scripts/rvk1_torvk2.py
deleted file mode 100644
index d013343c05c..00000000000
--- a/release/scripts/rvk1_torvk2.py
+++ /dev/null
@@ -1,341 +0,0 @@
-#!BPY
-# coding: utf-8
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Deformed mesh to Rvk'
-Blender: 248
-Group: 'Mesh'
-Tip: 'Copy deform data (not surf. subdiv) of active obj to rvk of the 2nd selected obj'
-"""
-
-__author__ = "Jean-Michel Soler (jms)"
-__url__ = ("blender", "blenderartists.org",
-"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_rvk1versrvk2.htm",
-"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "2009/05/18"
-
-__bpydoc__ = """\
-"DEFORM to RVK2" copies deformed data (except all data with not exactly
-the same number of vertices like EDGESPLIT,DECIMATE,SUBSURF, BOOLEAN,
-BUILD, MIRROR, ARRAY) of the active object to the RVK (relative vertex
-key, now called Shapes key) of the other selected object.
-
-It is presupposed that the second mesh object is built exactly like the first
-one. In fact, it is better to use a true copy with at least one basic shape
-key. If there is no other object selected, the script can create a copy.
-
-The new version of this scrit (Blender 2.43) manages the modifier changes.
-There are a lot of modifiers but only the ones which just deforms the shape
-can be used : LATTICE, CURVE, WAVE, ARMATURE, CAST, DISPLACE, SMOOTH.
-SIMPLEDEFORM and SHRINKWRAP are not correctly seen before Blender 2.49, but
-they can be copied too. You can unset one or more of these modifiers from
-the script.
-
-Usage:
-
-Select the object that will receive the rvk info, then select the deformed
-object, enter Edit Mode and run this script from the "Mesh->Scripts" menu of
-the 3d View. If the active object has subsurf turned on and nonzero subdiv
-level, the script will ask if it should change that. Before copying data to
-the rvk it will also ask whether it should replace or add a new vertex group.
-
-
-"""
-#----------------------------------------------
-# jm soler (c) 2004-2009 : 'Deformed mesh to Rvk'
-# released under GPL licence
-#----------------------------------------------
-"""
-Ce programme est libre, vous pouvez le redistribuer et/ou
-le modifier selon les termes de la Licence Publique Générale GNU
-publiée par la Free Software Foundation (version 2 ou bien toute
-autre version ultérieure choisie par vous).
-
-Ce programme est distribué car potentiellement utile, mais SANS
-AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties
-de commercialisation ou d'adaptation dans un but spécifique.
-Reportez-vous à la Licence Publique Générale GNU pour plus de détails.
-
-Vous devez avoir reçu une copie de la Licence Publique Générale GNU
-en même temps que ce programme ; si ce n'est pas le cas, écrivez à la
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-MA 02111-1307, États-Unis.
-
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-"""
-#----------------------------------------------
-# official Page :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_rvk1versrvk2.htm
-# download the script :
-# http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
-# Communicate upon problems or errors:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#----------------------------------------------
-# Page officielle :
-# http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
-# Communiquer les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-#---------------------------------------------
-
-import Blender
-from Blender import NMesh,Draw,Object,Modifier
-
-DEBUG=0
-
-def Value(t):
- exec "t=Modifier.Types.%s"%t
- return t
-
-def copy_shapes(RVK1,RVK2):
- POSSMOD_list=['EDGESPLIT',
- 'DECIMATE',
- 'SUBSURF',
- 'BOOLEAN',
- 'BUILD',
- 'MIRROR',
- 'ARRAY',
- 'BEVEL',
- 'EXPLODE']
-
- AUTHMOD_list=['LATTICE',
- 'CURVE',
- 'WAVE',
- 'ARMATURE',
- 'SMOOTH',
- 'SIMPLEDEFORM',
- 'SHRINKWRAP',
- 'CAST',
- 'DISPLACE',
- 'MESHDEFORM']
-
-
- BMOD=[['Possible Modifiers'],
- ['Allowed Modifiers']]
- # =============================================================
- # must be 2 meshes ============================================
- # =============================================================
- if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh':
- #MODIFIERS=0
- FRAME=Blender.Get('curframe')
- DATA2=RVK2.getData()
- if DEBUG: print DATA2.getKey()
- # ============================================================
- # at least the second must have a shape key ==================
- # ============================================================
- def select_modifier(RVK1, RVK2, DATA2):
- # ======================================================
- # in case of modifiers, use =============================
- # ======================================================
- if RVK1.modifiers:
- #MODIFIERS=1
- POSSMOD=[Value(t) for t in POSSMOD_list]
- AUTHMOD=[Value(t) for t in AUTHMOD_list]
- if DEBUG: print 'POSSMOD:',POSSMOD,'\nAUTHMOD:', AUTHMOD
- MODRVK1=RVK1.modifiers
- block = []
- # ===================================================
- # === Bloc Menu Modifiers ===1 doc =================
- # ===================================================
- m=0
- for mod in MODRVK1:
- if DEBUG: print mod.type
- if mod.type in POSSMOD:
- BMOD[0].append([Draw.Create(0),mod.type,
- m,
- POSSMOD_list[POSSMOD.index(mod.type)],
- mod[Modifier.Settings.RENDER]==1,
- mod[Modifier.Settings.EDITMODE]==1
- ])
- elif mod.type in AUTHMOD:
- BMOD[1].append([Draw.Create(1),
- mod.type,
- m,
- AUTHMOD_list[AUTHMOD.index(mod.type)],
- mod[Modifier.Settings.RENDER]==1,
- mod[Modifier.Settings.EDITMODE]==1
- ])
- m+=1
- # ===================================================
- # === Bloc Menu Modifiers ===2 display =============
- # ===================================================
- block.append(BMOD[1][0])
- for B in BMOD[1][1:]:
- block.append((B[3],B[0],""))
- block.append(BMOD[0][0])
- block.append("not alredy implemented")
- block.append("in this script.")
- for B in BMOD[0][1:]:
- block.append((B[3],B[0],""))
- retval = Blender.Draw.PupBlock("MESH 2 RVK", block)
- # ===================================================
- # === unset Modifiers =============================
- # ===================================================
- for B in BMOD[0][1:]:
- if DEBUG: print B[2]
- MODRVK1[B[2]][Modifier.Settings.RENDER]=0
- for B in BMOD[1]:
- if not B[1]:
- MODRVK1[B[2]][Modifier.Settings.RENDER]=0
- # ===================================================
- # === update Modifiers =============================
- # ===================================================
- #RVK1.makeDisplayList()
- # =======================================================
- # === get deformed mesh ================================
- # =======================================================
- RVK1NAME=Object.GetSelected()[0].getName()
- meshrvk1=NMesh.GetRawFromObject(RVK1NAME)
- if DEBUG: print len(meshrvk1.verts)
- # =======================================================
- # === get normal mesh for vertex group =================
- # =======================================================
- DATA1=RVK1.getData()
- # =======================================================
- # === get destination mesh ============================
- # =======================================================
- DATA2=RVK2.getData()
- if DEBUG: print len(meshrvk1.verts)
- if DEBUG: print len(DATA2.verts)
- # ========================================================
- # ===== is there the same number of vertices =============
- # ========================================================
- if len(meshrvk1.verts)==len(DATA2.verts):
- name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 "
- result = Draw.PupMenu(name)
- if result==1:
- # =====================================================
- # ===== Do we save vertex groups ? ===================
- # =====================================================
- GROUPNAME2=DATA2.getVertGroupNames()
- if len(GROUPNAME2)!=0:
- for GROUP2 in GROUPNAME2:
- DATA2.removeVertGroup(GROUP2)
- GROUPNAME1=DATA1.getVertGroupNames()
- if len(GROUPNAME1)!=0:
- for GROUP1 in GROUPNAME1:
- DATA2.addVertGroup(GROUP1)
- DATA2.assignVertsToGroup(GROUP1,DATA1.getVertsFromGroup(GROUP1),1.0,'replace')
- # ========================================================
- # ===== now copy the vertices coords =====================
- # ========================================================
- for v in meshrvk1.verts:
- i= meshrvk1.verts.index(v)
- v1=DATA2.verts[i]
- for n in [0,1,2]:
- v1.co[n]=v.co[n]
- DATA2.update()
- DATA2.insertKey(FRAME,'relative')
- DATA2.update()
- RVK2.makeDisplayList()
-
- if RVK1.modifiers:
- # ===================================================
- # === unset Modifiers =============================
- # ===================================================
- for B in BMOD[0][1:]:
- MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2]
- for B in BMOD[1]:
- if not B[1]:
- MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2]
-
- else:
- name = "Meshes Objects must have the same number of vertices %t|Ok. %x1"
- result = Draw.PupMenu(name)
- return
- if DATA2.getKey():
- select_modifier(RVK1, RVK2, DATA2)
- else:
- name = "Second Object must have at least a shape key %t| Ok. %x1| Add one ? %x2"
- result = Draw.PupMenu(name)
- if result :
- RVK2.insertShapeKey()
- DATA2=RVK2.getData()
- select_modifier(RVK1, RVK2, DATA2)
- else:
- return
- else:
- name = "Object must be Meshes %t| Ok. %x1"
- result = Draw.PupMenu(name)
- return
-
-def deform2rvk():
- scn = Blender.Scene.GetCurrent()
- # =================================================================
- # at leat 2 objects ===============================================
- # =================================================================
- if len(scn.objects.selected) >1 :
- RVK1 = Object.GetSelected()[0]
- RVK2=Object.GetSelected()[1]
- if RVK2.getType()=='Mesh' :
- copy_shapes(RVK1,RVK2)
- # =================================================================
- # ... but if only one...===========================================
- # =================================================================
- elif len(scn.objects.selected)==1:
- name = "At least 2 Meshes must be selected %t| Ok. %x1| Add one ? %x2"
- result = Draw.PupMenu(name)
- RVK1 = Object.GetSelected()[0]
- if result and RVK1.getType()=='Mesh' :
- Blender.Object.Duplicate(mesh=1)
- RVK2=scn.objects.active
- mod = RVK2.modifiers
- for m in mod :
- RVK2.modifiers.remove(m)
- RVK2.LocX+=2.0
- copy_shapes(RVK1,RVK2)
- scn.objects.selected=[]
- RVK2.sel=1
- RVK1.sel=1
- # ================================================================
- # ... and not a mesh...===========================================
- # ================================================================
- elif result:
- name = "Selected object must be a mesh %t| Ok. %x1"
- result = Draw.PupMenu(name)
- return
- else :
- return
- # ================================================================
- # ... if not object at all. =====================================
- # ================================================================
- else:
- name = "At least one Mesh object must be selected %t| Ok. %x1"
- result = Draw.PupMenu(name)
- return
-
- Blender.Redraw()
-
-EDITMODE=Blender.Window.EditMode()
-Blender.Window.EditMode(0)
-END = 0
-DEFAULT= Blender.Get('curframe')
-
-while not END:
- deform2rvk()
- name = "Do you want to copy at a new frame %t| Yes ? %x1| No ? %x2"
- result = Draw.PupMenu(name)
- if result == 1:
- msg = "Frame :"
- inputresult = Draw.PupIntInput(msg, DEFAULT , Blender.Get('staframe'), Blender.Get('endframe'))
- print inputresult
- if inputresult != None:
- Blender.Set('curframe',inputresult)
- Blender.Window.RedrawAll()
- else:
- END = 1
- else:
- END = 1
-
-Blender.Window.EditMode(EDITMODE)
diff --git a/release/scripts/save_theme.py b/release/scripts/save_theme.py
deleted file mode 100644
index 1d23b12403a..00000000000
--- a/release/scripts/save_theme.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#!BPY
-
-"""
-Name: 'Save Current Theme...'
-Blender: 242
-Group: 'Export'
-Tooltip: 'Save current theme as a BPython script'
-"""
-
-__author__ = "Willian P. Germano"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "2.43 2006/12/30"
-
-__bpydoc__ = """\
-This script saves the current Theme in Blender as a Blender Python script.
-
-Usage:
-
-Use Blender's Theme tab in the User Preferences window to create and name your
-theme, then run this script from the File->Export menu to save it.
-
-It is saved as a bpython script, meaning that you can simply run it to change
-the current theme. By default it is currently saved under the
-"Misc" group, available only from the Scripts window "Scripts->Misc" menu.
-
-To appear in the menu, a theme saved with this script must be put in your
-Blender's scripts dir, that's what happens by default when you save one by
-yourself. If you don't know where this dir is, running
-
-import Blender<br>print Blender.Get("scriptsdir")
-
-on the Text Editor window (use menu or ALT+P to run it) will write the path on
-the console.
-
-Remember to edit your exported theme's source file to put your name and
-some information on it before sharing it with others.
-"""
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig com br
-# --------------------------------------------------------------------------
-# The scripts generated by this script are put under Public Domain by
-# default, but you are free to edit the ones you generate with this script
-# and change their license to another one of your choice.
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2005: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-from Blender.Window import Theme, FileSelector
-
-theme = Theme.Get()[0] # get current theme
-
-# default filename: theme's name + '_theme.py' in user's scripts dir:
-default_fname = Blender.Get("scriptsdir")
-if (default_fname):
- default_fname = Blender.sys.join(default_fname, theme.name + '_theme.py')
-else:
- default_fname = theme.name + '_theme.py'
-
-default_fname = default_fname.replace(' ','_')
-
-def write_theme(filename):
- "Write the current theme as a bpython script"
-
- if not filename.endswith('.py'): filename += '.py'
-
- fout = file(filename, "w")
-
- fout.write("""#!BPY
-
-# \"\"\"
-# Name: '%s'
-# Blender: 242
-# Group: 'Themes'
-# Tooltip: 'Change current theme'
-# \"\"\"
-
-__%s__ = "????"
-__%s__ = "2.43"
-__%s__ = ["blender"]
-__%s__ = \"\"\"\\
-You can edit this section to write something about your script that can
-be read then with the Scripts Help Browser script in Blender.
-
-Remember to also set author, version and possibly url(s) above. You can also
-define an __email__ tag, check some bundled script's source for examples.
-\"\"\"
-
-# This script was automatically generated by the save_theme.py bpython script.
-# By default, these generated scripts are released as Public Domain, but you
-# are free to change the license of the scripts you generate with
-# save_theme.py before releasing them.
-
-import Blender
-from Blender.Window import Theme
-
-theme = Theme.New('%s')
-""" % (theme.name, "author", "version", "url", "bpydoc", theme.name))
-
- for tsp in theme.get(): #
- command = "\n%s = theme.get('%s')" % (tsp, tsp)
- fout.write(command + "\n")
- exec(command)
- exec("vars = dir(%s)" % tsp)
- vars.remove('theme')
-
- for var in vars:
- v = "%s.%s" % (tsp, var)
- exec("value = %s" % v)
- if type(value) == str:
- fout.write("%s = '%s'\n" % (v, value))
- else:
- fout.write("%s = %s\n" % (v, value))
-
- fout.write('\nBlender.Redraw(-1)')
- fout.close()
- try:
- Blender.UpdateMenus()
- except:
- Blender.Draw.PupMenu("Warning - check console!%t|Menus could not be automatically updated")
-
-FileSelector(write_theme, "Save Current Theme", default_fname)
diff --git a/release/scripts/scripttemplate_background_job.py b/release/scripts/scripttemplate_background_job.py
deleted file mode 100644
index 86b58991849..00000000000
--- a/release/scripts/scripttemplate_background_job.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#!BPY
-"""
-Name: 'Background Job Example'
-Blender: 248
-Group: 'ScriptTemplate'
-Tooltip: 'Script template for automating tasks from the command line with blender'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''# This script is an example of how you can run blender from the command line (in background mode with no interface)
-# to automate tasks, in this example it creates a text object, camera and light, then renders and/or saves it.
-# This example also shows how you can parse command line options to python scripts.
-#
-# Example usage for this test.
-# blender -b -P $HOME/background_job.py -- --text="Hello World" --render="/tmp/hello" --save="/tmp/hello.blend"
-#
-# Notice all python args are after the '--' argument.
-
-import Blender
-import bpy
-
-def example_function(body_text, save_path, render_path):
-
- sce= bpy.data.scenes.active
-
- txt_data= bpy.data.curves.new('MyText', 'Text3d')
-
- # Text Object
- txt_ob = sce.objects.new(txt_data) # add the data to the scene as an object
- txt_data.setText(body_text) # set the body text to the command line arg given
- txt_data.setAlignment(Blender.Text3d.MIDDLE)# center text
-
- # Camera
- cam_data= bpy.data.cameras.new('MyCam') # create new camera data
- cam_ob= sce.objects.new(cam_data) # add the camera data to the scene (creating a new object)
- sce.objects.camera= cam_ob # set the active camera
- cam_ob.loc= 0,0,10
-
- # Lamp
- lamp_data= bpy.data.lamps.new('MyLamp')
- lamp_ob= sce.objects.new(lamp_data)
- lamp_ob.loc= 2,2,5
-
- if save_path:
- try:
- f= open(save_path, 'w')
- f.close()
- ok= True
- except:
- print 'Cannot save to path "%s"' % save_path
- ok= False
-
- if ok:
- Blender.Save(save_path, 1)
-
- if render_path:
- render= sce.render
- render.extensions= True
- render.renderPath = render_path
- render.sFrame= 1
- render.eFrame= 1
- render.renderAnim()
-
-
-
-import sys # to get command line args
-import optparse # to parse options for us and print a nice help message
-
-script_name= 'background_job.py'
-
-def main():
-
- # get the args passed to blender after "--", all of which are ignored by blender specifically
- # so python may receive its own arguments
- argv= sys.argv
-
- if '--' not in argv:
- argv = [] # as if no args are passed
- else:
- argv = argv[argv.index('--')+1: ] # get all args after "--"
-
- # When --help or no args are given, print this help
- usage_text = 'Run blender in background mode with this script:\n'
- usage_text += ' blender -b -P ' + script_name + ' -- [options]'
-
- parser = optparse.OptionParser(usage = usage_text)
-
-
- # Example background utility, add some text and renders or saves it (with options)
- # Possible types are: string, int, long, choice, float and complex.
- parser.add_option('-t', '--text', dest='body_text', help='This text will be used to render an image', type='string')
-
- parser.add_option('-s', '--save', dest='save_path', help='Save the generated file to the specified path', metavar='FILE')
- parser.add_option('-r', '--render', dest='render_path', help='Render an image to the specified path', metavar='FILE')
-
- options, args = parser.parse_args(argv) # In this example we wont use the args
-
- if not argv:
- parser.print_help()
- return
-
- if not options.body_text:
- print 'Error: --text="some string" argument not given, aborting.\n'
- parser.print_help()
- return
-
- # Run the example function
- example_function(options.body_text, options.save_path, options.render_path)
-
- print 'batch job finished, exiting'
-
-
-if __name__ == '__main__':
- main()
-'''
-
-new_text = bpy.data.texts.new('background_job.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
-
diff --git a/release/scripts/scripttemplate_camera_object.py b/release/scripts/scripttemplate_camera_object.py
deleted file mode 100644
index cacc35ed1a5..00000000000
--- a/release/scripts/scripttemplate_camera_object.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!BPY
-"""
-Name: 'Camera/Object Example'
-Blender: 245
-Group: 'ScriptTemplate'
-Tooltip: 'Script template for setting the camera direction'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''#!BPY
-"""
-Name: 'My Camera script'
-Blender: 245
-Group: 'Object'
-Tooltip: 'Rotate the camera to center on the active object'
-"""
-
-import Blender
-from Blender import Window, Scene, Draw, Mathutils
-
-# Rotate the camera in such a way that it centers on the currently active object
-def RotCamToOb(cam, ob):
-
- # Get the camera matrix
- camMat = cam.getMatrix('worldspace');
-
- # Get the location of the camera and object and make sure they're vectors
- camLoc = Mathutils.Vector(cam.loc)
- obLoc = Mathutils.Vector(ob.loc)
-
- # Get the vector (direction) from the camera to the object
- newVec = obLoc - camLoc
-
- # Make a quaternion that points the camera along the vector
- newQuat = newVec.toTrackQuat('-z', 'y')
-
- # Convert the new quaternion to a rotation matrix (and resize it to 4x4 so it matches the other matrices)
- rotMat = newQuat.toMatrix().resize4x4()
-
- # Make a matrix with only the current location of the camera
- transMat = Mathutils.TranslationMatrix(camMat.translationPart());
-
- # Multiply the rotation and translation matrixes to make 1 matrix with all data
- newMat = rotMat * transMat
-
- # Now we make this matrix the camera matrix and voila done!
- cam.setMatrix(newMat)
-
-#Make sure blender and the objects are in the right state and start doing stuff
-def SceneCheck():
-
- # Show a neat waitcursor whilst the script runs
- Window.WaitCursor(1)
-
- # If we are in edit mode, go out of edit mode and store the status in a var
- emode = int(Window.EditMode())
- if emode: Window.EditMode(0)
-
- # Get the scene, the camera and the currently active object
- scn = Scene.GetCurrent()
- cam = scn.getCurrentCamera()
- ob = scn.getActiveObject()
-
- # Lets do some checks to make sure we have everything
- # And if we don't then call a return which stops the entire script
- if not cam:
- Draw.PupMenu('Error, no active camera, aborting.')
- return
-
- if not ob:
- Draw.PupMenu('Error, no active object, aborting.')
- return
-
- if cam == ob:
- Draw.PupMenu('Error, select an object other than the camera, aborting.')
- return
-
- # Start the main function of the script if we didn't encounter any errors
- RotCamToOb(cam, ob)
-
- # Update the scene
- scn.update()
-
- # Redraw the 3d view so we can instantly see what was changed
- Window.Redraw(Window.Types.VIEW3D)
-
- # If we were in edit mode when the script started, go back into edit mode
- if emode: Window.EditMode(1)
-
- # Remove the waitcursor
- Window.WaitCursor(0)
-
-# Start the script
-SceneCheck()
-
-'''
-
-new_text = bpy.data.texts.new('camobject_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_gamelogic.py b/release/scripts/scripttemplate_gamelogic.py
deleted file mode 100644
index 577847c0dda..00000000000
--- a/release/scripts/scripttemplate_gamelogic.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!BPY
-"""
-Name: 'GameLogic Example'
-Blender: 249
-Group: 'ScriptTemplate'
-Tooltip: 'Script template with examples of how to use game logic'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''
-# This script must be assigned to a python controller
-# where it can access the object that owns it and the sensors/actuators that it connects to.
-
-# GameLogic has been added to the global namespace no need to import
-
-# for keyboard event comparison
-# import GameKeys
-
-# support for Vector(), Matrix() types and advanced functions like AngleBetweenVecs(v1,v2) and RotationMatrix(...)
-# import Mathutils
-
-# for functions like getWindowWidth(), getWindowHeight()
-# import Rasterizer
-
-def main():
- cont = GameLogic.getCurrentController()
-
- # The KX_GameObject that owns this controller.
- own = cont.owner
-
- # for scripts that deal with spacial logic
- own_pos = own.worldPosition
-
-
- # Some example functions, remove to write your own script.
- # check for a positive sensor, will run on any object without errors.
- print 'Logic info for KX_GameObject', own.name
- input = False
-
- for sens in cont.sensors:
- # The sensor can be on another object, we may want to use it
- own_sens = sens.owner
- print ' sensor:', sens.name,
- if sens.positive:
- print '(true)'
- input = True
- else:
- print '(false)'
-
- for actu in cont.actuators:
- # The actuator can be on another object, we may want to use it
- own_actu = actu.owner
- print ' actuator:', actu.name
-
- # This runs the actuator or turns it off
- # note that actuators will continue to run unless explicitly turned off.
- if input:
- cont.activate(actu)
- else:
- cont.deactivate(actu)
-
- # Its also good practice to get sensors and actuators by name
- # rather then index so any changes to their order wont break the script.
-
- # sens_key = cont.sensors['key_sensor']
- # actu_motion = cont.actuators['motion']
-
-
- # Loop through all other objects in the scene
- sce = GameLogic.getCurrentScene()
- print 'Scene Objects:', sce.name
- for ob in sce.objects:
- print ' ', ob.name, ob.worldPosition
-
-
- # Example where collision objects are checked for their properties
- # adding to our objects "life" property
- """
- actu_collide = cont.sensors['collision_sens']
- for ob in actu_collide.objectHitList:
- # Check to see the object has this property
- if ob.has_key('life'):
- own['life'] += ob['life']
- ob['life'] = 0
- print own['life']
- """
-
-main()
-'''
-
-new_text = bpy.data.texts.new('gamelogic_example.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_gamelogic_basic.py b/release/scripts/scripttemplate_gamelogic_basic.py
deleted file mode 100644
index fd404d5c8a4..00000000000
--- a/release/scripts/scripttemplate_gamelogic_basic.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!BPY
-"""
-Name: 'GameLogic Template'
-Blender: 249
-Group: 'ScriptTemplate'
-Tooltip: 'Basic template for new game logic scripts'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''
-def main():
-
- cont = GameLogic.getCurrentController()
- own = cont.owner
-
- sens = cont.sensors['mySensor']
- actu = cont.actuators['myActuator']
-
- if sens.positive:
- cont.activate(actu)
- else:
- cont.deactivate(actu)
-
-main()
-'''
-
-new_text = bpy.data.texts.new('gamelogic_simple.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_gamelogic_module.py b/release/scripts/scripttemplate_gamelogic_module.py
deleted file mode 100644
index 2ef4950917b..00000000000
--- a/release/scripts/scripttemplate_gamelogic_module.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!BPY
-"""
-Name: 'GameLogic Module'
-Blender: 249
-Group: 'ScriptTemplate'
-Tooltip: 'Basic template for new game logic modules'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''
-# This module can be accessed by a python controller with
-# its execution method set to 'Module'
-# * Set the module string to "gamelogic_module.main" (without quotes)
-# * When renaming the script it MUST have a .py extension
-# * External text modules are supported as long as they are at
-# the same location as the blendfile or one of its libraries.
-
-import GameLogic
-
-# variables defined here will only be set once when the
-# module is first imported. Set object spesific vars
-# inside the function if you intend to use the module
-# with multiple objects.
-
-def main(cont):
- own = cont.owner
-
- sens = cont.sensors['mySensor']
- actu = cont.actuators['myActuator']
-
- if sens.positive:
- cont.activate(actu)
- else:
- cont.deactivate(actu)
-
-# dont call main(GameLogic.getCurrentController()), the py controller will
-'''
-
-new_text = bpy.data.texts.new('gamelogic_module.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_ipo_gen.py b/release/scripts/scripttemplate_ipo_gen.py
deleted file mode 100644
index a333b4f20bf..00000000000
--- a/release/scripts/scripttemplate_ipo_gen.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#!BPY
-"""
-Name: 'IPO Example'
-Blender: 245
-Group: 'ScriptTemplate'
-Tooltip: 'Script template for setting the IPO'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''#!BPY
-"""
-Name: 'My Ipo Script'
-Blender: 245
-Group: 'Animation'
-Tooltip: 'Put some useful info here'
-"""
-
-# Add a licence here if you wish to re-distribute, we recommend the GPL
-
-from Blender import Ipo, Mathutils, Window
-import bpy, BPyMessages
-
-def makeRandomIpo(object, firstFrame, numberOfFrames, frameStep):
- # Create an new Ipo Curve of name myIpo and type Object
- myIpo = bpy.data.ipos.new('myIpo', 'Object')
-
- # Create LocX, LocY, and LocZ Ipo curves in our new Curve Object
- # and store them so we can access them later
- myIpo_x = myIpo.addCurve('LocX')
- myIpo_y = myIpo.addCurve('LocY')
- myIpo_z = myIpo.addCurve('LocZ')
-
- # What value we want to scale our random value by
- ipoScale = 4
-
- # This Calculates the End Frame for use in an xrange() expression
- endFrame = firstFrame + (numberOfFrames * frameStep) + frameStep
-
- for frame in xrange(firstFrame, endFrame, frameStep):
-
- # Use the Mathutils Rand() function to get random numbers
- ipoValue_x = Mathutils.Rand(-1, 1) * ipoScale
- ipoValue_y = Mathutils.Rand(-1, 1) * ipoScale
- ipoValue_z = Mathutils.Rand(-1, 1) * ipoScale
-
- # Append to the Ipo curve at location frame, with the value ipoValue_x
- # Note that we should pass the append function a tuple or a BezTriple
- myIpo_x.append((frame, ipoValue_x))
-
- # Similar to above
- myIpo_y.append((frame, ipoValue_y))
- myIpo_z.append((frame, ipoValue_z))
-
- # Link our new Ipo Curve to the passed object
- object.setIpo(myIpo)
- print object
-
-
-def main():
-
- # Get the active scene, since there can be multiple ones
- sce = bpy.data.scenes.active
-
- # Get the active object
- object = sce.objects.active
-
- # If there is no active object, pop up an error message
- if not object:
- BPyMessages.Error_NoActive()
-
- Window.WaitCursor(1)
-
- # Call our makeRandomIpo function
- # Pass it our object, Tell it to keys from the start frame until the end frame, at a step of 10 frames
- # between them
-
- makeRandomIpo(object, sce.render.sFrame, sce.render.eFrame, 10)
-
- Window.WaitCursor(0)
-
-if __name__ == '__main__':
- main()
-
-'''
-
-new_text = bpy.data.texts.new('ipo_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_mesh_edit.py b/release/scripts/scripttemplate_mesh_edit.py
deleted file mode 100644
index 159fb884925..00000000000
--- a/release/scripts/scripttemplate_mesh_edit.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!BPY
-"""
-Name: 'Mesh Editing'
-Blender: 243
-Group: 'ScriptTemplate'
-Tooltip: 'Add a new text for editing a mesh'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''#!BPY
-"""
-Name: 'My Mesh Script'
-Blender: 243
-Group: 'Mesh'
-Tooltip: 'Put some useful info here'
-"""
-
-# Add a licence here if you wish to re-distribute, we recommend the GPL
-
-from Blender import Scene, Mesh, Window, sys
-import BPyMessages
-import bpy
-
-def my_mesh_util(me):
- # This function runs out of editmode with a mesh
- # error cases are alredy checked for
-
- # Remove these when writing your own tool
- print me.name
- print 'vert count', len(me.verts)
- print 'edge count', len(me.edges)
- print 'face count', len(me.faces)
-
- # Examples
-
- # Move selected verts on the x axis
- """
- for v in me.verts:
- if v.sel:
- v.co.x += 1.0
- """
-
- # Shrink selected faces
- """
- for f in me.faces:
- if f.sel:
- c = f.cent
- for v in f:
- v.co = (c+v.co)/2
- """
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = bpy.data.scenes.active
-
- # Get the active object, there can only ever be 1
- # and the active object is always the editmode object.
- ob_act = sce.objects.active
-
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
-
- # Saves the editmode state and go's out of
- # editmode if its enabled, we cant make
- # changes to the mesh data while in editmode.
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
-
- Window.WaitCursor(1)
- me = ob_act.getData(mesh=1) # old NMesh api is default
- t = sys.time()
-
- # Run the mesh editing function
- my_mesh_util(me)
-
- # Restore editmode if it was enabled
- if is_editmode: Window.EditMode(1)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'My Script finished in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
-
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main()
-'''
-
-new_text = bpy.data.texts.new('mesh_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll() \ No newline at end of file
diff --git a/release/scripts/scripttemplate_metaball_create.py b/release/scripts/scripttemplate_metaball_create.py
deleted file mode 100644
index 28db9de3af6..00000000000
--- a/release/scripts/scripttemplate_metaball_create.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!BPY
-"""
-Name: 'Metaball Generation'
-Blender: 245
-Group: 'ScriptTemplate'
-Tooltip: 'Script template to make metaballs from a mesh'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''#!BPY
-"""
-Name: 'My Metaball Script'
-Blender: 245
-Group: 'Misc'
-Tooltip: 'Put some useful info here'
-"""
-
-# Add a license here if you wish to re-disribute, we recommend the GPL
-
-from Blender import Metaball, Mesh, Window
-import bpy
-
-def makeMetaSculpture(sce):
- #Create a base mesh for our sculpture to use
- monkey = Mesh.Primitives.Monkey()
-
- #Create a new meta datablock to use and give it a name
- metaObj = Metaball.New()
- metaObj.name = "MetaSuzanne"
-
- #Increase the resolution so it looks better
- metaObj.wiresize = 0.2
- metaObj.rendersize = 0.1
-
- #The radius for our new meta objects to take
- metaRadius = 2.0
-
- for f in monkey.faces:
-
- #Create a new metaball as part of the Meta Object Data
- newBall = metaObj.elements.add()
-
- #Make the new ball have the same coordinates as a vertex on our Mesh
- newBall.co = f.cent
-
- #Assign the same radius to all balls
- newBall.radius = f.area * metaRadius
-
- #Create the new object and put our meta data there
- sce.objects.new(metaObj, "MetaSuzanne")
-
-
-def main():
- scene = bpy.data.scenes.active #Get the active scene
-
- Window.WaitCursor(1)
-
- #Call the sculpture making function
- makeMetaSculpture(scene)
-
- Window.WaitCursor(0)
-
- #Redraw the Screen When Finished
- Window.RedrawAll(1)
-
-if __name__ == '__main__':
- main()
-'''
-
-new_text = bpy.data.texts.new('metaball_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_object_edit.py b/release/scripts/scripttemplate_object_edit.py
deleted file mode 100644
index 3ba20f20dd1..00000000000
--- a/release/scripts/scripttemplate_object_edit.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!BPY
-"""
-Name: 'Object Editing'
-Blender: 243
-Group: 'ScriptTemplate'
-Tooltip: 'Add a new text for editing selected objects'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''#!BPY
-"""
-Name: 'My Object Script'
-Blender: 245
-Group: 'Object'
-Tooltip: 'Put some useful info here'
-"""
-
-# Add a licence here if you wish to re-distribute, we recommend the GPL
-
-from Blender import Window, sys
-import bpy
-
-def my_object_util(sce):
-
- # Remove these when writing your own tool
- print 'Blend object count', len(bpy.data.objects)
- print 'Scene object count', len(sce.objects)
-
- # context means its selected, in the view layer and not hidden.
- print 'Scene context count', len(sce.objects.context)
-
- # Examples
-
- # Move context objects on the x axis
- """
- for ob in sce.objects.context:
- ob.LocX += 1
- """
-
- # Copy Objects, does not copy object data
- """
- # Store the current contetx
- context = list(sce.objects.context)
- # de-select all
- sce.objects.selected = []
-
- for ob in context:
- ob_copy = ob.copy()
- sce.objects.link(ob_copy) # the copy is not added to a scene
- ob_copy.sel = True
- """
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = bpy.data.scenes.active
-
- Window.WaitCursor(1)
- t = sys.time()
-
- # Run the object editing function
- my_object_util(sce)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'My Script finished in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
-
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main()
-
-'''
-
-new_text = bpy.data.texts.new('object_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_pyconstraint.py b/release/scripts/scripttemplate_pyconstraint.py
deleted file mode 100644
index 0215e47a1bd..00000000000
--- a/release/scripts/scripttemplate_pyconstraint.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!BPY
-"""
-Name: 'Script Constraint'
-Blender: 245
-Group: 'ScriptTemplate'
-Tooltip: 'Add a new script for custom constraints'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-"""#BPYCONSTRAINT
-'''
- PyConstraint template, access this in the "add constraint" scripts submenu.
- Add docstring here
-'''
-
-import Blender
-from Blender import Draw
-from Blender import Mathutils
-import math
-
-'''
- This variable specifies the number of targets
- that this constraint can use
-'''
-NUM_TARGETS = 1
-
-
-'''
- This function is called to evaluate the constraint
- obmatrix: (Matrix) copy of owner's 'ownerspace' matrix
- targetmatrices: (List) list of copies of the 'targetspace' matrices of the targets (where applicable)
- idprop: (IDProperties) wrapped data referring to this
- constraint instance's idproperties
-'''
-def doConstraint(obmatrix, targetmatrices, idprop):
- # Separate out the transformation components for easy access.
- obloc = obmatrix.translationPart() # Translation
- obrot = obmatrix.toEuler() # Rotation
- obsca = obmatrix.scalePart() # Scale
-
- # Define user-settable parameters
- # Must also be defined in getSettings().
- if not idprop.has_key('user_toggle'): idprop['user_toggle'] = 1
- if not idprop.has_key('user_slider'): idprop['user_slider'] = 1.0
-
-
- # Do stuff here, changing obloc, obrot, and obsca.
-
-
- # Convert back into a matrix for loc, scale, rotation,
- mtxloc = Mathutils.TranslationMatrix(obloc)
- mtxrot = obrot.toMatrix().resize4x4()
- mtxsca = Mathutils.Matrix([obsca[0],0,0,0], [0,obsca[1],0,0], [0,0,obsca[2],0], [0,0,0,1])
-
- # Recombine the separate elements into a transform matrix.
- outputmatrix = mtxsca * mtxrot * mtxloc
-
- # Return the new matrix.
- return outputmatrix
-
-
-
-'''
- This function manipulates the matrix of a target prior to sending it to doConstraint()
- target_object: wrapped data, representing the target object
- subtarget_bone: wrapped data, representing the subtarget pose-bone/vertex-group (where applicable)
- target_matrix: (Matrix) the transformation matrix of the target
- id_properties_of_constraint: (IDProperties) wrapped idproperties
-'''
-def doTarget(target_object, subtarget_bone, target_matrix, id_properties_of_constraint):
- return target_matrix
-
-
-'''
- This function draws a pupblock that lets the user set
- the values of custom settings the constraint defines.
- This function is called when the user presses the settings button.
- idprop: (IDProperties) wrapped data referring to this
- constraint instance's idproperties
-'''
-def getSettings(idprop):
- # Define user-settable parameters.
- # Must also be defined in getSettings().
- if not idprop.has_key('user_toggle'): idprop['user_toggle'] = 1
- if not idprop.has_key('user_slider'): idprop['user_slider'] = 1.0
-
- # create temporary vars for interface
- utoggle = Draw.Create(idprop['user_toggle'])
- uslider = Draw.Create(idprop['user_slider'])
-
-
- # define and draw pupblock
- block = []
- block.append("Buttons: ")
- block.append(("Toggle", utoggle, "This is a toggle button."))
- block.append("More buttons: ")
- block.append(("Slider", uslider, 0.0000001, 1000.0, "This is a number field."))
-
- retval = Draw.PupBlock("Constraint Template", block)
-
- # update id-property values after user changes settings
- if (retval):
- idprop['user_toggle']= utoggle.val
- idprop['user_slider']= uslider.val
-
-"""
-
-new_text = bpy.data.texts.new('pyconstraint_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/scripttemplate_text_plugin.py b/release/scripts/scripttemplate_text_plugin.py
deleted file mode 100644
index 4ae562736d3..00000000000
--- a/release/scripts/scripttemplate_text_plugin.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!BPY
-"""
-Name: 'Text Plugin'
-Blender: 246
-Group: 'ScriptTemplate'
-Tooltip: 'Add a new text for writing a text plugin'
-"""
-
-from Blender import Window
-import bpy
-
-script_data = \
-'''#!BPY
-"""
-Name: 'My Plugin Script'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Ctrl+Alt+U'
-Tooltip: 'Put some useful info here'
-"""
-
-# Add a licence here if you wish to re-distribute, we recommend the GPL
-
-from Blender import Window, sys
-import BPyTextPlugin, bpy
-
-def my_script_util(txt):
- # This function prints out statistical information about a script
-
- desc = BPyTextPlugin.get_cached_descriptor(txt)
- print '---------------------------------------'
- print 'Script Name:', desc.name
- print 'Classes:', len(desc.classes)
- print ' ', desc.classes.keys()
- print 'Functions:', len(desc.defs)
- print ' ', desc.defs.keys()
- print 'Variables:', len(desc.vars)
- print ' ', desc.vars.keys()
-
-def main():
-
- # Gets the active text object, there can be many in one blend file.
- txt = bpy.data.texts.active
-
- # Silently return if the script has been run with no active text
- if not txt:
- return
-
- # Text plug-ins should run quickly so we time it here
- Window.WaitCursor(1)
- t = sys.time()
-
- # Run our utility function
- my_script_util(txt)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'Plugin script finished in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
-
-
-# This lets you import the script without running it
-if __name__ == '__main__':
- main()
-'''
-
-new_text = bpy.data.texts.new('textplugin_template.py')
-new_text.write(script_data)
-bpy.data.texts.active = new_text
-Window.RedrawAll()
diff --git a/release/scripts/slp_import.py b/release/scripts/slp_import.py
deleted file mode 100644
index 30387ad7440..00000000000
--- a/release/scripts/slp_import.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!BPY
-
-"""
-Name: 'Pro Engineer (.slp)...'
-Blender: 232
-Group: 'Import'
-Tooltip: 'Import Pro Engineer (.slp) File Format'
-"""
-
-__author__ = "Anthony D'Agostino (Scorpius)"
-__url__ = ("blender", "blenderartists.org",
-"Author's homepage, http://www.redrival.com/scorpius")
-__version__ = "Part of IOSuite 0.5"
-
-__bpydoc__ = """\
-This script imports Pro Engineer files to Blender.
-
-This format can be exported from Pro/Engineer and most other CAD
-applications. Written at the request of a Blender user. It is almost
-identical to RAW format.
-
-Usage:<br>
- Execute this script from the "File->Import" menu and choose an SLP file to
-open.
-
-Notes:<br>
- Generates the standard verts and faces lists, but without duplicate
-verts. Only *exact* duplicates are removed, there is no way to specify a
-tolerance.
-"""
-
-# $Id$
-#
-# +---------------------------------------------------------+
-# | Copyright (c) 2004 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | May 3, 2004 |
-# | Read and write SLP Triangle File Format (*.slp) |
-# +---------------------------------------------------------+
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender, meshtools
-#import time
-
-# ================================
-# === Read SLP Triangle Format ===
-# ================================
-def read(filename):
- #start = time.clock()
- file = open(filename, "rb")
-
- raw = []
- for line in file: #.xreadlines():
- data = line.split()
- if data[0] == "vertex":
- vert = map(float, data[1:])
- raw.append(vert)
-
- tri = []
- for i in xrange(0, len(raw), 3):
- tri.append(raw[i] + raw[i+1] + raw[i+2])
-
- #$import pprint; pprint.pprint(tri)
-
- # Collect data from RAW format
- faces = []
- for line in tri:
- f1, f2, f3, f4, f5, f6, f7, f8, f9 = line
- faces.append([(f1, f2, f3), (f4, f5, f6), (f7, f8, f9)])
-
- # Generate verts and faces lists, without duplicates
- verts = []
- coords = {}
- index = 0
- for i in xrange(len(faces)):
- for j in xrange(len(faces[i])):
- vertex = faces[i][j]
- if not coords.has_key(vertex):
- coords[vertex] = index
- index += 1
- verts.append(vertex)
- faces[i][j] = coords[vertex]
-
- objname = Blender.sys.splitext(Blender.sys.basename(filename))[0]
-
- meshtools.create_mesh(verts, faces, objname)
- Blender.Window.DrawProgressBar(1.0, '') # clear progressbar
- file.close()
- #end = time.clock()
- #seconds = " in %.2f %s" % (end-start, "seconds")
- message = "Successfully imported " + Blender.sys.basename(filename)# + seconds
- meshtools.print_boxed(message)
-
-def fs_callback(filename):
- read(filename)
-
-if __name__ == '__main__':
- Blender.Window.FileSelector(fs_callback, "Import SLP", "*.slp")
diff --git a/release/scripts/sysinfo.py b/release/scripts/sysinfo.py
deleted file mode 100644
index 3a671e7221e..00000000000
--- a/release/scripts/sysinfo.py
+++ /dev/null
@@ -1,287 +0,0 @@
-#!BPY
-
-"""
-Name: 'System Information...'
-Blender: 236
-Group: 'HelpSystem'
-Tooltip: 'Information about your Blender environment, useful to diagnose problems.'
-"""
-
-__author__ = "Willian P. Germano"
-__url__ = ("blenderartists.org", "blenderartists.org")
-__version__ = "1.1"
-__bpydoc__ = """\
-This script creates a text in Blender's Text Editor with information
-about your OS, video card, OpenGL driver, Blender and Python versions,
-script related paths and more.
-
-If you are experiencing trouble running Blender itself or any Blender Python
-script, this information can be useful to fix any problems or at least for
-online searches (like checking if there are known issues related to your
-video card) or to get help from other users or the program's developers.
-"""
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# sysinfo.py version 1.1 Mar 20, 2005
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-import Blender.sys as bsys
-from Blender.BGL import *
-import sys
-
-Blender.Window.WaitCursor(1)
-# has_textwrap = 1 # see commented code below
-output_filename = "system-info.txt"
-warnings = 0
-notices = 0 # non critical warnings
-
-def cutPoint(text, length):
- "Returns position of the last space found before 'length' chars"
- l = length
- c = text[l]
- while c != ' ':
- l -= 1
- if l == 0: return length # no space found
- c = text[l]
- return l
-
-def textWrap(text, length = 70):
- lines = []
- while len(text) > 70:
- cpt = cutPoint(text, length)
- line, text = text[:cpt], text[cpt + 1:]
- lines.append(line)
- lines.append(text)
- return lines
-
-## Better use our own text wrap functions here
-#try:
-# import textwrap
-#except:
-# has_textwrap = 0
-# msg = sys.exc_info()[1].__str__().split()[3]
-# Blender.Draw.PupMenu("Python error:|This script requires the %s module" %msg)
-
-version = Blender.Get('version') / 100.0
-header = "= Blender %s System Information =" % version
-lilies = len(header)*"="+"\n"
-header = lilies + header + "\n" + lilies
-
-output = Blender.Text.New(output_filename)
-
-output.write(header + "\n\n")
-
-output.write("%s\n\n" % Blender.Get('buildinfo'))
-
-output.write("Platform: %s\n========\n\n" % sys.platform)
-
-output.write("Python:\n======\n\n")
-output.write("- Version: %s\n\n" % sys.version)
-output.write("- Paths:\n\n")
-for p in sys.path:
- output.write(p + '\n')
-
-output.write("\n- Directories:")
-
-dirlist = [
- ['homedir', 'Blender home dir', 1],
- ['scriptsdir', 'Default dir for scripts', 1],
- ['datadir', 'Default "bpydata/" data dir for scripts', 1],
- ['uscriptsdir', 'User defined dir for scripts', 0],
- ['udatadir', 'Data dir "bpydata/" inside user defined dir', 0]
-]
-
-has_dir = {}
-
-for dir in dirlist:
- dirname, dirstr, is_critical = dir
- dirpath = Blender.Get(dirname)
- output.write("\n\n %s:\n" % dirstr)
- if not dirpath:
- has_dir[dirname] = False
- if is_critical:
- warnings += 1
- output.write(" <WARNING> -- not found")
- else:
- notices += 1
- output.write(" <NOTICE> -- not found")
- else:
- output.write(" %s" % dirpath)
- has_dir[dirname] = True
-
-if not has_dir['homedir']:
- outmsg = """
-
-<WARNING> - Blender home dir not found!
- This should probably be "<path>/.blender/"
- where <path> is usually the user's home dir.
-
- Blender's home dir is where entries like:
- folders scripts/, plugins/ and locale/ and
- files .Blanguages and .bfont.ttf
- are located.
-
- It's also where Blender stores the Bpymenus file
- with information about registered scripts, so it
- only needs to scan scripts dir(s) when they are
- modified.
-"""
- output.write(outmsg)
-
-has_uconfdir = False
-if has_dir['udatadir']:
- uconfigdir = bsys.join(Blender.Get('udatadir'), 'config')
- output.write("\n\n User defined config data dir:")
- if bsys.exists(uconfigdir):
- has_uconfdir = True
- output.write(" %s" % uconfigdir)
- else:
- notices += 1
- output.write("""
- <NOTICE> -- not found.
- bpydata/config/ should be inside the user defined scripts dir.
- It's used by Blender to store scripts configuration data.
- (Since it is on the user defined dir, a new Blender installation
- won't overwrite the data.)
-""")
-
-configdir = bsys.join(Blender.Get('datadir'), 'config')
-output.write('\n\n Default config data "bpydata/config/" dir:\n')
-if bsys.exists(configdir):
- output.write(" %s" % configdir)
-else:
- warnings += 1
- output.write("""<WARNING> -- not found.
- config/ should be inside the default scripts *data dir*.
- It's used by Blender to store scripts configuration data
- when <user defined scripts dir>/bpydata/config/ dir is
- not available.
-""")
-
-if has_uconfdir:
- output.write("""
-
-The user defined config dir will be used.
-""")
-
-cvsdir = 'release/scripts'
-if bsys.dirsep == '\\': cvsdir = cvsdir.replace('/','\\')
-sdir = Blender.Get('scriptsdir')
-if sdir and sdir.find(cvsdir) >= 0:
- if has_uconfdir:
- notices += 1
- output.write("\n\n<NOTICE>:\n")
- else:
- warnings += 1
- output.write("\n\n<WARNING>:\n")
- output.write("""
-It seems this Blender binary is located in its cvs source tree.
-
-It's recommended that the release/scripts/ dir tree is copied
-to your blender home dir.
-""")
- if not has_uconfdir:
- output.write("""
-Since you also don't have a user defined scripts dir with the
-bpydata/config dir inside it, it will not be possible to save
-and restore scripts configuration data files, since writing
-to a dir inside a cvs tree is not a good idea and is avoided.
-""")
-
-missing_mods = [] # missing basic modules
-
-try:
- from BPyBlender import basic_modules
- for m in basic_modules:
- try: exec ("import %s" % m)
- except: missing_mods.append(m)
-
- if missing_mods:
- outmsg = """
-
-<WARNING>:
-
-Some expected modules were not found.
-Because of that some scripts bundled with Blender may not work.
-Please read the FAQ in the Readme.html file shipped with Blender
-for information about how to fix the problem.
-Missing modules:
-"""
- output.write(outmsg)
- warnings += 1
- for m in missing_mods:
- output.write('-> ' + m + '\n')
- if 'BPyRegistry' in missing_mods:
- output.write("""
-Module BPyRegistry.py is missing!
-Without this module it's not possible to save and restore
-scripts configuration data files.
-""")
-
- else:
- output.write("\n\n- Modules: all basic ones were found.\n")
-
-except ImportError:
- output.write("\n\n<WARNING>:\n Couldn't find BPyBlender.py in scripts/bpymodules/ dir.")
- output.write("\n Basic modules availability won't be tested.\n")
- warnings += 1
-
-output.write("\nOpenGL:\n======\n\n")
-output.write("- Renderer: %s\n" % glGetString(GL_RENDERER))
-output.write("- Vendor: %s\n" % glGetString(GL_VENDOR))
-output.write("- Version: %s\n\n" % glGetString(GL_VERSION))
-output.write("- Extensions:\n\n")
-
-glext = glGetString(GL_EXTENSIONS)
-glext = textWrap(glext, 70)
-
-for l in glext:
- output.write(l + "\n")
-
-output.write("\n\n- Simplistic almost useless benchmark:\n\n")
-t = Blender.sys.time()
-nredraws = 10
-for i in range(nredraws):
- Blender.Redraw(-1) # redraw all windows
-result = Blender.sys.time() - t
-output.write("Redrawing all areas %s times took %.4f seconds.\n" % (nredraws, result))
-
-if warnings or notices:
- output.write("\n%s%s\n" % (warnings*"#", notices*"."))
- if warnings:
- output.write("\n(*) Found %d warning" % warnings)
- if (warnings > 1): output.write("s") # (blush)
- output.write(", documented in the text above.\n")
- if notices:
- output.write("\n(*) Found %d notice" % notices)
- if (notices > 1): output.write("s") # (blush)
- output.write(", documented in the text above.\n")
-
-else: output.write("\n==\nNo problems were found (scroll up for details).")
-
-Blender.Window.WaitCursor(0)
-exitmsg = "Done!|Please check the text %s in the Text Editor window" % output.name
-Blender.Draw.PupMenu(exitmsg)
diff --git a/release/scripts/textplugin_convert_ge.py b/release/scripts/textplugin_convert_ge.py
deleted file mode 100644
index fb17367d622..00000000000
--- a/release/scripts/textplugin_convert_ge.py
+++ /dev/null
@@ -1,863 +0,0 @@
-#!BPY
-"""
-Name: 'Convert BGE 2.49'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: ''
-Tooltip: 'Attemps to update deprecated usage of game engine API.'
-"""
-
-#
-# Copyright 2009 Alex Fraser <alex@phatcore.com>
-#
-# This program is free software: you can 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/>.
-#
-
-#
-# This script updates game engine scripts that were designed for pre-2.49
-# versions of Blender to run with the new API. Deprecated function calls are
-# listed in attributeRenameDict. This script searches for instances of the keys
-# in a target script and re-writes them.
-#
-# Some deprecated functions are complicated to re-write. The most common
-# conversions have been implemented, but some have not. Running this will reduce
-# the number of deprecation warnings in your scripts, but may not eliminate them
-# entirely.
-#
-# NOTE: The conversion is not guaranteed to be perfect. It is strongly
-# recommended that you review all changes after running this script.
-#
-# TODO: The following attributes are either ambiguous or need special processing
-# to handle parameters. Deprecated attributes that map to multiple target
-# attributes will require a refactor of the main conversion loop in the
-# convert248to249 function: currently, it doesn't allow any conversion to
-# advance the row index by more than one.
-#
-# getLinearVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator)
-# Conflicts with KX_GameObject.
-# Maps to multiple attributes.
-# setLinearVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator)
-# Conflicts with KX_GameObject.
-# Maps to multiple attributes.
-# getAngularVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator)
-# Conflicts with KX_GameObject.
-# Maps to multiple attributes.
-# setAngularVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator)
-# Conflicts with KX_GameObject.
-# Maps to multiple attributes.
-# setAction (BL_ShapeActionActuator, BL_ActionActuator)
-# `reset' argument has no conversion target.
-# set (KX_VisibilityActuator, KX_IpoActuator)
-# Different numbers of arguments.
-# Arguments map to multiple attributes.
-# getIndex (SCA_JoystickSensor)
-# Incompatible values: Old = 1-based index; new = 0-based.
-# getMesh (KX_SCA_ReplaceMeshActuator)
-# Return types differ. Need to call object.name.
-# getObject (KX_SCA_AddObjectActuator, KX_CameraActuator,
-# KX_TrackToActuator, KX_ParentActuator)
-# Default return type differs between classes.
-# setIndex (SCA_JoystickSensor)
-# Incompatible values: Old = 1-based index; new = 0-based.
-# setObject (KX_SCA_AddObjectActuator, KX_CameraActuator,
-# KX_TrackToActuator, KX_ParentActuator)
-# Incompatible types: Old = KX_GameObject or String; new =
-# KX_GameObject.
-# setOperation (KX_SCA_DynamicActuator, KX_StateActuator)
-# Ambiguous: different target names.
-# getDRot (KX_ObjectActuator)
-# Maps to multiple attributes.
-# setDRot (KX_ObjectActuator)
-# Arguments map to multiple attributes.
-# getDLoc (KX_ObjectActuator)
-# Maps to multiple attributes.
-# setDLoc (KX_ObjectActuator)
-# Arguments map to multiple attributes.
-# getTorque (KX_ObjectActuator)
-# Maps to multiple attributes.
-# setTorque (KX_ObjectActuator)
-# Arguments map to multiple attributes.
-# getForce (KX_ObjectActuator)
-# Maps to multiple attributes.
-# setForce (KX_ObjectActuator)
-# Arguments map to multiple attributes.
-# position (KX_GameObject)
-# Conflicts with KX_SoundActuator.
-# orientation (KX_GameObject)
-# Conflicts with KX_SoundActuator.
-#
-
-import string
-import re
-
-COMMENTCHAR = '#'
-
-class ParseError(Exception): pass
-class ConversionError(Exception): pass
-
-def findBalancedParens(lines, row, col, openChar = '(', closeChar = ')'):
- """Finds a balanced pair of parentheses, searching from lines[row][col].
- The opening parenthesis must be on the starting line.
-
- Returns two tuples containing the row and column of the opening paren, and
- the row and column of the matching paren.
-
- Throws a ParseError if the first character is not openChar, or if a matching
- paren cannot be found."""
-
- #
- # Find the opening coordinates.
- #
- oRow = row
- oCol = col
- line = lines[oRow]
- while oCol < len(line):
- if line[oCol] == openChar:
- break
- elif line[oCol] == COMMENTCHAR:
- break
- oCol = oCol + 1
-
- if oCol >= len(line) or line[oCol] != openChar or not re.match(r'^\s*$', line[col:oCol]):
- raise ParseError, "Can't find opening parenthesis. '%s'" % openChar
-
- #
- # Find the closing coordinates.
- #
- eRow = oRow
- eCol = oCol + 1
- level = 1
- while eRow < len(lines) and level > 0:
- line = lines[eRow]
- while eCol < len(line) and level > 0:
- c = line[eCol]
- if c == openChar:
- # Found a nested paren.
- level = level + 1
- elif c == closeChar:
- # Exiting one level of nesting.
- level = level - 1
- if level == 0:
- # Back to top level!
- return (oRow, oCol), (eRow, eCol)
- elif c == COMMENTCHAR:
- # Comment. Skip the rest of the line.
- break
- eCol = eCol + 1
- eRow = eRow + 1
- eCol = 0
- raise ParseError, "Couldn't find closing parenthesis."
-
-def findLastAssignment(lines, row, attrName):
- """Finds the most recent assignment of `attrName' before `row'. Returns
- everything after the '=' sign or None, if there was no match."""
- contRegex = re.compile(r'[^#]*?' + # Don't search in comments.
- attrName +
- r'\s*=\s*(.*)') # Assignment
-
- cRow = row - 1
- while cRow >= 0:
- match = contRegex.search(lines[cRow])
- if match:
- return match.group(1)
- cRow = cRow - 1
- return None
-
-def replaceSubstr(s, start, end, newSubStr):
- """Replace the contents of `s' between `start' and `end' with
- `newSubStr'."""
- return s[:start] + newSubStr + s[end:]
-
-def replaceNextParens(lines, row, colStart, newOpenChar, newCloseChar,
- oldOpenChar = '(', oldCloseChar = ')'):
- """Replace the next set of parentheses with different characters. The
- opening parenthesis must be located on line `row', and on or after
- `colStart'. The closing parenthesis may be on the same line or any following
- line. The strings are edited in-place.
-
- Throws a ParseError if the set of parentheses can't be found. In this case,
- the strings in `lines' will be untouched."""
- try:
- pOpen, pClose = findBalancedParens(lines, row, colStart, oldOpenChar,
- oldCloseChar)
- except ParseError:
- raise
-
- # Replacement may change string length. Replace closing paren first.
- r, c = pClose
- lines[r] = replaceSubstr(lines[r], c, c + 1, newCloseChar)
- # Replace opening paren.
- r, c = pOpen
- lines[r] = replaceSubstr(lines[r], c, c + 1, newOpenChar)
-
-def replaceSimpleGetter(lines, row, colStart, colEnd, newName):
- """Replace a call to a simple getter function with a reference to a
- property, e.g. foo.getBar() -> foo.bar
-
- The function identifier being replaced must be on line `row' and
- between `colStart' and `colEnd'. The opening parenthesis must follow
- immediately (whitespace is allowed). The closing parenthesis may be on the
- same or following lines.
-
- Throws a ConversionError if the parentheses can't be found. In this case
- the content of `lines' will be untouched."""
- try:
- replaceNextParens(lines, row, colEnd, newOpenChar = '', newCloseChar = '')
- except ParseError:
- raise ConversionError, ("Deprecated function reference.")
-
- lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName)
-
-def replaceSimpleSetter(lines, row, colStart, colEnd, newName):
- """Replace a call to a simple setter function with a reference to a
- property, e.g. foo.setBar(baz) -> foo.bar = baz
-
- The function identifier being replaced must be on line `row' and
- between `colStart' and `colEnd'. The opening parenthesis must follow
- immediately (whitespace is allowed). The closing parenthesis may be on the
- same or following lines.
-
- Throws a ConversionError if the parentheses can't be found. In this case
- the content of `lines' will be untouched."""
- try:
- replaceNextParens(lines, row, colEnd, newOpenChar = '', newCloseChar = '')
- except ParseError:
- raise ConversionError, ("Deprecated function reference.")
-
- lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName + ' = ')
-
-def replaceArgsWithListSetter(lines, row, colStart, colEnd, newName):
- """Replace a call to a multi-agument setter function with a reference to a
- list property, e.g. foo.setBar(baz, bazZ) -> foo.bar = [baz, bazZ]
-
- The function identifier being replaced must be on line `row' and
- between `colStart' and `colEnd'. The opening parenthesis must follow
- immediately (whitespace is allowed). The closing parenthesis may be on the
- same or following lines.
-
- Throws a ConversionError if the parentheses can't be found. In this case
- the content of `lines' will be untouched."""
- try:
- replaceNextParens(lines, row, colEnd, newOpenChar = '[', newCloseChar = ']')
- except ParseError:
- raise ConversionError, ("Deprecated function reference.")
-
- lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName + ' = ')
-
-
-def replaceKeyedGetter(lines, row, colStart, colEnd, newName):
- """Replace a call to a keyed getter function with a reference to a
- property, e.g. foo.getBar(baz) -> foo.bar[baz]
-
- The function identifier being replaced must be on line `row' and
- between `colStart' and `colEnd'. The opening parenthesis must follow
- immediately (whitespace is allowed). The closing parenthesis may be on the
- same or following lines.
-
- Throws a ConversionError if the parentheses can't be found. In this case
- the content of `lines' will be untouched."""
- try:
- replaceNextParens(lines, row, colEnd, newOpenChar = '[', newCloseChar = ']')
- except ParseError:
- raise ConversionError, ("Deprecated function reference.")
-
- lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName)
-
-def replaceGetXYPosition(lines, row, colStart, colEnd, axis):
- '''SCA_MouseSensor.getXPosition; SCA_MouseSensor.getYPosition.
- This is like a keyed getter, but the key is embedded in the attribute
- name.
-
- Throws a ConversionError if the parentheses can't be found. In this case
- the content of `lines' will be untouched.'''
- try:
- (openRow, openCol), (closeRow, closeCol) = findBalancedParens(lines,
- row, colEnd)
- except ParseError:
- raise ConversionError, "Deprecated function reference."
- if closeRow != row:
- raise ConversionError, "Can't modify multiple lines."
-
- lines[row] = replaceSubstr(lines[row], openCol, closeCol + 1,
- "[%s]" % axis)
-
- lines[row] = replaceSubstr(lines[row], colStart, colEnd, 'position')
-
-def replaceRename(lines, row, colStart, colEnd, newName):
- """Replace an identifier with another, e.g.
- foo.getBar() -> foo.getBaz()
- foo.bar -> foo.baz
-
- The identifier being replaced must be on line `row' and between `colStart'
- and `colEnd'."""
- lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName)
-
-def replaceAddActiveActuator(lines, row, colStart, colEnd, closure):
- '''Extra work needs to be done here to find out the name of the controller,
- and whether the actuator should be activated or deactivated.
-
- Throws a ConversionError if the actuator, controller or condition can't be
- found. In this case the content of `lines' will be untouched.'''
- try:
- (openRow, openCol), (closeRow, closeCol) = findBalancedParens(lines, row, colEnd)
- except ParseError:
- ConversionError, "Can't find arguments."
-
- if closeRow != openRow:
- raise ConversionError, ("Can't perform conversion: arguments span multiple lines.")
-
- args = lines[row][openCol + 1:closeCol]
- match = re.search(r'([a-zA-Z_]\w*)' # Actuator identifier
- r',\s*'
- r'([0-9a-zA-Z_]\w*)', # Condition (boolean)
- args)
- if not match:
- raise ConversionError, "Can't find arguments."
-
- actuator = match.group(1)
- condition = match.group(2)
- controller = None
-
- assn = findLastAssignment(lines, row, actuator)
- if assn:
- match = re.search(r'([a-zA-Z_]\w*)' # Controller identifier
- r'\s*\.\s*' # Dot
- r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier
- assn)
- if match:
- controller = match.group(1)
-
- if not controller:
- raise ConversionError, "Can't find actuator's controller."
-
- gameLogicStart = lines[row].rfind("GameLogic", 0, colStart)
- if gameLogicStart < 0:
- raise ConversionError, "Can't find GameLogic identifier."
-
- newExpr = None
- if condition in ['1', 'True']:
- newExpr = "%s.activate(%s)" % (controller, actuator)
- elif condition in ['0', 'False']:
- newExpr = "%s.deactivate(%s)" % (controller, actuator)
- else:
- newExpr = "(lambda: %s and (%s.activate(%s) or True) or %s.deactivate(%s))()" % (
- condition, controller, actuator, controller, actuator)
- lines[row] = replaceSubstr(lines[row], gameLogicStart, closeCol + 1, newExpr)
-
-def getObject(line, attributeStart):
- '''Get the object that an attribute belongs to. `attributeStart' is the
- index of the first character of the attribute name in the string `line'.
- Returns: the identifier preceding `attributeStart', or None if one can't be
- found.'''
- match = re.search(r'([a-zA-Z_]\w*)\s*\.\s*$', line[0:attributeStart])
- if not match:
- return None
- return match.group(1)
-
-def replaceGetActuator(lines, row, colStart, colEnd, closure):
- '''getActuator is ambiguous: it could belong to SCA_IController or
- SCA_ActuatorSensor. Try to resolve and then convert.
-
- Raises a ConversionError if the parentheses can't be found, or if the
- ambiguity can't be resolved.'''
- # Get the name of the object this attribute is attached to.
- obName = getObject(lines[row], colStart)
- if obName:
- # Try to find out whether the object is a controller.
- assn = findLastAssignment(lines, row, obName)
- if assn and re.search(r'GameLogic\s*\.\s*getCurrentController', assn):
- # It is (probably) a controller!
- replaceKeyedGetter(lines, row, colStart, colEnd, 'actuators')
- return
-
- raise ConversionError, "Ambiguous: addActiveActuator -> actuators[key] (SCA_IController) or actuator (SCA_ActuatorSensor)."
-
-def replaceSetOrientation(lines, row, colStart, colEnd, closure):
- '''setOrientation is ambiguous: it could belong to KX_SoundActuator or
- KX_GameObject. Try to resolve and then convert. If the type can't be
- determined, it is assumed to be a KX_GameObject. Currently, only the
- conversion for KX_GameObject is implemented.
-
- Raises a ConversionError if the parentheses can't be found, or if the
- object is found to be a KX_SoundActuator.'''
- # Get the name of the object this attribute is attached to.
- obName = getObject(lines[row], colStart)
- if obName:
- # Try to find out whether the object is an actuator.
- assn = findLastAssignment(lines, row, obName)
- if assn:
- match = re.search(r'([a-zA-Z_]\w*)' # Controller identifier
- r'\s*\.\s*' # Dot
- r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier
- assn)
- if match:
- # It's probably a KX_SoundActuator.
- raise ConversionError, "Not implemented: Can't convert arguments to matrix."
-
- # It's probably a KX_GameObject.
- replaceSimpleSetter(lines, row, colStart, colEnd, 'localOrientation')
-
-def replaceSetPosition(lines, row, colStart, colEnd, closure):
- '''setPosition is ambiguous: it could belong to KX_SoundActuator or
- KX_GameObject. Try to resolve and then convert. If the type can't be
- determined, it is assumed to be a KX_GameObject.
-
- Raises a ConversionError if the parentheses can't be found.'''
- # Get the name of the object this attribute is attached to.
- obName = getObject(lines[row], colStart)
- if obName:
- # Try to find out whether the object is an actuator.
- assn = findLastAssignment(lines, row, obName)
- if assn:
- match = re.search(r'([a-zA-Z_]\w*)' # Controller identifier
- r'\s*\.\s*' # Dot
- r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier
- assn)
- if match:
- # It's probably a KX_SoundActuator.
- replaceSimpleSetter(lines, row, colStart, colEnd, 'position')
-
- # It's probably a KX_GameObject.
- replaceSimpleSetter(lines, row, colStart, colEnd, 'localPosition')
-
-def replaceSplitProperty(lines, row, colStart, colEnd, (newGetter, newSetter)):
- '''Some property attributes behave differently when being written to or read
- from. Try to determine the operation, and replace accordingly. E.G.
- o.position = foo -> o.localPosition = foo # set
- foo = o.position -> foo = o.worldPosition # get
-
- This implementation can not handle cases where the object is returned from
- a function, e.g.
- foo = bar.getObject().position # Error!
-
- Raises a ConversionError if the operation can't be determined, or if the
- object is returned from a function.'''
- assnRegex = re.compile(r'(=\s*)?' # Getter
- r'[a-zA-Z_]\w*' # Object identifier
- r'\.([a-zA-Z_][a-zA-Z0-9_.]*)+' # Trailing attributes
- r'(\s*=)?') # Setter
- match = assnRegex.search(lines[row])
-
- if not match:
- raise ConversionError, "Can't determine operation (getting or setting)."
-
- setting = False
- getting = False
- if match.group(1):
- getting = True
- if match.group(3):
- setting = True
- if (getting and setting) or ((not getting) and (not setting)):
- raise ConversionError, "Can't determine operation (getting or setting)."
-
- if getting:
- replaceRename(lines, row, colStart, colEnd, newGetter)
- else:
- replaceRename(lines, row, colStart, colEnd, newSetter)
-
-def notImplemented(lines, row, colStart, colEnd, classNames):
- message = "Conversion not implemented. See documentation for " +\
- string.join(classNames, ', ')
- raise ConversionError, message
-
-#
-# Deprecated attribute information. The format is:
-# deprecatedAttributeName: (conversionFunction, closure)
-# Usually the closure will be the name of the superceding attribute.
-#
-# Since each deprecated attribute can appear in this dictionary only once, it is
-# the conversion function's responsibility to resolve ambiguity.
-#
-attributeRenameDict = {
- # Special cases
- 'addActiveActuator': (replaceAddActiveActuator, None), #
- 'getActuator': (replaceGetActuator, None), # SCA_IController, SCA_ActuatorSensor
- 'getXPosition': (replaceGetXYPosition, '0'), # SCA_MouseSensor
- 'getYPosition': (replaceGetXYPosition, '1'), # SCA_MouseSensor
- 'setOrientation': (replaceSetOrientation, None), # KX_GameObject, KX_SoundActuator
- 'setPosition': (replaceSetPosition, None), # KX_GameObject, KX_SoundActuator
-
- # Keyed getters/setters
- 'getSensor': (replaceKeyedGetter, 'sensors'), # SCA_IController
-
- # Multi-arg -> List setter
- 'setAxis': (replaceArgsWithListSetter, 'axis'), # SCA_JoystickSensor
- 'setForceLimitX': (replaceArgsWithListSetter, 'forceLimitX'), # KX_ObjectActuator
- 'setForceLimitY': (replaceArgsWithListSetter, 'forceLimitY'), # KX_ObjectActuator
- 'setForceLimitZ': (replaceArgsWithListSetter, 'forceLimitZ'), # KX_ObjectActuator
- 'setHat': (replaceArgsWithListSetter, 'hat'), # SCA_JoystickSensor
- 'setPID': (replaceArgsWithListSetter, 'pid'), # KX_ObjectActuator
- 'setVelocity': (replaceArgsWithListSetter, 'velocity'), # KX_SoundActuator
-
- # Straight rename
- 'getButtonValue': (replaceRename, 'getButtonActiveList'), # SCA_JoystickSensor
-
- # Split properties
- 'scaling': (replaceSplitProperty, ('worldScaling', 'localScaling')), # KX_GameObject
-
- # Simple getters/setters
- 'getSensors': (replaceSimpleGetter, 'sensors'), # SCA_IController
- 'getActuators': (replaceSimpleGetter, 'actuators'), # SCA_IController
- 'enableViewport': (replaceSimpleSetter, 'useViewport'), # KX_Camera
- 'getAction': (replaceSimpleGetter, 'action'), # BL_ShapeActionActuator, BL_ActionActuator
- 'getAxis': (replaceSimpleGetter, 'axis'), # SCA_JoystickSensor
- 'getAxisValue': (replaceSimpleGetter, 'axisValues'), # SCA_JoystickSensor
- 'getBlendin': (replaceSimpleGetter, 'blendIn'), # BL_ShapeActionActuator, BL_ActionActuator
- 'getBodies': (replaceSimpleGetter, 'bodies'), # KX_NetworkMessageSensor
- 'getButton': (replaceSimpleGetter, 'button'), # SCA_JoystickSensor
- 'getCamera': (replaceSimpleGetter, 'camera'), # KX_SceneActuator
- 'getConeOrigin': (replaceSimpleGetter, 'coneOrigin'), # KX_RadarSensor
- 'getConeTarget': (replaceSimpleGetter, 'coneTarget'), # KX_RadarSensor
- 'getContinue': (replaceSimpleGetter, 'useContinue'), # BL_ActionActuator
- 'getCurrentlyPressedKeys': (replaceSimpleGetter, 'events'), # SCA_KeyboardSensor
- 'getDamping': (replaceSimpleGetter, 'damping'), # KX_ObjectActuator
- 'getDelay': (replaceSimpleGetter, 'delay'), # SCA_DelaySensor
- 'getDistribution': (replaceSimpleGetter, 'distribution'), # SCA_RandomActuator
- 'getDuration': (replaceSimpleGetter, 'duration'), # SCA_DelaySensor
- 'getEnd': (replaceSimpleGetter, 'frameEnd'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator
- 'getExecutePriority': (replaceSimpleGetter, 'executePriority'), # SCA_ILogicBrick
- 'getFile': (replaceSimpleGetter, 'fileName'), # KX_GameActuator
- 'getFilename': (replaceSimpleGetter, 'fileName'), # KX_SoundActuator
- 'getForceIpoActsLocal': (replaceSimpleGetter, 'useIpoLocal'), # KX_IpoActuator
- 'getForceLimitX': (replaceSimpleGetter, 'forceLimitX'), # KX_ObjectActuator
- 'getForceLimitY': (replaceSimpleGetter, 'forceLimitY'), # KX_ObjectActuator
- 'getForceLimitZ': (replaceSimpleGetter, 'forceLimitZ'), # KX_ObjectActuator
- 'getFrame': (replaceSimpleGetter, 'frame'), # BL_ShapeActionActuator, BL_ActionActuator
- 'getFrameMessageCount': (replaceSimpleGetter, 'frameMessageCount'), # KX_NetworkMessageSensor
- 'getFrameProperty': (replaceSimpleGetter, 'framePropName'), # BL_ShapeActionActuator, BL_ActionActuator
- 'getFrequency': (replaceSimpleGetter, 'frequency'), # SCA_ISensor
- 'getGain': (replaceSimpleGetter, 'volume'), # KX_SoundActuator
- 'getHat': (replaceSimpleGetter, 'hat'), # SCA_JoystickSensor
- 'getHeight': (replaceSimpleGetter, 'height'), # KX_CameraActuator
- 'getHitNormal': (replaceSimpleGetter, 'hitNormal'), # KX_MouseFocusSensor, KX_RaySensor
- 'getHitObject': (replaceSimpleGetter, 'hitObject'), # KX_MouseFocusSensor, KX_RaySensor, KX_TouchSensor
- 'getHitObjectList': (replaceSimpleGetter, 'hitObjectList'), # KX_TouchSensor
- 'getHitPosition': (replaceSimpleGetter, 'hitPosition'), # KX_MouseFocusSensor, KX_RaySensor
- 'getHold1': (replaceSimpleGetter, 'hold1'), # SCA_KeyboardSensor
- 'getHold2': (replaceSimpleGetter, 'hold2'), # SCA_KeyboardSensor
- 'getInvert': (replaceSimpleGetter, 'invert'), # SCA_ISensor
- 'getIpoAdd': (replaceSimpleGetter, 'useIpoAdd'), # KX_IpoActuator
- 'getIpoAsForce': (replaceSimpleGetter, 'useIpoAsForce'), # KX_IpoActuator
- 'getKey': (replaceSimpleGetter, 'key'), # SCA_KeyboardSensor
- 'getLastCreatedObject': (replaceSimpleGetter, 'objectLastCreated'), # KX_SCA_AddObjectActuator
- 'getLevel': (replaceSimpleGetter, 'level'), # SCA_ISensor
- 'getLightList': (replaceSimpleGetter, 'lights'), # KX_Scene
- 'getLooping': (replaceSimpleGetter, 'looping'), # KX_SoundActuator
- 'getMass': (replaceSimpleGetter, 'mass'), # KX_GameObject
- 'getMax': (replaceSimpleGetter, 'max'), # KX_CameraActuator
- 'getMin': (replaceSimpleGetter, 'min'), # KX_CameraActuator
- 'getName': (replaceSimpleGetter, 'name'), # KX_Scene
- 'getNumAxes': (replaceSimpleGetter, 'numAxis'), # SCA_JoystickSensor
- 'getNumButtons': (replaceSimpleGetter, 'numButtons'), # SCA_JoystickSensor
- 'getNumHats': (replaceSimpleGetter, 'numHats'), # SCA_JoystickSensor
- 'getObjectList': (replaceSimpleGetter, 'objects'), # KX_Scene
- 'getOperation': (replaceSimpleGetter, 'mode'), # KX_SCA_DynamicActuator
- 'getOrientation': (replaceSimpleGetter, 'worldOrientation'), # KX_GameObject
- 'getOwner': (replaceSimpleGetter, 'owner'), # SCA_ILogicBrick
- 'getPara1': (replaceSimpleGetter, 'para1'), # SCA_RandomActuator
- 'getPara2': (replaceSimpleGetter, 'para2'), # SCA_RandomActuator
- 'getParent': (replaceSimpleGetter, 'parent'), # KX_GameObject
- 'getPID': (replaceSimpleGetter, 'pid'), # KX_ObjectActuator
- 'getPitch': (replaceSimpleGetter, 'pitch'), # KX_SoundActuator
- 'getPosition': (replaceSimpleGetter, 'worldPosition'), # KX_GameObject
- 'getPressedKeys': (replaceSimpleGetter, 'events'), # SCA_KeyboardSensor
- 'getPriority': (replaceSimpleGetter, 'priority'), # BL_ShapeActionActuator, BL_ActionActuator
- 'getProjectionMatrix': (replaceSimpleGetter, 'projection_matrix'), # KX_Camera
- 'getProperty': (replaceSimpleGetter, 'propName'), # SCA_PropertySensor, SCA_RandomActuator, SCA_PropertyActuator
- 'getRayDirection': (replaceSimpleGetter, 'rayDirection'), # KX_MouseFocusSensor, KX_RaySensor
- 'getRaySource': (replaceSimpleGetter, 'raySource'), # KX_MouseFocusSensor
- 'getRayTarget': (replaceSimpleGetter, 'rayTarget'), # KX_MouseFocusSensor
- 'getRepeat': (replaceSimpleGetter, 'repeat'), # SCA_DelaySensor
- 'getRollOffFactor': (replaceSimpleGetter, 'rollOffFactor'), # KX_SoundActuator
- 'getScene': (replaceSimpleGetter, 'scene'), # KX_SceneActuator
- 'getScript': (replaceSimpleGetter, 'script'), # SCA_PythonController
- 'getSeed': (replaceSimpleGetter, 'seed'), # SCA_RandomActuator
- 'getStart': (replaceSimpleGetter, 'frameStart'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator
- 'getState': (replaceSimpleGetter, 'state'), # SCA_IController, KX_GameObject
- 'getSubject': (replaceSimpleGetter, 'subject'), # KX_NetworkMessageSensor
- 'getSubjects': (replaceSimpleGetter, 'subjects'), # KX_NetworkMessageSensor
- 'getThreshold': (replaceSimpleGetter, 'threshold'), # SCA_JoystickSensor
- 'getTime': (replaceSimpleGetter, 'time'), # KX_SCA_AddObjectActuator, KX_TrackToActuator
- 'getTouchMaterial': (replaceSimpleGetter, 'useMaterial'), # KX_TouchSensor
- 'getType': (replaceSimpleGetter, 'mode'), # SCA_PropertySensor
- 'getUse3D': (replaceSimpleGetter, 'use3D'), # KX_TrackToActuator
- 'getUseNegPulseMode': (replaceSimpleGetter, 'useNegPulseMode'), # SCA_ISensor
- 'getUsePosPulseMode': (replaceSimpleGetter, 'usePosPulseMode'), # SCA_ISensor
- 'getUseRestart': (replaceSimpleGetter, 'useRestart'), # KX_SceneActuator
- 'getValue': (replaceSimpleGetter, 'value'), # SCA_PropertySensor, SCA_PropertyActuator
- 'getVisible': (replaceSimpleGetter, 'visible'), # KX_GameObject
- 'getXY': (replaceSimpleGetter, 'useXY'), # KX_CameraActuator
- 'isConnected': (replaceSimpleGetter, 'connected'), # SCA_JoystickSensor
- 'isPositive': (replaceSimpleGetter, 'positive'), # SCA_ISensor
- 'isTriggered': (replaceSimpleGetter, 'triggered'), # SCA_ISensor
- 'setActuator': (replaceSimpleSetter, 'actuator'), # SCA_ActuatorSensor
- 'setBlendin': (replaceSimpleSetter, 'blendIn'), # BL_ShapeActionActuator, BL_ActionActuator
- 'setBlendtime': (replaceSimpleSetter, 'blendTime'), # BL_ShapeActionActuator, BL_ActionActuator
- 'setBodyType': (replaceSimpleSetter, 'usePropBody'), # KX_NetworkMessageActuator
- 'setBody': (replaceSimpleSetter, 'body'), # KX_NetworkMessageActuator
- 'setButton': (replaceSimpleSetter, 'button'), # SCA_JoystickSensor
- 'setCamera': (replaceSimpleSetter, 'camera'), # KX_SceneActuator
- 'setContinue': (replaceSimpleSetter, 'useContinue'), # BL_ActionActuator
- 'setDamping': (replaceSimpleSetter, 'damping'), # KX_ObjectActuator
- 'setDelay': (replaceSimpleSetter, 'delay'), # SCA_DelaySensor
- 'setDuration': (replaceSimpleSetter, 'duration'), # SCA_DelaySensor
- 'setEnd': (replaceSimpleSetter, 'frameEnd'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator
- 'setExecutePriority': (replaceSimpleSetter, 'executePriority'), # SCA_ILogicBrick
- 'setFile': (replaceSimpleSetter, 'fileName'), # KX_GameActuator
- 'setFilename': (replaceSimpleSetter, 'fileName'), # KX_SoundActuator
- 'setForceIpoActsLocal': (replaceSimpleSetter, 'useIpoLocal'), # KX_IpoActuator
- 'setFrame': (replaceSimpleSetter, 'frame'), # BL_ShapeActionActuator, BL_ActionActuator
- 'setFrameProperty': (replaceSimpleSetter, 'framePropName'), # BL_ShapeActionActuator, BL_ActionActuator
- 'setFrequency': (replaceSimpleSetter, 'frequency'), # SCA_ISensor
- 'setGain': (replaceSimpleSetter, 'volume'), # KX_SoundActuator
- 'setHeight': (replaceSimpleSetter, 'height'), # KX_CameraActuator
- 'setHold1': (replaceSimpleSetter, 'hold1'), # SCA_KeyboardSensor
- 'setHold2': (replaceSimpleSetter, 'hold2'), # SCA_KeyboardSensor
- 'setInvert': (replaceSimpleSetter, 'invert'), # SCA_ISensor
- 'setIpoAdd': (replaceSimpleSetter, 'useIpoAdd'), # KX_IpoActuator
- 'setIpoAsForce': (replaceSimpleSetter, 'useIpoAsForce'), # KX_IpoActuator
- 'setKey': (replaceSimpleSetter, 'key'), # SCA_KeyboardSensor
- 'setLevel': (replaceSimpleSetter, 'level'), # SCA_ISensor
- 'setLooping': (replaceSimpleSetter, 'looping'), # KX_SoundActuator
- 'setMask': (replaceSimpleSetter, 'mask'), # KX_StateActuator
- 'setMax': (replaceSimpleSetter, 'max'), # KX_CameraActuator
- 'setMesh': (replaceSimpleSetter, 'mesh'), # KX_SCA_ReplaceMeshActuator
- 'setMin': (replaceSimpleSetter, 'min'), # KX_CameraActuator
- 'setPitch': (replaceSimpleSetter, 'pitch'), # KX_SoundActuator
- 'setPriority': (replaceSimpleSetter, 'priority'), # BL_ShapeActionActuator, BL_ActionActuator
- 'setProjectionMatrix': (replaceSimpleSetter, 'projection_matrix'), # KX_Camera
- 'setProperty': (replaceSimpleSetter, 'propName'), # KX_IpoActuator, SCA_PropertySensor, SCA_RandomActuator, SCA_PropertyActuator
- 'setRepeat': (replaceSimpleSetter, 'repeat'), # SCA_DelaySensor
- 'setRollOffFactor': (replaceSimpleSetter, 'rollOffFactor'), # KX_SoundActuator
- 'setScene': (replaceSimpleSetter, 'scene'), # KX_SceneActuator
- 'setScript': (replaceSimpleSetter, 'script'), # SCA_PythonController
- 'setSeed': (replaceSimpleSetter, 'seed'), # SCA_RandomActuator
- 'setStart': (replaceSimpleSetter, 'frameStart'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator
- 'setState': (replaceSimpleSetter, 'state'), # KX_GameObject
- 'setSubject': (replaceSimpleSetter, 'subject'), # KX_NetworkMessageActuator
- 'setSubjectFilterText': (replaceSimpleSetter, 'subject'), # KX_NetworkMessageSensor
- 'setThreshold': (replaceSimpleSetter, 'threshold'), # SCA_JoystickSensor
- 'setTime': (replaceSimpleSetter, 'time'), # KX_SCA_AddObjectActuator, KX_TrackToActuator
- 'setToPropName': (replaceSimpleSetter, 'propName'), # KX_NetworkMessageActuator
- 'setType': (replaceSimpleSetter, 'mode'), # SCA_PropertySensor
- 'setUse3D': (replaceSimpleSetter, 'use3D'), # KX_TrackToActuator
- 'setUseNegPulseMode': (replaceSimpleSetter, 'useNegPulseMode'), # SCA_ISensor
- 'setUsePosPulseMode': (replaceSimpleSetter, 'usePosPulseMode'), # SCA_ISensor
- 'setUseRestart': (replaceSimpleSetter, 'useRestart'), # KX_SceneActuator
- 'setValue': (replaceSimpleSetter, 'value'), # SCA_PropertySensor, SCA_PropertyActuator
- 'setXY': (replaceSimpleSetter, 'useXY'), # KX_CameraActuator
-
- # Unimplemented!
- 'getLinearVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']),
- 'setLinearVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']),
- 'getAngularVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']),
- 'setAngularVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']),
- 'setAction': (notImplemented, ['BL_ShapeActionActuator', 'BL_ActionActuator']),
- 'set': (notImplemented, ['KX_VisibilityActuator', 'KX_IpoActuator']),
- 'getIndex': (notImplemented, ['SCA_JoystickSensor']),
- 'getMesh': (notImplemented, ['KX_SCA_ReplaceMeshActuator']),
- 'getObject': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_CameraActuator', 'KX_TrackToActuator', 'KX_ParentActuator']),
- 'setIndex': (notImplemented, ['SCA_JoystickSensor']),
- 'setObject': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_CameraActuator', 'KX_TrackToActuator', 'KX_ParentActuator']),
- 'setOperation': (notImplemented, ['KX_SCA_DynamicActuator', 'KX_StateActuator']),
- 'position': (notImplemented, ['KX_GameObject', 'KX_SoundActuator']),
- 'orientation': (notImplemented, ['KX_GameObject', 'KX_SoundActuator']),
- 'getDRot': (notImplemented, ['KX_ObjectActuator']),
- 'setDRot': (notImplemented, ['KX_ObjectActuator']),
- 'getDLoc': (notImplemented, ['KX_ObjectActuator']),
- 'setDLoc': (notImplemented, ['KX_ObjectActuator']),
- 'getTorque': (notImplemented, ['KX_ObjectActuator']),
- 'getTorque': (notImplemented, ['KX_ObjectActuator']),
- 'getForce': (notImplemented, ['KX_ObjectActuator']),
- 'setForce': (notImplemented, ['KX_ObjectActuator']),
-}
-
-def convert248to249(lines, log = True, logErrors = True, fileName = None):
- # Regular expression for finding attributes. For the string 'a.b', this
- # returns three groups: ['a.b', 'a.', 'b']. The last is the attribute name.
- attrRegex = re.compile(r'\.\s*' # Dot
- r'([a-zA-Z_]\w*)') # Identifier
-
- fileIdStr = ""
- if fileName:
- fileIdStr = fileName + ": "
- row = 0
- col = 0
- nconverted = 0
- nerrors = 0
- while row < len(lines):
- originalLine = lines[row]
- changed = False
- while col < len(lines[row]):
- # Don't search past comment. We have to check each iteration
- # because the line contents may have changed.
- commentStart = lines[row].find('#', col)
- if commentStart < 0:
- commentStart = len(lines[row])
-
- # Search for an attribute identifier.
- match = attrRegex.search(lines[row], col, commentStart)
- if not match:
- break
-
- attrName = match.group(1)
- if attributeRenameDict.has_key(attrName):
- # name is deprecated.
- func, closure = attributeRenameDict[attrName]
- try:
- # Convert!
- func(lines, row, match.start(1), match.end(1), closure)
- except ConversionError, e:
- # Insert a comment saying the conversion failed.
- print "ERROR: %sline %d, %s: %s\n" % (
- fileIdStr, row + 1, attrName, e)
- if logErrors:
- lines.insert(row,
- "##248## ERROR: %s: %s\n" %
- (attrName, e))
- row = row + 1
- nerrors = nerrors + 1
- else:
- changed = True
- nconverted = nconverted + 1
- # Search the rest of this line.
- col = match.start(1)
-
- if changed and log:
- # Insert a comment to showing difference in lines.
- if originalLine[-1] != '\n':
- originalLine = originalLine + '\n'
- lines.insert(row, "##248##%s" % originalLine)
- row = row + 1
-
- row = row + 1
- col = 0
- return nconverted, nerrors
-
-def usage():
- print "Usage: blender248to249.py [options] <infile> [outfile]"
- print "Options:"
- print "\t--nolog Don't include old lines as comments."
- print "\t--quieterrors Don't insert errors as comments."
-
-def runAsConsoleScript():
- '''Called when being run as a console script.'''
- try:
- opts, args = getopt.getopt(sys.argv[1:], "", ["nolog", "quieterrors"])
- except getopt.GetoptError, err:
- # print help information and exit:
- print str(err)
- usage()
- sys.exit(2)
-
- log = True
- logErrors = True
- for o, a in opts:
- if o == "--nolog":
- log = False
- elif o == "--quieterrors":
- logErrors = False
-
- try:
- inpath = args.pop(0)
- except IndexError:
- usage()
- sys.exit(2)
- try:
- outpath = args.pop(0)
- except IndexError:
- outpath = inpath
-
- infile = io.FileIO(inpath, 'r')
- # arbitrary file size of around 100kB
- lines = infile.readlines(100000)
- infile.close()
-
- nconverted, nerrors = convert248to249(lines, log, logErrors)
-
- outfile = io.FileIO(outpath, 'w')
- outfile.writelines(lines)
- outfile.close()
- print "Conversion finished. Modified %d attributes." % nconverted
- print "There were %d errors." % nerrors
- print "Please review all the changes."
-
-def runAsTextPlugin():
- '''Called when run as a text plugin.'''
-
- import Blender
- from Blender import Window, sys, Draw
- import BPyTextPlugin, bpy
-
- message = ("Convert Game Engine script from 4.48 API to 2.49 API%t|"
- "Run on active script only%x1|"
- "Run on ALL text buffers%x2")
- convertAllBuffers = Draw.PupMenu(message) == 2
-
- Window.WaitCursor(1)
- try:
- nconverted = 0
- nerrors = 0
-
- if convertAllBuffers:
- texts = bpy.data.texts
- else:
- if not bpy.data.texts.active:
- Draw.PupMenu("No active buffer.")
- return
- texts = [bpy.data.texts.active]
-
- Blender.SaveUndoState('Convert BGE 2.49')
-
- for txt in texts:
- bufName = txt.name
- if txt.lib:
- bufName = txt.lib + '/' + bufName
- lines = txt.asLines()
- for i in range(0, len(lines)):
- if not lines[i].endswith('\n'):
- lines[i] = lines[i] + '\n'
-
- nc, ne = convert248to249(lines, fileName = bufName)
- nconverted = nconverted + nc
- nerrors = nerrors + ne
- txt.clear()
- for line in lines:
- txt.write(line)
-
- finally:
- Window.WaitCursor(0)
-
- message = "Converted %d attributes." % nconverted
- if nerrors == 1:
- message = message + " There was 1 error (see console)."
- if nerrors > 1:
- message = message + " There were %d errors (see console)." % nerrors
- message = message + "|Please review all the changes."
- Draw.PupMenu(message)
-
-def main():
- try:
- import Blender
- except ImportError:
- runAsConsoleScript()
- else:
- runAsTextPlugin()
-
-# This lets you import the script without running it
-if __name__ == "__main__":
- import sys
- import getopt
- import io
- main()
diff --git a/release/scripts/textplugin_functiondocs.py b/release/scripts/textplugin_functiondocs.py
deleted file mode 100644
index 41c8d4842a0..00000000000
--- a/release/scripts/textplugin_functiondocs.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!BPY
-"""
-Name: 'Function Documentation | Ctrl I'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Ctrl+I'
-Tooltip: 'Attempts to display documentation about the function preceding the cursor.'
-"""
-
-# Only run if we have the required modules
-try:
- import bpy
- from BPyTextPlugin import *
-except ImportError:
- OK = False
-else:
- OK = True
-
-def main():
- txt = bpy.data.texts.active
- if not txt:
- return
-
- (line, c) = current_line(txt)
-
- # Check we are in a normal context
- if get_context(txt) != CTX_NORMAL:
- return
-
- # Identify the name under the cursor
- llen = len(line)
- while c<llen and (line[c].isalnum() or line[c]=='_'):
- c += 1
-
- targets = get_targets(line, c)
-
- # If no name under cursor, look backward to see if we're in function parens
- if len(targets) == 0 or targets[0] == '':
- # Look backwards for first '(' without ')'
- b = 0
- found = False
- for i in range(c-1, -1, -1):
- if line[i] == ')': b += 1
- elif line[i] == '(':
- b -= 1
- if b < 0:
- found = True
- c = i
- break
- if found: targets = get_targets(line, c)
- if len(targets) == 0 or targets[0] == '':
- return
-
- obj = resolve_targets(txt, targets)
- if not obj: return
-
- if isinstance(obj, Definition): # Local definition
- txt.showDocs(obj.doc)
- elif hasattr(obj, '__doc__') and obj.__doc__:
- txt.showDocs(obj.__doc__)
-
-# Check we are running as a script and not imported as a module
-if __name__ == "__main__" and OK:
- main()
diff --git a/release/scripts/textplugin_imports.py b/release/scripts/textplugin_imports.py
deleted file mode 100644
index ec608243c2b..00000000000
--- a/release/scripts/textplugin_imports.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!BPY
-"""
-Name: 'Import Complete|Space'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Space'
-Tooltip: 'Lists modules when import or from is typed'
-"""
-
-# Only run if we have the required modules
-try:
- import bpy, sys
- from BPyTextPlugin import *
-except ImportError:
- OK = False
-else:
- OK = True
-
-def main():
- txt = bpy.data.texts.active
- if not txt:
- return
-
- line, c = current_line(txt)
-
- # Check we are in a normal context
- if get_context(txt) != CTX_NORMAL:
- return
-
- pos = line.rfind('from ', 0, c)
-
- # No 'from' found
- if pos == -1:
- # Check instead for straight 'import xxxx'
- pos2 = line.rfind('import ', 0, c)
- if pos2 != -1:
- pos2 += 7
- for i in range(pos2, c):
- if line[i]==',' or (line[i]==' ' and line[i-1]==','):
- pos2 = i+1
- elif not line[i].isalnum() and line[i] != '_':
- return
- items = [(m, 'm') for m in get_modules()]
- items.sort(cmp = suggest_cmp)
- txt.suggest(items, line[pos2:c].strip())
- return
-
- # Found 'from xxxxx' before cursor
- immediate = True
- pos += 5
- for i in range(pos, c):
- if not line[i].isalnum() and line[i] != '_' and line[i] != '.':
- immediate = False
- break
-
- # Immediate 'from' followed by at most a module name
- if immediate:
- items = [(m, 'm') for m in get_modules()]
- items.sort(cmp = suggest_cmp)
- txt.suggest(items, line[pos:c])
- return
-
- # Found 'from' earlier, suggest import if not already there
- pos2 = line.rfind('import ', pos, c)
-
- # No 'import' found after 'from' so suggest it
- if pos2 == -1:
- txt.suggest([('import', 'k')], '')
- return
-
- # Immediate 'import' before cursor and after 'from...'
- for i in range(pos2+7, c):
- if line[i]==',' or (line[i]==' ' and line[i-1]==','):
- pass
- elif not line[i].isalnum() and line[i] != '_':
- return
- between = line[pos:pos2-1].strip()
- try:
- mod = get_module(between)
- except ImportError:
- return
-
- items = [('*', 'k')]
- for (k,v) in mod.__dict__.items():
- items.append((k, type_char(v)))
- items.sort(cmp = suggest_cmp)
- txt.suggest(items, '')
-
-# Check we are running as a script and not imported as a module
-if __name__ == "__main__" and OK:
- main()
diff --git a/release/scripts/textplugin_membersuggest.py b/release/scripts/textplugin_membersuggest.py
deleted file mode 100644
index 7c0de78b704..00000000000
--- a/release/scripts/textplugin_membersuggest.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#!BPY
-"""
-Name: 'Member Suggest | .'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Period'
-Tooltip: 'Lists members of the object preceding the cursor in the current text space'
-"""
-
-# Only run if we have the required modules
-try:
- import bpy
- from BPyTextPlugin import *
-except ImportError:
- OK = False
-else:
- OK = True
-
-def main():
- txt = bpy.data.texts.active
- if not txt:
- return
-
- (line, c) = current_line(txt)
-
- # Check we are in a normal context
- if get_context(txt) != CTX_NORMAL:
- return
-
- targets = get_targets(line, c)
-
- if targets[0] == '': # Check if we are looking at a constant [] {} '' etc.
- i = c - len('.'.join(targets)) - 1
- if i >= 0:
- if line[i] == '"' or line[i] == "'":
- targets[0] = 'str'
- elif line[i] == '}':
- targets[0] = 'dict'
- elif line[i] == ']': # Could be array elem x[y] or list [y]
- i = line.rfind('[', 0, i) - 1
- while i >= 0:
- if line[i].isalnum() or line[i] == '_':
- break
- elif line[i] != ' ' and line[i] != '\t':
- i = -1
- break
- i -= 1
- if i < 0:
- targets[0] = 'list'
-
- obj = resolve_targets(txt, targets[:-1])
- if not obj:
- return
-
- items = []
-
- if isinstance(obj, VarDesc):
- obj = obj.type
-
- if isinstance(obj, Definition): # Locally defined
- if hasattr(obj, 'classes'):
- items.extend([(s, 'f') for s in obj.classes.keys()])
- if hasattr(obj, 'defs'):
- items.extend([(s, 'f') for s in obj.defs.keys()])
- if hasattr(obj, 'vars'):
- items.extend([(s, 'v') for s in obj.vars.keys()])
-
- else: # Otherwise we have an imported or builtin object
- try:
- attr = obj.__dict__.keys()
- except AttributeError:
- attr = dir(obj)
- else:
- if not attr: attr = dir(obj)
-
- for k in attr:
- try:
- v = getattr(obj, k)
- except (AttributeError, TypeError): # Some attributes are not readable
- pass
- else:
- items.append((k, type_char(v)))
-
- if items != []:
- items.sort(cmp = suggest_cmp)
- txt.suggest(items, targets[-1])
-
-# Check we are running as a script and not imported as a module
-if __name__ == "__main__" and OK:
- main()
diff --git a/release/scripts/textplugin_outliner.py b/release/scripts/textplugin_outliner.py
deleted file mode 100644
index 3879a2819a5..00000000000
--- a/release/scripts/textplugin_outliner.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#!BPY
-"""
-Name: 'Code Outline | Ctrl T'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Ctrl+T'
-Tooltip: 'Provides a menu for jumping to class and functions definitions.'
-"""
-
-# Only run if we have the required modules
-try:
- import bpy
- from BPyTextPlugin import *
- from Blender import Draw
-except ImportError:
- OK = False
-else:
- OK = True
-
-def make_menu(items, eventoffs):
- n = len(items)
- if n < 20:
- return [(items[i], i+1+eventoffs) for i in range(len(items))]
-
- letters = []
- check = 'abcdefghijklmnopqrstuvwxyz_' # Names cannot start 0-9
- for c in check:
- for item in items:
- if item[0].lower() == c:
- letters.append(c)
- break
-
- entries = {}
- i = 0
- for item in items:
- i += 1
- c = item[0].lower()
- entries.setdefault(c, []).append((item, i+eventoffs))
-
- subs = []
- for c in letters:
- subs.append((c, entries[c]))
-
- return subs
-
-def find_word(txt, word):
- i = 0
- txt.reset()
- while True:
- try:
- line = txt.readline()
- except StopIteration:
- break
- c = line.find(word)
- if c != -1:
- txt.setCursorPos(i, c)
- break
- i += 1
-
-def main():
- txt = bpy.data.texts.active
- if not txt:
- return
-
- # Identify word under cursor
- if get_context(txt) == CTX_NORMAL:
- line, c = current_line(txt)
- start = c-1
- end = c
- while start >= 0:
- if not line[start].lower() in 'abcdefghijklmnopqrstuvwxyz0123456789_':
- break
- start -= 1
- while end < len(line):
- if not line[end].lower() in 'abcdefghijklmnopqrstuvwxyz0123456789_':
- break
- end += 1
- word = line[start+1:end]
- if word in KEYWORDS:
- word = None
- else:
- word = None
-
- script = get_cached_descriptor(txt)
- items = []
- desc = None
-
- tmp = script.classes.keys()
- tmp.sort(cmp = suggest_cmp)
- class_menu = make_menu(tmp, len(items))
- class_menu_length = len(tmp)
- items.extend(tmp)
-
- tmp = script.defs.keys()
- tmp.sort(cmp = suggest_cmp)
- defs_menu = make_menu(tmp, len(items))
- defs_menu_length = len(tmp)
- items.extend(tmp)
-
- tmp = script.vars.keys()
- tmp.sort(cmp = suggest_cmp)
- vars_menu = make_menu(tmp, len(items))
- vars_menu_length = len(tmp)
- items.extend(tmp)
-
- menu = [('Script %t', 0),
- ('Classes', class_menu),
- ('Functions', defs_menu),
- ('Variables', vars_menu)]
- if word:
- menu.extend([None, ('Locate', [(word, -10)])])
-
- i = Draw.PupTreeMenu(menu)
- if i == -1:
- return
-
- # Chosen to search for word under cursor
- if i == -10:
- if script.classes.has_key(word):
- desc = script.classes[word]
- elif script.defs.has_key(word):
- desc = script.defs[word]
- elif script.vars.has_key(word):
- desc = script.vars[word]
- else:
- find_word(txt, word)
- return
- else:
- i -= 1
- if i < class_menu_length:
- desc = script.classes[items[i]]
- elif i < class_menu_length + defs_menu_length:
- desc = script.defs[items[i]]
- elif i < class_menu_length + defs_menu_length + vars_menu_length:
- desc = script.vars[items[i]]
-
- if desc:
- txt.setCursorPos(desc.lineno-1, 0)
-
-# Check we are running as a script and not imported as a module
-if __name__ == "__main__" and OK:
- main()
diff --git a/release/scripts/textplugin_suggest.py b/release/scripts/textplugin_suggest.py
deleted file mode 100644
index d8122212d3b..00000000000
--- a/release/scripts/textplugin_suggest.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!BPY
-"""
-Name: 'Suggest All | Ctrl Space'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Ctrl+Space'
-Tooltip: 'Performs suggestions based on the context of the cursor'
-"""
-
-# Only run if we have the required modules
-try:
- import bpy
- from BPyTextPlugin import *
-except ImportError:
- OK = False
-else:
- OK = True
-
-def check_membersuggest(line, c):
- pos = line.rfind('.', 0, c)
- if pos == -1:
- return False
- for s in line[pos+1:c]:
- if not s.isalnum() and s != '_':
- return False
- return True
-
-def check_imports(line, c):
- pos = line.rfind('import ', 0, c)
- if pos > -1:
- for s in line[pos+7:c]:
- if not s.isalnum() and s != '_':
- return False
- return True
- pos = line.rfind('from ', 0, c)
- if pos > -1:
- for s in line[pos+5:c]:
- if not s.isalnum() and s != '_':
- return False
- return True
- return False
-
-def main():
- txt = bpy.data.texts.active
- if not txt:
- return
-
- line, c = current_line(txt)
-
- # Check we are in a normal context
- if get_context(txt) != CTX_NORMAL:
- return
-
- # Check the character preceding the cursor and execute the corresponding script
-
- if check_membersuggest(line, c):
- import textplugin_membersuggest
- textplugin_membersuggest.main()
- return
-
- elif check_imports(line, c):
- import textplugin_imports
- textplugin_imports.main()
- return
-
- # Otherwise we suggest globals, keywords, etc.
- list = []
- targets = get_targets(line, c)
- desc = get_cached_descriptor(txt)
-
- for k in KEYWORDS:
- list.append((k, 'k'))
-
- for k, v in get_builtins().items():
- list.append((k, type_char(v)))
-
- for k, v in desc.imports.items():
- list.append((k, type_char(v)))
-
- for k, v in desc.classes.items():
- list.append((k, 'f'))
-
- for k, v in desc.defs.items():
- list.append((k, 'f'))
-
- for k, v in desc.vars.items():
- list.append((k, 'v'))
-
- list.sort(cmp = suggest_cmp)
- txt.suggest(list, targets[-1])
-
-# Check we are running as a script and not imported as a module
-if __name__ == "__main__" and OK:
- main()
diff --git a/release/scripts/textplugin_templates.py b/release/scripts/textplugin_templates.py
deleted file mode 100644
index 8f949563ac0..00000000000
--- a/release/scripts/textplugin_templates.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!BPY
-"""
-Name: 'Template Completion | Tab'
-Blender: 246
-Group: 'TextPlugin'
-Shortcut: 'Tab'
-Tooltip: 'Completes templates based on the text preceding the cursor'
-"""
-
-# Only run if we have the required modules
-try:
- import bpy
- from BPyTextPlugin import *
- from Blender import Text
-except ImportError:
- OK = False
-else:
- OK = True
-
-templates = {
- 'ie':
- 'if ${1:cond}:\n'
- '\t${2}\n'
- 'else:\n'
- '\t${3}\n',
- 'iei':
- 'if ${1:cond}:\n'
- '\t${2}\n'
- 'elif:\n'
- '\t${3}\n'
- 'else:\n'
- '\t${4}\n',
- 'def':
- 'def ${1:name}(${2:params}):\n'
- '\t"""(${2}) - ${3:comment}"""\n'
- '\t${4}',
- 'cls':
- 'class ${1:name}(${2:parent}):\n'
- '\t"""${3:docs}"""\n'
- '\t\n'
- '\tdef __init__(self, ${4:params}):\n'
- '\t\t"""Creates a new ${1}"""\n'
- '\t\t${5}',
- 'class':
- 'class ${1:name}(${2:parent}):\n'
- '\t"""${3:docs}"""\n'
- '\t\n'
- '\tdef __init__(self, ${4:params}):\n'
- '\t\t"""Creates a new ${1}"""\n'
- '\t\t${5}'
-}
-
-def main():
- txt = bpy.data.texts.active
- if not txt:
- return
-
- row, c = txt.getCursorPos()
- line = txt.asLines(row, row+1)[0]
- indent=0
- while indent<c and (line[indent]==' ' or line[indent]=='\t'):
- indent += 1
-
- # Check we are in a normal context
- if get_context(txt) != CTX_NORMAL:
- return
-
- targets = get_targets(line, c-1);
- if len(targets) != 1: return
-
- color = (0, 192, 32)
-
- for trigger, template in templates.items():
- if trigger != targets[0]: continue
- inserts = {}
- txt.delete(-len(trigger)-1)
- y, x = txt.getCursorPos()
- first = None
-
- # Insert template text and parse for insertion points
- count = len(template); i = 0
- while i < count:
- if i<count-1 and template[i]=='$' and template[i+1]=='{':
- i += 2
- e = template.find('}', i)
- item = template[i:e].split(':')
- if len(item)<2: item.append('')
- if not inserts.has_key(item[0]):
- inserts[item[0]] = (item[1], [(x, y)])
- else:
- inserts[item[0]][1].append((x, y))
- item[1] = inserts[item[0]][0]
- if not first: first = (item[1], x, y)
- txt.insert(item[1])
- x += len(item[1])
- i = e
- else:
- txt.insert(template[i])
- if template[i] == '\n':
- txt.insert(line[:indent])
- y += 1
- x = indent
- else:
- x += 1
- i += 1
-
- # Insert markers at insertion points
- for id, (text, points) in inserts.items():
- for x, y in points:
- txt.setCursorPos(y, x)
- txt.setSelectPos(y, x+len(text))
- txt.markSelection((hash(text)+int(id)) & 0xFFFF, color,
- Text.TMARK_TEMP | Text.TMARK_EDITALL)
- if first:
- text, x, y = first
- txt.setCursorPos(y, x)
- txt.setSelectPos(y, x+len(text))
- break
-
-
-# Check we are running as a script and not imported as a module
-if __name__ == "__main__" and OK:
- main()
diff --git a/release/ui/buttons_data_armature.py b/release/scripts/ui/buttons_data_armature.py
index 5924a2eb4ea..9344294ff9e 100644
--- a/release/ui/buttons_data_armature.py
+++ b/release/scripts/ui/buttons_data_armature.py
@@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel):
__context__ = "data"
def poll(self, context):
- return (context.armature)
+ return context.armature
class DATA_PT_context_arm(DataButtonsPanel):
__show_header__ = False
@@ -37,7 +37,9 @@ class DATA_PT_skeleton(DataButtonsPanel):
ob = context.object
arm = context.armature
space = context.space_data
-
+
+ layout.itemR(arm, "pose_position", expand=True)
+
split = layout.split()
col = split.column()
@@ -50,7 +52,6 @@ class DATA_PT_skeleton(DataButtonsPanel):
col.itemR(arm, "auto_ik")
col = split.column()
- col.itemR(arm, "rest_position")
col.itemL(text="Deform:")
col.itemR(arm, "deform_vertexgroups", text="Vertex Groups")
col.itemR(arm, "deform_envelope", text="Envelopes")
@@ -121,28 +122,34 @@ class DATA_PT_paths(DataButtonsPanel):
layout = self.layout
arm = context.armature
-
+
+ layout.itemR(arm, "paths_type", expand=True)
+
split = layout.split()
col = split.column()
- col.itemR(arm, "paths_show_around_current_frame", text="Around Frame")
-
sub = col.column(align=True)
- if (arm.paths_show_around_current_frame):
+ if (arm.paths_type == 'CURRENT_FRAME'):
sub.itemR(arm, "path_before_current", text="Before")
sub.itemR(arm, "path_after_current", text="After")
- else:
+ elif (arm.paths_type == 'RANGE'):
sub.itemR(arm, "path_start_frame", text="Start")
sub.itemR(arm, "path_end_frame", text="End")
- sub.itemR(arm, "path_size", text="Step")
- col.itemR(arm, "paths_calculate_head_positions", text="Head")
+ sub.itemR(arm, "path_size", text="Step")
+ col.row().itemR(arm, "paths_location", expand=True)
col = split.column()
- col.itemL(text="Show:")
+ col.itemL(text="Display:")
col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers")
col.itemR(arm, "paths_highlight_keyframes", text="Keyframes")
col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers")
+
+ layout.itemS()
+
+ row = layout.row()
+ row.itemO("pose.paths_calculate", text="Calculate Paths")
+ row.itemO("pose.paths_clear", text="Clear Paths")
class DATA_PT_ghost(DataButtonsPanel):
__label__ = "Ghost"
@@ -151,11 +158,12 @@ class DATA_PT_ghost(DataButtonsPanel):
layout = self.layout
arm = context.armature
-
+
+ layout.itemR(arm, "ghost_type", expand=True)
+
split = layout.split()
col = split.column()
- col.itemR(arm, "ghost_type", text="")
sub = col.column(align=True)
if arm.ghost_type == 'RANGE':
@@ -167,6 +175,7 @@ class DATA_PT_ghost(DataButtonsPanel):
sub.itemR(arm, "ghost_size", text="Step")
col = split.column()
+ col.itemL(text="Display:")
col.itemR(arm, "ghost_only_selected", text="Selected Only")
bpy.types.register(DATA_PT_context_arm)
diff --git a/release/ui/buttons_data_bone.py b/release/scripts/ui/buttons_data_bone.py
index a0121821e55..5971e4492ce 100644
--- a/release/ui/buttons_data_bone.py
+++ b/release/scripts/ui/buttons_data_bone.py
@@ -57,23 +57,20 @@ class BONE_PT_transform(BoneButtonsPanel):
col = row.column()
if pchan.rotation_mode == 'QUATERNION':
- col.itemR(pchan, "rotation", text="Rotation")
+ col.itemR(pchan, "rotation_quaternion", text="Rotation")
elif pchan.rotation_mode == 'AXIS_ANGLE':
- col.itemL(text="Rotation")
- col.itemR(pchan, "rotation_angle", text="Angle")
- col.itemR(pchan, "rotation_axis", text="Axis")
+ #col.itemL(text="Rotation")
+ #col.itemR(pchan, "rotation_angle", text="Angle")
+ #col.itemR(pchan, "rotation_axis", text="Axis")
+ col.itemR(pchan, "rotation_axis_angle", text="Rotation")
else:
- col.itemR(pchan, "euler_rotation", text="Rotation")
+ col.itemR(pchan, "rotation_euler", text="Rotation")
row.column().itemR(pchan, "scale")
-
- if pchan.rotation_mode == 'QUATERNION':
- col = layout.column(align=True)
- col.itemL(text="Euler:")
- col.row().itemR(pchan, "euler_rotation", text="")
class BONE_PT_transform_locks(BoneButtonsPanel):
__label__ = "Transform Locks"
+ __default_closed__ = True
def poll(self, context):
return context.bone
@@ -173,10 +170,13 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel):
bone = context.bone
pchan = ob.pose.pose_channels[context.bone.name]
+ row = layout.row()
+ row.itemR(ob.pose, "ik_solver")
+
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_x", text="X")
row = split.row()
- row.itemR(pchan, "ik_stiffness_x", text="Stiffness")
+ row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
row.active = pchan.ik_dof_x
split = layout.split(percentage=0.25)
@@ -191,7 +191,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel):
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_y", text="Y")
row = split.row()
- row.itemR(pchan, "ik_stiffness_y", text="Stiffness")
+ row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
row.active = pchan.ik_dof_y
split = layout.split(percentage=0.25)
@@ -206,7 +206,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel):
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_z", text="Z")
row = split.row()
- row.itemR(pchan, "ik_stiffness_z", text="Stiffness")
+ row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
row.active = pchan.ik_dof_z
split = layout.split(percentage=0.25)
@@ -217,11 +217,26 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel):
row.itemR(pchan, "ik_min_z", text="")
row.itemR(pchan, "ik_max_z", text="")
row.active = pchan.ik_dof_z and pchan.ik_limit_z
-
split = layout.split()
- split.itemR(pchan, "ik_stretch", text="Stretch")
+ split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
split.itemL()
+ if ob.pose.ik_solver == "ITASC":
+ layout.itemL(text="Joint constraint:")
+ split = layout.split(percentage=0.3)
+ row = split.row()
+ row.itemR(pchan, "ik_rot_control", text="Rotation")
+ row = split.row()
+ row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
+ row.active = pchan.ik_rot_control
+ # not supported yet
+ #split = layout.split(percentage=0.3)
+ #row = split.row()
+ #row.itemR(pchan, "ik_lin_control", text="Size")
+ #row = split.row()
+ #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
+ #row.active = pchan.ik_lin_control
+
class BONE_PT_deform(BoneButtonsPanel):
__label__ = "Deform"
__default_closed__ = True
@@ -270,9 +285,65 @@ class BONE_PT_deform(BoneButtonsPanel):
col.itemL(text="Offset:")
col.itemR(bone, "cyclic_offset")
+class BONE_PT_iksolver_itasc(BoneButtonsPanel):
+ __idname__ = "BONE_PT_iksolver_itasc"
+ __label__ = "iTaSC parameters"
+ __default_closed__ = True
+
+ def poll(self, context):
+ ob = context.object
+ bone = context.bone
+
+ if ob and context.bone:
+ pchan = ob.pose.pose_channels[context.bone.name]
+ return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
+
+ return False
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ itasc = ob.pose.ik_param
+
+ layout.row().itemR(itasc, "simulation")
+ if itasc.simulation:
+ split = layout.split()
+ row = split.row()
+ row.itemR(itasc, "reiteration")
+ row = split.row()
+ if itasc.reiteration:
+ itasc.initial_reiteration = True
+ row.itemR(itasc, "initial_reiteration")
+ row.active = not itasc.reiteration
+
+ flow = layout.column_flow()
+ flow.itemR(itasc, "precision")
+ flow.itemR(itasc, "num_iter")
+ flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration
+
+ if itasc.simulation:
+ layout.itemR(itasc, "auto_step")
+ row = layout.row()
+ if itasc.auto_step:
+ row.itemR(itasc, "min_step")
+ row.itemR(itasc, "max_step")
+ else:
+ row.itemR(itasc, "num_step")
+
+ layout.itemR(itasc, "solver")
+ if itasc.simulation:
+ layout.itemR(itasc, "feedback")
+ layout.itemR(itasc, "max_velocity")
+ if itasc.solver == "DLS":
+ row = layout.row()
+ row.itemR(itasc, "dampmax")
+ row.itemR(itasc, "dampeps")
+
bpy.types.register(BONE_PT_context_bone)
bpy.types.register(BONE_PT_transform)
bpy.types.register(BONE_PT_transform_locks)
bpy.types.register(BONE_PT_bone)
bpy.types.register(BONE_PT_deform)
bpy.types.register(BONE_PT_inverse_kinematics)
+bpy.types.register(BONE_PT_iksolver_itasc)
diff --git a/release/ui/buttons_data_camera.py b/release/scripts/ui/buttons_data_camera.py
index aa107d8dbdd..19d7dfef852 100644
--- a/release/ui/buttons_data_camera.py
+++ b/release/scripts/ui/buttons_data_camera.py
@@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel):
__context__ = "data"
def poll(self, context):
- return (context.camera)
+ return context.camera
class DATA_PT_context_camera(DataButtonsPanel):
__show_header__ = False
@@ -38,13 +38,13 @@ class DATA_PT_camera(DataButtonsPanel):
layout.itemR(cam, "type", expand=True)
- row = layout.row(align=True)
+ row = layout.row()
if cam.type == 'PERSP':
- row.itemR(cam, "lens_unit", text="")
if cam.lens_unit == 'MILLIMETERS':
row.itemR(cam, "lens", text="Angle")
elif cam.lens_unit == 'DEGREES':
row.itemR(cam, "angle")
+ row.itemR(cam, "lens_unit", text="")
elif cam.type == 'ORTHO':
row.itemR(cam, "ortho_scale")
@@ -86,12 +86,13 @@ class DATA_PT_camera_display(DataButtonsPanel):
col.itemR(cam, "show_name", text="Name")
col = split.column()
+ col.itemR(cam, "draw_size", text="Size")
+ col.itemS()
col.itemR(cam, "show_passepartout", text="Passepartout")
sub = col.column()
sub.active = cam.show_passepartout
sub.itemR(cam, "passepartout_alpha", text="Alpha", slider=True)
- col.itemR(cam, "draw_size", text="Size")
-
+
bpy.types.register(DATA_PT_context_camera)
bpy.types.register(DATA_PT_camera)
bpy.types.register(DATA_PT_camera_display)
diff --git a/release/ui/buttons_data_curve.py b/release/scripts/ui/buttons_data_curve.py
index 1a5e56b02a4..c715cfb5d93 100644
--- a/release/ui/buttons_data_curve.py
+++ b/release/scripts/ui/buttons_data_curve.py
@@ -56,7 +56,7 @@ class DATA_PT_shape_curve(DataButtonsPanel):
if not is_surf:
row = layout.row()
- row.itemR(curve, "curve_2d")
+ row.itemR(curve, "dimensions", expand=True)
split = layout.split()
@@ -64,7 +64,7 @@ class DATA_PT_shape_curve(DataButtonsPanel):
if not is_surf:
sub = col.column()
- sub.active = curve.curve_2d
+ sub.active = (curve.dimensions=='2D')
sub.itemL(text="Caps:")
row = sub.row()
row.itemR(curve, "front")
@@ -96,29 +96,30 @@ class DATA_PT_shape_curve(DataButtonsPanel):
# col.itemL(text="NORMALS")
# col.itemR(curve, "vertex_normal_flip")
-class DATA_PT_geometry_curve(DataButtonsPanelCurve):
- __label__ = "Geometry "
+class DATA_PT_geometry_curve(DataButtonsPanel):
+ __label__ = "Geometry"
def draw(self, context):
layout = self.layout
curve = context.curve
-
+
split = layout.split()
col = split.column()
col.itemL(text="Modification:")
col.itemR(curve, "width")
col.itemR(curve, "extrude")
- col.itemR(curve, "taper_object", icon='ICON_OUTLINER_OB_CURVE')
+ col.itemL(text="Taper Object:")
+ col.itemR(curve, "taper_object", text="")
col = split.column()
col.itemL(text="Bevel:")
col.itemR(curve, "bevel_depth", text="Depth")
col.itemR(curve, "bevel_resolution", text="Resolution")
- col.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE')
+ col.itemL(text="Bevel Object:")
+ col.itemR(curve, "bevel_object", text="")
-
class DATA_PT_pathanim(DataButtonsPanelCurve):
__label__ = "Path Animation"
@@ -208,7 +209,7 @@ class DATA_PT_active_spline(DataButtonsPanelActive):
if not is_surf:
split = layout.split()
col = split.column()
- col.active = (not curve.curve_2d)
+ col.active = (curve.dimensions=='3D')
col.itemL(text="Interpolation:")
col.itemR(act_spline, "tilt_interpolation", text="Tilt")
diff --git a/release/ui/buttons_data_empty.py b/release/scripts/ui/buttons_data_empty.py
index c07f3136fae..c07f3136fae 100644
--- a/release/ui/buttons_data_empty.py
+++ b/release/scripts/ui/buttons_data_empty.py
diff --git a/release/ui/buttons_data_lamp.py b/release/scripts/ui/buttons_data_lamp.py
index 808a205b1b8..86ca5beb9b5 100644
--- a/release/ui/buttons_data_lamp.py
+++ b/release/scripts/ui/buttons_data_lamp.py
@@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel):
__context__ = "data"
def poll(self, context):
- return (context.lamp)
+ return context.lamp
class DATA_PT_preview(DataButtonsPanel):
__label__ = "Preview"
@@ -75,7 +75,7 @@ class DATA_PT_lamp(DataButtonsPanel):
col.itemR(lamp, "diffuse")
class DATA_PT_sunsky(DataButtonsPanel):
- __label__ = "Sun/Sky"
+ __label__ = "Sky & Atmosphere"
def poll(self, context):
lamp = context.lamp
@@ -86,10 +86,8 @@ class DATA_PT_sunsky(DataButtonsPanel):
lamp = context.lamp.sky
- row = layout.row()
- row.itemR(lamp, "sky")
- row.itemR(lamp, "atmosphere")
-
+ layout.itemR(lamp, "sky")
+
row = layout.row()
row.active = lamp.sky or lamp.atmosphere
row.itemR(lamp, "atmosphere_turbidity", text="Turbidity")
@@ -98,38 +96,39 @@ class DATA_PT_sunsky(DataButtonsPanel):
col = split.column()
col.active = lamp.sky
- col.itemL(text="Blend Mode:")
- sub = col.column(align=True)
+ col.itemL(text="Blending:")
+ sub = col.column()
sub.itemR(lamp, "sky_blend_type", text="")
sub.itemR(lamp, "sky_blend", text="Factor")
col.itemL(text="Color Space:")
- sub = col.column(align=True)
- sub.itemR(lamp, "sky_color_space", text="")
+ sub = col.column()
+ sub.row().itemR(lamp, "sky_color_space", expand=True)
sub.itemR(lamp, "sky_exposure", text="Exposure")
col = split.column()
col.active = lamp.sky
col.itemL(text="Horizon:")
- sub = col.column(align=True)
+ sub = col.column()
sub.itemR(lamp, "horizon_brightness", text="Brightness")
sub.itemR(lamp, "spread", text="Spread")
col.itemL(text="Sun:")
- sub = col.column(align=True)
+ sub = col.column()
sub.itemR(lamp, "sun_brightness", text="Brightness")
sub.itemR(lamp, "sun_size", text="Size")
sub.itemR(lamp, "backscattered_light", slider=True,text="Back Light")
layout.itemS()
+ layout.itemR(lamp, "atmosphere")
+
split = layout.split()
col = split.column()
col.active = lamp.atmosphere
- col.itemL(text="Sun:")
- col.itemR(lamp, "sun_intensity", text="Intensity")
- col.itemL(text="Scale Distance:")
+ col.itemL(text="Intensity:")
+ col.itemR(lamp, "sun_intensity", text="Sun")
col.itemR(lamp, "atmosphere_distance_factor", text="Distance")
col = split.column()
@@ -198,7 +197,7 @@ class DATA_PT_shadow(DataButtonsPanel):
sub.itemR(lamp, "dither")
sub.itemR(lamp, "jitter")
- if lamp.shadow_method == 'BUFFER_SHADOW':
+ elif lamp.shadow_method == 'BUFFER_SHADOW':
col = layout.column()
col.itemL(text="Buffer Type:")
col.row().itemR(lamp, "shadow_buffer_type", expand=True)
@@ -258,8 +257,6 @@ class DATA_PT_area(DataButtonsPanel):
elif (lamp.shape == 'RECTANGLE'):
sub.itemR(lamp, "size", text="Size X")
sub.itemR(lamp, "size_y", text="Size Y")
-
- col = split.column()
class DATA_PT_spot(DataButtonsPanel):
__label__ = "Spot Shape"
@@ -301,7 +298,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel):
def draw(self, context):
lamp = context.lamp
- self.layout.template_curve_mapping(lamp.falloff_curve)
+ self.layout.template_curve_mapping(lamp, "falloff_curve")
bpy.types.register(DATA_PT_context_lamp)
bpy.types.register(DATA_PT_preview)
diff --git a/release/ui/buttons_data_lattice.py b/release/scripts/ui/buttons_data_lattice.py
index 895c1a65bea..bc977860330 100644
--- a/release/ui/buttons_data_lattice.py
+++ b/release/scripts/ui/buttons_data_lattice.py
@@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel):
__context__ = "data"
def poll(self, context):
- return (context.lattice)
+ return context.lattice
class DATA_PT_context_lattice(DataButtonsPanel):
__show_header__ = False
diff --git a/release/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py
index 33b3960b381..780ae3ac8f9 100644
--- a/release/ui/buttons_data_mesh.py
+++ b/release/scripts/ui/buttons_data_mesh.py
@@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel):
__context__ = "data"
def poll(self, context):
- return (context.mesh)
+ return context.mesh
class DATA_PT_context_mesh(DataButtonsPanel):
__show_header__ = False
@@ -60,15 +60,15 @@ class DATA_PT_vertex_groups(DataButtonsPanel):
ob = context.object
row = layout.row()
- row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index")
+ row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=2)
col = row.column(align=True)
col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="")
col.itemO("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="")
- col.itemO("object.vertex_group_copy", icon='ICON_BLANK1', text="")
+ col.itemO("object.vertex_group_copy", icon='ICON_COPYDOWN', text="")
if ob.data.users > 1:
- col.itemO("object.vertex_group_copy_to_linked", icon='ICON_BLANK1', text="")
+ col.itemO("object.vertex_group_copy_to_linked", icon='ICON_COPYDOWN', text="")
group = ob.active_vertex_group
if group:
diff --git a/release/ui/buttons_data_metaball.py b/release/scripts/ui/buttons_data_metaball.py
index 88c0066c67f..757546fdf8a 100644
--- a/release/ui/buttons_data_metaball.py
+++ b/release/scripts/ui/buttons_data_metaball.py
@@ -6,7 +6,7 @@ class DataButtonsPanel(bpy.types.Panel):
__context__ = "data"
def poll(self, context):
- return (context.meta_ball)
+ return context.meta_ball
class DATA_PT_context_metaball(DataButtonsPanel):
__show_header__ = False
@@ -74,11 +74,9 @@ class DATA_PT_metaball_element(DataButtonsPanel):
col.itemR(metaelem, "hide", text="Hide")
if metaelem.type == 'BALL':
-
col = split.column(align=True)
elif metaelem.type == 'CUBE':
-
col = split.column(align=True)
col.itemL(text="Size:")
col.itemR(metaelem, "size_x", text="X")
@@ -86,26 +84,22 @@ class DATA_PT_metaball_element(DataButtonsPanel):
col.itemR(metaelem, "size_z", text="Z")
elif metaelem.type == 'TUBE':
-
col = split.column(align=True)
col.itemL(text="Size:")
col.itemR(metaelem, "size_x", text="X")
elif metaelem.type == 'PLANE':
-
col = split.column(align=True)
col.itemL(text="Size:")
col.itemR(metaelem, "size_x", text="X")
col.itemR(metaelem, "size_y", text="Y")
elif metaelem.type == 'ELLIPSOID':
-
col = split.column(align=True)
col.itemL(text="Size:")
col.itemR(metaelem, "size_x", text="X")
col.itemR(metaelem, "size_y", text="Y")
col.itemR(metaelem, "size_z", text="Z")
-
bpy.types.register(DATA_PT_context_metaball)
bpy.types.register(DATA_PT_metaball)
diff --git a/release/ui/buttons_data_modifier.py b/release/scripts/ui/buttons_data_modifier.py
index 754e8ce106e..754e8ce106e 100644
--- a/release/ui/buttons_data_modifier.py
+++ b/release/scripts/ui/buttons_data_modifier.py
diff --git a/release/ui/buttons_data_text.py b/release/scripts/ui/buttons_data_text.py
index d0e7ea09a92..0d46d5f8a0d 100644
--- a/release/ui/buttons_data_text.py
+++ b/release/scripts/ui/buttons_data_text.py
@@ -36,9 +36,7 @@ class DATA_PT_shape_text(DataButtonsPanel):
ob = context.object
curve = context.curve
- space = context.space_data
-
- layout.itemR(curve, "curve_2d")
+ space = context.space_data
split = layout.split()
@@ -55,8 +53,8 @@ class DATA_PT_shape_text(DataButtonsPanel):
col = split.column()
col.itemL(text="Resolution:")
sub = col.column(align=True)
- sub.itemR(curve, "resolution_u", text="Preview U")
- sub.itemR(curve, "render_resolution_u", text="Render U")
+ sub.itemR(curve, "resolution_u", text="Preview")
+ sub.itemR(curve, "render_resolution_u", text="Render")
# resolution_v is not used for text
@@ -127,7 +125,6 @@ class DATA_PT_font(DataButtonsPanel):
col.itemL(text="Underline:")
col.itemR(text, "ul_position", text="Position")
col.itemR(text, "ul_height", text="Thickness")
-
class DATA_PT_paragraph(DataButtonsPanel):
__label__ = "Paragraph"
@@ -153,7 +150,6 @@ class DATA_PT_paragraph(DataButtonsPanel):
col.itemR(text, "offset_x", text="X")
col.itemR(text, "offset_y", text="Y")
-
class DATA_PT_textboxes(DataButtonsPanel):
__label__ = "Text Boxes"
diff --git a/release/ui/buttons_game.py b/release/scripts/ui/buttons_game.py
index 73ba566e23f..5f5d4f916d0 100644
--- a/release/ui/buttons_game.py
+++ b/release/scripts/ui/buttons_game.py
@@ -26,7 +26,6 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
#if game.physics_type == 'DYNAMIC':
if game.physics_type in ('DYNAMIC', 'RIGID_BODY'):
-
split = layout.split()
col = split.column()
@@ -88,7 +87,6 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
col.itemR(game, "lock_z_rot_axis", text="Z")
elif game.physics_type == 'SOFT_BODY':
-
col = layout.column()
col.itemR(game, "actor")
col.itemR(game, "ghost")
@@ -124,14 +122,12 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
sub.itemR(soft, "cluster_iterations", text="Iterations")
elif game.physics_type == 'STATIC':
-
col = layout.column()
col.itemR(game, "actor")
col.itemR(game, "ghost")
col.itemR(ob, "restrict_render", text="Invisible")
elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'):
-
layout.itemR(ob, "restrict_render", text="Invisible")
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel):
@@ -304,12 +300,25 @@ class SCENE_PT_game_performance(SceneButtonsPanel):
col.itemL(text="Render:")
col.itemR(gs, "all_frames")
col.itemR(gs, "display_lists")
+
+class SCENE_PT_game_sound(SceneButtonsPanel):
+ __label__ = "Sound"
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+
+ layout.itemR(scene, "distance_model")
+ layout.itemR(scene, "speed_of_sound", text="Speed")
+ layout.itemR(scene, "doppler_factor")
bpy.types.register(SCENE_PT_game)
bpy.types.register(SCENE_PT_game_player)
bpy.types.register(SCENE_PT_game_stereo)
bpy.types.register(SCENE_PT_game_shading)
bpy.types.register(SCENE_PT_game_performance)
+bpy.types.register(SCENE_PT_game_sound)
class WorldButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
diff --git a/release/ui/buttons_material.py b/release/scripts/ui/buttons_material.py
index dc11731d7a9..ee7193da301 100644
--- a/release/ui/buttons_material.py
+++ b/release/scripts/ui/buttons_material.py
@@ -28,7 +28,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel):
# this manages materials for all engine types
engine = context.scene.render_data.engine
- return (context.object) and (engine in self.COMPAT_ENGINES)
+ return (context.material or context.object) and (engine in self.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
@@ -65,8 +65,9 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel):
elif mat:
split.template_ID(space, "pin_id")
split.itemS()
-
- layout.itemR(mat, "type", expand=True)
+
+ if mat:
+ layout.itemR(mat, "type", expand=True)
class MATERIAL_PT_shading(MaterialButtonsPanel):
__label__ = "Shading"
@@ -282,7 +283,7 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel):
if mat.use_diffuse_ramp:
layout.itemS()
- layout.template_color_ramp(mat.diffuse_ramp, expand=True)
+ layout.template_color_ramp(mat, "diffuse_ramp", expand=True)
layout.itemS()
row = layout.row()
split = row.split(percentage=0.3)
@@ -334,7 +335,7 @@ class MATERIAL_PT_specular(MaterialButtonsPanel):
if mat.use_specular_ramp:
layout.itemS()
- layout.template_color_ramp(mat.specular_ramp, expand=True)
+ layout.template_color_ramp(mat, "specular_ramp", expand=True)
layout.itemS()
row = layout.row()
split = row.split(percentage=0.3)
@@ -355,8 +356,8 @@ class MATERIAL_PT_sss(MaterialButtonsPanel):
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
- sss = context.material.subsurface_scattering
mat = context.material
+ sss = mat.subsurface_scattering
self.layout.active = (not mat.shadeless)
self.layout.itemR(sss, "enabled", text="")
@@ -365,7 +366,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel):
layout = self.layout
mat = context.material
- sss = context.material.subsurface_scattering
+ sss = mat.subsurface_scattering
layout.active = sss.enabled
@@ -408,7 +409,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel):
layout = self.layout
mat = context.material
- raym = context.material.raytrace_mirror
+ raym = mat.raytrace_mirror
layout.active = raym.enabled
@@ -456,13 +457,14 @@ class MATERIAL_PT_transp(MaterialButtonsPanel):
def draw_header(self, context):
mat = context.material
+
self.layout.itemR(mat, "transparency", text="")
def draw(self, context):
layout = self.layout
mat = context.material
- rayt = context.material.raytrace_transparency
+ rayt = mat.raytrace_transparency
row = layout.row()
row.active = mat.transparency and (not mat.shadeless)
@@ -560,11 +562,9 @@ class MATERIAL_PT_flare(MaterialButtonsPanel):
return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
def draw_header(self, context):
- layout = self.layout
-
- mat = context.material
- halo = mat.halo
- layout.itemR(halo, "flare_mode", text="")
+ halo = context.material.halo
+
+ self.layout.itemR(halo, "flare_mode", text="")
def draw(self, context):
layout = self.layout
@@ -609,9 +609,9 @@ class VolumeButtonsPanel(bpy.types.Panel):
mat = context.material
engine = context.scene.render_data.engine
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
-
-class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
- __label__ = "Shading"
+
+class MATERIAL_PT_volume_density(VolumeButtonsPanel):
+ __label__ = "Density"
__default_closed__ = False
COMPAT_ENGINES = set(['BLENDER_RENDER'])
@@ -621,22 +621,39 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
mat = context.material
vol = context.material.volume
- row = layout.row()
+ split = layout.split()
+ row = split.row()
row.itemR(vol, "density")
- row.itemR(vol, "scattering")
+ row.itemR(vol, "density_scale")
+
+
+class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
+ __label__ = "Shading"
+ __default_closed__ = False
+ COMPAT_ENGINES = set(['BLENDER_RENDER'])
+ def draw(self, context):
+ layout = self.layout
+
+ vol = context.material.volume
+
split = layout.split()
col = split.column()
- col.itemR(vol, "absorption")
- col.itemR(vol, "absorption_color", text="")
-
+ col.itemR(vol, "scattering")
+ col.itemR(vol, "asymmetry")
+ col.itemR(vol, "transmission_color")
+
col = split.column()
- col.itemR(vol, "emission")
- col.itemR(vol, "emission_color", text="")
+ sub = col.column(align=True)
+ sub.itemR(vol, "emission")
+ sub.itemR(vol, "emission_color", text="")
+ sub = col.column(align=True)
+ sub.itemR(vol, "reflection")
+ sub.itemR(vol, "reflection_color", text="")
-class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
- __label__ = "Scattering"
+class MATERIAL_PT_volume_lighting(VolumeButtonsPanel):
+ __label__ = "Lighting"
__default_closed__ = False
COMPAT_ENGINES = set(['BLENDER_RENDER'])
@@ -649,24 +666,26 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
col = split.column()
col.itemR(vol, "scattering_mode", text="")
+
+ col = split.column()
+
if vol.scattering_mode == 'SINGLE_SCATTERING':
col.itemR(vol, "light_cache")
sub = col.column()
sub.active = vol.light_cache
sub.itemR(vol, "cache_resolution")
elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'):
+ sub = col.column()
+ sub.enabled = True
+ sub.active = False
+ sub.itemR(vol, "light_cache")
col.itemR(vol, "cache_resolution")
- col = col.column(align=True)
- col.itemR(vol, "ms_diffusion")
- col.itemR(vol, "ms_spread")
- col.itemR(vol, "ms_intensity")
-
- col = split.column()
- # col.itemL(text="Anisotropic Scattering:")
- col.itemR(vol, "phase_function", text="")
- if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
- col.itemR(vol, "asymmetry")
+ sub = col.column(align=True)
+ sub.itemR(vol, "ms_diffusion")
+ sub.itemR(vol, "ms_spread")
+ sub.itemR(vol, "ms_intensity")
+
class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
__label__= "Transparency"
@@ -676,11 +695,8 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
layout = self.layout
mat = context.material
- rayt = context.material.raytrace_transparency
- row= layout.row()
- row.itemR(mat, "transparency_method", expand=True)
- row.active = mat.transparency and (not mat.shadeless)
+ layout.itemR(mat, "transparency_method", expand=True)
class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
__label__ = "Integration"
@@ -689,8 +705,7 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
def draw(self, context):
layout = self.layout
-
- mat = context.material
+
vol = context.material.volume
split = layout.split()
@@ -700,14 +715,13 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
col.itemR(vol, "step_calculation", text="")
col = col.column(align=True)
col.itemR(vol, "step_size")
- col.itemR(vol, "shading_step_size")
col = split.column()
col.itemL()
col.itemR(vol, "depth_cutoff")
- col.itemR(vol, "density_scale")
+bpy.types.register(MATERIAL_PT_volume_density)
bpy.types.register(MATERIAL_PT_volume_shading)
-bpy.types.register(MATERIAL_PT_volume_scattering)
+bpy.types.register(MATERIAL_PT_volume_lighting)
bpy.types.register(MATERIAL_PT_volume_transp)
bpy.types.register(MATERIAL_PT_volume_integration)
diff --git a/release/ui/buttons_object.py b/release/scripts/ui/buttons_object.py
index af2c7cfb58a..c069572aa28 100644
--- a/release/ui/buttons_object.py
+++ b/release/scripts/ui/buttons_object.py
@@ -25,11 +25,48 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
layout = self.layout
ob = context.object
+
+ layout.itemR(ob, "rotation_mode")
row = layout.row()
+
row.column().itemR(ob, "location")
- row.column().itemR(ob, "rotation")
+ if ob.rotation_mode == 'QUATERNION':
+ row.column().itemR(ob, "rotation_quaternion", text="Rotation")
+ elif ob.rotation_mode == 'AXIS_ANGLE':
+ #row.column().itemL(text="Rotation")
+ #row.column().itemR(pchan, "rotation_angle", text="Angle")
+ #row.column().itemR(pchan, "rotation_axis", text="Axis")
+ row.column().itemR(ob, "rotation_axis_angle", text="Rotation")
+ else:
+ row.column().itemR(ob, "rotation_euler", text="Rotation")
+
row.column().itemR(ob, "scale")
+
+class OBJECT_PT_transform_locks(ObjectButtonsPanel):
+ __label__ = "Transform Locks"
+ __default_closed__ = True
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+
+ row = layout.row()
+
+ col = row.column()
+ col.itemR(ob, "lock_location")
+
+ col = row.column()
+ if ob.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
+ col.itemR(ob, "lock_rotations_4d", text="Lock Rotation")
+ if ob.lock_rotations_4d:
+ col.itemR(ob, "lock_rotation_w", text="W")
+ col.itemR(ob, "lock_rotation", text="")
+ else:
+ col.itemR(ob, "lock_rotation", text="Rotation")
+
+ row.column().itemR(ob, "lock_scale")
class OBJECT_PT_relations(ObjectButtonsPanel):
__label__ = "Relations"
@@ -92,10 +129,14 @@ class OBJECT_PT_display(ObjectButtonsPanel):
layout = self.layout
ob = context.object
-
- row = layout.row()
- row.itemR(ob, "max_draw_type", text="Type")
- row.itemR(ob, "draw_bounds_type", text="Bounds")
+
+ split = layout.split()
+ col = split.column()
+ col.itemR(ob, "max_draw_type", text="Type")
+ col = split.column()
+ row = col.row()
+ row.itemR(ob, "draw_bounds", text="Bounds")
+ row.itemR(ob, "draw_bounds_type", text="")
flow = layout.column_flow()
flow.itemR(ob, "draw_name", text="Name")
@@ -174,6 +215,7 @@ class OBJECT_PT_animation(ObjectButtonsPanel):
bpy.types.register(OBJECT_PT_context_object)
bpy.types.register(OBJECT_PT_transform)
+bpy.types.register(OBJECT_PT_transform_locks)
bpy.types.register(OBJECT_PT_relations)
bpy.types.register(OBJECT_PT_groups)
bpy.types.register(OBJECT_PT_display)
diff --git a/release/ui/buttons_object_constraint.py b/release/scripts/ui/buttons_object_constraint.py
index c8f7e467a18..e089cff264f 100644
--- a/release/ui/buttons_object_constraint.py
+++ b/release/scripts/ui/buttons_object_constraint.py
@@ -6,14 +6,14 @@ class ConstraintButtonsPanel(bpy.types.Panel):
__region_type__ = 'WINDOW'
__context__ = "constraint"
- def draw_constraint(self, con):
+ def draw_constraint(self, context, con):
layout = self.layout
box = layout.template_constraint(con)
if box:
# match enum type to our functions, avoids a lookup table.
- getattr(self, con.type)(box, con)
+ getattr(self, con.type)(context, box, con)
# show/key buttons here are most likely obsolete now, with
# keyframing functionality being part of every button
@@ -48,8 +48,28 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemR(con, "head_tail", text="")
elif con.target.type in ('MESH', 'LATTICE'):
layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
+
+ def ik_template(self, layout, con):
+ layout.itemR(con, "pole_target")
- def CHILD_OF(self, layout, con):
+ if con.pole_target and con.pole_target.type == 'ARMATURE':
+ layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
+
+ if con.pole_target:
+ row = layout.row()
+ row.itemL()
+ row.itemR(con, "pole_angle")
+
+ split = layout.split()
+ col = split.column()
+ col.itemR(con, "tail")
+ col.itemR(con, "stretch")
+
+ col = split.column()
+ col.itemR(con, "iterations")
+ col.itemR(con, "chain_length")
+
+ def CHILD_OF(self, context, layout, con):
self.target_template(layout, con)
split = layout.split()
@@ -76,7 +96,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemO("constraint.childof_set_inverse")
row.itemO("constraint.childof_clear_inverse")
- def TRACK_TO(self, layout, con):
+ def TRACK_TO(self, context, layout, con):
self.target_template(layout, con)
row = layout.row()
@@ -90,35 +110,40 @@ class ConstraintButtonsPanel(bpy.types.Panel):
self.space_template(layout, con)
- def IK(self, layout, con):
+ def IK(self, context, layout, con):
+ if context.object.pose.ik_solver == "ITASC":
+ layout.itemR(con, "ik_type")
+ getattr(self, "IK_"+con.ik_type)(context, layout, con)
+ else:
+ self.IK_COPY_POSE(context, layout, con)
+
+ def IK_COPY_POSE(self, context, layout, con):
self.target_template(layout, con)
-
- layout.itemR(con, "pole_target")
-
- if con.pole_target and con.pole_target.type == 'ARMATURE':
- layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
-
+ self.ik_template(layout, con)
+
split = layout.split()
-
col = split.column()
- col.itemR(con, "iterations")
- col.itemR(con, "chain_length")
- sub = col.column()
- sub.active = con.pole_target
- sub.itemR(con, "pole_angle")
+ col.itemL()
+ col.itemR(con, "targetless")
+ col.itemR(con, "rotation")
+
+ col = split.column()
col.itemL(text="Weight:")
col.itemR(con, "weight", text="Position", slider=True)
sub = col.column()
sub.active = con.rotation
sub.itemR(con, "orient_weight", text="Rotation", slider=True)
- col = split.column()
- col.itemR(con, "tail")
- col.itemR(con, "rotation")
- col.itemR(con, "targetless")
- col.itemR(con, "stretch")
-
- def FOLLOW_PATH(self, layout, con):
+ def IK_DISTANCE(self, context, layout, con):
+ self.target_template(layout, con)
+ self.ik_template(layout, con)
+
+ layout.itemR(con, "limit_mode")
+ row = layout.row()
+ row.itemR(con, "weight", text="Weight", slider=True)
+ row.itemR(con, "distance", text="Distance", slider=True)
+
+ def FOLLOW_PATH(self, context, layout, con):
self.target_template(layout, con)
split = layout.split()
@@ -130,7 +155,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
col = split.column()
col.itemR(con, "use_fixed_position")
if con.use_fixed_position:
- col.itemR(con, "offset_percentage", text="Offset")
+ col.itemR(con, "offset_factor", text="Offset")
else:
col.itemR(con, "offset")
@@ -142,7 +167,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemR(con, "up", text="Up")
row.itemL()
- def LIMIT_ROTATION(self, layout, con):
+ def LIMIT_ROTATION(self, context, layout, con):
split = layout.split()
@@ -175,7 +200,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Convert:")
row.itemR(con, "owner_space", text="")
- def LIMIT_LOCATION(self, layout, con):
+ def LIMIT_LOCATION(self, context, layout, con):
split = layout.split()
col = split.column()
@@ -216,7 +241,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Convert:")
row.itemR(con, "owner_space", text="")
- def LIMIT_SCALE(self, layout, con):
+ def LIMIT_SCALE(self, context, layout, con):
split = layout.split()
col = split.column()
@@ -257,7 +282,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Convert:")
row.itemR(con, "owner_space", text="")
- def COPY_ROTATION(self, layout, con):
+ def COPY_ROTATION(self, context, layout, con):
self.target_template(layout, con)
split = layout.split()
@@ -284,7 +309,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
self.space_template(layout, con)
- def COPY_LOCATION(self, layout, con):
+ def COPY_LOCATION(self, context, layout, con):
self.target_template(layout, con)
split = layout.split()
@@ -311,7 +336,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
self.space_template(layout, con)
- def COPY_SCALE(self, layout, con):
+ def COPY_SCALE(self, context, layout, con):
self.target_template(layout, con)
row = layout.row(align=True)
@@ -323,9 +348,9 @@ class ConstraintButtonsPanel(bpy.types.Panel):
self.space_template(layout, con)
- #def SCRIPT(self, layout, con):
+ #def SCRIPT(self, context, layout, con):
- def ACTION(self, layout, con):
+ def ACTION(self, context, layout, con):
self.target_template(layout, con)
layout.itemR(con, "action")
@@ -345,7 +370,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Convert:")
row.itemR(con, "owner_space", text="")
- def LOCKED_TRACK(self, layout, con):
+ def LOCKED_TRACK(self, context, layout, con):
self.target_template(layout, con)
row = layout.row()
@@ -356,7 +381,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Lock:")
row.itemR(con, "locked", expand=True)
- def LIMIT_DISTANCE(self, layout, con):
+ def LIMIT_DISTANCE(self, context, layout, con):
self.target_template(layout, con)
col = layout.column(align=True);
@@ -367,7 +392,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Clamp Region:")
row.itemR(con, "limit_mode", text="")
- def STRETCH_TO(self, layout, con):
+ def STRETCH_TO(self, context, layout, con):
self.target_template(layout, con)
row = layout.row()
@@ -383,7 +408,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Plane:")
row.itemR(con, "keep_axis", expand=True)
- def FLOOR(self, layout, con):
+ def FLOOR(self, context, layout, con):
self.target_template(layout, con)
row = layout.row()
@@ -396,7 +421,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row.itemL(text="Min/Max:")
row.itemR(con, "floor_location", expand=True)
- def RIGID_BODY_JOINT(self, layout, con):
+ def RIGID_BODY_JOINT(self, context, layout, con):
self.target_template(layout, con)
layout.itemR(con, "pivot_type")
@@ -422,7 +447,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
#Missing: Limit arrays (not wrapped in RNA yet)
- def CLAMP_TO(self, layout, con):
+ def CLAMP_TO(self, context, layout, con):
self.target_template(layout, con)
row = layout.row()
@@ -432,7 +457,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
row = layout.row()
row.itemR(con, "cyclic")
- def TRANSFORM(self, layout, con):
+ def TRANSFORM(self, context, layout, con):
self.target_template(layout, con)
layout.itemR(con, "extrapolate_motion", text="Extrapolate")
@@ -481,7 +506,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
self.space_template(layout, con)
- def SHRINKWRAP (self, layout, con):
+ def SHRINKWRAP (self, context, layout, con):
self.target_template(layout, con)
layout.itemR(con, "distance")
@@ -509,11 +534,11 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
row.itemL();
for con in ob.constraints:
- self.draw_constraint(con)
+ self.draw_constraint(context, con)
class BONE_PT_constraints(ConstraintButtonsPanel):
__label__ = "Constraints"
- __context__ = "bone"
+ __context__ = "bone_constraint"
def poll(self, context):
ob = context.object
@@ -530,7 +555,7 @@ class BONE_PT_constraints(ConstraintButtonsPanel):
row.itemL();
for con in pchan.constraints:
- self.draw_constraint(con)
+ self.draw_constraint(context, con)
bpy.types.register(OBJECT_PT_constraints)
bpy.types.register(BONE_PT_constraints)
diff --git a/release/ui/buttons_particle.py b/release/scripts/ui/buttons_particle.py
index 1d496e19121..1a800fc4dfd 100644
--- a/release/ui/buttons_particle.py
+++ b/release/scripts/ui/buttons_particle.py
@@ -1,6 +1,11 @@
import bpy
+from buttons_physics_common import point_cache_ui
+from buttons_physics_common import effector_weights_ui
+from buttons_physics_common import basic_force_field_settings_ui
+from buttons_physics_common import basic_force_field_falloff_ui
+
def particle_panel_enabled(psys):
return psys.point_cache.baked==False and psys.edited==False
@@ -10,71 +15,6 @@ def particle_panel_poll(context):
if psys.settings==None: return False
return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
-def point_cache_ui(self, cache, enabled, particles, smoke):
- layout = self.layout
- layout.set_context_pointer("PointCache", cache)
-
- row = layout.row()
- row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
- col = row.column(align=True)
- col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
- col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
-
- row = layout.row()
- row.itemL(text="File Name:")
- if particles:
- row.itemR(cache, "external")
-
- if cache.external:
- split = layout.split(percentage=0.80)
- split.itemR(cache, "name", text="")
- split.itemR(cache, "index", text="")
-
- layout.itemL(text="File Path:")
- layout.itemR(cache, "filepath", text="")
-
- layout.itemL(text=cache.info)
- else:
- layout.itemR(cache, "name", text="")
-
- if not particles:
- row = layout.row()
- row.enabled = enabled
- row.itemR(cache, "start_frame")
- row.itemR(cache, "end_frame")
-
- row = layout.row()
-
- if cache.baked == True:
- row.itemO("ptcache.free_bake", text="Free Bake")
- else:
- row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
-
- sub = row.row()
- sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
- sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
-
- row = layout.row()
- row.enabled = enabled
- row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
- row.itemR(cache, "step");
-
- if not smoke:
- row = layout.row()
- sub = row.row()
- sub.enabled = enabled
- sub.itemR(cache, "quick_cache")
- row.itemR(cache, "disk_cache")
-
- layout.itemL(text=cache.info)
-
- layout.itemS()
-
- row = layout.row()
- row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
- row.itemO("ptcache.free_bake_all", text="Free All Bakes")
- layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
-
class ParticleButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
@@ -244,22 +184,22 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
split = layout.split()
col = split.column()
- col.itemL(text="Quality:")
- col.itemR(cloth, "quality", text="Steps",slider=True)
- col.itemL(text="Gravity:")
- col.itemR(cloth, "gravity", text="")
-
- col = split.column()
col.itemL(text="Material:")
sub = col.column(align=True)
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
sub.itemR(cloth, "mass")
+ sub.itemR(cloth, "bending_stiffness", text="Bending")
+ sub.itemR(cloth, "internal_friction", slider="True")
+
+ col = split.column()
+
col.itemL(text="Damping:")
sub = col.column(align=True)
sub.itemR(cloth, "spring_damping", text="Spring")
sub.itemR(cloth, "air_damping", text="Air")
- layout.itemR(cloth, "internal_friction", slider="True")
+ col.itemL(text="Quality:")
+ col.itemR(cloth, "quality", text="Steps",slider=True)
class PARTICLE_PT_cache(ParticleButtonsPanel):
__label__ = "Cache"
@@ -383,9 +323,11 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
sub.itemR(part, "brownian_factor")
sub.itemR(part, "drag_factor", slider=True)
sub.itemR(part, "damp_factor", slider=True)
- sub.itemR(part, "integrator")
sub = split.column()
- sub.itemR(part, "acceleration")
+ sub.itemR(part, "size_deflect")
+ sub.itemR(part, "die_on_collision")
+ sub.itemR(part, "integrator")
+ sub.itemR(part, "time_tweak")
elif part.physics_type == 'KEYED':
split = layout.split()
@@ -443,14 +385,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
col = row.column()
col.itemL(text="Misc:")
- col.itemR(part, "gravity")
col.itemR(boids, "banking", slider=True)
col.itemR(boids, "height", slider=True)
- if part.physics_type=='NEWTON':
- sub.itemR(part, "size_deflect")
- sub.itemR(part, "die_on_collision")
- elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
+ if part.physics_type=='KEYED' or part.physics_type=='BOIDS':
if part.physics_type=='BOIDS':
layout.itemL(text="Relations:")
@@ -503,18 +441,18 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
boids = context.particle_system.settings.boids
layout = self.layout
- layout.enabled = particle_panel_enabled(psys)
+ layout.enabled = particle_panel_enabled(context.particle_system)
# 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")
#col = row.row()
#subrow = col.row(align=True)
- #subrow.itemO("boid.boidstate_add", icon='ICON_ZOOMIN', text="")
- #subrow.itemO("boid.boidstate_del", icon='ICON_ZOOMOUT', text="")
+ #subrow.itemO("boid.state_add", icon='ICON_ZOOMIN', text="")
+ #subrow.itemO("boid.state_del", icon='ICON_ZOOMOUT', text="")
#subrow = row.row(align=True)
- #subrow.itemO("boid.boidstate_move_up", icon='VICON_MOVE_UP', text="")
- #subrow.itemO("boid.boidstate_move_down", icon='VICON_MOVE_DOWN', text="")
+ #subrow.itemO("boid.state_move_up", icon='VICON_MOVE_UP', text="")
+ #subrow.itemO("boid.state_move_down", icon='VICON_MOVE_DOWN', text="")
state = boids.active_boid_state
@@ -533,12 +471,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
col = row.column()
subrow = col.row()
subcol = subrow.column(align=True)
- subcol.item_menu_enumO("boid.boidrule_add", "type", icon='ICON_ZOOMIN', text="")
- subcol.itemO("boid.boidrule_del", icon='ICON_ZOOMOUT', text="")
+ subcol.item_menu_enumO("boid.rule_add", "type", icon='ICON_ZOOMIN', text="")
+ subcol.itemO("boid.rule_del", icon='ICON_ZOOMOUT', text="")
subrow = col.row()
subcol = subrow.column(align=True)
- subcol.itemO("boid.boidrule_move_up", icon='VICON_MOVE_UP', text="")
- subcol.itemO("boid.boidrule_move_down", icon='VICON_MOVE_DOWN', text="")
+ subcol.itemO("boid.rule_move_up", icon='VICON_MOVE_UP', text="")
+ subcol.itemO("boid.rule_move_down", icon='VICON_MOVE_DOWN', text="")
rule = state.active_boid_rule
@@ -855,30 +793,41 @@ class PARTICLE_PT_children(ParticleButtonsPanel):
sub = split.column()
sub.itemR(part, "kink_shape", slider=True)
-class PARTICLE_PT_effectors(ParticleButtonsPanel):
- __label__ = "Effectors"
+class PARTICLE_PT_field_weights(ParticleButtonsPanel):
+ __label__ = "Field Weights"
+ __default_closed__ = True
+
+ def draw(self, context):
+ part = context.particle_system.settings
+ effector_weights_ui(self, part.effector_weights)
+
+ if part.type == 'HAIR':
+ self.layout.itemR(part.effector_weights, "do_growing_hair")
+
+class PARTICLE_PT_force_fields(ParticleButtonsPanel):
+ __label__ = "Force Field Settings"
__default_closed__ = True
def draw(self, context):
layout = self.layout
-
- psys = context.particle_system
- part = psys.settings
+ part = context.particle_system.settings
- layout.itemR(part, "effector_group")
+ layout.itemR(part, "self_effect")
- layout.itemR(part, "eweight_all", slider=True)
+ split = layout.split(percentage=0.2)
+ split.itemL(text="Type 1:")
+ split.itemR(part.force_field_1, "type",text="")
+ basic_force_field_settings_ui(self, part.force_field_1)
+ basic_force_field_falloff_ui(self, part.force_field_1)
- layout.itemS()
- layout.itemR(part, "eweight_spherical", slider=True)
- layout.itemR(part, "eweight_vortex", slider=True)
- layout.itemR(part, "eweight_magnetic", slider=True)
- layout.itemR(part, "eweight_wind", slider=True)
- layout.itemR(part, "eweight_curveguide", slider=True)
- layout.itemR(part, "eweight_texture", slider=True)
- layout.itemR(part, "eweight_harmonic", slider=True)
- layout.itemR(part, "eweight_charge", slider=True)
- layout.itemR(part, "eweight_lennardjones", slider=True)
+ if part.force_field_1.type != 'NONE':
+ layout.itemL(text="")
+
+ split = layout.split(percentage=0.2)
+ split.itemL(text="Type 2:")
+ split.itemR(part.force_field_2, "type",text="")
+ basic_force_field_settings_ui(self, part.force_field_2)
+ basic_force_field_falloff_ui(self, part.force_field_2)
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
__label__ = "Vertexgroups"
@@ -955,5 +904,6 @@ bpy.types.register(PARTICLE_PT_boidbrain)
bpy.types.register(PARTICLE_PT_render)
bpy.types.register(PARTICLE_PT_draw)
bpy.types.register(PARTICLE_PT_children)
-bpy.types.register(PARTICLE_PT_effectors)
+bpy.types.register(PARTICLE_PT_field_weights)
+bpy.types.register(PARTICLE_PT_force_fields)
bpy.types.register(PARTICLE_PT_vertexgroups)
diff --git a/release/ui/buttons_physics_cloth.py b/release/scripts/ui/buttons_physics_cloth.py
index 5cdca3c2c74..e25497b3713 100644
--- a/release/ui/buttons_physics_cloth.py
+++ b/release/scripts/ui/buttons_physics_cloth.py
@@ -1,7 +1,8 @@
import bpy
-from buttons_particle import point_cache_ui
+from buttons_physics_common import point_cache_ui
+from buttons_physics_common import effector_weights_ui
def cloth_panel_enabled(md):
return md.point_cache.baked==False
@@ -49,10 +50,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
split = layout.split()
col = split.column()
- col.itemL(text="Quality:")
- col.itemR(cloth, "quality", text="Steps",slider=True)
- col.itemL(text="Gravity:")
- col.itemR(cloth, "gravity", text="")
+ col.itemL(text="Material:")
+ sub = col.column(align=True)
+ sub.itemR(cloth, "mass")
+ sub.itemR(cloth, "structural_stiffness", text="Structural")
+ sub.itemR(cloth, "bending_stiffness", text="Bending")
col.itemR(cloth, "pin_cloth", text="Pin")
sub = col.column(align=True)
@@ -61,18 +63,18 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
col = split.column()
- col.itemL(text="Presets...")
- col.itemL(text="TODO!")
- col.itemL(text="Material:")
- sub = col.column(align=True)
- sub.itemR(cloth, "mass")
- sub.itemR(cloth, "structural_stiffness", text="Structural")
- sub.itemR(cloth, "bending_stiffness", text="Bending")
+
col.itemL(text="Damping:")
sub = col.column(align=True)
sub.itemR(cloth, "spring_damping", text="Spring")
sub.itemR(cloth, "air_damping", text="Air")
+ col.itemL(text="Presets...")
+ col.itemL(text="TODO!")
+
+ col.itemL(text="Quality:")
+ col.itemR(cloth, "quality", text="Steps",slider=True)
+
# Disabled for now
"""
if cloth.mass_vertex_group:
@@ -89,7 +91,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.cloth)
+ return context.cloth
def draw(self, context):
md = context.cloth
@@ -100,7 +102,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.cloth)
+ return context.cloth
def draw_header(self, context):
cloth = context.cloth.collision_settings
@@ -135,7 +137,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.cloth != None)
+ return context.cloth
def draw_header(self, context):
cloth = context.cloth.settings
@@ -165,8 +167,20 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
sub = col.column(align=True)
sub.itemR(cloth, "bending_stiffness_max", text="Max")
sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
+
+class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel):
+ __label__ = "Cloth Field Weights"
+ __default_closed__ = True
+
+ def poll(self, context):
+ return (context.cloth)
+
+ def draw(self, context):
+ cloth = context.cloth.settings
+ effector_weights_ui(self, cloth.effector_weights)
bpy.types.register(PHYSICS_PT_cloth)
bpy.types.register(PHYSICS_PT_cloth_cache)
bpy.types.register(PHYSICS_PT_cloth_collision)
bpy.types.register(PHYSICS_PT_cloth_stiffness)
+bpy.types.register(PHYSICS_PT_cloth_field_weights)
diff --git a/release/scripts/ui/buttons_physics_common.py b/release/scripts/ui/buttons_physics_common.py
new file mode 100644
index 00000000000..b65d092fcfa
--- /dev/null
+++ b/release/scripts/ui/buttons_physics_common.py
@@ -0,0 +1,153 @@
+import bpy
+
+def point_cache_ui(self, cache, enabled, particles, smoke):
+ layout = self.layout
+ layout.set_context_pointer("PointCache", cache)
+
+ row = layout.row()
+ row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
+ col = row.column(align=True)
+ col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
+ col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
+
+ row = layout.row()
+ row.itemL(text="File Name:")
+ if particles:
+ row.itemR(cache, "external")
+
+ if cache.external:
+ split = layout.split(percentage=0.80)
+ split.itemR(cache, "name", text="")
+ split.itemR(cache, "index", text="")
+
+ layout.itemL(text="File Path:")
+ layout.itemR(cache, "filepath", text="")
+
+ layout.itemL(text=cache.info)
+ else:
+ layout.itemR(cache, "name", text="")
+
+ if not particles:
+ row = layout.row()
+ row.enabled = enabled
+ row.itemR(cache, "start_frame")
+ row.itemR(cache, "end_frame")
+
+ row = layout.row()
+
+ if cache.baked == True:
+ row.itemO("ptcache.free_bake", text="Free Bake")
+ else:
+ row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
+
+ sub = row.row()
+ sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
+ sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
+
+ row = layout.row()
+ row.enabled = enabled
+ row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
+ if not smoke:
+ row.itemR(cache, "step");
+
+ if not smoke:
+ row = layout.row()
+ sub = row.row()
+ sub.enabled = enabled
+ sub.itemR(cache, "quick_cache")
+ row.itemR(cache, "disk_cache")
+
+ layout.itemL(text=cache.info)
+
+ layout.itemS()
+
+ row = layout.row()
+ row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+ row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+ layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
+
+def effector_weights_ui(self, weights):
+ layout = self.layout
+
+ layout.itemR(weights, "group")
+
+ split = layout.split()
+ split.itemR(weights, "gravity", slider=True)
+ split.itemR(weights, "all", slider=True)
+
+ layout.itemS()
+
+ flow = layout.column_flow()
+ flow.itemR(weights, "spherical", slider=True)
+ flow.itemR(weights, "vortex", slider=True)
+ flow.itemR(weights, "magnetic", slider=True)
+ flow.itemR(weights, "wind", slider=True)
+ flow.itemR(weights, "curveguide", slider=True)
+ flow.itemR(weights, "texture", slider=True)
+ flow.itemR(weights, "harmonic", slider=True)
+ flow.itemR(weights, "charge", slider=True)
+ flow.itemR(weights, "lennardjones", slider=True)
+ flow.itemR(weights, "turbulence", slider=True)
+ flow.itemR(weights, "drag", slider=True)
+ flow.itemR(weights, "boid", slider=True)
+
+def basic_force_field_settings_ui(self, field):
+ layout = self.layout
+ split = layout.split()
+
+ if not field or field.type == 'NONE':
+ return
+
+ col = split.column()
+
+ if field.type == 'DRAG':
+ col.itemR(field, "linear_drag", text="Linear")
+ else:
+ col.itemR(field, "strength")
+
+ if field.type == 'TURBULENCE':
+ col.itemR(field, "size")
+ col.itemR(field, "flow")
+ elif field.type == 'HARMONIC':
+ col.itemR(field, "harmonic_damping", text="Damping")
+ elif field.type == 'VORTEX' and field.shape == 'PLANE':
+ col.itemR(field, "inflow")
+ elif field.type == 'DRAG':
+ col.itemR(field, "quadratic_drag", text="Quadratic")
+ else:
+ col.itemR(field, "flow")
+
+ col = split.column()
+ col.itemR(field, "noise")
+ col.itemR(field, "seed")
+ if field.type == 'TURBULENCE':
+ col.itemR(field, "global_coordinates", text="Global")
+
+ row = layout.row()
+ row.itemL(text="Effect point:")
+ row.itemR(field, "do_location")
+ row.itemR(field, "do_rotation")
+
+
+def basic_force_field_falloff_ui(self, field):
+ layout = self.layout
+ split = layout.split(percentage=0.35)
+
+ if not field or field.type == 'NONE':
+ return
+
+ col = split.column()
+ col.itemR(field, "z_direction", text="")
+ col.itemR(field, "use_min_distance", text="Use Minimum")
+ col.itemR(field, "use_max_distance", text="Use Maximum")
+
+ col = split.column()
+ col.itemR(field, "falloff_power", text="Power")
+
+ sub = col.column()
+ sub.active = field.use_min_distance
+ sub.itemR(field, "minimum_distance", text="Distance")
+
+ sub = col.column()
+ sub.active = field.use_max_distance
+ sub.itemR(field, "maximum_distance", text="Distance") \ No newline at end of file
diff --git a/release/ui/buttons_physics_field.py b/release/scripts/ui/buttons_physics_field.py
index 58033d2c431..24740acc68f 100644
--- a/release/ui/buttons_physics_field.py
+++ b/release/scripts/ui/buttons_physics_field.py
@@ -1,6 +1,9 @@
import bpy
+from buttons_physics_common import basic_force_field_settings_ui
+from buttons_physics_common import basic_force_field_falloff_ui
+
class PhysicButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
__region_type__ = 'WINDOW'
@@ -12,7 +15,6 @@ class PhysicButtonsPanel(bpy.types.Panel):
class PHYSICS_PT_field(PhysicButtonsPanel):
__label__ = "Force Fields"
- __default_closed__ = True
def draw(self, context):
layout = self.layout
@@ -23,50 +25,21 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
#layout.active = field.enabled
split = layout.split(percentage=0.2)
-
split.itemL(text="Type:")
split.itemR(field, "type",text="")
+
+ if field.type not in ('NONE', 'GUIDE', 'TEXTURE'):
+ split = layout.split(percentage=0.2)
+ #split = layout.row()
+ split.itemL(text="Shape:")
+ split.itemR(field, "shape", text="")
split = layout.split()
- if field.type == 'GUIDE':
+ if field.type == 'NONE':
+ return # nothing to draw
+ elif field.type == 'GUIDE':
layout.itemR(field, "guide_path_add")
-
- elif field.type == 'WIND':
- split.itemR(field, "strength")
-
- col = split.column()
- col.itemR(field, "noise")
- col.itemR(field, "seed")
-
- elif field.type == 'VORTEX':
- split.itemR(field, "strength")
- split.itemL()
-
- elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'):
- split.itemR(field, "strength")
-
- col = split.column()
- col.itemR(field, "planar")
- col.itemR(field, "surface")
-
- elif field.type == 'BOID':
- split.itemR(field, "strength")
- split.itemR(field, "surface")
-
- elif field.type == 'MAGNET':
- split.itemR(field, "strength")
- split.itemR(field, "planar")
-
- elif field.type == 'HARMONIC':
- col = split.column()
- col.itemR(field, "strength")
- col.itemR(field, "harmonic_damping", text="Damping")
-
- col = split.column()
- col.itemR(field, "planar")
- col.itemR(field, "surface")
-
elif field.type == 'TEXTURE':
col = split.column()
col.itemR(field, "strength")
@@ -78,32 +51,17 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
col.itemR(field, "use_coordinates")
col.itemR(field, "root_coordinates")
col.itemR(field, "force_2d")
+ else :
+ basic_force_field_settings_ui(self, field)
- if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', 'WIND', 'VORTEX', 'TEXTURE', 'MAGNET', 'BOID'):
+ if field.type not in ('NONE', 'GUIDE'):
layout.itemL(text="Falloff:")
layout.itemR(field, "falloff_type", expand=True)
- split = layout.split(percentage=0.35)
-
- col = split.column()
- col.itemR(field, "positive_z", text="Positive Z")
- col.itemR(field, "use_min_distance", text="Use Minimum")
- col.itemR(field, "use_max_distance", text="Use Maximum")
-
- col = split.column()
- col.itemR(field, "falloff_power", text="Power")
-
- sub = col.column()
- sub.active = field.use_min_distance
- sub.itemR(field, "minimum_distance", text="Distance")
-
- sub = col.column()
- sub.active = field.use_max_distance
- sub.itemR(field, "maximum_distance", text="Distance")
+ basic_force_field_falloff_ui(self, field)
if field.falloff_type == 'CONE':
-
layout.itemS()
split = layout.split(percentage=0.35)
@@ -125,7 +83,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
sub.itemR(field, "radial_maximum", text="Angle")
elif field.falloff_type == 'TUBE':
-
layout.itemS()
split = layout.split(percentage=0.35)
@@ -159,7 +116,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
class PHYSICS_PT_collision(PhysicButtonsPanel):
__label__ = "Collision"
- __default_closed__ = True
+ #__default_closed__ = True
def poll(self, context):
ob = context.object
@@ -214,7 +171,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel):
sub.itemR(settings, "inner_thickness", text="Inner", slider=True)
layout.itemL(text="Force Fields:")
- layout.itemR(md, "absorption", text="Absorption")
+ layout.itemR(settings, "absorption", text="Absorption")
col = split.column()
col.itemL(text="")
diff --git a/release/ui/buttons_physics_fluid.py b/release/scripts/ui/buttons_physics_fluid.py
index 6f7a97ff793..e178a831ddd 100644
--- a/release/ui/buttons_physics_fluid.py
+++ b/release/scripts/ui/buttons_physics_fluid.py
@@ -174,8 +174,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
def poll(self, context):
md = context.fluid
- if md:
- return (md.settings.type == 'DOMAIN')
+ return md and (md.settings.type == 'DOMAIN')
def draw(self, context):
layout = self.layout
@@ -213,8 +212,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel):
def poll(self, context):
md = context.fluid
- if md:
- return (md.settings.type == 'DOMAIN')
+ return md and (md.settings.type == 'DOMAIN')
def draw(self, context):
layout = self.layout
@@ -242,8 +240,7 @@ class PHYSICS_PT_domain_particles(PhysicButtonsPanel):
def poll(self, context):
md = context.fluid
- if md:
- return (md.settings.type == 'DOMAIN')
+ return md and (md.settings.type == 'DOMAIN')
def draw(self, context):
layout = self.layout
diff --git a/release/ui/buttons_physics_smoke.py b/release/scripts/ui/buttons_physics_smoke.py
index 6aee152e92a..1541b0bae14 100644
--- a/release/ui/buttons_physics_smoke.py
+++ b/release/scripts/ui/buttons_physics_smoke.py
@@ -90,10 +90,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
def poll(self, context):
md = context.smoke
- if md:
- return (md.smoke_type == 'TYPE_DOMAIN')
-
- return False
+ return md and (md.smoke_type == 'TYPE_DOMAIN')
def draw(self, context):
layout = self.layout
diff --git a/release/ui/buttons_physics_softbody.py b/release/scripts/ui/buttons_physics_softbody.py
index 703977a056f..cd66df00044 100644
--- a/release/ui/buttons_physics_softbody.py
+++ b/release/scripts/ui/buttons_physics_softbody.py
@@ -1,7 +1,8 @@
import bpy
-from buttons_particle import point_cache_ui
+from buttons_physics_common import point_cache_ui
+from buttons_physics_common import effector_weights_ui
def softbody_panel_enabled(md):
return md.point_cache.baked==False
@@ -55,7 +56,6 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel):
col = split.column()
col.itemL(text="Simulation:")
- col.itemR(softbody, "gravity")
col.itemR(softbody, "speed")
class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
@@ -63,7 +63,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.soft_body)
+ return context.soft_body
def draw(self, context):
md = context.soft_body
@@ -74,7 +74,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.soft_body)
+ return context.soft_body
def draw_header(self, context):
softbody = context.soft_body.settings
@@ -115,7 +115,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.soft_body)
+ return context.soft_body
def draw_header(self, context):
softbody = context.soft_body.settings
@@ -163,7 +163,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.soft_body)
+ return context.soft_body
def draw_header(self, context):
softbody = context.soft_body.settings
@@ -194,7 +194,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
__default_closed__ = True
def poll(self, context):
- return (context.soft_body)
+ return context.soft_body
def draw(self, context):
layout = self.layout
@@ -222,6 +222,18 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
layout.itemL(text="Diagnostics:")
layout.itemR(softbody, "diagnose")
+
+class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
+ __label__ = "Soft Body Field Weights"
+ __default_closed__ = True
+
+ def poll(self, context):
+ return (context.soft_body)
+
+ def draw(self, context):
+ md = context.soft_body
+ softbody = md.settings
+ effector_weights_ui(self, softbody.effector_weights)
bpy.types.register(PHYSICS_PT_softbody)
bpy.types.register(PHYSICS_PT_softbody_cache)
@@ -229,3 +241,4 @@ bpy.types.register(PHYSICS_PT_softbody_goal)
bpy.types.register(PHYSICS_PT_softbody_edge)
bpy.types.register(PHYSICS_PT_softbody_collision)
bpy.types.register(PHYSICS_PT_softbody_solver)
+bpy.types.register(PHYSICS_PT_softbody_field_weights)
diff --git a/release/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py
index 3c321f11f6e..2fbd176e36a 100644
--- a/release/ui/buttons_scene.py
+++ b/release/scripts/ui/buttons_scene.py
@@ -240,7 +240,8 @@ class SCENE_PT_output(RenderButtonsPanel):
split = layout.split()
col = split.column()
- col.itemR(rd, "exr_codec")
+ col.itemL(text="Codec:")
+ col.itemR(rd, "exr_codec", text="")
subsplit = split.split()
col = subsplit.column()
@@ -253,12 +254,11 @@ class SCENE_PT_output(RenderButtonsPanel):
split = layout.split()
col = split.column()
col.itemL(text="Depth:")
- col.row().itemR(rd, "jpeg_depth", expand=True)
+ col.row().itemR(rd, "jpeg2k_depth", expand=True)
col = split.column()
- col.itemR(rd, "jpeg_preset", text="")
- col.itemR(rd, "jpeg_ycc")
- col.itemR(rd, "exr_preview")
+ col.itemR(rd, "jpeg2k_preset", text="")
+ col.itemR(rd, "jpeg2k_ycc")
elif rd.file_format in ('CINEON', 'DPX'):
split = layout.split()
@@ -322,8 +322,10 @@ class SCENE_PT_encoding(RenderButtonsPanel):
col = split.column()
col.itemR(rd, "ffmpeg_audio_bitrate")
+ col.itemR(rd, "ffmpeg_audio_mixrate")
col = split.column()
col.itemR(rd, "ffmpeg_multiplex_audio")
+ col.itemR(rd, "ffmpeg_audio_volume")
class SCENE_PT_antialiasing(RenderButtonsPanel):
__label__ = "Anti-Aliasing"
@@ -449,7 +451,23 @@ class SCENE_PT_unit(RenderButtonsPanel):
row.itemR(unit, "scale_length", text="Scale")
row.itemR(unit, "use_separate")
+class SCENE_PT_physics(RenderButtonsPanel):
+ __label__ = "Gravity"
+ COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+ def draw_header(self, context):
+ self.layout.itemR(context.scene, "use_gravity", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+
+ layout.active = scene.use_gravity
+
+ layout.itemR(scene, "gravity", text="")
+
bpy.types.register(SCENE_PT_render)
bpy.types.register(SCENE_PT_layers)
bpy.types.register(SCENE_PT_dimensions)
@@ -461,3 +479,4 @@ bpy.types.register(SCENE_PT_performance)
bpy.types.register(SCENE_PT_post_processing)
bpy.types.register(SCENE_PT_stamp)
bpy.types.register(SCENE_PT_unit)
+bpy.types.register(SCENE_PT_physics)
diff --git a/release/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py
index 90ce40b4832..6eab84afc42 100644
--- a/release/ui/buttons_texture.py
+++ b/release/scripts/ui/buttons_texture.py
@@ -96,7 +96,7 @@ class TEXTURE_PT_colors(TextureButtonsPanel):
layout.itemR(tex, "use_color_ramp", text="Ramp")
if tex.use_color_ramp:
- layout.template_color_ramp(tex.color_ramp, expand=True)
+ layout.template_color_ramp(tex, "color_ramp", expand=True)
split = layout.split()
@@ -175,14 +175,14 @@ class TEXTURE_PT_mapping(TextureSlotPanel):
row.itemR(tex, "z_mapping", text="")
if br:
- layout.itemR(tex, "brush_map_mode", expand=True)
+ layout.itemR(tex, "map_mode", expand=True)
row = layout.row()
- row.active = tex.brush_map_mode in ('FIXED', 'TILED')
+ row.active = tex.map_mode in ('FIXED', 'TILED')
row.itemR(tex, "angle")
row = layout.row()
- row.active = tex.brush_map_mode in ('TILED', '3D')
+ row.active = tex.map_mode in ('TILED', '3D')
row.column().itemR(tex, "size")
else:
row = layout.row()
@@ -246,14 +246,14 @@ class TEXTURE_PT_influence(TextureSlotPanel):
col = split.column()
factor_but(col, tex.map_density, "map_density", "density_factor", "Density")
factor_but(col, tex.map_emission, "map_emission", "emission_factor", "Emission")
- factor_but(col, tex.map_absorption, "map_absorption", "absorption_factor", "Absorption")
factor_but(col, tex.map_scattering, "map_scattering", "scattering_factor", "Scattering")
+ factor_but(col, tex.map_reflection, "map_reflection", "reflection_factor", "Reflection")
col = split.column()
col.itemL(text=" ")
factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color")
- factor_but(col, tex.map_colorabsorption, "map_colorabsorption", "colorabsorption_factor", "Absorption Color")
-
+ factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color")
+ factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color")
elif la:
row = layout.row()
@@ -381,7 +381,10 @@ class TEXTURE_PT_blend(TextureTypePanel):
tex = context.texture
layout.itemR(tex, "progression")
- layout.itemR(tex, "flip_axis")
+ sub = layout.row()
+
+ sub.active = (tex.progression in ('LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'))
+ sub.itemR(tex, "flip_axis", expand=True)
class TEXTURE_PT_stucci(TextureTypePanel):
__label__ = "Stucci"
@@ -407,10 +410,10 @@ class TEXTURE_PT_image(TextureTypePanel):
def draw(self, context):
layout = self.layout
-
+
tex = context.texture
- layout.template_texture_image(tex)
+ layout.template_image(tex, "image", tex.image_user)
class TEXTURE_PT_image_sampling(TextureTypePanel):
__label__ = "Image Sampling"
@@ -614,9 +617,8 @@ class TEXTURE_PT_distortednoise(TextureTypePanel):
flow.itemR(tex, "nabla")
class TEXTURE_PT_voxeldata(TextureButtonsPanel):
- __idname__= "TEXTURE_PT_voxeldata"
__label__ = "Voxel Data"
-
+
def poll(self, context):
tex = context.texture
return (tex and tex.type == 'VOXEL_DATA')
@@ -641,12 +643,12 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel):
row.itemR(vd, "still_frame_number")
layout.itemR(vd, "interpolation")
+ layout.itemR(vd, "extension")
layout.itemR(vd, "intensity")
class TEXTURE_PT_pointdensity(TextureButtonsPanel):
- __idname__= "TEXTURE_PT_pointdensity"
__label__ = "Point Density"
-
+
def poll(self, context):
tex = context.texture
return (tex and tex.type == 'POINT_DENSITY')
@@ -686,7 +688,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel):
if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_VELOCITY'):
col.itemR(pd, "speed_scale")
if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_AGE'):
- layout.template_color_ramp(pd.color_ramp, expand=True)
+ layout.template_color_ramp(pd, "color_ramp", expand=True)
col = split.column()
col.itemL()
diff --git a/release/ui/buttons_world.py b/release/scripts/ui/buttons_world.py
index b02673d126f..3134c0ce46b 100644
--- a/release/ui/buttons_world.py
+++ b/release/scripts/ui/buttons_world.py
@@ -169,10 +169,9 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel):
col.itemR(ao, "energy")
col = split.column()
- colsub = col.split(percentage=0.3)
- colsub.itemL(text="Color:")
- colsub.itemR(ao, "color", text="")
-
+ sub = col.split(percentage=0.3)
+ sub.itemL(text="Color:")
+ sub.itemR(ao, "color", text="")
bpy.types.register(WORLD_PT_context_world)
bpy.types.register(WORLD_PT_preview)
diff --git a/release/ui/space_buttons.py b/release/scripts/ui/space_buttons.py
index aa89c06ea08..aa89c06ea08 100644
--- a/release/ui/space_buttons.py
+++ b/release/scripts/ui/space_buttons.py
diff --git a/release/ui/space_console.py b/release/scripts/ui/space_console.py
index 136082a285a..a65d7577c7a 100644
--- a/release/ui/space_console.py
+++ b/release/scripts/ui/space_console.py
@@ -1,9 +1,5 @@
-
import bpy
-import bpy_ops # XXX - should not need to do this
-del bpy_ops
-
class CONSOLE_HT_header(bpy.types.Header):
__space_type__ = 'CONSOLE'
@@ -37,6 +33,9 @@ class CONSOLE_HT_header(bpy.types.Header):
row = layout.row()
row.enabled = sc.show_report_operator
row.itemO("console.report_replay")
+ else:
+ row = layout.row(align=True)
+ row.itemO("console.autocomplete", text="Autocomplete")
class CONSOLE_MT_console(bpy.types.Menu):
__space_type__ = 'CONSOLE'
@@ -107,9 +106,7 @@ def get_console(console_id):
return namespace, console, stdout, stderr
class CONSOLE_OT_exec(bpy.types.Operator):
- '''
- Execute the current console line as a python expression.
- '''
+ '''Execute the current console line as a python expression.'''
__idname__ = "console.execute"
__label__ = "Console Execute"
__register__ = False
@@ -183,216 +180,14 @@ class CONSOLE_OT_exec(bpy.types.Operator):
return ('FINISHED',)
-def autocomp(bcon):
- '''
- This function has been taken from a BGE console autocomp I wrote a while ago
- the dictionaty bcon is not needed but it means I can copy and paste from the old func
- which works ok for now.
-
- could be moved into its own module.
- '''
-
-
- def is_delimiter(ch):
- '''
- For skipping words
- '''
- if ch == '_':
- return False
- if ch.isalnum():
- return False
-
- return True
-
- def is_delimiter_autocomp(ch):
- '''
- When autocompleteing will earch back and
- '''
- if ch in '._[] "\'':
- return False
- if ch.isalnum():
- return False
-
- return True
-
-
- def do_autocomp(autocomp_prefix, autocomp_members):
- '''
- return text to insert and a list of options
- '''
- autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
-
- print("AUTO: '%s'" % autocomp_prefix)
- print("MEMBERS: '%s'" % str(autocomp_members))
-
- if not autocomp_prefix:
- return '', autocomp_members
- elif len(autocomp_members) > 1:
- # find a common string between all members after the prefix
- # 'ge' [getA, getB, getC] --> 'get'
-
- # get the shortest member
- min_len = min([len(v) for v in autocomp_members])
-
- autocomp_prefix_ret = ''
-
- for i in range(len(autocomp_prefix), min_len):
- char_soup = set()
- for v in autocomp_members:
- char_soup.add(v[i])
-
- if len(char_soup) > 1:
- break
- else:
- autocomp_prefix_ret += char_soup.pop()
-
- print(autocomp_prefix_ret)
- return autocomp_prefix_ret, autocomp_members
- elif len(autocomp_members) == 1:
- return autocomp_members[0][len(autocomp_prefix):], []
- else:
- return '', []
-
-
- def BCon_PrevChar(bcon):
- cursor = bcon['cursor']-1
- if cursor<0:
- return None
-
- try:
- return bcon['edit_text'][cursor]
- except:
- return None
-
-
- def BCon_NextChar(bcon):
- try:
- return bcon['edit_text'][bcon['cursor']]
- except:
- return None
-
- def BCon_cursorLeft(bcon):
- bcon['cursor'] -= 1
- if bcon['cursor'] < 0:
- bcon['cursor'] = 0
-
- def BCon_cursorRight(bcon):
- bcon['cursor'] += 1
- if bcon['cursor'] > len(bcon['edit_text']):
- bcon['cursor'] = len(bcon['edit_text'])
-
- def BCon_AddScrollback(bcon, text):
-
- bcon['scrollback'] = bcon['scrollback'] + text
-
-
- def BCon_cursorInsertChar(bcon, ch):
- if bcon['cursor']==0:
- bcon['edit_text'] = ch + bcon['edit_text']
- elif bcon['cursor']==len(bcon['edit_text']):
- bcon['edit_text'] = bcon['edit_text'] + ch
- else:
- bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
-
- bcon['cursor']
- if bcon['cursor'] > len(bcon['edit_text']):
- bcon['cursor'] = len(bcon['edit_text'])
- BCon_cursorRight(bcon)
-
-
- TEMP_NAME = '___tempname___'
-
- cursor_orig = bcon['cursor']
-
- ch = BCon_PrevChar(bcon)
- while ch != None and (not is_delimiter(ch)):
- ch = BCon_PrevChar(bcon)
- BCon_cursorLeft(bcon)
-
- if ch != None:
- BCon_cursorRight(bcon)
-
- #print (cursor_orig, bcon['cursor'])
-
- cursor_base = bcon['cursor']
-
- autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
-
- print("PREFIX:'%s'" % autocomp_prefix)
-
- # Get the previous word
- if BCon_PrevChar(bcon)=='.':
- BCon_cursorLeft(bcon)
- ch = BCon_PrevChar(bcon)
- while ch != None and is_delimiter_autocomp(ch)==False:
- ch = BCon_PrevChar(bcon)
- BCon_cursorLeft(bcon)
-
- cursor_new = bcon['cursor']
-
- if ch != None:
- cursor_new+=1
-
- pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
- print("AUTOCOMP EVAL: '%s'" % pytxt)
- #try:
- if pytxt:
- bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
- # print val
- else: ##except:
- val = None
-
- try:
- val = bcon['namespace'][TEMP_NAME]
- del bcon['namespace'][TEMP_NAME]
- except:
- val = None
-
- if val:
- autocomp_members = dir(val)
-
- autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
-
- bcon['cursor'] = cursor_orig
- for v in autocomp_prefix_ret:
- BCon_cursorInsertChar(bcon, v)
- cursor_orig = bcon['cursor']
-
- if autocomp_members:
- BCon_AddScrollback(bcon, ', '.join(autocomp_members))
-
- del val
-
- else:
- # Autocomp global namespace
- autocomp_members = bcon['namespace'].keys()
-
- if autocomp_prefix:
- autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
-
- autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
-
- bcon['cursor'] = cursor_orig
- for v in autocomp_prefix_ret:
- BCon_cursorInsertChar(bcon, v)
- cursor_orig = bcon['cursor']
-
- if autocomp_members:
- BCon_AddScrollback(bcon, ', '.join(autocomp_members))
-
- bcon['cursor'] = cursor_orig
-
-
class CONSOLE_OT_autocomplete(bpy.types.Operator):
- '''
- Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.
- '''
+ '''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.'''
__idname__ = "console.autocomplete"
__label__ = "Console Autocomplete"
__register__ = False
def poll(self, context):
- return context.space_data.type == 'PYTHON'
+ return context.space_data.console_type == 'PYTHON'
def execute(self, context):
@@ -420,7 +215,8 @@ class CONSOLE_OT_autocomplete(bpy.types.Operator):
# This function isnt aware of the text editor or being an operator
# just does the autocomp then copy its results back
- autocomp(bcon)
+ import autocomplete
+ autocomplete.execute(bcon)
# Now we need to copy back the line from blender back into the text editor.
# This will change when we dont use the text editor anymore
diff --git a/release/ui/space_filebrowser.py b/release/scripts/ui/space_filebrowser.py
index f1ea5555787..f1ea5555787 100644
--- a/release/ui/space_filebrowser.py
+++ b/release/scripts/ui/space_filebrowser.py
diff --git a/release/ui/space_image.py b/release/scripts/ui/space_image.py
index 0d0fd86ef8c..b14bec0e40e 100644
--- a/release/ui/space_image.py
+++ b/release/scripts/ui/space_image.py
@@ -277,6 +277,24 @@ class IMAGE_HT_header(bpy.types.Header):
if show_uvedit or sima.image_painting:
layout.itemR(sima, "update_automatically", text="")
+class IMAGE_PT_image_properties(bpy.types.Panel):
+ __space_type__ = 'IMAGE_EDITOR'
+ __region_type__ = 'UI'
+ __label__ = "Image"
+
+ def poll(self, context):
+ sima = context.space_data
+ return (sima.image)
+
+ def draw(self, context):
+ layout = self.layout
+
+ sima = context.space_data
+ ima = sima.image
+ iuser = sima.image_user
+
+ layout.template_image(sima, "image", iuser, compact=True)
+
class IMAGE_PT_game_properties(bpy.types.Panel):
__space_type__ = 'IMAGE_EDITOR'
__region_type__ = 'UI'
@@ -296,13 +314,7 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
split = layout.split()
col = split.column()
- col.itemR(ima, "clamp_x")
- col.itemR(ima, "clamp_y")
- col.itemR(ima, "mapping", expand=True)
- col.itemR(ima, "tiles")
-
- col = split.column()
-
+
sub = col.column(align=True)
sub.itemR(ima, "animated")
@@ -311,11 +323,21 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
subsub.itemR(ima, "animation_start", text="Start")
subsub.itemR(ima, "animation_end", text="End")
subsub.itemR(ima, "animation_speed", text="Speed")
-
- sub = col.row(align=True)
+
+ col.itemR(ima, "tiles")
+ sub = col.column(align=True)
sub.active = ima.tiles or ima.animated
sub.itemR(ima, "tiles_x", text="X")
sub.itemR(ima, "tiles_y", text="Y")
+
+ col = split.column()
+ col.itemL(text="Clamp:")
+ col.itemR(ima, "clamp_x", text="X")
+ col.itemR(ima, "clamp_y", text="Y")
+ col.itemS()
+ col.itemR(ima, "mapping", expand=True)
+
+
class IMAGE_PT_view_properties(bpy.types.Panel):
__space_type__ = 'IMAGE_EDITOR'
@@ -350,7 +372,9 @@ class IMAGE_PT_view_properties(bpy.types.Panel):
col.itemR(uvedit, "normalized_coordinates", text="Normalized")
if show_uvedit:
+
col = layout.column()
+ col.itemL(text="UVs:")
row = col.row()
row.itemR(uvedit, "edge_draw_type", expand=True)
@@ -368,6 +392,99 @@ class IMAGE_PT_view_properties(bpy.types.Panel):
#col.itemR(uvedit, "draw_edges")
#col.itemR(uvedit, "draw_faces")
+class IMAGE_PT_paint(bpy.types.Panel):
+ __space_type__ = 'IMAGE_EDITOR'
+ __region_type__ = 'UI'
+ __label__ = "Paint"
+
+ def poll(self, context):
+ sima = context.space_data
+ return sima.show_paint
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = context.tool_settings.image_paint
+ brush = settings.brush
+
+ col = layout.split().column()
+ row = col.row()
+ row.template_list(settings, "brushes", settings, "active_brush_index", rows=2)
+
+ col.template_ID(settings, "brush", new="brush.add")
+
+ row = layout.row(align=True)
+ row.item_enumR(settings, "tool", 'DRAW')
+ row.item_enumR(settings, "tool", 'SOFTEN')
+ row.item_enumR(settings, "tool", 'CLONE')
+ row.item_enumR(settings, "tool", 'SMEAR')
+
+ if brush:
+ col = layout.column()
+ col.itemR(brush, "color", text="")
+
+ row = col.row(align=True)
+ row.itemR(brush, "size", slider=True)
+ row.itemR(brush, "use_size_pressure", toggle=True, text="")
+
+ row = col.row(align=True)
+ row.itemR(brush, "strength", slider=True)
+ row.itemR(brush, "use_strength_pressure", toggle=True, text="")
+
+ row = col.row(align=True)
+ row.itemR(brush, "jitter", slider=True)
+ row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
+
+ col.itemR(brush, "blend", text="Blend")
+
+class IMAGE_PT_paint_stroke(bpy.types.Panel):
+ __space_type__ = 'IMAGE_EDITOR'
+ __region_type__ = 'UI'
+ __label__ = "Paint Stroke"
+ __default_closed__ = True
+
+ def poll(self, context):
+ sima = context.space_data
+ settings = context.tool_settings.image_paint
+ return sima.show_paint and settings.brush
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = context.tool_settings.image_paint
+ brush = settings.brush
+
+ layout.itemR(brush, "use_airbrush")
+ col = layout.column()
+ col.active = brush.use_airbrush
+ col.itemR(brush, "rate", slider=True)
+
+ layout.itemR(brush, "use_space")
+ row = layout.row(align=True)
+ row.active = brush.use_space
+ row.itemR(brush, "spacing", text="Distance", slider=True)
+ row.itemR(brush, "use_spacing_pressure", toggle=True, text="")
+
+class IMAGE_PT_paint_curve(bpy.types.Panel):
+ __space_type__ = 'IMAGE_EDITOR'
+ __region_type__ = 'UI'
+ __label__ = "Paint Curve"
+ __default_closed__ = True
+
+ def poll(self, context):
+ sima = context.space_data
+ settings = context.tool_settings.image_paint
+ return sima.show_paint and settings.brush
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = context.tool_settings.image_paint
+ brush = settings.brush
+
+ layout.template_curve_mapping(brush, "curve")
+ layout.item_menu_enumO("brush.curve_preset", property="shape")
+
bpy.types.register(IMAGE_MT_view)
bpy.types.register(IMAGE_MT_select)
bpy.types.register(IMAGE_MT_image)
@@ -377,5 +494,10 @@ bpy.types.register(IMAGE_MT_uvs_mirror)
bpy.types.register(IMAGE_MT_uvs_weldalign)
bpy.types.register(IMAGE_MT_uvs)
bpy.types.register(IMAGE_HT_header)
+bpy.types.register(IMAGE_PT_image_properties)
+bpy.types.register(IMAGE_PT_paint)
+bpy.types.register(IMAGE_PT_paint_stroke)
+bpy.types.register(IMAGE_PT_paint_curve)
bpy.types.register(IMAGE_PT_game_properties)
bpy.types.register(IMAGE_PT_view_properties)
+
diff --git a/release/ui/space_info.py b/release/scripts/ui/space_info.py
index 97243f857a6..c1a2b1f4275 100644
--- a/release/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -60,6 +60,10 @@ class INFO_MT_file(bpy.types.Menu):
layout.itemO("screen.userpref_show", text="User Preferences...")
layout.itemS()
+ layout.operator_context = "INVOKE_AREA"
+ layout.itemO("wm.link_append", text="Link")
+ layout.item_booleanO("wm.link_append", "link", False, text="Append")
+ layout.itemS()
layout.itemM("INFO_MT_file_import")
layout.itemM("INFO_MT_file_export")
@@ -80,7 +84,9 @@ class INFO_MT_file_import(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Nothing yet")
+ layout.itemO("import.3ds", text="3DS")
+ layout.itemO("import.obj", text="OBJ")
+
class INFO_MT_file_export(bpy.types.Menu):
__space_type__ = 'INFO'
@@ -89,7 +95,12 @@ class INFO_MT_file_export(bpy.types.Menu):
def draw(self, context):
layout = self.layout
+ layout.itemO("export.3ds", text="3DS")
+ layout.itemO("export.fbx", text="FBX")
+ layout.itemO("export.obj", text="OBJ")
layout.itemO("export.ply", text="PLY")
+ layout.itemO("export.x3d", text="X3D")
+
class INFO_MT_file_external_data(bpy.types.Menu):
__space_type__ = 'INFO'
@@ -120,7 +131,7 @@ class INFO_MT_add(bpy.types.Menu):
layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH')
layout.item_menu_enumO("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE')
layout.item_menu_enumO("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE')
- layout.item_menu_enumO("object.metaball_add", "type", 'META', icon='ICON_OUTLINER_OB_META')
+ layout.item_menu_enumO("object.metaball_add", "type", 'META', text="Metaball", icon='ICON_OUTLINER_OB_META')
layout.itemO("object.text_add", text="Text", icon='ICON_OUTLINER_OB_FONT')
layout.itemS()
@@ -132,7 +143,7 @@ class INFO_MT_add(bpy.types.Menu):
layout.itemS()
layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
- layout.item_enumO("object.add", "type", 'LAMP', icon='ICON_OUTLINER_OB_LAMP')
+ layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
class INFO_MT_game(bpy.types.Menu):
__space_type__ = 'INFO'
@@ -184,6 +195,9 @@ class INFO_MT_help(bpy.types.Menu):
layout.itemO("help.blender_eshop")
layout.itemO("help.developer_community")
layout.itemO("help.user_community")
+ layout.itemS()
+ layout.itemO("help.operator_cheat_sheet")
+
bpy.types.register(INFO_HT_header)
bpy.types.register(INFO_MT_file)
@@ -197,9 +211,6 @@ bpy.types.register(INFO_MT_help)
# Help operators
-import bpy_ops # XXX - should not need to do this
-del bpy_ops
-
class HelpOperator(bpy.types.Operator):
def execute(self, context):
try: import webbrowser
@@ -242,10 +253,37 @@ class HELP_OT_user_community(HelpOperator):
__label__ = "User Community"
__URL__ = 'http://www.blender.org/community/user-community/'
+class HELP_OT_operator_cheat_sheet(bpy.types.Operator):
+ __idname__ = "help.operator_cheat_sheet"
+ __label__ = "Operator Cheet Sheet (new textblock)"
+ def execute(self, context):
+ op_strings = []
+ tot = 0
+ for op_module_name in dir(bpy.ops):
+ op_module = getattr(bpy.ops, op_module_name)
+ for op_submodule_name in dir(op_module):
+ op = getattr(op_module, op_submodule_name)
+ text = repr(op)
+ if text.startswith('bpy.ops.'):
+ op_strings.append(text)
+ tot += 1
+
+ op_strings.append('')
+
+ bpy.ops.text.new() # XXX - assumes new text is always at the end!
+ textblock = bpy.data.texts[-1]
+ textblock.write('# %d Operators\n\n' % tot)
+ textblock.write('\n'.join(op_strings))
+ textblock.name = "OperatorList.txt"
+ print("See OperatorList.txt textblock")
+ return ('FINISHED',)
+
+
bpy.ops.add(HELP_OT_manual)
bpy.ops.add(HELP_OT_release_logs)
bpy.ops.add(HELP_OT_blender_website)
bpy.ops.add(HELP_OT_blender_eshop)
bpy.ops.add(HELP_OT_developer_community)
bpy.ops.add(HELP_OT_user_community)
+bpy.ops.add(HELP_OT_operator_cheat_sheet)
diff --git a/release/ui/space_logic.py b/release/scripts/ui/space_logic.py
index 5748d15a53a..5748d15a53a 100644
--- a/release/ui/space_logic.py
+++ b/release/scripts/ui/space_logic.py
diff --git a/release/ui/space_node.py b/release/scripts/ui/space_node.py
index 6ac1ac84f35..b32e6a9f61a 100644
--- a/release/ui/space_node.py
+++ b/release/scripts/ui/space_node.py
@@ -74,11 +74,10 @@ class NODE_MT_select(bpy.types.Menu):
layout.itemO("node.select_border")
- # XXX
- # layout.itemS()
- # layout.itemO("node.select_all")
- # layout.itemO("node.select_linked_from")
- # layout.itemO("node.select_linked_to")
+ layout.itemS()
+ layout.itemO("node.select_all")
+ layout.itemO("node.select_linked_from")
+ layout.itemO("node.select_linked_to")
class NODE_MT_node(bpy.types.Menu):
__space_type__ = 'NODE_EDITOR'
@@ -99,11 +98,10 @@ class NODE_MT_node(bpy.types.Menu):
# XXX
# layout.itemS()
# layout.itemO("node.make_link")
- # layout.itemS()
- # layout.itemO("node.edit_group")
- # layout.itemO("node.ungroup")
- # layout.itemO("node.group")
- # layout.itemO("node.make_link")
+ layout.itemS()
+ layout.itemO("node.group_edit")
+ layout.itemO("node.group_ungroup")
+ layout.itemO("node.group_make")
layout.itemS()
diff --git a/release/ui/space_outliner.py b/release/scripts/ui/space_outliner.py
index 522b620e29d..522b620e29d 100644
--- a/release/ui/space_outliner.py
+++ b/release/scripts/ui/space_outliner.py
diff --git a/release/ui/space_sequencer.py b/release/scripts/ui/space_sequencer.py
index daae4a83ec4..a804998cdaa 100644
--- a/release/ui/space_sequencer.py
+++ b/release/scripts/ui/space_sequencer.py
@@ -555,11 +555,9 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel):
return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
def draw_header(self, context):
- layout = self.layout
-
strip = act_strip(context)
- layout.itemR(strip, "use_proxy", text="")
+ self.layout.itemR(strip, "use_proxy", text="")
def draw(self, context):
layout = self.layout
diff --git a/release/ui/space_text.py b/release/scripts/ui/space_text.py
index 117033c50a1..117033c50a1 100644
--- a/release/ui/space_text.py
+++ b/release/scripts/ui/space_text.py
diff --git a/release/ui/space_time.py b/release/scripts/ui/space_time.py
index bb82eea3272..696dcf18623 100644
--- a/release/ui/space_time.py
+++ b/release/scripts/ui/space_time.py
@@ -9,7 +9,6 @@ class TIME_HT_header(bpy.types.Header):
st = context.space_data
scene = context.scene
- rd = context.scene.render_data
tools = context.tool_settings
screen = context.screen
@@ -55,7 +54,7 @@ class TIME_HT_header(bpy.types.Header):
subsub = row.row()
subsub.itemR(tools, "record_with_nla", toggle=True)
- layout.itemR(rd, "sync_audio", text="", toggle=True, icon='ICON_SPEAKER')
+ layout.itemR(scene, "sync_audio", text="", toggle=True, icon='ICON_SPEAKER')
layout.itemS()
@@ -112,7 +111,7 @@ class TIME_MT_playback(bpy.types.Menu):
layout = self.layout
st = context.space_data
- rd = context.scene.render_data
+ scene = context.scene
layout.itemR(st, "play_top_left")
layout.itemR(st, "play_all_3d")
@@ -120,6 +119,7 @@ class TIME_MT_playback(bpy.types.Menu):
layout.itemR(st, "play_buttons")
layout.itemR(st, "play_image")
layout.itemR(st, "play_sequencer")
+ layout.itemR(st, "play_nodes")
layout.itemS()
@@ -127,10 +127,10 @@ class TIME_MT_playback(bpy.types.Menu):
layout.itemS()
- layout.itemR(rd, "sync_audio", icon='ICON_SPEAKER')
+ layout.itemR(scene, "sync_audio", icon='ICON_SPEAKER')
+ layout.itemR(scene, "mute_audio")
+ layout.itemR(scene, "scrub_audio")
-
-
class TIME_MT_autokey(bpy.types.Menu):
__space_type__ = 'TIMELINE'
__label__ = "Auto-Keyframing Mode"
diff --git a/release/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index 636f9626957..a9126d2c7f1 100644
--- a/release/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -1,4 +1,4 @@
-
+
import bpy
class USERPREF_HT_header(bpy.types.Header):
@@ -97,14 +97,18 @@ class USERPREF_PT_view(bpy.types.Panel):
sub1 = sub.column()
sub1.itemL(text="Mouse Buttons:")
- sub1.itemR(view, "left_mouse_button_select")
- sub1.itemR(view, "right_mouse_button_select")
- sub1.itemR(view, "emulate_3_button_mouse")
+
+ sub2 = sub1.column()
+ sub2.enabled = (view.select_mouse == 'RIGHT')
+ sub2.itemR(view, "emulate_3_button_mouse")
+ sub1.itemL(text="Select With:")
+ sub1.row().itemR(view, "select_mouse", expand=True)
+ sub1.itemL(text="Middle Mouse:")
+ sub1.row().itemR(view, "middle_mouse", expand=True)
sub1.itemR(view, "use_middle_mouse_paste")
- sub1.itemR(view, "middle_mouse_rotate")
- sub1.itemR(view, "middle_mouse_pan")
- sub1.itemR(view, "wheel_invert_zoom")
- sub1.itemR(view, "wheel_scroll_lines")
+ sub1.itemL(text="Mouse Wheel:")
+ sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom")
+ sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines")
sub1.itemS()
sub1.itemS()
sub1.itemS()
@@ -156,15 +160,15 @@ class USERPREF_PT_edit(bpy.types.Panel):
sub = col.split(percentage=0.85)
sub1 = sub.column()
- sub1.itemL(text="Materials:")
- sub1.itemR(edit, "material_linked_object", text="Linked to Object")
- sub1.itemR(edit, "material_linked_obdata", text="Linked to ObData")
+ sub1.itemL(text="Link Materials To:")
+ sub1.row().itemR(edit, "material_link", expand=True)
sub1.itemS()
sub1.itemS()
sub1.itemS()
sub1.itemL(text="New Objects:")
sub1.itemR(edit, "enter_edit_mode")
- sub1.itemR(edit, "align_to_view")
+ sub1.itemL(text="Align To:")
+ sub1.row().itemR(edit, "object_align", expand=True)
sub1.itemS()
sub1.itemS()
sub1.itemS()
@@ -185,9 +189,9 @@ class USERPREF_PT_edit(bpy.types.Panel):
sub1.itemL(text="Grease Pencil:")
sub1.itemR(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance")
sub1.itemR(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance")
- sub1.itemR(edit, "grease_pencil_smooth_stroke", text="Smooth Stroke")
# sub1.itemR(edit, "grease_pencil_simplify_stroke", text="Simplify Stroke")
sub1.itemR(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
+ sub1.itemR(edit, "grease_pencil_smooth_stroke", text="Smooth Stroke")
col = split.column()
sub = col.split(percentage=0.85)
@@ -195,7 +199,7 @@ class USERPREF_PT_edit(bpy.types.Panel):
sub1 = sub.column()
sub1.itemL(text="Keyframing:")
sub1.itemR(edit, "use_visual_keying")
- sub1.itemR(edit, "new_interpolation_type")
+ sub1.itemR(edit, "new_interpolation_type", text="New F-Curves")
sub1.itemS()
sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing")
sub2 = sub1.column()
@@ -203,13 +207,16 @@ class USERPREF_PT_edit(bpy.types.Panel):
sub2.row().itemR(edit, "auto_keying_mode", expand=True)
sub2.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available")
sub2.itemR(edit, "auto_keyframe_insert_needed", text="Only Insert Needed")
+
sub1.itemS()
sub1.itemS()
sub1.itemS()
+
sub1.itemL(text="Undo:")
sub1.itemR(edit, "global_undo")
sub1.itemR(edit, "undo_steps", text="Steps")
sub1.itemR(edit, "undo_memory_limit", text="Memory Limit")
+
sub1.itemS()
sub1.itemS()
sub1.itemS()
@@ -218,7 +225,7 @@ class USERPREF_PT_edit(bpy.types.Panel):
sub = col.split(percentage=0.85)
sub1 = sub.column()
- sub1.itemL(text="Duplicate:")
+ sub1.itemL(text="Duplicate Data:")
sub1.itemR(edit, "duplicate_mesh", text="Mesh")
sub1.itemR(edit, "duplicate_surface", text="Surface")
sub1.itemR(edit, "duplicate_curve", text="Curve")
@@ -246,63 +253,64 @@ class USERPREF_PT_system(bpy.types.Panel):
userpref = context.user_preferences
system = userpref.system
- lan = userpref.language
split = layout.split()
col = split.column()
- sub = col.split(percentage=0.85)
+ sub = col.split(percentage=0.9)
sub1 = sub.column()
- sub1.itemR(system, "emulate_numpad")
+ sub1.itemL(text="General:")
+ sub1.itemR(system, "dpi")
+ sub1.itemR(system, "frame_server_port")
+ sub1.itemR(system, "scrollback", text="Console Scrollback")
+ sub1.itemR(system, "emulate_numpad")
+ sub1.itemR(system, "auto_run_python_scripts")
+
+ sub1.itemS()
sub1.itemS()
sub1.itemS()
- #Weight Colors
+ sub1.itemL(text="Sound:")
+ sub1.row().itemR(system, "audio_device", expand=True)
+ sub2 = sub1.column()
+ sub2.active = system.audio_device != 'AUDIO_DEVICE_NULL'
+ sub2.itemR(system, "enable_all_codecs")
+ sub2.itemR(system, "game_sound")
+ sub2.itemR(system, "audio_channels", text="Channels")
+ sub2.itemR(system, "audio_mixing_buffer", text="Mixing Buffer")
+ sub2.itemR(system, "audio_sample_rate", text="Sample Rate")
+ sub2.itemR(system, "audio_sample_format", text="Sample Format")
+
+ col = split.column()
+ sub = col.split(percentage=0.9)
+
+ sub1 = sub .column()
sub1.itemL(text="Weight Colors:")
sub1.itemR(system, "use_weight_color_range", text="Use Custom Range")
-
sub2 = sub1.column()
sub2.active = system.use_weight_color_range
- sub2.template_color_ramp(system.weight_color_range, expand=True)
+ sub2.template_color_ramp(system, "weight_color_range", expand=True)
+
+ sub1.itemS()
sub1.itemS()
sub1.itemS()
- #sequencer
- sub1.itemL(text="Sequencer:")
- sub1.itemR(system, "prefetch_frames")
- sub1.itemR(system, "memory_cache_limit")
-
- col = split.column()
- sub = col.split(percentage=0.85)
+ sub1.itemR(system, "language")
+ sub1.itemL(text="Translate:")
+ sub1.itemR(system, "translate_tooltips", text="Tooltips")
+ sub1.itemR(system, "translate_buttons", text="Labels")
+ sub1.itemR(system, "translate_toolbox", text="Toolbox")
- sub1 = sub .column()
- #System
- sub1.itemL(text="System:")
- sub1.itemR(lan, "dpi")
- sub1.itemR(system, "auto_run_python_scripts")
- sub1.itemR(system, "frame_server_port")
- sub1.itemR(system, "filter_file_extensions")
- sub1.itemR(system, "hide_dot_files_datablocks")
- sub1.itemR(lan, "scrollback", text="Console Scrollback")
- sub1.itemS()
sub1.itemS()
- sub1.itemL(text="Sound:")
- sub1.itemR(system, "audio_device")
- sub2 = sub1.column()
- sub2.active = system.audio_device != 'AUDIO_DEVICE_NULL'
- sub2.itemR(system, "enable_all_codecs")
- sub2.itemR(system, "game_sound")
- sub2.itemR(system, "audio_channels")
- sub2.itemR(system, "audio_mixing_buffer")
- sub2.itemR(system, "audio_sample_rate")
- sub2.itemR(system, "audio_sample_format")
+
+ sub1.itemR(system, "use_textured_fonts")
col = split.column()
- sub = col.split(percentage=0.85)
+ sub = col.split(percentage=0.9)
sub1 = sub.column()
- #OpenGL
+
sub1.itemL(text="OpenGL:")
sub1.itemR(system, "clip_alpha", slider=True)
sub1.itemR(system, "use_mipmaps")
@@ -312,7 +320,15 @@ class USERPREF_PT_system(bpy.types.Panel):
sub1.itemL(text="Textures:")
sub1.itemR(system, "gl_texture_limit", text="Limit Size")
sub1.itemR(system, "texture_time_out", text="Time Out")
- sub1.itemR(system, "texture_collection_rate", text="Collection Rate")
+ sub1.itemR(system, "texture_collection_rate", text="Collection Rate")
+
+ sub1.itemS()
+ sub1.itemS()
+ sub1.itemS()
+
+ sub1.itemL(text="Sequencer:")
+ sub1.itemR(system, "prefetch_frames")
+ sub1.itemR(system, "memory_cache_limit")
class USERPREF_PT_filepaths(bpy.types.Panel):
__space_type__ = 'USER_PREFERENCES'
@@ -329,7 +345,7 @@ class USERPREF_PT_filepaths(bpy.types.Panel):
userpref = context.user_preferences
paths = userpref.filepaths
- split = layout.split()
+ split = layout.split(percentage=0.6)
col = split.column()
col.itemL(text="File Paths:")
@@ -367,6 +383,8 @@ class USERPREF_PT_filepaths(bpy.types.Panel):
sub2.itemR(paths, "use_relative_paths")
sub2.itemR(paths, "compress_file")
sub2.itemR(paths, "load_ui")
+ sub2.itemR(paths, "filter_file_extensions")
+ sub2.itemR(paths, "hide_dot_files_datablocks")
sub2.itemS()
sub2.itemS()
sub2.itemL(text="Auto Save:")
@@ -378,36 +396,6 @@ class USERPREF_PT_filepaths(bpy.types.Panel):
sub3.enabled = paths.auto_save_temporary_files
sub3.itemR(paths, "auto_save_time", text="Timer (mins)")
-class USERPREF_PT_language(bpy.types.Panel):
- __space_type__ = 'USER_PREFERENCES'
- __label__ = "Language"
- __show_header__ = False
-
- def poll(self, context):
- userpref = context.user_preferences
- return (userpref.active_section == 'LANGUAGE_COLORS')
-
- def draw(self, context):
- layout = self.layout
-
- userpref = context.user_preferences
- lan = userpref.language
-
- split = layout.split()
- col = split.column()
-
- col.itemR(lan, "language")
- col.itemL(text="Translate:")
- col.itemR(lan, "translate_tooltips", text="Tooltips")
- col.itemR(lan, "translate_buttons", text="Labels")
- col.itemR(lan, "translate_toolbox", text="Toolbox")
- col.itemS()
- col.itemS()
- col.itemR(lan, "use_textured_fonts")
-
- col = split.column()
-
-
bpy.types.register(USERPREF_HT_header)
bpy.types.register(USERPREF_MT_view)
bpy.types.register(USERPREF_PT_tabs)
@@ -415,5 +403,4 @@ bpy.types.register(USERPREF_PT_view)
bpy.types.register(USERPREF_PT_edit)
bpy.types.register(USERPREF_PT_system)
bpy.types.register(USERPREF_PT_filepaths)
-bpy.types.register(USERPREF_PT_language)
diff --git a/release/ui/space_view3d.py b/release/scripts/ui/space_view3d.py
index df6579542d4..a270e053126 100644
--- a/release/ui/space_view3d.py
+++ b/release/scripts/ui/space_view3d.py
@@ -25,15 +25,17 @@ class VIEW3D_HT_header(bpy.types.Header):
# Select Menu
if mode_string not in ('EDIT_TEXT', 'SCULPT', 'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'):
- sub.itemM("VIEW3D_MT_select_%s" % mode_string)
+ sub.itemM("VIEW3D_MT_select_%s" % mode_string.lower())
if edit_object:
- sub.itemM("VIEW3D_MT_edit_%s" % edit_object.type)
+ sub.itemM("VIEW3D_MT_edit_%s" % edit_object.type.lower())
elif object:
ob_mode_string = object.mode
if mode_string not in ['PAINT_WEIGHT', 'PAINT_TEXTURE']:
- sub.itemM("VIEW3D_MT_%s" % mode_string)
+ sub.itemM("VIEW3D_MT_%s" % mode_string.lower())
+ else:
+ sub.itemM("VIEW3D_MT_object")
layout.template_header_3D()
@@ -134,6 +136,10 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu):
layout.item_floatO("view3d.zoom", "delta", 1.0, text="Zoom In")
layout.item_floatO("view3d.zoom", "delta", -1.0, text="Zoom Out")
+
+ layout.itemS()
+
+ layout.itemO("view3d.fly")
class VIEW3D_MT_view_align(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
@@ -153,7 +159,7 @@ class VIEW3D_MT_view_cameras(bpy.types.Menu):
# ********** Select menus, suffix from context.mode **********
-class VIEW3D_MT_select_OBJECT(bpy.types.Menu):
+class VIEW3D_MT_select_object(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -172,7 +178,7 @@ class VIEW3D_MT_select_OBJECT(bpy.types.Menu):
layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...")
layout.itemO("object.select_grouped", text="Select Grouped...")
-class VIEW3D_MT_select_POSE(bpy.types.Menu):
+class VIEW3D_MT_select_pose(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -203,7 +209,7 @@ class VIEW3D_MT_select_POSE(bpy.types.Menu):
props.extend = True
props.direction = 'CHILD'
-class VIEW3D_MT_select_PARTICLE(bpy.types.Menu):
+class VIEW3D_MT_select_particle(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -222,7 +228,7 @@ class VIEW3D_MT_select_PARTICLE(bpy.types.Menu):
layout.itemO("particle.select_more")
layout.itemO("particle.select_less")
-class VIEW3D_MT_select_EDIT_MESH(bpy.types.Menu):
+class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -266,7 +272,7 @@ class VIEW3D_MT_select_EDIT_MESH(bpy.types.Menu):
layout.itemO("mesh.loop_to_region")
layout.itemO("mesh.region_to_loop")
-class VIEW3D_MT_select_EDIT_CURVE(bpy.types.Menu):
+class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -295,7 +301,7 @@ class VIEW3D_MT_select_EDIT_CURVE(bpy.types.Menu):
layout.itemO("curve.select_more")
layout.itemO("curve.select_less")
-class VIEW3D_MT_select_EDIT_SURFACE(bpy.types.Menu):
+class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -321,7 +327,7 @@ class VIEW3D_MT_select_EDIT_SURFACE(bpy.types.Menu):
layout.itemO("curve.select_more")
layout.itemO("curve.select_less")
-class VIEW3D_MT_select_EDIT_METABALL(bpy.types.Menu):
+class VIEW3D_MT_select_edit_metaball(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -339,7 +345,7 @@ class VIEW3D_MT_select_EDIT_METABALL(bpy.types.Menu):
layout.itemO("mball.select_random_metaelems")
-class VIEW3D_MT_select_EDIT_LATTICE(bpy.types.Menu):
+class VIEW3D_MT_select_edit_lattice(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -352,7 +358,7 @@ class VIEW3D_MT_select_EDIT_LATTICE(bpy.types.Menu):
layout.itemO("lattice.select_all_toggle", text="Select/Deselect All")
-class VIEW3D_MT_select_EDIT_ARMATURE(bpy.types.Menu):
+class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -381,7 +387,7 @@ class VIEW3D_MT_select_EDIT_ARMATURE(bpy.types.Menu):
props.extend = True
props.direction = 'CHILD'
-class VIEW3D_MT_select_FACE(bpy.types.Menu):# XXX no matching enum
+class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum
__space_type__ = 'VIEW_3D'
__label__ = "Select"
@@ -392,7 +398,7 @@ class VIEW3D_MT_select_FACE(bpy.types.Menu):# XXX no matching enum
# ********** Object menu **********
-class VIEW3D_MT_OBJECT(bpy.types.Menu):
+class VIEW3D_MT_object(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__context__ = "objectmode"
__label__ = "Object"
@@ -400,7 +406,7 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.itemM("VIEW3D_MT_OBJECT_clear")
+ layout.itemM("VIEW3D_MT_object_clear")
layout.itemM("VIEW3D_MT_snap")
layout.itemS()
@@ -417,10 +423,10 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_OBJECT_parent")
- layout.itemM("VIEW3D_MT_OBJECT_track")
- layout.itemM("VIEW3D_MT_OBJECT_group")
- layout.itemM("VIEW3D_MT_OBJECT_constraints")
+ layout.itemM("VIEW3D_MT_object_parent")
+ layout.itemM("VIEW3D_MT_object_track")
+ layout.itemM("VIEW3D_MT_object_group")
+ layout.itemM("VIEW3D_MT_object_constraints")
layout.itemS()
@@ -428,9 +434,9 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_OBJECT_showhide")
+ layout.itemM("VIEW3D_MT_object_showhide")
-class VIEW3D_MT_OBJECT_clear(bpy.types.Menu):
+class VIEW3D_MT_object_clear(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Clear"
@@ -442,7 +448,7 @@ class VIEW3D_MT_OBJECT_clear(bpy.types.Menu):
layout.itemO("object.scale_clear", text="Scale")
layout.itemO("object.origin_clear", text="Origin")
-class VIEW3D_MT_OBJECT_parent(bpy.types.Menu):
+class VIEW3D_MT_object_parent(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Parent"
@@ -452,7 +458,7 @@ class VIEW3D_MT_OBJECT_parent(bpy.types.Menu):
layout.itemO("object.parent_set", text="Set")
layout.itemO("object.parent_clear", text="Clear")
-class VIEW3D_MT_OBJECT_track(bpy.types.Menu):
+class VIEW3D_MT_object_track(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Track"
@@ -462,7 +468,7 @@ class VIEW3D_MT_OBJECT_track(bpy.types.Menu):
layout.itemO("object.track_set", text="Set")
layout.itemO("object.track_clear", text="Clear")
-class VIEW3D_MT_OBJECT_group(bpy.types.Menu):
+class VIEW3D_MT_object_group(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Group"
@@ -477,7 +483,7 @@ class VIEW3D_MT_OBJECT_group(bpy.types.Menu):
layout.itemO("group.objects_add_active")
layout.itemO("group.objects_remove_active")
-class VIEW3D_MT_OBJECT_constraints(bpy.types.Menu):
+class VIEW3D_MT_object_constraints(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Constraints"
@@ -487,7 +493,7 @@ class VIEW3D_MT_OBJECT_constraints(bpy.types.Menu):
layout.itemO("object.constraint_add_with_targets")
layout.itemO("object.constraints_clear")
-class VIEW3D_MT_OBJECT_showhide(bpy.types.Menu):
+class VIEW3D_MT_object_showhide(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Show/Hide"
@@ -500,7 +506,7 @@ class VIEW3D_MT_OBJECT_showhide(bpy.types.Menu):
# ********** Vertex paint menu **********
-class VIEW3D_MT_PAINT_VERTEX(bpy.types.Menu):
+class VIEW3D_MT_paint_vertex(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Paint"
@@ -515,7 +521,7 @@ class VIEW3D_MT_PAINT_VERTEX(bpy.types.Menu):
# ********** Sculpt menu **********
-class VIEW3D_MT_SCULPT(bpy.types.Menu):
+class VIEW3D_MT_sculpt(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Sculpt"
@@ -537,21 +543,21 @@ class VIEW3D_MT_SCULPT(bpy.types.Menu):
layout.itemS()
if brush.sculpt_tool != 'GRAB':
- layout.itemR(brush, "airbrush")
+ layout.itemR(brush, "use_airbrush")
if brush.sculpt_tool != 'LAYER':
- layout.itemR(brush, "anchored")
+ layout.itemR(brush, "use_anchor")
if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'):
layout.itemR(brush, "flip_direction")
if brush.sculpt_tool == 'LAYER':
- layout.itemR(brush, "persistent")
+ layout.itemR(brush, "use_persistent")
layout.itemO("sculpt.set_persistent_base")
# ********** Particle menu **********
-class VIEW3D_MT_PARTICLE(bpy.types.Menu):
+class VIEW3D_MT_particle(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Particle"
@@ -574,14 +580,14 @@ class VIEW3D_MT_PARTICLE(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_PARTICLE_showhide")
+ layout.itemM("VIEW3D_MT_particle_showhide")
-class VIEW3D_MT_PARTICLE_showhide(VIEW3D_MT_showhide):
+class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide):
_operator_name = "particle"
# ********** Pose Menu **********
-class VIEW3D_MT_POSE(bpy.types.Menu):
+class VIEW3D_MT_pose(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Pose"
@@ -593,7 +599,7 @@ class VIEW3D_MT_POSE(bpy.types.Menu):
if arm.drawtype in ('BBONE', 'ENVELOPE'):
layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale Envelope Distance")
- layout.itemM("VIEW3D_MT_POSE_transform")
+ layout.itemM("VIEW3D_MT_pose_transform")
layout.itemS()
@@ -612,14 +618,14 @@ class VIEW3D_MT_POSE(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_POSE_pose")
- layout.itemM("VIEW3D_MT_POSE_motion")
- layout.itemM("VIEW3D_MT_POSE_group")
+ layout.itemM("VIEW3D_MT_pose_pose")
+ layout.itemM("VIEW3D_MT_pose_motion")
+ layout.itemM("VIEW3D_MT_pose_group")
layout.itemS()
- layout.itemM("VIEW3D_MT_POSE_ik")
- layout.itemM("VIEW3D_MT_POSE_constraints")
+ layout.itemM("VIEW3D_MT_pose_ik")
+ layout.itemM("VIEW3D_MT_pose_constraints")
layout.itemS()
@@ -638,10 +644,10 @@ class VIEW3D_MT_POSE(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_POSE_showhide")
+ layout.itemM("VIEW3D_MT_pose_showhide")
layout.item_menu_enumO("pose.flags_set", 'mode', text="Bone Settings")
-class VIEW3D_MT_POSE_transform(bpy.types.Menu):
+class VIEW3D_MT_pose_transform(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Clear Transform"
@@ -656,7 +662,7 @@ class VIEW3D_MT_POSE_transform(bpy.types.Menu):
layout.itemL(text="Origin")
-class VIEW3D_MT_POSE_pose(bpy.types.Menu):
+class VIEW3D_MT_pose_pose(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Pose Library"
@@ -671,7 +677,7 @@ class VIEW3D_MT_POSE_pose(bpy.types.Menu):
layout.itemO("poselib.pose_rename", text="Rename Pose...")
layout.itemO("poselib.pose_remove", text="Remove Pose...")
-class VIEW3D_MT_POSE_motion(bpy.types.Menu):
+class VIEW3D_MT_pose_motion(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Motion Paths"
@@ -681,7 +687,7 @@ class VIEW3D_MT_POSE_motion(bpy.types.Menu):
layout.itemO("pose.paths_calculate", text="Calculate")
layout.itemO("pose.paths_clear", text="Clear")
-class VIEW3D_MT_POSE_group(bpy.types.Menu):
+class VIEW3D_MT_pose_group(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Bone Groups"
@@ -696,7 +702,7 @@ class VIEW3D_MT_POSE_group(bpy.types.Menu):
layout.itemO("pose.group_unassign")
-class VIEW3D_MT_POSE_ik(bpy.types.Menu):
+class VIEW3D_MT_pose_ik(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Inverse Kinematics"
@@ -706,7 +712,7 @@ class VIEW3D_MT_POSE_ik(bpy.types.Menu):
layout.itemO("pose.ik_add")
layout.itemO("pose.ik_clear")
-class VIEW3D_MT_POSE_constraints(bpy.types.Menu):
+class VIEW3D_MT_pose_constraints(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Constraints"
@@ -716,13 +722,13 @@ class VIEW3D_MT_POSE_constraints(bpy.types.Menu):
layout.itemO("pose.constraint_add_with_targets", text="Add (With Targets)...")
layout.itemO("pose.constraints_clear")
-class VIEW3D_MT_POSE_showhide(VIEW3D_MT_showhide):
+class VIEW3D_MT_pose_showhide(VIEW3D_MT_showhide):
_operator_name = "pose"
# ********** Edit Menus, suffix from ob.type **********
# Edit MESH
-class VIEW3D_MT_edit_MESH(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Mesh"
@@ -750,10 +756,10 @@ class VIEW3D_MT_edit_MESH(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_MESH_vertices")
- layout.itemM("VIEW3D_MT_edit_MESH_edges")
- layout.itemM("VIEW3D_MT_edit_MESH_faces")
- layout.itemM("VIEW3D_MT_edit_MESH_normals")
+ layout.itemM("VIEW3D_MT_edit_mesh_vertices")
+ layout.itemM("VIEW3D_MT_edit_mesh_edges")
+ layout.itemM("VIEW3D_MT_edit_mesh_faces")
+ layout.itemM("VIEW3D_MT_edit_mesh_normals")
layout.itemS()
@@ -763,9 +769,9 @@ class VIEW3D_MT_edit_MESH(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_MESH_showhide")
+ layout.itemM("VIEW3D_MT_edit_mesh_showhide")
-class VIEW3D_MT_edit_MESH_vertices(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Vertices"
@@ -782,7 +788,7 @@ class VIEW3D_MT_edit_MESH_vertices(bpy.types.Menu):
layout.itemO("mesh.vertices_smooth")
layout.itemO("mesh.remove_doubles")
-class VIEW3D_MT_edit_MESH_edges(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Edges"
@@ -807,7 +813,7 @@ class VIEW3D_MT_edit_MESH_edges(bpy.types.Menu):
layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW")
layout.item_enumO("mesh.edge_rotate", "direction", 'CCW', text="Rotate Edge CCW")
-class VIEW3D_MT_edit_MESH_faces(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Faces"
@@ -829,7 +835,7 @@ class VIEW3D_MT_edit_MESH_faces(bpy.types.Menu):
layout.itemO("mesh.faces_shade_smooth")
layout.itemO("mesh.faces_shade_flat")
-class VIEW3D_MT_edit_MESH_normals(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Normals"
@@ -843,13 +849,13 @@ class VIEW3D_MT_edit_MESH_normals(bpy.types.Menu):
layout.itemO("mesh.flip_normals")
-class VIEW3D_MT_edit_MESH_showhide(VIEW3D_MT_showhide):
+class VIEW3D_MT_edit_mesh_showhide(VIEW3D_MT_showhide):
_operator_name = "mesh"
-# Edit CURVE
+# Edit Curve
-# draw_CURVE is used by VIEW3D_MT_edit_CURVE and VIEW3D_MT_edit_SURFACE
-def draw_CURVE(self, context):
+# draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
+def draw_curve(self, context):
layout = self.layout
settings = context.tool_settings
@@ -867,8 +873,8 @@ def draw_CURVE(self, context):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_CURVE_ctrlpoints")
- layout.itemM("VIEW3D_MT_edit_CURVE_segments")
+ layout.itemM("VIEW3D_MT_edit_curve_ctrlpoints")
+ layout.itemM("VIEW3D_MT_edit_curve_segments")
layout.itemS()
@@ -877,15 +883,15 @@ def draw_CURVE(self, context):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_CURVE_showhide")
+ layout.itemM("VIEW3D_MT_edit_curve_showhide")
-class VIEW3D_MT_edit_CURVE(bpy.types.Menu):
+class VIEW3D_MT_edit_curve(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Curve"
- draw = draw_CURVE
+ draw = draw_curve
-class VIEW3D_MT_edit_CURVE_ctrlpoints(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Control Points"
@@ -903,7 +909,7 @@ class VIEW3D_MT_edit_CURVE_ctrlpoints(bpy.types.Menu):
layout.item_menu_enumO("curve.handle_type_set", "type")
-class VIEW3D_MT_edit_CURVE_segments(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Segments"
@@ -913,18 +919,18 @@ class VIEW3D_MT_edit_CURVE_segments(bpy.types.Menu):
layout.itemO("curve.subdivide")
layout.itemO("curve.switch_direction")
-class VIEW3D_MT_edit_CURVE_showhide(VIEW3D_MT_showhide):
+class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide):
_operator_name = "curve"
# Edit SURFACE
-class VIEW3D_MT_edit_SURFACE(bpy.types.Menu):
+class VIEW3D_MT_edit_surface(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Surface"
- draw = draw_CURVE
+ draw = draw_curve
# Edit TEXT
-class VIEW3D_MT_edit_TEXT(bpy.types.Menu):
+class VIEW3D_MT_edit_text(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Text"
@@ -935,9 +941,9 @@ class VIEW3D_MT_edit_TEXT(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_TEXT_chars")
+ layout.itemm("view3d_mt_edit_text_chars")
-class VIEW3D_MT_edit_TEXT_chars(bpy.types.Menu):
+class VIEW3D_MT_edit_text_chars(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Special Characters"
@@ -972,7 +978,7 @@ class VIEW3D_MT_edit_TEXT_chars(bpy.types.Menu):
layout.item_stringO("font.text_insert", "text", b'\xC2\xA1'.decode(), text="Spanish Exclamation Mark|Alt !")
# Edit META
-class VIEW3D_MT_edit_META(bpy.types.Menu):
+class VIEW3D_MT_edit_meta(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Metaball"
@@ -1000,9 +1006,9 @@ class VIEW3D_MT_edit_META(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_META_showhide")
+ layout.itemM("VIEW3D_MT_edit_meta_showhide")
-class VIEW3D_MT_edit_META_showhide(bpy.types.Menu):
+class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Show/Hide"
@@ -1014,7 +1020,7 @@ class VIEW3D_MT_edit_META_showhide(bpy.types.Menu):
layout.item_booleanO("mball.hide_metaelems", "unselected", True, text="Hide Unselected")
# Edit LATTICE
-class VIEW3D_MT_edit_LATTICE(bpy.types.Menu):
+class VIEW3D_MT_edit_lattice(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Lattice"
@@ -1035,7 +1041,7 @@ class VIEW3D_MT_edit_LATTICE(bpy.types.Menu):
layout.item_menu_enumR(settings, "proportional_editing_falloff")
# Edit ARMATURE
-class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu):
+class VIEW3D_MT_edit_armature(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Armature"
@@ -1046,7 +1052,7 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu):
arm = edit_object.data
layout.itemM("VIEW3D_MT_snap")
- layout.itemM("VIEW3D_MT_edit_ARMATURE_roll")
+ layout.itemM("VIEW3D_MT_edit_armature_roll")
if arm.drawtype == 'ENVELOPE':
layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale Envelope Distance")
@@ -1086,13 +1092,13 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu):
layout.itemS()
- layout.itemM("VIEW3D_MT_edit_ARMATURE_parent")
+ layout.itemM("VIEW3D_MT_edit_armature_parent")
layout.itemS()
layout.item_menu_enumO("armature.flags_set", "mode", text="Bone Settings")
-class VIEW3D_MT_edit_ARMATURE_parent(bpy.types.Menu):
+class VIEW3D_MT_edit_armature_parent(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Parent"
@@ -1102,7 +1108,7 @@ class VIEW3D_MT_edit_ARMATURE_parent(bpy.types.Menu):
layout.itemO("armature.parent_set", text="Make")
layout.itemO("armature.parent_clear", text="Clear")
-class VIEW3D_MT_edit_ARMATURE_roll(bpy.types.Menu):
+class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
__space_type__ = 'VIEW_3D'
__label__ = "Bone Roll"
@@ -1134,16 +1140,17 @@ class VIEW3D_PT_3dview_properties(bpy.types.Panel):
scene = context.scene
col = layout.column()
- col.itemR(view, "camera")
+ col.itemL(text="Camera:")
+ col.itemR(view, "camera", text="")
col.itemR(view, "lens")
- layout.itemL(text="Clip:")
col = layout.column(align=True)
+ col.itemL(text="Clip:")
col.itemR(view, "clip_start", text="Start")
col.itemR(view, "clip_end", text="End")
- layout.itemL(text="Grid:")
col = layout.column(align=True)
+ col.itemL(text="Grid:")
col.itemR(view, "grid_lines", text="Lines")
col.itemR(view, "grid_spacing", text="Spacing")
col.itemR(view, "grid_subdivisions", text="Subdivisions")
@@ -1154,7 +1161,8 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel):
__space_type__ = 'VIEW_3D'
__region_type__ = 'UI'
__label__ = "Display"
-
+ __default_closed__ = True
+
def poll(self, context):
view = context.space_data
return (view)
@@ -1175,7 +1183,7 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel):
layout.itemS()
- layout.itemO("screen.region_foursplit")
+ layout.itemO("screen.region_foursplit", text="Toggle Quad View")
col = layout.column()
col.itemR(view, "lock_rotation")
@@ -1270,12 +1278,33 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
#col.itemR(bg, "image_user")
col.itemR(bg, "size")
col.itemR(bg, "transparency", slider=True)
- col.itemL(text="Offset:")
+
col = layout.column(align=True)
+ col.itemL(text="Offset:")
col.itemR(bg, "offset_x", text="X")
col.itemR(bg, "offset_y", text="Y")
+class VIEW3D_PT_transform_orientations(bpy.types.Panel):
+ __space_type__ = 'VIEW_3D'
+ __region_type__ = 'UI'
+ __label__ = "Transform Orientations"
+ __default_closed__ = True
+
+ def poll(self, context):
+ view = context.space_data
+ return (view)
+
+ def draw(self, context):
+ layout = self.layout
+
+ view = context.space_data
+
+ col = layout.column()
+ col.itemO("TFM_OT_select_orientation", text="Select")
+ col.itemO("TFM_OT_create_orientation", text="Create")
+ col.itemO("TFM_OT_delete_orientation", text="Delete")
+
bpy.types.register(VIEW3D_HT_header) # Header
bpy.types.register(VIEW3D_MT_view) #View Menus
@@ -1283,71 +1312,72 @@ bpy.types.register(VIEW3D_MT_view_navigation)
bpy.types.register(VIEW3D_MT_view_align)
bpy.types.register(VIEW3D_MT_view_cameras)
-bpy.types.register(VIEW3D_MT_select_OBJECT) # Select Menus
-bpy.types.register(VIEW3D_MT_select_POSE)
-bpy.types.register(VIEW3D_MT_select_PARTICLE)
-bpy.types.register(VIEW3D_MT_select_EDIT_MESH)
-bpy.types.register(VIEW3D_MT_select_EDIT_CURVE)
-bpy.types.register(VIEW3D_MT_select_EDIT_SURFACE)
-bpy.types.register(VIEW3D_MT_select_EDIT_METABALL)
-bpy.types.register(VIEW3D_MT_select_EDIT_LATTICE)
-bpy.types.register(VIEW3D_MT_select_EDIT_ARMATURE)
-bpy.types.register(VIEW3D_MT_select_FACE) # XXX todo
-
-bpy.types.register(VIEW3D_MT_OBJECT) # Object Menu
-bpy.types.register(VIEW3D_MT_OBJECT_clear)
-bpy.types.register(VIEW3D_MT_OBJECT_parent)
-bpy.types.register(VIEW3D_MT_OBJECT_track)
-bpy.types.register(VIEW3D_MT_OBJECT_group)
-bpy.types.register(VIEW3D_MT_OBJECT_constraints)
-bpy.types.register(VIEW3D_MT_OBJECT_showhide)
-
-bpy.types.register(VIEW3D_MT_SCULPT) # Sculpt Menu
-
-bpy.types.register(VIEW3D_MT_PAINT_VERTEX)
-
-bpy.types.register(VIEW3D_MT_PARTICLE) # Particle Menu
-bpy.types.register(VIEW3D_MT_PARTICLE_showhide)
-
-bpy.types.register(VIEW3D_MT_POSE) # POSE Menu
-bpy.types.register(VIEW3D_MT_POSE_transform)
-bpy.types.register(VIEW3D_MT_POSE_pose)
-bpy.types.register(VIEW3D_MT_POSE_motion)
-bpy.types.register(VIEW3D_MT_POSE_group)
-bpy.types.register(VIEW3D_MT_POSE_ik)
-bpy.types.register(VIEW3D_MT_POSE_constraints)
-bpy.types.register(VIEW3D_MT_POSE_showhide)
+bpy.types.register(VIEW3D_MT_select_object) # Select Menus
+bpy.types.register(VIEW3D_MT_select_pose)
+bpy.types.register(VIEW3D_MT_select_particle)
+bpy.types.register(VIEW3D_MT_select_edit_mesh)
+bpy.types.register(VIEW3D_MT_select_edit_curve)
+bpy.types.register(VIEW3D_MT_select_edit_surface)
+bpy.types.register(VIEW3D_MT_select_edit_metaball)
+bpy.types.register(VIEW3D_MT_select_edit_lattice)
+bpy.types.register(VIEW3D_MT_select_edit_armature)
+bpy.types.register(VIEW3D_MT_select_face) # XXX todo
+
+bpy.types.register(VIEW3D_MT_object) # Object Menu
+bpy.types.register(VIEW3D_MT_object_clear)
+bpy.types.register(VIEW3D_MT_object_parent)
+bpy.types.register(VIEW3D_MT_object_track)
+bpy.types.register(VIEW3D_MT_object_group)
+bpy.types.register(VIEW3D_MT_object_constraints)
+bpy.types.register(VIEW3D_MT_object_showhide)
+
+bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu
+
+bpy.types.register(VIEW3D_MT_paint_vertex)
+
+bpy.types.register(VIEW3D_MT_particle) # Particle Menu
+bpy.types.register(VIEW3D_MT_particle_showhide)
+
+bpy.types.register(VIEW3D_MT_pose) # POSE Menu
+bpy.types.register(VIEW3D_MT_pose_transform)
+bpy.types.register(VIEW3D_MT_pose_pose)
+bpy.types.register(VIEW3D_MT_pose_motion)
+bpy.types.register(VIEW3D_MT_pose_group)
+bpy.types.register(VIEW3D_MT_pose_ik)
+bpy.types.register(VIEW3D_MT_pose_constraints)
+bpy.types.register(VIEW3D_MT_pose_showhide)
bpy.types.register(VIEW3D_MT_snap) # Edit Menus
-bpy.types.register(VIEW3D_MT_edit_MESH)
-bpy.types.register(VIEW3D_MT_edit_MESH_vertices)
-bpy.types.register(VIEW3D_MT_edit_MESH_edges)
-bpy.types.register(VIEW3D_MT_edit_MESH_faces)
-bpy.types.register(VIEW3D_MT_edit_MESH_normals)
-bpy.types.register(VIEW3D_MT_edit_MESH_showhide)
+bpy.types.register(VIEW3D_MT_edit_mesh)
+bpy.types.register(VIEW3D_MT_edit_mesh_vertices)
+bpy.types.register(VIEW3D_MT_edit_mesh_edges)
+bpy.types.register(VIEW3D_MT_edit_mesh_faces)
+bpy.types.register(VIEW3D_MT_edit_mesh_normals)
+bpy.types.register(VIEW3D_MT_edit_mesh_showhide)
-bpy.types.register(VIEW3D_MT_edit_CURVE)
-bpy.types.register(VIEW3D_MT_edit_CURVE_ctrlpoints)
-bpy.types.register(VIEW3D_MT_edit_CURVE_segments)
-bpy.types.register(VIEW3D_MT_edit_CURVE_showhide)
+bpy.types.register(VIEW3D_MT_edit_curve)
+bpy.types.register(VIEW3D_MT_edit_curve_ctrlpoints)
+bpy.types.register(VIEW3D_MT_edit_curve_segments)
+bpy.types.register(VIEW3D_MT_edit_curve_showhide)
-bpy.types.register(VIEW3D_MT_edit_SURFACE)
+bpy.types.register(VIEW3D_MT_edit_surface)
-bpy.types.register(VIEW3D_MT_edit_TEXT)
-bpy.types.register(VIEW3D_MT_edit_TEXT_chars)
+bpy.types.register(VIEW3D_MT_edit_text)
+bpy.types.register(VIEW3D_MT_edit_text_chars)
-bpy.types.register(VIEW3D_MT_edit_META)
-bpy.types.register(VIEW3D_MT_edit_META_showhide)
+bpy.types.register(VIEW3D_MT_edit_meta)
+bpy.types.register(VIEW3D_MT_edit_meta_showhide)
-bpy.types.register(VIEW3D_MT_edit_LATTICE)
+bpy.types.register(VIEW3D_MT_edit_lattice)
-bpy.types.register(VIEW3D_MT_edit_ARMATURE)
-bpy.types.register(VIEW3D_MT_edit_ARMATURE_parent)
-bpy.types.register(VIEW3D_MT_edit_ARMATURE_roll)
+bpy.types.register(VIEW3D_MT_edit_armature)
+bpy.types.register(VIEW3D_MT_edit_armature_parent)
+bpy.types.register(VIEW3D_MT_edit_armature_roll)
bpy.types.register(VIEW3D_PT_3dview_properties) # Panels
bpy.types.register(VIEW3D_PT_3dview_display)
bpy.types.register(VIEW3D_PT_3dview_meshdisplay)
bpy.types.register(VIEW3D_PT_3dview_curvedisplay)
bpy.types.register(VIEW3D_PT_background_image)
+bpy.types.register(VIEW3D_PT_transform_orientations) \ No newline at end of file
diff --git a/release/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py
index 9dd2df14492..4c1b54ea8e6 100644
--- a/release/ui/space_view3d_toolbar.py
+++ b/release/scripts/ui/space_view3d_toolbar.py
@@ -14,36 +14,32 @@ class VIEW3D_PT_tools_objectmode(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
- layout.itemL(text="Object:")
-
col = layout.column(align=True)
+ col.itemL(text="Object:")
col.itemO("object.duplicate")
col.itemO("object.delete")
active_object= context.active_object
if active_object and active_object.type == 'MESH':
- layout.itemL(text="Shading:")
-
+
col = layout.column(align=True)
+ col.itemL(text="Shading:")
col.itemO("object.shade_smooth", text="Smooth")
col.itemO("object.shade_flat", text="Flat")
- layout.itemL(text="Keyframes:")
-
col = layout.column(align=True)
+ col.itemL(text="Keyframes:")
col.itemO("anim.insert_keyframe_menu", text="Insert")
col.itemO("anim.delete_keyframe_v3d", text="Remove")
- layout.itemL(text="Repeat:")
-
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -57,43 +53,40 @@ class VIEW3D_PT_tools_meshedit(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
- layout.itemL(text="Mesh:")
-
col = layout.column(align=True)
+ col.itemL(text="Mesh:")
col.itemO("mesh.duplicate")
col.itemO("mesh.delete")
- layout.itemL(text="Modeling:")
-
col = layout.column(align=True)
+ col.itemL(text="Modeling:")
col.itemO("mesh.extrude")
col.itemO("mesh.subdivide")
+ col.itemO("mesh.loopcut")
col.itemO("mesh.spin")
col.itemO("mesh.screw")
-
- layout.itemL(text="Shading:")
+ col.itemO("mesh.merge")
+ col.itemO("mesh.rip_move")
col = layout.column(align=True)
+ col.itemL(text="Shading:")
col.itemO("mesh.faces_shade_smooth", text="Smooth")
col.itemO("mesh.faces_shade_flat", text="Flat")
- layout.itemL(text="UV Mapping:")
-
col = layout.column(align=True)
+ col.itemL(text="UV Mapping:")
col.itemO("uv.mapping_menu", text="Unwrap")
col.itemO("mesh.uvs_rotate")
col.itemO("mesh.uvs_mirror")
- layout.itemL(text="Repeat:")
-
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -107,31 +100,34 @@ class VIEW3D_PT_tools_curveedit(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
-
- layout.itemL(text="Curve:")
col = layout.column(align=True)
+ col.itemL(text="Curve:")
col.itemO("curve.duplicate")
col.itemO("curve.delete")
col.itemO("curve.cyclic_toggle")
col.itemO("curve.switch_direction")
col.itemO("curve.spline_type_set")
- layout.itemL(text="Modeling:")
-
col = layout.column(align=True)
+ col.itemL(text="Handles:")
+ col.item_enumO("curve.handle_type_set", "type", 'AUTOMATIC')
+ col.item_enumO("curve.handle_type_set", "type", 'VECTOR')
+ col.item_enumO("curve.handle_type_set", "type", 'ALIGN')
+ col.item_enumO("curve.handle_type_set", "type", 'FREE_ALIGN')
+
+ col = layout.column(align=True)
+ col.itemL(text="Modeling:")
col.itemO("curve.extrude")
col.itemO("curve.subdivide")
- layout.itemL(text="Repeat:")
-
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -145,30 +141,26 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
- layout.itemL(text="Curve:")
-
col = layout.column(align=True)
+ col.itemL(text="Curve:")
col.itemO("curve.duplicate")
col.itemO("curve.delete")
col.itemO("curve.cyclic_toggle")
col.itemO("curve.switch_direction")
- layout.itemL(text="Modeling:")
-
col = layout.column(align=True)
+ col.itemL(text="Modeling:")
col.itemO("curve.extrude")
col.itemO("curve.subdivide")
- layout.itemL(text="Repeat:")
-
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -181,23 +173,20 @@ class VIEW3D_PT_tools_textedit(View3DPanel):
def draw(self, context):
layout = self.layout
-
- layout.itemL(text="Text Edit:")
-
+
col = layout.column(align=True)
+ col.itemL(text="Text Edit:")
col.itemO("font.text_copy", text="Copy")
col.itemO("font.text_cut", text="Cut")
col.itemO("font.text_paste", text="Paste")
- layout.itemL(text="Style:")
-
col = layout.column(align=True)
+ col.itemL(text="Style:")
col.itemO("font.case_set")
col.itemO("font.style_toggle")
-
- layout.itemL(text="Repeat:")
-
+
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -210,27 +199,25 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel):
def draw(self, context):
layout = self.layout
-
- layout.itemL(text="Transform:")
-
+
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
-
- layout.itemL(text="Bones:")
col = layout.column(align=True)
+ col.itemL(text="Bones:")
col.itemO("armature.bone_primitive_add", text="Add")
col.itemO("armature.duplicate", text="Duplicate")
col.itemO("armature.delete", text="Delete")
- layout.itemL(text="Modeling:")
- layout.itemO("armature.extrude")
-
- layout.itemL(text="Repeat:")
+ col = layout.column(align=True)
+ col.itemL(text="Modeling:")
+ col.itemO("armature.extrude")
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -244,16 +231,14 @@ class VIEW3D_PT_tools_mballedit(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
- layout.itemL(text="Repeat:")
-
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -267,16 +252,14 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
- layout.itemL(text="Repeat:")
-
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -290,40 +273,37 @@ class VIEW3D_PT_tools_posemode(View3DPanel):
def draw(self, context):
layout = self.layout
- layout.itemL(text="Transform:")
-
col = layout.column(align=True)
+ col.itemL(text="Transform:")
col.itemO("tfm.translate")
col.itemO("tfm.rotate")
col.itemO("tfm.resize", text="Scale")
- layout.itemL(text="Bones:")
-
col = layout.column(align=True)
+ col.itemL(text="Bones:")
col.itemO("pose.hide", text="Hide")
col.itemO("pose.reveal", text="Reveal")
- layout.itemL(text="Keyframes:")
-
col = layout.column(align=True)
+ col.itemL(text="Keyframes:")
col.itemO("anim.insert_keyframe_menu", text="Insert")
col.itemO("anim.delete_keyframe_v3d", text="Remove")
- layout.itemL(text="Pose:")
-
col = layout.column(align=True)
+ col.itemL(text="Pose:")
col.itemO("pose.copy", text="Copy")
col.itemO("pose.paste", text="Paste")
-
- layout.itemL(text="Library:")
+ col.itemO("poselib.pose_add", text="Add To Library")
+ col.itemO("poselib.browse_interactive", text="Browse Library")
col = layout.column(align=True)
- col.itemO("poselib.pose_add", text="Add")
- col.itemO("poselib.pose_remove", text="Remove")
-
- layout.itemL(text="Repeat:")
+ col.itemL(text="In-Between:")
+ col.itemO("pose.relax", text="Relax")
+ col.itemO("pose.push", text="Push")
+ col.itemO("pose.breakdown", text="Breakdowner")
col = layout.column(align=True)
+ col.itemL(text="Repeat:")
col.itemO("screen.repeat_last")
col.itemO("screen.repeat_history", text="History...")
col.itemO("screen.redo_last", text="Tweak...")
@@ -382,7 +362,6 @@ class VIEW3D_PT_tools_brush(PaintPanel):
col.itemR(brush, "strength", slider=True)
if settings.tool == 'ADD':
-
col = layout.column()
col.itemR(settings, "add_interpolate")
sub = col.column(align=True)
@@ -396,33 +375,38 @@ class VIEW3D_PT_tools_brush(PaintPanel):
# Sculpt Mode #
- elif context.sculpt_object and settings.brush:
+ elif context.sculpt_object and brush:
col = layout.column()
col.itemS()
-
+ col.itemR(brush, "sculpt_tool", expand=True)
+ col.itemS()
+
row = col.row(align=True)
row.itemR(brush, "size", slider=True)
- row.itemR(brush, "size_pressure", toggle=True, text="")
+ row.itemR(brush, "use_size_pressure", toggle=True, text="")
if brush.sculpt_tool != 'GRAB':
row = col.row(align=True)
row.itemR(brush, "strength", slider=True)
- row.itemR(brush, "strength_pressure", text="")
-
+ row.itemR(brush, "use_strength_pressure", text="")
+
+ ''' # XXX - TODO
+ row = col.row(align=True)
+ row.itemR(brush, "jitter", slider=True)
+ row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
+ '''
col = layout.column()
if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'):
- col.itemR(brush, "flip_direction")
+ col.row().itemR(brush, "direction", expand=True)
if brush.sculpt_tool == 'LAYER':
col.itemR(brush, "persistent")
col.itemO("sculpt.set_persistent_base")
- col.itemR(brush, "sculpt_tool")
-
# Texture Paint Mode #
- elif context.texture_paint_object:
+ elif context.texture_paint_object and brush:
col = layout.column(align=True)
col.item_enumR(settings, "tool", 'DRAW')
col.item_enumR(settings, "tool", 'SOFTEN')
@@ -434,41 +418,55 @@ class VIEW3D_PT_tools_brush(PaintPanel):
row = col.row(align=True)
row.itemR(brush, "size", slider=True)
- row.itemR(brush, "size_pressure", toggle=True, text="")
+ row.itemR(brush, "use_size_pressure", toggle=True, text="")
row = col.row(align=True)
row.itemR(brush, "strength", slider=True)
- row.itemR(brush, "strength_pressure", toggle=True, text="")
+ row.itemR(brush, "use_strength_pressure", toggle=True, text="")
+
+ row = col.row(align=True)
+ row.itemR(brush, "jitter", slider=True)
+ row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
- col.itemR(brush, "blend")
+ col.itemR(brush, "blend", text="Blend")
# Weight Paint Mode #
- elif context.weight_paint_object:
+ elif context.weight_paint_object and brush:
layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
col = layout.column()
row = col.row(align=True)
row.itemR(brush, "size", slider=True)
- row.itemR(brush, "size_pressure", toggle=True, text="")
+ row.itemR(brush, "use_size_pressure", toggle=True, text="")
row = col.row(align=True)
row.itemR(brush, "strength", slider=True)
- row.itemR(brush, "strength_pressure", toggle=True, text="")
+ row.itemR(brush, "use_strength_pressure", toggle=True, text="")
+
+ row = col.row(align=True)
+ row.itemR(brush, "jitter", slider=True)
+ row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
# Vertex Paint Mode #
- elif context.vertex_paint_object:
+ elif context.vertex_paint_object and brush:
col = layout.column()
col.itemR(brush, "color", text="")
row = col.row(align=True)
row.itemR(brush, "size", slider=True)
- row.itemR(brush, "size_pressure", toggle=True, text="")
+ row.itemR(brush, "use_size_pressure", toggle=True, text="")
row = col.row(align=True)
row.itemR(brush, "strength", slider=True)
- row.itemR(brush, "strength_pressure", toggle=True, text="")
+ row.itemR(brush, "use_strength_pressure", toggle=True, text="")
+
+ ''' # XXX - TODO
+ row = col.row(align=True)
+ row.itemR(brush, "jitter", slider=True)
+ row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
+ '''
class VIEW3D_PT_tools_brush_stroke(PaintPanel):
__label__ = "Stroke"
@@ -490,27 +488,27 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel):
if context.sculpt_object:
if brush.sculpt_tool != 'LAYER':
- layout.itemR(brush, "anchored")
- layout.itemR(brush, "rake")
+ layout.itemR(brush, "use_anchor")
+ layout.itemR(brush, "use_rake")
- layout.itemR(brush, "airbrush")
+ layout.itemR(brush, "use_airbrush")
col = layout.column()
- col.active = brush.airbrush
+ col.active = brush.use_airbrush
col.itemR(brush, "rate", slider=True)
if not texture_paint:
- layout.itemR(brush, "smooth_stroke")
+ layout.itemR(brush, "use_smooth_stroke")
col = layout.column()
- col.active = brush.smooth_stroke
+ col.active = brush.use_smooth_stroke
col.itemR(brush, "smooth_stroke_radius", text="Radius", slider=True)
col.itemR(brush, "smooth_stroke_factor", text="Factor", slider=True)
- layout.itemR(brush, "space")
+ layout.itemR(brush, "use_space")
row = layout.row(align=True)
- row.active = brush.space
+ row.active = brush.use_space
row.itemR(brush, "spacing", text="Distance", slider=True)
if texture_paint:
- row.itemR(brush, "spacing_pressure", toggle=True, text="")
+ row.itemR(brush, "use_spacing_pressure", toggle=True, text="")
class VIEW3D_PT_tools_brush_curve(PaintPanel):
__label__ = "Curve"
@@ -526,7 +524,7 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel):
settings = self.paint_settings(context)
brush = settings.brush
- layout.template_curve_mapping(brush.curve)
+ layout.template_curve_mapping(brush, "curve")
layout.item_menu_enumO("brush.curve_preset", property="shape")
class VIEW3D_PT_sculpt_options(PaintPanel):
@@ -614,16 +612,16 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel):
# ********** default tools for texturepaint ****************
class VIEW3D_PT_tools_projectpaint(View3DPanel):
- __context__ = "projectpaint"
+ __context__ = "texturepaint"
__label__ = "Project Paint"
def poll(self, context):
return context.tool_settings.image_paint.tool != 'SMEAR'
- def draw_header(self, context):
- layout = self.layout
- ipaint = context.tool_settings.image_paint
- layout.itemR(ipaint, "use_projection", text="")
+ def draw_header(self, context):
+ ipaint = context.tool_settings.image_paint
+
+ self.layout.itemR(ipaint, "use_projection", text="")
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/unweld.py b/release/scripts/unweld.py
deleted file mode 100644
index 3385e66e2d8..00000000000
--- a/release/scripts/unweld.py
+++ /dev/null
@@ -1,247 +0,0 @@
-#!BPY
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Unweld vertex/ices'
-Blender: 243
-Group: 'Mesh'
-Tip: 'Unweld all faces from a (or several) selected and common vertex. Made vertex bevelling'
-"""
-
-__author__ = "Jean-Michel Soler (jms)"
-__url__ = ("blender", "blenderartists.org",
-"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple",
-"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
-__version__ = "0.4.6 "
-__bpydoc__ = """\
-This script unwelds faces from one or several selected vertex/vertices.
-
-Usage:
-
-In edit mode Select at least one vertex, then run this script.
-
-The options are:
-
-- unbind points;<br>
- a new point is added to each face connected to the selected one.
-
-- with noise;<br>
- the new points location is varied with noise
-
-- middle face;<br>
- the new point is located at the center of face to which it is connected
-"""
-
-# ------------------------------------------
-# Un-Weld script 0.4.6
-# name="UnWeld"
-# Tip= 'Unweld all faces from a selected and common vertex.'
-# date='06/08/2006'
-# split all faces from one selected vertex
-# (c) 2004 J-M Soler released under GPL licence
-#----------------------------------------------
-# Official Page :
-# website = 'http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple'
-# Communicate problems and errors on:
-# community = 'http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender'
-#----------------------------------------------
-# Blender Artistic License
-# http://download.blender.org/documentation/html/x21254.html
-#---------------------------------------------
-# Changelog
-#----------------------------------------------
-# 25/05 :
-# -- separate choice, normal (same place) or spread at random, middle of the face
-# -- works on several vertices too
-# -- Quite vertex bevelling on <<lone>> vertex : create hole in faces around this
-# vertex
-# 03/06 :
-# -- a sort of "bevelled vertex" extrusion controled by horizontal mouse
-# displacement. just a beta test to the mouse control.
-# 08/08 :
-# -- minor correction to completely disconnect face.
-#----------------------------------------------
-# Page officielle :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple
-# Commsoler les problemes et erreurs sur:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-# Blender Artistic License
-# http://download.blender.org/documentation/html/x21254.html
-#---------------------------------------------
-# Changelog
-#----------------------------------------------
-# 25/05 :
-# -- separation du choix, normal ou dispersion hasardeuse,
-# milieu de face
-# -- sommets multiples /
-# -- presque unvertex bevelling sur un vertex solitaire : cree
-# un trou dans la facette autour du sommet
-# 03/06 :
-# -- une sorte de vertex extruder en biseau, controle par
-# movement horizontal de la souris
-# 08/08 :
-# -- correction mineure pour s'assurer que les faces soient
-# entierment deconnectees
-#----------------------------------------------
-
-import Blender
-from Blender import Noise
-from Blender.Draw import *
-from Blender.BGL import *
-import BPyMessages
-# $Id$
-
-NR=Noise.random
-DECAL=0.03
-t=[0.0,0.0,0.0]
-pl=[]
-orig=[]
-
-DEBUG = 0
-SUBSURF=0
-DIM=Create(1.0)
-
-def Buffer(v,t):
- if DEBUG : print dir(v)
- for n in range(len(v)): t[n]=t[n]+v[n]
- return t
-
-def freeBuffer(t):
- for n in range(3): t[n]=0.0
- return t
-
-def ModalBuffer(t,f):
- for n in range(3): t[n]/=len(f)
- return t
-
-def applyModalValue(v,t):
- for n in range(len(v)): v[n]=t[n]
- return v
-
-def docF(f0,f):
-
- if f0 and f:
- f0.mat=f.mat
- if f.uv :
- f0.uv=f.uv
- if f.col :
- f0.col=f.col
- if f.image :
- f0.image=f.image
- f0.smooth=f.smooth
- f0.mode=f.mode
- f0.flag=f.flag
- return f0
-
-
-def connectedFacesList(me,thegood):
- listf2v={}
- #tri des faces connectees aux sommets selectionnes
- for f in me.faces:
- for v in f.v:
- if v==thegood:
- if v.index not in listf2v: # .keys()
- listf2v[me.verts.index(v)]=[f]
- elif f not in listf2v[me.verts.index(v)]:
- listf2v[me.verts.index(v)].append(f)
- return listf2v
-
-
-def createAdditionalFace(me,thegood,listf2v):
- global t
- for f in listf2v[thegood.index]:
- f0=Blender.NMesh.Face()
- if result==3: t=freeBuffer(t)
- for v in f.v:
- if result==3: t=Buffer(v,t)
- if v!=thegood:
- f0.append(v)
- else:
- if result==2:
- nv=Blender.NMesh.Vert(thegood.co[0]+NR()*DECAL,
- thegood.co[1]+NR()*DECAL,
- thegood.co[2]+NR()*DECAL)
- else:
- nv=Blender.NMesh.Vert(thegood.co[0],
- thegood.co[1],
- thegood.co[2])
- nv.sel=1
- me.verts.append(nv)
- f0.append(me.verts[me.verts.index(nv)])
- localise=me.verts.index(nv)
- docF(f0,f)
- if result==3:
- t=ModalBuffer(t,f0.v)
- me.verts[localise]=applyModalValue(me.verts[localise],t)
- me.faces.append(f0)
- del me.verts[me.verts.index(thegood)]
- for f in listf2v[thegood.index]:
- del me.faces[me.faces.index(f)]
- return me
-
-def collecte_edge(listf2v,me,thegood):
- back=0
- edgelist = []
- vertlist = []
- if DEBUG : print listf2v
- for face in listf2v[thegood.index]:
- if len(face.v) == 4:
- vlist = [0,1,2,3,0]
- elif len(face.v) == 3:
- vlist = [0,1,2,0]
- else:
- vlist = [0,1]
- for i in xrange(len(vlist)-1):
- vert0 = min(face.v[vlist[i]].index,face.v[vlist[i+1]].index)
- vert1 = max(face.v[vlist[i]].index,face.v[vlist[i+1]].index)
- edgeinlist = 0
- if vert0==thegood.index or vert1==thegood.index:
- for edge in edgelist:
- if ((edge[0]==vert0) and (edge[1]==vert1)):
- edgeinlist = 1
- edge[2] = edge[2]+1
- edge.append(me.faces.index(face))
- break
- if edgeinlist==0:
- edge = [vert0,vert1,1,me.faces.index(face)]
- edgelist.append(edge)
-
- for i, edge in enumerate(edgelist):
- #print edge
- if len(edge)==4:
- del edgelist[i]
-
- edges=len(edgelist)
- if DEBUG : print 'number of edges : ',edges," Edge list : " ,edgelist
- return edges, edgelist
-
-import bpy
-OBJECT= bpy.data.scenes.active.objects.active
-
-if OBJECT and OBJECT.type=='Mesh':
- if OBJECT.getData(mesh=1).multires:
- BPyMessages.Error_NoMeshMultiresEdit()
- elif not BPyMessages.Warning_MeshDistroyLayers(OBJECT.getData(mesh=1)):
- pass
- else:
- EDITMODE=Blender.Window.EditMode()
- Blender.Window.EditMode(0)
- name = "Unweld %t|Unbind Points %x1|With Noise %x2|Middle Face %x3"
- result = Blender.Draw.PupMenu(name)
- if result:
- me=OBJECT.getData()
-
- for v in me.verts:
- if v.sel:
- thegood=v
- if DEBUG : print thegood
- listf2v=connectedFacesList(me,thegood)
- if listf2v:
- me=createAdditionalFace(me,thegood,listf2v)
- #OBJECT.link(me)
- me.update()
-
- OBJECT.makeDisplayList()
-
- Blender.Window.EditMode(EDITMODE)
-
-else:
- BPyMessages.Error_NoMeshActive()
diff --git a/release/scripts/uv_export.py b/release/scripts/uv_export.py
deleted file mode 100644
index 5977a3b76f6..00000000000
--- a/release/scripts/uv_export.py
+++ /dev/null
@@ -1,498 +0,0 @@
-#!BPY
-
-"""
-Name: 'Save UV Face Layout...'
-Blender: 242
-Group: 'UV'
-Tooltip: 'Export the UV face layout of the selected object to a .TGA or .SVG file'
-"""
-
-__author__ = "Martin 'theeth' Poirier"
-__url__ = ("http://www.blender.org", "http://blenderartists.org/")
-__version__ = "2.5"
-
-__bpydoc__ = """\
-This script exports the UV face layout of the selected mesh object to
-a TGA image file or a SVG vector file. Then you can, for example, paint details
-in this image using an external 2d paint program of your choice and bring it back
-to be used as a texture for the mesh.
-
-Usage:
-
-Open this script from UV/Image Editor's "UVs" menu, make sure there is a mesh
-selected, define size and wire size parameters and push "Export" button.
-
-There are more options to configure, like setting export path, if image should
-use object's name and more.
-
-Notes:<br>See change logs in scripts for a list of contributors.
-"""
-
-
-# $Id$
-#
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2003: Martin Poirier, theeth@yahoo.com
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-# thanks to jms for the tga functions:
-# Writetga and buffer functions
-# (c) 2002-2004 J-M Soler released under GPL licence
-# Official Page :
-# http://jmsoler.free.fr/didacticiel/blender/tutor/write_tga_pic.htm
-# Communicate problems and errors on:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
-# --------------------------
-# Version 1.1
-# Clear a bug that crashed the script when UV coords overlapped in the same faces
-# --------------------------
-# Version 1.2
-# Now with option to use the object's name as filename
-# --------------------------
-# Version 1.3 Updates by Zaz from Elysiun.com
-# Default path is now the directory of the last saved .blend
-# New options: Work on selected face only & Scale image when face wraps
-# --------------------------
-# Version 1.3a
-# Corrected a minor typo and added the tga extension to both export call
-# --------------------------
-# Version 1.4 Updates by Macouno from Elysiun.com
-# Fixed rounding error that can cause breaks in lines.
-# --------------------------
-# Version 2.0
-# New interface using PupBlock and FileSelector
-# Save/Load config to Registry
-# Edit in external program
-# --------------------------
-# Version 2.1 Updates by Jarod from blenderartists.org
-# New exportformat SVG
-# simple memory optimations, two third less memory usage
-# tga filewriting speed improvements, 3times faster now
-# --------------------------
-# Version 2.2
-# Cleanup code
-# Filename handling enhancement and bug fixes
-# --------------------------
-# Version 2.3
-# Added check for excentric UVs (only affects TGA)
-# --------------------------
-# Version 2.4
-# Port from NMesh to Mesh by Daniel Salazar (zanqdo)
-# --------------------------
-# Version 2.5
-# Fixed some old off by one rasterizing errors (didn't render points at 1.0 in the UV scale properly).
-# Fixed wire drawing for non 1 wire size (didn't wrap or stretch properly
-# and would often raise exceptions)
-# --------------------------
-
-
-FullPython = False
-
-import Blender
-import bpy
-import BPyMessages
-
-try:
- import os
- FullPython = True
-except:
- pass
-
-from math import *
-
-def ExportConfig():
- conf = {}
-
- conf["SIZE"] = bSize.val
- conf["WSIZE"] = bWSize.val
- conf["OBFILE"] = bObFile.val
- conf["WRAP"] = bWrap.val
- conf["ALLFACES"] = bAllFaces.val
- conf["EDIT"] = bEdit.val
- conf["EXTERNALEDITOR"] = bEditPath.val
- conf["UVFORMATSVG"] = bSVG.val
- conf["SVGFILL"] = bSVGFill.val
-
- Blender.Registry.SetKey("UVEXPORT", conf, True)
-
-def ImportConfig():
- global bSize, bWSize, bObFile, bWrap, bAllFaces
-
- conf = Blender.Registry.GetKey("UVEXPORT", True)
-
- if not conf:
- return
-
- try:
- bSize.val = conf["SIZE"]
- bWSize.val = conf["WSIZE"]
- bObFile.val = conf["OBFILE"]
- bWrap.val = conf["WRAP"]
- bAllFaces.val = conf["ALLFACES"]
- bEdit.val = conf["EDIT"]
- editor = conf["EXTERNALEDITOR"]
- bSVG.val = conf["UVFORMATSVG"]
- bSVGFill.val = conf["SVGFILL"]
- if editor:
- bEditPath.val = editor
- except KeyError:
- # If one of the key is not in the dict, don't worry, it'll use the defaults
- pass
-
-
-def PrintConfig():
- print
- print "Imagesize: %ipx" % bSize.val
- print "Wiresize : %ipx" % bWSize.val
-
- if bWrap.val:
- print "Wrap : yes"
- else:
- print "Wrap : no"
-
- if bAllFaces.val:
- print "AllFaces : yes"
- else:
- print "AllFaces : no"
-
- if bSVG.val:
- print "Format : *.svg"
- else:
- print "Format : *.tga"
-
-
-def ExportCallback(f):
- obj = Blender.Scene.GetCurrent().objects.active
-
- time1= Blender.sys.time()
-
- if not obj or obj.type != "Mesh":
- BPyMessages.Error_NoMeshActive()
- return
-
- is_editmode = Blender.Window.EditMode()
- if is_editmode: Blender.Window.EditMode(0)
-
- mesh = obj.getData(mesh=1)
- if not mesh.faceUV:
- if is_editmode: Blender.Window.EditMode(1)
- BPyMessages.Error_NoMeshUvActive()
- return
-
- # just for information...
- PrintConfig()
-
- # taking care of filename
- if bObFile.val:
- name = AddExtension(f, obj.name)
- else:
- name = AddExtension(f, None)
-
-
- print "Target :", name
- print
-
- UVFaces = ExtractUVFaces(mesh, bAllFaces.val)
-
- if is_editmode: Blender.Window.EditMode(1)
-
- if not bSVG.val:
- print "TGA export is running..."
- UV_Export_TGA(UVFaces, bSize.val, bWSize.val, bWrap.val, name)
- else:
- print "SVG export is running..."
- if bSVGFill.val:
- SVGFillColor="#F2DAF2"
- else:
- SVGFillColor="none"
-
- UV_Export_SVG(UVFaces, bSize.val, bWSize.val, bWrap.val, name, obj.name, SVGFillColor)
-
- print
- print " ...finished exporting in %.4f sec." % (Blender.sys.time()-time1)
-
- if FullPython and bEdit.val and bEditPath.val:
- filepath = os.path.realpath(name)
- print filepath
- os.spawnl(os.P_NOWAIT, bEditPath.val, "", filepath)
-
-
-def GetExtension():
- if bSVG.val:
- ext = "svg"
- else:
- ext = "tga"
-
- return ext
-
-def AddExtension(filename, object_name):
- ext = "." + GetExtension()
-
- hasExtension = (ext in filename or ext.upper() in filename)
-
- if object_name and hasExtension:
- filename = filename.replace(ext, "")
- hasExtension = False
-
- if object_name:
- filename += "_" + object_name
-
- if not hasExtension:
- filename += ext
-
- return filename
-
-def GetDefaultFilename():
- filename = Blender.Get("filename")
-
- filename = filename.replace(".blend", "")
- filename += "." + GetExtension()
-
- return filename
-
-def ExtractUVFaces(mesh, allface):
-
- if allface: return [f.uv for f in mesh.faces]
- else: return [f.uv for f in mesh.faces if f.sel]
-
-def Buffer(height=16, width=16, profondeur=1,rvb=255 ):
- """
- reserve l'espace memoire necessaire
- """
- p=[rvb]
- myb=height*width*profondeur
- print"Memory : %ikB" % (myb/1024)
- b=p*myb
- return b
-
-def write_tgafile(loc2,bitmap,width,height,profondeur):
-
- f=open(loc2,'wb')
-
- Origine_en_haut_a_gauche=32
- Origine_en_bas_a_gauche=0
-
- Data_Type_2=2
- RVB=profondeur*8
- RVBA=32
- entete0=[]
- for t in range(18):
- entete0.append(chr(0))
-
- entete0[2]=chr(Data_Type_2)
- entete0[13]=chr(width/256)
- entete0[12]=chr(width % 256)
- entete0[15]=chr(height/256)
- entete0[14]=chr(height % 256)
- entete0[16]=chr(RVB)
- entete0[17]=chr(Origine_en_bas_a_gauche)
-
- # Origine_en_haut_a_gauche
- print" ...writing tga..."
- for t in entete0:
- f.write(t)
-
- redpx=chr(0) + chr(0) + chr(255)
- blackpx=chr(0) + chr(0) + chr(0)
- whitepx=chr(255) + chr(255) + chr(255)
-
- for t in bitmap:
- if t==255:
- f.write(whitepx)
- elif t==0:
- f.write(blackpx)
- else:
- f.write(redpx)
-
- f.close()
-
-
-def UV_Export_TGA(vList, size, wsize, wrap, file):
- extreme_warning = False
-
- minx = 0
- miny = 0
- scale = 1.0
-
- step = 0
-
- img = Buffer(size,size)
-
- if wrap:
- wrapSize = size
- else:
- wrapSize = size
- maxx = -100000
- maxy = -100000
- for f in vList:
- for v in f:
- x = int(v[0] * size)
- maxx = max (x + wsize - 1, maxx)
- minx = min (x - wsize + 1, minx)
-
- y = int(v[1] * size)
- maxy = max (y + wsize - 1, maxy)
- miny = min (y - wsize + 1, miny)
- wrapSize = max (maxx - minx + 1, maxy - miny + 1)
- scale = float (size) / float (wrapSize)
-
- max_index = size - 1 # max index of the buffer (height or width)
- fnum = 0
- fcnt = len (vList)
-
- for f in vList:
- fnum = fnum + 1
- if not fnum % 100:
- print "%i of %i Faces completed" % (fnum, fcnt)
-
- for index in range(len(f)):
- co1 = f[index]
- if index < len(f) - 1:
- co2 = f[index + 1]
- else:
- co2 = f[0]
-
- step = int(ceil(size*sqrt((co1[0]-co2[0])**2+(co1[1]-co2[1])**2)))
- if step:
- try:
- for t in xrange(step):
- x = int(floor((co1[0] + t*(co2[0]-co1[0])/step) * max_index))
- y = int(floor((co1[1] + t*(co2[1]-co1[1])/step) * max_index))
-
- for dx in range(-1*wsize + 1, wsize):
- if wrap:
- wx = (x + dx) % wrapSize
- else:
- wx = int ((x - minx + dx) * scale)
-
- for dy in range(-1*wsize + 1, wsize):
- if wrap:
- wy = (y + dy) % wrapSize
- else:
- wy = int ((y - miny + dy) * scale)
-
- co = wx * 1 + wy * 1 * size
- img[co] = 0
- except OverflowError:
- if not extreme_warning:
- print "Skipping extremely long UV edges, check your layout for excentric values"
- extreme_warning = True
-
- for v in f:
- x = int(v[0] * max_index)
- y = int(v[1] * max_index)
-
- if wrap:
- x = x % wrapSize
- y = y % wrapSize
- else:
- x = int ((x - minx) * scale)
- y = int ((y - miny) * scale)
-
- co = x * 1 + y * 1 * size
- img[co] = 1
-
-
- write_tgafile(file,img,size,size,3)
-
-def UV_Export_SVG(vList, size, wsize, wrap, file, objname, facesfillcolor):
- fl=open(file,'wb')
- fl.write('<?xml version="1.0"?>\r\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r\n')
- fl.write('<svg width="' + str(size) + 'px" height="' + str(size) + 'px" viewBox="0 0 ' + str(size) + ' ' + str(size) + '" xmlns="http://www.w3.org/2000/svg" version="1.1">\r\n')
- fl.write('<desc>UV-Map from Object: ' + str(objname) +'. Exported from Blender3D with UV Exportscript</desc>\r\n')
- fl.write('<rect x="0" y="0" width="' + str(size) + '" height="' + str(size) + '" fill="none" stroke="blue" stroke-width="' + str(wsize) + 'px" />\r\n')
- fl.write('<g style="fill:' + str(facesfillcolor) + '; stroke:black; stroke-width:' + str(wsize) + 'px;">\r\n')
-
- fnum = 0
- fcnt = len (vList)
- fnumv = (long) (fcnt/10)
-
- for f in vList:
- fnum = fnum + 1
-
- if fnum == fnumv:
- print ".",
- fnumv = fnumv + ((long) (fcnt/10))
-
- fl.write('<polygon points="')
- for index in range(len(f)):
- co = f[index]
- fl.write("%.3f,%.3f " % (co[0]*size, size-co[1]*size))
- fl.write('" />\r\n')
-
- print "%i Faces completed." % fnum
- fl.write('</g>\r\n')
- fl.write('</svg>')
- fl.close()
-
-def SetEditorAndExportCallback(f):
- global bEditPath
- bEditPath.val = f
-
- ExportConfig()
-
- Export()
-
-def Export():
- Blender.Window.FileSelector(ExportCallback, "Save UV (%s)" % GetExtension(), GetDefaultFilename())
-
-def SetEditorAndExport():
- Blender.Window.FileSelector(SetEditorAndExportCallback, "Select Editor")
-
-# ###################################### MAIN SCRIPT BODY ###############################
-
-# Create user values and fill with defaults
-bSize = Blender.Draw.Create(512)
-bWSize = Blender.Draw.Create(1)
-bObFile = Blender.Draw.Create(1)
-bWrap = Blender.Draw.Create(1)
-bAllFaces = Blender.Draw.Create(1)
-bEdit = Blender.Draw.Create(0)
-bEditPath = Blender.Draw.Create("")
-bSVG = Blender.Draw.Create(0)
-bSVGFill = Blender.Draw.Create(1)
-
-# Import saved configurations
-ImportConfig()
-
-
-Block = []
-
-Block.append(("Size: ", bSize, 64, 16384, "Size of the exported image"))
-Block.append(("Wire: ", bWSize, 1, 9, "Size of the wire of the faces"))
-Block.append(("Wrap", bWrap, "Wrap to image size, scale otherwise"))
-Block.append(("All Faces", bAllFaces, "Export all or only selected faces"))
-Block.append(("Object", bObFile, "Use object name in filename"))
-Block.append(("SVG", bSVG, "save as *.svg instead of *.tga"))
-Block.append(("Fill SVG faces", bSVGFill, "SVG faces will be filled, none filled otherwise"))
-
-if FullPython:
- Block.append(("Edit", bEdit, "Edit resulting file in an external program"))
- Block.append(("Editor: ", bEditPath, 0, 399, "Path to external editor (leave blank to select a new one)"))
-
-retval = Blender.Draw.PupBlock("UV Image Export", Block)
-
-if retval:
- ExportConfig()
-
- if bEdit.val and not bEditPath.val:
- SetEditorAndExport()
- else:
- Export() \ No newline at end of file
diff --git a/release/scripts/uv_seams_from_islands.py b/release/scripts/uv_seams_from_islands.py
deleted file mode 100644
index 7f156efde7d..00000000000
--- a/release/scripts/uv_seams_from_islands.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!BPY
-"""
-Name: 'Seams from Islands'
-Blender: 246
-Group: 'UV'
-Tooltip: 'Add seams onto the mesh at the bounds of UV islands'
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Mesh, Window, sys
-import BPyMessages
-
-def seams_from_islands(me):
- # This function runs out of editmode with a mesh
- # error cases are alredy checked for
-
- # next intex
- wrap_q = [1,2,3,0]
- wrap_t = [1,2,0]
- edge_uvs = {}
- for f in me.faces:
- f_uv = [(round(uv.x, 6), round(uv.y, 6)) for uv in f.uv]
- f_vi = [v.index for v in f]
- for i, key in enumerate(f.edge_keys):
- if len(f)==3:
- uv1, uv2 = f_uv[i], f_uv[wrap_t[i]]
- vi1, vi2 = f_vi[i], f_vi[wrap_t[i]]
- else: # quad
- uv1, uv2 = f_uv[i], f_uv[wrap_q[i]]
- vi1, vi2 = f_vi[i], f_vi[wrap_q[i]]
-
- if vi1 > vi2: uv1,uv2 = uv2,uv1
-
- edge_uvs.setdefault(key, []).append((uv1, uv2))
-
- # add seams
- SEAM = Mesh.EdgeFlags.SEAM
- for ed in me.edges:
- try: # the edge might not be in a face
- if len(set(edge_uvs[ed.key])) > 1:
- ed.flag |= SEAM
- except:
- pass
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = Scene.GetCurrent()
-
- # Get the active object, there can only ever be 1
- # and the active object is always the editmode object.
- ob_act = sce.objects.active
- me = ob_act.getData(mesh=1)
-
- if not ob_act or ob_act.type != 'Mesh' or not me.faceUV:
- BPyMessages.Error_NoMeshUvActive()
- return
-
- # Saves the editmode state and go's out of
- # editmode if its enabled, we cant make
- # changes to the mesh data while in editmode.
- is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(0)
-
- Window.WaitCursor(1)
-
- t = sys.time()
-
- # Run the mesh editing function
- seams_from_islands(me)
-
- if is_editmode: Window.EditMode(1)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'UV Seams from Islands finished in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
-
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/uvcalc_follow_active_coords.py b/release/scripts/uvcalc_follow_active_coords.py
deleted file mode 100644
index 83df200991f..00000000000
--- a/release/scripts/uvcalc_follow_active_coords.py
+++ /dev/null
@@ -1,254 +0,0 @@
-#!BPY
-"""
-Name: 'Follow Active (quads)'
-Blender: 242
-Group: 'UVCalculation'
-Tooltip: 'Follow from active quads.'
-"""
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0 2006/02/07"
-
-__bpydoc__ = """\
-This script sets the UV mapping and image of selected faces from adjacent unselected faces.
-
-for full docs see...
-http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Follow_active_quads
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import *
-import bpy
-import BPyMesh
-
-def extend(EXTEND_MODE,ob):
- if EXTEND_MODE == -1:
- return
- me = ob.getData(mesh=1)
- me_verts = me.verts
- # Toggle Edit mode
- is_editmode = Window.EditMode()
- if is_editmode:
- Window.EditMode(0)
- Window.WaitCursor(1)
- t = sys.time()
- edge_average_lengths = {}
-
- OTHER_INDEX = 2,3,0,1
- FAST_INDICIES = 0,2,1,3 # order is faster
- def extend_uvs(face_source, face_target, edge_key):
- '''
- Takes 2 faces,
- Projects its extends its UV coords onto the face next to it.
- Both faces must share an edge.
- '''
-
- def face_edge_vs(vi):
- # assunme a quad
- return [(vi[0], vi[1]), (vi[1], vi[2]), (vi[2], vi[3]), (vi[3], vi[0])]
-
- uvs_source = face_source.uv
- uvs_target = face_target.uv
-
- vidx_source = [v.index for v in face_source]
- vidx_target = [v.index for v in face_target]
-
- # vertex index is the key, uv is the value
- uvs_vhash_source = dict( [ (vindex, uvs_source[i]) for i, vindex in enumerate(vidx_source)] )
- uvs_vhash_target = dict( [ (vindex, uvs_target[i]) for i, vindex in enumerate(vidx_target)] )
-
- edge_idxs_source = face_edge_vs(vidx_source)
- edge_idxs_target = face_edge_vs(vidx_target)
-
- source_matching_edge = -1
- target_matching_edge = -1
-
- edge_key_swap = edge_key[1], edge_key[0]
-
- try: source_matching_edge = edge_idxs_source.index(edge_key)
- except: source_matching_edge = edge_idxs_source.index(edge_key_swap)
- try: target_matching_edge = edge_idxs_target.index(edge_key)
- except: target_matching_edge = edge_idxs_target.index(edge_key_swap)
-
-
-
- edgepair_inner_source = edge_idxs_source[source_matching_edge]
- edgepair_inner_target = edge_idxs_target[target_matching_edge]
- edgepair_outer_source = edge_idxs_source[OTHER_INDEX[source_matching_edge]]
- edgepair_outer_target = edge_idxs_target[OTHER_INDEX[target_matching_edge]]
-
- if edge_idxs_source[source_matching_edge] == edge_idxs_target[target_matching_edge]:
- iA= 0; iB= 1 # Flipped, most common
- else: # The normals of these faces must be different
- iA= 1; iB= 0
-
-
- # Set the target UV's touching source face, no tricky calc needed,
- uvs_vhash_target[edgepair_inner_target[0]][:] = uvs_vhash_source[edgepair_inner_source[iA]]
- uvs_vhash_target[edgepair_inner_target[1]][:] = uvs_vhash_source[edgepair_inner_source[iB]]
-
-
- # Set the 2 UV's on the target face that are not touching
- # for this we need to do basic expaning on the source faces UV's
- if EXTEND_MODE == 2:
-
- try: # divide by zero is possible
- '''
- measure the length of each face from the middle of each edge to the opposite
- allong the axis we are copying, use this
- '''
- i1a= edgepair_outer_target[iB]
- i2a= edgepair_inner_target[iA]
- if i1a>i2a: i1a, i2a = i2a, i1a
-
- i1b= edgepair_outer_source[iB]
- i2b= edgepair_inner_source[iA]
- if i1b>i2b: i1b, i2b = i2b, i1b
- # print edge_average_lengths
- factor = edge_average_lengths[i1a, i2a][0] / edge_average_lengths[i1b, i2b][0]
- except:
- # Div By Zero?
- factor = 1.0
-
- uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] +factor * (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
- uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] +factor * (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
-
- else:
- # same as above but with no factor
- uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
- uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
-
- if not me.faceUV:
- me.faceUV= True
-
- face_act = me.activeFace
- if face_act == -1:
- Draw.PupMenu('ERROR: No active face')
- return
-
- face_sel= [f for f in me.faces if len(f) == 4 and f.sel]
-
- face_act_local_index = -1
- for i, f in enumerate(face_sel):
- if f.index == face_act:
- face_act_local_index = i
- break
-
- if face_act_local_index == -1:
- Draw.PupMenu('ERROR: Active face not selected')
- return
-
-
-
- # Modes
- # 0 unsearched
- # 1:mapped, use search from this face. - removed!!
- # 2:all siblings have been searched. dont search again.
- face_modes = [0] * len(face_sel)
- face_modes[face_act_local_index] = 1 # extend UV's from this face.
-
-
- # Edge connectivty
- edge_faces = {}
- for i, f in enumerate(face_sel):
- for edkey in f.edge_keys:
- try: edge_faces[edkey].append(i)
- except: edge_faces[edkey] = [i]
-
- SEAM = Mesh.EdgeFlags.SEAM
-
- if EXTEND_MODE == 2:
- edge_loops = BPyMesh.getFaceLoopEdges(face_sel, [ed.key for ed in me.edges if ed.flag & SEAM] )
- me_verts = me.verts
- for loop in edge_loops:
- looplen = [0.0]
- for ed in loop:
- edge_average_lengths[ed] = looplen
- looplen[0] += (me_verts[ed[0]].co - me_verts[ed[1]].co).length
- looplen[0] = looplen[0] / len(loop)
-
-
-
- # remove seams, so we dont map accross seams.
- for ed in me.edges:
- if ed.flag & SEAM:
- # remove the edge pair if we can
- try: del edge_faces[ed.key]
- except: pass
- # Done finding seams
-
-
- # face connectivity - faces around each face
- # only store a list of indicies for each face.
- face_faces = [[] for i in xrange(len(face_sel))]
-
- for edge_key, faces in edge_faces.iteritems():
- if len(faces) == 2: # Only do edges with 2 face users for now
- face_faces[faces[0]].append((faces[1], edge_key))
- face_faces[faces[1]].append((faces[0], edge_key))
-
-
- # Now we know what face is connected to what other face, map them by connectivity
- ok = True
- while ok:
- ok = False
- for i in xrange(len(face_sel)):
- if face_modes[i] == 1: # searchable
- for f_sibling, edge_key in face_faces[i]:
- if face_modes[f_sibling] == 0:
- face_modes[f_sibling] = 1 # mapped and search from.
- extend_uvs(face_sel[i], face_sel[f_sibling], edge_key)
- face_modes[i] = 1 # we can map from this one now.
- ok= True # keep searching
-
- face_modes[i] = 2 # dont search again
- print sys.time() - t
-
- if is_editmode:
- Window.EditMode(1)
- else:
- me.update()
-
- Window.RedrawAll()
- Window.WaitCursor(0)
-
-
-def main():
- sce = bpy.data.scenes.active
- ob = sce.objects.active
-
- # print ob, ob.type
- if ob == None or ob.type != 'Mesh':
- Draw.PupMenu('ERROR: No mesh object.')
- return
-
-
-
- # 0:normal extend, 1:edge length
- EXTEND_MODE = Draw.PupMenu("Use Face Area%t|Loop Average%x2|None%x0")
- extend(EXTEND_MODE,ob)
-
-if __name__ == '__main__':
- main()
-
diff --git a/release/scripts/uvcalc_lightmap.py b/release/scripts/uvcalc_lightmap.py
deleted file mode 100644
index 1433ccbd13a..00000000000
--- a/release/scripts/uvcalc_lightmap.py
+++ /dev/null
@@ -1,599 +0,0 @@
-#!BPY
-"""
-Name: 'Lightmap UVPack'
-Blender: 242
-Group: 'UVCalculation'
-Tooltip: 'Give each face non overlapping space on a texture.'
-"""
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0 2006/02/07"
-
-__bpydoc__ = """\
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import *
-import bpy
-import BPyMesh
-# reload(BPyMesh)
-
-from math import sqrt
-
-def AngleBetweenVecs(a1,a2):
- try:
- return Mathutils.AngleBetweenVecs(a1,a2)
- except:
- return 180.0
-
-# python 2.3 has no reversed() iterator. this will only work on lists and tuples
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-class prettyface(object):
- __slots__ = 'uv', 'width', 'height', 'children', 'xoff', 'yoff', 'has_parent', 'rot'
- def __init__(self, data):
-
- self.has_parent = False
- self.rot = False # only used for triables
- self.xoff = 0
- self.yoff = 0
-
- if type(data) == list: # list of data
- self.uv = None
-
- # join the data
- if len(data) == 2:
- # 2 vertical blocks
- data[1].xoff = data[0].width
- self.width = data[0].width * 2
- self.height = data[0].height
-
- elif len(data) == 4:
- # 4 blocks all the same size
- d = data[0].width # dimension x/y are the same
-
- data[1].xoff += d
- data[2].yoff += d
-
- data[3].xoff += d
- data[3].yoff += d
-
- self.width = self.height = d*2
-
- #else:
- # print len(data), data
- # raise "Error"
-
- for pf in data:
- pf.has_parent = True
-
-
- self.children = data
-
- elif type(data) == tuple:
- # 2 blender faces
- # f, (len_min, len_mid, len_max)
- self.uv = data
-
- f1, lens1, lens1ord = data[0]
- if data[1]:
- f2, lens2, lens2ord = data[1]
- self.width = (lens1[lens1ord[0]] + lens2[lens2ord[0]])/2
- self.height = (lens1[lens1ord[1]] + lens2[lens2ord[1]])/2
- else: # 1 tri :/
- self.width = lens1[0]
- self.height = lens1[1]
-
- self.children = []
-
-
- else: # blender face
- self.uv = data.uv
-
- cos = [v.co for v in data]
- self.width = ((cos[0]-cos[1]).length + (cos[2]-cos[3]).length)/2
- self.height = ((cos[1]-cos[2]).length + (cos[0]-cos[3]).length)/2
-
- self.children = []
-
-
- def spin(self):
- if self.uv and len(self.uv) == 4:
- self.uv = self.uv[1], self.uv[2], self.uv[3], self.uv[0]
-
- self.width, self.height = self.height, self.width
- self.xoff, self.yoff = self.yoff, self.xoff # not needed?
- self.rot = not self.rot # only for tri pairs.
- # print 'spinning'
- for pf in self.children:
- pf.spin()
-
-
- def place(self, xoff, yoff, xfac, yfac, margin_w, margin_h):
-
- xoff += self.xoff
- yoff += self.yoff
-
- for pf in self.children:
- pf.place(xoff, yoff, xfac, yfac, margin_w, margin_h)
-
- uv = self.uv
- if not uv:
- return
-
- x1 = xoff
- y1 = yoff
- x2 = xoff + self.width
- y2 = yoff + self.height
-
- # Scale the values
- x1 = x1/xfac + margin_w
- x2 = x2/xfac - margin_w
- y1 = y1/yfac + margin_h
- y2 = y2/yfac - margin_h
-
- # 2 Tri pairs
- if len(uv) == 2:
- # match the order of angle sizes of the 3d verts with the UV angles and rotate.
- def get_tri_angles(v1,v2,v3):
- a1= AngleBetweenVecs(v2-v1,v3-v1)
- a2= AngleBetweenVecs(v1-v2,v3-v2)
- a3 = 180 - (a1+a2) #a3= AngleBetweenVecs(v2-v3,v1-v3)
-
-
- return [(a1,0),(a2,1),(a3,2)]
-
- def set_uv(f, p1, p2, p3):
-
- # cos =
- #v1 = cos[0]-cos[1]
- #v2 = cos[1]-cos[2]
- #v3 = cos[2]-cos[0]
- angles_co = get_tri_angles(*[v.co for v in f])
- angles_co.sort()
- I = [i for a,i in angles_co]
-
- fuv = f.uv
- if self.rot:
- fuv[I[2]][:] = p1
- fuv[I[1]][:] = p2
- fuv[I[0]][:] = p3
- else:
- fuv[I[2]][:] = p1
- fuv[I[0]][:] = p2
- fuv[I[1]][:] = p3
-
- f, lens, lensord = uv[0]
-
- set_uv(f, (x1,y1), (x1, y2-margin_h), (x2-margin_w, y1))
-
- if uv[1]:
- f, lens, lensord = uv[1]
- set_uv(f, (x2,y2), (x2, y1+margin_h), (x1+margin_w, y2))
-
- else: # 1 QUAD
- uv[1][:] = x1,y1
- uv[2][:] = x1,y2
- uv[3][:] = x2,y2
- uv[0][:] = x2,y1
-
- def __hash__(self):
- # None unique hash
- return self.width, self.height
-
-
-def lightmap_uvpack( meshes,\
-PREF_SEL_ONLY= True,\
-PREF_NEW_UVLAYER= False,\
-PREF_PACK_IN_ONE= False,\
-PREF_APPLY_IMAGE= False,\
-PREF_IMG_PX_SIZE= 512,\
-PREF_BOX_DIV= 8,\
-PREF_MARGIN_DIV= 512):
- '''
- BOX_DIV if the maximum division of the UV map that
- a box may be consolidated into.
- Basicly, a lower value will be slower but waist less space
- and a higher value will have more clumpy boxes but more waisted space
- '''
-
- if not meshes:
- return
-
- t = sys.time()
-
- if PREF_PACK_IN_ONE:
- if PREF_APPLY_IMAGE:
- image = Image.New('lightmap', PREF_IMG_PX_SIZE, PREF_IMG_PX_SIZE, 24)
- face_groups = [[]]
- else:
- face_groups = []
-
- for me in meshes:
- # Add face UV if it does not exist.
- # All new faces are selected.
- me.faceUV = True
-
- if PREF_SEL_ONLY:
- faces = [f for f in me.faces if f.sel]
- else:
- faces = list(me.faces)
-
- if PREF_PACK_IN_ONE:
- face_groups[0].extend(faces)
- else:
- face_groups.append(faces)
-
- if PREF_NEW_UVLAYER:
- uvname_org = uvname = 'lightmap'
- uvnames = me.getUVLayerNames()
- i = 1
- while uvname in uvnames:
- uvname = '%s.%03d' % (uvname_org, i)
- i+=1
-
- me.addUVLayer(uvname)
- me.activeUVLayer = uvname
-
- del uvnames, uvname_org, uvname
-
- for face_sel in face_groups:
- print "\nStarting unwrap"
-
- if len(face_sel) <4:
- print '\tWarning, less then 4 faces, skipping'
- continue
-
- pretty_faces = [prettyface(f) for f in face_sel if len(f) == 4]
-
-
- # Do we have any tri's
- if len(pretty_faces) != len(face_sel):
-
- # Now add tri's, not so simple because we need to pair them up.
- def trylens(f):
- # f must be a tri
- cos = [v.co for v in f]
- lens = [(cos[0] - cos[1]).length, (cos[1] - cos[2]).length, (cos[2] - cos[0]).length]
-
- lens_min = lens.index(min(lens))
- lens_max = lens.index(max(lens))
- for i in xrange(3):
- if i != lens_min and i!= lens_max:
- lens_mid = i
- break
- lens_order = lens_min, lens_mid, lens_max
-
- return f, lens, lens_order
-
- tri_lengths = [trylens(f) for f in face_sel if len(f) == 3]
- del trylens
-
- def trilensdiff(t1,t2):
- return\
- abs(t1[1][t1[2][0]]-t2[1][t2[2][0]])+\
- abs(t1[1][t1[2][1]]-t2[1][t2[2][1]])+\
- abs(t1[1][t1[2][2]]-t2[1][t2[2][2]])
-
- while tri_lengths:
- tri1 = tri_lengths.pop()
-
- if not tri_lengths:
- pretty_faces.append(prettyface((tri1, None)))
- break
-
- best_tri_index = -1
- best_tri_diff = 100000000.0
-
- for i, tri2 in enumerate(tri_lengths):
- diff = trilensdiff(tri1, tri2)
- if diff < best_tri_diff:
- best_tri_index = i
- best_tri_diff = diff
-
- pretty_faces.append(prettyface((tri1, tri_lengths.pop(best_tri_index))))
-
-
- # Get the min, max and total areas
- max_area = 0.0
- min_area = 100000000.0
- tot_area = 0
- for f in face_sel:
- area = f.area
- if area > max_area: max_area = area
- if area < min_area: min_area = area
- tot_area += area
-
- max_len = sqrt(max_area)
- min_len = sqrt(min_area)
- side_len = sqrt(tot_area)
-
- # Build widths
-
- curr_len = max_len
-
- print '\tGenerating lengths...',
-
- lengths = []
- while curr_len > min_len:
- lengths.append(curr_len)
- curr_len = curr_len/2
-
- # Dont allow boxes smaller then the margin
- # since we contract on the margin, boxes that are smaller will create errors
- # print curr_len, side_len/MARGIN_DIV
- if curr_len/4 < side_len/PREF_MARGIN_DIV:
- break
-
- if not lengths:
- lengths.append(curr_len)
-
- # convert into ints
- lengths_to_ints = {}
-
- l_int = 1
- for l in reversed(lengths):
- lengths_to_ints[l] = l_int
- l_int*=2
-
- lengths_to_ints = lengths_to_ints.items()
- lengths_to_ints.sort()
- print 'done'
-
- # apply quantized values.
-
- for pf in pretty_faces:
- w = pf.width
- h = pf.height
- bestw_diff = 1000000000.0
- besth_diff = 1000000000.0
- new_w = 0.0
- new_h = 0.0
- for l, i in lengths_to_ints:
- d = abs(l - w)
- if d < bestw_diff:
- bestw_diff = d
- new_w = i # assign the int version
-
- d = abs(l - h)
- if d < besth_diff:
- besth_diff = d
- new_h = i # ditto
-
- pf.width = new_w
- pf.height = new_h
-
- if new_w > new_h:
- pf.spin()
-
- print '...done'
-
-
- # Since the boxes are sized in powers of 2, we can neatly group them into bigger squares
- # this is done hierarchily, so that we may avoid running the pack function
- # on many thousands of boxes, (under 1k is best) because it would get slow.
- # Using an off and even dict us usefull because they are packed differently
- # where w/h are the same, their packed in groups of 4
- # where they are different they are packed in pairs
- #
- # After this is done an external pack func is done that packs the whole group.
-
- print '\tConsolidating Boxes...',
- even_dict = {} # w/h are the same, the key is an int (w)
- odd_dict = {} # w/h are different, the key is the (w,h)
-
- for pf in pretty_faces:
- w,h = pf.width, pf.height
- if w==h: even_dict.setdefault(w, []).append( pf )
- else: odd_dict.setdefault((w,h), []).append( pf )
-
- # Count the number of boxes consolidated, only used for stats.
- c = 0
-
- # This is tricky. the total area of all packed boxes, then squt that to get an estimated size
- # this is used then converted into out INT space so we can compare it with
- # the ints assigned to the boxes size
- # and divided by BOX_DIV, basicly if BOX_DIV is 8
- # ...then the maximum box consolidataion (recursive grouping) will have a max width & height
- # ...1/8th of the UV size.
- # ...limiting this is needed or you end up with bug unused texture spaces
- # ...however if its too high, boxpacking is way too slow for high poly meshes.
- float_to_int_factor = lengths_to_ints[0][0]
- if float_to_int_factor > 0:
- max_int_dimension = int(((side_len / float_to_int_factor)) / PREF_BOX_DIV)
- ok = True
- else:
- max_int_dimension = 0.0 # wont be used
- ok = False
-
- # RECURSIVE prettyface grouping
- while ok:
- ok = False
-
- # Tall boxes in groups of 2
- for d, boxes in odd_dict.items():
- if d[1] < max_int_dimension:
- #\boxes.sort(key = lambda a: len(a.children))
- while len(boxes) >= 2:
- # print "foo", len(boxes)
- ok = True
- c += 1
- pf_parent = prettyface([boxes.pop(), boxes.pop()])
- pretty_faces.append(pf_parent)
-
- w,h = pf_parent.width, pf_parent.height
-
- if w>h: raise "error"
-
- if w==h:
- even_dict.setdefault(w, []).append(pf_parent)
- else:
- odd_dict.setdefault((w,h), []).append(pf_parent)
-
- # Even boxes in groups of 4
- for d, boxes in even_dict.items():
- if d < max_int_dimension:
- # py 2.3 compat
- try: boxes.sort(key = lambda a: len(a.children))
- except: boxes.sort(lambda a, b: cmp(len(a.children), len(b.children)))
-
- while len(boxes) >= 4:
- # print "bar", len(boxes)
- ok = True
- c += 1
-
- pf_parent = prettyface([boxes.pop(), boxes.pop(), boxes.pop(), boxes.pop()])
- pretty_faces.append(pf_parent)
- w = pf_parent.width # width and weight are the same
- even_dict.setdefault(w, []).append(pf_parent)
-
- del even_dict
- del odd_dict
-
- orig = len(pretty_faces)
-
- pretty_faces = [pf for pf in pretty_faces if not pf.has_parent]
-
- # spin every second prettyface
- # if there all vertical you get less efficiently used texture space
- i = len(pretty_faces)
- d = 0
- while i:
- i -=1
- pf = pretty_faces[i]
- if pf.width != pf.height:
- d += 1
- if d % 2: # only pack every second
- pf.spin()
- # pass
-
- print 'Consolidated', c, 'boxes, done'
- # print 'done', orig, len(pretty_faces)
-
-
- # boxes2Pack.append([islandIdx, w,h])
- print '\tPacking Boxes', len(pretty_faces), '...',
- boxes2Pack = [ [0.0, 0.0, pf.width, pf.height, i] for i, pf in enumerate(pretty_faces)]
- packWidth, packHeight = Geometry.BoxPack2D(boxes2Pack)
-
- # print packWidth, packHeight
-
- packWidth = float(packWidth)
- packHeight = float(packHeight)
-
- margin_w = ((packWidth) / PREF_MARGIN_DIV)/ packWidth
- margin_h = ((packHeight) / PREF_MARGIN_DIV) / packHeight
-
- # print margin_w, margin_h
- print 'done'
-
- # Apply the boxes back to the UV coords.
- print '\twriting back UVs',
- for i, box in enumerate(boxes2Pack):
- pretty_faces[i].place(box[0], box[1], packWidth, packHeight, margin_w, margin_h)
- # pf.place(box[1][1], box[1][2], packWidth, packHeight, margin_w, margin_h)
- print 'done'
-
-
- if PREF_APPLY_IMAGE:
- if not PREF_PACK_IN_ONE:
- image = Image.New('lightmap', PREF_IMG_PX_SIZE, PREF_IMG_PX_SIZE, 24)
-
- for f in face_sel:
- f.image = image
-
- for me in meshes:
- me.update()
-
- print 'finished all %.2f ' % (sys.time() - t)
-
- Window.RedrawAll()
-
-def main():
- scn = bpy.data.scenes.active
-
- PREF_ACT_ONLY = Draw.Create(1)
- PREF_SEL_ONLY = Draw.Create(1)
- PREF_NEW_UVLAYER = Draw.Create(0)
- PREF_PACK_IN_ONE = Draw.Create(0)
- PREF_APPLY_IMAGE = Draw.Create(0)
- PREF_IMG_PX_SIZE = Draw.Create(512)
- PREF_BOX_DIV = Draw.Create(12)
- PREF_MARGIN_DIV = Draw.Create(0.1)
-
- if not Draw.PupBlock('Lightmap Pack', [\
- 'Context...',
- ('Active Object', PREF_ACT_ONLY, 'If disabled, include other selected objects for packing the lightmap.'),\
- ('Selected Faces', PREF_SEL_ONLY, 'Use only selected faces from all selected meshes.'),\
- 'Image & UVs...',
- ('Share Tex Space', PREF_PACK_IN_ONE, 'Objects Share texture space, map all objects into 1 uvmap'),\
- ('New UV Layer', PREF_NEW_UVLAYER, 'Create a new UV layer for every mesh packed'),\
- ('New Image', PREF_APPLY_IMAGE, 'Assign new images for every mesh (only one if shared tex space enabled)'),\
- ('Image Size', PREF_IMG_PX_SIZE, 64, 5000, 'Width and Height for the new image'),\
- 'UV Packing...',
- ('Pack Quality: ', PREF_BOX_DIV, 1, 48, 'Pre Packing before the complex boxpack'),\
- ('Margin: ', PREF_MARGIN_DIV, 0.001, 1.0, 'Size of the margin as a division of the UV')\
- ]):
- return
-
-
- if PREF_ACT_ONLY.val:
- ob = scn.objects.active
- if ob == None or ob.type != 'Mesh':
- Draw.PupMenu('Error%t|No mesh object.')
- return
- meshes = [ ob.getData(mesh=1) ]
- else:
- meshes = dict([ (me.name, me) for ob in scn.objects.context if ob.type == 'Mesh' for me in (ob.getData(mesh=1),) if not me.lib if len(me.faces)])
- meshes = meshes.values()
- if not meshes:
- Draw.PupMenu('Error%t|No mesh objects selected.')
- return
-
- # Toggle Edit mode
- is_editmode = Window.EditMode()
- if is_editmode:
- Window.EditMode(0)
-
-
- Window.WaitCursor(1)
- lightmap_uvpack(meshes,\
- PREF_SEL_ONLY.val,\
- PREF_NEW_UVLAYER.val,\
- PREF_PACK_IN_ONE.val,\
- PREF_APPLY_IMAGE.val,\
- PREF_IMG_PX_SIZE.val,\
- PREF_BOX_DIV.val,\
- int(1/(PREF_MARGIN_DIV.val/100)))
-
- if is_editmode:
- Window.EditMode(1)
-
- Window.WaitCursor(0)
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/uvcalc_quad_clickproj.py b/release/scripts/uvcalc_quad_clickproj.py
deleted file mode 100644
index 298103e4d5f..00000000000
--- a/release/scripts/uvcalc_quad_clickproj.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Click project from face'
-Blender: 245
-Group: 'UVCalculation'
-Tooltip: '3 Clicks to project uvs onto selected faces.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__=\
-'''
-http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Click_project_from_face
-"
-
-'''
-
-# --------------------------------------------------------------------------
-# Click project v0.1 by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-import BPyMesh
-import BPyWindow
-
-mouseViewRay= BPyWindow.mouseViewRay
-from Blender import Mathutils, Window, Scene, Draw, sys
-from Blender.Mathutils import Vector, Matrix, LineIntersect, Intersect #, AngleBetweenVecs, Intersect
-LMB= Window.MButs.L
-RMB= Window.MButs.R
-
-def using_modifier(ob):
- for m in ob.modifiers:
- if m[Blender.Modifier.Settings.REALTIME]:
- return True
- return False
-
-def mouseup():
- # Loop until click
- mouse_buttons = Window.GetMouseButtons()
- while not mouse_buttons & LMB:
- sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
- while mouse_buttons & LMB:
- sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
-
-def mousedown_wait():
- # If the menu has just been pressed dont use its mousedown,
- mouse_buttons = Window.GetMouseButtons()
- while mouse_buttons & LMB:
- mouse_buttons = Window.GetMouseButtons()
- sys.sleep(10)
-
-def main():
-
- scn = bpy.data.scenes.active
- ob = scn.objects.active
- if not ob or ob.type!='Mesh':
- return
-
- is_editmode = Window.EditMode()
- if is_editmode:
- Window.EditMode(0)
-
- mousedown_wait() # so the menu items clicking dosnt trigger the mouseclick
-
- Window.DrawProgressBar (0.0, '')
- Window.DrawProgressBar (0.1, '(1 of 3) Click on a face corner')
-
- # wait for a click
- mouse_buttons = Window.GetMouseButtons()
- while not mouse_buttons & LMB:
- sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
-
- # Allow for RMB cancel
- if mouse_buttons & RMB:
- return
-
- while mouse_buttons & LMB:
- sys.sleep(10)
- mouse_buttons = Window.GetMouseButtons()
-
-
- Window.DrawProgressBar (0.2, '(2 of 3 ) Click confirms the U coords')
-
- mousedown_wait()
-
- obmat= ob.matrixWorld
- screen_x, screen_y = Window.GetMouseCoords()
- mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)
-
- if not mouseInView or not OriginA:
- return
-
- me = ob.getData(mesh=1)
-
- # Get the face under the mouse
- face_click, isect, side = BPyMesh.pickMeshRayFace(me, OriginA, DirectionA)
- if not face_click:
- return
-
- proj_z_component = face_click.no
- if not face_click:
- return
-
- # Find the face vertex thats closest to the mouse,
- # this vert will be used as the corner to map from.
- best_v= None
- best_length = 10000000
- vi1 = None
- for i, v in enumerate(face_click.v):
- l = (v.co-isect).length
- if l < best_length:
- best_v = v
- best_length = l
- vi1 = i
-
- # now get the 2 edges in the face that connect to v
- # we can work it out fairly easerly
- if len(face_click)==4:
- if vi1==0: vi2, vi3= 3,1
- elif vi1==1: vi2, vi3= 0,2
- elif vi1==2: vi2, vi3= 1,3
- elif vi1==3: vi2, vi3= 2,0
- else:
- if vi1==0: vi2, vi3= 2,1
- elif vi1==1: vi2, vi3= 0,2
- elif vi1==2: vi2, vi3= 1,0
-
- face_corner_main =face_click.v[vi1].co
- face_corner_a =face_click.v[vi2].co
- face_corner_b =face_click.v[vi3].co
-
- line_a_len = (face_corner_a-face_corner_main).length
- line_b_len = (face_corner_b-face_corner_main).length
-
- orig_cursor = Window.GetCursorPos()
- Window.SetCursorPos(face_corner_main.x, face_corner_main.y, face_corner_main.z)
-
- SHIFT = Window.Qual.SHIFT
- MODE = 0 # firstclick, 1, secondclick
- mouse_buttons = Window.GetMouseButtons()
-
- project_mat = Matrix([0,0,0], [0,0,0], [0,0,0])
-
-
- def get_face_coords(f):
- f_uv = f.uv
- return [(v.co-face_corner_main, f_uv[i]) for i,v in enumerate(f.v)]
-
- if me.faceUV==False:
- me.faceUV= True
-
- coords = [ (co,uv) for f in me.faces if f.sel for co, uv in get_face_coords(f)]
-
- coords_orig = [uv.copy() for co, uv in coords]
- USE_MODIFIER = using_modifier(ob)
-
- while 1:
- if mouse_buttons & LMB:
- if MODE == 0:
- mousedown_wait()
- Window.DrawProgressBar (0.8, '(3 of 3 ) Click confirms the V coords')
- MODE = 1 # second click
-
- # Se we cont continually set the length and get float error
- proj_y_component_orig = proj_y_component.copy()
- else:
- break
-
- elif mouse_buttons & RMB:
- # Restore old uvs
- for i, uv_orig in enumerate(coords_orig):
- coords[i][1][:] = uv_orig
- break
-
- mouse_buttons = Window.GetMouseButtons()
- screen_x, screen_y = Window.GetMouseCoords()
- mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)
-
- if not mouseInView:
- continue
-
- # Do a ray tri intersection, not clipped by the tri
- new_isect = Intersect(face_corner_main, face_corner_a, face_corner_b, DirectionA, OriginA, False)
- new_isect_alt = new_isect + DirectionA*0.0001
-
-
- # The distance from the mouse cursor ray vector to the edge
- line_isect_a_pair = LineIntersect(new_isect, new_isect_alt, face_corner_main, face_corner_a)
- line_isect_b_pair = LineIntersect(new_isect, new_isect_alt, face_corner_main, face_corner_b)
-
- # SHIFT to flip the axis.
- is_shift = Window.GetKeyQualifiers() & SHIFT
-
- if MODE == 0:
- line_dist_a = (line_isect_a_pair[0]-line_isect_a_pair[1]).length
- line_dist_b = (line_isect_b_pair[0]-line_isect_b_pair[1]).length
-
- if line_dist_a < line_dist_b:
- proj_x_component = face_corner_a - face_corner_main
- y_axis_length = line_b_len
- x_axis_length = (line_isect_a_pair[1]-face_corner_main).length
- else:
- proj_x_component = face_corner_b - face_corner_main
- y_axis_length = line_a_len
- x_axis_length = (line_isect_b_pair[1]-face_corner_main).length
-
- proj_y_component = proj_x_component.cross(proj_z_component)
-
- proj_y_component.length = 1/y_axis_length
- proj_x_component.length = 1/x_axis_length
-
- if is_shift: proj_x_component.negate()
-
- else:
- proj_y_component[:] = proj_y_component_orig
- if line_dist_a < line_dist_b:
- proj_y_component.length = 1/(line_isect_a_pair[1]-new_isect).length
- else:
- proj_y_component.length = 1/(line_isect_b_pair[1]-new_isect).length
-
- if is_shift: proj_y_component.negate()
-
- # Use the existing matrix to make a new 3x3 projecton matrix
- project_mat[0][:] = -proj_y_component
- project_mat[1][:] = -proj_x_component
- project_mat[2][:] = proj_z_component
-
- # Apply the projection matrix
- for proj_co, uv in coords:
- uv[:] = (project_mat * proj_co)[0:2]
-
- if USE_MODIFIER:
- me.update()
-
- Window.Redraw(Window.Types.VIEW3D)
-
- Window.SetCursorPos(*orig_cursor)
- if is_editmode:
- Window.EditMode(1)
-
- Window.RedrawAll()
-
-if __name__=='__main__':
- main()
- Window.DrawProgressBar(1.0, '')
-
diff --git a/release/scripts/uvcalc_smart_project.py b/release/scripts/uvcalc_smart_project.py
deleted file mode 100644
index 9d9bd2aaefd..00000000000
--- a/release/scripts/uvcalc_smart_project.py
+++ /dev/null
@@ -1,1132 +0,0 @@
-#!BPY
-
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'Unwrap (smart projections)'
-Blender: 240
-Group: 'UVCalculation'
-Tooltip: 'UV Unwrap mesh faces for all select mesh objects'
-"""
-
-
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.1 12/18/05"
-
-__bpydoc__ = """\
-This script projection unwraps the selected faces of a mesh.
-
-it operates on all selected mesh objects, and can be used unwrap
-selected faces, or all faces.
-"""
-
-# --------------------------------------------------------------------------
-# Smart Projection UV Projection Unwrapper v1.1 by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-from Blender import Object, Draw, Window, sys, Mesh, Geometry
-from Blender.Mathutils import Matrix, Vector, RotationMatrix
-import bpy
-from math import cos
-
-DEG_TO_RAD = 0.017453292519943295 # pi/180.0
-SMALL_NUM = 0.000000001
-BIG_NUM = 1e15
-
-global USER_FILL_HOLES
-global USER_FILL_HOLES_QUALITY
-USER_FILL_HOLES = None
-USER_FILL_HOLES_QUALITY = None
-
-dict_matrix = {}
-
-def pointInTri2D(v, v1, v2, v3):
- global dict_matrix
-
- key = v1.x, v1.y, v2.x, v2.y, v3.x, v3.y
-
- # Commented because its slower to do teh bounds check, we should realy cache the bounds info for each face.
- '''
- # BOUNDS CHECK
- xmin= 1000000
- ymin= 1000000
-
- xmax= -1000000
- ymax= -1000000
-
- for i in (0,2,4):
- x= key[i]
- y= key[i+1]
-
- if xmax<x: xmax= x
- if ymax<y: ymax= y
- if xmin>x: xmin= x
- if ymin>y: ymin= y
-
- x= v.x
- y= v.y
-
- if x<xmin or x>xmax or y < ymin or y > ymax:
- return False
- # Done with bounds check
- '''
- try:
- mtx = dict_matrix[key]
- if not mtx:
- return False
- except:
- side1 = v2 - v1
- side2 = v3 - v1
-
- nor = side1.cross(side2)
-
- l1 = [side1[0], side1[1], side1[2]]
- l2 = [side2[0], side2[1], side2[2]]
- l3 = [nor[0], nor[1], nor[2]]
-
- mtx = Matrix(l1, l2, l3)
-
- # Zero area 2d tri, even tho we throw away zerop area faces
- # the projection UV can result in a zero area UV.
- if not mtx.determinant():
- dict_matrix[key] = None
- return False
-
- mtx.invert()
-
- dict_matrix[key] = mtx
-
- uvw = (v - v1) * mtx
- return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1
-
-
-def boundsIsland(faces):
- minx = maxx = faces[0].uv[0][0] # Set initial bounds.
- miny = maxy = faces[0].uv[0][1]
- # print len(faces), minx, maxx, miny , maxy
- for f in faces:
- for uv in f.uv:
- x= uv.x
- y= uv.y
- if x<minx: minx= x
- if y<miny: miny= y
- if x>maxx: maxx= x
- if y>maxy: maxy= y
-
- return minx, miny, maxx, maxy
-
-"""
-def boundsEdgeLoop(edges):
- minx = maxx = edges[0][0] # Set initial bounds.
- miny = maxy = edges[0][1]
- # print len(faces), minx, maxx, miny , maxy
- for ed in edges:
- for pt in ed:
- print 'ass'
- x= pt[0]
- y= pt[1]
- if x<minx: x= minx
- if y<miny: y= miny
- if x>maxx: x= maxx
- if y>maxy: y= maxy
-
- return minx, miny, maxx, maxy
-"""
-
-# Turns the islands into a list of unpordered edges (Non internal)
-# Onlt for UV's
-# only returns outline edges for intersection tests. and unique points.
-
-def island2Edge(island):
-
- # Vert index edges
- edges = {}
-
- unique_points= {}
-
- for f in island:
- f_uvkey= map(tuple, f.uv)
-
-
- for vIdx, edkey in enumerate(f.edge_keys):
- unique_points[f_uvkey[vIdx]] = f.uv[vIdx]
-
- if f.v[vIdx].index > f.v[vIdx-1].index:
- i1= vIdx-1; i2= vIdx
- else:
- i1= vIdx; i2= vIdx-1
-
- try: edges[ f_uvkey[i1], f_uvkey[i2] ] *= 0 # sets eny edge with more then 1 user to 0 are not returned.
- except: edges[ f_uvkey[i1], f_uvkey[i2] ] = (f.uv[i1] - f.uv[i2]).length,
-
- # If 2 are the same then they will be together, but full [a,b] order is not correct.
-
- # Sort by length
-
-
- length_sorted_edges = [(Vector(key[0]), Vector(key[1]), value) for key, value in edges.iteritems() if value != 0]
-
- try: length_sorted_edges.sort(key = lambda A: -A[2]) # largest first
- except: length_sorted_edges.sort(lambda A, B: cmp(B[2], A[2]))
-
- # Its okay to leave the length in there.
- #for e in length_sorted_edges:
- # e.pop(2)
-
- # return edges and unique points
- return length_sorted_edges, [v.__copy__().resize3D() for v in unique_points.itervalues()]
-
-# ========================= NOT WORKING????
-# Find if a points inside an edge loop, un-orderd.
-# pt is and x/y
-# edges are a non ordered loop of edges.
-# #offsets are the edge x and y offset.
-"""
-def pointInEdges(pt, edges):
- #
- x1 = pt[0]
- y1 = pt[1]
-
- # Point to the left of this line.
- x2 = -100000
- y2 = -10000
- intersectCount = 0
- for ed in edges:
- xi, yi = lineIntersection2D(x1,y1, x2,y2, ed[0][0], ed[0][1], ed[1][0], ed[1][1])
- if xi != None: # Is there an intersection.
- intersectCount+=1
-
- return intersectCount % 2
-"""
-
-def pointInIsland(pt, island):
- vec1 = Vector(); vec2 = Vector(); vec3 = Vector()
- for f in island:
- vec1.x, vec1.y = f.uv[0]
- vec2.x, vec2.y = f.uv[1]
- vec3.x, vec3.y = f.uv[2]
-
- if pointInTri2D(pt, vec1, vec2, vec3):
- return True
-
- if len(f.v) == 4:
- vec1.x, vec1.y = f.uv[0]
- vec2.x, vec2.y = f.uv[2]
- vec3.x, vec3.y = f.uv[3]
- if pointInTri2D(pt, vec1, vec2, vec3):
- return True
- return False
-
-
-# box is (left,bottom, right, top)
-def islandIntersectUvIsland(source, target, SourceOffset):
- # Is 1 point in the box, inside the vertLoops
- edgeLoopsSource = source[6] # Pretend this is offset
- edgeLoopsTarget = target[6]
-
- # Edge intersect test
- for ed in edgeLoopsSource:
- for seg in edgeLoopsTarget:
- i = Geometry.LineIntersect2D(\
- seg[0], seg[1], SourceOffset+ed[0], SourceOffset+ed[1])
- if i:
- return 1 # LINE INTERSECTION
-
- # 1 test for source being totally inside target
- SourceOffset.resize3D()
- for pv in source[7]:
- if pointInIsland(pv+SourceOffset, target[0]):
- return 2 # SOURCE INSIDE TARGET
-
- # 2 test for a part of the target being totaly inside the source.
- for pv in target[7]:
- if pointInIsland(pv-SourceOffset, source[0]):
- return 3 # PART OF TARGET INSIDE SOURCE.
-
- return 0 # NO INTERSECTION
-
-
-
-
-# Returns the X/y Bounds of a list of vectors.
-def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1):
-
- # UV's will never extend this far.
- minx = miny = BIG_NUM
- maxx = maxy = -BIG_NUM
-
- for i, v in enumerate(vecs):
-
- # Do this allong the way
- if mat != -1:
- v = vecs[i] = v*mat
- x= v.x
- y= v.y
- if x<minx: minx= x
- if y<miny: miny= y
- if x>maxx: maxx= x
- if y>maxy: maxy= y
-
- # Spesific to this algo, bail out if we get bigger then the current area
- if bestAreaSoFar != -1 and (maxx-minx) * (maxy-miny) > bestAreaSoFar:
- return (BIG_NUM, None), None
- w = maxx-minx
- h = maxy-miny
- return (w*h, w,h), vecs # Area, vecs
-
-# Takes a list of faces that make up a UV island and rotate
-# until they optimally fit inside a square.
-ROTMAT_2D_POS_90D = RotationMatrix( 90, 2)
-ROTMAT_2D_POS_45D = RotationMatrix( 45, 2)
-
-RotMatStepRotation = []
-rot_angle = 22.5 #45.0/2
-while rot_angle > 0.1:
- RotMatStepRotation.append([\
- RotationMatrix( rot_angle, 2),\
- RotationMatrix( -rot_angle, 2)])
-
- rot_angle = rot_angle/2.0
-
-
-def optiRotateUvIsland(faces):
- global currentArea
-
- # Bestfit Rotation
- def best2dRotation(uvVecs, MAT1, MAT2):
- global currentArea
-
- newAreaPos, newfaceProjectionGroupListPos =\
- testNewVecLs2DRotIsBetter(uvVecs[:], MAT1, currentArea[0])
-
-
- # Why do I use newpos here? May as well give the best area to date for an early bailout
- # some slight speed increase in this.
- # If the new rotation is smaller then the existing, we can
- # avoid copying a list and overwrite the old, crappy one.
-
- if newAreaPos[0] < currentArea[0]:
- newAreaNeg, newfaceProjectionGroupListNeg =\
- testNewVecLs2DRotIsBetter(uvVecs, MAT2, newAreaPos[0]) # Reuse the old bigger list.
- else:
- newAreaNeg, newfaceProjectionGroupListNeg =\
- testNewVecLs2DRotIsBetter(uvVecs[:], MAT2, currentArea[0]) # Cant reuse, make a copy.
-
-
- # Now from the 3 options we need to discover which to use
- # we have cerrentArea/newAreaPos/newAreaNeg
- bestArea = min(currentArea[0], newAreaPos[0], newAreaNeg[0])
-
- if currentArea[0] == bestArea:
- return uvVecs
- elif newAreaPos[0] == bestArea:
- uvVecs = newfaceProjectionGroupListPos
- currentArea = newAreaPos
- elif newAreaNeg[0] == bestArea:
- uvVecs = newfaceProjectionGroupListNeg
- currentArea = newAreaNeg
-
- return uvVecs
-
-
- # Serialized UV coords to Vectors
- uvVecs = [uv for f in faces for uv in f.uv]
-
- # Theres a small enough number of these to hard code it
- # rather then a loop.
-
- # Will not modify anything
- currentArea, dummy =\
- testNewVecLs2DRotIsBetter(uvVecs)
-
-
- # Try a 45d rotation
- newAreaPos, newfaceProjectionGroupListPos = testNewVecLs2DRotIsBetter(uvVecs[:], ROTMAT_2D_POS_45D, currentArea[0])
-
- if newAreaPos[0] < currentArea[0]:
- uvVecs = newfaceProjectionGroupListPos
- currentArea = newAreaPos
- # 45d done
-
- # Testcase different rotations and find the onfe that best fits in a square
- for ROTMAT in RotMatStepRotation:
- uvVecs = best2dRotation(uvVecs, ROTMAT[0], ROTMAT[1])
-
- # Only if you want it, make faces verticle!
- if currentArea[1] > currentArea[2]:
- # Rotate 90d
- # Work directly on the list, no need to return a value.
- testNewVecLs2DRotIsBetter(uvVecs, ROTMAT_2D_POS_90D)
-
-
- # Now write the vectors back to the face UV's
- i = 0 # count the serialized uv/vectors
- for f in faces:
- #f.uv = [uv for uv in uvVecs[i:len(f)+i] ]
- for j, k in enumerate(xrange(i, len(f.v)+i)):
- f.uv[j][:] = uvVecs[k]
- i += len(f.v)
-
-
-# Takes an island list and tries to find concave, hollow areas to pack smaller islands into.
-def mergeUvIslands(islandList):
- global USER_FILL_HOLES
- global USER_FILL_HOLES_QUALITY
-
-
- # Pack islands to bottom LHS
- # Sync with island
-
- #islandTotFaceArea = [] # A list of floats, each island area
- #islandArea = [] # a list of tuples ( area, w,h)
-
-
- decoratedIslandList = []
-
- islandIdx = len(islandList)
- while islandIdx:
- islandIdx-=1
- minx, miny, maxx, maxy = boundsIsland(islandList[islandIdx])
- w, h = maxx-minx, maxy-miny
-
- totFaceArea = 0
- offset= Vector(minx, miny)
- for f in islandList[islandIdx]:
- for uv in f.uv:
- uv -= offset
-
- totFaceArea += f.area
-
- islandBoundsArea = w*h
- efficiency = abs(islandBoundsArea - totFaceArea)
-
- # UV Edge list used for intersections as well as unique points.
- edges, uniqueEdgePoints = island2Edge(islandList[islandIdx])
-
- decoratedIslandList.append([islandList[islandIdx], totFaceArea, efficiency, islandBoundsArea, w,h, edges, uniqueEdgePoints])
-
-
- # Sort by island bounding box area, smallest face area first.
- # no.. chance that to most simple edge loop first.
- decoratedIslandListAreaSort =decoratedIslandList[:]
-
- try: decoratedIslandListAreaSort.sort(key = lambda A: A[3])
- except: decoratedIslandListAreaSort.sort(lambda A, B: cmp(A[3], B[3]))
-
-
- # sort by efficiency, Least Efficient first.
- decoratedIslandListEfficSort = decoratedIslandList[:]
- # decoratedIslandListEfficSort.sort(lambda A, B: cmp(B[2], A[2]))
-
- try: decoratedIslandListEfficSort.sort(key = lambda A: -A[2])
- except: decoratedIslandListEfficSort.sort(lambda A, B: cmp(B[2], A[2]))
-
- # ================================================== THESE CAN BE TWEAKED.
- # This is a quality value for the number of tests.
- # from 1 to 4, generic quality value is from 1 to 100
- USER_STEP_QUALITY = ((USER_FILL_HOLES_QUALITY - 1) / 25.0) + 1
-
- # If 100 will test as long as there is enough free space.
- # this is rarely enough, and testing takes a while, so lower quality speeds this up.
-
- # 1 means they have the same quality
- USER_FREE_SPACE_TO_TEST_QUALITY = 1 + (((100 - USER_FILL_HOLES_QUALITY)/100.0) *5)
-
- #print 'USER_STEP_QUALITY', USER_STEP_QUALITY
- #print 'USER_FREE_SPACE_TO_TEST_QUALITY', USER_FREE_SPACE_TO_TEST_QUALITY
-
- removedCount = 0
-
- areaIslandIdx = 0
- ctrl = Window.Qual.CTRL
- BREAK= False
- while areaIslandIdx < len(decoratedIslandListAreaSort) and not BREAK:
- sourceIsland = decoratedIslandListAreaSort[areaIslandIdx]
- # Alredy packed?
- if not sourceIsland[0]:
- areaIslandIdx+=1
- else:
- efficIslandIdx = 0
- while efficIslandIdx < len(decoratedIslandListEfficSort) and not BREAK:
-
- if Window.GetKeyQualifiers() & ctrl:
- BREAK= True
- break
-
- # Now we have 2 islands, is the efficience of the islands lowers theres an
- # increasing likely hood that we can fit merge into the bigger UV island.
- # this ensures a tight fit.
-
- # Just use figures we have about user/unused area to see if they might fit.
-
- targetIsland = decoratedIslandListEfficSort[efficIslandIdx]
-
-
- if sourceIsland[0] == targetIsland[0] or\
- not targetIsland[0] or\
- not sourceIsland[0]:
- pass
- else:
-
- # ([island, totFaceArea, efficiency, islandArea, w,h])
- # Waisted space on target is greater then UV bounding island area.
-
-
- # if targetIsland[3] > (sourceIsland[2]) and\ #
- # print USER_FREE_SPACE_TO_TEST_QUALITY, 'ass'
- if targetIsland[2] > (sourceIsland[1] * USER_FREE_SPACE_TO_TEST_QUALITY) and\
- targetIsland[4] > sourceIsland[4] and\
- targetIsland[5] > sourceIsland[5]:
-
- # DEBUG # print '%.10f %.10f' % (targetIsland[3], sourceIsland[1])
-
- # These enough spare space lets move the box until it fits
-
- # How many times does the source fit into the target x/y
- blockTestXUnit = targetIsland[4]/sourceIsland[4]
- blockTestYUnit = targetIsland[5]/sourceIsland[5]
-
- boxLeft = 0
-
-
- # Distllllance we can move between whilst staying inside the targets bounds.
- testWidth = targetIsland[4] - sourceIsland[4]
- testHeight = targetIsland[5] - sourceIsland[5]
-
- # Increment we move each test. x/y
- xIncrement = (testWidth / (blockTestXUnit * ((USER_STEP_QUALITY/50)+0.1)))
- yIncrement = (testHeight / (blockTestYUnit * ((USER_STEP_QUALITY/50)+0.1)))
-
- # Make sure were not moving less then a 3rg of our width/height
- if xIncrement<sourceIsland[4]/3:
- xIncrement= sourceIsland[4]
- if yIncrement<sourceIsland[5]/3:
- yIncrement= sourceIsland[5]
-
-
- boxLeft = 0 # Start 1 back so we can jump into the loop.
- boxBottom= 0 #-yIncrement
-
- ##testcount= 0
-
- while boxBottom <= testHeight:
- # Should we use this? - not needed for now.
- #if Window.GetKeyQualifiers() & ctrl:
- # BREAK= True
- # break
-
- ##testcount+=1
- #print 'Testing intersect'
- Intersect = islandIntersectUvIsland(sourceIsland, targetIsland, Vector(boxLeft, boxBottom))
- #print 'Done', Intersect
- if Intersect == 1: # Line intersect, dont bother with this any more
- pass
-
- if Intersect == 2: # Source inside target
- '''
- We have an intersection, if we are inside the target
- then move us 1 whole width accross,
- Its possible this is a bad idea since 2 skinny Angular faces
- could join without 1 whole move, but its a lot more optimal to speed this up
- since we have alredy tested for it.
-
- It gives about 10% speedup with minimal errors.
- '''
- #print 'ass'
- # Move the test allong its width + SMALL_NUM
- #boxLeft += sourceIsland[4] + SMALL_NUM
- boxLeft += sourceIsland[4]
- elif Intersect == 0: # No intersection?? Place it.
- # Progress
- removedCount +=1
- Window.DrawProgressBar(0.0, 'Merged: %i islands, Ctrl to finish early.' % removedCount)
-
- # Move faces into new island and offset
- targetIsland[0].extend(sourceIsland[0])
- offset= Vector(boxLeft, boxBottom)
-
- for f in sourceIsland[0]:
- for uv in f.uv:
- uv+= offset
-
- sourceIsland[0][:] = [] # Empty
-
-
- # Move edge loop into new and offset.
- # targetIsland[6].extend(sourceIsland[6])
- #while sourceIsland[6]:
- targetIsland[6].extend( [ (\
- (e[0]+offset, e[1]+offset, e[2])\
- ) for e in sourceIsland[6] ] )
-
- sourceIsland[6][:] = [] # Empty
-
- # Sort by edge length, reverse so biggest are first.
-
- try: targetIsland[6].sort(key = lambda A: A[2])
- except: targetIsland[6].sort(lambda B,A: cmp(A[2], B[2] ))
-
-
- targetIsland[7].extend(sourceIsland[7])
- offset= Vector(boxLeft, boxBottom, 0)
- for p in sourceIsland[7]:
- p+= offset
-
- sourceIsland[7][:] = []
-
-
- # Decrement the efficiency
- targetIsland[1]+=sourceIsland[1] # Increment totFaceArea
- targetIsland[2]-=sourceIsland[1] # Decrement efficiency
- # IF we ever used these again, should set to 0, eg
- sourceIsland[2] = 0 # No area if anyone wants to know
-
- break
-
-
- # INCREMENR NEXT LOCATION
- if boxLeft > testWidth:
- boxBottom += yIncrement
- boxLeft = 0.0
- else:
- boxLeft += xIncrement
- ##print testcount
-
- efficIslandIdx+=1
- areaIslandIdx+=1
-
- # Remove empty islands
- i = len(islandList)
- while i:
- i-=1
- if not islandList[i]:
- del islandList[i] # Can increment islands removed here.
-
-# Takes groups of faces. assumes face groups are UV groups.
-def getUvIslands(faceGroups, me):
-
- # Get seams so we dont cross over seams
- edge_seams = {} # shoudl be a set
- SEAM = Mesh.EdgeFlags.SEAM
- for ed in me.edges:
- if ed.flag & SEAM:
- edge_seams[ed.key] = None # dummy var- use sets!
- # Done finding seams
-
-
- islandList = []
-
- Window.DrawProgressBar(0.0, 'Splitting %d projection groups into UV islands:' % len(faceGroups))
- #print '\tSplitting %d projection groups into UV islands:' % len(faceGroups),
- # Find grouped faces
-
- faceGroupIdx = len(faceGroups)
-
- while faceGroupIdx:
- faceGroupIdx-=1
- faces = faceGroups[faceGroupIdx]
-
- if not faces:
- continue
-
- # Build edge dict
- edge_users = {}
-
- for i, f in enumerate(faces):
- for ed_key in f.edge_keys:
- if edge_seams.has_key(ed_key): # DELIMIT SEAMS! ;)
- edge_users[ed_key] = [] # so as not to raise an error
- else:
- try: edge_users[ed_key].append(i)
- except: edge_users[ed_key] = [i]
-
- # Modes
- # 0 - face not yet touched.
- # 1 - added to island list, and need to search
- # 2 - touched and searched - dont touch again.
- face_modes = [0] * len(faces) # initialize zero - untested.
-
- face_modes[0] = 1 # start the search with face 1
-
- newIsland = []
-
- newIsland.append(faces[0])
-
-
- ok = True
- while ok:
-
- ok = True
- while ok:
- ok= False
- for i in xrange(len(faces)):
- if face_modes[i] == 1: # search
- for ed_key in faces[i].edge_keys:
- for ii in edge_users[ed_key]:
- if i != ii and face_modes[ii] == 0:
- face_modes[ii] = ok = 1 # mark as searched
- newIsland.append(faces[ii])
-
- # mark as searched, dont look again.
- face_modes[i] = 2
-
- islandList.append(newIsland)
-
- ok = False
- for i in xrange(len(faces)):
- if face_modes[i] == 0:
- newIsland = []
- newIsland.append(faces[i])
-
- face_modes[i] = ok = 1
- break
- # if not ok will stop looping
-
- Window.DrawProgressBar(0.1, 'Optimizing Rotation for %i UV Islands' % len(islandList))
-
- for island in islandList:
- optiRotateUvIsland(island)
-
- return islandList
-
-
-def packIslands(islandList):
- if USER_FILL_HOLES:
- Window.DrawProgressBar(0.1, 'Merging Islands (Ctrl: skip merge)...')
- mergeUvIslands(islandList) # Modify in place
-
-
- # Now we have UV islands, we need to pack them.
-
- # Make a synchronised list with the islands
- # so we can box pak the islands.
- packBoxes = []
-
- # Keep a list of X/Y offset so we can save time by writing the
- # uv's and packed data in one pass.
- islandOffsetList = []
-
- islandIdx = 0
-
- while islandIdx < len(islandList):
- minx, miny, maxx, maxy = boundsIsland(islandList[islandIdx])
-
- w, h = maxx-minx, maxy-miny
-
- if USER_ISLAND_MARGIN:
- minx -= USER_ISLAND_MARGIN# *w
- miny -= USER_ISLAND_MARGIN# *h
- maxx += USER_ISLAND_MARGIN# *w
- maxy += USER_ISLAND_MARGIN# *h
-
- # recalc width and height
- w, h = maxx-minx, maxy-miny
-
- if w < 0.00001 or h < 0.00001:
- del islandList[islandIdx]
- islandIdx -=1
- continue
-
- '''Save the offset to be applied later,
- we could apply to the UVs now and allign them to the bottom left hand area
- of the UV coords like the box packer imagines they are
- but, its quicker just to remember their offset and
- apply the packing and offset in 1 pass '''
- islandOffsetList.append((minx, miny))
-
- # Add to boxList. use the island idx for the BOX id.
- packBoxes.append([0, 0, w, h])
- islandIdx+=1
-
- # Now we have a list of boxes to pack that syncs
- # with the islands.
-
- #print '\tPacking UV Islands...'
- Window.DrawProgressBar(0.7, 'Packing %i UV Islands...' % len(packBoxes) )
-
- time1 = sys.time()
- packWidth, packHeight = Geometry.BoxPack2D(packBoxes)
-
- # print 'Box Packing Time:', sys.time() - time1
-
- #if len(pa ckedLs) != len(islandList):
- # raise "Error packed boxes differes from original length"
-
- #print '\tWriting Packed Data to faces'
- Window.DrawProgressBar(0.8, 'Writing Packed Data to faces')
-
- # Sort by ID, so there in sync again
- islandIdx = len(islandList)
- # Having these here avoids devide by 0
- if islandIdx:
-
- if USER_STRETCH_ASPECT:
- # Maximize to uv area?? Will write a normalize function.
- xfactor = 1.0 / packWidth
- yfactor = 1.0 / packHeight
- else:
- # Keep proportions.
- xfactor = yfactor = 1.0 / max(packWidth, packHeight)
-
- while islandIdx:
- islandIdx -=1
- # Write the packed values to the UV's
-
- xoffset = packBoxes[islandIdx][0] - islandOffsetList[islandIdx][0]
- yoffset = packBoxes[islandIdx][1] - islandOffsetList[islandIdx][1]
-
- for f in islandList[islandIdx]: # Offsetting the UV's so they fit in there packed box
- for uv in f.uv:
- uv.x= (uv.x+xoffset) * xfactor
- uv.y= (uv.y+yoffset) * yfactor
-
-
-
-def VectoMat(vec):
- a3 = vec.__copy__().normalize()
-
- up = Vector(0,0,1)
- if abs(a3.dot(up)) == 1.0:
- up = Vector(0,1,0)
-
- a1 = a3.cross(up).normalize()
- a2 = a3.cross(a1)
- return Matrix([a1[0], a1[1], a1[2]], [a2[0], a2[1], a2[2]], [a3[0], a3[1], a3[2]])
-
-
-
-class thickface(object):
- __slost__= 'v', 'uv', 'no', 'area', 'edge_keys'
- def __init__(self, face):
- self.v = face.v
- self.uv = face.uv
- self.no = face.no
- self.area = face.area
- self.edge_keys = face.edge_keys
-
-global ob
-ob = None
-def main():
- global USER_FILL_HOLES
- global USER_FILL_HOLES_QUALITY
- global USER_STRETCH_ASPECT
- global USER_ISLAND_MARGIN
-
- objects= bpy.data.scenes.active.objects
-
- # we can will tag them later.
- obList = [ob for ob in objects.context if ob.type == 'Mesh']
-
- # Face select object may not be selected.
- ob = objects.active
- if ob and ob.sel == 0 and ob.type == 'Mesh':
- # Add to the list
- obList =[ob]
- del objects
-
- if not obList:
- Draw.PupMenu('error, no selected mesh objects')
- return
-
- # Create the variables.
- USER_PROJECTION_LIMIT = Draw.Create(66)
- USER_ONLY_SELECTED_FACES = Draw.Create(1)
- USER_SHARE_SPACE = Draw.Create(1) # Only for hole filling.
- USER_STRETCH_ASPECT = Draw.Create(1) # Only for hole filling.
- USER_ISLAND_MARGIN = Draw.Create(0.0) # Only for hole filling.
- USER_FILL_HOLES = Draw.Create(0)
- USER_FILL_HOLES_QUALITY = Draw.Create(50) # Only for hole filling.
- USER_VIEW_INIT = Draw.Create(0) # Only for hole filling.
- USER_AREA_WEIGHT = Draw.Create(1) # Only for hole filling.
-
-
- pup_block = [\
- 'Projection',\
- ('Angle Limit:', USER_PROJECTION_LIMIT, 1, 89, 'lower for more projection groups, higher for less distortion.'),\
- ('Selected Faces Only', USER_ONLY_SELECTED_FACES, 'Use only selected faces from all selected meshes.'),\
- ('Init from view', USER_VIEW_INIT, 'The first projection will be from the view vector.'),\
- ('Area Weight', USER_AREA_WEIGHT, 'Weight projections vector by face area.'),\
- '',\
- '',\
- '',\
- 'UV Layout',\
- ('Share Tex Space', USER_SHARE_SPACE, 'Objects Share texture space, map all objects into 1 uvmap.'),\
- ('Stretch to bounds', USER_STRETCH_ASPECT, 'Stretch the final output to texture bounds.'),\
- ('Island Margin:', USER_ISLAND_MARGIN, 0.0, 0.5, 'Margin to reduce bleed from adjacent islands.'),\
- 'Fill in empty areas',\
- ('Fill Holes', USER_FILL_HOLES, 'Fill in empty areas reduced texture waistage (slow).'),\
- ('Fill Quality:', USER_FILL_HOLES_QUALITY, 1, 100, 'Depends on fill holes, how tightly to fill UV holes, (higher is slower)'),\
- ]
-
- # Reuse variable
- if len(obList) == 1:
- ob = "Unwrap %i Selected Mesh"
- else:
- ob = "Unwrap %i Selected Meshes"
-
- # HACK, loop until mouse is lifted.
- '''
- while Window.GetMouseButtons() != 0:
- sys.sleep(10)
- '''
-
- if not Draw.PupBlock(ob % len(obList), pup_block):
- return
- del ob
-
- # Convert from being button types
- USER_PROJECTION_LIMIT = USER_PROJECTION_LIMIT.val
- USER_ONLY_SELECTED_FACES = USER_ONLY_SELECTED_FACES.val
- USER_SHARE_SPACE = USER_SHARE_SPACE.val
- USER_STRETCH_ASPECT = USER_STRETCH_ASPECT.val
- USER_ISLAND_MARGIN = USER_ISLAND_MARGIN.val
- USER_FILL_HOLES = USER_FILL_HOLES.val
- USER_FILL_HOLES_QUALITY = USER_FILL_HOLES_QUALITY.val
- USER_VIEW_INIT = USER_VIEW_INIT.val
- USER_AREA_WEIGHT = USER_AREA_WEIGHT.val
-
- USER_PROJECTION_LIMIT_CONVERTED = cos(USER_PROJECTION_LIMIT * DEG_TO_RAD)
- USER_PROJECTION_LIMIT_HALF_CONVERTED = cos((USER_PROJECTION_LIMIT/2) * DEG_TO_RAD)
-
-
- # Toggle Edit mode
- is_editmode = Window.EditMode()
- if is_editmode:
- Window.EditMode(0)
- # Assume face select mode! an annoying hack to toggle face select mode because Mesh dosent like faceSelectMode.
-
- if USER_SHARE_SPACE:
- # Sort by data name so we get consistant results
- try: obList.sort(key = lambda ob: ob.getData(name_only=1))
- except: obList.sort(lambda ob1, ob2: cmp( ob1.getData(name_only=1), ob2.getData(name_only=1) ))
-
- collected_islandList= []
-
- Window.WaitCursor(1)
-
- time1 = sys.time()
-
- # Tag as False se we dont operate on teh same mesh twice.
- bpy.data.meshes.tag = False
-
- for ob in obList:
- me = ob.getData(mesh=1)
-
- if me.tag or me.lib:
- continue
-
- # Tag as used
- me.tag = True
-
- if not me.faceUV: # Mesh has no UV Coords, dont bother.
- me.faceUV= True
-
- if USER_ONLY_SELECTED_FACES:
- meshFaces = [thickface(f) for f in me.faces if f.sel]
- else:
- meshFaces = map(thickface, me.faces)
-
- if not meshFaces:
- continue
-
- Window.DrawProgressBar(0.1, 'SmartProj UV Unwrapper, mapping "%s", %i faces.' % (me.name, len(meshFaces)))
-
- # =======
- # Generate a projection list from face normals, this is ment to be smart :)
-
- # make a list of face props that are in sync with meshFaces
- # Make a Face List that is sorted by area.
- # meshFaces = []
-
- # meshFaces.sort( lambda a, b: cmp(b.area , a.area) ) # Biggest first.
- try: meshFaces.sort( key = lambda a: -a.area )
- except: meshFaces.sort( lambda a, b: cmp(b.area , a.area) )
-
- # remove all zero area faces
- while meshFaces and meshFaces[-1].area <= SMALL_NUM:
- # Set their UV's to 0,0
- for uv in meshFaces[-1].uv:
- uv.zero()
- meshFaces.pop()
-
- # Smallest first is slightly more efficient, but if the user cancels early then its better we work on the larger data.
-
- # Generate Projection Vecs
- # 0d is 1.0
- # 180 IS -0.59846
-
-
- # Initialize projectVecs
- if USER_VIEW_INIT:
- # Generate Projection
- projectVecs = [Vector(Window.GetViewVector()) * ob.matrixWorld.copy().invert().rotationPart()] # We add to this allong the way
- else:
- projectVecs = []
-
- newProjectVec = meshFaces[0].no
- newProjectMeshFaces = [] # Popping stuffs it up.
-
-
- # Predent that the most unique angke is ages away to start the loop off
- mostUniqueAngle = -1.0
-
- # This is popped
- tempMeshFaces = meshFaces[:]
-
-
-
- # This while only gathers projection vecs, faces are assigned later on.
- while 1:
- # If theres none there then start with the largest face
-
- # add all the faces that are close.
- for fIdx in xrange(len(tempMeshFaces)-1, -1, -1):
- # Use half the angle limit so we dont overweight faces towards this
- # normal and hog all the faces.
- if newProjectVec.dot(tempMeshFaces[fIdx].no) > USER_PROJECTION_LIMIT_HALF_CONVERTED:
- newProjectMeshFaces.append(tempMeshFaces.pop(fIdx))
-
- # Add the average of all these faces normals as a projectionVec
- averageVec = Vector(0,0,0)
- if USER_AREA_WEIGHT:
- for fprop in newProjectMeshFaces:
- averageVec += (fprop.no * fprop.area)
- else:
- for fprop in newProjectMeshFaces:
- averageVec += fprop.no
-
- if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0: # Avoid NAN
- projectVecs.append(averageVec.normalize())
-
-
- # Get the next vec!
- # Pick the face thats most different to all existing angles :)
- mostUniqueAngle = 1.0 # 1.0 is 0d. no difference.
- mostUniqueIndex = 0 # dummy
-
- for fIdx in xrange(len(tempMeshFaces)-1, -1, -1):
- angleDifference = -1.0 # 180d difference.
-
- # Get the closest vec angle we are to.
- for p in projectVecs:
- temp_angle_diff= p.dot(tempMeshFaces[fIdx].no)
-
- if angleDifference < temp_angle_diff:
- angleDifference= temp_angle_diff
-
- if angleDifference < mostUniqueAngle:
- # We have a new most different angle
- mostUniqueIndex = fIdx
- mostUniqueAngle = angleDifference
-
- if mostUniqueAngle < USER_PROJECTION_LIMIT_CONVERTED:
- #print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces)
- # Now weight the vector to all its faces, will give a more direct projection
- # if the face its self was not representive of the normal from surrounding faces.
-
- newProjectVec = tempMeshFaces[mostUniqueIndex].no
- newProjectMeshFaces = [tempMeshFaces.pop(mostUniqueIndex)]
-
-
- else:
- if len(projectVecs) >= 1: # Must have at least 2 projections
- break
-
-
- # If there are only zero area faces then its possible
- # there are no projectionVecs
- if not len(projectVecs):
- Draw.PupMenu('error, no projection vecs where generated, 0 area faces can cause this.')
- return
-
- faceProjectionGroupList =[[] for i in xrange(len(projectVecs)) ]
-
- # MAP and Arrange # We know there are 3 or 4 faces here
-
- for fIdx in xrange(len(meshFaces)-1, -1, -1):
- fvec = meshFaces[fIdx].no
- i = len(projectVecs)
-
- # Initialize first
- bestAng = fvec.dot(projectVecs[0])
- bestAngIdx = 0
-
- # Cycle through the remaining, first alredy done
- while i-1:
- i-=1
-
- newAng = fvec.dot(projectVecs[i])
- if newAng > bestAng: # Reverse logic for dotvecs
- bestAng = newAng
- bestAngIdx = i
-
- # Store the area for later use.
- faceProjectionGroupList[bestAngIdx].append(meshFaces[fIdx])
-
- # Cull faceProjectionGroupList,
-
-
- # Now faceProjectionGroupList is full of faces that face match the project Vecs list
- for i in xrange(len(projectVecs)):
- # Account for projectVecs having no faces.
- if not faceProjectionGroupList[i]:
- continue
-
- # Make a projection matrix from a unit length vector.
- MatProj = VectoMat(projectVecs[i])
-
- # Get the faces UV's from the projected vertex.
- for f in faceProjectionGroupList[i]:
- f_uv = f.uv
- for j, v in enumerate(f.v):
- f_uv[j][:] = (MatProj * v.co)[:2]
-
-
- if USER_SHARE_SPACE:
- # Should we collect and pack later?
- islandList = getUvIslands(faceProjectionGroupList, me)
- collected_islandList.extend(islandList)
-
- else:
- # Should we pack the islands for this 1 object?
- islandList = getUvIslands(faceProjectionGroupList, me)
- packIslands(islandList)
-
-
- # update the mesh here if we need to.
-
- # We want to pack all in 1 go, so pack now
- if USER_SHARE_SPACE:
- Window.DrawProgressBar(0.9, "Box Packing for all objects...")
- packIslands(collected_islandList)
-
- print "Smart Projection time: %.2f" % (sys.time() - time1)
- # Window.DrawProgressBar(0.9, "Smart Projections done, time: %.2f sec." % (sys.time() - time1))
-
- if is_editmode:
- Window.EditMode(1)
-
- Window.DrawProgressBar(1.0, "")
- Window.WaitCursor(0)
- Window.RedrawAll()
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/uvcopy.py b/release/scripts/uvcopy.py
deleted file mode 100644
index 73206e47109..00000000000
--- a/release/scripts/uvcopy.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!BPY
-""" Registration info for Blender menus: <- these words are ignored
-Name: 'UV Copy from Active'
-Blender: 242
-Group: 'Object'
-Tip: 'Copy UV coords from a mesh to another that has same vertex indices'
-"""
-
-__author__ = "Toni Alatalo, Martin Poirier et. al."
-__url__ = ("blender", "blenderartists.org")
-__version__ = "0.2 01/2006"
-
-__bpydoc__ = """\
-This script copies UV coords from a mesh to another (version of the same mesh).
-All target meshes must have the same number of faces at the active
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import Blender
-
-def face_key(me):
- '''
- Returns the face lengths for this mesh
- only copy between meshes that have matching face_key's
- '''
- return tuple([len(f) for f in me.faces])
-
-def main():
- scene = Blender.Scene.GetCurrent()
-
- source_ob = scene.objects.active
-
- if not source_ob or source_ob.type != 'Mesh':
- Blender.Draw.PupMenu("Error%t|No active object to copy UVs from.")
- return
-
- source_me = source_ob.getData(mesh=1)
-
- target_mes = [ ob.getData(mesh=1) for ob in scene.objects.context if ob != source_ob if ob.type == 'Mesh']
-
- # remove double meshes
- target_mes = dict([(me.name, me) for me in target_mes])
- target_mes = target_mes.values()
-
- if not target_mes:
- Blender.Draw.PupMenu("Error%t|No selected object(s) to copy UVs to.")
- return
-
- source_me = source_ob.getData(mesh=1)
-
- if not source_me.faceUV:
- Blender.Draw.PupMenu("Error%t|Active mesh has no UVs.")
- return
-
- if not target_mes:
- Blender.Draw.PupMenu("Error%t|no selected object other than the source, hence no target defined.")
- return
- error = False
-
- source_face_key = face_key(source_me)
- source_faces = source_me.faces
-
- fail_count = 0
-
- for target in target_mes:
- if len(source_me.faces) != len(target.faces):
- print '\ttarget "%s" facelen does not match "%s".' % (target.name, source_me.name)
- error = True
- fail_count +=1
- else:
- # slow but worth comparing
- if source_face_key != face_key(target):
- print '\t\terror, face len dosnt match for ob "%s" next mesh...' % target.name
- error = True
- fail_count +=1
- else:
- target_faces = target.faces
-
- # Add uvs if there not there
- target.faceUV = True
-
- for i, f_source in enumerate(source_faces):
- target_faces[i].uv = f_source.uv
-
- target.update()
-
- msg = 'Copied UVs to %d of %d mesh(s)' % (len(target_mes)-fail_count, len(target_mes))
-
- if error:
- msg += "|Could not copy some UV's, see console."
-
- Blender.Draw.PupMenu('UV Copy Finished%t|' + msg)
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/vertexpaint_from_material.py b/release/scripts/vertexpaint_from_material.py
deleted file mode 100644
index 9668c521f3a..00000000000
--- a/release/scripts/vertexpaint_from_material.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!BPY
-"""
-Name: 'Copy from Material...'
-Blender: 242
-Group: 'VertexPaint'
-Tooltip: 'Writes material diffuse color as vertex colors.'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ("www.blender.org", "blenderartists.org")
-__version__ = "1.0"
-
-__bpydoc__ = """\
-This script copies material colors to vertex colors.
-Optionaly you can operate on all faces and many objects as well as multiplying with the current color.
-"""
-
-
-from Blender import *
-
-def matcol(mat):
- '''
- Returns the material color as a tuple 3 from 0 to 255
- '''
- if mat:
- return \
- int(mat.R*255),\
- int(mat.G*255),\
- int(mat.B*255)
- else:
- return None
-
-def mat2vcol(PREF_SEL_FACES_ONLY, PREF_ACTOB_ONLY, PREF_MULTIPLY_COLOR):
- scn= Scene.GetCurrent()
- if PREF_ACTOB_ONLY:
- obs= [scn.getActiveObject()]
- else:
- obs= Object.GetSelected()
- ob= scn.getActiveObject()
- if ob not in obs:
- obs.append(ob)
-
-
- for ob in obs:
- if ob.type != 'Mesh':
- continue
-
- me= ob.getData(mesh=1)
-
- try:
- me.vertexColors=True
- except: # no faces
- continue
-
- matcols= [matcol(mat) for mat in me.materials]
- len_matcols= len(matcols)
-
- for f in me.faces:
- if not PREF_SEL_FACES_ONLY or f.sel:
- f_mat= f.mat
- if f_mat < len_matcols:
- mat= matcols[f.mat]
- if mat:
- if PREF_MULTIPLY_COLOR:
- for c in f.col:
- c.r= int(((c.r/255.0) * (mat[0]/255.0)) * 255.0)
- c.g= int(((c.g/255.0) * (mat[1]/255.0)) * 255.0)
- c.b= int(((c.b/255.0) * (mat[2]/255.0)) * 255.0)
- else:
- for c in f.col:
- c.r=mat[0]
- c.g=mat[1]
- c.b=mat[2]
- me.update()
-
-def main():
- # Create the variables.
-
- PREF_SEL_FACES_ONLY= Draw.Create(1)
- PREF_ACTOB_ONLY= Draw.Create(1)
- PREF_MULTIPLY_COLOR = Draw.Create(0)
-
- pup_block = [\
- ('Sel Faces Only', PREF_SEL_FACES_ONLY, 'Only apply to selected faces.'),\
- ('Active Only', PREF_ACTOB_ONLY, 'Operate on all selected objects.'),\
- ('Multiply Existing', PREF_MULTIPLY_COLOR, 'Multiplies material color with existing.'),\
- ]
-
- if not Draw.PupBlock('VCols from Material', pup_block):
- return
-
- PREF_SEL_FACES_ONLY= PREF_SEL_FACES_ONLY.val
- PREF_ACTOB_ONLY= PREF_ACTOB_ONLY.val
- PREF_MULTIPLY_COLOR= PREF_MULTIPLY_COLOR.val
-
- mat2vcol(PREF_SEL_FACES_ONLY, PREF_ACTOB_ONLY, PREF_MULTIPLY_COLOR)
-
-if __name__=='__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/vertexpaint_selfshadow_ao.py b/release/scripts/vertexpaint_selfshadow_ao.py
deleted file mode 100644
index 3554e016f79..00000000000
--- a/release/scripts/vertexpaint_selfshadow_ao.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#!BPY
-"""
-Name: 'Self Shadow VCols (AO)...'
-Blender: 245
-Group: 'VertexPaint'
-Tooltip: 'Generate Fake Ambient Occlusion with vertex colors.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Self Shadow
-
-This usript uses the angles between faces to shade the mesh,
-and optionaly blur the shading to remove artifacts from spesific edges.
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Draw, sys, Window, Mathutils, Mesh
-import bpy
-import BPyMesh
-
-
-def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_STRENGTH, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY):
- Window.WaitCursor(1)
- Ang= Mathutils.AngleBetweenVecs
-
- BPyMesh.meshCalcNormals(me)
-
- vert_tone= [0.0] * len(me.verts)
- vert_tone_count= [0] * len(me.verts)
-
- min_tone=0
- max_tone=0
-
- for i, f in enumerate(me.faces):
- fc= f.cent
- fno = f.no
-
- for v in f.v:
- vno=v.no # get a scaled down normal.
-
- dot= vno.dot(v.co) - vno.dot(fc)
- vert_tone_count[v.index]+=1
- try:
- a= Ang(vno, fno)
- except:
- continue
-
- # Convex
- if dot>0:
- a= min(PREF_CLAMP_CONVEX, a)
- if not PREF_SHADOW_ONLY:
- vert_tone[v.index] += a
- else:
- a= min(PREF_CLAMP_CONCAVE, a)
- vert_tone[v.index] -= a
-
- # average vert_tone_list into vert_tonef
- for i, tones in enumerate(vert_tone):
- if vert_tone_count[i]:
- vert_tone[i] = vert_tone[i] / vert_tone_count[i]
-
-
- # Below we use edges to blur along so the edges need counting, not the faces
- vert_tone_count= [0] * len(me.verts)
- for ed in me.edges:
- vert_tone_count[ed.v1.index] += 1
- vert_tone_count[ed.v2.index] += 1
-
-
- # Blur tone
- blur = PREF_BLUR_STRENGTH
- blur_inv = 1.0 - PREF_BLUR_STRENGTH
-
- for i in xrange(PREF_BLUR_ITERATIONS):
-
- # backup the original tones
- orig_vert_tone= list(vert_tone)
-
- for ed in me.edges:
-
- i1= ed.v1.index
- i2= ed.v2.index
-
- val1= (orig_vert_tone[i2]*blur) + (orig_vert_tone[i1]*blur_inv)
- val2= (orig_vert_tone[i1]*blur) + (orig_vert_tone[i2]*blur_inv)
-
- # Apply the ton divided by the number of faces connected
- vert_tone[i1]+= val1 / max(vert_tone_count[i1], 1)
- vert_tone[i2]+= val2 / max(vert_tone_count[i2], 1)
-
-
- min_tone= min(vert_tone)
- max_tone= max(vert_tone)
-
- #print min_tone, max_tone
-
- tone_range= max_tone-min_tone
- if max_tone==min_tone:
- return
-
- for f in me.faces:
- if not PREF_SEL_ONLY or f.sel:
- f_col= f.col
- for i, v in enumerate(f):
- col= f_col[i]
- tone= vert_tone[v.index]
- tone= (tone-min_tone)/tone_range
-
- col.r= int(tone*col.r)
- col.g= int(tone*col.g)
- col.b= int(tone*col.b)
-
- Window.WaitCursor(0)
-
-def main():
- sce= bpy.data.scenes.active
- ob= sce.objects.active
-
- if not ob or ob.type != 'Mesh':
- Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- me= ob.getData(mesh=1)
-
- PREF_BLUR_ITERATIONS= Draw.Create(1)
- PREF_BLUR_STRENGTH= Draw.Create(0.5)
- PREF_CLAMP_CONCAVE= Draw.Create(90)
- PREF_CLAMP_CONVEX= Draw.Create(20)
- PREF_SHADOW_ONLY= Draw.Create(0)
- PREF_SEL_ONLY= Draw.Create(0)
- pup_block= [\
- 'Post AO Blur',\
- ('Strength:', PREF_BLUR_STRENGTH, 0, 1, 'Blur strength per iteration'),\
- ('Iterations:', PREF_BLUR_ITERATIONS, 0, 40, 'Number times to blur the colors. (higher blurs more)'),\
- 'Angle Clipping',\
- ('Highlight Angle:', PREF_CLAMP_CONVEX, 0, 180, 'Less then 180 limits the angle used in the tonal range.'),\
- ('Shadow Angle:', PREF_CLAMP_CONCAVE, 0, 180, 'Less then 180 limits the angle used in the tonal range.'),\
- ('Shadow Only', PREF_SHADOW_ONLY, 'Dont calculate highlights for convex areas.'),\
- ('Sel Faces Only', PREF_SEL_ONLY, 'Only apply to UV/Face selected faces (mix vpain/uvface select).'),\
- ]
-
- if not Draw.PupBlock('SelfShadow...', pup_block):
- return
-
- if not me.vertexColors:
- me.vertexColors= 1
-
- t= sys.time()
- vertexFakeAO(me, PREF_BLUR_ITERATIONS.val, \
- PREF_BLUR_STRENGTH.val, \
- PREF_CLAMP_CONCAVE.val, \
- PREF_CLAMP_CONVEX.val, \
- PREF_SHADOW_ONLY.val, \
- PREF_SEL_ONLY.val)
-
- if ob.modifiers:
- me.update()
-
- print 'done in %.6f' % (sys.time()-t)
-if __name__=='__main__':
- main()
-
diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py
deleted file mode 100644
index bd1a35f7c3b..00000000000
--- a/release/scripts/vrml97_export.py
+++ /dev/null
@@ -1,1300 +0,0 @@
-#!BPY
-""" Registration info for Blender menus:
-Name: 'VRML97 (.wrl)...'
-Blender: 241
-Group: 'Export'
-Tooltip: 'Export to VRML97 file (.wrl)'
-"""
-
-__author__ = ("Rick Kimball", "Ken Miller", "Steve Matthews", "Bart")
-__url__ = ["blender", "blenderartists.org",
-"Author's (Rick) homepage, http://kimballsoftware.com/blender",
-"Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
-__email__ = ["Bart, bart:neeneenee*de"]
-__version__ = "2006/01/17"
-__bpydoc__ = """\
-This script exports to VRML97 format.
-
-Usage:
-
-Run this script from "File->Export" menu. A pop-up will ask whether you
-want to export only selected or all relevant objects.
-"""
-
-
-# $Id$
-#
-#------------------------------------------------------------------------
-# VRML97 exporter for blender 2.36 or above
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-#
-
-####################################
-# Library dependancies
-####################################
-
-import Blender
-from Blender import Object, Mesh, Lamp, Draw, BGL, \
- Image, Text, sys, Mathutils, Registry
-from Blender.Scene import Render
-
-import math
-
-####################################
-# Global Variables
-####################################
-
-scene = Blender.Scene.getCurrent()
-world = Blender.World.GetCurrent()
-worldmat = Blender.Texture.Get()
-filename = Blender.Get('filename')
-_safeOverwrite = True
-extension = ''
-
-# Matrices below are used only when export_rotate_z_to_y.val:
-#
-# Blender is Z up, VRML is Y up, both are right hand coordinate
-# systems, so to go from Blender coords to VRML coords we rotate
-# by 90 degrees around the X axis. In matrix notation, we have a
-# matrix, and it's inverse, as:
-M_blen2vrml = Mathutils.Matrix([1,0,0,0], \
- [0,0,1,0], \
- [0,-1,0,0], \
- [0,0,0,1])
-M_vrml2blen = Mathutils.Matrix([1,0,0,0], \
- [0,0,-1,0], \
- [0,1,0,0], \
- [0,0,0,1])
-
-
-class DrawTypes:
- """Object DrawTypes enum values
- BOUNDS - draw only the bounding box of the object
- WIRE - draw object as a wire frame
- SOLID - draw object with flat shading
- SHADED - draw object with OpenGL shading
-"""
- BOUNDBOX = 1
- WIRE = 2
- SOLID = 3
- SHADED = 4
- TEXTURE = 5
-
-if not hasattr(Blender.Object,'DrawTypes'):
- Blender.Object.DrawTypes = DrawTypes()
-
-##########################################################
-# Functions for writing output file
-##########################################################
-
-class VRML2Export:
-
- def __init__(self, filename):
- #--- public you can change these ---
- self.wire = 0
- self.proto = 1
- self.facecolors = 0
- self.vcolors = 0
- self.billnode = 0
- self.halonode = 0
- self.collnode = 0
- self.tilenode = 0
- self.wire = 0
- self.twosided = 0
-
- # level of verbosity in console 0-none, 1-some, 2-most
- try:
- rt = Blender.Get('rt')
- if (rt == 42):
- self.verbose = 1
- elif (rt == 43):
- self.verbose = 2
- else:
- self.verbose = 0
- except:
- self.verbose = 0
-
- # decimals for material color values 0.000 - 1.000
- self.cp=7
- # decimals for vertex coordinate values 0.000 - n.000
- self.vp=7
- # decimals for texture coordinate values 0.000 - 1.000
- self.tp=7
-
- #--- class private don't touch ---
- self.texNames={} # dictionary of textureNames
- self.matNames={} # dictionary of materialNames
- self.meshNames={} # dictionary of meshNames
- self.coordNames={} # dictionary of coordNames
- self.indentLevel=0 # keeps track of current indenting
- self.filename=filename
- self.file = open(filename, "w")
- self.bNav=0
- self.nodeID=0
- self.namesReserved=[ "Anchor", "Appearance", "AudioClip",
- "Background","Billboard", "Box",
- "Collision", "Color", "ColorInterpolator",
- "Cone", "Coordinate",
- "CoordinateInterpolator", "Cylinder",
- "CylinderSensor",
- "DirectionalLight",
- "ElevationGrid", "Extrustion",
- "Fog", "FontStyle", "Group",
- "ImageTexture", "IndexedFaceSet",
- "IndexedLineSet", "Inline",
- "LOD", "Material", "MovieTexture",
- "NavigationInfo", "Normal",
- "NormalInterpolator",
- "OrientationInterpolator", "PixelTexture",
- "PlaneSensor", "PointLight", "PointSet",
- "PositionInterpolator", "ProxmimitySensor",
- "ScalarInterpolator", "Script", "Shape",
- "Sound", "Sphere", "SphereSensor",
- "SpotLight", "Switch", "Text",
- "TextureCoordinate", "TextureTransform",
- "TimeSensor", "TouchSensor", "Transform",
- "Viewpoint", "VisibilitySensor", "WorldInfo" ]
- self.namesStandard=[ "Empty", "Empty.000", "Empty.001",
- "Empty.002", "Empty.003", "Empty.004",
- "Empty.005", "Empty.006", "Empty.007",
- "Empty.008", "Empty.009", "Empty.010",
- "Empty.011", "Empty.012",
- "Scene.001", "Scene.002", "Scene.003",
- "Scene.004", "Scene.005", "Scene.06",
- "Scene.013", "Scene.006", "Scene.007",
- "Scene.008", "Scene.009", "Scene.010",
- "Scene.011","Scene.012",
- "World", "World.000", "World.001",
- "World.002", "World.003", "World.004",
- "World.005" ]
- self.namesFog=[ "", "LINEAR"," EXPONENTIAL", "" ]
-
-##########################################################
-# Writing nodes routines
-##########################################################
-
- def writeHeader(self):
- bfile = sys.expandpath(Blender.Get('filename'))
- self.file.write("#VRML V2.0 utf8\n\n")
- self.file.write("# This file was authored with Blender " \
- "(http://www.blender.org/)\n")
- self.file.write("# Blender version %s\n" % Blender.Get('version'))
- self.file.write("# Blender file %s\n" % sys.basename(bfile))
- self.file.write("# Exported using VRML97 exporter " \
- "v1.55 (2006/01/17)\n\n")
-
- def writeInline(self):
- inlines = Blender.Scene.Get()
- allinlines = len(inlines)
- if scene != inlines[0]:
- return
- else:
- for i in xrange(allinlines):
- nameinline=inlines[i].getName()
- if (nameinline not in self.namesStandard) and (i > 0):
- self.writeIndented("DEF %s Inline {\n" % \
- (self.cleanStr(nameinline)), 1)
- nameinline = nameinline+".wrl"
- self.writeIndented("url \"%s\" \n" % nameinline)
- self.writeIndented("}\n", -1)
- self.writeIndented("\n")
-
- def writeScript(self):
- textEditor = Blender.Text.Get()
- alltext = len(textEditor)
- for i in xrange(alltext):
- nametext = textEditor[i].getName()
- nlines = textEditor[i].getNLines()
- if (self.proto == 1):
- if (nametext == "proto" or nametext == "proto.js" or \
- nametext == "proto.txt") and (nlines != None):
- nalllines = len(textEditor[i].asLines())
- alllines = textEditor[i].asLines()
- for j in xrange(nalllines):
- self.writeIndented(alllines[j] + "\n")
- elif (self.proto == 0):
- if (nametext == "route" or nametext == "route.js" or \
- nametext == "route.txt") and (nlines != None):
- nalllines = len(textEditor[i].asLines())
- alllines = textEditor[i].asLines()
- for j in xrange(nalllines):
- self.writeIndented(alllines[j] + "\n")
- self.writeIndented("\n")
-
- def writeViewpoint(self, thisObj):
- # NOTE: The transform node above this will take care of
- # the position and orientation of the camera
- context = scene.getRenderingContext()
- ratio = float(context.imageSizeY()) / float(context.imageSizeX())
- temp = ratio * 16 / thisObj.data.getLens()
- lens = 2 * math.atan(temp)
- lens = min(lens, math.pi)
-
- self.writeIndented("DEF %s Viewpoint {\n" % \
- (self.cleanStr(thisObj.name)), 1)
- self.writeIndented('description "%s" \n' % thisObj.name)
- self.writeIndented("position 0.0 0.0 0.0\n")
- # Need camera to point to -y in local space to accomodate
- # the transforma node above
- self.writeIndented("orientation 1.0 0.0 0.0 %f\n" % (-math.pi/2.0))
- self.writeIndented("fieldOfView %.3f\n" % (lens))
- self.writeIndented("}\n", -1)
- self.writeIndented("\n")
-
- def writeFog(self):
- if world:
- mtype = world.getMistype()
- mparam = world.getMist()
- grd = world.getHor()
- grd0, grd1, grd2 = grd[0], grd[1], grd[2]
- else:
- return
- if (mtype == 1 or mtype == 2):
- self.writeIndented("Fog {\n",1)
- self.writeIndented('fogType "%s"\n' % self.namesFog[mtype])
- self.writeIndented("color %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("visibilityRange %s\n" % \
- round(mparam[2],self.cp))
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
- else:
- return
-
- def writeNavigationInfo(self, scene):
- allObj = []
- allObj = list(scene.objects)
- headlight = "TRUE"
- vislimit = 0.0
- for thisObj in allObj:
- objType=thisObj.type
- if objType == "Camera":
- vislimit = thisObj.data.getClipEnd()
- elif objType == "Lamp":
- headlight = "FALSE"
- self.writeIndented("NavigationInfo {\n",1)
- self.writeIndented("headlight %s\n" % headlight)
- self.writeIndented("visibilityLimit %s\n" % \
- (round(vislimit,self.cp)))
- self.writeIndented("type [\"EXAMINE\", \"ANY\"]\n")
- self.writeIndented("avatarSize [0.25, 1.75, 0.75]\n")
- self.writeIndented("} \n",-1)
- self.writeIndented(" \n")
-
- def writeSpotLight(self, object, lamp):
- # Note: location and orientation are handled by the
- # transform node above this object
- if world:
- ambi = world.getAmb()
- ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
- else:
- ambi = 0
- ambientIntensity = 0
-
- # compute cutoff and beamwidth
- intensity=min(lamp.energy/1.75,1.0)
- beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
- cutOffAngle=beamWidth*1.3
-
- radius = lamp.dist*math.cos(beamWidth)
- self.writeIndented("DEF %s SpotLight {\n" % \
- self.cleanStr(object.name),1)
- self.writeIndented("radius %s\n" % (round(radius,self.cp)))
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambientIntensity,self.cp)))
- self.writeIndented("intensity %s\n" % (round(intensity,self.cp)))
- self.writeIndented("color %s %s %s\n" % \
- (round(lamp.col[0],self.cp), \
- round(lamp.col[1],self.cp), \
- round(lamp.col[2],self.cp)))
- self.writeIndented("beamWidth %s\n" % (round(beamWidth,self.cp)))
- self.writeIndented("cutOffAngle %s\n" % \
- (round(cutOffAngle,self.cp)))
- # Note: point down -Y axis, transform node above will rotate
- self.writeIndented("direction 0.0 -1.0 0.0\n")
- self.writeIndented("location 0.0 0.0 0.0\n")
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def writeDirectionalLight(self, object, lamp):
- # Note: location and orientation are handled by the
- # transform node above this object
- if world:
- ambi = world.getAmb()
- ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
- else:
- ambi = 0
- ambientIntensity = 0
-
- intensity=min(lamp.energy/1.75,1.0)
- self.writeIndented("DEF %s DirectionalLight {\n" % \
- self.cleanStr(object.name),1)
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambientIntensity,self.cp)))
- self.writeIndented("color %s %s %s\n" % \
- (round(lamp.col[0],self.cp), \
- round(lamp.col[1],self.cp), \
- round(lamp.col[2],self.cp)))
- self.writeIndented("intensity %s\n" % \
- (round(intensity,self.cp)))
- # Note: point down -Y axis, transform node above will rotate
- self.writeIndented("direction 0.0 -1.0 0.0\n")
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def writePointLight(self, object, lamp):
- # Note: location is at origin because parent transform node
- # takes care of this
- if world:
- ambi = world.getAmb()
- ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
- else:
- ambi = 0
- ambientIntensity = 0
- om = object.getMatrix()
- intensity=min(lamp.energy/1.75,1.0)
- radius = lamp.dist
- self.writeIndented("DEF %s PointLight {\n" % \
- self.cleanStr(object.name),1)
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambientIntensity,self.cp)))
- self.writeIndented("color %s %s %s\n" % \
- (round(lamp.col[0],self.cp), \
- round(lamp.col[1],self.cp), \
- round(lamp.col[2],self.cp)))
- self.writeIndented("intensity %s\n" % (round(intensity,self.cp)))
- self.writeIndented("location 0.0 0.0 0.0\n")
- self.writeIndented("radius %s\n" % radius )
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def writeNode(self, thisObj):
- # Note: location and orientation are handled by the
- # transform node above this object
- objectname=str(thisObj.getName())
- if objectname in self.namesStandard:
- return
- else:
- self.writeIndented("%s {\n" % objectname,1)
- # May need to check that the direction is done right
- self.writeIndented("direction 0.0 -1.0 0.0\n")
- self.writeIndented("location 0.0 0.0 0.0\n")
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def secureName(self, name):
- name = name + str(self.nodeID)
- self.nodeID += 1
- if len(name) <= 3:
- newname = "_" + str(self.nodeID)
- return "%s" % (newname)
- else:
- for bad in ['"','#',"'",',','.','[','\\',']','{','}']:
- name=name.replace(bad,'_')
- if name in self.namesReserved:
- newname = name[0:3] + "_" + str(self.nodeID)
- return "%s" % (newname)
- elif name[0].isdigit():
- newname = "_" + name + str(self.nodeID)
- return "%s" % (newname)
- else:
- newname = name
- return "%s" % (newname)
-
- def classifyMesh(self, me, ob):
- self.halonode = 0
- self.billnode = 0
- self.facecolors = 0
- self.vcolors = 0
- self.tilenode = 0
- self.colnode = 0
- self.wire = 0
- if me.faceUV:
- for face in me.faces:
- if (face.mode & Mesh.FaceModes['HALO']):
- self.halonode = 1
- if (face.mode & Mesh.FaceModes['BILLBOARD']):
- self.billnode = 1
- if (face.mode & Mesh.FaceModes['OBCOL']):
- self.facecolors = 1
- if (face.mode & Mesh.FaceModes['SHAREDCOL']):
- self.vcolors = 1
- if (face.mode & Mesh.FaceModes['TILES']):
- self.tilenode = 1
- if not (face.mode & Mesh.FaceModes['DYNAMIC']):
- self.collnode = 1
- if (face.mode & Mesh.FaceModes['TWOSIDE']):
- self.twosided = 1
-
- # Bit of a crufty trick, but if mesh has vertex colors
- # (as a non-face property) and if first material has
- # vcol paint set, we export the vertex colors
- if (me.vertexColors):
- if len(me.materials) > 0:
- mat = me.materials[0]
- if mat:
- if (mat.mode & Blender.Material.Modes['VCOL_PAINT']):
- self.vcolors = 1
- else:
- self.vcolors = 0
-
- # check if object is wireframe only
- if ob.drawType == Blender.Object.DrawTypes.WIRE:
- # user selected WIRE=2 on the Drawtype=Wire on (F9) Edit page
- self.wire = 1
-
- ###
- ### The next few functions nest Collision/Billboard/Halo nodes.
- ### For real mesh data export, jump down to writeMeshData()
- ###
- def writeMesh(self, ob, normals = 0):
-
- imageMap={} # set of used images
- sided={} # 'one':cnt , 'two':cnt
- vColors={} # 'multi':1
-
- if (len(ob.modifiers) > 0):
- me = Mesh.New()
- me.getFromObject(ob.name)
- # Careful with the name, the temporary mesh may
- # reuse the default name for other meshes. So we
- # pick our own name.
- me.name = "MOD_%s" % (ob.name)
- else:
- me = ob.getData(mesh = 1)
-
- self.classifyMesh(me, ob)
-
- if (self.collnode):
- self.writeCollisionMesh(me, ob, normals)
- return
- else:
- self.writeRegularMesh(me, ob, normals)
- return
-
- def writeCollisionMesh(self, me, ob, normals = 0):
- self.writeIndented("Collision {\n",1)
- self.writeIndented("collide FALSE\n")
- self.writeIndented("children [\n")
-
- self.writeRegularMesh(me, ob, normals)
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- def writeRegularMesh(self, me, ob, normals = 0):
- if (self.billnode):
- self.writeBillboardMesh(me, ob, normals)
- elif (self.halonode):
- self.writeHaloMesh(me, ob, normals)
- else:
- self.writeMeshData(me, ob, normals)
-
- def writeBillboardMesh(self, me, ob, normals = 0):
- self.writeIndented("Billboard {\n",1)
- self.writeIndented("axisOfRotation 0 1 0\n")
- self.writeIndented("children [\n")
-
- self.writeMeshData(me, ob, normals)
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- def writeHaloMesh(self, me, ob, normals = 0):
- self.writeIndented("Billboard {\n",1)
- self.writeIndented("axisOfRotation 0 0 0\n")
- self.writeIndented("children [\n")
-
- self.writeMeshData(me, ob, normals)
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- ###
- ### Here is where real mesh data is written
- ###
- def writeMeshData(self, me, ob, normals = 0):
- meshName = self.cleanStr(me.name)
-
- if self.meshNames.has_key(meshName):
- self.writeIndented("USE ME_%s\n" % meshName, 0)
- self.meshNames[meshName]+=1
- if (self.verbose == 1):
- print " Using Mesh %s (Blender mesh: %s)\n" % \
- (meshName, me.name)
- return
- self.meshNames[meshName]=1
-
- if (self.verbose == 1):
- print " Writing Mesh %s (Blender mesh: %s)\n" % \
- (meshName, me.name)
- return
-
- self.writeIndented("DEF ME_%s Group {\n" % meshName,1)
- self.writeIndented("children [\n", 1)
-
- hasImageTexture = 0
- issmooth = 0
-
- maters = me.materials
- nummats = len(me.materials)
-
- # Vertex and Face colors trump materials and image textures
- if (self.facecolors or self.vcolors):
- if nummats > 0:
- self.writeShape(ob, me, 0, None)
- else:
- self.writeShape(ob, me, -1, None)
-
- # Do meshes with materials, possibly with image textures
- elif nummats > 0:
- for matnum in xrange(len(maters)):
- images = []
- if me.faceUV:
- images = self.getImages(me, matnum)
- if len(images) > 0:
- for image in images:
- self.writeShape(ob, me, matnum, image)
- else:
- self.writeShape(ob, me, matnum, None)
- else:
- self.writeShape(ob, me, matnum, None)
- else:
- if me.faceUV:
- images = self.getImages(me, -1)
- if len(images) > 0:
- for image in images:
- self.writeShape(ob, me, -1, image)
- else:
- self.writeShape(ob, me, -1, None)
- else:
- self.writeShape(ob, me, -1, None)
-
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- def getImages(self, me, matnum):
- imageNames = {}
- images = []
- for face in me.faces:
- if (matnum == -1) or (face.mat == matnum):
- if (face.image):
- imName = self.cleanStr(face.image.name)
- if not imageNames.has_key(imName):
- images.append(face.image)
- imageNames[imName]=1
- return images
-
- def writeCoordinates(self, me, meshName):
- coordName = "coord_%s" % (meshName)
- # look up coord name, use it if available
- if self.coordNames.has_key(coordName):
- self.writeIndented("coord USE %s\n" % coordName, 0)
- self.coordNames[coordName]+=1
- return;
-
- self.coordNames[coordName]=1
-
- #-- vertices
- self.writeIndented("coord DEF %s Coordinate {\n" % (coordName), 1)
- self.writeIndented("point [\n", 1)
- meshVertexList = me.verts
-
- for vertex in meshVertexList:
- vrmlvert = blenvert = Mathutils.Vector(vertex.co)
- if export_rotate_z_to_y.val:
- vrmlvert = M_blen2vrml * vrmlvert
- self.writeUnindented("%s %s %s\n " % \
- (vrmlvert[0], \
- vrmlvert[1], \
- vrmlvert[2]))
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
- self.writeIndented("\n")
-
- def testShape(self, ob, me, matnum, image):
- if ( (matnum == -1) and (image == None) ):
- if ( len(me.faces) > 0 ):
- return True
- # Check if any faces the material or image
- for face in me.faces:
- if (matnum == -1):
- if (face.image == image):
- return True
- elif (image == None):
- if (face.mat == matnum):
- return True
- else:
- if ((face.image == image) and (face.mat == matnum)):
- return True
-
- return False
-
- def writeShape(self, ob, me, matnum, image):
- # matnum == -1 means don't check the face.mat
- # image == None means don't check face.image
-
- if ( not self.testShape(ob, me, matnum, image) ):
- return False
-
- self.writeIndented("Shape {\n",1)
-
- self.writeIndented("appearance Appearance {\n", 1)
- if (matnum != -1):
- mater = me.materials[matnum]
- if (mater):
- self.writeMaterial(mater, self.cleanStr(mater.name,''))
- if (mater.mode & Blender.Material.Modes['TEXFACE']):
- if image != None:
- self.writeImageTexture(image.name, image.filename)
- else:
- self.writeDefaultMaterial()
- else:
- if image != None:
- self.writeImageTexture(image.name, image.filename)
-
- self.writeIndented("}\n", -1)
-
- self.writeGeometry(ob, me, matnum, image)
-
- self.writeIndented("}\n", -1)
-
- return True
-
- def writeGeometry(self, ob, me, matnum, image):
-
- #-- IndexedFaceSet or IndexedLineSet
- meshName = self.cleanStr(me.name)
-
- # check if object is wireframe only
- if (self.wire):
- ifStyle="IndexedLineSet"
- else:
- # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
- ifStyle="IndexedFaceSet"
-
- self.writeIndented("geometry %s {\n" % ifStyle, 1)
- if not self.wire:
- if self.twosided == 1:
- self.writeIndented("solid FALSE\n")
- else:
- self.writeIndented("solid TRUE\n")
-
- self.writeCoordinates(me, meshName)
- self.writeCoordIndex(me, meshName, matnum, image)
- self.writeTextureCoordinates(me, meshName, matnum, image)
- if self.facecolors:
- self.writeFaceColors(me)
- elif self.vcolors:
- self.writeVertexColors(me)
- self.writeIndented("}\n", -1)
-
- def writeCoordIndex(self, me, meshName, matnum, image):
- meshVertexList = me.verts
- self.writeIndented("coordIndex [\n", 1)
- coordIndexList=[]
- for face in me.faces:
- if (matnum == -1) or (face.mat == matnum):
- if (image == None) or (face.image == image):
- cordStr=""
- for v in face.verts:
- indx=v.index
- cordStr = cordStr + "%s " % indx
- self.writeUnindented(cordStr + "-1, \n")
- self.writeIndented("]\n", -1)
-
- def writeTextureCoordinates(self, me, meshName, matnum, image):
- if (image == None):
- return
-
- texCoordList=[]
- texIndexList=[]
- j=0
-
- for face in me.faces:
- coordStr = ""
- indexStr = ""
- if (matnum == -1) or (face.mat == matnum):
- if (face.image == image):
- for i in xrange(len(face.verts)):
- uv = face.uv[i]
- indexStr += "%s " % (j)
- coordStr += "%s %s, " % \
- (round(uv[0], self.tp), \
- round(uv[1], self.tp))
- j=j+1
- indexStr += "-1"
- texIndexList.append(indexStr)
- texCoordList.append(coordStr)
-
- self.writeIndented("texCoord TextureCoordinate {\n", 1)
- self.writeIndented("point [\n", 1)
- for coord in texCoordList:
- self.writeUnindented("%s\n" % (coord))
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- self.writeIndented("texCoordIndex [\n", 1)
- for ind in texIndexList:
- self.writeUnindented("%s\n" % (ind))
- self.writeIndented("]\n", -1)
-
- def writeFaceColors(self, me):
- self.writeIndented("colorPerVertex FALSE\n")
- self.writeIndented("color Color {\n",1)
- self.writeIndented("color [\n", 1)
-
- for face in me.faces:
- if face.col:
- c=face.col[0]
- if self.verbose >= 2:
- print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)
-
- aColor = self.rgbToFS(c)
- self.writeUnindented("%s,\n" % aColor)
- self.writeIndented("]\n",-1)
- self.writeIndented("}\n",-1)
-
- def writeVertexColors(self, me):
- self.writeIndented("colorPerVertex TRUE\n")
- self.writeIndented("color Color {\n",1)
- self.writeIndented("color [\n\t\t\t\t\t\t", 1)
-
- cols = [None] * len(me.verts)
-
- for face in me.faces:
- for vind in xrange(len(face.v)):
- vertex = face.v[vind]
- i = vertex.index
- if cols[i] == None:
- cols[i] = face.col[vind]
-
- for i in xrange(len(me.verts)):
- aColor = self.rgbToFS(cols[i])
- self.writeUnindented("%s\n" % aColor)
-
- self.writeIndented("\n", 0)
- self.writeIndented("]\n",-1)
- self.writeIndented("}\n",-1)
-
- def writeDefaultMaterial(self):
- matName = "default"
-
- # look up material name, use it if available
- if self.matNames.has_key(matName):
- self.writeIndented("material USE MA_%s\n" % matName)
- self.matNames[matName]+=1
- return;
-
- self.matNames[matName]=1
- self.writeIndented("material DEF MA_%s Material {\n" % matName, 1)
- self.writeIndented("diffuseColor 0.8 0.8 0.8\n")
- self.writeIndented("specularColor 1.0 1.0 1.0\n")
- self.writeIndented("shininess 0.5\n")
- self.writeIndented("transparency 0.0\n")
- self.writeIndented("}\n",-1)
-
- def writeMaterial(self, mat, matName):
- # look up material name, use it if available
- if self.matNames.has_key(matName):
- self.writeIndented("material USE MA_%s\n" % matName)
- self.matNames[matName]+=1
- return;
-
- self.matNames[matName]=1
-
- ambient = mat.amb/3
- diffuseR, diffuseG, diffuseB = \
- mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
- if world:
- ambi = world.getAmb()
- ambi0, ambi1, ambi2 = (ambi[0]*mat.amb) * 2, \
- (ambi[1]*mat.amb) * 2, \
- (ambi[2]*mat.amb) * 2
- else:
- ambi0, ambi1, ambi2 = 0, 0, 0
- emisR, emisG, emisB = (diffuseR*mat.emit+ambi0) / 2, \
- (diffuseG*mat.emit+ambi1) / 2, \
- (diffuseB*mat.emit+ambi2) / 2
-
- shininess = mat.hard/512.0
- specR = (mat.specCol[0]+0.001) / (1.25/(mat.getSpec()+0.001))
- specG = (mat.specCol[1]+0.001) / (1.25/(mat.getSpec()+0.001))
- specB = (mat.specCol[2]+0.001) / (1.25/(mat.getSpec()+0.001))
- transp = 1 - mat.alpha
- matFlags = mat.getMode()
- if matFlags & Blender.Material.Modes['SHADELESS']:
- ambient = 1
- shine = 1
- specR = emitR = diffuseR
- specG = emitG = diffuseG
- specB = emitB = diffuseB
- self.writeIndented("material DEF MA_%s Material {\n" % matName, 1)
- self.writeIndented("diffuseColor %s %s %s\n" % \
- (round(diffuseR,self.cp), \
- round(diffuseG,self.cp), \
- round(diffuseB,self.cp)))
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambient,self.cp)))
- self.writeIndented("specularColor %s %s %s\n" % \
- (round(specR,self.cp), \
- round(specG,self.cp), \
- round(specB,self.cp)))
- self.writeIndented("emissiveColor %s %s %s\n" % \
- (round(emisR,self.cp), \
- round(emisG,self.cp), \
- round(emisB,self.cp)))
- self.writeIndented("shininess %s\n" % (round(shininess,self.cp)))
- self.writeIndented("transparency %s\n" % (round(transp,self.cp)))
- self.writeIndented("}\n",-1)
-
- def writeImageTexture(self, name, filename):
- if self.texNames.has_key(name):
- self.writeIndented("texture USE %s\n" % self.cleanStr(name))
- self.texNames[name] += 1
- return
- else:
- self.writeIndented("texture DEF %s ImageTexture {\n" % \
- self.cleanStr(name), 1)
- self.writeIndented('url "%s"\n' % \
- filename.split("\\")[-1].split("/")[-1])
- self.writeIndented("}\n",-1)
- self.texNames[name] = 1
-
- def writeBackground(self):
- if world:
- worldname = world.getName()
- else:
- return
- blending = world.getSkytype()
- grd = world.getHor()
- grd0, grd1, grd2 = grd[0], grd[1], grd[2]
- sky = world.getZen()
- sky0, sky1, sky2 = sky[0], sky[1], sky[2]
- mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2]
- mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2
- if worldname in self.namesStandard:
- self.writeIndented("Background {\n",1)
- else:
- self.writeIndented("DEF %s Background {\n" % \
- self.secureName(worldname),1)
- # No Skytype - just Hor color
- if blending == 0:
- self.writeIndented("groundColor %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("skyColor %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- # Blend Gradient
- elif blending == 1:
- self.writeIndented("groundColor [ %s %s %s, " % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("groundAngle [ 1.57, 1.57 ]\n")
- self.writeIndented("skyColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("skyAngle [ 1.57, 1.57 ]\n")
- # Blend+Real Gradient Inverse
- elif blending == 3:
- self.writeIndented("groundColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("groundAngle [ 1.57, 1.57 ]\n")
- self.writeIndented("skyColor [ %s %s %s, " % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("skyAngle [ 1.57, 1.57 ]\n")
- # Paper - just Zen Color
- elif blending == 4:
- self.writeIndented("groundColor %s %s %s\n" % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("skyColor %s %s %s\n" % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- # Blend+Real+Paper - komplex gradient
- elif blending == 7:
- self.writeIndented("groundColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("groundAngle [ 1.57, 1.57 ]\n")
- self.writeIndented("skyColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(grd0,self.cp),
- round(grd1,self.cp),
- round(grd2,self.cp)))
- self.writeIndented("skyAngle [ 1.57, 1.57 ]\n")
- # Any Other two colors
- else:
- self.writeIndented("groundColor %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("skyColor %s %s %s\n" % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- alltexture = len(worldmat)
- for i in xrange(alltexture):
- namemat = worldmat[i].getName()
- pic = worldmat[i].getImage()
- if pic:
- # Stripped path.
- pic_path= pic.filename.split('\\')[-1].split('/')[-1]
- if namemat == "back":
- self.writeIndented('backUrl "%s"\n' % pic_path)
- elif namemat == "bottom":
- self.writeIndented('bottomUrl "%s"\n' % pic_path)
- elif namemat == "front":
- self.writeIndented('frontUrl "%s"\n' % pic_path)
- elif namemat == "left":
- self.writeIndented('leftUrl "%s"\n' % pic_path)
- elif namemat == "right":
- self.writeIndented('rightUrl "%s"\n' % pic_path)
- elif namemat == "top":
- self.writeIndented('topUrl "%s"\n' % pic_path)
- self.writeIndented("}",-1)
- self.writeIndented("\n\n")
-
- def writeLamp(self, ob):
- la = ob.data
- laType = la.getType()
-
- if laType == Lamp.Types.Lamp:
- self.writePointLight(ob, la)
- elif laType == Lamp.Types.Spot:
- self.writeSpotLight(ob, la)
- elif laType == Lamp.Types.Sun:
- self.writeDirectionalLight(ob, la)
- else:
- self.writeDirectionalLight(ob, la)
-
- def writeObject(self, ob):
-
- obname = self.cleanStr(ob.name)
-
- try:
- obtype=ob.getType()
- except AttributeError:
- print "Error: Unable to get type info for %s" % obname
- return
-
- if self.verbose >= 1:
- print "++ Writing %s object %s (Blender name: %s)\n" % \
- (obtype, obname, ob.name)
-
- # Note: I am leaving empties out for now -- the original
- # script does some really weird stuff with empties
- if ( (obtype != "Camera") and \
- (obtype != "Mesh") and \
- (obtype != "Lamp") ):
- print "Info: Ignoring [%s], object type [%s] " \
- "not handle yet" % (obname, obtype)
- return
-
- ob_matrix = Mathutils.Matrix(ob.getMatrix('worldspace'))
- if export_rotate_z_to_y.val:
- matrix = M_blen2vrml * ob_matrix * M_vrml2blen
- else:
- matrix = ob_matrix
- e = matrix.rotationPart().toEuler()
-
- v = matrix.translationPart()
- (axis, angle) = self.eulToVecRot(self.deg2rad(e.x), \
- self.deg2rad(e.y), \
- self.deg2rad(e.z))
-
- mrot = e.toMatrix().resize4x4()
- try:
- mrot.invert()
- except:
- print "Warning: %s has degenerate transformation!" % (obname)
- return
-
- diag = matrix * mrot
- sizeX = diag[0][0]
- sizeY = diag[1][1]
- sizeZ = diag[2][2]
-
- if self.verbose >= 1:
- print " Transformation:\n" \
- " loc: %f %f %f\n" \
- " size: %f %f %f\n" \
- " Rot: (%f %f %f), %f\n" % \
- (v.x, v.y, v.z, \
- sizeX, sizeY, sizeZ, \
- axis[0], axis[1], axis[2], angle)
-
- self.writeIndented("DEF OB_%s Transform {\n" % (obname), 1)
- self.writeIndented("translation %f %f %f\n" % \
- (v.x, v.y, v.z) )
-
- self.writeIndented("rotation %f %f %f %f\n" % \
- (axis[0],axis[1],axis[2],angle) )
-
- self.writeIndented("scale %f %f %f\n" % \
- (sizeX, sizeY, sizeZ) )
-
- self.writeIndented("children [\n", 1)
-
- self.writeObData(ob)
-
- self.writeIndented("]\n", -1) # end object
- self.writeIndented("}\n", -1) # end object
-
- def writeObData(self, ob):
-
- obtype = ob.getType()
-
- if obtype == "Camera":
- self.writeViewpoint(ob)
- elif obtype == "Mesh":
- self.writeMesh(ob)
- elif obtype == "Lamp":
- self.writeLamp(ob)
- elif obtype == "Empty":
- self.writeNode(ob)
-
-
-##########################################################
-# export routine
-##########################################################
-
- def export(self, scene, world, worldmat):
- print "Info: starting VRML97 export to " + self.filename + "..."
- self.writeHeader()
- self.writeScript()
- self.writeNavigationInfo(scene)
- self.writeBackground()
- self.writeFog()
- self.proto = 0
- allObj = []
- if export_selection_only.val:
- allObj = list(scene.objects.context)
- else:
- allObj = list(scene.objects)
- self.writeInline()
-
- for thisObj in allObj:
- self.writeObject(thisObj)
-
- if not export_selection_only.val:
- self.writeScript()
- self.cleanup()
-
-##########################################################
-# Utility methods
-##########################################################
-
- def cleanup(self):
- self.file.close()
- self.texNames={}
- self.matNames={}
- self.indentLevel=0
- print "Info: finished VRML97 export to %s\n" % self.filename
-
- def cleanStr(self, name, prefix='rsvd_'):
- """cleanStr(name,prefix) - try to create a valid VRML DEF \
- name from object name"""
-
- newName=name[:]
- if len(newName) == 0:
- self.nNodeID+=1
- return "%s%d" % (prefix, self.nNodeID)
-
- if newName in self.namesReserved:
- newName='%s%s' % (prefix,newName)
-
- if newName[0].isdigit():
- newName='%s%s' % ('_',newName)
-
- for bad in (' ','"','#',"'",',','.','[','\\',']','{','}'):
- newName=newName.replace(bad,'_')
- return newName
-
- def rgbToFS(self, c):
- s = "%s %s %s" % \
- (round(c.r/255.0,self.cp), \
- round(c.g/255.0,self.cp), \
- round(c.b/255.0,self.cp))
- return s
-
- def rad2deg(self, v):
- return round(v*180.0/math.pi,4)
-
- def deg2rad(self, v):
- return (v*math.pi)/180.0;
-
- def eulToVecRot(self, RotX, RotY, RotZ):
-
- ti = RotX*0.5
- tj = RotY*0.5
- th = RotZ*0.5
-
- ci = math.cos(ti)
- cj = math.cos(tj)
- ch = math.cos(th)
- si = math.sin(ti)
- sj = math.sin(tj)
- sh = math.sin(th)
- cc = ci*ch
- cs = ci*sh
- sc = si*ch
- ss = si*sh
-
- q0 = cj*cc + sj*ss
- q1 = cj*sc - sj*cs
- q2 = cj*ss + sj*cc
- q3 = cj*cs - sj*sc
-
- angle = 2 * math.acos(q0)
- if (math.fabs(angle) < 0.000001):
- axis = [1.0, 0.0, 0.0]
- else:
- sphi = 1.0/math.sqrt(1.0 - (q0*q0))
- axis = [q1 * sphi, q2 * sphi, q3 * sphi]
-
- a = Mathutils.Vector(axis)
- a.normalize()
- return ([a.x, a.y, a.z], angle)
-
-
- # For writing well formed VRML code
- #----------------------------------
- def writeIndented(self, s, inc=0):
- if inc < 1:
- self.indentLevel = self.indentLevel + inc
-
- self.file.write( self.indentLevel*"\t" + s)
-
- if inc > 0:
- self.indentLevel = self.indentLevel + inc
-
- # Sometimes better to not have too many
- # tab characters in a long list, for file size
- #----------------------------------
- def writeUnindented(self, s):
- self.file.write(s)
-
-##########################################################
-# Callbacks, needed before Main
-##########################################################
-
-def select_file(filename):
- if sys.exists(filename) and _safeOverwrite:
- result = \
- Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0")
- if(result != 1):
- return
-
- if not filename.endswith(extension):
- filename += extension
-
- wrlexport=VRML2Export(filename)
- wrlexport.export(scene, world, worldmat)
-
-#########################################################
-# UI and Registry utilities
-#########################################################
-
-export_selection_only = Draw.Create(0)
-export_rotate_z_to_y = Draw.Create(1)
-export_compressed = Draw.Create(0)
-
-def save_to_registry():
- d = {}
- d['selection_only'] = export_selection_only.val
- d['rotate_z_to_y'] = export_rotate_z_to_y.val
- d['compressed'] = export_compressed.val
- Registry.SetKey('vrml97_export', d, True)
-
-def load_from_registry():
- d = Registry.GetKey('vrml97_export', True)
- if d:
- try:
- export_selection_only.val = d['selection_only']
- export_rotate_z_to_y.val = d['rotate_z_to_y']
- export_compressed.val = d['compressed']
- except: save_to_registry() # If data is not valid, rewrite it.
-
-def show_popup():
- pup_block = [
- ('Selection Only', export_selection_only, 'Only export objects in visible selection. Else export whole scene.'),
- ('Rotate +Z to +Y', export_rotate_z_to_y, 'Rotate such that +Z axis (Blender up) becomes +Y (VRML up).'),
- ('Compress', export_compressed, 'Generate a .wrz file (normal VRML compressed by gzip).')
- ]
- return Draw.PupBlock('Export VRML 97...', pup_block)
-
-#########################################################
-# main routine
-#########################################################
-
-load_from_registry()
-
-# Note that show_popup must be done before Blender.Window.FileSelector,
-# because export_compressed affects the suggested extension of resulting
-# file.
-
-if show_popup():
- save_to_registry()
- if export_compressed.val:
- extension=".wrz"
- from gzip import *
- else:
- extension=".wrl"
- Blender.Window.FileSelector(select_file, "Export VRML97", \
- sys.makename(ext=extension))
diff --git a/release/scripts/weightpaint_average.py b/release/scripts/weightpaint_average.py
deleted file mode 100644
index 4e8830256b2..00000000000
--- a/release/scripts/weightpaint_average.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!BPY
-"""
-Name: 'Vertex Groups Island Average'
-Blender: 243
-Group: 'WeightPaint'
-Tooltip: 'Average the vertex weights for each connected set of verts'
-"""
-
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-import Blender
-from Blender import Scene, Mesh, Window, sys, Draw
-from BPyMesh import meshWeight2List, list2MeshWeight, mesh2linkedFaces
-
-import BPyMessages
-import bpy
-
-def faceGroups2VertSets(face_groups):
- ''' Return the face groups as sets of vert indicies '''
- return [set([v.index for f in fg for v in f]) for fg in face_groups]
-
-
-def vgroup_average(ob_orig, me, sce, PREF_ALL_VGROUPS=True):
- if not me.getVertGroupNames():
- return
-
- weight_names, weight_list = meshWeight2List(me)
-
- weight_names_len = len(weight_names)
- vgroup_dummy = [0.0] * weight_names_len
- vgroup_range = range(weight_names_len)
-
- if not PREF_ALL_VGROUPS:
- weight_active_index = weight_names.index(me.activeGroup)
-
- for vert_set in faceGroups2VertSets( mesh2linkedFaces(me) ):
- if not vert_set:
- continue
-
-
- if PREF_ALL_VGROUPS:
- # We need to average the vgroups
- collected_group = vgroup_dummy[:]
- for i in vert_set:
- vert_group = weight_list[i] # get the original weight
- weight_list[i] = collected_group # replace with the collected group
-
- for j in vgroup_range: # iter through the vgroups
- collected_group[j] += vert_group[j]
-
- for j in vgroup_range:
- collected_group[j] /= len(vert_set)
- else:
- # Active group only
- vert_weight = 0.0
- for i in vert_set:
- vert_weight += weight_list[i][weight_active_index]
-
- vert_weight /= len(vert_set)
-
- for i in vert_set:
- weight_list[i][weight_active_index] = vert_weight
-
- list2MeshWeight(me, weight_names, weight_list)
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = bpy.data.scenes.active
-
- # Get the active object, there can only ever be 1
- # and the active object is always the editmode object.
- ob_act = sce.objects.active
-
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- # Saves the editmode state and go's out of
- # editmode if its enabled, we cant make
- # changes to the mesh data while in editmode.
- is_editmode = Window.EditMode()
- Window.EditMode(0)
-
- PREF_ALL_VGROUPS = Draw.PupMenu("All Groups?%t|All Groups%x1|Active Group Only%x0")
- if PREF_ALL_VGROUPS==-1:
- return
-
- Window.WaitCursor(1)
- me = ob_act.getData(mesh=1) # old NMesh api is default
- t = sys.time()
-
- # Run the mesh editing function
- vgroup_average(ob_act, me, sce, PREF_ALL_VGROUPS)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'Average VGroups in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
- if is_editmode: Window.EditMode(1)
-
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/weightpaint_clean.py b/release/scripts/weightpaint_clean.py
deleted file mode 100644
index ca2184bade4..00000000000
--- a/release/scripts/weightpaint_clean.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!BPY
-"""
-Name: 'Clean Weight...'
-Blender: 245
-Group: 'WeightPaint'
-Tooltip: 'Removed verts from groups below a weight limit.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Clean Weight
-
-This Script is to be used only in weight paint mode,
-It removes very low weighted verts from the current group with a weight option.
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Draw, Object
-import BPyMesh
-def weightClean(me, PREF_THRESH, PREF_KEEP_SINGLE, PREF_OTHER_GROUPS):
-
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
- act_group= me.activeGroup
-
- rem_count = 0
-
- if PREF_OTHER_GROUPS:
- for wd in vWeightDict:
- l = len(wd)
- if not PREF_KEEP_SINGLE or l > 1:
- # cant use iteritems because the dict is having items removed
- for group in wd.keys():
- w= wd[group]
- if w <= PREF_THRESH:
- # small weight, remove.
- del wd[group]
- rem_count +=1
- l-=1
-
- if PREF_KEEP_SINGLE and l == 1:
- break
-
- else:
- for wd in vWeightDict:
- if not PREF_KEEP_SINGLE or len(wd) > 1:
- try:
- w= wd[act_group]
- if w <= PREF_THRESH:
- # small weight, remove.
- del wd[act_group]
- rem_count +=1
- except:
- pass
-
- # Copy weights back to the mesh.
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
- return rem_count
-
-
-def main():
- scn= Scene.GetCurrent()
- ob= scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- me= ob.getData(mesh=1)
-
- PREF_PEAKWEIGHT= Draw.Create(0.001)
- PREF_KEEP_SINGLE= Draw.Create(1)
- PREF_OTHER_GROUPS= Draw.Create(0)
-
- pup_block= [\
- ('Peak Weight:', PREF_PEAKWEIGHT, 0.005, 1.0, 'Remove verts from groups below this weight.'),\
- ('All Other Groups', PREF_OTHER_GROUPS, 'Clean all groups, not just the current one.'),\
- ('Keep Single User', PREF_KEEP_SINGLE, 'Keep verts in at least 1 group.'),\
- ]
-
- if not Draw.PupBlock('Clean Selected Meshes...', pup_block):
- return
-
- rem_count = weightClean(me, PREF_PEAKWEIGHT.val, PREF_KEEP_SINGLE.val, PREF_OTHER_GROUPS.val)
-
- # Run on entire blend file. usefull sometimes but dont let users do it.
- '''
- rem_count = 0
- for ob in Object.Get():
- if ob.type != 'Mesh':
- continue
- me= ob.getData(mesh=1)
-
- rem_count += weightClean(me, PREF_PEAKWEIGHT.val, PREF_KEEP_SINGLE.val, PREF_OTHER_GROUPS.val)
- '''
- Draw.PupMenu('Removed %i verts from groups' % rem_count)
-
-if __name__=='__main__':
- main()
diff --git a/release/scripts/weightpaint_copy.py b/release/scripts/weightpaint_copy.py
deleted file mode 100644
index 976bba0ea2c..00000000000
--- a/release/scripts/weightpaint_copy.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!BPY
-"""
-Name: 'Copy Active Group...'
-Blender: 243
-Group: 'WeightPaint'
-Tooltip: 'Copy the active group to a new one'
-"""
-
-__author__ = ["Campbell Barton"]
-__url__ = ("blender.org",)
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Active Group Copy
-
-This script makes a copy of the active group
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Draw, Window, Mesh
-import BPyMesh
-SMALL_NUM= 0.000001
-def copy_act_vgroup(me, PREF_NAME, PREF_SEL_ONLY):
- Window.WaitCursor(1)
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
- act_group= me.activeGroup
-
- if not PREF_SEL_ONLY:
- for wd in vWeightDict:
- try: wd[PREF_NAME] = wd[act_group]
- except: pass
- else:
- # Selected faces only
- verts = {} # should use set
- for f in me.faces:
- if f.sel:
- for v in f:
- verts[v.index] = None
-
- for i in verts.iterkeys():
- wd = vWeightDict[i]
- try: wd[PREF_NAME] = wd[act_group]
- except: pass
-
-
-
- groupNames.append(PREF_NAME)
- # Copy weights back to the mesh.
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
- Window.WaitCursor(0)
-
-def main():
- scn= Scene.GetCurrent()
- ob= scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- me= ob.getData(mesh=1)
- act_group= me.activeGroup
-
- PREF_NAME= Draw.Create(act_group + '_copy')
- PREF_SEL_ONLY = Draw.Create(0)
-
- pup_block= [\
- ('', PREF_NAME, 0, 31, 'Name of group copy.'),\
- ('Only Selected', PREF_SEL_ONLY, 'Only include selected faces in the new grop.'),\
- ]
-
- if not Draw.PupBlock('New Name...', pup_block):
- return
- PREF_NAME = PREF_NAME.val
- PREF_SEL_ONLY = PREF_SEL_ONLY.val
- copy_act_vgroup(me, PREF_NAME, PREF_SEL_ONLY)
-
- try: me.activeGroup = PREF_NAME
- except: pass
-
-if __name__=='__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/weightpaint_envelope_assign.py b/release/scripts/weightpaint_envelope_assign.py
deleted file mode 100644
index cafa44fef38..00000000000
--- a/release/scripts/weightpaint_envelope_assign.py
+++ /dev/null
@@ -1,240 +0,0 @@
-#!BPY
-
-"""
-Name: 'Envelope via Group Objects'
-Blender: 242
-Group: 'WeightPaint'
-Tooltip: 'Assigns weights to vertices via object envelopes'
-"""
-
-__author__ = ["Campbell Barton"]
-__url__ = ("blender", "blenderartist.org")
-__version__ = "0.1"
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-def intersection_data(ob):
- '''
- Takes an object and returns raw triangles and tri bounds.
- returns a list of (v1,v2,v3, xmin, ymin, xmax, ymax)
- ... to be used for ray intersection
- '''
- global tot_ymin, tot_xmin, tot_ymax, tot_xmax, tot_zmin, tot_zmax
- tot_zmin = tot_ymin = tot_xmin = 100000000.0
- tot_zmax = tot_ymax = tot_xmax = -100000000.0
-
- def tribounds_xy(v1,v2,v3):
- '''
- return the 3 vecs with bounds, also update tot_*min/max
- '''
- global tot_ymin, tot_xmin, tot_ymax, tot_xmax, tot_zmin, tot_zmax
- xmin = xmax = v1.x
- ymin = ymax = v1.y
-
- x = v2.x
- y = v2.y
- if x>xmax: xmax = x
- if y>ymax: ymax = y
- if x<xmin: xmin = x
- if y<ymin: ymin = y
-
-
- x = v3.x
- y = v3.y
- if x>xmax: xmax = x
- if y>ymax: ymax = y
- if x<xmin: xmin = x
- if y<ymin: ymin = y
-
- # totbounds
- for z in v1.z, v2.z, v3.z:
- if z>tot_zmax: tot_zmax = z
- if z<tot_zmin: tot_zmin = z
-
- # maintain global min/max for x and y
- if xmax>tot_xmax: tot_xmax = xmax
- if xmin<tot_xmin: tot_xmin = xmin
-
- if ymax>tot_ymax: tot_ymax = ymax
- if ymin<tot_ymin: tot_ymin = ymin
-
- return v1,v2,v3, xmin, ymin, xmax, ymax
-
- me = BPyMesh.getMeshFromObject(ob)
-
- if not me:
- return []
-
- me.transform(ob.matrixWorld)
-
- mesh_data = []
-
- # copy all the vectors so when the mesh is free'd we still have access.
- mesh_vert_cos= [v.co.copy() for v in me.verts]
-
- for f in me.faces:
- f_v = [mesh_vert_cos[v.index] for v in f]
- mesh_data.append( tribounds_xy(f_v[0], f_v[1], f_v[2]) )
- if len(f) == 4:
- mesh_data.append( tribounds_xy(f_v[0], f_v[2], f_v[3]) )
-
- me.verts = None # free some memory
-
- return ob.name, mesh_data, tot_xmin, tot_ymin, tot_zmin, tot_xmax, tot_ymax, tot_zmax
-
-from Blender import *
-ray = Mathutils.Vector(0,0,-1)
-def point_in_data(point, mesh_data_tuple):
- ob_name, mesh_data, tot_xmin, tot_ymin, tot_zmin, tot_xmax, tot_ymax, tot_zmax = mesh_data_tuple
-
- Intersect = Mathutils.Intersect
- x = point.x
- y = point.y
- z = point.z
-
- # Bouds check for all mesh data
- if not (\
- tot_zmin < z < tot_zmax and\
- tot_ymin < y < tot_ymax and\
- tot_xmin < x < tot_xmax\
- ):
- return False
-
- def isect(tri_data):
- v1,v2,v3, xmin, ymin, xmax, ymax = tri_data
- if not (xmin < x < xmax and ymin < y < ymax):
- return False
-
- if v1.z < z and v2.z < z and v3.z < z:
- return False
-
- isect = Intersect(v1, v2,v3, ray, point, 1) # Clipped.
- if isect and isect.z > z: # This is so the ray only counts if its above the point.
- return True
- else:
- return False
-
- # return len([None for tri_data in mesh_data if isect(tri_data)]) % 2
- return len( filter(isect, mesh_data) ) % 2
-
-import BPyMesh
-def env_from_group(ob_act, grp, PREF_UPDATE_ACT=True):
-
- me = ob_act.getData(mesh=1)
-
- if PREF_UPDATE_ACT:
- act_group = me.activeGroup
- if act_group == None:
- Draw.PupMenu('Error%t|No active vertex group.')
- return
-
- try:
- ob = Object.Get(act_group)
- except:
- Draw.PupMenu('Error%t|No object named "'+ act_group +'".')
- return
-
- group_isect = intersection_data(ob)
-
- else:
-
- # get intersection data
- # group_isect_data = [intersection_data(ob) for ob in group.objects]
- group_isect_data = []
- for ob in grp.objects:
- if ob != ob_act: # in case we're in the group.
- gid = intersection_data(ob)
- if gid[1]: # has some triangles?
- group_isect_data.append( gid )
-
- # we only need 1 for the active group
- if PREF_UPDATE_ACT:
- break
-
- # sort by name
- group_isect_data.sort()
-
- if PREF_UPDATE_ACT:
- group_names, vweight_list = BPyMesh.meshWeight2List(me)
- group_index = group_names.index(act_group)
- else:
- group_names = [gid[0] for gid in group_isect_data]
- vweight_list= [[0.0]* len(group_names) for i in xrange(len(me.verts))]
-
-
-
- ob_act_mat = ob_act.matrixWorld
- for vi, v in enumerate(me.verts):
- # Get all the groups for this vert
- co = v.co * ob_act_mat
-
- if PREF_UPDATE_ACT:
- # only update existing
- if point_in_data(co, group_isect): w = 1.0
- else: w = 0.0
- vweight_list[vi][group_index] = w
-
- else:
- # generate new vgroup weights.
- for group_index, group_isect in enumerate(group_isect_data):
- if point_in_data(co, group_isect):
- vweight_list[vi][group_index] = 1.0
-
- BPyMesh.list2MeshWeight(me, group_names, vweight_list)
-
-import BPyMessages
-def main():
-
- scn= Scene.GetCurrent()
- ob_act = scn.objects.active
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- PREF_ENV_GROUPNAME= Draw.Create('')
- PREF_UPDATE_ACT= Draw.Create(True)
- pup_block= [\
- ('Update Active', PREF_UPDATE_ACT, 'Only apply envelope weights to the active group.'),\
- '...or initialize from group',\
- ('GR:', PREF_ENV_GROUPNAME, 0, 21, 'The name of an existing groups, each member will be used as a weight envelope'),\
- ]
-
- if not Draw.PupBlock('Envelope From Group...', pup_block):
- return
-
- PREF_UPDATE_ACT= PREF_UPDATE_ACT.val
-
- if not PREF_UPDATE_ACT:
- try:
- grp = Group.Get(PREF_ENV_GROUPNAME.val)
- except:
- Draw.PupMenu('Error%t|Group "' + PREF_ENV_GROUPNAME.val + '" does not exist.')
- return
- else:
- grp = None
-
- Window.WaitCursor(1)
- t = sys.time()
- env_from_group(ob_act, grp, PREF_UPDATE_ACT)
- print 'assigned envelopes in:', sys.time() - t
- Window.WaitCursor(0)
-
-if __name__ == '__main__':
- main()
diff --git a/release/scripts/weightpaint_gradient.py b/release/scripts/weightpaint_gradient.py
deleted file mode 100644
index eb7aff7eb89..00000000000
--- a/release/scripts/weightpaint_gradient.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!BPY
-"""
-Name: 'Weight Gradient...'
-Blender: 245
-Group: 'WeightPaint'
-Tooltip: 'Click on the start and end grad points for the mesh for selected faces.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__=\
-'''
-This script is used to fill the selected faces with a gradient
-To use the script, switch to "Face Select" mode then "Vertex Paint" mode
-Select the faces you wish to apply the gradient to.
-Click twice on the mesh to set the start and end points of the gradient.
-The color under the mouse will be used for the start and end blend colors.
-Note:
-Holding Shift or clicking outside the mesh on the second click will blend the first colour to nothing.
-'''
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-
-import mesh_gradient
-import Blender
-
-def main():
- scn= Blender.Scene.GetCurrent()
- ob= scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- Blender.Draw.PupMenu('Error, no active mesh object, aborting.')
- return
- # MODE 0 == VCOL
- # MODE 1 == WEIGHT
- MODE= 0
- mesh_gradient.vertexGradientPick(ob, MODE)
-
-
-if __name__ == '__main__':
- main()
-
diff --git a/release/scripts/weightpaint_grow_shrink.py b/release/scripts/weightpaint_grow_shrink.py
deleted file mode 100644
index 5c0f28685f9..00000000000
--- a/release/scripts/weightpaint_grow_shrink.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!BPY
-"""
-Name: 'Grow/Shrink Weight...'
-Blender: 245
-Group: 'WeightPaint'
-Tooltip: 'Grow/Shrink active vertex group.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Grow Shrink Weight
-
-This Script is to be used only in weight paint mode,
-It grows/shrinks the bounds of the weight painted area
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Draw, Window
-import BPyMesh
-def actWeightNormalize(me, PREF_MODE, PREF_MAX_DIST, PREF_STRENGTH, PREF_ITERATIONS):
- Window.WaitCursor(1)
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
- act_group= me.activeGroup
-
- # Start with assumed zero weights
- orig_vert_weights= [0.0] * len(vWeightDict) # Will be directly assigned to orig_vert_weights
-
-
- # fill in the zeros with real weights.
- for i, wd in enumerate(vWeightDict):
- try:
- orig_vert_weights[i]= wd[act_group]
- except:
- pass
-
- new_vert_weights= list(orig_vert_weights)
-
- for dummy in xrange(PREF_ITERATIONS):
- # Minimize or maximize the weights. connection based.
-
- if PREF_MODE==0: # Grow
- op= max
- else: # Shrink
- op= min
-
- for ed in me.edges:
- if not PREF_MAX_DIST or ed.length < PREF_MAX_DIST:
-
- i1= ed.v1.index
- i2= ed.v2.index
- new_weight= op(orig_vert_weights[i1], orig_vert_weights[i2])
-
- if PREF_STRENGTH==1.0: # do a full copy
- new_vert_weights[i1]= op(new_weight, new_vert_weights[i1])
- new_vert_weights[i2]= op(new_weight, new_vert_weights[i2])
-
- else: # Do a faded copy
- new_vert_weights[i1]= op(new_weight, new_vert_weights[i1])
- new_vert_weights[i2]= op(new_weight, new_vert_weights[i2])
-
- # Face the copy with the original (orig is updated per iteration)
- new_vert_weights[i1]= (new_vert_weights[i1]*PREF_STRENGTH) + (orig_vert_weights[i1]*(1-PREF_STRENGTH))
- new_vert_weights[i2]= (new_vert_weights[i2]*PREF_STRENGTH) + (orig_vert_weights[i2]*(1-PREF_STRENGTH))
-
-
- for i, wd in enumerate(vWeightDict):
- new_weight= new_vert_weights[i]
- if new_weight != orig_vert_weights[i]:
- wd[act_group]= new_weight
-
- if dummy+1 != PREF_ITERATIONS: # dont copy the list on the last round.
- orig_vert_weights= list(new_vert_weights)
-
-
- # Copy weights back to the mesh.
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
- Window.WaitCursor(0)
-
-def main():
- scn= Scene.GetCurrent()
- ob= scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- me= ob.getData(mesh=1)
-
- PREF_MAXDIST= Draw.Create(0.0)
- PREF_STRENGTH= Draw.Create(1.0)
- PREF_MODE= Draw.Create(0)
- PREF_ITERATIONS= Draw.Create(1)
-
- pup_block= [\
- ('Bleed Dist:', PREF_MAXDIST, 0.0, 1.0, 'Set a distance limit for bleeding.'),\
- ('Bleed Strength:', PREF_STRENGTH, 0.01, 1.0, 'Bleed strength between adjacent verts weight. 1:full, 0:None'),\
- ('Iterations', PREF_ITERATIONS, 1, 20, 'Number of times to run the blending calculation.'),\
- ('Contract (Shrink)', PREF_MODE, 'Shrink instead of growing.'),\
- ]
-
- if not Draw.PupBlock('Grow/Shrink...', pup_block):
- return
-
- actWeightNormalize(me, PREF_MODE.val, PREF_MAXDIST.val, PREF_STRENGTH.val, PREF_ITERATIONS.val)
-
-
-if __name__=='__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/weightpaint_invert.py b/release/scripts/weightpaint_invert.py
deleted file mode 100644
index cdae83a9d50..00000000000
--- a/release/scripts/weightpaint_invert.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!BPY
-"""
-Name: 'Invert Active Group'
-Blender: 245
-Group: 'WeightPaint'
-Tooltip: 'Invert the active vertex group'
-"""
-
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-import Blender
-from Blender import Scene, Mesh, Window, sys
-
-import BPyMessages
-import bpy
-
-def vgroup_invert(ob_orig, me):
- if not me.getVertGroupNames():
- return
- group_act = me.activeGroup
- if group_act == None:
- return
-
- group_data = me.getVertsFromGroup(group_act, 1)
-
- weights= [1.0] * len(me.verts) # 1.0 - initialize inverted
-
- group_data = me.getVertsFromGroup(group_act, 1) # (i,w) tuples.
-
- me.removeVertGroup(group_act) # messes up the active group.
- for i,w in group_data:
- weights[i] = 1.0-w
-
- me.addVertGroup(group_act)
-
- rep = Blender.Mesh.AssignModes.REPLACE
- vertList= [None]
- for i,weight in enumerate(weights):
- vertList[0] = i
- me.assignVertsToGroup(group_act, vertList, weight, rep)
-
- me.activeGroup = group_act
- me.update()
-
-def main():
-
- # Gets the current scene, there can be many scenes in 1 blend file.
- sce = bpy.data.scenes.active
-
- # Get the active object, there can only ever be 1
- # and the active object is always the editmode object.
- ob_act = sce.objects.active
-
- if not ob_act or ob_act.type != 'Mesh':
- BPyMessages.Error_NoMeshActive()
- return
-
- # Saves the editmode state and go's out of
- # editmode if its enabled, we cant make
- # changes to the mesh data while in editmode.
- is_editmode = Window.EditMode()
- Window.EditMode(0)
-
- Window.WaitCursor(1)
- me = ob_act.getData(mesh=1) # old NMesh api is default
- t = sys.time()
-
- # Run the mesh editing function
- vgroup_invert(ob_act, me)
-
- # Timing the script is a good way to be aware on any speed hits when scripting
- print 'Invert VGroup in %.2f seconds' % (sys.time()-t)
- Window.WaitCursor(0)
- if is_editmode: Window.EditMode(1)
-
-# This lets you can import the script without running it
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/weightpaint_normalize.py b/release/scripts/weightpaint_normalize.py
deleted file mode 100644
index 6059922eecb..00000000000
--- a/release/scripts/weightpaint_normalize.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!BPY
-"""
-Name: 'Normalize/Scale Weight...'
-Blender: 245
-Group: 'WeightPaint'
-Tooltip: 'Normalize the weight of the active weightgroup.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-
-Normalize Weights
-
-This Script is to be used only in weight paint mode,
-It Normalizes the weights of the current group, to the desired peak
-optionaly scaling groups that are shared by these verts so the
-proportion of the veighting is unchanged.
-"""
-
-# ***** 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 *****
-# --------------------------------------------------------------------------
-
-from Blender import Scene, Draw, Object, Modifier
-import BPyMesh
-SMALL_NUM= 0.000001
-
-def getArmatureGroups(ob, me):
-
- arm_obs = []
-
- arm = ob.parent
- if arm and arm.type == 'Armature' and ob.parentType == Object.ParentTypes.ARMATURE:
- arm_obs.append(arm)
-
- for m in ob.modifiers:
- if m.type== Modifier.Types.ARMATURE:
- arm = m[Modifier.Settings.OBJECT]
- if arm:
- arm_obs.append(arm)
-
- # convert to a dict and back, should be a set! :/ - python 2.3 dosnt like.
- return dict([ (bonename, None) for arm in arm_obs for bonename in arm.data.bones.keys() ]).keys()
-
-
-
-def actWeightNormalize(me, ob, PREF_PEAKWEIGHT, PREF_ACTIVE_ONLY, PREF_ARMATURE_ONLY, PREF_KEEP_PROPORTION):
-
- groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
- new_weight= max_weight= -1.0
- act_group= me.activeGroup
-
- if PREF_ACTIVE_ONLY:
- normalizeGroups = [act_group]
- else:
- normalizeGroups = groupNames[:]
-
- if PREF_ARMATURE_ONLY:
-
- armature_groups = getArmatureGroups(ob, me)
-
- i = len(normalizeGroups)
- while i:
- i-=1
- if not normalizeGroups[i] in armature_groups:
- del normalizeGroups[i]
-
-
- for act_group in normalizeGroups:
- vWeightDictUsed=[False] * len(vWeightDict)
-
- for i, wd in enumerate(vWeightDict):
- try:
- new_weight= wd[act_group]
- if new_weight > max_weight:
- max_weight= new_weight
- vWeightDictUsed[i]=wd
- except:
- pass
-
- # These can be skipped for now, they complicate things when using multiple vgroups,
- '''
- if max_weight < SMALL_NUM or new_weight == -1:
- Draw.PupMenu('No verts to normalize. exiting.')
- #return
-
- if abs(max_weight-PREF_PEAKWEIGHT) < SMALL_NUM:
- Draw.PupMenu('Vert Weights are alredy normalized.')
- #return
- '''
- max_weight= max_weight/PREF_PEAKWEIGHT
-
- if PREF_KEEP_PROPORTION:
- # TODO, PROPORTIONAL WEIGHT SCALING.
- for wd in vWeightDictUsed:
- if wd: # not false.
- if len(wd) == 1:
- # Only 1 group for thsi vert. Simple
- wd[act_group] /= max_weight
- else:
- # More then 1 group. will need to scale all users evenly.
- if PREF_ARMATURE_ONLY:
- local_maxweight= max([v for k, v in wd.iteritems() if k in armature_groups]) / PREF_PEAKWEIGHT
- if local_maxweight > 0.0:
- # So groups that are not used in any bones are ignored.
- for weight in wd.iterkeys():
- if weight in armature_groups:
- wd[weight] /= local_maxweight
- else:
- local_maxweight= max(wd.itervalues()) / PREF_PEAKWEIGHT
- for weight in wd.iterkeys():
- wd[weight] /= local_maxweight
-
- else: # Simple, just scale the weights up. we alredy know this is in an armature group (if needed)
- for wd in vWeightDictUsed:
- if wd: # not false.
- wd[act_group] /= max_weight
-
- # Copy weights back to the mesh.
- BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
-
-
-def main():
- scn= Scene.GetCurrent()
- ob= scn.objects.active
-
- if not ob or ob.type != 'Mesh':
- Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- me= ob.getData(mesh=1)
-
- PREF_PEAKWEIGHT= Draw.Create(1.0)
- PREF_ACTIVE_ONLY= Draw.Create(1)
- PREF_KEEP_PROPORTION= Draw.Create(1)
- PREF_ARMATURE_ONLY= Draw.Create(0)
-
- pup_block= [\
- ('Peak Weight:', PREF_PEAKWEIGHT, 0.01, 1.0, 'Upper weight for normalizing.'),\
- ('Active Only', PREF_ACTIVE_ONLY, 'Only Normalize groups that have matching bones in an armature (when an armature is used).'),\
- ('Proportional', PREF_KEEP_PROPORTION, 'Scale other weights so verts (Keep weights with other groups in proportion).'),\
- ('Armature Only', PREF_ARMATURE_ONLY, 'Only Normalize groups that have matching bones in an armature (when an armature is used).'),\
- ]
-
- if not Draw.PupBlock('Clean Selected Meshes...', pup_block):
- return
-
- actWeightNormalize(me, ob, PREF_PEAKWEIGHT.val, PREF_ACTIVE_ONLY.val, PREF_ARMATURE_ONLY.val, PREF_KEEP_PROPORTION.val)
-
-if __name__=='__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/widgetwizard.py b/release/scripts/widgetwizard.py
deleted file mode 100644
index a7ddd68268a..00000000000
--- a/release/scripts/widgetwizard.py
+++ /dev/null
@@ -1,917 +0,0 @@
-#!BPY
-
-"""
-Name: 'Shape Widget Wizard'
-Blender: 238
-Group: 'Animation'
-Tip: 'Adds Widgets for Driven Shapes'
-"""
-
-__author__ = ["Johnny Matthews (guitargeek)"]
-__url__ = ("blender", "blenderartists.org")
-__version__ = "0.0.9 12/15/05"
-
-__bpydoc__ = """\
-"Shape Widget Wizard" creates objects that drive shape channels.
-
-Explanation:
-
-Shapes define morph targets and sometimes it is helpful to animate with a GUI
-control panel of widgets. This script lets you define several different types
-of controls that (depending on the type) control 1 to 4 shapes with a single
-controller.
-
-Usage:
-
-1. Click where you want the widget to go<br>
-2. Highlight the object that has shapes<br>
-3. Run the script<br>
-4. Choose the type of widget (there are next and back buttons if you pick the wrong kind)<br>
-5. Click next and choose what shapes go where on the widget<br>
-6. Choose a display name for the widget<br>
-7. Click finish
-
-The widget is added and you are returned to the first screen for adding another widget.
-
-"""
-
-###################################################################
-# #
-# Shape Widget Wizard #
-# #
-# all versions (C) December 2005 Johnny Matthews (guitargeek) #
-# #
-# Released under the GPL #
-# #
-# Works in Blender 2.4 and higher #
-# #
-# This script can be found online at: #
-# http://guitargeek.superihost.com/widgetmaker #
-# #
-# email: johnny.matthews@gmail.com #
-###################################################################
-# History #
-# 0.9 #
-# Added Name Objects #
-# 0.81 #
-# Added Single Shape Toggle #
-# #
-# 0.8 #
-# Controller is Transform Locked and can only move #
-# in appropriate directions #
-# #
-# 0.7 #
-# Controller is named the same as the range + ".ctrl" #
-# #
-###################################################################
-
-import Blender
-import bpy
-from Blender import Mesh,Object,Material,Window,IpoCurve,Ipo,Text3d
-from Blender.BGL import *
-from Blender.Draw import *
-print "----------------------"
-
-SHAPE1_ONE_MONE = 1
-SHAPE1_ONE_ZERO = 2
-SHAPE1_ZERO_MONE = 3
-SHAPE1_TOGGLE = 12
-SHAPE2_EXCLUSIVE = 4
-SHAPE2_V = 5
-SHAPE2_T = 6
-SHAPE2_INVT = 7
-SHAPE2_PLUS = 8
-SHAPE3_T = 9
-SHAPE3_INVT = 10
-SHAPE4_X = 11
-
-
-stage = 1
-numshapes = Create(1)
-widmenu = Create(1)
-rangename = Create("Range")
-shapes = [Create(0),Create(0),Create(0),Create(0)]
-drawtype = 0
-
-
-#get rid of an ipo curve by deleting all its points
-def delCurve(ipo):
- while len(ipo.bezierPoints) > 0:
- ipo.delBezier(0)
- ipo.recalc()
-
-#if a given ipocurve is not there create it, otherwise get it
-def verifyIpocurve(ky,index):
- ipo = ky.ipo
- if ipo == None:
- nip = bpy.data.ipos.new("keyipo", "Key")
- ky.ipo = nip
- ipo = ky.ipo
- if index == 0:
- idx = "Basis"
- else:
- idx = "Key " + str(index)
- crv = ipo[idx]
- if crv == None:
- # print idx
- crv = ipo.addCurve(idx)
- crv.interpolation = IpoCurve.InterpTypes.LINEAR
- return crv
-
-# Add the Drivers and Curves
-def setupDrivers(ob,ctrl,type):
- global shapes
- me = ob.getData(mesh=1)
- ky = me.key
-
- # Should we add an error here??
- if not ky:
- return
-
- if type in [SHAPE1_ONE_MONE,SHAPE1_ONE_ZERO,SHAPE1_ZERO_MONE]:
- ctrl.protectFlags = int("111111011",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
-
- delCurve(ipo)
- if type == 1:
- ipo.append((-1,-1))
- ipo.append((0,0))
- ipo.append((1,1))
- if type == 2:
- ipo.append((0,0))
- ipo.append((1,1))
- if type == 3:
- ipo.append((-1,-1))
- ipo.append((0,0))
- ipo.recalc()
-
- if type == SHAPE1_TOGGLE:
- ctrl.protectFlags = int("111111011",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((0,0))
- ipo.append((0.5,0))
- ipo.append((0.500001,1))
- ipo.append((1,1))
- ipo.recalc()
-
- if type == SHAPE2_EXCLUSIVE:
- ctrl.protectFlags = int("111111011",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((0,0))
- ipo.append((1,1))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_Z
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((-1,1))
- ipo2.append((0,0))
- ipo2.recalc()
-
- if type == SHAPE2_T:
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((-1,-1))
- ipo.append((0,0))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((-1,-1))
- ipo2.append((1,1))
- ipo2.recalc()
-
- if type == SHAPE2_INVT:
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((0,0))
- ipo.append((1,1))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((-1,-1))
- ipo2.append((1,1))
- ipo2.recalc()
-
- if type == SHAPE2_PLUS:
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((-1,-1))
- ipo.append((1,1))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((-1,-1))
- ipo2.append((1,1))
- ipo2.recalc()
-
- if type == SHAPE2_V: # 2 Shape Mix
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- delCurve(ipo)
- ipo.append((0,0))
- ipo.append((1,1))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- delCurve(ipo2)
- ipo2.append((0,0))
- ipo2.append((1,1))
- ipo2.recalc()
-
-
- if type == SHAPE3_INVT:
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((0,0))
- ipo.append((1,1))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((-1,1))
- ipo2.append((0,0))
- ipo2.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[2].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((0,0))
- ipo2.append((1,1))
- ipo2.recalc()
-
- if type == SHAPE3_T:
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- ipo.recalc()
- delCurve(ipo)
- ipo.append((-1,-1))
- ipo.append((0,0))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((-1,1))
- ipo2.append((0,0))
- ipo2.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[2].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- ipo2.recalc()
- delCurve(ipo2)
- ipo2.append((0,0))
- ipo2.append((1,1))
- ipo2.recalc()
-
- if type == SHAPE4_X:
- ctrl.protectFlags = int("111111010",2)
- ipo = verifyIpocurve(ky,shapes[0].val)
- ipo.driver = 1
- ipo.driverObject = ctrl
- ipo.driverChannel = IpoCurve.LOC_Z
- delCurve(ipo)
- ipo.append((0,0))
- ipo.append((1,1))
- ipo.recalc()
-
- ipo2 = verifyIpocurve(ky,shapes[1].val)
- ipo2.driver = 1
- ipo2.driverObject = ctrl
- ipo2.driverChannel = IpoCurve.LOC_X
- delCurve(ipo2)
- ipo2.append((0,0))
- ipo2.append((1,1))
- ipo2.recalc()
-
- ipo3 = verifyIpocurve(ky,shapes[2].val)
- ipo3.driver = 1
- ipo3.driverObject = ctrl
- ipo3.driverChannel = IpoCurve.LOC_X
- delCurve(ipo3)
- ipo3.append((-1,1))
- ipo3.append((0,0))
- ipo3.recalc()
-
- ipo4 = verifyIpocurve(ky,shapes[3].val)
- ipo4.driver = 1
- ipo4.driverObject = ctrl
- ipo4.driverChannel = IpoCurve.LOC_Z
- delCurve(ipo4)
- ipo4.append((-1,1))
- ipo4.append((0,0))
- ipo4.recalc()
-
-#The Main Call to Build the Widget
-
-def build(type):
- global shapes,widmenu,rangename
- sce = bpy.data.scenes.active
- ob = sce.objects.active
-
- try:
- ob.getData(mesh=1).key
- except:
- Blender.Draw.PupMenu('Aborting%t|Object has no keys')
- return
-
- loc = Window.GetCursorPos()
- range = makeRange(sce, type,rangename.val)
- controller = makeController(sce, rangename.val)
- text = makeText(sce, rangename.val)
-
- range.restrictRender = True
- controller.restrictRender = True
- text.restrictRender = True
-
- range.setLocation(loc)
- controller.setLocation(loc)
- text.setLocation(loc)
-
- range.makeParent([controller],1)
- range.makeParent([text],0)
-
- sce.update()
-
- setupDrivers(ob,controller,widmenu.val)
-
-#Create the text
-
-def makeText(sce, name):
- txt = bpy.data.curves.new(name+'.name', 'Text3d')
-
- txt.setDrawMode(Text3d.DRAW3D)
- txt.setAlignment(Text3d.MIDDLE)
- txt.setText(name)
- ob = sce.objects.new(txt)
- ob.setEuler((3.14159/2,0,0))
- return ob
-
-
-#Create the mesh controller
-
-def makeController(sce, name):
- me = bpy.data.meshes.new(name+".ctrl")
- ob = sce.objects.new(me)
- me.verts.extend([\
- (-0.15,0, 0),\
- ( 0,0, 0.15),\
- ( 0.15,0, 0),\
- ( 0,0,-0.15)])
-
- me.edges.extend([(0,1,2,3)])
- return ob
-
-#Create the mesh range
-
-def makeRange(sce,type,name):
- #ob.setDrawMode(8) # Draw Name
- me = bpy.data.meshes.new(name)
- ob = sce.objects.new(me)
-
- if type == SHAPE1_ONE_ZERO:
- me.verts.extend([\
- (-0.15,0,0),\
- ( 0.15,0,0),\
- (-0.15,0,1),\
- ( 0.15,0,1),\
- (-0.25,0,.1),\
- (-0.25,0,-.10),\
- (0.25,0,.1),\
- (0.25,0,-0.10)])
-
- me.edges.extend([(0,1,3,2),(4,5,0),(6,7,1)])
-
- elif type == SHAPE1_TOGGLE:
- me.verts.extend([\
- (-0.15,0,-0.5),\
- ( 0.15,0,-0.5),\
- ( 0.15,0, 0.5),\
- (-0.15,0, 0.5),\
- (-0.15,0, 1.5),\
- ( 0.15,0, 1.5)])
-
- me.edges.extend([(0,1,2,3),(3,4,5,2)])
-
- elif type == SHAPE1_ZERO_MONE:
- me.verts.extend([\
- (-0.15,0,0),\
- ( 0.15,0,0),\
- (-0.15,0,-1),\
- ( 0.15,0,-1),\
- (-0.25,0,.1),\
- (-0.25,0,-.10),\
- (0.25,0,.1),\
- (0.25,0,-0.10)])
-
- me.edges.extend([(0,1,3,2),(4,5,0),(6,7,1)])
-
- elif type in [SHAPE1_ONE_MONE,SHAPE2_EXCLUSIVE]:
- me.verts.extend([\
- (-0.15,0,-1),\
- ( 0.15,0,-1),\
- (-0.15,0,1),\
- ( 0.15,0,1),\
- (-0.25,0,.1),\
- (-0.25,0,-.10),\
- (0.25,0,.1),\
- (0.25,0,-0.10),\
- (-0.15,0,0),\
- ( 0.15,0,0)])
-
- l = [(0,1,3,2),(4,5,8),(6,7,9)]
- me.edges.extend(l)
-
- elif type == SHAPE2_T:
- me.verts.extend([\
- (-1,0,0),\
- ( 1,0,0),\
- ( 1,0,-1),\
- (-1,0,-1)])
-
- me.edges.extend([(0,1,2,3)])
-
- elif type == SHAPE2_INVT:
- me.verts.extend([\
- (-1,0,0),\
- ( 1,0,0),\
- ( 1,0,1),\
- (-1,0,1)])
-
- me.edges.extend([(0,1,2,3)])
-
- elif type == SHAPE2_PLUS:
- me.verts.extend([\
- (-1,0,-1),\
- ( 1,0,-1),\
- ( 1,0,1),\
- (-1,0,1)])
- me.edges.extend([(0,1,2,3)])
-
- elif type == SHAPE2_V:
- me.verts.extend([\
- (0,0,0),\
- (1,0,0),\
- (1,0,1),\
- (0,0,1)])
-
- me.edges.extend([(0,1,2,3)])
- ob.setEuler((0,-0.78539,0))
-
- elif type == SHAPE3_INVT:
- me.verts.extend([\
- (-1,0,0),\
- ( 1,0,0),\
- ( 1,0,1),\
- (-1,0,1)])
-
- me.edges.extend([(0,1,2,3)])
-
- elif type == SHAPE3_T:
- me.verts.extend([\
- (-1,0,0),\
- ( 1,0,0),\
- ( 1,0,-1),\
- (-1,0,-1)])
-
- me.edges.extend([(0,1,2,3)])
-
-
- elif type == SHAPE4_X:
- me.verts.extend([\
- (0,0,-1),\
- (1,0,-1),\
- (1,0,0),\
- (1,0,1),\
- (0,0,1),\
- (-1,0,1),\
- (-1,0,0),\
- (-1,0,-1)])
-
- me.edges.extend([(0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,0)])
- ob.setEuler((0,-0.78539,0))
-
- return ob
-
-
-def create():
- main()
-
-####################### gui ######################
-
-
-EVENT_NONE = 1
-EVENT_EXIT = 100
-EVENT_WIDGET_MENU = 101
-EVENT_NEXT = 102
-EVENT_BACK = 103
-
-#get the list of shapes from the selected object
-
-def shapeMenuText():
- ob = bpy.data.scenes.active.objects.active
- if not ob:
- return ""
-
- me = ob.getData(mesh=1)
- try: key= me.key
- except: key = None
-
- if key == None:
- return ""
-
- blocks = key.blocks
- menu = "Choose Shape %t|"
- for i, block in enumerate(blocks):
- menu = menu + block.name + " %x" + str(i) + "|"
- return menu
-
-
-#draw the widget for the gui
-
-def drawWidget(type):
- glColor3f(0.0,0.0,0.0)
- global shapes
- if type == SHAPE1_ONE_MONE:# 1 to -1 Single Shape
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,50)
- glVertex2i(170,50)
- glVertex2i(170,150)
- glVertex2i(150,150)
- glVertex2i(150,50)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,100)
- glVertex2i(190,100)
- glEnd()
- glRasterPos2d(180,140)
- Text("1","normal")
- glRasterPos2d(180,60)
- Text("-1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 190, 100, 100, 18, shapes[0].val, "Choose Shape.")
- elif type == SHAPE1_TOGGLE:# Toggle Single Shape
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,50)
- glVertex2i(170,50)
- glVertex2i(170,100)
- glVertex2i(150,100)
- glVertex2i(150,50)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(170,100)
- glVertex2i(170,150)
- glVertex2i(150,150)
- glVertex2i(150,100)
- glEnd()
- glRasterPos2d(180,140)
- Text("On","normal")
- glRasterPos2d(180,60)
- Text("Off","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 190, 100, 100, 18, shapes[0].val, "Choose Shape.")
- elif type == SHAPE1_ONE_ZERO: # 1 to 0 Single Shape
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,50)
- glVertex2i(170,50)
- glVertex2i(170,150)
- glVertex2i(150,150)
- glVertex2i(150,50)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,50)
- glVertex2i(190,50)
- glEnd()
- glRasterPos2d(180,140)
- Text("1","normal")
- glRasterPos2d(180,60)
- Text("0","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 190, 100, 100, 18, shapes[0].val, "Choose Shape.")
- elif type == SHAPE1_ZERO_MONE:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,50)
- glVertex2i(170,50)
- glVertex2i(170,150)
- glVertex2i(150,150)
- glVertex2i(150,50)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,150)
- glVertex2i(190,150)
- glEnd()
- glRasterPos2d(180,140)
- Text("0","normal")
- glRasterPos2d(180,60)
- Text("-1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 190, 100, 100, 18, shapes[0].val, "Choose Shape.")
- elif type == SHAPE2_EXCLUSIVE:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,50)
- glVertex2i(170,50)
- glVertex2i(170,150)
- glVertex2i(150,150)
- glVertex2i(150,50)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,100)
- glVertex2i(190,100)
- glEnd()
- glRasterPos2d(180,140)
- Text("1","normal")
- glRasterPos2d(180,60)
- Text("1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 195, 135, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 195, 52, 100, 18, shapes[1].val, "Choose Shape 2.")
- elif type == SHAPE2_T:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,75)
- glVertex2i(250,75)
- glVertex2i(250,125)
- glVertex2i(150,125)
- glVertex2i(150,75)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,125)
- glVertex2i(260,125)
- glEnd()
- glRasterPos2d(200,140)
- Text("0","normal")
- glRasterPos2d(200,60)
- Text("-1","normal")
- glRasterPos2d(250,140)
- Text("1","normal")
- glRasterPos2d(150,140)
- Text("-1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 220, 52, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 260, 135, 100, 18, shapes[1].val, "Choose Shape 2.")
- elif type == SHAPE2_INVT:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,75)
- glVertex2i(250,75)
- glVertex2i(250,125)
- glVertex2i(150,125)
- glVertex2i(150,75)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,75)
- glVertex2i(260,75)
- glEnd()
- glRasterPos2d(200,60)
- Text("0","normal")
- glRasterPos2d(200,140)
- Text("1","normal")
- glRasterPos2d(250,60)
- Text("1","normal")
- glRasterPos2d(150,60)
- Text("-1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 220, 135, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 260, 52, 100, 18, shapes[1].val, "Choose Shape 2.")
- elif type == SHAPE2_PLUS:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,50)
- glVertex2i(250,50)
- glVertex2i(250,150)
- glVertex2i(150,150)
- glVertex2i(150,50)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,100)
- glVertex2i(260,100)
- glEnd()
- glRasterPos2d(200,105)
- Text("0","normal")
- glRasterPos2d(200,140)
- Text("1","normal")
- glRasterPos2d(200,55)
- Text("-1","normal")
- glRasterPos2d(250,105)
- Text("1","normal")
- glRasterPos2d(150,105)
- Text("-1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 220, 155, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 260, 100, 100, 18, shapes[1].val, "Choose Shape 2.")
- elif type == SHAPE2_V:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,70)
- glVertex2i(185,105)
- glVertex2i(150,141)
- glVertex2i(115,105)
- glVertex2i(150,70)
- glEnd()
- glRasterPos2d(110,105)
- Text("1","normal")
- glRasterPos2d(190,105)
- Text("1","normal")
- glRasterPos2d(150,80)
- Text("0","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 20, 125, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 195, 125, 100, 18, shapes[1].val, "Choose Shape 2.")
-
-
-
- elif type == SHAPE3_T:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,75)
- glVertex2i(250,75)
- glVertex2i(250,125)
- glVertex2i(150,125)
- glVertex2i(150,75)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,125)
- glVertex2i(260,125)
- glEnd()
- glRasterPos2d(200,140)
- Text("0","normal")
- glRasterPos2d(200,60)
- Text("-1","normal")
- glRasterPos2d(250,140)
- Text("1","normal")
- glRasterPos2d(150,140)
- Text("1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 220, 52, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 45, 135, 100, 18, shapes[1].val, "Choose Shape 2.")
- shapes[2] = Menu(shapeMenuText(), EVENT_NONE, 260, 135, 100, 18, shapes[2].val, "Choose Shape 3.")
- elif type == SHAPE3_INVT:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,75)
- glVertex2i(250,75)
- glVertex2i(250,125)
- glVertex2i(150,125)
- glVertex2i(150,75)
- glEnd()
- glBegin(GL_LINE_STRIP)
- glVertex2i(140,75)
- glVertex2i(260,75)
- glEnd()
- glRasterPos2d(200,60)
- Text("0","normal")
- glRasterPos2d(200,140)
- Text("1","normal")
- glRasterPos2d(250,60)
- Text("1","normal")
- glRasterPos2d(150,60)
- Text("1","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 220, 135, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 45, 52, 100, 18, shapes[1].val, "Choose Shape 2.")
- shapes[2] = Menu(shapeMenuText(), EVENT_NONE, 260, 52, 100, 18, shapes[2].val, "Choose Shape 3.")
-
-
- elif type == SHAPE4_X:
- glBegin(GL_LINE_STRIP)
- glVertex2i(150,70)
- glVertex2i(185,105)
- glVertex2i(150,141)
- glVertex2i(115,105)
- glVertex2i(150,70)
- glEnd()
- glRasterPos2d(120,125)
- Text("1","normal")
- glRasterPos2d(180,125)
- Text("1","normal")
- glRasterPos2d(120,80)
- Text("1","normal")
- glRasterPos2d(180,80)
- Text("1","normal")
-
- glRasterPos2d(145,105)
- Text("0","normal")
- shapes[0] = Menu(shapeMenuText(), EVENT_NONE, 10, 125, 100, 18, shapes[0].val, "Choose Shape 1.")
- shapes[1] = Menu(shapeMenuText(), EVENT_NONE, 195, 125, 100, 18, shapes[1].val, "Choose Shape 2.")
- shapes[2] = Menu(shapeMenuText(), EVENT_NONE, 10, 60, 100, 18, shapes[2].val, "Choose Shape 3.")
- shapes[3] = Menu(shapeMenuText(), EVENT_NONE, 195, 60, 100, 18, shapes[3].val, "Choose Shape 4.")
-
-#the gui callback
-
-def draw():
- global widmenu,numshapes,stage,type, shapes,rangename
- #glRasterPos2d(5,200)
- #Text("Shape Widget Wizard","large")
- Label("Shape Widget Wizard", 5,200, 200, 12)
-
- PushButton("Quit", EVENT_EXIT, 5, 5, 50, 18)
-
- if stage == 1:
- name = "Choose Widget Type %t|\
-1 Shape: 1 / -1 %x" +str(SHAPE1_ONE_MONE) +"|\
-1 Shape: 1,0 %x" +str(SHAPE1_ONE_ZERO) +"|\
-1 Shape: 0,-1 %x" +str(SHAPE1_ZERO_MONE)+"|\
-1 Shape: Toggle %x" +str(SHAPE1_TOGGLE) +"|\
-2 Shape Exclusive %x"+str(SHAPE2_EXCLUSIVE)+"|\
-2 Shape - V %x" +str(SHAPE2_V) +"|\
-2 Shape - T %x" +str(SHAPE2_T) +"|\
-2 Shape - Inv T %x" +str(SHAPE2_INVT) +"|\
-2 Shape - + %x" +str(SHAPE2_PLUS) +"|\
-3 Shape - T %x" +str(SHAPE3_T) +"|\
-3 Shape - Inv T%x" +str(SHAPE3_INVT) +"|\
-4 Shape - Mix %x" +str(SHAPE4_X)
- widmenu = Menu(name, EVENT_NONE, 5, 120, 200, 40, widmenu.val, "Choose Widget Type.")
- PushButton("Next", EVENT_NEXT, 5, 25, 50, 18)
-
- elif stage == 2:
- glRasterPos2d(60,140)
- rangename = String("Name: ", EVENT_NONE, 5, 170, 200, 18, rangename.val, 50, "Name for Range Object")
- drawWidget(widmenu.val)
- BeginAlign()
- PushButton("Back", EVENT_BACK, 5, 25, 50, 18, "Choose another shape type")
- PushButton("Finish", EVENT_NEXT, 55, 25, 50, 18, "Add Objects at the cursor location")
- EndAlign()
- return
-
-
-
-def event(evt, val):
- if (evt == QKEY and not val):
- Exit()
-
-
-def bevent(evt):
- global widmenu,stage,drawtype
- ######### Manages GUI events
- if evt==EVENT_EXIT:
- Exit()
- elif evt==EVENT_BACK:
- if stage == 2:
- stage = 1
- Redraw()
- elif evt==EVENT_NEXT:
- if stage == 1:
- stage = 2
- Redraw()
- elif stage == 2:
- build(widmenu.val)
- stage = 1
- Window.RedrawAll()
-
-
-Register(draw, event, bevent)
diff --git a/release/scripts/wizard_bolt_factory.py b/release/scripts/wizard_bolt_factory.py
deleted file mode 100644
index 2d653b211d5..00000000000
--- a/release/scripts/wizard_bolt_factory.py
+++ /dev/null
@@ -1,2811 +0,0 @@
-#!BPY
-# -*- coding: latin-1 -*-
-"""
-Name: 'Bolt Factory'
-Blender: 248
-Group: 'Wizards'
-Tooltip: 'Create models of various types of screw fasteners.'
-"""
-
-__author__ = " Aaron Keith (Spudmn) "
-__version__ = "2.02 2009/06/10"
-__url__ = ["Author's site,http://sourceforge.net/projects/boltfactory/", "Blender,http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Misc/Bolt_Factory"]
-__bpydoc__ = """\
-Bolt_Factory.py
-
-Bolt Factory is a Python script for Blender 3D.
-
-The script allows the user to create models of various types of screw fasteners.
-
-For best results set the material to smooth and apply a Edge Split modifier
-with default settings.
-
-
-History:
- V2.02 10/06/09 by Aaron Keith
-
- -Added changes made by the Blender team.
-
- V2.01 26/05/09 by Aaron Keith
-
- - Fixed normal's on Lock Nut
-
-V2.00 22/05/09 by Aaron Keith
-
-- Better error checking.
-- Lock Nut and Hex Nut meshes added.
-- Pre-sets for common metric bolts and nuts.
-- Improved GUI.
-- Meshes scaled to a smaller size
-- Fixed bug when using crest and root percent other than 10%
-- Can now create meshes in Edit Mode. This will add to the
- current mesh and align with the current view.
-
-V1.00 01/04/08 by Aaron Keith
-
-- This version is very much a work in progress.
-- This is my first attempt to program in Python. This version is
- unpolished and doesn't do much error checking. Therefore
- if the user sets strange variable the model created will be
- as equally strange.
-
-- To Do:
-- Better error checking.
-- More Head and Bit types.
-- Better documentation.
-
-
-"""
-
-# --------------------------------------------------------------------------
-# Bolt_Factory.py
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Copyright (C) 2009: Aaron Keith
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-
-
-
-import Blender
-from Blender import Draw, BGL,Mesh
-from Blender import *
-from math import *
-from Blender import Mathutils
-from Blender.Mathutils import *
-
-
-#Global_Scale = 0.001 #1 blender unit = X mm
-Global_Scale = 0.1 #1 blender unit = X mm
-#Global_Scale = 1.0 #1 blender unit = X mm
-Global_NutRad = 0.0
-MAX_INPUT_NUMBER = 50
-
-No_Event,On_Preset_Click,On_Apply_Click,On_Create_Click,On_Hex_Click, On_Cap_Click,On_Dome_Click,On_Pan_Click,On_Bit_None_Click,On_Bit_Allen_Click,On_Bit_Philips_Click,On_Exit_Click,On_Model_Bolt_Click,On_Model_Nut_Click,On_Hex_Nut_Click,On_Lock_Nut_Click,On_Test_Click = range(17) # this is like a ENUM
-
-
-Head_Type={'HEX' : [Draw.Create(1),On_Hex_Click,""],
- 'CAP' : [Draw.Create(0),On_Cap_Click,""],
- 'DOME': [Draw.Create(0),On_Dome_Click,""],
- 'PAN' : [Draw.Create(0),On_Pan_Click,""]}
-
-
-Bit_Type={'NONE' : [Draw.Create(1),On_Bit_None_Click,""],
- 'ALLEN' : [Draw.Create(0),On_Bit_Allen_Click,""],
- 'PHILLIPS': [Draw.Create(0),On_Bit_Philips_Click,""]}
-
-Model_Type={'BOLT' : [Draw.Create(1),On_Model_Bolt_Click,"Bolt Settings"],
- 'NUT' : [Draw.Create(0),On_Model_Nut_Click,"Nut Settings"]}
-
-Nut_Type={'HEX' : [Draw.Create(1),On_Hex_Nut_Click,""],
- 'LOCK' : [Draw.Create(0),On_Lock_Nut_Click,""]}
-
-
-Phillips_Bit_Depth = Draw.Create(3.27)
-Philips_Bit_Dia = Draw.Create(5.20)
-
-Allen_Bit_Depth = Draw.Create(4.0)
-Allen_Bit_Flat_Distance = Draw.Create(6.0)
-
-Hex_Head_Height = Draw.Create(5.3)
-Hex_Head_Flat_Distance = Draw.Create(13.0)
-
-Cap_Head_Dia = Draw.Create(13.5)
-Cap_Head_Height = Draw.Create(8.0)
-
-Dome_Head_Dia = Draw.Create(16.0)
-
-Pan_Head_Dia = Draw.Create(16.0)
-
-Shank_Dia = Draw.Create(8.0)
-Shank_Length = Draw.Create(0.0)
-
-Thread_Length = Draw.Create(16.0)
-Major_Dia = Draw.Create(8.0)
-Minor_Dia = Draw.Create(6.917)
-Pitch = Draw.Create(1.0)
-Crest_Percent = Draw.Create(10)
-Root_Percent = Draw.Create(10)
-
-Hex_Nut_Height = Draw.Create(8.0)
-Hex_Nut_Flat_Distance = Draw.Create(13.0)
-
-Preset_Menu = Draw.Create(5)
-
-
-##########################################################################################
-##########################################################################################
-## Miscellaneous Utilities
-##########################################################################################
-##########################################################################################
-
-# Returns a list of verts rotated by the given matrix. Used by SpinDup
-def Rot_Mesh(verts,matrix):
- return [list(Vector(v) * matrix) for v in verts]
-
-# Returns a list of faces that has there index incremented by offset
-def Copy_Faces(faces,offset):
- ret = []
- for f in faces:
- fsub = []
- for i in range(len(f)):
- fsub.append(f[i]+ offset)
- ret.append(fsub)
- return ret
-
-
-# Much like Blenders built in SpinDup.
-def SpinDup(VERTS,FACES,DEGREE,DIVISIONS,AXIS):
- verts=[]
- faces=[]
-
- if DIVISIONS == 0:
- DIVISIONS = 1
-
- step = DEGREE/DIVISIONS # set step so pieces * step = degrees in arc
-
- for i in xrange(int(DIVISIONS)):
- rotmat = Mathutils.RotationMatrix(step*i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis.
- Rot = Rot_Mesh(VERTS,rotmat)
- faces.extend(Copy_Faces(FACES,len(verts)))
- verts.extend(Rot)
- return verts,faces
-
-
-# Returns a list of verts that have been moved up the z axis by DISTANCE
-def Move_Verts_Up_Z(VERTS,DISTANCE):
- return [[v[0],v[1],v[2]+DISTANCE] for v in VERTS]
-
-
-# Returns a list of verts and faces that has been mirrored in the AXIS
-def Mirror_Verts_Faces(VERTS,FACES,AXIS,FLIP_POINT =0):
- ret_vert = []
- ret_face = []
- offset = len(VERTS)
- if AXIS == 'y':
- for v in VERTS:
- Delta = v[0] - FLIP_POINT
- ret_vert.append([FLIP_POINT-Delta,v[1],v[2]])
- if AXIS == 'x':
- for v in VERTS:
- Delta = v[1] - FLIP_POINT
- ret_vert.append([v[0],FLIP_POINT-Delta,v[2]])
- if AXIS == 'z':
- for v in VERTS:
- Delta = v[2] - FLIP_POINT
- ret_vert.append([v[0],v[1],FLIP_POINT-Delta])
-
- for f in FACES:
- fsub = []
- for i in range(len(f)):
- fsub.append(f[i]+ offset)
- fsub.reverse() # flip the order to make norm point out
- ret_face.append(fsub)
-
- return ret_vert,ret_face
-
-
-
-# Returns a list of faces that
-# make up an array of 4 point polygon.
-def Build_Face_List_Quads(OFFSET,COLUM,ROW,FLIP = 0):
- Ret =[]
- RowStart = 0;
- for j in range(ROW):
- for i in range(COLUM):
- Res1 = RowStart + i;
- Res2 = RowStart + i + (COLUM +1)
- Res3 = RowStart + i + (COLUM +1) +1
- Res4 = RowStart+i+1
- if FLIP:
- Ret.append([OFFSET+Res1,OFFSET+Res2,OFFSET+Res3,OFFSET+Res4])
- else:
- Ret.append([OFFSET+Res4,OFFSET+Res3,OFFSET+Res2,OFFSET+Res1])
- RowStart += COLUM+1
- return Ret
-
-
-# Returns a list of faces that makes up a fill pattern for a
-# circle
-def Fill_Ring_Face(OFFSET,NUM,FACE_DOWN = 0):
- Ret =[]
- Face = [1,2,0]
- TempFace = [0,0,0]
- A = 0
- B = 1
- C = 2
- if NUM < 3:
- return None
- for i in range(NUM-2):
- if (i%2):
- TempFace[0] = Face[C];
- TempFace[1] = Face[C] + 1;
- TempFace[2] = Face[B];
- if FACE_DOWN:
- Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]])
- else:
- Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]])
- else:
- TempFace[0] =Face[C];
- if Face[C] == 0:
- TempFace[1] = NUM-1;
- else:
- TempFace[1] = Face[C] - 1;
- TempFace[2] = Face[B];
- if FACE_DOWN:
- Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]])
- else:
- Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]])
-
- Face[0] = TempFace[0]
- Face[1] = TempFace[1]
- Face[2] = TempFace[2]
- return Ret
-
-
-##########################################################################################
-##########################################################################################
-## Converter Functions For Bolt Factory
-##########################################################################################
-##########################################################################################
-
-
-def Flat_To_Radius(FLAT):
- h = (float(FLAT)/2)/cos(radians(30))
- return h
-
-def Get_Phillips_Bit_Height(Bit_Dia):
- Flat_Width_half = (Bit_Dia*(0.5/1.82))/2.0
- Bit_Rad = Bit_Dia / 2.0
- x = Bit_Rad - Flat_Width_half
- y = tan(radians(60))*x
- return y
-
-##########################################################################################
-##########################################################################################
-## Error Checking
-##########################################################################################
-##########################################################################################
-
-
-def Error_Check():
-
- #global Phillips_Bit_Depth
- #global Philips_Bit_Dia
-
- #global Allen_Bit_Depth
- #global Allen_Bit_Flat_Distance
-
- #global Hex_Head_Height
- #global Hex_Head_Flat_Distance
-
- #global Cap_Head_Dia
- #global Cap_Head_Height
-
-
- #global Dome_Head_Dia
-
- #global Pan_Head_Dia
-
- #global Shank_Dia
- #global Shank_Length
-
- global Thread_Length
- global Major_Dia
- global Minor_Dia
- global Pitch
- global Hex_Nut_Flat_Distance
- global Model_Type
- #global Crest_Percent
- #global Root_Percent
-
- Error_Result = 0
-
- if Minor_Dia.val >= Major_Dia.val:
- error_txt = "Error%t|Major Dia must be larger than Minor Dia"
- Blender.Draw.PupMenu(error_txt)
- print error_txt
- Error_Result = TRUE
-
- elif (Model_Type['BOLT'][0].val) and ((Pitch.val*7.0) > Thread_Length.val):
- error_txt = "Error%t|Thread length must be at least 7 times the Pitch"
- Blender.Draw.PupMenu(error_txt)
- print error_txt
- Error_Result = TRUE
-
- elif (Model_Type['NUT'][0].val) and (Hex_Nut_Flat_Distance.val < Major_Dia.val):
- error_txt = "Error%t|Nut Flat Distance must be greater than Major Dia"
- Blender.Draw.PupMenu(error_txt)
- print error_txt
- Error_Result = TRUE
-
- elif (Model_Type['NUT'][0].val) and ((Pitch.val * 2.5 )> Hex_Nut_Height.val):
- error_txt = "Error%t|Nut Height must be greater than 2.5 * Pitch"
- Blender.Draw.PupMenu(error_txt)
- print error_txt
- Error_Result = TRUE
-
- elif (Model_Type['BOLT'][0].val):
- Check_Head_Height = None
- Check_Bit_Height = None
- if (Bit_Type['ALLEN'][0].val):
- Check_Bit_Height = Allen_Bit_Depth.val
- if (Bit_Type['PHILLIPS'][0].val):
- Check_Bit_Height = Phillips_Bit_Depth.val
- if (Head_Type['HEX'][0].val):
- Check_Head_Height = Hex_Head_Height.val
- if (Head_Type['CAP'][0].val):
- Check_Head_Height = Cap_Head_Height.val
-
- if Check_Head_Height != None and Check_Bit_Height != None :
- if Check_Bit_Height > Check_Head_Height:
- error_txt = "Error%t|Bit Depth must not be greater that Head Height"
- Blender.Draw.PupMenu(error_txt)
- print error_txt
- Error_Result = TRUE
-
-
- return Error_Result
-
-
-
-##########################################################################################
-##########################################################################################
-## Create Allen Bit
-##########################################################################################
-##########################################################################################
-
-
-def Allen_Fill(OFFSET,FLIP= 0):
- faces = []
- Lookup = [[19,1,0],
- [19,2,1],
- [19,3,2],
- [19,20,3],
- [20,4,3],
- [20,5,4],
- [20,6,5],
- [20,7,6],
- [20,8,7],
- [20,9,8],
-
- [20,21,9],
-
- [21,10,9],
- [21,11,10],
- [21,12,11],
- [21,13,12],
- [21,14,13],
- [21,15,14],
-
- [21,22,15],
- [22,16,15],
- [22,17,16],
- [22,18,17]
- ]
- for i in Lookup:
- if FLIP:
- faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]])
- else:
- faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2]])
-
- return faces
-
-def Allen_Bit_Dia(FLAT_DISTANCE):
- Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30))
- return (Flat_Radius * 1.05) * 2.0
-
-def Allen_Bit_Dia_To_Flat(DIA):
- Flat_Radius = (DIA/2.0)/1.05
- return (Flat_Radius * cos (radians(30)))* 2.0
-
-
-
-def Create_Allen_Bit(FLAT_DISTANCE,HEIGHT):
- Div = 36
- verts = []
- faces = []
-
- Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30))
- OUTTER_RADIUS = Flat_Radius * 1.05
- Outter_Radius_Height = Flat_Radius * (0.1/5.77)
- FaceStart_Outside = len(verts)
- Deg_Step = 360.0 /float(Div)
-
- for i in range((Div/2)+1): # only do half and mirror later
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,0])
-
- FaceStart_Inside = len(verts)
-
- Deg_Step = 360.0 /float(6)
- for i in range((6/2)+1):
- x = sin(radians(i*Deg_Step))* Flat_Radius
- y = cos(radians(i*Deg_Step))* Flat_Radius
- verts.append([x,y,0-Outter_Radius_Height])
-
- faces.extend(Allen_Fill(FaceStart_Outside,0))
-
-
- FaceStart_Bottom = len(verts)
-
- Deg_Step = 360.0 /float(6)
- for i in range((6/2)+1):
- x = sin(radians(i*Deg_Step))* Flat_Radius
- y = cos(radians(i*Deg_Step))* Flat_Radius
- verts.append([x,y,0-HEIGHT])
-
- faces.extend(Build_Face_List_Quads(FaceStart_Inside,3,1,TRUE))
- faces.extend(Fill_Ring_Face(FaceStart_Bottom,4))
-
-
- M_Verts,M_Faces = Mirror_Verts_Faces(verts,faces,'y')
- verts.extend(M_Verts)
- faces.extend(M_Faces)
-
- return verts,faces,OUTTER_RADIUS * 2.0
-
-
-##########################################################################################
-##########################################################################################
-## Create Phillips Bit
-##########################################################################################
-##########################################################################################
-
-
-def Phillips_Fill(OFFSET,FLIP= 0):
- faces = []
- Lookup = [[0,1,10],
- [1,11,10],
- [1,2,11],
- [2,12,11],
-
- [2,3,12],
- [3,4,12],
- [4,5,12],
- [5,6,12],
- [6,7,12],
-
- [7,13,12],
- [7,8,13],
- [8,14,13],
- [8,9,14],
-
-
- [10,11,16,15],
- [11,12,16],
- [12,13,16],
- [13,14,17,16],
- [15,16,17,18]
-
-
- ]
- for i in Lookup:
- if FLIP:
- if len(i) == 3:
- faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]])
- else:
- faces.append([OFFSET+i[3],OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]])
- else:
- if len(i) == 3:
- faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2]])
- else:
- faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2],OFFSET+i[3]])
- return faces
-
-
-
-def Create_Phillips_Bit(FLAT_DIA,FLAT_WIDTH,HEIGHT):
- Div = 36
- verts = []
- faces = []
-
- FLAT_RADIUS = FLAT_DIA * 0.5
- OUTTER_RADIUS = FLAT_RADIUS * 1.05
-
- Flat_Half = float(FLAT_WIDTH)/2.0
-
- FaceStart_Outside = len(verts)
- Deg_Step = 360.0 /float(Div)
- for i in range((Div/4)+1): # only do half and mirror later
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,0])
-
-
- FaceStart_Inside = len(verts)
- verts.append([0,FLAT_RADIUS,0]) #10
- verts.append([Flat_Half,FLAT_RADIUS,0]) #11
- verts.append([Flat_Half,Flat_Half,0]) #12
- verts.append([FLAT_RADIUS,Flat_Half,0]) #13
- verts.append([FLAT_RADIUS,0,0]) #14
-
-
- verts.append([0,Flat_Half,0-HEIGHT]) #15
- verts.append([Flat_Half,Flat_Half,0-HEIGHT]) #16
- verts.append([Flat_Half,0,0-HEIGHT]) #17
-
- verts.append([0,0,0-HEIGHT]) #18
-
- faces.extend(Phillips_Fill(FaceStart_Outside,TRUE))
-
- Spin_Verts,Spin_Face = SpinDup(verts,faces,360,4,'z')
-
- return Spin_Verts,Spin_Face,OUTTER_RADIUS * 2
-
-
-##########################################################################################
-##########################################################################################
-## Create Head Types
-##########################################################################################
-##########################################################################################
-
-def Max_Pan_Bit_Dia(HEAD_DIA):
- HEAD_RADIUS = HEAD_DIA * 0.5
- XRad = HEAD_RADIUS * 1.976
- return (sin(radians(10))*XRad) * 2.0
-
-
-def Create_Pan_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET):
-
- DIV = 36
- HOLE_RADIUS = HOLE_DIA * 0.5
- HEAD_RADIUS = HEAD_DIA * 0.5
- SHANK_RADIUS = SHANK_DIA * 0.5
-
- verts = []
- faces = []
- Row = 0
- BEVEL = HEIGHT * 0.01
- #Dome_Rad = HEAD_RADIUS * (1.0/1.75)
-
- Dome_Rad = HEAD_RADIUS * 1.12
- RAD_Offset = HEAD_RADIUS * 0.96
- OtherRad = HEAD_RADIUS * 0.16
- OtherRad_X_Offset = HEAD_RADIUS * 0.84
- OtherRad_Z_Offset = HEAD_RADIUS * 0.504
- XRad = HEAD_RADIUS * 1.976
- ZRad = HEAD_RADIUS * 1.768
- EndRad = HEAD_RADIUS * 0.284
- EndZOffset = HEAD_RADIUS * 0.432
- HEIGHT = HEAD_RADIUS * 0.59
-
-# Dome_Rad = 5.6
-# RAD_Offset = 4.9
-# OtherRad = 0.8
-# OtherRad_X_Offset = 4.2
-# OtherRad_Z_Offset = 2.52
-# XRad = 9.88
-# ZRad = 8.84
-# EndRad = 1.42
-# EndZOffset = 2.16
-# HEIGHT = 2.95
-
- FaceStart = FACE_OFFSET
-
- z = cos(radians(10))*ZRad
- verts.append([HOLE_RADIUS,0.0,(0.0-ZRad)+z])
- Start_Height = 0 - ((0.0-ZRad)+z)
- Row += 1
-
- #for i in range(0,30,10): was 0 to 30 more work needed to make this look good.
- for i in range(10,30,10):
- x = sin(radians(i))*XRad
- z = cos(radians(i))*ZRad
- verts.append([x,0.0,(0.0-ZRad)+z])
- Row += 1
-
- for i in range(20,140,10):
- x = sin(radians(i))*EndRad
- z = cos(radians(i))*EndRad
- if ((0.0 - EndZOffset)+z) < (0.0-HEIGHT):
- verts.append([(HEAD_RADIUS -EndRad)+x,0.0,0.0 - HEIGHT])
- else:
- verts.append([(HEAD_RADIUS -EndRad)+x,0.0,(0.0 - EndZOffset)+z])
- Row += 1
-
-
- verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)])
- Row += 1
-
- verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)-Start_Height])
- Row += 1
-
-
- sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z')
- sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop
-
- faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV))
-
- Global_Head_Height = HEIGHT ;
-
-
- return Move_Verts_Up_Z(sVerts,Start_Height),faces,HEIGHT
-
-
-
-def Create_Dome_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET):
- DIV = 36
- HOLE_RADIUS = HOLE_DIA * 0.5
- HEAD_RADIUS = HEAD_DIA * 0.5
- SHANK_RADIUS = SHANK_DIA * 0.5
-
- verts = []
- faces = []
- Row = 0
- BEVEL = HEIGHT * 0.01
- #Dome_Rad = HEAD_RADIUS * (1.0/1.75)
-
- Dome_Rad = HEAD_RADIUS * 1.12
- #Head_Height = HEAD_RADIUS * 0.78
- RAD_Offset = HEAD_RADIUS * 0.98
- Dome_Height = HEAD_RADIUS * 0.64
- OtherRad = HEAD_RADIUS * 0.16
- OtherRad_X_Offset = HEAD_RADIUS * 0.84
- OtherRad_Z_Offset = HEAD_RADIUS * 0.504
-
-
-# Dome_Rad = 5.6
-# RAD_Offset = 4.9
-# Dome_Height = 3.2
-# OtherRad = 0.8
-# OtherRad_X_Offset = 4.2
-# OtherRad_Z_Offset = 2.52
-#
-
- FaceStart = FACE_OFFSET
-
- verts.append([HOLE_RADIUS,0.0,0.0])
- Row += 1
-
-
- for i in range(0,60,10):
- x = sin(radians(i))*Dome_Rad
- z = cos(radians(i))*Dome_Rad
- if ((0.0-RAD_Offset)+z) <= 0:
- verts.append([x,0.0,(0.0-RAD_Offset)+z])
- Row += 1
-
-
- for i in range(60,160,10):
- x = sin(radians(i))*OtherRad
- z = cos(radians(i))*OtherRad
- z = (0.0-OtherRad_Z_Offset)+z
- if z < (0.0-Dome_Height):
- z = (0.0-Dome_Height)
- verts.append([OtherRad_X_Offset+x,0.0,z])
- Row += 1
-
- verts.append([SHANK_RADIUS,0.0,(0.0-Dome_Height)])
- Row += 1
-
-
- sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z')
- sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop
-
- faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV))
-
- return sVerts,faces,Dome_Height
-
-
-
-def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2):
- DIV = 36
-
- HOLE_RADIUS = HOLE_DIA * 0.5
- HEAD_RADIUS = HEAD_DIA * 0.5
- SHANK_RADIUS = SHANK_DIA * 0.5
-
- verts = []
- faces = []
- Row = 0
- BEVEL = HEIGHT * 0.01
-
-
- FaceStart = len(verts)
-
- verts.append([HOLE_RADIUS,0.0,0.0])
- Row += 1
-
- #rad
-
- for i in range(0,100,10):
- x = sin(radians(i))*RAD1
- z = cos(radians(i))*RAD1
- verts.append([(HEAD_RADIUS-RAD1)+x,0.0,(0.0-RAD1)+z])
- Row += 1
-
-
- verts.append([HEAD_RADIUS,0.0,0.0-HEIGHT+BEVEL])
- Row += 1
-
- verts.append([HEAD_RADIUS-BEVEL,0.0,0.0-HEIGHT])
- Row += 1
-
- #rad2
-
- for i in range(0,100,10):
- x = sin(radians(i))*RAD2
- z = cos(radians(i))*RAD2
- verts.append([(SHANK_RADIUS+RAD2)-x,0.0,(0.0-HEIGHT-RAD2)+z])
- Row += 1
-
-
- sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z')
- sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop
-
-
- faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV))
-
- return sVerts,faces,HEIGHT+RAD2
-
-
-
-def Create_Hex_Head(FLAT,HOLE_DIA,SHANK_DIA,HEIGHT):
-
- verts = []
- faces = []
- HOLE_RADIUS = HOLE_DIA * 0.5
- Half_Flat = FLAT/2
- TopBevelRadius = Half_Flat - (Half_Flat* (0.05/8))
- Undercut_Height = (Half_Flat* (0.05/8))
- Shank_Bevel = (Half_Flat* (0.05/8))
- Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
- #Undercut_Height = 5
- SHANK_RADIUS = SHANK_DIA/2
- Row = 0;
-
- verts.append([0.0,0.0,0.0])
-
-
- FaceStart = len(verts)
- #inner hole
-
- x = sin(radians(0))*HOLE_RADIUS
- y = cos(radians(0))*HOLE_RADIUS
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/6))*HOLE_RADIUS
- y = cos(radians(60/6))*HOLE_RADIUS
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/3))*HOLE_RADIUS
- y = cos(radians(60/3))*HOLE_RADIUS
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/2))*HOLE_RADIUS
- y = cos(radians(60/2))*HOLE_RADIUS
- verts.append([x,y,0.0])
- Row += 1
-
- #bevel
-
- x = sin(radians(0))*TopBevelRadius
- y = cos(radians(0))*TopBevelRadius
- vec1 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/6))*TopBevelRadius
- y = cos(radians(60/6))*TopBevelRadius
- vec2 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/3))*TopBevelRadius
- y = cos(radians(60/3))*TopBevelRadius
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/2))*TopBevelRadius
- y = cos(radians(60/2))*TopBevelRadius
- vec4 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
- Row += 1
-
- #Flats
-
- x = tan(radians(0))*Half_Flat
- dvec = vec1 - Mathutils.Vector([x,Half_Flat,0.0])
- verts.append([x,Half_Flat,-dvec.length])
-
-
- x = tan(radians(60/6))*Half_Flat
- dvec = vec2 - Mathutils.Vector([x,Half_Flat,0.0])
- verts.append([x,Half_Flat,-dvec.length])
-
-
- x = tan(radians(60/3))*Half_Flat
- dvec = vec3 - Mathutils.Vector([x,Half_Flat,0.0])
- Lowest_Point = -dvec.length
- verts.append([x,Half_Flat,-dvec.length])
-
-
- x = tan(radians(60/2))*Half_Flat
- dvec = vec4 - Mathutils.Vector([x,Half_Flat,0.0])
- Lowest_Point = -dvec.length
- verts.append([x,Half_Flat,-dvec.length])
- Row += 1
-
- #down Bits Tri
- x = tan(radians(0))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
-
- x = tan(radians(60/6))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
-
- x = tan(radians(60/3))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
-
- x = tan(radians(60/2))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
- Row += 1
-
- #down Bits
-
- x = tan(radians(0))*Half_Flat
- verts.append([x,Half_Flat,-Flat_Height])
-
- x = tan(radians(60/6))*Half_Flat
- verts.append([x,Half_Flat,-Flat_Height])
-
- x = tan(radians(60/3))*Half_Flat
- verts.append([x,Half_Flat,-Flat_Height])
-
- x = tan(radians(60/2))*Half_Flat
- verts.append([x,Half_Flat,-Flat_Height])
- Row += 1
-
-
- #under cut
-
- x = sin(radians(0))*Half_Flat
- y = cos(radians(0))*Half_Flat
- vec1 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height])
-
- x = sin(radians(60/6))*Half_Flat
- y = cos(radians(60/6))*Half_Flat
- vec2 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height])
-
- x = sin(radians(60/3))*Half_Flat
- y = cos(radians(60/3))*Half_Flat
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height])
-
- x = sin(radians(60/2))*Half_Flat
- y = cos(radians(60/2))*Half_Flat
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height])
- Row += 1
-
- #under cut down bit
- x = sin(radians(0))*Half_Flat
- y = cos(radians(0))*Half_Flat
- vec1 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
-
- x = sin(radians(60/6))*Half_Flat
- y = cos(radians(60/6))*Half_Flat
- vec2 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
-
- x = sin(radians(60/3))*Half_Flat
- y = cos(radians(60/3))*Half_Flat
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
-
- x = sin(radians(60/2))*Half_Flat
- y = cos(radians(60/2))*Half_Flat
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
- Row += 1
-
- #under cut to Shank BEVEAL
- x = sin(radians(0))*(SHANK_RADIUS+Shank_Bevel)
- y = cos(radians(0))*(SHANK_RADIUS+Shank_Bevel)
- vec1 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
-
- x = sin(radians(60/6))*(SHANK_RADIUS+Shank_Bevel)
- y = cos(radians(60/6))*(SHANK_RADIUS+Shank_Bevel)
- vec2 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
-
- x = sin(radians(60/3))*(SHANK_RADIUS+Shank_Bevel)
- y = cos(radians(60/3))*(SHANK_RADIUS+Shank_Bevel)
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
-
- x = sin(radians(60/2))*(SHANK_RADIUS+Shank_Bevel)
- y = cos(radians(60/2))*(SHANK_RADIUS+Shank_Bevel)
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height])
- Row += 1
-
- #under cut to Shank BEVEAL
- x = sin(radians(0))*SHANK_RADIUS
- y = cos(radians(0))*SHANK_RADIUS
- vec1 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
-
- x = sin(radians(60/6))*SHANK_RADIUS
- y = cos(radians(60/6))*SHANK_RADIUS
- vec2 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
-
- x = sin(radians(60/3))*SHANK_RADIUS
- y = cos(radians(60/3))*SHANK_RADIUS
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
-
- x = sin(radians(60/2))*SHANK_RADIUS
- y = cos(radians(60/2))*SHANK_RADIUS
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
- Row += 1
-
-
- #Global_Head_Height = 0 - (-HEIGHT-0.1)
- faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1))
-
-
- Mirror_Verts,Mirror_Faces = Mirror_Verts_Faces(verts,faces,'y')
- verts.extend(Mirror_Verts)
- faces.extend(Mirror_Faces)
-
- Spin_Verts,Spin_Faces = SpinDup(verts,faces,360,6,'z')
-
- return Spin_Verts,Spin_Faces,0 - (-HEIGHT)
-
-
-##########################################################################################
-##########################################################################################
-## Create Bolt
-##########################################################################################
-##########################################################################################
-
-
-
-def MakeBolt():
- global Phillips_Bit_Depth
- global Philips_Bit_Dia
-
- global Allen_Bit_Depth
- global Allen_Bit_Flat_Distance
-
- global Hex_Head_Height
- global Hex_Head_Flat_Distance
-
- global Cap_Head_Dia
- global Cap_Head_Height
-
-
- global Dome_Head_Dia
-
- global Pan_Head_Dia
-
- global Shank_Dia
- global Shank_Length
-
- global Thread_Length
- global Major_Dia
- global Minor_Dia
- global Pitch
- global Crest_Percent
- global Root_Percent
-
- verts = []
- faces = []
- Bit_Verts = []
- Bit_Faces = []
- Bit_Dia = 0.001
- Head_Verts = []
- Head_Faces= []
- Head_Height = 0.0
- ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Flat_Distance.val # set default
-
-
- Head_Height = Hex_Head_Height.val # will be changed by the Head Functions
-
- if Bit_Type['ALLEN'][0].val and Head_Type['PAN'][0].val:
- #need to size Allen bit if it is too big.
- if Allen_Bit_Dia(Allen_Bit_Flat_Distance.val) > Max_Pan_Bit_Dia(Pan_Head_Dia.val):
- ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Dia_To_Flat(Max_Pan_Bit_Dia(Pan_Head_Dia.val)) * 1.05
- print "Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance
-
- #bit Mesh
- if Bit_Type['ALLEN'][0].val:
- Bit_Verts,Bit_Faces,Bit_Dia = Create_Allen_Bit(ReSized_Allen_Bit_Flat_Distance,Allen_Bit_Depth.val)
-
- if Bit_Type['PHILLIPS'][0].val:
- Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(Philips_Bit_Dia.val,Philips_Bit_Dia.val*(0.5/1.82),Phillips_Bit_Depth.val)
-
-
- #Head Mesh
- if Head_Type['HEX'][0].val:
- Head_Verts,Head_Faces,Head_Height = Create_Hex_Head(Hex_Head_Flat_Distance.val,Bit_Dia,Shank_Dia.val,Hex_Head_Height.val)
-
- elif Head_Type['CAP'][0].val:
- Head_Verts,Head_Faces,Head_Height = Create_Cap_Head(Bit_Dia,Cap_Head_Dia.val,Shank_Dia.val,Cap_Head_Height.val,Cap_Head_Dia.val*(1.0/19.0),Cap_Head_Dia.val*(1.0/19.0))
-
- elif Head_Type['DOME'][0].val:
- Head_Verts,Head_Faces,Head_Height = Create_Dome_Head(Bit_Dia,Dome_Head_Dia.val,Shank_Dia.val,Hex_Head_Height.val,1,1,0)
-
- elif Head_Type['PAN'][0].val:
- Head_Verts,Head_Faces,Head_Height = Create_Pan_Head(Bit_Dia,Pan_Head_Dia.val,Shank_Dia.val,Hex_Head_Height.val,1,1,0)
-
-
- Face_Start = len(verts)
- verts.extend(Move_Verts_Up_Z(Bit_Verts,Head_Height))
- faces.extend(Copy_Faces(Bit_Faces,Face_Start))
-
- Face_Start = len(verts)
- verts.extend(Move_Verts_Up_Z(Head_Verts,Head_Height))
- faces.extend(Copy_Faces(Head_Faces,Face_Start))
-
- Face_Start = len(verts)
- Thread_Verts,Thread_Faces,Thread_Height = Create_External_Thread(Shank_Dia.val,Shank_Length.val,Minor_Dia.val,Major_Dia.val,Pitch.val,Thread_Length.val,Crest_Percent.val,Root_Percent.val)
-
- verts.extend(Move_Verts_Up_Z(Thread_Verts,00))
- faces.extend(Copy_Faces(Thread_Faces,Face_Start))
-
- return Move_Verts_Up_Z(verts,Thread_Height),faces
-
-
-
-
-
-
-
-##########################################################################################
-##########################################################################################
-## Create Internal Thread
-##########################################################################################
-##########################################################################################
-
-
-def Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset):
-
-
- Ret_Row = 0;
-
- Height_Offset = Height_Offset + PITCH #Move the offset up so that the verts start at
- #at the correct place (Height_Start)
-
- Half_Pitch = float(PITCH)/2
- Height_Start = Height_Offset - PITCH
- Height_Step = float(PITCH)/float(DIV)
- Deg_Step = 360.0 /float(DIV)
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
-
- Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV)
- for j in range(1):
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z])
- Height_Offset -= Crest_Height
- Ret_Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z ])
- Height_Offset -= Crest_to_Root_Height
- Ret_Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- if j == 0:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- verts.append([x,y,z ])
- Height_Offset -= Root_Height
- Ret_Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
-
- if j == 0:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- verts.append([x,y,z ])
- Height_Offset -= Root_to_Crest_Height
- Ret_Row += 1
-
- return Ret_Row,Height_Offset
-
-
-def Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset):
-
-
- Ret_Row = 0;
-
- Half_Pitch = float(PITCH)/2
- #Height_End = Height_Offset - PITCH - PITCH - PITCH- PITCH - PITCH- PITCH
- Height_End = Height_Offset - PITCH
- #Height_End = -2.1
- Height_Step = float(PITCH)/float(DIV)
- Deg_Step = 360.0 /float(DIV)
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
-
-
- Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV)
-
- Num = 0
-
- for j in range(2):
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z < Height_End:
- z = Height_End
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z])
- Height_Offset -= Crest_Height
- Ret_Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z < Height_End:
- z = Height_End
-
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z ])
- Height_Offset -= Crest_to_Root_Height
- Ret_Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z < Height_End:
- z = Height_End
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- if j == Num:
- x = sin(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank))
- y = cos(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank))
- if j > Num:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS)
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS )
-
- verts.append([x,y,z ])
- Height_Offset -= Root_Height
- Ret_Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z < Height_End:
- z = Height_End
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
-
- if j == Num:
- x = sin(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank))
- y = cos(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank))
- if j > Num:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS )
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS )
-
- verts.append([x,y,z ])
- Height_Offset -= Root_to_Crest_Height
- Ret_Row += 1
-
-
- return Ret_Row,Height_End # send back Height End as this is the lowest point
-
-
-def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,INTERNAL = 1):
- verts = []
- faces = []
-
- DIV = 36
-
- INNER_RADIUS = INNER_DIA/2
- OUTTER_RADIUS = OUTTER_DIA/2
-
- Half_Pitch = float(PITCH)/2
- Deg_Step = 360.0 /float(DIV)
- Height_Step = float(PITCH)/float(DIV)
-
- Num = int(round((HEIGHT- PITCH)/PITCH)) # less one pitch for the start and end that is 1/2 pitch high
-
- Col = 0
- Row = 0
-
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
- Height_Offset = 0
- FaceStart = len(verts)
-
- Row_Inc,Height_Offset = Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset)
- Row += Row_Inc
-
- for j in range(Num):
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,Height_Offset - (Height_Step*i) ])
- Height_Offset -= Crest_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,Height_Offset - (Height_Step*i) ])
- Height_Offset -= Crest_to_Root_Height
- Row += 1
-
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- verts.append([x,y,Height_Offset - (Height_Step*i) ])
- Height_Offset -= Root_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- verts.append([x,y,Height_Offset - (Height_Step*i) ])
- Height_Offset -= Root_to_Crest_Height
- Row += 1
-
-
- Row_Inc,Height_Offset = Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset)
- Row += Row_Inc
-
- faces.extend(Build_Face_List_Quads(FaceStart,DIV,Row -1,INTERNAL))
-
- return verts,faces,0 - Height_Offset
-
-
-
-##########################################################################################
-##########################################################################################
-## Create External Thread
-##########################################################################################
-##########################################################################################
-
-
-
-def Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset):
-
-
- Ret_Row = 0;
-
- Half_Pitch = float(PITCH)/2
- Height_Start = Height_Offset - PITCH
- Height_Step = float(PITCH)/float(DIV)
- Deg_Step = 360.0 /float(DIV)
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
-#theard start
-
- Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV)
- for j in range(4):
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z])
- Height_Offset -= Crest_Height
- Ret_Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z ])
- Height_Offset -= Crest_to_Root_Height
- Ret_Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- if j == 0:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- verts.append([x,y,z ])
- Height_Offset -= Root_Height
- Ret_Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
-
- if j == 0:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- verts.append([x,y,z ])
- Height_Offset -= Root_to_Crest_Height
- Ret_Row += 1
-
- return Ret_Row,Height_Offset
-
-
-def Create_Shank_Verts(START_DIA,OUTTER_DIA,LENGTH,Z_LOCATION = 0):
-
- verts = []
- DIV = 36
-
- START_RADIUS = START_DIA/2
- OUTTER_RADIUS = OUTTER_DIA/2
-
- Opp = abs(START_RADIUS - OUTTER_RADIUS)
- Taper_Lentgh = Opp/tan(radians(31));
-
- if Taper_Lentgh > LENGTH:
- Taper_Lentgh = 0
-
- Stright_Length = LENGTH - Taper_Lentgh
-
- Deg_Step = 360.0 /float(DIV)
-
- Row = 0
-
- Lowest_Z_Vert = 0;
-
- Height_Offset = Z_LOCATION
-
-
- #ring
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*START_RADIUS
- y = cos(radians(i*Deg_Step))*START_RADIUS
- z = Height_Offset - 0
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Stright_Length
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*START_RADIUS
- y = cos(radians(i*Deg_Step))*START_RADIUS
- z = Height_Offset - 0
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Taper_Lentgh
- Row += 1
-
-
- return verts,Row,Height_Offset
-
-
-def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0):
-
- verts = []
- DIV = 36
-
- INNER_RADIUS = INNER_DIA/2
- OUTTER_RADIUS = OUTTER_DIA/2
-
- Half_Pitch = float(PITCH)/2
- Deg_Step = 360.0 /float(DIV)
- Height_Step = float(PITCH)/float(DIV)
-
- Row = 0
-
- Lowest_Z_Vert = 0;
-
- Height_Offset = Z_LOCATION
-
- Height_Start = Height_Offset
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
- Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV)
-
- Height_Offset = Z_LOCATION + PITCH
- Cut_off = Z_LOCATION
-
-
- for j in range(1):
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- z = Height_Offset - (Height_Step*i)
- if z > Cut_off : z = Cut_off
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- z = Height_Offset - (Height_Step*i)
- if z > Cut_off : z = Cut_off
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_to_Root_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- z = Height_Offset - (Height_Step*i)
- if z > Cut_off : z = Cut_off
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- z = Height_Offset - (Height_Step*i)
- if z > Cut_off : z = Cut_off
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_to_Crest_Height
- Row += 1
-
-
- for j in range(2):
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_Height
- Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- verts.append([x,y,z ])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_to_Root_Height
- Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- if j == 0:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- verts.append([x,y,z ])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_Height
- Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- if z > Height_Start:
- z = Height_Start
-
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
-
- if j == 0:
- x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank))
- verts.append([x,y,z ])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_to_Crest_Height
- Row += 1
-
-
- return verts,Row,Height_Offset
-
-
-
-def Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0):
- verts = []
-
- DIV = 36
-
- INNER_RADIUS = INNER_DIA/2
- OUTTER_RADIUS = OUTTER_DIA/2
-
- Half_Pitch = float(PITCH)/2
- Deg_Step = 360.0 /float(DIV)
- Height_Step = float(PITCH)/float(DIV)
-
- NUM_OF_START_THREADS = 4.0
- NUM_OF_END_THREADS = 3.0
- Num = int((HEIGHT- ((NUM_OF_START_THREADS*PITCH) + (NUM_OF_END_THREADS*PITCH) ))/PITCH)
- Row = 0
-
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
-
- Height_Offset = Z_LOCATION
-
- Lowest_Z_Vert = 0;
- FaceStart = len(verts)
-
-
- for j in range(Num):
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- z = Height_Offset - (Height_Step*i)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
- y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
- z = Height_Offset - (Height_Step*i)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_to_Root_Height
- Row += 1
-
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- z = Height_Offset - (Height_Step*i)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_Height
- Row += 1
-
- for i in range(DIV+1):
- x = sin(radians(i*Deg_Step))*INNER_RADIUS
- y = cos(radians(i*Deg_Step))*INNER_RADIUS
- z = Height_Offset - (Height_Step*i)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_to_Crest_Height
- Row += 1
-
- return verts,Row,Height_Offset
-
-
-
-def Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0):
- verts = []
-
- DIV = 36
-
- INNER_RADIUS = INNER_DIA/2
- OUTTER_RADIUS = OUTTER_DIA/2
-
- Half_Pitch = float(PITCH)/2
- Deg_Step = 360.0 /float(DIV)
- Height_Step = float(PITCH)/float(DIV)
-
- Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
- Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
- Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
-
- Col = 0
- Row = 0
-
- Height_Offset = Z_LOCATION
-
- Tapper_Height_Start = Height_Offset - PITCH - PITCH
-
- Max_Height = Tapper_Height_Start - PITCH
-
- Lowest_Z_Vert = 0;
-
- FaceStart = len(verts)
- for j in range(4):
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- z = max(z,Max_Height)
- Tapper_Radius = OUTTER_RADIUS
- if z < Tapper_Height_Start:
- Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
-
- x = sin(radians(i*Deg_Step))*(Tapper_Radius)
- y = cos(radians(i*Deg_Step))*(Tapper_Radius)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_Height
- Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- z = max(z,Max_Height)
- Tapper_Radius = OUTTER_RADIUS
- if z < Tapper_Height_Start:
- Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
-
- x = sin(radians(i*Deg_Step))*(Tapper_Radius)
- y = cos(radians(i*Deg_Step))*(Tapper_Radius)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Crest_to_Root_Height
- Row += 1
-
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- z = max(z,Max_Height)
- Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
- if Tapper_Radius > INNER_RADIUS:
- Tapper_Radius = INNER_RADIUS
-
- x = sin(radians(i*Deg_Step))*(Tapper_Radius)
- y = cos(radians(i*Deg_Step))*(Tapper_Radius)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_Height
- Row += 1
-
- for i in range(DIV+1):
- z = Height_Offset - (Height_Step*i)
- z = max(z,Max_Height)
- Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
- if Tapper_Radius > INNER_RADIUS:
- Tapper_Radius = INNER_RADIUS
-
- x = sin(radians(i*Deg_Step))*(Tapper_Radius)
- y = cos(radians(i*Deg_Step))*(Tapper_Radius)
- verts.append([x,y,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Height_Offset -= Root_to_Crest_Height
- Row += 1
-
- return verts,Row,Height_Offset,Lowest_Z_Vert
-
-
-
-
-def Create_External_Thread(SHANK_DIA,SHANK_LENGTH,INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT):
-
- verts = []
- faces = []
-
- DIV = 36
-
- Total_Row = 0
- Thread_Len = 0;
-
- Face_Start = len(verts)
- Offset = 0.0;
-
-
- Shank_Verts,Shank_Row,Offset = Create_Shank_Verts(SHANK_DIA,OUTTER_DIA,SHANK_LENGTH,Offset)
- Total_Row += Shank_Row
-
- Thread_Start_Verts,Thread_Start_Row,Offset = Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset)
- Total_Row += Thread_Start_Row
-
-
- Thread_Verts,Thread_Row,Offset = Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT,Offset)
- Total_Row += Thread_Row
-
-
- Thread_End_Verts,Thread_End_Row,Offset,Lowest_Z_Vert = Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset )
- Total_Row += Thread_End_Row
-
-
- verts.extend(Shank_Verts)
- verts.extend(Thread_Start_Verts)
- verts.extend(Thread_Verts)
- verts.extend(Thread_End_Verts)
-
- faces.extend(Build_Face_List_Quads(Face_Start,DIV,Total_Row -1,0))
- faces.extend(Fill_Ring_Face(len(verts)-DIV,DIV,1))
-
- return verts,faces,0.0 - Lowest_Z_Vert
-
-
-##########################################################################################
-##########################################################################################
-## Create Nut
-##########################################################################################
-##########################################################################################
-
-
-def add_Hex_Nut(FLAT,HOLE_DIA,HEIGHT):
- global Global_Head_Height
- global Global_NutRad
-
- verts = []
- faces = []
- HOLE_RADIUS = HOLE_DIA * 0.5
- Half_Flat = FLAT/2
- Half_Height = HEIGHT/2
- TopBevelRadius = Half_Flat - 0.05
-
- Global_NutRad = TopBevelRadius
-
- Row = 0;
- Lowest_Z_Vert = 0.0;
-
- verts.append([0.0,0.0,0.0])
-
-
- FaceStart = len(verts)
- #inner hole
-
- x = sin(radians(0))*HOLE_RADIUS
- y = cos(radians(0))*HOLE_RADIUS
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/6))*HOLE_RADIUS
- y = cos(radians(60/6))*HOLE_RADIUS
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/3))*HOLE_RADIUS
- y = cos(radians(60/3))*HOLE_RADIUS
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/2))*HOLE_RADIUS
- y = cos(radians(60/2))*HOLE_RADIUS
- verts.append([x,y,0.0])
- Row += 1
-
- #bevel
-
- x = sin(radians(0))*TopBevelRadius
- y = cos(radians(0))*TopBevelRadius
- vec1 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/6))*TopBevelRadius
- y = cos(radians(60/6))*TopBevelRadius
- vec2 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/3))*TopBevelRadius
- y = cos(radians(60/3))*TopBevelRadius
- vec3 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
-
-
- x = sin(radians(60/2))*TopBevelRadius
- y = cos(radians(60/2))*TopBevelRadius
- vec4 = Mathutils.Vector([x,y,0.0])
- verts.append([x,y,0.0])
- Row += 1
-
- #Flats
-
- x = tan(radians(0))*Half_Flat
- dvec = vec1 - Mathutils.Vector([x,Half_Flat,0.0])
- verts.append([x,Half_Flat,-dvec.length])
- Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length)
-
-
- x = tan(radians(60/6))*Half_Flat
- dvec = vec2 - Mathutils.Vector([x,Half_Flat,0.0])
- verts.append([x,Half_Flat,-dvec.length])
- Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length)
-
-
- x = tan(radians(60/3))*Half_Flat
- dvec = vec3 - Mathutils.Vector([x,Half_Flat,0.0])
- Lowest_Point = -dvec.length
- verts.append([x,Half_Flat,-dvec.length])
- Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length)
-
- x = tan(radians(60/2))*Half_Flat
- dvec = vec4 - Mathutils.Vector([x,Half_Flat,0.0])
- Lowest_Point = -dvec.length
- verts.append([x,Half_Flat,-dvec.length])
- Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length)
- Row += 1
-
- #down Bits Tri
- x = tan(radians(0))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
-
-
- x = tan(radians(60/6))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
-
- x = tan(radians(60/3))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
-
- x = tan(radians(60/2))*Half_Flat
- verts.append([x,Half_Flat,Lowest_Point])
- Lowest_Z_Vert = min(Lowest_Z_Vert,Lowest_Point)
- Row += 1
-
- #down Bits
-
- x = tan(radians(0))*Half_Flat
- verts.append([x,Half_Flat,-Half_Height])
-
- x = tan(radians(60/6))*Half_Flat
- verts.append([x,Half_Flat,-Half_Height])
-
- x = tan(radians(60/3))*Half_Flat
- verts.append([x,Half_Flat,-Half_Height])
-
- x = tan(radians(60/2))*Half_Flat
- verts.append([x,Half_Flat,-Half_Height])
- Lowest_Z_Vert = min(Lowest_Z_Vert,-Half_Height)
- Row += 1
-
-
-
-
- faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1))
-
-
- Global_Head_Height = HEIGHT
-
- Tvert,tface = Mirror_Verts_Faces(verts,faces,'z',Lowest_Z_Vert)
- verts.extend(Tvert)
- faces.extend(tface)
-
-
- Tvert,tface = Mirror_Verts_Faces(verts,faces,'y')
- verts.extend(Tvert)
- faces.extend(tface)
-
- S_verts,S_faces = SpinDup(verts,faces,360,6,'z')
- return S_verts,S_faces,TopBevelRadius
-
-
-def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0):
- DIV = 36
- verts = []
- faces = []
- Row = 0
-
- INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.25/4.75))
- EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75))
- RAD1 = (OUTSIDE_RADIUS * (0.5/4.75))
- OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75))
-
-
- FaceStart = len(verts)
-
- Start_Height = 0 - 3
- Height_Offset = Z_LOCATION
- Lowest_Z_Vert = 0
-
- x = INNER_HOLE
- z = (Height_Offset - OVER_ALL_HEIGTH) + EDGE_THICKNESS
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
- x = INNER_HOLE
- z = (Height_Offset - OVER_ALL_HEIGTH)
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
-
- for i in range(180,80,-10):
- x = sin(radians(i))*RAD1
- z = cos(radians(i))*RAD1
- verts.append([(OUTSIDE_RADIUS-RAD1)+x,0.0,((Height_Offset - OVER_ALL_HEIGTH)+RAD1)+z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
-
- x = OUTSIDE_RADIUS - 0
- z = Height_Offset
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
- sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z')
- sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop
-
- faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV,1))
-
- return Move_Verts_Up_Z(sVerts,0),faces,Lowest_Z_Vert
-
-
-
-def add_Nylon_Part(OUTSIDE_RADIUS,Z_LOCATION = 0):
- DIV = 36
- verts = []
- faces = []
- Row = 0
-
- INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75))
- EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75))
- RAD1 = (OUTSIDE_RADIUS * (0.5/4.75))
- OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75))
- PART_THICKNESS = OVER_ALL_HEIGTH - EDGE_THICKNESS
- PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5/4.75))
-
- FaceStart = len(verts)
-
- Start_Height = 0 - 3
- Height_Offset = Z_LOCATION
- Lowest_Z_Vert = 0
-
-
- x = INNER_HOLE + EDGE_THICKNESS
- z = Height_Offset
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
- x = PART_INNER_HOLE
- z = Height_Offset
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
- x = PART_INNER_HOLE
- z = Height_Offset - PART_THICKNESS
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
- x = INNER_HOLE + EDGE_THICKNESS
- z = Height_Offset - PART_THICKNESS
- verts.append([x,0.0,z])
- Lowest_Z_Vert = min(Lowest_Z_Vert,z)
- Row += 1
-
-
- sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z')
- sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop
-
- faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV,1))
-
- return sVerts,faces,0 - Lowest_Z_Vert
-
-
-
-def Nut_Mesh():
-
- verts = []
- faces = []
- Head_Verts = []
- Head_Faces= []
-
- Face_Start = len(verts)
- Thread_Verts,Thread_Faces,New_Nut_Height = Create_Internal_Thread(Minor_Dia.val,Major_Dia.val,Pitch.val,Hex_Nut_Height.val,Crest_Percent.val,Root_Percent.val,1)
- verts.extend(Thread_Verts)
- faces.extend(Copy_Faces(Thread_Faces,Face_Start))
-
- Face_Start = len(verts)
- Head_Verts,Head_Faces,Lock_Nut_Rad = add_Hex_Nut(Hex_Nut_Flat_Distance.val,Major_Dia.val,New_Nut_Height)
- verts.extend((Head_Verts))
- faces.extend(Copy_Faces(Head_Faces,Face_Start))
-
- LowZ = 0 - New_Nut_Height
-
- if Nut_Type['LOCK'][0].val:
- Face_Start = len(verts)
- Nylon_Head_Verts,Nylon_Head_faces,LowZ = add_Nylon_Head(Lock_Nut_Rad,0-New_Nut_Height)
- verts.extend((Nylon_Head_Verts))
- faces.extend(Copy_Faces(Nylon_Head_faces,Face_Start))
-
- Face_Start = len(verts)
- Nylon_Verts,Nylon_faces,Temp_LowZ = add_Nylon_Part(Lock_Nut_Rad,0-New_Nut_Height)
- verts.extend((Nylon_Verts))
- faces.extend(Copy_Faces(Nylon_faces,Face_Start))
-
-
- return Move_Verts_Up_Z(verts,0 - LowZ),faces
-
-
-
-##################################################################################################
-
-
-def Create_Nut():
-
- verts = []
- faces = []
-
-
- if Error_Check() :
- return
-
-
- verts, faces = Nut_Mesh()
- Add_Mesh_To_Scene('Nut', verts, faces)
-
-
-##################################################################################################
-
-
-def Create_Bolt():
- verts = []
- faces = []
-
-
- if Error_Check() :
- return
-
- verts, faces = MakeBolt()
- Add_Mesh_To_Scene('Bolt', verts, faces)
-
-
-
-def Remove_Doubles_From_Mesh(verts,faces):
- Ret_verts = []
- Ret_faces = []
-
- is_editmode = Window.EditMode() # Store edit mode state
- if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode.
-
- Temp_mesh = Mesh.New('MeshTemp') # create a new mesh
-
- Temp_mesh.verts.extend(verts) # add vertices to mesh
- Temp_mesh.faces.extend(faces) # add faces to the mesh (also adds edges)
-
- scn = Scene.GetCurrent() # link object to current scene
- Temp_Object = scn.objects.new(Temp_mesh, 'ObjectTemp')
-
- Temp_mesh.remDoubles(0.010)
- Temp_mesh.transform(Mathutils.Matrix([Global_Scale,0,0,0], [0,Global_Scale,0,0], [0,0,Global_Scale,0], [0,0,0, Global_Scale]))
- Ret_verts[:] = [v.co for v in Temp_mesh.verts]
- Ret_faces[:] = [ [v.index for v in f] for f in Temp_mesh.faces]
-
- #delete temp mesh
- scn.objects.unlink(Temp_Object)
- scn.update(0)
-
- if is_editmode: Window.EditMode(1)
- return Ret_verts,Ret_faces
-
-
-
-def Add_Mesh_To_Scene(name, verts, faces):
-
- scn = Scene.GetCurrent()
- if scn.lib: return
- ob_act = scn.objects.active
-
- is_editmode = Window.EditMode()
-
- cursor = Window.GetCursorPos()
- quat = None
-
- if is_editmode or Blender.Get('add_view_align'): # Aligning seems odd for editmode, but blender does it, oh well
- try: quat = Blender.Mathutils.Quaternion(Window.GetViewQuat())
- except: pass
-
-
- # Exist editmode for non mesh types
- if ob_act and ob_act.type != 'Mesh' and is_editmode:
- EditMode(0)
-
- # We are in mesh editmode
- if Window.EditMode():
- me = ob_act.getData(mesh=1)
-
- if me.multires:
- error_txt = 'Error%t|Unable to complete action with multires enabled'
- Blender.Draw.PupMenu(error_txt)
- print error_txt
- return
-
- #Don't want to remove doubles and scale the existing
- # mesh so we need to get the verts and the faces from
- # a mesh that has been scaled.
- verts,faces = Remove_Doubles_From_Mesh(verts, faces)
-
- # Add to existing mesh
- # must exit editmode to modify mesh
- Window.EditMode(0)
-
- me.sel = False
-
- vert_offset = len(me.verts)
- face_offset = len(me.faces)
-
-
- # transform the verts
- txmat = Blender.Mathutils.TranslationMatrix(Blender.Mathutils.Vector(cursor))
- if quat:
- mat = quat.toMatrix()
- mat.invert()
- mat.resize4x4()
- txmat = mat * txmat
-
- txmat = txmat * ob_act.matrixWorld.copy().invert()
-
-
- me.verts.extend(verts)
- # Transform the verts by the cursor and view rotation
- me.transform(txmat, selected_only=True)
-
- if vert_offset:
- me.faces.extend([[i+vert_offset for i in f] for f in faces])
- else:
- # Mesh with no data, unlikely
- me.faces.extend(faces)
- else:
-
- # Object mode add new
- me = Mesh.New(name)
- me.verts.extend(verts)
- me.faces.extend(faces)
-
-
- me.sel = True
-
- # Object creation and location
- scn.objects.selected = []
- ob_act = scn.objects.new(me, name)
-
- me.remDoubles(0.010)
- me.transform(Mathutils.Matrix([Global_Scale,0,0,0], [0,Global_Scale,0,0], [0,0,Global_Scale,0], [0,0,0, Global_Scale]))
-
- scn.objects.active = ob_act
-
- if quat:
- mat = quat.toMatrix()
- mat.invert()
- mat.resize4x4()
- ob_act.setMatrix(mat)
-
- ob_act.loc = cursor
-
- me.calcNormals()
-
- if is_editmode or Blender.Get('add_editmode'):
- Window.EditMode(1)
-
- Blender.Redraw(-1)#Redraw all
-
-##################################################################################################
-
-
-
-def Load_Preset():
-
- global Preset_Menu
- global Shank_Dia
- global Shank_Length
- global Thread_Length
- global Major_Dia
- global Minor_Dia
- global Pitch
- global Crest_Percent
- global Root_Percent
- global Allen_Bit_Flat_Distance
- global Allen_Bit_Depth
- global Head_Height
- global Hex_Head_Flat_Distance
- global Head_Dia
- global Dome_Head_Dia
- global Pan_Head_Dia
- global Philips_Bit_Dia
- global Phillips_Bit_Depth
- global Cap_Head_Height
-
- global Hex_Nut_Height
- global Hex_Nut_Flat_Distance
-
-
- if Preset_Menu.val == 1 : #M3
- Shank_Dia.val = 3.0
- #Pitch.val = 0.5 #Coarse
- Pitch.val = 0.35 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 3.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 5.5
- Hex_Head_Height.val = 2.0
- Cap_Head_Dia.val = 5.5
- Cap_Head_Height.val = 3.0
- Allen_Bit_Flat_Distance.val = 2.5
- Allen_Bit_Depth.val = 1.5
- Pan_Head_Dia.val = 5.6
- Dome_Head_Dia.val = 5.6
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 2.4
- Hex_Nut_Flat_Distance.val = 5.5
- Thread_Length.val = 6
- Shank_Length.val = 0.0
-
-
- if Preset_Menu.val == 2 : #M4
- Shank_Dia.val = 4.0
- #Pitch.val = 0.7 #Coarse
- Pitch.val = 0.5 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 4.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 7.0
- Hex_Head_Height.val = 2.8
- Cap_Head_Dia.val = 7.0
- Cap_Head_Height.val = 4.0
- Allen_Bit_Flat_Distance.val = 3.0
- Allen_Bit_Depth.val = 2.0
- Pan_Head_Dia.val = 8.0
- Dome_Head_Dia.val = 8.0
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 3.2
- Hex_Nut_Flat_Distance.val = 7.0
- Thread_Length.val = 8
- Shank_Length.val = 0.0
-
-
- if Preset_Menu.val == 3 : #M5
- Shank_Dia.val = 5.0
- #Pitch.val = 0.8 #Coarse
- Pitch.val = 0.5 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 5.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 8.0
- Hex_Head_Height.val = 3.5
- Cap_Head_Dia.val = 8.5
- Cap_Head_Height.val = 5.0
- Allen_Bit_Flat_Distance.val = 4.0
- Allen_Bit_Depth.val = 2.5
- Pan_Head_Dia.val = 9.5
- Dome_Head_Dia.val = 9.5
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 4.0
- Hex_Nut_Flat_Distance.val = 8.0
- Thread_Length.val = 10
- Shank_Length.val = 0.0
-
-
- if Preset_Menu.val == 4 : #M6
- Shank_Dia.val = 6.0
- #Pitch.val = 1.0 #Coarse
- Pitch.val = 0.75 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 6.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 10.0
- Hex_Head_Height.val = 4.0
- Cap_Head_Dia.val = 10.0
- Cap_Head_Height.val = 6.0
- Allen_Bit_Flat_Distance.val = 5.0
- Allen_Bit_Depth.val = 3.0
- Pan_Head_Dia.val = 12.0
- Dome_Head_Dia.val = 12.0
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 5.0
- Hex_Nut_Flat_Distance.val = 10.0
- Thread_Length.val = 12
- Shank_Length.val = 0.0
-
-
- if Preset_Menu.val == 5 : #M8
- Shank_Dia.val = 8.0
- #Pitch.val = 1.25 #Coarse
- Pitch.val = 1.00 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 8.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 13.0
- Hex_Head_Height.val = 5.3
- Cap_Head_Dia.val = 13.5
- Cap_Head_Height.val = 8.0
- Allen_Bit_Flat_Distance.val = 6.0
- Allen_Bit_Depth.val = 4.0
- Pan_Head_Dia.val = 16.0
- Dome_Head_Dia.val = 16.0
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 6.5
- Hex_Nut_Flat_Distance.val = 13.0
- Thread_Length.val = 16
- Shank_Length.val = 0.0
-
- if Preset_Menu.val == 6 : #M10
- Shank_Dia.val = 10.0
- #Pitch.val = 1.5 #Coarse
- Pitch.val = 1.25 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 10.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 17.0
- Hex_Head_Height.val = 6.4
- Cap_Head_Dia.val = 16.0
- Cap_Head_Height.val = 10.0
- Allen_Bit_Flat_Distance.val = 8.0
- Allen_Bit_Depth.val = 5.0
- Pan_Head_Dia.val = 20.0
- Dome_Head_Dia.val = 20.0
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 8.0
- Hex_Nut_Flat_Distance.val = 17.0
- Thread_Length.val = 20
- Shank_Length.val = 0.0
-
-
- if Preset_Menu.val == 7 : #M12
- #Pitch.val = 1.75 #Coarse
- Pitch.val = 1.50 #Fine
- Crest_Percent.val = 10
- Root_Percent.val = 10
- Major_Dia.val = 12.0
- Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val)
- Hex_Head_Flat_Distance.val = 19.0
- Hex_Head_Height.val = 7.5
- Cap_Head_Dia.val = 18.5
- Cap_Head_Height.val = 12.0
- Allen_Bit_Flat_Distance.val = 10.0
- Allen_Bit_Depth.val = 6.0
- Pan_Head_Dia.val = 24.0
- Dome_Head_Dia.val = 24.0
- Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6)
- Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val)
- Hex_Nut_Height.val = 10.0
- Hex_Nut_Flat_Distance.val = 19.0
- Shank_Dia.val = 12.0
- Shank_Length.val = 33.0
- Thread_Length.val = 32.0
-
-##############################################################################################
-
-def Test():
- verts = []
- faces = []
-
- if Error_Check() :
- return
-
- verts, faces = MakeBolt()
-
- Add_Mesh_To_Scene("TestBolt", verts,faces)
-
- Window.Redraw(-1)
-
-
-
-
-def event(evt, val): # the function to handle input events
-
- if evt == Draw.ESCKEY:
- Draw.Exit() # exit when user presses ESC
- return
-
-
-def button_event(evt): # the function to handle Draw Button events
-
- if evt == On_Exit_Click:
- Draw.Exit() # exit when user presses ESC
- return
-
- if evt == On_Test_Click:
- Test()
- Draw.Redraw(1)
-
- if evt == On_Preset_Click:
- Load_Preset()
- Draw.Redraw(1)
-
- if evt == On_Create_Click:
- if Model_Type['BOLT'][0].val:
- Create_Bolt()
- if Model_Type['NUT'][0].val:
- Create_Nut()
- Draw.Redraw(1)
-
- elif (evt in [On_Hex_Click, On_Cap_Click,On_Dome_Click,On_Pan_Click]):
- for k in Head_Type.iterkeys():
- if Head_Type[k][1]!=evt:
- Head_Type[k][0].val=0
- else:
- Head_Type[k][0].val=1
- Draw.Redraw(1)
-
- elif (evt in [On_Bit_None_Click,On_Bit_Allen_Click,On_Bit_Philips_Click]):
- for k in Bit_Type.iterkeys():
- if Bit_Type[k][1]!=evt:
- Bit_Type[k][0].val=0
- else:
- Bit_Type[k][0].val=1
- Draw.Redraw(1)
-
- elif (evt in [On_Model_Bolt_Click,On_Model_Nut_Click]):
- for k in Model_Type.iterkeys():
- if Model_Type[k][1]!=evt:
- Model_Type[k][0].val=0
- else:
- Model_Type[k][0].val=1
- Draw.Redraw(1)
-
- elif (evt in [On_Hex_Nut_Click,On_Lock_Nut_Click]):
- for k in Nut_Type.iterkeys():
- if Nut_Type[k][1]!=evt:
- Nut_Type[k][0].val=0
- else:
- Nut_Type[k][0].val=1
- Draw.Redraw(1)
-
-#####################################################################################
-
-
-def Draw_Border(X1,Y1,X2,Y2): # X1,Y1 = Top Left X2,Y2 = Bottom Right
- INDENT = 3
-
- BGL.glColor3f(1.0,1.0,1.0)
- BGL.glBegin(BGL.GL_LINES)
- BGL.glVertex2i(X1+INDENT,Y1-INDENT) #top line
- BGL.glVertex2i(X2-INDENT,Y1-INDENT)
-
- BGL.glVertex2i(X1+INDENT,Y1-INDENT) #left line
- BGL.glVertex2i(X1+INDENT,Y2+INDENT)
- BGL.glEnd()
-
- BGL.glColor3f(0.5,0.5,0.5)
- BGL.glBegin(BGL.GL_LINES)
- BGL.glVertex2i(X2-INDENT,Y1-INDENT) #Right line
- BGL.glVertex2i(X2-INDENT,Y2+INDENT)
-
- BGL.glVertex2i(X1+INDENT,Y2+INDENT) #bottom line
- BGL.glVertex2i(X2-INDENT,Y2+INDENT)
- BGL.glEnd()
-
-
-
-
-def Create_Tab(X1,Y1,X2,Y2,Title,Buttons): # X1,Y1 = Top Left X2,Y2 = Bottom Right
-
- BIT_BUTTON_WIDTH = 55
- BIT_BUTTON_HEIGHT = 18
- TITLE_HEIGHT = 15
- INDENT = 6
- BUTTON_GAP = 4
-
- BGL.glColor3f(0.75, 0.75, 0.75)
- BGL.glRecti(X1,Y1,X2,Y2)
-
- Draw_Border(X1,Y1,X2,Y2);
-
- BGL.glColor3f(0.0,0.0,0.0)
- BGL.glRasterPos2d(X1+INDENT,Y1 - TITLE_HEIGHT)
- Draw.Text(Title)
-
- Button_X = X1 + INDENT
- Button_Y = Y1 - TITLE_HEIGHT - BIT_BUTTON_HEIGHT - 8
-
- #Nut_Number_X = Nut_Button_X
- #Nut_Number_Y = Nut_Button_Y - 25
- if (Buttons != 0):
- key= Buttons.keys()
- for k in key:
- Buttons[k][0]= Draw.Toggle(k,Buttons[k][1],Button_X,Button_Y, BIT_BUTTON_WIDTH,BIT_BUTTON_HEIGHT,Buttons[k][0].val,Buttons[k][2])
- Button_X += BIT_BUTTON_WIDTH + BUTTON_GAP
-
-
-
-def Dispaly_Title_Bar(Y_POS,CONTROL_HEIGHT):
- CONTROL_WIDTH = 250
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS -CONTROL_HEIGHT,"Bolt Factory V2.02",Model_Type)
-
-
-
-def Dispaly_Preset_Tab(Y_POS,CONTROL_HEIGHT):
- CONTROL_WIDTH = 250
- BUTTON_Y_OFFSET = 40
-
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Preset",0)
-
- name = "M3%x1|M4%x2|M5%x3|M6%x4|M8%x5|M10%x6|M12%x7"
-
- global Preset_Menu
- Preset_Menu = Draw.Menu(name,No_Event,9,Y_POS-BUTTON_Y_OFFSET,50,18, Preset_Menu.val, "Predefined metric screw sizes.")
- Draw.Button("Apply",On_Preset_Click,150,Y_POS-BUTTON_Y_OFFSET,55,18,"Apply the preset screw sizes.")
-
-
-def Dispaly_Bit_Tab(Y_POS,CONTROL_HEIGHT):
-
- CONTROL_WIDTH = 250
- NUMBER_HEIGHT = 18
- NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3
-
- Bit_Number_X = 3+3+3
- Bit_Number_Y = Y_POS - 64
-
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Bit Type",Bit_Type)
-
- if Bit_Type['NONE'][0].val:
- DoNothing = 1;
-
- elif Bit_Type['ALLEN'][0].val:
- global Allen_Bit_Depth
- Allen_Bit_Depth = Draw.Number('Bit Depth: ',No_Event,Bit_Number_X,Bit_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Allen_Bit_Depth.val, 0,100, '')
- Bit_Number_Y -= NUMBER_HEIGHT
- global Allen_Bit_Flat_Distance
- Allen_Bit_Flat_Distance = Draw.Number('Flat Dist: ',No_Event,Bit_Number_X,Bit_Number_Y,NUMBER_WIDTH,NUMBER_HEIGHT,Allen_Bit_Flat_Distance.val, 0,100, '')
- Bit_Number_Y -= NUMBER_HEIGHT
-
- elif Bit_Type['PHILLIPS'][0].val:
- global Phillips_Bit_Depth
- Phillips_Bit_Depth = Draw.Number('Bit Depth: ',No_Event,Bit_Number_X,Bit_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Phillips_Bit_Depth.val, 0,100, '')
- Bit_Number_Y -= NUMBER_HEIGHT
- global Philips_Bit_Dia
- Philips_Bit_Dia = Draw.Number('Bit Dia: ',No_Event,Bit_Number_X,Bit_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Philips_Bit_Dia.val, 0,100, '')
- Bit_Number_Y -= NUMBER_HEIGHT
-
-
-
-def Dispaly_Shank_Tab(Y_POS,CONTROL_HEIGHT):
-
- CONTROL_WIDTH = 250
- NUMBER_HEIGHT = 18
- NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3
-
- Number_X = 3+3+3
- Number_Y_Pos = Y_POS - 40
-
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Shank",0)
-
- global Shank_Length
- Shank_Length = Draw.Number('Shank Length: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Shank_Length.val, 0,MAX_INPUT_NUMBER, 'some text tip')
- Number_Y_Pos -= NUMBER_HEIGHT
-
- global Shank_Dia
- Shank_Dia = Draw.Number('Shank Dia: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Shank_Dia.val, 0,MAX_INPUT_NUMBER, 'some text tip')
- Number_Y_Pos -= NUMBER_HEIGHT
-
-
-
-def Dispaly_Thread_Tab(Y_POS,CONTROL_HEIGHT):
-
- CONTROL_WIDTH = 250
- NUMBER_HEIGHT = 18
- NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3
-
-
- Number_X = 3+3+3
- Number_Y_Pos = Y_POS - 40
-
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Thread",0)
-
- global Thread_Length
- if Model_Type['BOLT'][0].val:
- Thread_Length = Draw.Number('Thread Length: ',No_Event, Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Thread_Length.val, 0,MAX_INPUT_NUMBER, '')
- Number_Y_Pos -= NUMBER_HEIGHT
-
- global Major_Dia
- Major_Dia = Draw.Number('Major Dia: ',No_Event,Number_X,Number_Y_Pos, NUMBER_WIDTH,NUMBER_HEIGHT, Major_Dia.val, 0,MAX_INPUT_NUMBER, '')
- Number_Y_Pos -= NUMBER_HEIGHT
-
- global Minor_Dia
- Minor_Dia = Draw.Number('Minor Dia: ',No_Event,Number_X,Number_Y_Pos, NUMBER_WIDTH,NUMBER_HEIGHT, Minor_Dia.val, 0,MAX_INPUT_NUMBER, '')
- Number_Y_Pos -= NUMBER_HEIGHT
-
- global Pitch
- Pitch = Draw.Number('Pitch: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Pitch.val, 0.1,7.0, '')
- Number_Y_Pos -= NUMBER_HEIGHT
-
- global Crest_Percent
- Crest_Percent = Draw.Number('Crest %: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT,Crest_Percent.val, 1,90, '')
- Number_Y_Pos -= NUMBER_HEIGHT
-
- global Root_Percent
- Root_Percent = Draw.Number('Root %: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT,Root_Percent.val, 1,90, '')
- Number_Y_Pos -= NUMBER_HEIGHT
-
-
-
-
-def Dispaly_Head_Tab(Y_POS,CONTROL_HEIGHT):
-
- CONTROL_WIDTH = 250
- NUMBER_HEIGHT = 18
- NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3
-
- Head_Number_X = 3+3+3
- Head_Number_Y = Y_POS - 64
-
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Head Type",Head_Type)
-
- if Head_Type['HEX'][0].val:
- global Hex_Head_Height
- Hex_Head_Height = Draw.Number('Head Height: ',No_Event,Head_Number_X ,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Head_Height.val, 0,100, '')
- Head_Number_Y -= NUMBER_HEIGHT
- global Hex_Head_Flat_Distance
- Hex_Head_Flat_Distance = Draw.Number('Head Hex Flat Distance ',No_Event,Head_Number_X,Head_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Head_Flat_Distance.val, 0,MAX_INPUT_NUMBER, '')
- Head_Number_Y -= NUMBER_HEIGHT
-
- elif Head_Type['CAP'][0].val:
- global Cap_Head_Height
- Cap_Head_Height = Draw.Number('Head Height: ',No_Event, Head_Number_X,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Cap_Head_Height.val, 0,100, '')
- Head_Number_Y -= NUMBER_HEIGHT
- global Cap_Head_Dia
- Cap_Head_Dia = Draw.Number('Head Dia ',No_Event,Head_Number_X,Head_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Cap_Head_Dia.val, 0,MAX_INPUT_NUMBER, '')
- Head_Number_Y -= NUMBER_HEIGHT
-
- elif Head_Type['DOME'][0].val:
- global Dome_Head_Dia
- Dome_Head_Dia = Draw.Number(' Dome Head Dia ',No_Event,Head_Number_X,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Dome_Head_Dia.val, 0,MAX_INPUT_NUMBER, '')
- Head_Number_Y -= NUMBER_HEIGHT
-
- elif Head_Type['PAN'][0].val:
- global Pan_Head_Dia
- Pan_Head_Dia = Draw.Number('Pan Head Dia ',No_Event,Head_Number_X,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Pan_Head_Dia.val, 0,MAX_INPUT_NUMBER, '')
- Head_Number_Y -= NUMBER_HEIGHT
-
-
-
-
-def Dispaly_Nut_Tab(Y_POS,CONTROL_HEIGHT):
-
- CONTROL_WIDTH = 250
- NUMBER_HEIGHT = 18
- NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3
-
- Nut_Number_X = 3+3+3
- Nut_Number_Y = Y_POS - 64
-
- Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Nut Type",Nut_Type)
-
- #if Nut_Type['HEX'][0].val:
- global Hex_Nut_Height
- Hex_Nut_Height = Draw.Number('Nut Height: ',No_Event,Nut_Number_X ,Nut_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Nut_Height.val, 0,MAX_INPUT_NUMBER, '')
- Nut_Number_Y -= NUMBER_HEIGHT
- global Hex_Nut_Flat_Distance
- Hex_Nut_Flat_Distance = Draw.Number('Nut Flat Distance ',No_Event,Nut_Number_X,Nut_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Nut_Flat_Distance.val, 0,MAX_INPUT_NUMBER, '')
- Nut_Number_Y -= NUMBER_HEIGHT
-
-
-def Dispaly_Bolt_Tab():
-
- Dispaly_Shank_Tab(284,66)
- Dispaly_Head_Tab(374,90)
- Dispaly_Bit_Tab(464,90)
-
-
-##########################################################################################
-
-def gui(): # the function to draw the screen
-
- CONTROL_WIDTH = 250
-
- BGL.glClearColor(0.6, 0.6, 0.6, 1.0)
- BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
-
- BGL.glColor3f(0.75, 0.75, 0.75)
- BGL.glRecti(3,30,CONTROL_WIDTH,3)
-
- Dispaly_Title_Bar(514,50);
-
- if Model_Type['BOLT'][0].val:
- Dispaly_Bolt_Tab();
-
- if Model_Type['NUT'][0].val:
- Dispaly_Nut_Tab(464,246);
-
- Dispaly_Thread_Tab(218,138)
-
- Dispaly_Preset_Tab(80,50)
-
- Draw.PushButton("Create",On_Create_Click,6,8,55,18,"Create Bolt")
- Draw.Button("Exit",On_Exit_Click,6+55+4,8,55,18)
-
-# Draw.Button("Test",On_Test_Click,150,10,55,20)
-
-Load_Preset()
-Draw.Register(gui, event, button_event) # registering the 3 callbacks
diff --git a/release/scripts/wizard_curve2tree.py b/release/scripts/wizard_curve2tree.py
deleted file mode 100644
index 07b45c1986f..00000000000
--- a/release/scripts/wizard_curve2tree.py
+++ /dev/null
@@ -1,4048 +0,0 @@
-#!BPY
-"""
-Name: 'Tree from Curves'
-Blender: 245
-Group: 'Wizards'
-Tip: 'Generate trees from curve shapes'
-"""
-
-__author__ = "Campbell Barton"
-__url__ = ['www.blender.org', 'blenderartists.org']
-__version__ = "0.1"
-
-__bpydoc__ = """\
-
-"""
-
-# --------------------------------------------------------------------------
-# Tree from Curves v0.1 by Campbell Barton (AKA Ideasman42)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-# --------------------------------------------------------------------------
-
-import bpy
-import Blender
-import BPyMesh
-from Blender.Mathutils import Vector, Matrix, AngleBetweenVecs, LineIntersect, TranslationMatrix, ScaleMatrix, RotationMatrix, Rand
-from Blender.Geometry import ClosestPointOnLine
-from Blender.Noise import randuvec
-
-GLOBALS = {}
-GLOBALS['non_bez_error'] = 0
-
-'''
-def debugVec(v1,v2):
- sce = bpy.data.scenes.active
- me = bpy.data.meshes.new()
- me.verts.extend( [v1,v2] )
- me.edges.extend( [(0,1)] )
- sce.objects.new(me)
-'''
-
-def AngleBetweenVecsSafe(a1, a2):
- try:
- return AngleBetweenVecs(a1,a2)
- except:
- return 180.0
-
-# Python 2.3 has no reversed.
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-# Copied from blender, we could wrap this! - BKE_curve.c
-# But probably not toooo bad in python
-def forward_diff_bezier(q0, q1, q2, q3, pointlist, steps, axis):
- f= float(steps)
- rt0= q0
- rt1= 3.0*(q1-q0)/f
- f*= f
- rt2= 3.0*(q0-2.0*q1+q2)/f
- f*= steps
- rt3= (q3-q0+3.0*(q1-q2))/f
-
- q0= rt0
- q1= rt1+rt2+rt3
- q2= 2*rt2+6*rt3
- q3= 6*rt3
- if axis == None:
- for a in xrange(steps+1):
- pointlist[a] = q0
- q0+= q1
- q1+= q2
- q2+= q3;
-
- else:
- for a in xrange(steps+1):
- pointlist[a][axis] = q0
- q0+= q1
- q1+= q2
- q2+= q3;
-
-def points_from_bezier_seg(steps, pointlist, radlist, bez1_vec, bez2_vec, radius1, radius2):
-
- # x,y,z,axis
- for ii in (0,1,2):
- forward_diff_bezier(bez1_vec[1][ii], bez1_vec[2][ii], bez2_vec[0][ii], bez2_vec[1][ii], pointlist, steps, ii)
-
- # radius - no axis, Copied from blenders BBone roll interpolation.
- forward_diff_bezier(radius1, radius1 + 0.390464*(radius2-radius1), radius2 - 0.390464*(radius2-radius1), radius2, radlist, steps, None)
-
-
-def debug_pt(co):
- Blender.Window.SetCursorPos(tuple(co))
- Blender.Window.RedrawAll()
- print 'debugging', co
-
-def freshMesh(mesh):
- '''
- Utility function to get a new mesh or clear the existing one, but dont clear everything.
- '''
- if mesh:
- materials = mesh.materials
- mesh.verts = None
- for group in mesh.getVertGroupNames():
- mesh.removeVertGroup(group)
-
- # Add materials back
- mesh.materials = materials
- else:
- mesh = bpy.data.meshes.new()
-
- return mesh
-
-def getObFromName(name):
- if name:
- try: return bpy.data.objects[name]
- except: return None
- else:
- return None
-
-def getGroupFromName(name):
- if name:
- try: return bpy.data.groups[name]
- except: return None
- else:
- return None
-
-def closestVecIndex(vec, vecls):
- best= -1
- best_dist = 100000000
- for i, vec_test in enumerate(vecls):
- # Dont use yet, we may want to tho
- if vec_test: # Seems odd, but use this so we can disable some verts in the list.
- dist = (vec-vec_test).length
- if dist < best_dist:
- best = i
- best_dist = dist
-
- return best
-
-IRATIONAL_NUM = 22.0/7.0
-def next_random_num(rnd):
- '''
- return a random number between 0.0 and 1.0
- '''
- rnd[0] += (rnd[0] * IRATIONAL_NUM) % 1
- # prevent
- if rnd[0] > 1000000:
- rnd[0]-=1000000
- return rnd[0] % 1
-
-eul = 0.00001
-
-BRANCH_TYPE_CURVE = 0
-BRANCH_TYPE_GROWN = 1
-BRANCH_TYPE_FILL = 2
-
-class tree:
- def __init__(self):
- self.branches_all = []
- self.branches_root = []
- self.branches_twigs = []
- self.mesh = None
- self.armature = None
- self.objectCurve = None
- self.objectCurveMat = None
- self.objectCurveIMat = None
-
- self.objectTwigBounds = None # use for twigs only at the moment.
- self.objectTwigBoundsIMat = None
- self.objectTwigBoundsMat = None
- self.objectTwigBoundsMesh = None
-
- self.objectLeafBounds = None
- self.objectLeafBoundsIMat = None
- self.objectLeafBoundsMesh = None
-
- self.limbScale = 1.0
-
- self.debug_objects = []
- self.steps = 6 # defalt, curve overwrites
-
- def __repr__(self):
- s = ''
- s += '[Tree]'
- s += ' limbScale: %.6f' % self.limbScale
- s += ' object: %s' % self.objectCurve
-
- for brch in self.branches_root:
- s += str(brch)
- return s
-
- def fromCurve(self, objectCurve):
- # Now calculate the normals
- self.objectCurve = objectCurve
- self.objectCurveMat = objectCurve.matrixWorld
- self.objectCurveIMat = self.objectCurveMat.copy().invert()
- curve = objectCurve.data
- self.steps = curve.resolu # curve resolution
-
- # Set the curve object scale
- if curve.bevob:
- # A bit of a hack to guess the size of the curve object if you have one.
- bb = curve.bevob.boundingBox
- # self.limbScale = (bb[0] - bb[7]).length / 2.825 # THIS IS GOOD WHEN NON SUBSURRFED
- self.limbScale = (bb[0] - bb[7]).length / 1.8
- elif curve.ext2 != 0.0:
- self.limbScale = curve.ext2 * 1.5
-
- # forward_diff_bezier will fill in the blanks
- # nice we can reuse these for every curve segment :)
- pointlist = [[None, None, None] for i in xrange(self.steps+1)]
- radlist = [ None for i in xrange(self.steps+1) ]
-
- for spline in curve:
-
- if len(spline) < 2: # Ignore single point splines
- continue
-
- if spline.type != 1: # 0 poly, 1 bez, 4 nurbs
- GLOBALS['non_bez_error'] = 1
- continue
-
-
- brch = branch()
- brch.type = BRANCH_TYPE_CURVE
-
-
-
- bez_list = list(spline)
- for i in xrange(1, len(bez_list)):
- bez1 = bez_list[i-1]
- bez2 = bez_list[i]
- vec1 = bez1.vec
- vec2 = bez2.vec
- if abs(vec1[1][0]-vec2[1][0]) > 0.000001 or\
- abs(vec1[1][1]-vec2[1][1]) > 0.000001 or\
- abs(vec1[1][2]-vec2[1][2]) > 0.000001:
-
- points_from_bezier_seg(self.steps, pointlist, radlist, vec1, vec2, bez1.radius, bez2.radius)
-
- # remove endpoint for all but the last
- len_pointlist = len(pointlist)
- if i != len(bez_list)-1:
- len_pointlist -= 1
-
- brch.bpoints.extend([ bpoint(brch, Vector(pointlist[ii]), Vector(), radlist[ii] * self.limbScale) for ii in xrange(len_pointlist) ])
-
- # Finalize once point data is there
- if brch.bpoints:
- # if all points are in the same location, this is possible
- self.branches_all.append(brch)
- if brch.bpoints[0].radius < brch.bpoints[-1].radius: # This means we dont have to worry about curve direction.
- brch.bpoints.reverse()
- brch.calcData()
-
- # Sort from big to small, so big branches get priority
- # Py 2.3 dosnt have keywords in sort
- try: self.branches_all.sort( key = lambda brch: -brch.bpoints[0].radius )
- except: self.branches_all.sort( lambda brch_a, brch_b: cmp(brch_b.bpoints[0].radius, brch_a.bpoints[0].radius) ) # py2.3
-
-
- def closestBranchPt(self, co):
- best_brch = None
- best_pt = None
- best_dist = 10000000000
- for brch in self.branches_all:
- for pt in brch.bpoints:
- # if pt.inTwigBounds: # only find twigs, give different results for leaves
- l = (pt.co-co).length
- if l < best_dist:
- best_dist = l
- best_brch = brch
- best_pt = pt
- return best_brch, best_pt
-
- def setTwigBounds(self, objectMesh):
- self.objectTwigBounds = objectMesh
- self.objectTwigBoundsMesh = objectMesh.getData(mesh=1)
- self.objectTwigBoundsMat = objectMesh.matrixWorld.copy()
- self.objectTwigBoundsIMat = self.objectTwigBoundsMat.copy().invert()
-
- for brch in self.branches_all:
- brch.calcTwigBounds(self)
-
- def setLeafBounds(self, objectMesh):
- self.objectLeafBounds = objectMesh
- self.objectLeafBoundsMesh = objectMesh.getData(mesh=1)
- self.objectLeafBoundsIMat = objectMesh.matrixWorld.copy().invert()
-
- def isPointInTwigBounds(self, co, selected_only=False):
- return self.objectTwigBoundsMesh.pointInside(co * self.objectCurveMat * self.objectTwigBoundsIMat, selected_only)
-
- def isPointInLeafBounds(self, co, selected_only=False):
- return self.objectLeafBoundsMesh.pointInside(co * self.objectCurveMat * self.objectLeafBoundsIMat, selected_only)
-
- def resetTags(self, value):
- for brch in self.branches_all:
- brch.tag = value
-
- def buildConnections( self,\
- sloppy = 1.0,\
- connect_base_trim = 1.0,\
- do_twigs = False,\
- twig_ratio = 2.0,\
- twig_select_mode = 0,\
- twig_select_factor = 0.5,\
- twig_scale = 0.8,\
- twig_scale_width = 1.0,\
- twig_random_orientation = 180,\
- twig_random_angle = 33,\
- twig_recursive=True,\
- twig_recursive_limit=3,\
- twig_ob_bounds=None,\
- twig_ob_bounds_prune=True,\
- twig_ob_bounds_prune_taper=1.0,\
- twig_placement_maxradius=10.0,\
- twig_placement_maxtwig=0,\
- twig_follow_parent=0.0,\
- twig_follow_x=0.0,\
- twig_follow_y=0.0,\
- twig_follow_z=0.0,\
- do_variation = 0,\
- variation_seed = 1,\
- variation_orientation = 0.0,\
- variation_scale = 0.0,\
- do_twigs_fill = 0,\
- twig_fill_levels=4,\
- twig_fill_rand_scale=0.0,\
- twig_fill_fork_angle_max=180.0,\
- twig_fill_radius_min=0.1,\
- twig_fill_radius_factor=0.75,\
- twig_fill_shape_type=0,\
- twig_fill_shape_rand=0.0,\
- twig_fill_shape_power=0.3,\
- ):
- '''
- build tree data - fromCurve must run first
- '''
-
-
- # Sort the branchs by the first radius, so big branchs get joins first
- ### self.branches_all.sort( key = lambda brch: brch.bpoints[0].radius )
-
- #self.branches_all.reverse()
-
- # Connect branches
- for i in xrange(len(self.branches_all)):
- brch_i = self.branches_all[i]
-
- for j in xrange(len(self.branches_all)):
- if i != j:
- # See if any of the points match this branch
- # see if Branch 'i' is the child of branch 'j'
-
- brch_j = self.branches_all[j]
-
- if not brch_j.inParentChain(brch_i): # So we dont make cyclic tree!
-
- pt_best_j, dist = brch_j.findClosest(brch_i.bpoints[0].co)
-
- # Check its in range, allow for a bit out - hense the sloppy
- # The second check in the following IF was added incase the point is close enough to the line but the midpoint is further away
- # ...in this case the the resulting mesh will be adjusted to fit the join so its best to make it.
- if (dist < pt_best_j.radius * sloppy) or \
- ((brch_i.bpoints[0].co - pt_best_j.co).length < pt_best_j.radius * sloppy):
-
-
- brch_i.parent_pt = pt_best_j
- pt_best_j.childCount += 1 # dont remove me
-
- brch_i.baseTrim(connect_base_trim)
-
- '''
- if pt_best_j.childCount>4:
- raise "ERROR"
- '''
-
- # addas a member of best_j.children later when we have the geometry info available.
-
- #### print "Found Connection!!!", i, j
- break # go onto the next branch
-
- """
- children = [brch_child for brch_child in pt.children]
- if children:
- # This pt is one side of the segment, pt.next joins this segment.
- # calculate the median point the 2 segments would spanal
- # Once this is done we need to adjust 2 things
- # 1) move both segments up/down so they match the branches best.
- # 2) set the spacing of the segments around the point.
-
-
- # First try to get the ideal some space around each joint
- # the spacing shoule be an average of
- for brch.bpoints:
- """
-
- '''
- for brch in self.branches_all:
- brch.checkPointList()
- '''
-
- # Variations - use for making multiple versions of the same tree.
- if do_variation:
- irational_num = 22.0/7.0 # use to make the random number more odd
- rnd = [variation_seed]
-
- # Add children temporarily
- for brch in self.branches_all:
- if brch.parent_pt:
- rnd_rot = ((next_random_num(rnd) * variation_orientation) - 0.5) * 720
- mat_orientation = RotationMatrix(rnd_rot, 3, 'r', brch.parent_pt.no)
- rnd_sca = 1 + ((next_random_num(rnd)-0.5)* variation_scale )
- mat_scale = Matrix([rnd_sca,0,0],[0,rnd_sca,0],[0,0,rnd_sca])
- # mat_orientation = RotationMatrix(0, 3, 'r', brch.parent_pt.no)
- brch.transformRecursive(self, mat_scale * mat_orientation, brch.parent_pt.co)
-
- if (do_twigs or do_twigs_fill) and twig_ob_bounds: # Only spawn twigs inside this mesh
- self.setTwigBounds(twig_ob_bounds)
-
- # Important we so this with existing parent/child but before connecting and calculating verts.
- if do_twigs:
-
- # scale values down
- twig_random_orientation= twig_random_orientation/360.0
- twig_random_angle= twig_random_angle/360.0
-
- irational_num = 22.0/7.0 # use to make the random number more odd
-
- if not twig_recursive:
- twig_recursive_limit = 0
-
- self.buildTwigs(twig_ratio, twig_select_mode, twig_select_factor)
-
- branches_twig_attached = []
-
- # This wont add all! :/
- brch_twig_index = 0
- brch_twig_index_LAST = -1 # use this to prevent in inf loop, since its possible we cant place every branch
- while brch_twig_index < len(self.branches_twigs) and brch_twig_index_LAST != brch_twig_index:
- ###print "While"
- ### print brch_twig_index, len(self.branches_twigs) # if this dosnt change, quit the while
-
- brch_twig_index_LAST = brch_twig_index
-
- # new twigs have been added, recalculate
- branches_twig_sort = [brch.bestTwigSegment() for brch in self.branches_all]
- branches_twig_sort.sort() # this will sort the branches with best braches for adding twigs to at the start of the list
-
- for tmp_sortval, twig_pt_index, brch_parent in branches_twig_sort: # tmp_sortval is not used.
- if twig_pt_index != -1 and \
- (twig_recursive_limit == 0 or brch_parent.generation < twig_recursive_limit) and \
- (twig_placement_maxtwig == 0 or brch_parent.twig_count < twig_placement_maxtwig) and \
- brch_parent.bpoints[twig_pt_index].radius < twig_placement_maxradius:
-
- if brch_twig_index >= len(self.branches_twigs):
- break
-
- brch_twig = self.branches_twigs[brch_twig_index]
- parent_pt = brch_parent.bpoints[twig_pt_index]
-
- brch_twig.parent_pt = parent_pt
- parent_pt.childCount += 1
-
- # Scale this twig using this way...
- # The size of the parent, scaled by the parent point's radius,
- # ...compared to the parent branch;s root point radius.
- # Also take into account the length of the parent branch
- # Use this for pretend random numbers too.
- scale = twig_scale * (parent_pt.branch.bpoints[0].radius / brch_twig.bpoints[0].radius) * (parent_pt.radius / parent_pt.branch.bpoints[0].radius)
-
- # Random orientation
- # THIS IS NOT RANDOM - Dont be real random so we can always get re-produceale results.
- if twig_random_orientation: rnd1 = (((irational_num * scale * 10000000) % 360) - 180) * twig_random_orientation
- else: rnd1 = 0.0
- if twig_random_angle: rnd2 = (((irational_num * scale * 66666666) % 360) - 180) * twig_random_angle
- else: rnd2 = 0.0
-
- # Align this with the existing branch
- angle = AngleBetweenVecsSafe(zup, parent_pt.no)
- cross = zup.cross(parent_pt.no)
- mat_align = RotationMatrix(angle, 3, 'r', cross)
-
- # Use the bend on the point to work out which way to make the branch point!
- if parent_pt.prev: cross = parent_pt.no.cross(parent_pt.prev.no - parent_pt.no)
- else: cross = parent_pt.no.cross(parent_pt.next.no - parent_pt.no)
-
- if parent_pt.branch.parent_pt:
- angle = AngleBetweenVecsSafe(parent_pt.branch.parent_pt.no, parent_pt.no)
- else:
- # Should add a UI for this... only happens when twigs come off a root branch
- angle = 66
-
- mat_branch_angle = RotationMatrix(angle+rnd1, 3, 'r', cross)
- mat_scale = Matrix([scale,0,0],[0,scale,0],[0,0,scale])
-
- mat_orientation = RotationMatrix(rnd2, 3, 'r', parent_pt.no)
-
- if twig_scale_width != 1.0:
- # adjust length - no radius adjusting
- for pt in brch_twig.bpoints:
- pt.radius *= twig_scale_width
-
- brch_twig.transform(mat_scale * mat_branch_angle * mat_align * mat_orientation, parent_pt.co)
-
- # Follow the parent normal
- if twig_follow_parent or twig_follow_x or twig_follow_y or twig_follow_z:
-
- vecs = []
- brch_twig_len = float(len(brch_twig.bpoints))
-
- if twig_follow_parent:
- no = parent_pt.no.copy() * twig_follow_parent
- else:
- no = Vector()
-
- no.x += twig_follow_x
- no.y += twig_follow_y
- no.z += twig_follow_z
-
- for i, pt in enumerate(brch_twig.bpoints):
- if pt.prev:
- fac = i / brch_twig_len
-
- # Scale this value
- fac_inv = 1-fac
-
- no_orig = pt.co - pt.prev.co
- len_orig = no_orig.length
-
- no_new = (fac_inv * no_orig) + (fac * no)
- no_new.length = len_orig
-
- # Mix the 2 normals
- vecs.append(no_new)
-
- # Apply the coords
- for i, pt in enumerate(brch_twig.bpoints):
- if pt.prev:
- pt.co = pt.prev.co + vecs[i-1]
-
- brch_twig.calcPointExtras()
-
-
- # When using a bounding mesh, clip and calculate points in bounds.
- #print "Attempting to trim base"
- brch_twig.baseTrim(connect_base_trim)
-
- if twig_ob_bounds and (twig_ob_bounds_prune or twig_recursive):
- brch_twig.calcTwigBounds(self)
-
- # we would not have been but here if the bounds were outside
- if twig_ob_bounds_prune:
- brch_twig.boundsTrim()
- if twig_ob_bounds_prune_taper != 1.0:
- # taper to a point. we could use some nice taper algo here - just linear atm.
-
- brch_twig.taper(twig_ob_bounds_prune_taper)
-
- # Make sure this dosnt mess up anything else
-
- brch_twig_index += 1
-
- # Add to the branches
- #self.branches_all.append(brch_twig)
- if len(brch_twig.bpoints) > 2:
- branches_twig_attached.append(brch_twig)
- brch_twig.generation = brch_parent.generation + 1
- brch_parent.twig_count += 1
- else:
- # Dont add the branch
- parent_pt.childCount -= 1
-
- # Watch This! - move 1 tab down for no recursive twigs
- if twig_recursive:
- self.branches_all.extend(branches_twig_attached)
- branches_twig_attached = []
-
- if not twig_recursive:
- self.branches_all.extend(branches_twig_attached)
- branches_twig_attached = []
-
-
- if do_twigs_fill and twig_ob_bounds:
- self.twigFill(\
- twig_fill_levels,\
- twig_fill_rand_scale,\
- twig_fill_fork_angle_max,\
- twig_fill_radius_min,\
- twig_fill_radius_factor,\
- twig_fill_shape_type,\
- twig_fill_shape_rand,\
- twig_fill_shape_power,\
- )
-
- ### self.branches_all.sort( key = lambda brch: brch.parent_pt != None )
-
- # Calc points with dependancies
- # detect circular loops!!! - TODO
- #### self.resetTags(False) # NOT NEEDED NOW
- done_nothing = False
- while done_nothing == False:
- done_nothing = True
-
- for brch in self.branches_all:
-
- if brch.tag == False and (brch.parent_pt == None or brch.parent_pt.branch.tag == True):
- # Assign this to a spesific side of the parents point
- # we know this is a child but not which side it should be attached to.
- if brch.parent_pt:
-
- child_locs = [\
- brch.parent_pt.childPointUnused(0),\
- brch.parent_pt.childPointUnused(1),\
- brch.parent_pt.childPointUnused(2),\
- brch.parent_pt.childPointUnused(3)]
-
- best_idx = closestVecIndex(brch.bpoints[0].co, child_locs)
-
- # best_idx could be -1 if all childPoint's are used however we check for this and dont allow it to happen.
- #if best_idx==-1:
- # raise "Error"z
- brch.parent_pt.children[best_idx] = brch
-
- for pt in brch.bpoints:
- pt.calcVerts()
-
- done_nothing = False
- brch.tag = True
-
- '''
- for i in xrange(len(self.branches_all)):
- brch_i = self.branches_all[i]
- print brch_i.myindex,
- print 'tag', brch_i.tag,
- print 'parent is',
- if brch_i.parent_pt:
- print brch_i.parent_pt.branch.myindex
- else:
- print None
- '''
-
- def optimizeSpacing(self, seg_density=0.5, seg_density_angle=20.0, seg_density_radius=0.3, joint_compression=1.0, joint_smooth=1.0):
- '''
- Optimize spacing, taking branch hierarchy children into account,
- can add or subdivide segments so branch joins dont look horrible.
- '''
- for brch in self.branches_all:
- brch.evenJointDistrobution(joint_compression)
-
- # Correct points that were messed up from sliding
- # This happens when one point is pushed past another and the branch gets an overlaping line
-
- for brch in self.branches_all:
- brch.fixOverlapError(joint_smooth)
-
-
- # Collapsing
- for brch in self.branches_all:
- brch.collapsePoints(seg_density, seg_density_angle, seg_density_radius, joint_smooth)
-
- '''
- for brch in self.branches_all:
- brch.branchReJoin()
- '''
-
- def twigFill(self_tree,\
- twig_fill_levels,\
- twig_fill_rand_scale,\
- twig_fill_fork_angle_max,\
- twig_fill_radius_min,\
- twig_fill_radius_factor,\
- twig_fill_shape_type,\
- twig_fill_shape_rand,\
- twig_fill_shape_power,\
- ):
- '''
- Fill with twigs, this function uses its own class 'segment'
-
- twig_fill_shape_type;
- 0 - no child smoothing
- 1 - smooth one child
- 2 - smooth both children
-
- '''
-
- rnd = [1]
-
- segments_all = []
- segments_level = []
-
- # Only for testing
- def preview_curve():
- TWIG_WIDTH_MAX = 1.0
- TWIG_WIDTH_MIN = 0.1
- cu = bpy.data.curves["cu"]
- # remove all curves
- while len(cu):
- del cu[0]
- # return
-
- cu.setFlag(1)
- cu.ext2 = 0.01
-
- WIDTH_STEP = (TWIG_WIDTH_MAX-TWIG_WIDTH_MIN) / twig_fill_levels
-
- for i, seg in enumerate(segments_all):
-
- # 1 is the base and 2 is the tail
-
- p1_h2 = seg.getHeadHandle() # isnt used
- p1_co = seg.headCo
- p1_h1 = seg.getHeadHandle()
-
- p2_h1 = seg.getTailHandle()
-
- p2_co = seg.tailCo
- p2_h2 = seg.tailCo # isnt used
-
- bez1 = Blender.BezTriple.New([ p1_h1[0], p1_h1[1], p1_h1[2], p1_co[0], p1_co[1], p1_co[2], p1_h2[0], p1_h2[1], p1_h2[2] ])
- bez2 = Blender.BezTriple.New([ p2_h1[0], p2_h1[1], p2_h1[2], p2_co[0], p2_co[1], p2_co[2], p2_h2[0], p2_h2[1], p2_h2[2] ])
- bez1.handleTypes = bez2.handleTypes = [Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE]
-
- bez1.radius = TWIG_WIDTH_MIN + (WIDTH_STEP * (seg.levelFromLeaf+1))
- bez2.radius = TWIG_WIDTH_MIN + (WIDTH_STEP * seg.levelFromLeaf)
-
- cunurb = cu.appendNurb(bez1)
- cunurb.append(bez2)
-
- # This sucks
- for bez in cunurb:
- bez.handleTypes = [Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE]
-
- ### cc = sce.objects.new( cu )
- cu.update()
-
-
- def mergeCo(parentCo, ch1Co, ch2Co, twig_fill_shape_rand):
- if twig_fill_shape_rand==0.0:
- return (parentCo + ch1Co + ch2Co) / 3.0
- else:
-
- w1 = (next_random_num(rnd)*twig_fill_shape_rand) + (1-twig_fill_shape_rand)
- w2 = (next_random_num(rnd)*twig_fill_shape_rand) + (1-twig_fill_shape_rand)
- w3 = (next_random_num(rnd)*twig_fill_shape_rand) + (1-twig_fill_shape_rand)
- wtot = w1+w2+w3
- w1=w1/wtot
- w2=w2/wtot
- w3=w3/wtot
-
- # return (parentCo*w1 + ch1Co*w2 + ch2Co*w2)
- co1 = (parentCo * w1) + (ch1Co * (1.0-w1))
- co2 = (ch1Co * w2) + (ch2Co * (1.0-w2))
- co3 = (ch2Co * w3) + (parentCo * (1.0-w3))
-
- return (co1 + co2 + co3) / 3.0
-
-
-
- class segment:
- def __init__(self, level):
- self.headCo = Vector()
- self.tailCo = Vector()
- self.parent = None
- self.mergeCount = 0
- self.levelFromLeaf = level # how far we are from the leaf in levels
- self.levelFromRoot = -1 # set later, assume root bone
- self.children = []
- segments_all.append(self)
-
- if level >= len(segments_level): segments_level.append([self])
- else: segments_level[level].append(self)
-
- self.brothers = []
- self.no = Vector() # only endpoints have these
- # self.id = len(segments_all)
-
- # First value is the bpoint,
- # Second value is what to do -
- # 0 - dont join
- # 1 - Join to parent (tree point)
- # 2 - join to parent, point from another fill-twig branch we just created.
-
- self.bpt = (None, False) # branch point for root segs only
- self.new_bpt = None
-
- self.used = False # use this to tell if we are apart of a branch
-
- def sibling(self):
- i = self.parent.children.index(self)
-
- if i == 0:
- return self.parent.children[ 1 ]
- elif i == 1:
- return self.parent.children[ 0 ]
- else:
- raise "error"
-
-
- def getHeadHandle(self):
- """
- For Bezier only
- """
-
- if not self.parent:
- return self.headCo
-
- if twig_fill_shape_type == 0: # no smoothing
- return self.headCo
- elif twig_fill_shape_type == 1:
- if self.parent.children[1] == self:
- return self.headCo
- # 2 - always do both
-
-
- # Y shape with curve? optional
-
- # we have a parent but it has no handle direction, easier
- if not self.parent.parent: no = self.parent.headCo - self.parent.tailCo
- else: no = self.parent.parent.headCo-self.parent.tailCo
-
- no.length = self.getLength() * twig_fill_shape_power
- # Ok we have to account for the parents handle
- return self.headCo - no
- # return self.headCo - Vector(1, 0,0)
-
- def getTailHandle(self):
- """
- For Bezier only
- """
- if self.parent:
- no = self.parent.headCo-self.tailCo
- no.length = self.getLength() * twig_fill_shape_power
- return self.tailCo + no
- else:
- return self.tailCo # isnt used
-
- def getRootSeg(self):
- seg = self
- while seg.parent:
- seg = seg.parent
-
- return seg
-
- def calcBrothers(self):
- # Run on children first
- self.brothers.extend( \
- [seg_child_sibling.parent \
- for seg_child in self.children \
- for seg_child_sibling in seg_child.brothers \
- if seg_child_sibling.parent not in (self, None)]\
- )
- #print self.brothers
-
- def calcLevelFromRoot(self):
- if self.parent:
- self.levelFromRoot = self.parent.levelFromRoot + 1
-
- for seg_child in self.children:
- seg_child.calcLevelFromRoot()
-
- # Dont use for now, but scale worked, transform was never tested.
- """
- def transform(self, matrix):
- self.headCo = self.headCo * matrix
- self.tailCo = self.tailCo * matrix
-
- if self.children:
- ch1 = self.children[0]
- ch2 = self.children[1]
-
- ch1.transform(matrix)
- ch2.transform(matrix)
-
- def scale(self, scale, cent=None):
- # scale = 0.9
- #matrix = Matrix([scale,0,0],[0,scale,0],[0,0,scale]).resize4x4()
- #self.transform(matrix)
- if cent == None: # first iter
- cent = self.headCo
- self.tailCo = ((self.tailCo-cent) * scale) + cent
- else:
- self.headCo = ((self.headCo-cent) * scale) + cent
- self.tailCo = ((self.tailCo-cent) * scale) + cent
-
- if self.children:
- self.children[0].scale(scale, cent)
- self.children[1].scale(scale, cent)
- """
- def recalcChildLoc(self):
- if not self.children:
- return
- ch1 = self.children[0]
- ch2 = self.children[1]
- new_mid = mergeCo(self.headCo, ch1.tailCo, ch2.tailCo, twig_fill_shape_rand)
-
- self.tailCo[:] = ch1.headCo[:] = ch2.headCo[:] = new_mid
-
- ch1.recalcChildLoc()
- ch2.recalcChildLoc()
-
- def merge(self, other):
- """
- Merge other into self and make a new segment
- """
- """
- seg_child = segment(self.levelFromLeaf)
- self.levelFromLeaf += 1
-
- seg_child.parent = other.parent = self
-
- # No need, recalcChildLoc sets the other coords
- #self.parent.tailCo = (self.headCo + self.tailCo + other.tailCo) / 3.0
- #self.parent.headCo[:] = self.headCo
-
- seg_child.headCo[:] = self.headCo
-
- # isect = LineIntersect(self.headCo, self.tailCo, other.headCo, other.tailCo)
- # new_head = (isect[0]+isect[1]) * 0.5
-
- seg_child.mergeCount += 1
- other.mergeCount += 1
-
- self.children.extend([ seg_child, other ])
-
- self.recalcChildLoc()
-
- # print 'merging', self.id, other.id
- """
-
- #new_head = (self.headCo + self.tailCo + other.headCo + other.tailCo) * 0.25
-
- self.parent = other.parent = segment(self.levelFromLeaf + 1)
-
- # No need, recalcChildLoc sets the self.parent.tailCo
- # self.parent.tailCo = (self.headCo + self.tailCo + other.tailCo) / 3.0
-
- self.parent.headCo[:] = self.headCo
- self.parent.bpt = self.bpt
- self.bpt = (None, False)
-
- # isect = LineIntersect(self.headCo, self.tailCo, other.headCo, other.tailCo)
- # new_head = (isect[0]+isect[1]) * 0.5
-
- self.mergeCount += 1
- other.mergeCount += 1
-
- self.parent.children.extend([ self, other ])
-
- self.parent.recalcChildLoc()
- # print 'merging', self.id, other.id
-
-
- def findBestMerge(self, twig_fill_fork_angle_max):
- # print "findBestMerge"
- if self.parent != None:
- return
-
- best_dist = 1000000
- best_seg = None
- for seg_list in (self.brothers, segments_level[self.levelFromLeaf]):
- #for seg_list in (segments_level[self.levelFromLeaf],):
-
- # only use all other segments if we cant find any from our brothers
- if seg_list == segments_level[self.levelFromLeaf] and best_seg != None:
- break
-
- for seg in seg_list:
- # 2 ppoint join
- if seg != self and seg.mergeCount == 0 and seg.parent == None:
-
- # find the point they would join
- test_dist = (self.tailCo - seg.tailCo).length
- if test_dist < best_dist:
- if twig_fill_fork_angle_max > 179:
- best_dist = test_dist
- best_seg = seg
- else:
- # Work out if the desired angle range is ok.
- mco = mergeCo( self.headCo, self.tailCo, seg.tailCo, 0.0 ) # we dont want the random value for this test
- ang = AngleBetweenVecsSafe(self.tailCo-mco, seg.tailCo-mco)
- if ang < twig_fill_fork_angle_max:
- best_dist = test_dist
- best_seg = seg
- return best_seg
-
- def getNormal(self):
- return (self.headCo - self.tailCo).normalize()
-
- def getLength(self):
- return (self.headCo - self.tailCo).length
- """
- def toMatrix(self, LEAF_SCALE, LEAF_RANDSCALE, LEAF_RANDVEC):
- if LEAF_RANDSCALE: scale = LEAF_SCALE * Rand(1.0-LEAF_RANDSCALE, 1.0+LEAF_RANDSCALE)
- else: scale = LEAF_SCALE * 1.0
-
- if LEAF_RANDVEC: rand_vec = Vector( Rand(-1, 1), Rand(-1, 1), Rand(-1, 1) ).normalize() * LEAF_RANDVEC
- else: rand_vec = Vector( )
-
- return Matrix([scale,0,0],[0,scale,0],[0,0,scale]).resize4x4() * (self.no + rand_vec).toTrackQuat('x', 'z').toMatrix().resize4x4() * TranslationMatrix(self.tailCo)
- """
- def distripute_seg_on_mesh(me__, face_group):
- """
- add segment endpoints
- """
-
- vert_segment_mapping = {}
- for f in face_group:
- for v in f:
- i = v.index
- if i not in vert_segment_mapping:
- vert_segment_mapping[i] = len(segments_all)
- v.sel = True
- seg = segment(0)
- # seg.tailCo = v.co.copy() # headCo undefined atm.
- seg.tailCo = v.co.copy() * self_tree.objectTwigBoundsMat * self_tree.objectCurveIMat
-
- # self_tree.objectCurveMat
-
- seg.no = v.no
-
- # Build connectivity
- for ed in me__.edges:
- if ed.v1.sel and ed.v2.sel:
- i1,i2 = ed.key
- i1 = vert_segment_mapping[i1]
- i2 = vert_segment_mapping[i2]
-
- segments_all[i1].brothers.append( segments_all[i2] )
- segments_all[i2].brothers.append( segments_all[i1] )
-
- # Dont need to return anything, added when created.
-
- def set_seg_attach_point(seg, interior_points, twig_fill_rand_scale):
- """
- Can only run on end nodes that have normals set
- """
- best_dist = 1000000000.0
- best_point = None
-
- co = seg.tailCo
-
- for pt in interior_points:
- # line from the point to the seg endpoint
-
- line_normal = seg.tailCo - pt.nextMidCo
- l = line_normal.length
-
-
- cross1 = seg.no.cross(line_normal)
- cross2 = pt.no.cross(line_normal)
-
- angle_line = min(AngleBetweenVecsSafe(cross1, cross2), AngleBetweenVecsSafe(cross1, -cross2))
- angle_leaf_no_diff = min(AngleBetweenVecsSafe(line_normal, seg.no), AngleBetweenVecsSafe(line_normal, -seg.no))
-
- # BEST_ANG=66.0
- # angle = 66.0 # min(AngleBetweenVecs(v2_co-v1_co, leaf.co-cc), AngleBetweenVecs(v1_co-v2_co, leaf.co-cc))
- # print angle, angle2
- # l = (l * ((1+abs(angle-BEST_ANG))**2 )) / (1+angle_line)
- l = (1+(angle_leaf_no_diff/180)) * (1+(angle_line/180)) * l
-
- if l < best_dist:
- best_pt = pt
- best_co = pt.nextMidCo
-
- best_dist = l
-
- # twig_fill_rand_scale
- seg.headCo = best_co.copy()
-
- if twig_fill_rand_scale:
- seg_dir = seg.tailCo - seg.headCo
-
- seg_dir.length = seg_dir.length * ( 1.0 - (next_random_num(rnd)*twig_fill_rand_scale) )
- seg.tailCo = seg.headCo + seg_dir
-
-
- if best_pt.childCount < 4:
- # Watch this!!! adding a user before its attached and the branch is created!
- # make sure if its not added later on, this isnt left added
- best_pt.childCount += 1
-
- # True/False denotes weather we try to connect to our parent branch
- seg.bpt = (best_pt, True)
- else:
- seg.bpt = (best_pt, False)
-
- return True
-
-
- # END Twig code, next add them
-
-
- """
- Uses a reversed approch, fill in twigs from a bounding mesh
- """
- # print "twig_fill_fork_angle_max"
- # twig_fill_fork_angle_max = 60.0 #
- # forward_diff_bezier will fill in the blanks
- # nice we can reuse these for every curve segment :)
- pointlist = [[None, None, None] for i in xrange(self_tree.steps+1)]
- radlist = [ None for i in xrange(self_tree.steps+1) ]
-
- orig_branch_count = len(self_tree.branches_all)
-
- for face_group in BPyMesh.mesh2linkedFaces(self_tree.objectTwigBoundsMesh):
- # Set the selection to do point inside.
- self_tree.objectTwigBoundsMesh.sel = False
- for f in face_group: f.sel = True
-
- interior_points = []
- interior_normal = Vector()
- for i, brch in enumerate(self_tree.branches_all):
-
- if i == orig_branch_count:
- break # no need to check new branches are inside us
-
- for pt in brch.bpoints:
- if pt.next and pt.childCount < 4: # cannot attach to the last points
- if self_tree.isPointInTwigBounds(pt.co, True): # selected_only
- interior_points.append(pt)
- interior_normal += pt.no * pt.radius
-
- segments_all[:] = []
- segments_level[:] = []
-
- if interior_points:
- # Ok, we can add twigs now
- distripute_seg_on_mesh( self_tree.objectTwigBoundsMesh, face_group )
-
- for seg in segments_level[0]: # only be zero segments
- # Warning, increments the child count for bpoints we attach to!!
- set_seg_attach_point(seg, interior_points, twig_fill_rand_scale)
-
- # Try sorting by other properties! this is ok for now
- for segments_level_current in segments_level:
- try: segments_level_current.sort( key = lambda seg: -(seg.headCo-seg.tailCo).length )
- except: segments_level_current.sort( lambda a,b: cmp((b.headCo-b.tailCo).length, (a.headCo-a.tailCo).length) ) # py2.3
-
- for level in xrange(twig_fill_levels):
- if len(segments_level) > level:
- for seg in segments_level[level]:
- # print level, seg.brothers
- if seg.mergeCount == 0:
- seg_merge = seg.findBestMerge(twig_fill_fork_angle_max)
- if seg_merge:
- seg.merge( seg_merge )
-
- if len(segments_level) > level+1:
- for seg in segments_level[level+1]:
- seg.calcBrothers()
-
- for seg in segments_all:
- if seg.parent == None:
- seg.levelFromRoot = 0
- seg.calcLevelFromRoot()
-
- '''
- for i, seg in enumerate(segments_all):
- # Make a branch from this data!
-
- brch = branch()
- brch.type = BRANCH_TYPE_FILL
- self_tree.branches_all.append(brch)
-
- # ============================= do this per bez pair
- # 1 is the base and 2 is the tail
-
- #p1_h1 = seg.getHeadHandle()
- p1_co = seg.headCo.copy()
- p1_h2 = seg.getHeadHandle() # isnt used
-
- p2_h1 = seg.getTailHandle()
- p2_co = seg.tailCo.copy()
- #p2_h2 = seg.getTailHandle() # isnt used
-
-
- bez1_vec = (None, p1_co, p1_h2)
- bez2_vec = (p2_h1, p2_co, None)
-
- seg_root = seg.getRootSeg()
-
- radius_root = seg_root.bpt.radius * twig_fill_radius_factor
- # Clamp so the head is never smaller then the tail
- if radius_root < twig_fill_radius_min: radius_root = twig_fill_radius_min
-
- if seg_root.levelFromLeaf:
- # print seg_root.levelFromLeaf, seg.levelFromRoot
- WIDTH_STEP = (radius_root - twig_fill_radius_min) / (seg_root.levelFromLeaf+1)
-
- radius1 = twig_fill_radius_min + (WIDTH_STEP * (seg.levelFromLeaf+1))
- if seg.levelFromLeaf: radius2 = twig_fill_radius_min + (WIDTH_STEP * seg.levelFromLeaf)
- else: radius2 = twig_fill_radius_min
- else:
- radius1 = radius_root
- radius2 = twig_fill_radius_min
-
-
- points_from_bezier_seg(self_tree.steps, pointlist, radlist, bez1_vec, bez2_vec, radius1, radius2)
-
- # dont apply self_tree.limbScale here! - its alredy done
- bpoints = [ bpoint(brch, Vector(pointlist[ii]), Vector(), radlist[ii]) for ii in xrange(len(pointlist)) ]
-
- # remove endpoint for all but the last
- #if i != len(bez_list)-1:
- # bpoints.pop()
-
- brch.bpoints.extend(bpoints)
- # =============================
-
- # Finalize once point data is there
- brch.calcData()
- #
- #preview_curve()
- '''
-
- for segments_level_current in reversed(segments_level):
- for seg in segments_level_current:
- if seg.used == False and (seg.parent == None or seg.parent.used == True):
-
- # The root segment for this set of links.
- # seg_root_linked = seg
-
- brch = branch()
- brch.type = BRANCH_TYPE_FILL
- self_tree.branches_all.append(brch)
-
- # Can we attach to a real branch?
- if seg.parent == None:
- if seg.bpt[1]: # we can do a real join into the attach point
- brch.parent_pt = seg.bpt[0]
- # brch.parent_pt.childCount # this has alredy changed from
-
- '''
- if seg.parent:
- if seg.bpt[1] == 2:
- #if seg.bpt[1]:
- # print "Making Connection"
- if seg.bpt[0] == None:
- raise "Error"
- if seg.bpt[1] != 2:
- print seg.bpt[1]
- raise "Error"
-
- brch.parent_pt = seg.bpt[1]
- brch.parent_pt.childCount += 1
- if brch.parent_pt.childCount > 4:
- raise "Aeeae"
- print "\n\nM<aking Joint!!"
- '''
-
- if seg.parent:
- sibling = seg.sibling()
- if sibling.new_bpt:
- if sibling.new_bpt.childCount < 4:
- brch.parent_pt = sibling.new_bpt
- brch.parent_pt.childCount +=1
-
- # Go down the hierarhy
- is_first = True
- while seg != None:
- seg.used = True
-
- # ==============================================
-
- #p1_h1 = seg.getHeadHandle()
- p1_co = seg.headCo.copy()
- p1_h2 = seg.getHeadHandle() # isnt used
-
- p2_h1 = seg.getTailHandle()
- p2_co = seg.tailCo.copy()
- #p2_h2 = seg.getTailHandle() # isnt used
-
-
- bez1_vec = (None, p1_co, p1_h2)
- bez2_vec = (p2_h1, p2_co, None)
-
- seg_root = seg.getRootSeg()
-
- radius_root = seg_root.bpt[0].radius * twig_fill_radius_factor
- # Clamp so the head is never smaller then the tail
- if radius_root < twig_fill_radius_min: radius_root = twig_fill_radius_min
-
- if seg_root.levelFromLeaf:
- # print seg_root.levelFromLeaf, seg.levelFromRoot
- widthStep = (radius_root - twig_fill_radius_min) / (seg_root.levelFromLeaf+1)
-
- radius1 = twig_fill_radius_min + (widthStep * (seg.levelFromLeaf+1))
- if seg.levelFromLeaf: radius2 = twig_fill_radius_min + (widthStep * seg.levelFromLeaf)
- else: radius2 = twig_fill_radius_min
- else:
- radius1 = radius_root
- radius2 = twig_fill_radius_min
-
- points_from_bezier_seg(self_tree.steps, pointlist, radlist, bez1_vec, bez2_vec, radius1, radius2)
-
-
- start_pointlist = 0
-
- # This is like baseTrim, (remove the base points to make nice joins, accounting for radius of parent point)
- # except we do it before the branch is made
-
- if brch.parent_pt:
- while len(pointlist) - start_pointlist > 2 and (Vector(pointlist[start_pointlist]) - brch.parent_pt.co).length < (brch.parent_pt.radius*2):
- start_pointlist +=1
-
- if is_first and brch.parent_pt:
- # We need to move the base point to a place where it looks good on the parent branch
- # to do this. move the first point, then remove the following points that look horrible (double back on themself)
-
- no = Vector(pointlist[0]) - Vector(pointlist[-1])
- no.length = brch.parent_pt.radius*2
- pointlist[0] = list(Vector(pointlist[0]) - no)
-
- """
- pointlist[1][0] = (pointlist[0][0] + pointlist[2][0])/2.0
- pointlist[1][1] = (pointlist[0][1] + pointlist[2][1])/2.0
- pointlist[1][2] = (pointlist[0][2] + pointlist[2][2])/2.0
-
- pointlist[2][0] = (pointlist[1][0] + pointlist[3][0])/2.0
- pointlist[2][1] = (pointlist[1][1] + pointlist[3][1])/2.0
- pointlist[2][2] = (pointlist[1][2] + pointlist[3][2])/2.0
- """
-
-
- # Done setting the start point
-
-
- len_pointlist = len(pointlist)
- if seg.children:
- len_pointlist -= 1
-
- # dont apply self_tree.limbScale here! - its alredy done
- bpoints = [ bpoint(brch, Vector(pointlist[ii]), Vector(), radlist[ii]) for ii in xrange(start_pointlist, len_pointlist) ]
- brch.bpoints.extend( bpoints )
- # ==============================================
-
- seg.new_bpt = bpoints[0]
-
- if seg.children:
- seg = seg.children[0]
- else:
- seg = None
-
- is_first = False
-
- # done adding points
- brch.calcData()
-
-
-
-
- def buildTwigs(self, twig_ratio, twig_select_mode, twig_select_factor):
-
- ratio_int = int(len(self.branches_all) * twig_ratio)
- if ratio_int == 0:
- return
-
- # So we only mix branches of similar lengths
- branches_sorted = self.branches_all[:]
-
- # Get the branches based on our selection method!
- if twig_select_mode==0:
- try: branches_sorted.sort( key = lambda brch: brch.getLength())
- except: branches_sorted.sort( lambda a,b: cmp(a.getLength(),a.getLength()) ) # py2.3
- elif twig_select_mode==1:
- try: branches_sorted.sort( key = lambda brch:-brch.getLength())
- except: branches_sorted.sort( lambda a,b: cmp(b.getLength(), a.getLength()) ) # py2.3
- elif twig_select_mode==2:
- try: branches_sorted.sort( key = lambda brch:brch.getStraightness())
- except: branches_sorted.sort( lambda a,b: cmp(a.getStraightness(), b.getStraightness())) # py2.3
- elif twig_select_mode==3:
- try: branches_sorted.sort( key = lambda brch:-brch.getStraightness())
- except: branches_sorted.sort( lambda a,b: cmp(b.getStraightness(), a.getStraightness())) # py2.3
-
- factor_int = int(len(self.branches_all) * twig_select_factor)
- branches_sorted[factor_int:] = [] # remove the last part of the list
-
- try: branches_sorted.sort( key = lambda brch: len(brch.bpoints))
- except: branches_sorted.sort( lambda a,b: cmp(len(a.bpoints), len(b.bpoints)) ) # py2.3
-
- branches_new = []
- #for i in xrange(ratio_int):
- tot_twigs = 0
-
- step = 1
- while tot_twigs < ratio_int and step < len(branches_sorted):
- # Make branches from the existing
- for j in xrange(step, len(branches_sorted)):
- brch = branches_sorted[j-step].mixToNew(branches_sorted[j], None)
- branches_new.append( brch )
- tot_twigs +=1
-
- if tot_twigs > ratio_int:
- break
-
- ### print "TwigCount", len(branches_new), ratio_int
-
- self.branches_twigs = branches_new
-
- def toDebugDisplay(self):
- '''
- Should be able to call this at any time to see whats going on, dosnt work so nice ATM.
- '''
- sce = bpy.data.scenes.active
-
- for ob in self.debug_objects:
- for ob in sce.objects:
- sce.objects.unlink(ob)
-
- for branch_index, brch in enumerate(self.branches_all):
- pt_index = 0
- for pt_index, pt in enumerate(brch.bpoints):
- name = '%.3d_%.3d' % (branch_index, pt_index)
- if pt.next==None:
- name += '_end'
- if pt.prev==None:
- name += '_start'
-
- ob = sce.objects.new('Empty', name)
- self.debug_objects.append(ob)
- mat = ScaleMatrix(pt.radius, 4) * TranslationMatrix(pt.co)
- ob.setMatrix(mat)
- ob.setDrawMode(8) # drawname
- Blender.Window.RedrawAll()
-
-
-
- def toMesh(self, mesh=None,\
- do_uv=True,\
- do_uv_keep_vproportion=True,\
- do_uv_vnormalize=False,\
- do_uv_uscale=False,\
- uv_image = None,\
- uv_x_scale=1.0,\
- uv_y_scale=4.0,\
- do_uv_blend_layer= False,\
- do_cap_ends=False,\
- ):
-
- self.mesh = freshMesh(mesh)
- totverts = 0
-
- for brch in self.branches_all:
- totverts += len(brch.bpoints)
-
- self.mesh.verts.extend( [ (0.0,0.0,0.0) ] * ((totverts * 4)+1) ) # +1 is a dummy vert
- verts = self.mesh.verts
-
- # Assign verts to points, 4 verts for each point.
- i = 1 # dummy vert, should be 0
- for brch in self.branches_all:
- for pt in brch.bpoints:
- pt.verts[0] = verts[i]
- pt.verts[1] = verts[i+1]
- pt.verts[2] = verts[i+2]
- pt.verts[3] = verts[i+3]
- i+=4
-
- # Do this again because of collapsing
- # pt.calcVerts(brch)
-
- # roll the tube so quads best meet up to their branches.
- for brch in self.branches_all:
- #for pt in brch.bpoints:
- if brch.parent_pt:
-
- # Use temp lists for gathering an average
- if brch.parent_pt.roll_angle == None:
- brch.parent_pt.roll_angle = [brch.getParentQuadAngle()]
- # More then 2 branches use this point, add to the list
- else:
- brch.parent_pt.roll_angle.append( brch.getParentQuadAngle() )
-
- # average the temp lists into floats
- for brch in self.branches_all:
- #for pt in brch.bpoints:
- if brch.parent_pt and type(brch.parent_pt.roll_angle) == list:
- # print brch.parent_pt.roll_angle
- f = 0.0
- for val in brch.parent_pt.roll_angle:
- f += val
- brch.parent_pt.roll_angle = f/len(brch.parent_pt.roll_angle)
-
- # set the roll of all the first segments that have parents,
- # this is because their roll is set from their parent quad and we dont want them to roll away from that.
- for brch in self.branches_all:
- if brch.parent_pt:
- # if the first joint has a child then apply half the roll
- # theres no correct solition here, but this seems ok
- if brch.bpoints[0].roll_angle != None:
- #brch.bpoints[0].roll_angle *= 0.5
- #brch.bpoints[0].roll_angle = 0.0
- #brch.bpoints[1].roll_angle = 0.0
- brch.bpoints[0].roll_angle = 0.0
- pass
- else:
- # our roll was set from the branches parent and needs no changing
- # set it to zero so the following functions know to interpolate.
- brch.bpoints[0].roll_angle = 0.0
- #brch.bpoints[1].roll_angle = 0.0
-
- '''
- Now interpolate the roll!
- The method used here is a little odd.
-
- * first loop up the branch and set each points value to the "last defined" value and record the steps
- since the last defined value
- * Do the same again but backwards
-
- now for each undefined value we have 1 or 2 values, if its 1 its simple we just use that value
- ( no interpolation ), if there are 2 then we use the offsets from each end to work out the interpolation.
-
- one up, one back, and another to set the values, so 3 loops all up.
- '''
- #### print "scan up the branch..."
- for brch in self.branches_all:
- last_value = None
- last_index = -1
- for i in xrange(len(brch.bpoints)):
- pt = brch.bpoints[i]
- if type(pt.roll_angle) in (float, int):
- last_value = pt.roll_angle
- last_index = i
- else:
- if type(last_value) in (float, int):
- # Assign a list, because there may be a connecting roll value from another joint
- pt.roll_angle = [(last_value, i-last_index)]
-
- #### print "scan down the branch..."
- last_value = None
- last_index = -1
- for i in xrange(len(brch.bpoints)-1, -1, -1): # same as above but reverse
- pt = brch.bpoints[i]
- if type(pt.roll_angle) in (float, int):
- last_value = pt.roll_angle
- last_index = i
- else:
- if last_value != None:
- if type(pt.roll_angle) == list:
- pt.roll_angle.append((last_value, last_index-i))
- else:
- #pt.roll_angle = [(last_value, last_index-i)]
-
- # Dont bother assigning a list because we wont need to add to it later
- pt.roll_angle = last_value
-
- # print "looping ,...."
- ### print "assigning/interpolating roll values"
- for pt in brch.bpoints:
-
- # print "this roll IS", pt.roll_angle
-
- if pt.roll_angle == None:
- continue
- elif type(pt.roll_angle) in (float, int):
- pass
- elif len(pt.roll_angle) == 1:
- pt.roll_angle = pt.roll_angle[0][0]
- else:
- # interpolate
- tot = pt.roll_angle[0][1] + pt.roll_angle[1][1]
- pt.roll_angle = \
- (pt.roll_angle[0][0] * (tot - pt.roll_angle[0][1]) +\
- pt.roll_angle[1][0] * (tot - pt.roll_angle[1][1])) / tot
-
- #### print pt.roll_angle, 'interpolated roll'
-
- pt.roll(pt.roll_angle)
-
- # Done with temp average list. now we know the best roll for each branch.
-
- # mesh the data
- for brch in self.branches_all:
- for pt in brch.bpoints:
- pt.toMesh(self.mesh)
-
- #faces_extend = [ face for brch in self.branches_all for pt in brch.bpoints for face in pt.faces if face ]
-
-
-
- faces_extend = []
- for brch in self.branches_all:
- if brch.parent_pt:
- faces_extend.extend(brch.faces)
- for pt in brch.bpoints:
- for face in pt.faces:
- if face:
- faces_extend.append(face)
-
- if do_cap_ends:
- # TODO - UV map and image?
- faces_extend.extend([ brch.bpoints[-1].verts for brch in self.branches_all ])
-
- faces = self.mesh.faces
-
- faces.extend(faces_extend, smooth=True)
-
- if do_uv:
- # Assign the faces back
- face_index = 0
- for brch in self.branches_all:
- if brch.parent_pt:
- for i in (0,1,2,3):
- face = brch.faces[i] = faces[face_index+i]
- face_index +=4
-
- for pt in brch.bpoints:
- for i in (0,1,2,3):
- if pt.faces[i]:
- pt.faces[i] = faces[face_index]
- face_index +=1
-
- #if self.mesh.faces:
- # self.mesh.faceUV = True
- mesh.addUVLayer( 'base' )
-
- # rename the uv layer
- #mesh.renameUVLayer(mesh.getUVLayerNames()[0], 'base')
-
- for brch in self.branches_all:
-
- uv_x_scale_branch = 1.0
- if do_uv_uscale:
- uv_x_scale_branch = 0.0
- for pt in brch.bpoints:
- uv_x_scale_branch += pt.radius
-
- uv_x_scale_branch = uv_x_scale_branch / len(brch.bpoints)
- # uv_x_scale_branch = brch.bpoints[0].radius
-
- if do_uv_vnormalize:
- uv_normalize = []
-
- def uvmap_faces(my_faces, y_val, y_size):
- '''
- Accept a branch or pt faces
- '''
- uv_ls = [None, None, None, None]
- for i in (0,1,2,3):
- if my_faces[i]:
- if uv_image:
- my_faces[i].image = uv_image
- uvs = my_faces[i].uv
- else:
- # Use these for calculating blending values
- uvs = [Vector(0,0), Vector(0,0), Vector(0,0), Vector(0,0)]
-
- uv_ls[i] = uvs
-
- x1 = i*0.25 * uv_x_scale * uv_x_scale_branch
- x2 = (i+1)*0.25 * uv_x_scale * uv_x_scale_branch
-
- uvs[3].x = x1;
- uvs[3].y = y_val+y_size
-
- uvs[0].x = x1
- uvs[0].y = y_val
-
- uvs[1].x = x2
- uvs[1].y = y_val
-
- uvs[2].x = x2
- uvs[2].y = y_val+y_size
-
- if do_uv_vnormalize:
- uv_normalize.extend(uvs)
-
- return uv_ls
-
- # Done uvmap_faces
-
- y_val = 0.0
-
- if brch.parent_pt:
- y_size = (brch.getParentFaceCent() - brch.bpoints[0].co).length
-
- if do_uv_keep_vproportion:
- y_size = y_size / ((brch.bpoints[0].radius + brch.parent_pt.radius)/2) * uv_y_scale
-
- brch.uv = uvmap_faces(brch.faces, 0.0, y_size)
-
- y_val += y_size
-
- for pt in brch.bpoints:
- if pt.next:
- y_size = (pt.co-pt.next.co).length
- # scale the uvs by the radius, avoids stritching.
- if do_uv_keep_vproportion:
- y_size = y_size / pt.radius * uv_y_scale
- pt.uv = uvmap_faces(pt.faces, y_val, y_size)
- y_val += y_size
-
-
- if do_uv_vnormalize and uv_normalize:
- # Use yscale here so you can choose to have half the normalized value say.
- vscale = (1/uv_normalize[-1].y) * uv_y_scale
- for uv in uv_normalize:
- uv.y *= vscale
-
-
- # Done with UV mapping the first layer! now map the blend layers
- if do_uv_blend_layer:
- # Set up the blend UV layer - this is simply the blending for branch joints
- mesh.addUVLayer( 'blend' )
- mesh.activeUVLayer = 'blend'
-
- # Set all faces to be on full blend
- for f in mesh.faces:
- for uv in f.uv:
- uv.y = uv.x = 0.0
-
- for brch in self.branches_all:
- if brch.parent_pt:
- for f in brch.faces:
- if f:
- uvs = f.uv
- uvs[0].x = uvs[1].x = uvs[2].x = uvs[3].x = 0.0
- uvs[0].y = uvs[1].y = 1.0 # swap these? - same as inverting the blend
- uvs[2].y = uvs[3].y = 0.0
-
- # Set up the join UV layer, this overlays nice blended
- mesh.addUVLayer( 'join' )
- mesh.activeUVLayer = 'join'
-
- # Set all faces to be on full blend
- for f in mesh.faces:
- for uv in f.uv:
- uv.y = uv.x = 0.0
-
- for brch in self.branches_all:
- if brch.parent_pt:
- # The UV's that this branch would cover if it was a face,
- uvs_base = brch.parent_pt.uv[brch.getParentQuadIndex()]
-
- uvs_base_mid = Vector(0,0)
- for uv in uvs_base:
- uvs_base_mid += uv
-
- uvs_base_mid *= 0.25
-
- # TODO - Factor scale and distance in here
- ## uvs_base_small = [(uv+uvs_base_mid)*0.5 for uv in uvs_base]
- uvs_base_small = [uvs_base_mid, uvs_base_mid, uvs_base_mid, uvs_base_mid]
-
- if brch.faces[0]:
- f = brch.faces[0]
- uvs = f.uv
- uvs[0][:] = uvs_base[0]
- uvs[1][:] = uvs_base[1]
-
- uvs[2][:] = uvs_base_small[1]
- uvs[3][:] = uvs_base_small[0]
-
- if brch.faces[1]:
- f = brch.faces[1]
- uvs = f.uv
- uvs[0][:] = uvs_base[1]
- uvs[1][:] = uvs_base[2]
-
- uvs[2][:] = uvs_base_small[2]
- uvs[3][:] = uvs_base_small[1]
-
- if brch.faces[2]:
- f = brch.faces[2]
- uvs = f.uv
- uvs[0][:] = uvs_base[2]
- uvs[1][:] = uvs_base[3]
-
- uvs[2][:] = uvs_base_small[3]
- uvs[3][:] = uvs_base_small[2]
-
- if brch.faces[3]:
- f = brch.faces[3]
- uvs = f.uv
- uvs[0][:] = uvs_base[3]
- uvs[1][:] = uvs_base[0]
-
- uvs[2][:] = uvs_base_small[0]
- uvs[3][:] = uvs_base_small[3]
-
- mesh.activeUVLayer = 'base' # just so people dont get worried the texture is not there - dosnt effect rendering.
- else:
- # no UV's
- pass
-
- if do_cap_ends:
- # de-select end points for
- i = len(faces)-1
-
- cap_end_face_start = len(faces) - len(self.branches_all)
-
- j = 0
- for i in xrange(cap_end_face_start, len(faces)):
- self.branches_all[j].face_cap = faces[i]
- faces[i].sel = 0
-
- # default UV's are ok for now :/
- if do_uv and uv_image:
- faces[i].image = uv_image
-
- j +=1
-
- # set edge crease for capped ends.
- for ed in self.mesh.edges:
- if ed.v1.sel==False and ed.v2.sel==False:
- ed.crease = 255
- ed.sel = True # so its all selected still
-
- del faces_extend
-
- return self.mesh
-
- def toLeafMesh(self, mesh_leaf,\
- leaf_branch_limit = 0.5,\
- leaf_branch_limit_rand = 0.8,\
- leaf_branch_limit_type_curve = False,\
- leaf_branch_limit_type_grow = False,\
- leaf_branch_limit_type_fill = False,\
- leaf_size = 0.5,\
- leaf_size_rand = 0.5,\
- leaf_branch_density = 0.2,\
- leaf_branch_pitch_angle = 0.0,\
- leaf_branch_pitch_rand = 0.2,\
- leaf_branch_roll_rand = 0.2,\
- leaf_branch_angle = 75.0,\
- leaf_rand_seed = 1.0,\
- leaf_object=None,\
- ):
-
- '''
- return a mesh with leaves seperate from the tree
-
- Add to the existing mesh.
- '''
-
- #radius = [(pt.radius for pt in self.branches_all for pt in brch.bpoints for pt in brch.bpoints]
- mesh_leaf = freshMesh(mesh_leaf)
- self.mesh_leaf = mesh_leaf
-
- # if not leaf_object: return # make the dupli anyway :/ - they can do it later or the script could complain
-
- if leaf_branch_limit == 1.0:
- max_radius = 1000000.0
- else:
- # We wont place leaves on all branches so...
- # first collect stats, we want to know the average radius and total segments
- totpoints = 0
- radius = 0.0
- max_radius = 0.0
- for brch in self.branches_all:
- for pt in brch.bpoints:
- radius += pt.radius
- if pt.radius > max_radius:
- max_radius = pt.radius
-
- #totpoints += len(brch.bpoints)
-
- radius_max = max_radius * leaf_branch_limit
-
- verts_extend = []
- faces_extend = []
-
- co1 = Vector(0.0, -0.5, -0.5)
- co2 = Vector(0.0, -0.5, 0.5)
- co3 = Vector(0.0, 0.5, 0.5)
- co4 = Vector(0.0, 0.5, -0.5)
-
- rnd_seed = [leaf_rand_seed] # could have seed as an input setting
-
- for brch in self.branches_all:
-
- # quick test, do we need leaves on this branch?
- if leaf_branch_limit != 1.0 and brch.bpoints[-1].radius > radius_max:
- continue
-
-
- for pt in brch.bpoints:
-
- # For each point we can add 2 leaves
- for odd_even in (0,1):
-
-
- if (pt == brch.bpoints[-1] and odd_even==1) or \
- (leaf_branch_density != 1.0 and leaf_branch_density < next_random_num(rnd_seed)):
- pass
- else:
- if leaf_branch_limit_rand:
- # (-1 : +1) * leaf_branch_limit_rand
- rnd = 1 + (((next_random_num(rnd_seed) - 0.5) * 2 ) * leaf_branch_limit_rand)
- else:
- rnd = 1.0
-
- if pt.childCount == 0 and (leaf_branch_limit == 1.0 or (pt.radius * rnd) < radius_max):
- leaf_size_tmp = leaf_size * (1.0-(next_random_num(rnd_seed)*leaf_size_rand))
-
- # endpoints dont rotate
- if pt.next != None:
- cross1 = zup.cross(pt.no) # use this to offset the leaf later
- cross2 = cross1.cross(pt.no)
- if odd_even ==0:
- mat_yaw = RotationMatrix(leaf_branch_angle, 3, 'r', cross2)
- else:
- mat_yaw = RotationMatrix(-leaf_branch_angle, 3, 'r', cross2)
-
- leaf_no = (pt.no * mat_yaw)
-
- # Correct upwards pointing from changing the yaw
- #my_up = zup * mat
-
- # correct leaf location for branch width
- cross1.length = pt.radius/2
- leaf_co = pt.co + cross1
- else:
- # no correction needed, we are at the end of the branch
- leaf_no = pt.no
- leaf_co = pt.co
-
- mat = Matrix([leaf_size_tmp,0,0],[0,leaf_size_tmp,0],[0,0,leaf_size_tmp]) * leaf_no.toTrackQuat('x', 'z').toMatrix()
-
- # Randomize pitch and roll for the leaf
-
- # work out the axis to pitch and roll
- cross1 = zup.cross(leaf_no) # use this to offset the leaf later
- if leaf_branch_pitch_rand or leaf_branch_pitch_angle:
-
- angle = -leaf_branch_pitch_angle
- if leaf_branch_pitch_rand:
- angle += leaf_branch_pitch_rand * ((next_random_num(rnd_seed)-0.5)*360)
-
- mat_pitch = RotationMatrix( angle, 3, 'r', cross1)
- mat = mat * mat_pitch
- if leaf_branch_roll_rand:
- mat_roll = RotationMatrix( leaf_branch_roll_rand * ((next_random_num(rnd_seed)-0.5)*360), 3, 'r', leaf_no)
- mat = mat * mat_roll
-
- mat = mat.resize4x4() * TranslationMatrix(leaf_co)
-
- i = len(verts_extend)
- faces_extend.append( (i,i+1,i+2,i+3) )
- verts_extend.extend([tuple(co4*mat), tuple(co3*mat), tuple(co2*mat), tuple(co1*mat)])
- #count += 1
-
-
- # setup dupli's
-
- self.mesh_leaf.verts.extend(verts_extend)
- self.mesh_leaf.faces.extend(faces_extend)
-
- return self.mesh_leaf
-
-
- def toArmature(self, ob_arm, armature):
-
- armature.drawType = Blender.Armature.STICK
- armature.makeEditable() # enter editmode
-
- # Assume toMesh has run
- self.armature = armature
- for bonename in armature.bones.keys():
- del armature.bones[bonename]
-
-
- group_names = []
-
- for i, brch in enumerate(self.branches_all):
-
- # get a list of parent points to make into bones. use parents and endpoints
- bpoints_parent = [pt for pt in brch.bpoints if pt.childCount or pt.prev == None or pt.next == None]
- bpbone_last = None
- for j in xrange(len(bpoints_parent)-1):
-
- # bone container class
- bpoints_parent[j].bpbone = bpbone = bpoint_bone()
- bpbone.name = '%i_%i' % (i,j) # must be unique
- group_names.append(bpbone.name)
-
- bpbone.editbone = Blender.Armature.Editbone() # automatically added to the armature
- self.armature.bones[bpbone.name] = bpbone.editbone
-
- bpbone.editbone.head = bpoints_parent[j].co
- bpbone.editbone.head = bpoints_parent[j].co
- bpbone.editbone.tail = bpoints_parent[j+1].co
-
- # parent the chain.
- if bpbone_last:
- bpbone.editbone.parent = bpbone_last.editbone
- bpbone.editbone.options = [Blender.Armature.CONNECTED]
-
- bpbone_last = bpbone
-
- for brch in self.branches_all:
- if brch.parent_pt: # We must have a parent
-
- # find the bone in the parent chain to use for the parent of this
- parent_pt = brch.parent_pt
- bpbone_parent = None
- while parent_pt:
- bpbone_parent = parent_pt.bpbone
- if bpbone_parent:
- break
-
- parent_pt = parent_pt.prev
-
-
- if bpbone_parent:
- brch.bpoints[0].bpbone.editbone.parent = bpbone_parent.editbone
- else: # in rare cases this may not work. should be verry rare but check anyway.
- print 'this is really odd... look into the bug.'
-
- self.armature.update() # exit editmode
-
- # Skin the mesh
- if self.mesh:
- for group in group_names:
- self.mesh.addVertGroup(group)
-
- for brch in self.branches_all:
- vertList = []
- group = '' # dummy
-
- for pt in brch.bpoints:
- if pt.bpbone:
- if vertList:
- self.mesh.assignVertsToGroup(group, vertList, 1.0, Blender.Mesh.AssignModes.ADD)
-
- vertList = []
- group = pt.bpbone.name
-
- vertList.extend( [v.index for v in pt.verts] )
-
- if vertList:
- self.mesh.assignVertsToGroup(group, vertList, 1.0, Blender.Mesh.AssignModes.ADD)
-
- return self.armature
-
- def toAction(self, ob_arm, texture, anim_speed=1.0, anim_magnitude=1.0, anim_speed_size_scale=True, anim_offset_scale=1.0):
- # Assume armature
- action = ob_arm.action
- if not action:
- action = bpy.data.actions.new()
- action.fakeUser = False # so we dont get masses of bad data
- ob_arm.action = action
-
- # Blender.Armature.NLA.ob_arm.
- pose = ob_arm.getPose()
-
- for pose_bone in pose.bones.values():
- pose_bone.insertKey(ob_arm, 0, [Blender.Object.Pose.ROT], True)
-
- # Now get all the IPO's
-
- ipo_dict = action.getAllChannelIpos()
- # print ipo_dict
-
- # Sicne its per frame, it increases very fast. scale it down a bit
- anim_speed = anim_speed/100
-
- # When we have the same trees next to eachother, they will animate the same way unless we give each its own texture or offset settings.
- # We can use the object's location as a factor - this also will have the advantage? of seeing the animation move across the tree's
- # allow a scale so the difference between tree textures can be adjusted.
- anim_offset = self.objectCurve.matrixWorld.translationPart() * anim_offset_scale
-
- anim_speed_final = anim_speed
- # Assign drivers to them all
- for name, ipo in ipo_dict.iteritems():
- tex_str = 'b.Texture.Get("%s")' % texture.name
-
- if anim_speed_size_scale:
- # Adjust the speed by the bone size.
- # get the point from the name. a bit ugly but works fine ;) - Just dont mess the index up!
- lookup = [int(val) for val in name.split('_')]
- pt = self.branches_all[ lookup[0] ].bpoints[ lookup[1] ]
- anim_speed_final = anim_speed / (1+pt.radius)
-
- cu = ipo[Blender.Ipo.PO_QUATX]
- try: cu.delBezier(0)
- except: pass
- cu.driver = 2 # Python expression
- cu.driverExpression = '%.3f*(%s.evaluate(((b.Get("curframe")*%.3f)+%.3f,%.3f,%.3f)).w-0.5)' % (anim_magnitude, tex_str, anim_speed_final, anim_offset.x, anim_offset.y, anim_offset.z)
-
- cu = ipo[Blender.Ipo.PO_QUATY]
- try: cu.delBezier(0)
- except: pass
- cu.driver = 2 # Python expression
- cu.driverExpression = '%.3f*(%s.evaluate((%.3f,(b.Get("curframe")*%.3f)+%.3f,%.3f)).w-0.5)' % (anim_magnitude, tex_str, anim_offset.x, anim_speed_final, anim_offset.y, anim_offset.z)
-
- cu = ipo[Blender.Ipo.PO_QUATZ]
- try: cu.delBezier(0)
- except: pass
- cu.driver = 2 # Python expression
- cu.driverExpression = '%.3f*(%s.evaluate((%.3f,%.3f,(b.Get("curframe")*%.3f)+%.3f)).w-0.5)' % (anim_magnitude, tex_str, anim_offset.x, anim_offset.y, anim_speed_final, anim_offset.z)
-
-xyzup = Vector(1,1,1).normalize()
-xup = Vector(1,0,0)
-yup = Vector(0,1,0)
-zup = Vector(0,0,1)
-
-class bpoint_bone:
- def __init__(self):
- self.name = None
- self.editbone = None
- self.blenbone = None
- self.posebone = None
-
-class bpoint(object):
- ''' The point in the middle of the branch, not the mesh points
- '''
- __slots__ = 'branch', 'co', 'no', 'radius', 'vecs', 'verts', 'children', 'faces', 'uv', 'next', 'prev', 'childCount', 'bpbone', 'roll_angle', 'nextMidCo', 'childrenMidCo', 'childrenMidRadius', 'targetCos', 'inTwigBounds'
- def __init__(self, brch, co, no, radius):
- self.branch = brch
- self.co = co
- self.no = no
- self.radius = radius
- self.vecs = [None, None, None, None] # 4 for now
- self.verts = [None, None, None, None]
- self.children = [None, None, None, None] # child branches, dont fill in faces here
- self.faces = [None, None, None, None]
- self.uv = None # matching faces, except - UV's are calculated even if there is no face, this is so we can calculate the blending UV's
- self.next = None
- self.prev = None
- self.childCount = 0
- self.bpbone = None # bpoint_bone instance
-
- # when set, This is the angle we need to roll to best face our branches
- # the roll that is set may be interpolated if we are between 2 branches that need to roll.
- # Set to None means that the roll will be left default (from parent)
- self.roll_angle = None
-
-
- # The location between this and the next point,
- # if we want to be tricky we can try make this not just a simple
- # inbetween and use the normals to have some curvature
- self.nextMidCo = None
-
- # Similar to above, median point of all children
- self.childrenMidCo = None
-
- # Similar as above, but for radius
- self.childrenMidRadius = None
-
- # Target locations are used when you want to move the point to a new location but there are
- # more then 1 influence, build up a list and then apply
- self.targetCos = []
-
- # When we use twig bounding mesh, store if this point is in the bounding mesh. Assume true unless we set to false and do the test
- self.inTwigBounds = True
-
- def __repr__(self):
- s = ''
- s += '\t\tco:', self.co
- s += '\t\tno:', self.no
- s += '\t\tradius:', self.radius
- s += '\t\tchildren:', [(child != False) for child in self.children]
- return s
-
- def makeLast(self):
- self.next = None
- self.nextMidCo = None
- self.childrenMidCo = None
-
- def setCo(self, co):
- self.co[:] = co
- self.calcNextMidCo()
- self.calcNormal()
-
- if self.prev:
- self.prev.calcNextMidCo()
- self.prev.calcNormal()
- self.prev.calcChildrenMidData()
-
- if self.next:
- self.prev.calcNormal()
-
- self.calcChildrenMidData()
-
-
- def nextLength(self):
- return (self.co-self.next.co).length
- def prevLength(self):
- return (self.co-self.prev.co).length
-
- def hasOverlapError(self):
- if self.prev == None:
- return False
- if self.next == None:
- return False
- '''
- # see if this point sits on the line between its siblings.
- co, fac = ClosestPointOnLine(self.co, self.prev.co, self.next.co)
-
- if fac >= 0.0 and fac <= 1.0:
- return False # no overlap, we are good
- else:
- return True # error, some overlap
- '''
-
-
- # Alternate method, maybe better
- ln = self.nextLength()
- lp = self.prevLength()
- ls = (self.prev.co-self.next.co).length
-
- # Are we overlapping? the length from our next or prev is longer then the next-TO-previous?
- if ln>ls or lp>ls:
- return True
- else:
- return False
-
-
- def applyTargetLocation(self):
- if not self.targetCos:
- return False
- elif len(self.targetCos) == 1:
- co_all = self.targetCos[0]
- else:
- co_all = Vector()
- for co in self.targetCos:
- co_all += co
- co_all = co_all / len(self.targetCos)
-
- self.targetCos[:] = []
-
- length = (self.co-co_all).length
- # work out if we are moving up or down
- if AngleBetweenVecsSafe(self.no, self.co - co_all) < 90:
-
- # Up
- while length > (self.co-self.prev.co).length:
- if not self.collapseUp():
- break
-
- else:
- # Down
- while length*2 > (self.co-self.next.co).length:
- if not self.collapseDown():
- break
-
- self.setCo(co_all)
-
- return True
-
- def calcNextMidCo(self):
- if not self.next:
- return None
-
- # be tricky later.
- self.nextMidCo = (self.co + self.next.co) * 0.5
-
- def calcNormal(self):
- if self.prev == None:
- self.no = (self.next.co - self.co).normalize()
- elif self.next == None:
- self.no = (self.co - self.prev.co).normalize()
- else:
- self.no = (self.next.co - self.prev.co).normalize()
-
- def calcChildrenMidData(self):
- '''
- Calculate childrenMidCo & childrenMidRadius
- This is a bit tricky, we need to find a point between this and the next,
- the medium of all children, this point will be on the line between this and the next.
- '''
- if not self.next:
- return None
-
- # factor between this and the next point
- radius = factor = factor_i = 0.0
-
- count = 0
- for brch in self.children:
- if brch: # we dont need the co at teh moment.
- co, fac = ClosestPointOnLine(brch.bpoints[0].co, self.co, self.next.co)
- factor_i += fac
- count += 1
-
- radius += brch.bpoints[0].radius
-
- if not count:
- return
-
- # interpolate points
- factor_i = factor_i/count
- factor = 1-factor_i
-
- self.childrenMidCo = (self.co * factor) + (self.next.co * factor_i)
- self.childrenMidRadius = radius
-
- #debug_pt(self.childrenMidCo)
-
- def getAbsVec(self, index):
- # print self.vecs, index
- return self.co + self.vecs[index]
-
- def slide(self, factor):
- '''
- Slides the segment up and down using the prev and next points
- '''
- self.setCo(self.slideCo(factor))
-
- def slideCo(self, factor):
- if self.prev == None or self.next == None or factor==0.0:
- return
-
- if factor < 0.0:
- prev_co = self.prev.co
- co = self.co
-
- ofs = co-prev_co
- ofs.length = abs(factor)
- self.co - ofs
-
- return self.co - ofs
- else:
- next_co = self.next.co
- co = self.co
-
- ofs = co-next_co
- ofs.length = abs(factor)
-
- return self.co - ofs
-
-
- def collapseDown(self):
- '''
- Collapse the next point into this one
- '''
-
- # self.next.next == None check is so we dont shorten the final length of branches.
- if self.next == None or self.next.next == None or self.childCount or self.next.childCount:
- return False
-
- self.branch.bpoints.remove(self.next)
- self.next = self.next.next # skip
- self.next.prev = self
-
- # Watch this place - must update all data thats needed. roll is not calculaetd yet.
- self.calcNextMidCo()
- return True
-
- def collapseUp(self):
- '''
- Collapse the previous point into this one
- '''
-
- # self.next.next == None check is so we dont shorten the final length of branches.
- if self.prev == None or self.prev.prev == None or self.prev.childCount or self.prev.prev.childCount:
- return False
-
- self.branch.bpoints.remove(self.prev)
- self.prev = self.prev.prev # skip
- self.prev.next = self
-
- # Watch this place - must update all data thats needed. roll is not calculaetd yet.
- self.prev.calcNextMidCo()
- return True
-
-
- def smooth(self, factor, factor_joint):
- '''
- Blend this point into the other 2 points
- '''
- if self.next == None or self.prev == None:
- return False
-
- if self.childCount or self.prev.childCount:
- factor = factor_joint;
-
- if factor==0.0:
- return False;
-
- radius = (self.next.radius + self.prev.radius)/2.0
- no = (self.next.no + self.prev.no).normalize()
-
- # do a line intersect to work out the best location
- '''
- cos = LineIntersect( self.next.co, self.next.co+self.next.no,\
- self.prev.co, self.prev.co+self.prev.no)
- if cos == None:
- co = (self.prev.co + self.next.co)/2.0
- else:
- co = (cos[0]+cos[1])/2.0
- '''
- # Above can give odd results every now and then
- co = (self.prev.co + self.next.co)/2.0
-
- # Now apply
- factor_i = 1.0-factor
- self.setCo(self.co*factor_i + co*factor)
- self.radius = self.radius*factor_i + radius*factor
-
- return True
-
- def childPoint(self, index):
- '''
- Returns the middle point for any children between this and the next edge
- '''
- if self.next == None:
- raise 'Error'
-
- if index == 0: return (self.getAbsVec(0) + self.next.getAbsVec(1)) / 2
- if index == 1: return (self.getAbsVec(1) + self.next.getAbsVec(2)) / 2
- if index == 2: return (self.getAbsVec(2) + self.next.getAbsVec(3)) / 2
- if index == 3: return (self.getAbsVec(3) + self.next.getAbsVec(0)) / 2
-
- def childPointUnused(self, index):
- '''
- Same as above but return None when the point is alredy used.
- '''
- if self.children[index]:
- return None
- return self.childPoint(index)
-
-
- def roll(self, angle):
- '''
- Roll the quad about its normal
- use for aurienting the sides of a quad to meet a branch that stems from here...
- '''
- # debugVec(self.co, self.co + self.no)
-
- mat = RotationMatrix(angle, 3, 'r', self.no)
- for i in xrange(4):
- self.vecs[i] = self.vecs[i] * mat
-
-
- def toMesh(self, mesh):
- self.verts[0].co = self.getAbsVec(0)
- self.verts[1].co = self.getAbsVec(1)
- self.verts[2].co = self.getAbsVec(2)
- self.verts[3].co = self.getAbsVec(3)
-
- if not self.next:
- return
-
- if self.prev == None and self.branch.parent_pt:
- # join from parent branch
-
- # which side are we of the parents quad
- index = self.branch.parent_pt.children.index(self.branch)
-
- # collect the points we are to merge into between the parent its next point
- if index==0: verts = [self.branch.parent_pt.verts[0], self.branch.parent_pt.verts[1], self.branch.parent_pt.next.verts[1], self.branch.parent_pt.next.verts[0]]
- if index==1: verts = [self.branch.parent_pt.verts[1], self.branch.parent_pt.verts[2], self.branch.parent_pt.next.verts[2], self.branch.parent_pt.next.verts[1]]
- if index==2: verts = [self.branch.parent_pt.verts[2], self.branch.parent_pt.verts[3], self.branch.parent_pt.next.verts[3], self.branch.parent_pt.next.verts[2]]
- if index==3: verts = [self.branch.parent_pt.verts[3], self.branch.parent_pt.verts[0], self.branch.parent_pt.next.verts[0], self.branch.parent_pt.next.verts[3]]
-
-
- # Watchout for overlapping faces!
- self.branch.faces[:] =\
- [verts[0], verts[1], self.verts[1], self.verts[0]],\
- [verts[1], verts[2], self.verts[2], self.verts[1]],\
- [verts[2], verts[3], self.verts[3], self.verts[2]],\
- [verts[3], verts[0], self.verts[0], self.verts[3]]
-
- # normal join, parents or no parents
- if not self.children[0]: self.faces[0] = [self.verts[0], self.verts[1], self.next.verts[1], self.next.verts[0]]
- if not self.children[1]: self.faces[1] = [self.verts[1], self.verts[2], self.next.verts[2], self.next.verts[1]]
- if not self.children[2]: self.faces[2] = [self.verts[2], self.verts[3], self.next.verts[3], self.next.verts[2]]
- if not self.children[3]: self.faces[3] = [self.verts[3], self.verts[0], self.next.verts[0], self.next.verts[3]]
-
- def calcVerts(self):
- if self.prev == None:
- if self.branch.parent_pt:
- cross = self.no.cross(self.branch.parent_pt.no) * RotationMatrix(-45, 3, 'r', self.no)
- else:
- # parentless branch - for best results get a cross thats not the same as the normal, in rare cases this happens.
-
- # Was just doing
- # cross = zup
- # which works most of the time, but no verticle lines
-
- if AngleBetweenVecsSafe(self.no, zup) > 1.0: cross = zup
- elif AngleBetweenVecsSafe(self.no, yup) > 1.0: cross = yup
- else: cross = xup
-
- else:
- cross = self.prev.vecs[0].cross(self.no)
-
- self.vecs[0] = self.no.cross(cross)
- self.vecs[0].length = abs(self.radius)
- mat = RotationMatrix(90, 3, 'r', self.no)
- self.vecs[1] = self.vecs[0] * mat
- self.vecs[2] = self.vecs[1] * mat
- self.vecs[3] = self.vecs[2] * mat
-
- def hasChildren(self):
- '''
- Use .childCount where possible, this does the real check
- '''
- if self.children.count(None) == 4:
- return False
- else:
- return True
-
-class branch:
- def __init__(self):
- self.bpoints = []
- self.parent_pt = None
- self.tag = False # have we calculated our points
- self.face_cap = None
- self.length = -1
- # self.totchildren = 0
- # Bones per branch
- self.faces = [None, None, None, None]
- self.uv = None # face uvs can be fake, always 4
- self.bones = []
- self.generation = 0 # use to limit twig reproduction
- self.twig_count = 0 # count the number of twigs - so as to limit how many twigs a branch gets
- # self.myindex = -1
- ### self.segment_spacing_scale = 1.0 # use this to scale up the spacing - so small twigs dont get WAY too many polys
- self.type = None
-
- def __repr__(self):
- s = ''
- s += '\tbranch'
- s += '\tbpoints:', len(self.bpoints)
- for pt in brch.bpoints:
- s += str(self.pt)
-
- def getNormal(self):
- return (self.bpoints[-1].co - self.bpoints[0].co).normalize()
-
- def getParentAngle(self):
- if self.parent_pt:
- return AngleBetweenVecsSafe(self.parent_pt.no, self.bpoints[0].no )
- else:
- return 45.0
-
- def getParentRadiusRatio(self):
- if self.parent_pt:
- return self.bpoints[0].radius / self.parent_pt.radius
- else:
- return 0.8
-
- def getLength(self):
- return (self.bpoints[0].co - self.bpoints[-1].co).length
-
- def getStraightness(self):
- straight = 0.0
- pt = self.bpoints[0]
- while pt.next:
- straight += AngleBetweenVecsSafe(pt.no, pt.next.no)
- pt = pt.next
- return straight
-
-
- '''
- def calcTotChildren(self):
- for pt in self.bpoints:
- self.totchildren += pt.childCount
- '''
- def calcData(self):
- '''
- Finalize once point data is there
- '''
- self.calcPointLinkedList()
- self.calcPointExtras()
-
- def calcPointLinkedList(self):
- for i in xrange(1, len(self.bpoints)-1):
- self.bpoints[i].next = self.bpoints[i+1]
- self.bpoints[i].prev = self.bpoints[i-1]
-
- self.bpoints[0].next = self.bpoints[1]
- self.bpoints[-1].prev = self.bpoints[-2]
-
- def calcPointExtras(self):
- '''
- Run on a new branch or after transforming an existing one.
- '''
- for pt in self.bpoints:
- pt.calcNormal()
- pt.calcNextMidCo()
-
- def calcTwigBounds(self, tree):
- '''
- Check if out points are
- '''
- for pt in self.bpoints:
- pt.inTwigBounds = tree.isPointInTwigBounds(pt.co)
- #if pt.inTwigBounds:
- # debug_pt(pt.co)
-
- def baseTrim(self, connect_base_trim):
- # if 1) dont remove the whole branch, maybe an option but later
- # if 2) we are alredy a parent, cant remove me now.... darn :/ not nice...
- # could do this properly but it would be slower and its a corner case.
- #
- # if 3) this point is within the branch, remove it.
- # Scale this value by the difference in radius, a low trim looks better when the parent is a lot bigger..
- #
-
- while len(self.bpoints)>2 and\
- self.bpoints[0].childCount == 0 and\
- (self.parent_pt.nextMidCo - self.bpoints[0].co).length < ((self.parent_pt.radius + self.parent_pt.next.radius)/4) + (self.bpoints[0].radius * connect_base_trim):
- # Note /4 - is a bit odd, since /2 is correct, but /4 lets us have more tight joints by default
-
-
- del self.bpoints[0]
- self.bpoints[0].prev = None
-
- def boundsTrim(self):
- '''
- depends on calcTwigBounds running first. - also assumes no children assigned yet! make sure this is always the case.
- '''
- trim = False
- for i, pt in enumerate(self.bpoints):
- if not pt.inTwigBounds:
- trim = True
- break
-
- # We must have at least 2 points to be a valid branch. this will be a stump :/
- if not trim or i < 3:
- self.bpoints = [] #
- return
-
- # Shorten the point list
- self.bpoints = self.bpoints[:i]
- self.bpoints[-1].makeLast()
-
- def taper(self, twig_ob_bounds_prune_taper = 0.0):
- l = float(len( self.bpoints ))
- for i, pt in enumerate(self.bpoints):
- pt.radius *= (((l-i)/l) + (twig_ob_bounds_prune_taper*(i/l)) )
-
- def getParentBranch(self):
- if not self.parent_pt:
- return None
- return self.parent_pt.branch
-
- def getParentQuadAngle(self):
- '''
- The angle off we are from our parent quad,
- '''
- # used to roll the parent so its faces us better
-
- # Warning this can be zero sometimes, see the try below for the error
- parent_normal = self.getParentFaceCent() - self.parent_pt.nextMidCo
-
-
- self_normal = self.bpoints[1].co - self.parent_pt.co
- # We only want the angle in relation to the parent points normal
- # modify self_normal to make this so
- cross = self_normal.cross(self.parent_pt.no)
- self_normal = self.parent_pt.no.cross(cross) # CHECK
-
- #try: angle = AngleBetweenVecs(parent_normal, self_normal)
- #except: return 0.0
- angle = AngleBetweenVecsSafe(parent_normal, self_normal)
-
-
- # see if we need to rotate positive or negative
- # USE DOT PRODUCT!
- cross = parent_normal.cross(self_normal)
- if AngleBetweenVecsSafe(cross, self.parent_pt.no) > 90:
- angle = -angle
-
- return angle
-
- def getParentQuadIndex(self):
- return self.parent_pt.children.index(self)
- def getParentFaceCent(self):
- return self.parent_pt.childPoint( self.getParentQuadIndex() )
-
- def findClosest(self, co):
- '''
- Find the closest point that can bare a child
- '''
-
-
- ''' # this dosnt work, but could.
- best = None
- best_dist = 100000000
- for pt in self.bpoints:
- if pt.next:
- co_on_line, fac = ClosestPointOnLine(co, pt.co, pt.next.co)
- print fac
- if fac >= 0.0 and fac <= 1.0:
-
- return pt, (co-co_on_line).length
-
- return best, best_dist
- '''
- best = None
- best_dist = 100000000
- for pt in self.bpoints:
- if pt.nextMidCo and pt.childCount < 4:
- dist = (pt.nextMidCo-co).length
- if dist < best_dist:
- best = pt
- best_dist = dist
-
- return best, best_dist
-
- def inParentChain(self, brch):
- '''
- See if this branch is a parent of self or in the chain
- '''
-
- self_parent_lookup = self.getParentBranch()
- while self_parent_lookup:
- if self_parent_lookup == brch:
- return True
- self_parent_lookup = self_parent_lookup.getParentBranch()
-
- return False
-
- def transform(self, mat, loc=None, scale=None):
- if scale==None:
- scale = (xyzup * mat).length
-
- for pt in self.bpoints:
- if loc:
- pt.co = (pt.co * mat) + loc
- else:
- pt.co = pt.co * mat
- pt.radius *= scale
-
- for pt in self.bpoints:
- self.calcPointExtras()
-
- def translate(self, co):
- '''
- Simply move the twig on the branch
- '''
- ofs = self.bpoints[0].co-co
- for pt in self.bpoints:
- pt.co -= ofs
-
- def transformRecursive(self, tree, mat3x3, cent, scale=None):
-
- if scale==None:
- # incase this is a translation matrix
- scale = ((xyzup * mat3x3) - (Vector(0,0,0) * mat3x3)).length
-
- for pt in self.bpoints: pt.co = ((pt.co-cent) * mat3x3) + cent
- #for pt in self.bpoints: pt.co = (pt.co * mat3x3)
- for pt in self.bpoints: self.calcPointExtras()
-
-
- for brch in tree.branches_all:
- if brch.parent_pt:
- if brch.parent_pt.branch == self:
-
- brch.transformRecursive(tree, mat3x3, cent, scale)
-
- '''
- for pt in self.bpoints:
- for brch in pt.children:
- if brch:
- brch.transformRecursive(mat3x3, cent, scale)
- '''
- def bestTwigSegment(self):
- '''
- Return the most free part on the branch to place a new twig
- return (sort_value, best_index, self)
- '''
-
- # loop up and down the branch - counding how far from the last parent segment we are
- spacing1 = [0] * (len(self.bpoints)-1)
- spacing2 = spacing1[:]
-
- step_from_parent = 0
- for i in xrange(len(spacing1)): # -1 because the last pt cant have kits
-
- if self.bpoints[i].childCount or self.bpoints[i].inTwigBounds==False:
- step_from_parent = 0
- else:
- step_from_parent += 1
-
- spacing1[i] += step_from_parent # -1 because the last pt cant have kits
-
- best_index = -1
- best_val = -1
- step_from_parent = 0
- for i in xrange(len(spacing1)-1, -1, -1):
-
- if self.bpoints[i].childCount or self.bpoints[i].inTwigBounds==False:
- step_from_parent = 0
- else:
- step_from_parent += 1
-
- spacing2[i] += step_from_parent
-
- # inTwigBounds is true by default, when twigBounds are used it can be false
- if self.bpoints[i].childCount < 4 and self.bpoints[i].inTwigBounds:
- # Dont allow to assign more verts then 4
- val = spacing1[i] * spacing2[i]
- if val > best_val:
- best_val = val
- best_index = i
-
- #if best_index == -1:
- # raise "Error"
-
- # This value is only used for sorting, so the lower the value - the sooner it gets a twig.
- #sort_val = -best_val + (1/self.getLength())
- sort_val=self.getLength()
-
- return sort_val, best_index, self
-
- def evenPointDistrobution(self, factor=1.0, factor_joint=1.0):
- '''
- Redistribute points that are not evenly distributed
- factor is between 0.0 and 1.0
- '''
-
- for pt in self.bpoints:
- if pt.next and pt.prev and pt.childCount == 0 and pt.prev.childCount == 0:
- w1 = pt.nextLength()
- w2 = pt.prevLength()
- wtot = w1+w2
- if wtot > 0.0:
- w1=w1/wtot
- #w2=w2/wtot
- w1 = abs(w1-0.5)*2 # make this from 0.0 to 1.0, where 0 is the middle and 1.0 is as far out of the middle as possible.
- # print "%.6f" % w1
- pt.smooth(w1*factor, w1*factor_joint)
-
- def fixOverlapError(self, joint_smooth=1.0):
- # Keep fixing until no hasOverlapError left to fix.
-
- error = True
- while error:
- error = False
- for pt in self.bpoints:
- if pt.prev and pt.next:
- if pt.hasOverlapError():
- if pt.smooth(1.0, joint_smooth): # if we cant fix then dont bother trying again.
- error = True
-
- def evenJointDistrobution(self, joint_compression = 1.0):
- # See if we need to evaluate this branch at all
- if len(self.bpoints) <= 2: # Rare but in this case we cant do anything
- return
- has_children = False
- for pt in self.bpoints:
- if pt.childCount:
- has_children = True
- break
-
- if not has_children:
- return
-
- # OK, we have children, so we have some work to do...
- # center each segment
-
- # work out the median location of all points children.
- for pt in self.bpoints:
- pt.calcChildrenMidData()
- pt.targetCos[:] = []
-
- for pt in self.bpoints:
-
- if pt.childrenMidCo:
- # Move this and the next segment to be around the child point.
- # TODO - factor in the branch angle, be careful with this - close angles can have extreme values.
- slide_dist = (pt.childrenMidCo - pt.co).length - (pt.childrenMidRadius * joint_compression)
- co = pt.slideCo( slide_dist )
- if co:
- pt.targetCos.append( co )
-
- slide_dist = (pt.childrenMidRadius * joint_compression) - (pt.childrenMidCo - pt.next.co).length
- co = pt.next.slideCo( slide_dist )
- if co:
- pt.next.targetCos.append( co )
-
- for pt in reversed(self.bpoints):
- pt.applyTargetLocation()
-
- def collapsePoints(self, seg_density=0.5, seg_density_angle=20.0, seg_density_radius=0.3, smooth_joint=1.0):
-
- collapse = True
- while collapse:
- collapse = False
- pt = self.bpoints[0]
- while pt:
- # Collapse angles greater then 90. they are useually artifacts
-
- if pt.prev and pt.next and pt.prev.childCount == 0:
- if (pt.radius + pt.prev.radius) != 0.0 and abs(pt.radius - pt.prev.radius) / (pt.radius + pt.prev.radius) < seg_density_radius:
- ang = AngleBetweenVecsSafe(pt.no, pt.prev.no)
- if seg_density_angle == 180 or ang > 90 or ang < seg_density_angle:
- ## if (pt.prev.nextMidCo-pt.co).length < ((pt.radius + pt.prev.radius)/2) * seg_density:
- if (pt.prev.nextMidCo-pt.co).length < seg_density or ang > 90:
- pt_save = pt.prev
- if pt.next.collapseUp(): # collapse this point
- collapse = True
- pt = pt_save # so we never reference a removed point
-
- if pt.childCount == 0 and pt.next: #if pt.childrenMidCo == None:
- if (pt.radius + pt.next.radius) != 0.0 and abs(pt.radius - pt.next.radius) / (pt.radius + pt.next.radius) < seg_density_radius:
- ang = AngleBetweenVecsSafe(pt.no, pt.next.no)
- if seg_density_angle == 180 or ang > 90 or ang < seg_density_angle:
- # do here because we only want to run this on points with no children,
- # Are we closer theto eachother then the radius?
- ## if (pt.nextMidCo-pt.co).length < ((pt.radius + pt.next.radius)/2) * seg_density:
- if (pt.nextMidCo-pt.co).length < seg_density or ang > 90:
- if pt.collapseDown():
- collapse = True
-
- pt = pt.next
- ## self.checkPointList()
- self.evenPointDistrobution(1.0, smooth_joint)
-
- for pt in self.bpoints:
- pt.calcNormal()
- pt.calcNextMidCo()
-
- # This is a bit dodgy - moving the branches around after placing can cause problems
- """
- def branchReJoin(self):
- '''
- Not needed but nice to run after collapsing incase segments moved a lot
- '''
- if not self.parent_pt:
- return # nothing to do
-
- # see if the next segment is closer now (after collapsing)
- parent_pt = self.parent_pt
- root_pt = self.bpoints[0]
-
- #try:
- index = parent_pt.children.index(self)
- #except:
- #print "This is bad!, but not being able to re-join isnt that big a deal"
-
- current_dist = (parent_pt.nextMidCo - root_pt.co).length
-
- # TODO - Check size of new area is ok to move into
-
- if parent_pt.next and parent_pt.next.next and parent_pt.next.children[index] == None:
- # We can go here if we want, see if its better
- if current_dist > (parent_pt.next.nextMidCo - root_pt.co).length:
- self.parent_pt.children[index] = None
- self.parent_pt.childCount -= 1
-
- self.parent_pt = parent_pt.next
- self.parent_pt.children[index] = self
- self.parent_pt.childCount += 1
- return
-
- if parent_pt.prev and parent_pt.prev.children[index] == None:
- # We can go here if we want, see if its better
- if current_dist > (parent_pt.prev.nextMidCo - root_pt.co).length:
- self.parent_pt.children[index] = None
- self.parent_pt.childCount -= 1
-
- self.parent_pt = parent_pt.prev
- self.parent_pt.children[index] = self
- self.parent_pt.childCount += 1
- return
- """
-
- def checkPointList(self):
- '''
- Error checking. use to check if collapsing worked.
- '''
- p_link = self.bpoints[0]
- i = 0
- while p_link:
- if self.bpoints[i] != p_link:
- raise "Error"
-
- if p_link.prev and p_link.prev != self.bpoints[i-1]:
- raise "Error Prev"
-
- if p_link.next and p_link.next != self.bpoints[i+1]:
- raise "Error Next"
-
- p_link = p_link.next
- i+=1
-
- def mixToNew(self, other, BLEND_MODE):
- '''
- Generate a new branch based on 2 existing ones
- These branches will point 'zup' - aurient 'xup' and have a tip length of 1.0
- '''
-
- # Lets be lazy! - if the branches are different sizes- use the shortest.
- # brch1 is always smaller
-
- brch1 = self
- brch2 = other
- if len(brch1.bpoints) > len(brch2.bpoints):
- brch1, brch2 = brch2, brch1
-
- if len(brch1.bpoints) == 1:
- return None
-
- co_start = brch1.bpoints[0].co
- cos1 = [ pt.co - co_start for pt in brch1.bpoints ]
-
- co_start = brch2.bpoints[0].co
- if len(brch1.bpoints) == len(brch2.bpoints):
- cos2 = [ pt.co - co_start for pt in brch2.bpoints ]
- else: # truncate the points
- cos2 = [ brch2.bpoints[i].co - co_start for i in xrange(len(brch1.bpoints)) ]
-
- scales = []
- for cos_ls in (cos1, cos2):
- cross = cos_ls[-1].cross(zup)
- mat = RotationMatrix(AngleBetweenVecsSafe(cos_ls[-1], zup), 3, 'r', cross)
- cos_ls[:] = [co*mat for co in cos_ls]
-
- # point z-up
-
- # Now they are both pointing the same way aurient the curves to be rotated the same way
- xy_nor = Vector(0,0,0)
- for co in cos_ls:
- xy_nor.x += co.x
- xy_nor.y += co.y
- cross = xy_nor.cross(xup)
-
- # Also scale them here so they are 1.0 tall always
- scale = 1.0/(cos_ls[0]-cos_ls[-1]).length
- mat = RotationMatrix(AngleBetweenVecsSafe(xy_nor, xup), 3, 'r', cross) * Matrix([scale,0,0],[0,scale,0],[0,0,scale])
- cos_ls[:] = [co*mat for co in cos_ls]
-
- scales.append(scale)
-
- # Make the new branch
- new_brch = branch()
- new_brch.type = BRANCH_TYPE_GROWN
- for i in xrange(len(cos1)):
- new_brch.bpoints.append( bpoint(new_brch, (cos1[i]+cos2[i])*0.5, Vector(), (brch1.bpoints[i].radius*scales[0] + brch2.bpoints[i].radius*scales[1])/2) )
-
- new_brch.calcData()
- return new_brch
-
- '''
- def toMesh(self):
- pass
- '''
-
-
-
-
-# No GUI code above this! ------------------------------------------------------
-
-# PREFS - These can be saved on the object's id property. use 'tree2curve' slot
-from Blender import Draw
-import BPyWindow
-ID_SLOT_NAME = 'Curve2Tree'
-
-EVENT_NONE = 0
-EVENT_EXIT = 1
-EVENT_UPDATE = 2
-EVENT_UPDATE_AND_UI = 2
-EVENT_REDRAW = 3
-
-
-# Prefs for each tree
-PREFS = {}
-PREFS['connect_sloppy'] = Draw.Create(1.5)
-PREFS['connect_base_trim'] = Draw.Create(1.0)
-PREFS['seg_density'] = Draw.Create(0.5)
-PREFS['seg_density_angle'] = Draw.Create(20.0)
-PREFS['seg_density_radius'] = Draw.Create(0.3)
-PREFS['seg_joint_compression'] = Draw.Create(1.0)
-PREFS['seg_joint_smooth'] = Draw.Create(2.0)
-PREFS['image_main'] = Draw.Create('')
-PREFS['do_uv'] = Draw.Create(0)
-PREFS['uv_x_scale'] = Draw.Create(4.0)
-PREFS['uv_y_scale'] = Draw.Create(1.0)
-PREFS['do_material'] = Draw.Create(0)
-PREFS['material_use_existing'] = Draw.Create(1)
-PREFS['material_texture'] = Draw.Create(1)
-PREFS['material_stencil'] = Draw.Create(1)
-PREFS['do_subsurf'] = Draw.Create(1)
-PREFS['do_cap_ends'] = Draw.Create(0)
-PREFS['do_uv_keep_vproportion'] = Draw.Create(1)
-PREFS['do_uv_vnormalize'] = Draw.Create(0)
-PREFS['do_uv_uscale'] = Draw.Create(0)
-PREFS['do_armature'] = Draw.Create(0)
-PREFS['do_anim'] = Draw.Create(1)
-try: PREFS['anim_tex'] = Draw.Create([tex for tex in bpy.data.textures][0].name)
-except: PREFS['anim_tex'] = Draw.Create('')
-
-PREFS['anim_speed'] = Draw.Create(0.2)
-PREFS['anim_magnitude'] = Draw.Create(0.2)
-PREFS['anim_speed_size_scale'] = Draw.Create(1)
-PREFS['anim_offset_scale'] = Draw.Create(1.0)
-
-PREFS['do_twigs_fill'] = Draw.Create(0)
-PREFS['twig_fill_levels'] = Draw.Create(4)
-
-PREFS['twig_fill_rand_scale'] = Draw.Create(0.1)
-PREFS['twig_fill_fork_angle_max'] = Draw.Create(180.0)
-PREFS['twig_fill_radius_min'] = Draw.Create(0.001)
-PREFS['twig_fill_radius_factor'] = Draw.Create(0.75)
-PREFS['twig_fill_shape_type'] = Draw.Create(1)
-PREFS['twig_fill_shape_rand'] = Draw.Create(0.5)
-PREFS['twig_fill_shape_power'] = Draw.Create(0.5)
-
-PREFS['do_twigs'] = Draw.Create(0)
-PREFS['twig_ratio'] = Draw.Create(2.0)
-PREFS['twig_select_mode'] = Draw.Create(0)
-PREFS['twig_select_factor'] = Draw.Create(0.5)
-PREFS['twig_scale'] = Draw.Create(0.8)
-PREFS['twig_scale_width'] = Draw.Create(1.0)
-PREFS['twig_random_orientation'] = Draw.Create(180)
-PREFS['twig_random_angle'] = Draw.Create(33)
-PREFS['twig_recursive'] = Draw.Create(1)
-PREFS['twig_recursive_limit'] = Draw.Create(3)
-PREFS['twig_ob_bounds'] = Draw.Create('') # WATCH out, used for do_twigs_fill AND do_twigs
-PREFS['twig_ob_bounds_prune'] = Draw.Create(1)
-PREFS['twig_ob_bounds_prune_taper'] = Draw.Create(1.0)
-PREFS['twig_placement_maxradius'] = Draw.Create(10.0)
-PREFS['twig_placement_maxtwig'] = Draw.Create(4)
-PREFS['twig_follow_parent'] = Draw.Create(0.0)
-PREFS['twig_follow_x'] = Draw.Create(0.0)
-PREFS['twig_follow_y'] = Draw.Create(0.0)
-PREFS['twig_follow_z'] = Draw.Create(0.0)
-
-PREFS['do_leaf'] = Draw.Create(0)
-
-PREFS['leaf_branch_limit'] = Draw.Create(0.25)
-PREFS['leaf_branch_limit_rand'] = Draw.Create(0.1)
-PREFS['leaf_branch_density'] = Draw.Create(0.1)
-PREFS['leaf_branch_pitch_angle'] = Draw.Create(0.0)
-PREFS['leaf_branch_pitch_rand'] = Draw.Create(0.2)
-PREFS['leaf_branch_roll_rand'] = Draw.Create(0.2)
-PREFS['leaf_branch_angle'] = Draw.Create(75.0)
-PREFS['leaf_rand_seed'] = Draw.Create(1.0)
-PREFS['leaf_size'] = Draw.Create(0.5)
-PREFS['leaf_size_rand'] = Draw.Create(0.5)
-
-PREFS['leaf_object'] = Draw.Create('')
-
-PREFS['do_variation'] = Draw.Create(0)
-PREFS['variation_seed'] = Draw.Create(1)
-PREFS['variation_orientation'] = Draw.Create(0.0)
-PREFS['variation_scale'] = Draw.Create(0.0)
-
-GLOBAL_PREFS = {}
-GLOBAL_PREFS['realtime_update'] = Draw.Create(0)
-
-
-def getContextCurveObjects():
- sce = bpy.data.scenes.active
- objects = []
- ob_act = sce.objects.active
- for ob in sce.objects.context:
- if ob == ob_act: ob_act = None
-
- if ob.type != 'Curve':
- ob = ob.parent
- if not ob or ob.type != 'Curve':
- continue
- objects.append(ob)
-
- # Alredy delt with
-
-
- # Add the active, important when using localview or local layers
- if ob_act:
- ob = ob_act
- if ob.type != 'Curve':
- ob = ob.parent
- if not ob or ob.type != 'Curve':
- pass
- else:
- objects.append(ob)
-
- return objects
-
-
-def Prefs2Dict(prefs, new_prefs):
- '''
- Make a copy with no button settings
- '''
- new_prefs.clear()
- for key, val in prefs.items():
- try: new_prefs[key] = val.val
- except: new_prefs[key] = val
- return new_prefs
-
-def Dict2Prefs(prefs, new_prefs):
- '''
- Make a copy with button settings
- '''
- for key in prefs: # items would be nice for id groups
- val = prefs[key]
- ok = True
-
- try:
- # If we have this setting allredy but its a different type, use the old setting (converting int's to floats for instance)
- new_val = new_prefs[key] # this may fail, thats ok
- if (type(new_val)==Blender.Types.ButtonType) and (type(new_val.val) != type(val)):
- ok = False
- except:
- pass
-
- if ok:
- try:
- new_prefs[key] = Blender.Draw.Create( val )
- except:
- new_prefs[key] = val
-
- return new_prefs
-
-def Prefs2IDProp(idprop, prefs):
- new_prefs = {}
- Prefs2Dict(prefs, new_prefs)
- try: del idprop[ID_SLOT_NAME]
- except: pass
-
- idprop[ID_SLOT_NAME] = new_prefs
-
-def IDProp2Prefs(idprop, prefs):
- try:
- prefs = idprop[ID_SLOT_NAME]
- except:
- return False
- Dict2Prefs(prefs, PREFS)
- return True
-
-def buildTree(ob_curve, single=False):
- '''
- Must be a curve object, write to a child mesh
- Must check this is a curve object!
- '''
- print 'Curve2Tree, starting...'
- # if were only doing 1 object, just use the current prefs
- prefs = {}
-
- if single or not (IDProp2Prefs(ob_curve.properties, prefs)):
- prefs = PREFS
-
-
- # Check prefs are ok.
-
-
- sce = bpy.data.scenes.active
-
- def getObChild(parent, obtype):
- try:
- return [ _ob for _ob in sce.objects if _ob.type == obtype if _ob.parent == parent ][0]
- except:
- return None
-
- def newObChild(parent, obdata):
-
- ob_new = bpy.data.scenes.active.objects.new(obdata)
- # ob_new.Layers = parent.Layers
-
- # new object settings
- parent.makeParent([ob_new])
- ob_new.setMatrix(Matrix())
- ob_new.sel = 0
- return ob_new
-
- def hasModifier(modtype):
- return len([mod for mod in ob_mesh.modifiers if mod.type == modtype]) > 0
-
-
- sce = bpy.data.scenes.active
-
- if PREFS['image_main'].val:
- try: image = bpy.data.images[PREFS['image_main'].val]
- except: image = None
- else: image = None
-
- # Get the mesh child
-
- print '\treading blenders curves...',
- time1 = Blender.sys.time()
-
- t = tree()
- t.fromCurve(ob_curve)
- if not t.branches_all:
- return # Empty curve? - may as well not throw an error
-
- time2 = Blender.sys.time() # time print
- """
- print '%.4f sec' % (time2-time1)
- if PREFS['do_twigs'].val:
- print '\tbuilding twigs...',
- t.buildTwigs(ratio=PREFS['twig_ratio'].val)
- time3 = Blender.sys.time() # time print
- print '%.4f sec' % (time3 - time2)
- """
- if 0: pass
- else:
- time3 = Blender.sys.time() # time print
-
- print '\tconnecting branches...',
-
- twig_ob_bounds = getObFromName(PREFS['twig_ob_bounds'].val)
-
- t.buildConnections(\
- sloppy = PREFS['connect_sloppy'].val,\
- connect_base_trim = PREFS['connect_base_trim'].val,\
- do_twigs = PREFS['do_twigs'].val,\
- twig_ratio = PREFS['twig_ratio'].val,\
- twig_select_mode = PREFS['twig_select_mode'].val,\
- twig_select_factor = PREFS['twig_select_factor'].val,\
- twig_scale = PREFS['twig_scale'].val,\
- twig_scale_width = PREFS['twig_scale_width'].val,\
- twig_random_orientation = PREFS['twig_random_orientation'].val,\
- twig_random_angle = PREFS['twig_random_angle'].val,\
- twig_recursive = PREFS['twig_recursive'].val,\
- twig_recursive_limit = PREFS['twig_recursive_limit'].val,\
- twig_ob_bounds = twig_ob_bounds,\
- twig_ob_bounds_prune = PREFS['twig_ob_bounds_prune'].val,\
- twig_ob_bounds_prune_taper = PREFS['twig_ob_bounds_prune_taper'].val,\
- twig_placement_maxradius = PREFS['twig_placement_maxradius'].val,\
- twig_placement_maxtwig = PREFS['twig_placement_maxtwig'].val,\
- twig_follow_parent = PREFS['twig_follow_parent'].val,\
- twig_follow_x = PREFS['twig_follow_x'].val,\
- twig_follow_y = PREFS['twig_follow_y'].val,\
- twig_follow_z = PREFS['twig_follow_z'].val,\
- do_variation = PREFS['do_variation'].val,\
- variation_seed = PREFS['variation_seed'].val,\
- variation_orientation = PREFS['variation_orientation'].val,\
- variation_scale = PREFS['variation_scale'].val,\
- do_twigs_fill = PREFS['do_twigs_fill'].val,\
- twig_fill_levels = PREFS['twig_fill_levels'].val,\
- twig_fill_rand_scale = PREFS['twig_fill_rand_scale'].val,\
- twig_fill_fork_angle_max = PREFS['twig_fill_fork_angle_max'].val,\
- twig_fill_radius_min = PREFS['twig_fill_radius_min'].val,\
- twig_fill_radius_factor = PREFS['twig_fill_radius_factor'].val,\
- twig_fill_shape_type = PREFS['twig_fill_shape_type'].val,\
- twig_fill_shape_rand = PREFS['twig_fill_shape_rand'].val,\
- twig_fill_shape_power = PREFS['twig_fill_shape_power'].val,\
- )
-
- time4 = Blender.sys.time() # time print
- print '%.4f sec' % (time4-time3)
- print '\toptimizing point spacing...',
-
- t.optimizeSpacing(\
- seg_density=PREFS['seg_density'].val,\
- seg_density_angle=PREFS['seg_density_angle'].val,\
- seg_density_radius=PREFS['seg_density_radius'].val,\
- joint_compression = PREFS['seg_joint_compression'].val,\
- joint_smooth = PREFS['seg_joint_smooth'].val\
- )
-
- time5 = Blender.sys.time() # time print
- print '%.4f sec' % (time5-time4)
- print '\tbuilding mesh...',
-
- ob_mesh = getObChild(ob_curve, 'Mesh')
- if not ob_mesh:
- # New object
- mesh = bpy.data.meshes.new('tree_' + ob_curve.name)
- ob_mesh = newObChild(ob_curve, mesh)
- # do subsurf later
-
- else:
- # Existing object
- mesh = ob_mesh.getData(mesh=1)
- ob_mesh.setMatrix(Matrix())
-
- # Do we need a do_uv_blend_layer?
- if PREFS['do_material'].val and PREFS['material_stencil'].val and PREFS['material_texture'].val:
- do_uv_blend_layer = True
- else:
- do_uv_blend_layer = False
-
- mesh = t.toMesh(mesh,\
- do_uv = PREFS['do_uv'].val,\
- uv_image = image,\
- do_uv_keep_vproportion = PREFS['do_uv_keep_vproportion'].val,\
- do_uv_vnormalize = PREFS['do_uv_vnormalize'].val,\
- do_uv_uscale = PREFS['do_uv_uscale'].val,\
- uv_x_scale = PREFS['uv_x_scale'].val,\
- uv_y_scale = PREFS['uv_y_scale'].val,\
- do_uv_blend_layer = do_uv_blend_layer,\
- do_cap_ends = PREFS['do_cap_ends'].val
- )
-
- if PREFS['do_leaf'].val:
- ob_leaf_dupliface = getObChild(ob_mesh, 'Mesh')
- if not ob_leaf_dupliface: # New object
- mesh_leaf = bpy.data.meshes.new('leaf_' + ob_curve.name)
- ob_leaf_dupliface = newObChild(ob_mesh, mesh_leaf)
- else:
- mesh_leaf = ob_leaf_dupliface.getData(mesh=1)
- ob_leaf_dupliface.setMatrix(Matrix())
-
- leaf_object = getObFromName(PREFS['leaf_object'].val)
-
- mesh_leaf = t.toLeafMesh(mesh_leaf,\
- leaf_branch_limit = PREFS['leaf_branch_limit'].val,\
- leaf_branch_limit_rand = PREFS['leaf_branch_limit_rand'].val,\
- leaf_size = PREFS['leaf_size'].val,\
- leaf_size_rand = PREFS['leaf_size_rand'].val,\
- leaf_branch_density = PREFS['leaf_branch_density'].val,\
- leaf_branch_pitch_angle = PREFS['leaf_branch_pitch_angle'].val,\
- leaf_branch_pitch_rand = PREFS['leaf_branch_pitch_rand'].val,\
- leaf_branch_roll_rand = PREFS['leaf_branch_roll_rand'].val,\
- leaf_branch_angle = PREFS['leaf_branch_angle'].val,\
- leaf_rand_seed = PREFS['leaf_rand_seed'].val,\
- leaf_object = leaf_object,\
- )
-
- if leaf_object:
- ob_leaf_dupliface.enableDupFaces = True
- ob_leaf_dupliface.enableDupFacesScale = True
- ob_leaf_dupliface.makeParent([leaf_object], 1)
- else:
- ob_leaf_dupliface.enableDupFaces = False
-
- mesh.calcNormals()
-
- if PREFS['do_material'].val:
-
- materials = mesh.materials
- if PREFS['material_use_existing'].val and materials:
- t.material = materials[0]
- else:
- t.material = bpy.data.materials.new(ob_curve.name)
- mesh.materials = [t.material]
-
- if PREFS['material_texture'].val:
-
- # Set up the base image texture
- t.texBase = bpy.data.textures.new('base_' + ob_curve.name)
- t.material.setTexture(0, t.texBase, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.COL)
- t.texBase.type = Blender.Texture.Types.IMAGE
- if image:
- t.texBase.image = image
- t.texBaseMTex = t.material.getTextures()[0]
- t.texBaseMTex.uvlayer = 'base'
-
- if PREFS['material_stencil'].val:
- # Set up the blend texture
- t.texBlend = bpy.data.textures.new('blend_' + ob_curve.name)
- t.material.setTexture(1, t.texBlend, Blender.Texture.TexCo.UV, 0) # map to None
- t.texBlend.type = Blender.Texture.Types.BLEND
- t.texBlend.flags |= Blender.Texture.Flags.FLIPBLEND
- t.texBlendMTex = t.material.getTextures()[1]
- t.texBlendMTex.stencil = True
- t.texBlendMTex.uvlayer = 'blend'
-
-
- # Now make the texture for the stencil to blend, can reuse texBase here, jus tdifferent settings for the mtex
- t.material.setTexture(2, t.texBase, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.COL)
- t.texJoinMTex = t.material.getTextures()[2]
- t.texJoinMTex.uvlayer = 'join'
-
- # Add a UV layer for blending
-
-
-
-
- time6 = Blender.sys.time() # time print
- print '%.4f sec' % (time6-time5)
-
- # Do armature stuff....
- if PREFS['do_armature'].val:
-
- print '\tbuilding armature & animation...',
-
- ob_arm = getObChild(ob_curve, 'Armature')
- if ob_arm:
- armature = ob_arm.data
- ob_arm.setMatrix(Matrix())
- else:
- armature = bpy.data.armatures.new()
- ob_arm = newObChild(ob_curve, armature)
-
- t.toArmature(ob_arm, armature)
-
- # Add the modifier.
- if not hasModifier(Blender.Modifier.Types.ARMATURE):
- mod = ob_mesh.modifiers.append(Blender.Modifier.Types.ARMATURE)
-
- # TODO - assigne object anyway, even if an existing modifier exists.
- mod[Blender.Modifier.Settings.OBJECT] = ob_arm
-
- if PREFS['do_anim'].val:
- try:
- tex = bpy.data.textures[PREFS['anim_tex'].val]
- except:
- tex = None
- Blender.Draw.PupMenu('error no texture, cannot animate bones')
-
- if tex:
- t.toAction(ob_arm, tex,\
- anim_speed = PREFS['anim_speed'].val,\
- anim_magnitude = PREFS['anim_magnitude'].val,\
- anim_speed_size_scale= PREFS['anim_speed_size_scale'].val,\
- anim_offset_scale=PREFS['anim_offset_scale'].val
- )
-
- time7 = Blender.sys.time() # time print
- print '%.4f sec\n' % (time7-time6)
- else:
- time7 = Blender.sys.time() # time print
-
- print 'done in %.4f sec' % (time7 - time1)
-
- # Add subsurf last it needed. so armature skinning is done first.
- # Do subsurf?
- if PREFS['do_subsurf'].val:
- if not hasModifier(Blender.Modifier.Types.SUBSURF):
- mod = ob_mesh.modifiers.append(Blender.Modifier.Types.SUBSURF)
-
- #ob_mesh.makeDisplayList()
- #mesh.update()
- bpy.data.scenes.active.update()
-
-def do_pref_read(e=0,v=0, quiet=False):
- '''
- We dont care about e and v values, only there because its a callback
- '''
- sce = bpy.data.scenes.active
- ob = sce.objects.active
-
- if not ob:
- if not quiet:
- Blender.Draw.PupMenu('No active curve object')
- return
-
- if ob.type != 'Curve':
- ob = ob.parent
-
- if ob == None or ob.type != 'Curve':
- if not quiet:
- Blender.Draw.PupMenu('No active curve object')
- return
-
- if not IDProp2Prefs(ob.properties, PREFS):
- if not quiet:
- Blender.Draw.PupMenu('Curve object has no settings stored on it')
- return
-
- Blender.Draw.Redraw()
-
-def do_pref_write(e,v):
-
- objects = getContextCurveObjects()
- if not objects:
- Blender.Draw.PupMenu('No curve objects selected')
- return
-
- for ob in objects:
- Prefs2IDProp(ob.properties, PREFS)
-
-def do_pref_clear(e,v):
- objects = getContextCurveObjects()
- if not objects:
- Blender.Draw.PupMenu('No curve objects selected')
- return
-
- for ob in objects:
- try: del ob.properties[ID_SLOT_NAME]
- except: pass
-
-def do_tex_check(e,v):
- if not v: return
- try:
- bpy.data.textures[v]
- except:
- PREFS['anim_tex'].val = ''
- Draw.PupMenu('Texture dosnt exist!')
- Draw.Redraw()
-
-def do_ob_check(e,v):
- if not v: return
- try:
- bpy.data.objects[v]
- except:
- # PREFS['twig_ob_bounds'].val = ''
- Draw.PupMenu('Object dosnt exist!')
- Draw.Redraw()
-
-def do_group_check(e,v):
- if not v: return
- try:
- bpy.data.groups[v]
- except:
- # PREFS['leaf_object'].val = ''
- Draw.PupMenu('dosnt exist!')
- Draw.Redraw()
-
-# Button callbacks
-def do_active_image(e,v):
- img = bpy.data.images.active
- if img:
- PREFS['image_main'].val = img.name
- else:
- PREFS['image_main'].val = ''
-
-# Button callbacks
-def do_tree_generate__real():
- sce = bpy.data.scenes.active
- objects = getContextCurveObjects()
-
- if not objects:
- Draw.PupMenu('Select one or more curve objects or a mesh/armature types with curve parents')
-
- is_editmode = Blender.Window.EditMode()
- if is_editmode:
- Blender.Window.EditMode(0, '', 0)
- Blender.Window.WaitCursor(1)
-
- for ob in objects:
- buildTree(ob, len(objects)==1)
-
- if is_editmode:
- Blender.Window.EditMode(1, '', 0)
-
- Blender.Window.RedrawAll()
-
- Blender.Window.WaitCursor(0)
-
-
-# Profile
-# Had to do this to get it to work in ubuntu "sudo aptitude install python-profiler"
-'''
-import hotshot
-import profile
-from hotshot import stats
-'''
-def do_tree_generate(e,v):
-
- do_tree_generate__real()
- '''
- prof = hotshot.Profile("hotshot_edi_stats")
- prof.runcall(do_tree_generate__real)
- prof.close()
- s = stats.load("hotshot_edi_stats")
- s.sort_stats("time").print_stats()
- '''
- if GLOBALS['non_bez_error']:
- Blender.Draw.PupMenu('Error%t|Nurbs and Poly curve types cant be used!')
- GLOBALS['non_bez_error'] = 0
-
-def do_tree_help(e,v):
- url = 'http://wiki.blender.org/index.php/Scripts/Manual/Wizards/TreeFromCurves'
- print 'Trying to open web browser with documentation at this address...'
- print '\t' + url
-
- try:
- import webbrowser
- webbrowser.open(url)
- except:
- print '...could not open a browser window.'
-
-
-def evt(e,val):
- pass
-
-def bevt(e):
-
- if e==EVENT_NONE:
- return
-
- if e == EVENT_UPDATE or e == EVENT_UPDATE_AND_UI:
- if GLOBAL_PREFS['realtime_update'].val:
- do_tree_generate(0,0) # values dont matter
-
- if e == EVENT_REDRAW or e == EVENT_UPDATE_AND_UI:
- Draw.Redraw()
- if e == EVENT_EXIT:
- Draw.Exit()
- pass
-
-def gui():
- MARGIN = 4
- rect = BPyWindow.spaceRect()
- but_width = int((rect[2]-MARGIN*2)/4.0) # 72
- # Clamp
- if but_width>100: but_width = 100
- but_height = 17
-
- x=MARGIN
- y=rect[3]-but_height-MARGIN
- xtmp = x
-
- Blender.Draw.BeginAlign()
- PREFS['do_twigs_fill'] = Draw.Toggle('Fill Twigs',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_twigs_fill'].val, 'Generate child branches based existing branches'); xtmp += but_width*2;
- if PREFS['do_twigs_fill'].val:
-
- PREFS['twig_fill_levels'] = Draw.Number('Generations', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_levels'].val, 1, 32, 'How many generations to make for filled twigs'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- # WARNING USED IN 2 PLACES!! - see below
- PREFS['twig_ob_bounds'] = Draw.String('OB Bound: ', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_ob_bounds'].val, 64, 'Only grow twigs inside this mesh object', do_ob_check); xtmp += but_width*2;
- PREFS['twig_fill_rand_scale'] = Draw.Number('Randomize Scale', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_rand_scale'].val, 0.0, 1.0, 'Randomize twig scale from the bounding mesh'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
-
- PREFS['twig_fill_radius_min'] = Draw.Number('Min Radius', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_radius_min'].val, 0.0, 1.0, 'Radius at endpoints of all twigs'); xtmp += but_width*2;
- PREFS['twig_fill_radius_factor'] = Draw.Number('Inherit Scale', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_radius_factor'].val, 0.0, 1.0, 'What attaching to branches, scale the radius by this value for filled twigs, 0.0 for fixed width twigs.'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
-
- #PREFS['twig_fill_shape_type'] = Draw.Number('Shape Type', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_shape_type'].val, 0.0, 1.0, 'Shape used for the fork'); xtmp += but_width*2;
- PREFS['twig_fill_shape_type'] = Draw.Menu('Join Type%t|Even%x0|Smooth One Child%x1|Smooth Both Children%x2',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_fill_shape_type'].val, 'Select the wat twigs '); xtmp += but_width*2;
- PREFS['twig_fill_fork_angle_max'] = Draw.Number('Shape Max Ang', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_fork_angle_max'].val, 0.0, 180.0, 'Maximum fork angle'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
-
- PREFS['twig_fill_shape_rand'] = Draw.Number('Shape Rand', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_shape_rand'].val, 0.0, 1.0, 'Randomize the shape of forks'); xtmp += but_width*2;
- PREFS['twig_fill_shape_power'] = Draw.Number('Shape Strength', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_fill_shape_power'].val, 0.0, 1.0, 'Strength of curves'); xtmp += but_width*2;
-
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
-
-
- # ---------- ---------- ---------- ----------
- Blender.Draw.BeginAlign()
- PREFS['do_twigs'] = Draw.Toggle('Grow Twigs',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_twigs'].val, 'Generate child branches based existing branches'); xtmp += but_width*2;
- if PREFS['do_twigs'].val:
-
- PREFS['twig_ratio'] = Draw.Number('Twig Multiply', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_ratio'].val, 0.01, 500.0, 'How many twigs to generate per branch'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- PREFS['twig_select_mode'] = Draw.Menu('Branch Selection Method%t|From Short%x0|From Long%x1|From Straight%x2|From Bent%x3|',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_select_mode'].val, 'Select branches to use as twigs based on this attribute'); xtmp += but_width*2;
- PREFS['twig_select_factor'] = Draw.Number('From Factor', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_select_factor'].val, 0.0, 16, 'Select branches, lower value is more strict and will give you less variation'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- PREFS['twig_recursive'] = Draw.Toggle('Recursive Twigs',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_recursive'].val, 'Recursively add twigs into eachother'); xtmp += but_width*2;
- PREFS['twig_recursive_limit'] = Draw.Number('Generations', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_recursive_limit'].val, 0.0, 16, 'Number of generations allowed, 0 is inf'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
-
- PREFS['twig_scale'] = Draw.Number('Twig Scale', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_scale'].val, 0.01, 10.0, 'Scale down twigs in relation to their parents each generation'); xtmp += but_width*2;
- PREFS['twig_scale_width'] = Draw.Number('Twig Scale Width', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_scale_width'].val, 0.01, 20.0, 'Scale the twig length only (not thickness)'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
-
- PREFS['twig_random_orientation'] = Draw.Number('Rand Orientation', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_random_orientation'].val, 0.0, 360.0, 'Random rotation around the parent'); xtmp += but_width*2;
- PREFS['twig_random_angle'] = Draw.Number('Rand Angle', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_random_angle'].val, 0.0, 360.0, 'Random rotation to the parent joint'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
-
- PREFS['twig_placement_maxradius'] = Draw.Number('Place Max Radius', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_placement_maxradius'].val, 0.0, 50.0, 'Only place twigs on branches below this radius'); xtmp += but_width*2;
- PREFS['twig_placement_maxtwig'] = Draw.Number('Place Max Count', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_placement_maxtwig'].val, 0.0, 50.0, 'Limit twig placement to this many per branch'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['twig_follow_parent'] = Draw.Number('ParFollow', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['twig_follow_parent'].val, 0.0, 10.0, 'Follow the parent branch'); xtmp += but_width;
- PREFS['twig_follow_x'] = Draw.Number('Grav X', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['twig_follow_x'].val, -10.0, 10.0, 'Twigs gravitate on the X axis'); xtmp += but_width;
- PREFS['twig_follow_y'] = Draw.Number('Grav Y', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['twig_follow_y'].val, -10.0, 10.0, 'Twigs gravitate on the Y axis'); xtmp += but_width;
- PREFS['twig_follow_z'] = Draw.Number('Grav Z', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['twig_follow_z'].val, -10.0, 10.0, 'Twigs gravitate on the Z axis'); xtmp += but_width;
-
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- # WARNING USED IN 2 PLACES!!
- PREFS['twig_ob_bounds'] = Draw.String('OB Bound: ', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_ob_bounds'].val, 64, 'Only grow twigs inside this mesh object', do_ob_check); xtmp += but_width*2;
-
- if PREFS['twig_ob_bounds_prune'].val:
- but_width_tmp = but_width
- else:
- but_width_tmp = but_width*2
-
- PREFS['twig_ob_bounds_prune'] = Draw.Toggle('Prune',EVENT_UPDATE_AND_UI, xtmp, y, but_width_tmp, but_height, PREFS['twig_ob_bounds_prune'].val, 'Prune twigs to the mesh object bounds'); xtmp += but_width_tmp;
- if PREFS['twig_ob_bounds_prune'].val:
- PREFS['twig_ob_bounds_prune_taper'] = Draw.Number('Taper', EVENT_UPDATE_AND_UI, xtmp, y, but_width, but_height, PREFS['twig_ob_bounds_prune_taper'].val, 0.0, 1.0, 'Taper pruned branches to a point'); xtmp += but_width;
-
- #PREFS['image_main'] = Draw.String('IM: ', EVENT_UPDATE, xtmp, y, but_width*3, but_height, PREFS['image_main'].val, 64, 'Image to apply to faces'); xtmp += but_width*3;
- #Draw.PushButton('Use Active', EVENT_UPDATE, xtmp, y, but_width, but_height, 'Get the image from the active image window', do_active_image); xtmp += but_width;
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
-
-
- Blender.Draw.BeginAlign()
- PREFS['do_leaf'] = Draw.Toggle('Generate Leaves',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_leaf'].val, 'Generate leaves using duplifaces'); xtmp += but_width*2;
-
- if PREFS['do_leaf'].val:
-
- PREFS['leaf_object'] = Draw.String('OB: ', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_object'].val, 64, 'Use this object as a leaf', do_ob_check); xtmp += but_width*2;
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- PREFS['leaf_size'] = Draw.Number('Size', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_size'].val, 0.001, 10.0, 'size of the leaf'); xtmp += but_width*2;
- PREFS['leaf_size_rand'] = Draw.Number('Randsize', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_size_rand'].val, 0.0, 1.0, 'randomize the leaf size'); xtmp += but_width*2;
-
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- # Dont use yet
- PREFS['leaf_branch_limit'] = Draw.Number('Branch Limit', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_limit'].val, 0.0, 1.0, 'Maximum thichness where a branch can bare leaves, higher value to place leaves on bigger branches'); xtmp += but_width*2;
- PREFS['leaf_branch_limit_rand'] = Draw.Number('Limit Random', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_limit_rand'].val, 0.0, 1.0, 'Randomize the allowed minimum branch width to place leaves'); xtmp += but_width*2;
-
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- PREFS['leaf_branch_density'] = Draw.Number('Density', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_density'].val, 0.0, 1.0, 'Chance each segment has of baring a leaf, use a high value for more leaves'); xtmp += but_width*2;
- PREFS['leaf_branch_angle'] = Draw.Number('Angle From Branch', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_angle'].val, 0.0, 90.0, 'angle the leaf is from the branch direction'); xtmp += but_width*2;
-
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- PREFS['leaf_rand_seed'] = Draw.Number('Random Seed', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_rand_seed'].val, 0.0, 10000.0, 'Set the seed for leaf random values'); xtmp += but_width*2;
- PREFS['leaf_branch_pitch_angle'] = Draw.Number('Pitch Angle', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_pitch_angle'].val, -180, 180.0, 'Change the pitch rotation of leaves, negative angle to point down'); xtmp += but_width*2;
-
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- PREFS['leaf_branch_pitch_rand'] = Draw.Number('Random Pitch', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_pitch_rand'].val, 0.0, 1.0, 'Randomize the leaf rotation (up-down/pitch)'); xtmp += but_width*2;
- PREFS['leaf_branch_roll_rand'] = Draw.Number('Random Roll', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_branch_roll_rand'].val, 0.0, 1.0, 'Randomize the leaf rotation (roll/tilt/yaw)'); xtmp += but_width*2;
-
-
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
-
- Blender.Draw.BeginAlign()
- if PREFS['do_uv'].val == 0: but_width_tmp = but_width*2
- else: but_width_tmp = but_width*4
- PREFS['do_uv'] = Draw.Toggle('Generate UVs',EVENT_UPDATE_AND_UI, xtmp, y, but_width_tmp, but_height, PREFS['do_uv'].val, 'Calculate UVs coords'); xtmp += but_width_tmp;
-
- if PREFS['do_uv'].val:
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- PREFS['do_uv_uscale'] = Draw.Toggle('U-Scale', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['do_uv_uscale'].val, 'Scale the width according to the face size (will NOT tile)'); xtmp += but_width;
- PREFS['do_uv_keep_vproportion'] = Draw.Toggle('V-Aspect', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['do_uv_keep_vproportion'].val, 'Correct the UV aspect with the branch width'); xtmp += but_width;
- PREFS['do_uv_vnormalize'] = Draw.Toggle('V-Normaize', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_uv_vnormalize'].val, 'Scale the UVs to fit onto the image verticaly'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['uv_x_scale'] = Draw.Number('Scale U', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['uv_x_scale'].val, 0.01, 10.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
- PREFS['uv_y_scale'] = Draw.Number('Scale V', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['uv_y_scale'].val, 0.01, 10.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['image_main'] = Draw.String('IM: ', EVENT_UPDATE, xtmp, y, but_width*3, but_height, PREFS['image_main'].val, 64, 'Image to apply to faces'); xtmp += but_width*3;
- Draw.PushButton('Use Active', EVENT_UPDATE, xtmp, y, but_width, but_height, 'Get the image from the active image window', do_active_image); xtmp += but_width;
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- Blender.Draw.BeginAlign()
- PREFS['do_material'] = Draw.Toggle('Generate Material',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_material'].val, 'Create material and textures (for seamless joints)'); xtmp += but_width*2;
-
- if PREFS['do_material'].val:
- PREFS['material_use_existing'] = Draw.Toggle('ReUse Existing',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['material_use_existing'].val, 'Modify the textures of the existing material'); xtmp += but_width*2;
-
- # ---------- ---------- ---------- ----------
- y-=but_height
- xtmp = x
-
- PREFS['material_texture'] = Draw.Toggle('Texture', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['material_texture'].val, 'Create an image texture for this material to use'); xtmp += but_width*2;
- PREFS['material_stencil'] = Draw.Toggle('Blend Joints', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['material_stencil'].val, 'Use a 2 more texture and UV layers to blend the seams between joints'); xtmp += but_width*2;
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- Blender.Draw.BeginAlign()
- if PREFS['do_armature'].val == 0:
- but_width_tmp = but_width*2
- else:
- but_width_tmp = but_width*4
-
- Blender.Draw.BeginAlign()
- PREFS['do_armature'] = Draw.Toggle('Generate Motion', EVENT_UPDATE_AND_UI, xtmp, y, but_width_tmp, but_height, PREFS['do_armature'].val, 'Generate Armatuer animation and apply to branches'); xtmp += but_width_tmp;
-
- # ---------- ---------- ---------- ----------
- if PREFS['do_armature'].val:
- y-=but_height
- xtmp = x
-
- PREFS['do_anim'] = Draw.Toggle('Texture Anim', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_anim'].val, 'Use a texture to animate the bones'); xtmp += but_width*2;
-
- if PREFS['do_anim'].val:
-
- PREFS['anim_tex'] = Draw.String('TEX: ', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['anim_tex'].val, 64, 'Texture to use for the IPO Driver animation', do_tex_check); xtmp += but_width*2;
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['anim_speed'] = Draw.Number('Speed', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['anim_speed'].val, 0.001, 10.0, 'Animate the movement faster with a higher value'); xtmp += but_width*2;
- PREFS['anim_magnitude'] = Draw.Number('Magnitude', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['anim_magnitude'].val, 0.001, 10.0, 'Animate with more motion with a higher value'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['anim_offset_scale'] = Draw.Number('Unique Offset Scale', EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['anim_offset_scale'].val, 0.001, 10.0, 'Use the curve object location as input into the texture so trees have more unique motion, a low value is less unique'); xtmp += but_width*4;
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
-
- PREFS['anim_speed_size_scale'] = Draw.Toggle('Branch Size Scales Speed', EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['anim_speed_size_scale'].val, 'Use the branch size as a factor when calculating speed'); xtmp += but_width*4;
-
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
-
-
-
-
- # ---------- ---------- ---------- ----------
-
- Blender.Draw.BeginAlign()
- PREFS['do_variation'] = Draw.Toggle('Generate Variation', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_variation'].val, 'Create a variant by moving the branches'); xtmp += but_width*2;
-
- # ---------- ---------- ---------- ----------
- if PREFS['do_variation'].val:
- PREFS['variation_seed'] = Draw.Number('Rand Seed', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['variation_seed'].val, 1, 100000, 'Change this to get a different variation'); xtmp += but_width*2;
- y-=but_height
- xtmp = x
-
-
- PREFS['variation_orientation'] = Draw.Number('Orientation', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['variation_orientation'].val, 0, 1.0, 'Randomize rotation of the branch around its parent'); xtmp += but_width*2;
- PREFS['variation_scale'] = Draw.Number('Scale', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['variation_scale'].val, 0.0, 1.0, 'Randomize the scale of branches'); xtmp += but_width*2;
-
- Blender.Draw.EndAlign()
-
- y-=but_height+(MARGIN*2)
- xtmp = x
-
-
-
- # ---------- ---------- ---------- ----------
- Blender.Draw.BeginAlign()
- PREFS['seg_density'] = Draw.Number('Segment Spacing',EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['seg_density'].val, 0.05, 10.0, 'Scale the limit points collapse, that are closer then the branch width'); xtmp += but_width*4;
-
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- PREFS['seg_density_angle'] = Draw.Number('Angle Spacing', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_density_angle'].val, 0.0, 180.0, 'Segments above this angle will not collapse (lower value for more detail)'); xtmp += but_width*2;
- PREFS['seg_density_radius'] = Draw.Number('Radius Spacing', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_density_radius'].val, 0.0, 1.0, 'Segments above this difference in radius will not collapse (lower value for more detail)'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['seg_joint_compression'] = Draw.Number('Joint Width', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_joint_compression'].val, 0.1, 2.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
- PREFS['seg_joint_smooth'] = Draw.Number('Joint Smooth', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_joint_smooth'].val, 0.0, 1.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- PREFS['connect_sloppy'] = Draw.Number('Connect Limit',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['connect_sloppy'].val, 0.1, 3.0, 'Strictness when connecting branches'); xtmp += but_width*2;
- PREFS['connect_base_trim'] = Draw.Number('Joint Bevel', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['connect_base_trim'].val, 0.0, 2.0, 'low value for a tight join, hi for a smoother bevel'); xtmp += but_width*2;
- Blender.Draw.EndAlign()
- y-=but_height+MARGIN
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- Blender.Draw.BeginAlign()
- PREFS['do_cap_ends'] = Draw.Toggle('Cap Ends',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_cap_ends'].val, 'Add faces onto branch endpoints'); xtmp += but_width*2;
- PREFS['do_subsurf'] = Draw.Toggle('SubSurf',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_subsurf'].val, 'Enable subsurf for newly generated objects'); xtmp += but_width*2;
- Blender.Draw.EndAlign()
- y-=but_height+MARGIN
- xtmp = x
-
-
- # ---------- ---------- ---------- ----------
- Blender.Draw.BeginAlign()
- Draw.PushButton('Read Active Prefs', EVENT_REDRAW, xtmp, y, but_width*2, but_height, 'Read the ID Property settings from the active curve object', do_pref_read); xtmp += but_width*2;
- Draw.PushButton('Write Prefs to Sel', EVENT_NONE, xtmp, y, but_width*2, but_height, 'Save these settings in the ID Properties of all selected curve objects', do_pref_write); xtmp += but_width*2;
-
- y-=but_height
- xtmp = x
-
- # ---------- ---------- ---------- ----------
- Draw.PushButton('Clear Prefs from Sel', EVENT_NONE, xtmp, y, but_width*4, but_height, 'Remove settings from the selected curve aaobjects', do_pref_clear); xtmp += but_width*4;
- Blender.Draw.EndAlign()
-
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- Blender.Draw.BeginAlign()
- Draw.PushButton('Exit', EVENT_EXIT, xtmp, y, but_width, but_height, ''); xtmp += but_width;
- Draw.PushButton('Help', EVENT_NONE, xtmp, y, but_width, but_height, '', do_tree_help); xtmp += but_width;
- Draw.PushButton('Generate from selection', EVENT_REDRAW, xtmp, y, but_width*2, but_height, 'Generate mesh', do_tree_generate); xtmp += but_width*3;
- Blender.Draw.EndAlign()
- y-=but_height+MARGIN
- xtmp = x
- # ---------- ---------- ---------- ----------
-
- GLOBAL_PREFS['realtime_update'] = Draw.Toggle('Automatic Update', EVENT_UPDATE, xtmp, y, but_width*4, but_height, GLOBAL_PREFS['realtime_update'].val, 'Update automatically when settings change'); xtmp += but_width*4;
-
-
-
-if __name__ == '__main__':
- # Read the active objects prefs on load. if they exist
- do_pref_read(quiet=True)
-
- Draw.Register(gui, evt, bevt)
diff --git a/release/scripts/wizard_landscape_ant.py b/release/scripts/wizard_landscape_ant.py
deleted file mode 100644
index 405c06432ca..00000000000
--- a/release/scripts/wizard_landscape_ant.py
+++ /dev/null
@@ -1,2148 +0,0 @@
-#!BPY
-"""
-Name: 'Landscape Generator (A.N.T)'
-Blender: 248
-Group: 'Wizards'
-Tip: 'Create landscape mesh.'
-"""
-
-__author__ = "Jimmy Hazevoet"
-__url__ = ('http://wiki.blender.org/index.php/Scripts/Manual/Wizards/ANTLandscape','elysiun')
-__version__ = "v.1.05 03-2007"
-__bpydoc__ = """\
-
-Another Noise Tool 'Landscape' v.1.05
-
-This script uses noise functions to create a terrain from a grid mesh.
-
-Usage:
-
-Make new terrain: press the "Add New Grid" button, change some noise settings and press the "Update" button.
-
-Work on previous made grid: select the grid/terrain in the 3D view, and press the "Assign" button.
-
-Tip: use a low resolution grid mesh and add some Multires levels for detail
-
-Note: when using Multires materials can get weird,
-only apply materials when your terrain is ready, or not use Multires.
-
-This Script creates a landscape mesh.
-Press the Auto button when you start the script.
-Then the Generate Button & read it's tooltip.
-The mesh created is average 16000 verts.
-To me the mesh appears quite small in the 3d view.
-Just Press S in the 3d view to scale it up.
-This saves overhead drawing the Mesh.
-
-Known Issues:
-If the mesh is not drawn in the 3d view first time,
-Move your mouse to the 3d view, or press the button again.
-
-Not really an issue, more to be aware.
-Due to the complex nature & design of the script, it only creates one mesh at a time.
-When you press Generate or Reset,
-Even if you have Closed then Opened the script or .blend file,
-The mesh Will be Overwritten.
-To create Multiple Landscapes you Must Re-Name or save the Mesh
-in Blender's F7 menu Links & Materials Panel.
-
-Readme:
-v.1.04:
-_ New G.U.I.
-_ New noise types like:
-Double_Terrain,
-StatsByAlt_Terrain,
-slickRock,
-ditorted_heteroTerrain,
-vlNoise_turbulence,
-and many more.
-
-New fractalized Effect functions.
-Effect types such as: gradient,
-waves and bumps, dome, piramide,
-squares, grid, shattered rocks,
-lunar, and many more.
-
-Bias types: Sin, Cos, Tri, Saw,
-and Default(no bias).
-
-For example the 'Rings' effect
-with 'Sin Bias' makes 'Rings'
-and 'Default Bias' makes 'Dome'.
-The Effect 'Mix factor' Slider gives control over how much of the Effect is vissible,
--1.0=noise, 0.0=average, 1.0=effect
-this slider controls also the 'Warp amount' if mix type 'Warp' is selected.
-
-Image effect: mix image with noise
-_ IPOCurve Filter: use Ipo curve to filter terrain height.
-I know it's a bit strange to use animation curves for landscape modelling, (actualy i want a curves panel in my G.U.I. but i dont know how to do that)
-the downside of this method is that you have this 'Empty' moving around in your scene, so put it on another layer and 'Pin' the Ipo block so that it stays visible.
-Usage:
-Add one 'Empty' Object to your scene, now add one Loc Key at Frame 1, go to Frame 101 (UpArrow ten times),
-move the 'Empty' +100 units in X+ direction and add another Loc Key, open the Ipo Curve Editor Window, rename this IpoBlock if you want,
-Copie the first curve to buffer and Paste it in the empty slots (from top to bottom), now you can edit the curves freely.
-(use the 'Pin' option to keep the curves visible while other objects are selected)
-Set the CurveLength and CurveHeight Button value's according to the length and height of the selected curve.
-A curve filter is very versatile when it comes to 'height' filtering.
-
-_ PreView in UV/Image Editor Window:
-The preview image is now rendered as Blender.Image and will be saved to file directory as 'ANTview_size.tga'
-you have to select 'ANTview_size.tga' in the UV/Image Editor Window
-now it's posible to render and save a large HeightMap image (you can also create nice texture images when the VertCol gradient is enabled),
-! If you Change the preview image Size a New Blender.Image object is created. (one for size 256, one for size 512 one for.....) !
-
-_ VertexColours: use any image as colour gradient.
-This function actualy uses one 'row' of pixels from a image to produce the color gradient,
-Make one or more custom gradient images with the Gimp or any other graphics software, the gradients must go from left to right (left is bottom and right is top.
-you only need one row of pixels so you can put 10 gradients in a 256*10 image.(higher resolutions like 512*n or 1024*n gives smoother result)
-Set Window DrawMode 'Textured' , and set the 'VCol Paint' option in the Materials panel !
-
-_ Mesh Tiles: Create large scale terrains.
-
-_ Vertices Selection: select flat areas.
-
-_ Keyboard HotKeys:
-SPACE = Update mesh.
-R = Randomise.
-V = Redraw preview.
-
-_ and more...
-
-"""
-
-
-
-
-###
-#
-# Alt+P to start script.
-#
-###
-# scroll down to see info about updates
-##
-################################################################################################################
-# Another Noise Tool 'Landscape'
-# Jimmy Hazevoet
-# license: Do whatever you want with it.
-################################################################################################################
-
-################################################################################################################
-# v.1.04:
-#
-# _ New G.U.I.
-# _ New noise types like: Double_Terrain, StatsByAlt_Terrain, slickRock, ditorted_heteroTerrain, vlNoise_turbulence, and many more.
-# _ New fractalized Effect functions.
-# Effect types such as: gradient, waves and bumps, dome, piramide, squares, grid, shattered rocks, lunar, and many more.
-# Bias types: Sin, Cos, Tri, Saw, and Default(no bias).
-# For example the 'Rings' effect with 'Sin Bias' makes 'Rings' and 'Default Bias' makes 'Dome'.
-# _ The Effect 'Mix factor' Slider gives control over how much of the Effect is vissible, -1.0=noise, 0.0=average, 1.0=effect
-# this slider controls also the 'Warp amount' if mix type 'Warp' is selected.
-# _ Image effect: mix image with noise
-# _ IPOCurve Filter: use Ipo curve to filter terrain height.
-# I know it's a bit strange to use animation curves for landscape modelling, (actualy i want a curves panel in my G.U.I. but i dont know how to do that)
-# the downside of this method is that you have this 'Empty' moving around in your scene, so put it on another layer and 'Pin' the Ipo block so that it stays visible.
-# Usage:
-# Add one 'Empty' Object to your scene, now add one Loc Key at Frame 1, go to Frame 101 (UpArrow ten times),
-# move the 'Empty' +100 units in X+ direction and add another Loc Key, open the Ipo Curve Editor Window, rename this IpoBlock if you want,
-# Copie the first curve to buffer and Paste it in the empty slots (from top to bottom), now you can edit the curves freely.
-# (use the 'Pin' option to keep the curves visible while other objects are selected)
-# Set the CurveLength and CurveHeight Button value's according to the length and height of the selected curve.
-# A curve filter is very versatile when it comes to 'height' filtering.
-# _ PreView in UV/Image Editor Window:
-# The preview image is now rendered as Blender.Image and will be saved to file directory as 'ANTview_size.tga'
-# you have to select 'ANTview_size.tga' in the UV/Image Editor Window
-# now it's posible to render and save a large HeightMap image (you can also create nice texture images when the VertCol gradient is enabled),
-# ! If you Change the preview image Size a New Blender.Image object is created. (one for size 256, one for size 512 one for.....) !
-# _ VertexColours: use any image as colour gradient.
-# This function actualy uses one 'row' of pixels from a image to produce the color gradient,
-# Make one or more custom gradient images with the Gimp or any other graphics software, the gradients must go from left to right (left is bottom and right is top.
-# you only need one row of pixels so you can put 10 gradients in a 256*10 image.(higher resolutions like 512*n or 1024*n gives smoother result)
-# Set Window DrawMode 'Textured' , and set the 'VCol Paint' option in the Materials panel !
-# _ Mesh Tiles: Create large scale terrains.
-# _ Vertices Selection: select flat areas.
-# _ Keyboard HotKeys:
-# SPACE = Update mesh.
-# R = Randomise.
-# V = Redraw preview.
-# _ and more...
-################################################################################################################
-
-################################################################################################################
-# BugFix: Sept./2006 v.1.04a
-#-----------------------------
-# _Image Effect did not worked well with tiled mesh. Fixed (now use Freq. and Loc. buttons to scale and position image).
-#
-################################################################################################################
-
-
-################################################################################################################
-# UPDATE: v.1.05 03-2007
-#---------------------------------------------------------------------------------------------------------------
-#
-# _ New: Save and Load function, save your settings to a .ant file.
-# __NOTE: when saving/loading settings to/from a file,
-# make sure the filename/path is not too long!
-# __HOTKEY__ Load from file: L
-# __HOTKEY__ Save to file : S
-#
-# _ New mesh code, uses Mesh instead of NMesh,
-# this gives a small speed improvement and alows you to use Multires.
-#
-# Usage: Select a Grid/Terrain mesh and hit the Assign button, now you can work on it, when ready you assign another.
-#
-# _ New: 'Musgrave' noise types, 'Random noise' and 'Constant' in 'Effects' section.
-# _ New: 'Custom Effect', write custom formulae ( x,y, a,b, from math import *, from Blender.Noise import * )
-# _ New: 'Custom Height Filter', write custom formulae ( x,y, h, a,b, from math import *, from Blender.Noise import * )
-# _ New: 'Change Filter Order', Toggle: OFF = Noise+Effect+Falloff+FILTER / ON = Noise+FILTER+Effect+Falloff
-#
-# _ If you want to make a tiled terrain, you need to set the coordinates to "WorldSpace" or "Center at Cursor" (in G.U.I.Noise panel),
-# create and place the grid meshes. now one by one select, assign and update, you may need to adjust the "EdgeFalloff" size.
-#
-# WARNING!: when using Multires, materials can get weird (?), so apply materials when your terrain is finnished.
-#
-###############################################################################################################
-
-
-###############################################################################################################
-#
-## Execute Script: Alt P
-#
-
-
-import Blender
-from Blender import *
-from math import *
-from Blender.Noise import *
-from Blender.Draw import *
-from Blender.BGL import *
-from Blender import Image
-import string
-from string import strip
-import BPyMathutils
-from BPyMathutils import genrand
-from random import choice
-scene = Scene.GetCurrent()
-
-###---------------------------------------------------------------------------
-
-CurVersion = 'A.N.T.Landscape v.1.05'
-
-##---------------------------------------------------------------------------
-# Customise default settings: ----------------------------------------------
-
-# Names:
-antfilename = 'Terrain' # Default filename
-previewname = Create('') # Default preview Image name
-DefaultIpoName = '' # Default Ipo DataBlock name (for height filter)
-# G.U.I.:
-FullScreen = Create( 0 ) # FullScreen on/off
-# gui colors:
-ledcolors = [ [1.0,0.498,0.498], [1.0,0.698,0.498], [1.0,0.898,0.498], [0.898,1.0,0.498], [0.698,1.0,0.498], [0.498,1.0,0.498], [0.498,1.0,0.698], [0.498,1.0,0.898], [0.600,0.918,1.0], [0.6,0.757,1.0], [0.6,0.6,1.0], [0.757,0.6,1.0], [0.898,0.498,1.0], [1.0,0.498,0.898] ]
-#ledcolor = [ 1.0, 0.5, 0.0 ]
-lightgrey = [ 0.76, 0.76, 0.76 ] # gui col.
-grey = [ 0.6, 0.6, 0.6 ] # panel col.
-background = [ 0.7, 0.7, 0.7, 1.0 ] # background col.
-black = [ 0.0, 0.0, 0.0 ] # text col.
-white = [ 1.0, 1.0, 1.0 ]
-# gui size
-size_x = 320 # gui x size
-size_y = 280 # gui y size
-# tabs
-guitabs = [ Create( 1 ), Create( 0 ), Create( 0 ), Create( 0 ), Create( 0 ) ] # gui Tabs
-# How long does it take to generate a mesh or image ?
-print_time = 0 # 1 = Print time in console.
-
-# end customise. ----------------------------------------------------------
-##--------------------------------------------------------------------------
-###--------------------------------------------------------------------------
-####--------------------------------------------------------------------------
-##---------------------------------------------------------------------------
-
-dirpath=Blender.sys.dirname(Blender.Get('filename'))
-fname=dirpath.replace('\\','/')+'/' + antfilename + '.ant'
-txtFile = Create( fname )
-
-###---------------------------------------------------------------------------
-columns = 10 # gui columns
-rows = 13 # gui rows
-actob = [] # active object
-actme = [] # active mesh
-ipoblockname=''
-thiscurve=[]
-selectedcurve=0
-phi=3.14159265359
-# events
-App_Evt = 144
-New_Evt = 166
-SelFile_Evt = 71
-LoadFile_Evt = 72
-SaveFile_Evt = 73
-UseMe_Evt = 74
-No_Evt = 1
-Btn_Evt = 2
-Msh_Evt = 12
-Upd_Evt = 3
-Rndm_Evt = 4
-Load_Evt = 5
-Sel_Evt = 6
-Save_Evt = 7
-Rend_Evt = 8
-End_Evt = 9
-Scrn_Evt = 15
-Im_Evt = 16
-gt0_Evt = 20
-gt1_Evt = 21
-gt2_Evt = 22
-gt3_Evt = 23
-gt4_Evt = 24
-Ipo_Evt = 17
-New_Ipo_Evt=700
-
-###---------------------------------------------------------------------------
-# menus
-noisetypemenu = "Noise type: %t|multiFractal %x0|ridgedMFractal %x1|hybridMFractal %x2|heteroTerrain %x3|fBm %x4|turbulence %x5|Voronoi turb. %x6|vlNoise turb. %x7|noise %x8|cellNoise %x9|Marble %x10|lava_multiFractal %x11|slopey_noise %x12|duo_multiFractal %x13|distorted_heteroTerrain %x14|slickRock %x15|terra_turbulence %x16|rocky_fBm %x17|StatsByAlt_Terrain %x18|Double_Terrain %x19|Shattered_hTerrain %x20|vlhTerrain %x21"
-noisebasismenu = "Basis %t|Blender Original%x0|Original Perlin%x1|Improved Perlin%x2|Voronoi_F1%x3|Voronoi_F2%x4|Voronoi_F3%x5|Voronoi_F4%x6|Voronoi_F2-F1%x7|Voronoi Crackle%x8|CellNoise%x9"
-voronitypemenu = "Voronoi type %t|Distance %x0|Distance Squared %x1|Manhattan %x2|Chebychev %x3|Minkovsky 1/2 %x4|Minkovsky 4 %x5|Minkovsky %x6"
-tBasismodemenu = "Terrain basis mode: %t|noise %x0|ridged noise %x1|vlNoise %x2|ridged vlNoise %x3"
-effecttypemenu = ['Effect Type %t','No Effect %x0','Image %x1','Turbulence %x2','vlNoise %x3','Marble %x4', 'multiFractal %x5','ridgedMFractal %x6','hybridMFractal %x7','heteroTerrain %x8','fBm %x9', 'Gradient %x10','Waves and Bumps %x11','ZigZag %x12','Wavy %x13','Sine Bump %x14','Dots %x15','Rings / Dome %x16','Spiral %x17','Square / Piramide %x18','Blocks %x19','Grid %x20','Tech %x21','Crackle %x22','Sparse Cracks %x23','Shattered Rocks %x24','Lunar %x25','Cosine noise %x26','Spike noise %x27','Stone noise %x28','Flat Turb %x29','Flat Voroni %x30','Random noise %x31','Constant %x32','Custom Effect %x33' ]
-mixtypemenu = ['Mix Type %t','Effect only %x0','%l','Mix %x1','Add %x2','Subtract %x3','Multiply %x4','Difference %x5','Screen %x6','addmodulo %x7','Minimum %x8','Maximum %x9','%l','Warp Effect %x10','Warp Noise %x11']
-biastypemenu = "Bias %t|Sin bias %x0|Cos bias %x1|Tri bias %x2|Saw bias %x3|Default (no bias)%x4"
-sharptypemenu = "Sharpen %t|Soft %x0|Sharp %x1|Sharper %x2"
-filtermodemenu = "Filter Mode %t|No Filter %x0| %l|Default Filters %x1|IPOCurve Filter %x2|Custom Filter %x3"
-filtertypemenu = "Filter Type %t|Default Terrace %x0|Sharper Terrace %x1|Rounded Terrace %x2|Posterise Mixed %x3|Posterise %x4|Layered Peaks %x5|Peaked %x6|Smooth-thing %x7|Sin bias %x8|Cos bias %x9|Tri bias %x10|Saw bias %x11|Clamp Max. %x12"
-falloftypemenu = "Edge Falloff %t|No Edge Falloff %x0| %l|Soft Falloff %x1|Default Falloff %x2|Hard Falloff %x3|Linear Falloff Y %x4|Linear Falloff X %x5|Diagonal Falloff + %x6|Diagonal Falloff - %x7|Square %x8|Round %x9"
-randomtypemenu = "Random type: %t|setRandomSeed() : Blender.Noise %x0|Rand() : Blender.Mathutils %x1|genrand() : BPyMathutils MersenneTwister %x2"
-
-##--------------------------------------------------
-def Set_ReSet_Values():
- global fileinfo, filemessage
- global iScale, Offset, Invert, NSize, Sx, Sy, Lx, Ly, WorldSpaceCo
- global NType, Basis, musgr, vlnoi, vlnoiTwo, voron, turbOne, turbTwo, marbleOne, marbleTwo, tBasismod, musgrTwo
- global CustomFX, effect_image, Effect_Ctrl, Min, Max, Falloff, CustomFilt, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order
- global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I, AutoUpd, PreView, DefaultIpoName
-
- filemessage = ''
- fileinfo = ''
- effect_image = 'Load and Select image.'
- AutoUpd = Create( 0 )
- PreView = [ Create( 0 ), Create( 1.0 ), Create( 0.0 ) ]
- ## Coords controls:
- WorldSpaceCo = Create(0)
- iScale = [ Create( 1.0 ), Create( 1.0 ), Create( 0.25) ]
- Offset = [ Create( 0.0 ), Create( 0.0), Create( 0.0) ]
- Invert = [ Create( 0 ), Create( 0 ), Create( 0 ) ]
- NSize = [ Create( 1.0 ), Create( 2.0 ) ]
- Sx = [ Create( 1.0 ), Create( 1.0 ) ]
- Sy = [ Create( 1.0 ), Create( 1.0 ) ]
- Lx = [ Create( 0.0 ), Create( 0.0 ) ]
- Ly = [ Create( 0.0 ), Create( 0.0 ) ]
- ## Noise controls:
- NType = Create( 3 )
- Basis = [ Create( 0 ), Create( 0 ) ]
- musgr = [ Create( 1.0 ), Create( 2.0 ), Create( 8 ), Create( 1.0 ), Create( 1.0 ), Create( 0.5 ) ]
- vlnoi = [ Create( 1.0 ), Create( 0 ) ]
- vlnoiTwo = [ Create( 1.0 ), Create( 0 ) ]
- voron = [ Create( 0 ), Create( 2.5 ) ]
- turbOne = [ Create( 6 ), Create( 0 ), Create( 0.5 ), Create( 2.0 ) ]
- marbleOne = [ Create( 6 ), Create( 0 ), Create( 2.0 ), Create( 0 ), Create( 0 ), Create( 1.0 ) ]
- tBasismod = Create(0)
- ## Effect controls:
- musgrTwo = [ Create( 1.0 ), Create( 2.0 ), Create( 8 ), Create( 1.0 ), Create( 1.0 ) ]
- turbTwo = [ Create( 6 ), Create( 0 ), Create( 0.5 ), Create( 2.0 ) ]
- marbleTwo = [ Create( 6 ), Create( 0 ), Create( 2.0 ), Create( 0 ), Create( 0 ), Create( 1.0 ) ]
- Effect_Ctrl = [ Create( 0 ),Create( 2 ),Create( 0.0 ),Create( 0 ),Create( 0.0 ) ,Create( 0 ),Create( 2.0 ),Create( 0.5 ),Create( 0.5 ) ]
- CustomFX = [ Create('sin(x*pi)'), Create('cos(y*pi)'), Create('abs(a*b)*0.5') ]
- ## Filter controls:
- Min = Create( 0.0 )
- Max = Create( 1.0 )
- Falloff = [ Create( 2 ), Create( 1.0 ), Create( 1.0 ), Create( 0 ) , Create( 0 ) ]
- Filter_Mode = Create( 0 )
- Def_Filter_Ctrl = [ Create( 0 ), Create( 3.0 ) ]
- Ipo_Filter_Ctrl = [ Create( DefaultIpoName ), Create( 0 ), Create( 100.0 ), Create( 100.0 ) ]
- Filter_Order = Create( 0 )
- CustomFilt = [ Create('sqrt(h*h)**2'), Create('0'), Create('a') ]
- ## Randomise noise buttons:
- RandMod = Create( 1 )
- RSeed = Create( 0 )
- rand_I = Create( 0 )
- rand_H = Create( 0 )
- rand_S = Create( 0 )
- rand_L = Create( 1 )
-
-##-------------------------
-Set_ReSet_Values()
-
-
-####----------------------------------------------------------------------------------------------------
-###----------------------------------------------------------------------------------------------------
-## G.U.I.: text,backpanel,panel
-#--------------------------------------------------
-def draw_Text( ( x, y ), text, color, size ):
- glColor3f( color[0],color[1],color[2] )
- glRasterPos2d(x,y)
- txtsize = 'small', 'normal', 'large'
- Text( text, txtsize[ size ] )
-def draw_BackPanel( text, x, y, w, h, colors ):
- glColor3f( colors[0]*0.76, colors[1]*0.76, colors[2]*0.76 )
- glRecti( x, h, w, h+20 )
- glColor3f( colors[0], colors[1], colors[2] )
- glRecti( x, y, w, h )
- glColor3f( colors[0], colors[1], colors[2] )
- glRasterPos2d( x+10, h+5 )
- Text( text, 'small' )
-def draw_Panel( x, y, w, h, colors ):
- glColor3f( colors[0], colors[1], colors[2] )
- glRecti( x,y, w,h )
-def draw_Frame( text, x, y, w, h, color ):
- glColor3f( color[0], color[1], color[2] )
- glRasterPos2i(x+3,h-3)
- Text(text ,'small')
- stringwidth = GetStringWidth( text,'small' )
- glColor3f( color[0], color[1], color[2] )
- glBegin(Blender.BGL.GL_LINE_STRIP)
- glVertex2i(x,h)
- glVertex2i(x,y)
- glVertex2i(w,y)
- glVertex2i(w,h)
- glVertex2i(x+stringwidth+10,h)
- glEnd()
-def draw_Led( x, y, colors ):
- glColor3f( colors[0], colors[1], colors[2] )
- glRecti( x,y, x+4,y+4 )
-
-
-###----------------------------------------------------------------------------------------------------
-## G.U.I. Buttons:
-#----------------------------------------------------------------------------------------------------
-
-###-------------------------
-## Main / Mesh Buttons:
-#
-def MeshButtons( col, row, width, height ):
- global actme, actob, AutoUpd, txtFile, filemessage, fileinfo
-
- PushButton("I", UseMe_Evt, col[8], row[3], width[0], height[1], "Info: Here you can write some text to save with the file." )
- draw_Text( ( col[0], row[1]+5 ), 'Info: ' + fileinfo, black, 0 )
- txtFile = String("", No_Evt, col[0], row[2], width[9], height[1], txtFile.val, 256, "File: Full path and filename" )
- PushButton( "Select", SelFile_Evt, col[1], row[3], width[0], height[1], "File: Open FileBrowser and select *.ant file" )
- PushButton( "Load", LoadFile_Evt,col[2], row[3], width[2], height[1], "File: Load settings from file ( HotKey: L )" )
- PushButton( "Save", SaveFile_Evt,col[5], row[3], width[2], height[1], "File: Save settings to file ( HotKey: S )" )
-
- activeobname = ''
- if actme !=[]:
- activeobname = actob[0].name
- draw_Text( ( col[5]+5, row[7]-5 ), 'OB: ' + activeobname, [0.0,0.0,1.0], 1 )
- PushButton( "Add New Grid", New_Evt, col[0], row[6], width[4], height[2] )
- PushButton( "Assign Selected", App_Evt, col[5], row[6], width[4], height[2], 'Assign selected terrain')
-
-###-------------------------
-## Noise Buttons:
-#
-def NoiseButtons( col, row, width, height ):
- global NSize, iScale, Offset, Invert, Lx, Ly, Sx, Sy, WorldSpaceCo
- global Ha, La, Oc, Of, Ga, Basis, NType, musgr, vlnoi, voron, turbOne, tBasismod
- global Depth, Hard, Amp, Freq, vlBasis, Distort, VFunc, VExp, VDep, marbleOne
- global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I
-
- bth = height[1]/2+5
- iScale[0] = Number("iScale:", Btn_Evt, col[5], row[2]+bth, width[3], height[1], iScale[0].val, -10.0, 10.0 , "Noise: Intensity Scale." )
- Invert[0] = Toggle("Inv.", Btn_Evt, col[9], row[2]+bth, width[0], height[1], Invert[0].val, "Noise: Invert")
- Offset[0] = Number("Offset:", Btn_Evt, col[5], row[3]+bth, width[4], height[1], Offset[0].val, -10.0, 10.0 , "Noise: Offset " )
- NSize[0] = Number("Noise Size:",Btn_Evt, col[5], row[5], width[4], height[2], NSize[0].val, 0.001, 10.0 , "Noise Size" )
- Sx[0] = Number("Size X:", Btn_Evt, col[5], row[6], width[4], height[1], Sx[0].val, 0.001, 10.0 , "Size X" )
- Sy[0] = Number("Size Y:", Btn_Evt, col[5], row[7], width[4], height[1], Sy[0].val, 0.001, 10.0 , "Size Y" )
- Lx[0] = Number("Loc X:", Btn_Evt, col[5], row[8], width[4], height[1], Lx[0].val, -10000.0, 10000.0 , "Loc X" )
- Ly[0] = Number("Loc Y:", Btn_Evt, col[5], row[9],width[4], height[1], Ly[0].val, -10000.0, 10000.0 , "Loc Y" )
- WorldSpaceCo = Menu( "Coordinates %t|Local Space %x0|World Space %x1|Center at CursorPos %x2", Btn_Evt, col[5], row[10], width[4], height[1], WorldSpaceCo.val, "x,y,z coordinates for noise, effect and height falloff " )
-
- NType = Menu( noisetypemenu, Btn_Evt, col[0], row[2], width[4], height[2], NType.val, "Noise type" )
- if NType.val == 6:
- voron[0] = Menu( voronitypemenu, Btn_Evt, col[0], row[3], width[4], height[1], voron[0].val, "Voronoi type" )
- else:
- if NType.val != 9:
- Basis[0] = Menu( noisebasismenu, Btn_Evt, col[0], row[3], width[4], height[1], Basis[0].val, "Noise Basis" )
-
- if NType.val in [0,1,2,3,4,11,12,13,14,15,17,18,19,20,21]:
- musgr[0] = Slider( "H: ", Btn_Evt, col[0], row[5], width[4], height[1], musgr[0].val, 0.0, 3.0, 0 , "H" )
- musgr[1] = Slider( "Lacu: ", Btn_Evt, col[0], row[6], width[4], height[1], musgr[1].val, 0.0, 6.0, 0 , "Lacunarity" )
- musgr[2] = Slider( "Octs: ", Btn_Evt, col[0], row[4], width[4], height[1], musgr[2].val, 0, 12, 0 , "Octaves" )
- if NType.val in [1,2,3,13,14,15,18,19,20,21]:
- musgr[3] = Slider( "Offst: ", Btn_Evt, col[0], row[7], width[4], height[1], musgr[3].val, 0.0, 6.0, 0 , "Offset" )
- if NType.val in [1,2,13,15,18]:
- musgr[4] = Slider( "Gain: ", Btn_Evt, col[0], row[8], width[4], height[1], musgr[4].val, 0.0, 6.0, 0 , "Gain" )
- if NType.val == 19:
- musgr[5] = Slider( "Thresh: ", Btn_Evt, col[0], row[8], width[4], height[1], musgr[5].val, 0.001, 2.0, 0 , "Threshold" )
- if NType.val in [5,6,7,16]:
- turbOne[0] = Number( "Depth:", Btn_Evt, col[0], row[4], width[4], height[1], turbOne[0].val, 0, 12, "Octaves")
- turbOne[1] = Toggle( "Hard noise", Btn_Evt, col[0], row[5], width[4], height[1], turbOne[1].val, "Soft noise / Hard noise")
- turbOne[2] = Slider( "Amp:", Btn_Evt, col[0], row[6], width[4], height[1], turbOne[2].val, 0.0, 3.0, 0, "Ampscale ")
- turbOne[3] = Slider( "Freq:", Btn_Evt, col[0], row[7], width[4], height[1], turbOne[3].val, 0.0, 6.0, 0, "Freqscale")
- if NType.val in [18,19]:
- tBasismod = Menu( tBasismodemenu, Btn_Evt, col[0], row[9], width[4], height[1], tBasismod.val, "Terrain basis mode.")
- if NType.val == 6:
- if voron[0].val == 6:
- voron[1] = Slider( "Exp: ", Btn_Evt, col[0], row[8], width[4], height[1], voron[1].val, 0.0,10.0, 0, "Minkovsky exponent")
- if NType.val in [7,11,12,14,20,21]:
- vlnoi[0] = Slider( "Dist: ", Btn_Evt, col[0], row[8], width[4], height[1], vlnoi[0].val, 0.0, 10.0, 0 , "Distort" )
- if NType.val in [7,13,14,15,21]:
- vlnoi[1] = Menu(noisebasismenu, Btn_Evt, col[0], row[9], width[4], height[1], vlnoi[1].val, "Distortion Noise")
- if NType.val == 10:
- marbleOne[0] = Number( "Depth: ", Btn_Evt, col[0], row[6], width[4], height[1], marbleOne[0].val, 0, 12, "Octaves")
- marbleOne[2] = Slider( "Turb: ", Btn_Evt, col[0], row[7], width[4], height[1], marbleOne[2].val, 0.0,20.0, 0, "Turbulence ")
- marbleOne[3] = Menu( biastypemenu, Btn_Evt ,col[0], row[4], width[4], height[1], marbleOne[3].val, "Bias")
- marbleOne[5] = Slider("ReScale: ", Btn_Evt, col[0], row[8], width[4], height[1], marbleOne[5].val, 0.0,20.0, 0, "ReScale")
- if marbleOne[3].val != 4:
- marbleOne[4] = Menu(sharptypemenu, Btn_Evt ,col[0], row[5], width[4], height[1], marbleOne[4].val, "Sharpen")
-
- RandMod = Menu( randomtypemenu, No_Evt, col[0], row[10], width[0], height[1], RandMod.val, "Random Type" )
- rand_H = Toggle("TH",No_Evt ,col[1], row[10], width[0], height[1], rand_H.val, "Randomise Terrain Height ( in Height panel )")
- rand_I = Toggle("NH",No_Evt ,col[2], row[10], width[0], height[1], rand_I.val, "Randomise Noise Height")
- rand_S = Toggle("NS",No_Evt ,col[3], row[10], width[0], height[1], rand_S.val, "Randomise Noise Size")
- rand_L = Toggle("NL",No_Evt ,col[4], row[10], width[0], height[1], rand_L.val, "Randomise Noise Location")
-
-###-------------------------
-## Effect Buttons:
-#
-def EffectButtons( col, row, width, height ):
- global Effect_Type, Effect_Ctrl, Blend_Effect, CustomFX
- global NSize, iScale, Offset, Invert, Lx, Ly, Sx, Sy
- global BasisTwo, turbTwo, marbleTwo, vlnoiTwo, musgrTwo
-
- Effect_Ctrl[0] = Menu( '|'.join( effecttypemenu ), Btn_Evt, col[0], row[2], width[4], height[2], Effect_Ctrl[0].val, "Effect: Type" )
- if Effect_Ctrl[0].val != 0:
- Effect_Ctrl[1] = Menu( '|'.join( mixtypemenu ), Btn_Evt, col[5], row[2], width[4], height[2], Effect_Ctrl[1].val, "Mix: Type" )
- if Effect_Ctrl[1].val in [10,11]:
- Effect_Ctrl[2] = Slider("Warp: ", Btn_Evt, col[5], row[3], width[4], height[1], Effect_Ctrl[2].val, -1.0, 1.0, 0, "Mix factor / Warp amount" )
- else: Effect_Ctrl[2] = Slider("Mix: ",Btn_Evt, col[5], row[3], width[4], height[1], Effect_Ctrl[2].val, -1.0, 1.0, 0, "Mix factor / Warp amount" )
-
- iScale[1] = Number("iScale:", Btn_Evt, col[5], row[4], width[3], height[1], iScale[1].val, -20.0, 20.0 , "Effect: Intensity Scale " )
- Invert[1] = Toggle("Inv.", Btn_Evt, col[9], row[4], width[0], height[1], Invert[1].val, "Effect: Invert")
- Offset[1] = Number("Offset:", Btn_Evt, col[5], row[5], width[4], height[1], Offset[1].val, -20.0, 20.0 , "Effect: Offset " )
- NSize[1] = Number("Frequency:",Btn_Evt, col[5], row[6], width[4], height[1], NSize[1].val, 0.001, 100.0, "Effect Frequency ( Scale )" )
- Sx[1] = Number("Freq X:", Btn_Evt, col[5], row[7], width[4], height[1], Sx[1].val, -50.0, 50.0 , "Effect Frequency X ( ScaleX )" )
- Sy[1] = Number("Freq Y:", Btn_Evt, col[5], row[8], width[4], height[1], Sy[1].val, -50.0, 50.0 , "Effect Frequency Y ( ScaleY )" )
- Lx[1] = Number("Loc X:", Btn_Evt, col[5], row[9], width[4], height[1], Lx[1].val, -1000.0, 1000.0 , "Effect Loc X" )
- Ly[1] = Number("Loc Y:", Btn_Evt, col[5], row[10], width[4], height[1], Ly[1].val, -1000.0, 1000.0 , "Effect Loc Y" )
-
- if Effect_Ctrl[0].val == 1:
- PushButton("Load Image", Load_Evt, col[0], row[4], width[4], height[2] , "Load Image")
- PushButton("Select Image", Sel_Evt, col[0], row[6], width[4], height[3] , "Select Image")
- draw_Text( ( col[0]+5, row[7] ), effect_image, black, 1 )
-
- if Effect_Ctrl[0].val in [2,3,4,5,6,7,8,9]:
- Basis[1] = Menu( noisebasismenu, Btn_Evt, col[0], row[3], width[4], height[1], Basis[1].val, "Basis" )
-
- if Effect_Ctrl[0].val == 2:
- turbTwo[0] = Number( "Depth:", Btn_Evt, col[0], row[4], width[4], height[1], turbTwo[0].val, 1, 12, "Octaves")
- turbTwo[1] = Toggle("Hard noise", Btn_Evt, col[0], row[5], width[4], height[1], turbTwo[1].val, "Hard noise")
- turbTwo[2] = Slider( "Amp:", Btn_Evt, col[0], row[6], width[4], height[1], turbTwo[2].val, 0.0, 3.0, 0, "Ampscale ")
- turbTwo[3] = Slider( "Freq:", Btn_Evt, col[0], row[7], width[4], height[1], turbTwo[3].val, 0.0, 6.0, 0, "Freqscale")
- if Effect_Ctrl[0].val == 3:
- vlnoiTwo[1] = Menu(noisebasismenu, Btn_Evt, col[0], row[4], width[4], height[1], vlnoiTwo[1].val, "Distortion Noise")
- vlnoiTwo[0] = Slider( "Dist: ", Btn_Evt, col[0], row[5], width[4], height[1], vlnoiTwo[0].val, 0.0, 10.0, 0 , "Distort" )
- if Effect_Ctrl[0].val == 4:
- marbleTwo[0] = Number( "Depth: ", Btn_Evt, col[0], row[6], width[4], height[1], marbleTwo[0].val, 1, 12, "Octaves")
- marbleTwo[2] = Slider( "Turb: ", Btn_Evt, col[0], row[7], width[4], height[1], marbleTwo[2].val, 0.0,20.0, 0, "Turbulence")
- marbleTwo[3] = Menu( biastypemenu, Btn_Evt ,col[0], row[4], width[4], height[1], marbleTwo[3].val, "Bias")
- marbleTwo[5] = Slider("ReScale: ", Btn_Evt, col[0], row[8], width[4], height[1], marbleTwo[5].val, 0.0,20.0, 0, "ReScale")
- if marbleTwo[3].val != 4:
- marbleTwo[4] = Menu(sharptypemenu,Btn_Evt ,col[0], row[5], width[4], height[1], marbleTwo[4].val, "Sharpen")
-
- if Effect_Ctrl[0].val in [5,6,7,8,9]:
- musgrTwo[0] = Slider( "H: ", Btn_Evt, col[0], row[5], width[4], height[1], musgrTwo[0].val, 0.0, 3.0, 0 , "H" )
- musgrTwo[1] = Slider( "Lacu: ", Btn_Evt, col[0], row[6], width[4], height[1], musgrTwo[1].val, 0.0, 6.0, 0 , "Lacunarity" )
- musgrTwo[2] = Slider( "Octs: ", Btn_Evt, col[0], row[4], width[4], height[1], musgrTwo[2].val, 0, 12, 0 , "Octaves" )
- if Effect_Ctrl[0].val in [6,7,8]:
- musgrTwo[3] = Slider( "Offst: ", Btn_Evt, col[0], row[7], width[4], height[1], musgrTwo[3].val, 0.0, 6.0, 0 , "Offset" )
- if Effect_Ctrl[0].val in [6,7]:
- musgrTwo[4] = Slider( "Gain: ", Btn_Evt, col[0], row[8], width[4], height[1], musgrTwo[4].val, 0.0, 6.0, 0 , "Gain" )
-
- if Effect_Ctrl[0].val > 9 and Effect_Ctrl[0].val < 31:
- Effect_Ctrl[5] = Number("Depth:", Btn_Evt, col[0], row[4], width[4], height[1], Effect_Ctrl[5].val, 0, 12 , "Fractalize Effect: Octaves" )
- Effect_Ctrl[4] = Number("Distort:",Btn_Evt, col[0], row[7], width[4], height[1], Effect_Ctrl[4].val, 0.0, 50.0 , "Distort Effect: Amount" )
- Effect_Ctrl[6] = Slider("Freq:", Btn_Evt, col[0], row[5], width[4], height[1], Effect_Ctrl[6].val, 0.0, 6.0, 0, "Fractalize Effect: Frequency" )
- Effect_Ctrl[7] = Slider("Amp:", Btn_Evt, col[0], row[6], width[4], height[1], Effect_Ctrl[7].val, 0.0, 3.0, 0, "Fractalize Effect: Amplitude" )
- if Effect_Ctrl[0].val < 22:
- Effect_Ctrl[3] = Menu(biastypemenu, Btn_Evt ,col[0], row[3], width[4], height[1], Effect_Ctrl[3].val, "Effect bias")
- if Effect_Ctrl[0].val in [31,32]:
- Effect_Ctrl[8] = Number("Amount:", Btn_Evt, col[0], row[4], width[4], height[1], Effect_Ctrl[8].val, -20.0, 20.0, "Effect: Amount" )
- if Effect_Ctrl[0].val == 33:
- draw_Text( ( col[0]+5, row[4] ), 'Custom math ( h, x,y, a,b )' , black, 0 )
- CustomFX[0] = String( "a = ", Btn_Evt, col[0], row[5], width[4], height[1] ,CustomFX[0].val,96, "a" )
- CustomFX[1] = String( "b = ", Btn_Evt, col[0], row[6], width[4], height[1] ,CustomFX[1].val,96, "b" )
- CustomFX[2] = String( "result = ", Btn_Evt, col[0], row[7], width[4], height[1] ,CustomFX[2].val,96, "result" )
-
-###-------------------------
-## Filter / Height Buttons:
-#
-def FilterButtons( col, row, width, height ):
- global iScale, Offset, Invert, Min, Max, Falloff, CustomFilt
- global Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, DefaultIpoName, Filter_Order
-
- iScale[2] = Number("Height:", Btn_Evt, col[5], row[2], width[3], height[2], iScale[2].val, -10.0, 10.0 , "Terrain Height: Scale" )
- Invert[2] = Toggle("Inv.", Btn_Evt, col[9], row[2], width[0], height[2], Invert[2].val, "Terrain Height: Invert")
- Offset[2] = Number("Offset:", Btn_Evt, col[5], row[3], width[4], height[1], Offset[2].val, -10.0, 10.0 , "Terrain Height: Offset" )
- Max = Number( "Plateau:", Btn_Evt, col[5], row[5], width[4], height[1], Max.val, Min.val, 1.0 , "Terrain Height: Clamp Max. ( Plateau )" )
- Min = Number( "Sealevel:", Btn_Evt, col[5], row[6], width[4], height[1], Min.val, -1.0, Max.val , "Terrain Height: Clamp Min. ( Sealevel )" )
- Falloff[0] = Menu( falloftypemenu, Btn_Evt ,col[5], row[9], width[4], height[2], Falloff[0].val, "Terrain Height: Edge falloff")
- if Falloff[0].val !=0:
- Falloff[1] = Number("X:", Btn_Evt, col[5], row[10], width[1], height[1], Falloff[1].val , 0.01, 100.0 , "Edge falloff: X Size" )
- Falloff[2] = Number("Y:", Btn_Evt, col[8], row[10], width[1], height[1], Falloff[2].val , 0.01, 100.0 , "Edge falloff: Y Size" )
- Falloff[4] = Toggle("Inv.", Btn_Evt, col[7], row[10], width[0], height[1], Falloff[4].val, "Edge falloff: Invert")
- Falloff[3] = Toggle("Edge At Sealevel", Btn_Evt, col[5], row[7], width[4], height[1], Falloff[3].val, "Edge falloff: Edge at Sealevel")
-
- Filter_Mode = Menu( filtermodemenu, No_Evt, col[0], row[2], width[4], height[2], Filter_Mode.val, "Filter: Mode")
- if Filter_Mode.val ==1:
- Def_Filter_Ctrl[0] = Menu( filtertypemenu, Btn_Evt, col[0], row[5], width[4], height[2], Def_Filter_Ctrl[0].val, "Filter: Type")
- Def_Filter_Ctrl[1] = Number("Amount: ", Btn_Evt, col[0], row[6], width[4], height[1], Def_Filter_Ctrl[1].val, 0.1, 100.0 , "Filter: Amount" )
-
- if Filter_Mode.val ==2:
- Ipo_Filter_Ctrl[0] = String("IP:", Ipo_Evt, col[0], row[5], width[4], height[2], Ipo_Filter_Ctrl[0].val,20, "Ipo datablock name" )
- if Ipo_Filter_Ctrl[0].val !='':
- Ipo_Filter_Ctrl[1] = Number("Use This Curve:",Ipo_Evt, col[0], row[7], width[4], height[3], Ipo_Filter_Ctrl[1].val, 0, 29, "Select curve to use" )
- Ipo_Filter_Ctrl[2] = Number("Curve Length:", Ipo_Evt, col[0], row[8], width[4], height[1], Ipo_Filter_Ctrl[2].val, 0.0, 1000.0, "X: Length (number of frames) of the selected curve." )
- Ipo_Filter_Ctrl[3] = Number("Curve Height:", Ipo_Evt, col[0], row[9], width[4], height[1], Ipo_Filter_Ctrl[3].val, 0.0, 1000.0, "Y: Height (offset) of the selected curve." )
- else:
- draw_Text( ( col[0]+5, row[6] ), 'Enter Ipo DataBlock name,' , black, 0 )
- draw_Text( ( col[0]+5, row[9] ), 'or else:' , black, 0 )
- PushButton( "New IpoDataBlock/Object", New_Ipo_Evt, col[0], row[10], width[4], height[1], "Creates new Ipo Object(Empty), and Ipo DataBlock(curves)' to use as height filter")
-
- if Filter_Mode.val ==3:
- draw_Text( ( col[0]+5, row[4] ), 'Custom math ( h, x,y, a,b )' , black, 0 )
- CustomFilt[0] = String( "a = ", Btn_Evt, col[0], row[5], width[4], height[1] ,CustomFilt[0].val,96, "a" )
- CustomFilt[1] = String( "b = ", Btn_Evt, col[0], row[6], width[4], height[1] ,CustomFilt[1].val,96, "b" )
- CustomFilt[2] = String( "result = ", Btn_Evt, col[0], row[7], width[4], height[1] ,CustomFilt[2].val,96, "result" )
- if Filter_Mode.val !=0:
- Filter_Order = Toggle("Change Filter Order", Btn_Evt, col[0], row[3], width[4], height[1], Filter_Order.val, "Filter Order: OFF = Noise+Effect+Falloff+FILTER / ON = Noise+FILTER+Effect+Falloff.")
-
-###-------------------------
-## Option / Generate Image Buttons:
-#
-def OptionButtons( col, row, width, height ):
- global PreView, previewname
-
- PreView[0] = Toggle("Make Image", No_Evt, col[0], row[2], width[4], height[2], PreView[0].val, "Image: On/Off (Make a new Image in UV/ImageEditor Window, and give a name to it)")
- if PreView[0].val !=0:
- previewname = String( "IM:", No_Evt, col[0], row[3], width[4], height[1] ,previewname.val, 16, "IM:Name, Render terrain height to this image" )
- PreView[1] = Number("", Im_Evt, col[0], row[4], width[1], height[1], PreView[1].val, 0.0, 10.0, "Image: Intensity Scale")
- PreView[2] = Number("", Im_Evt, col[3], row[4], width[1], height[1], PreView[2].val,-10.0, 10.0, "Image: Offset")
- PushButton( "Draw Image", Im_Evt, col[0], row[5], width[4], height[1] , "Image: Update image ( KEY: V )")
- draw_Text( ( col[5], row[1] ), 'Create yourself a new image', black, 0 )
- draw_Text( ( col[5], row[2] ), 'in UV/Image Editor Window,', black, 0 )
- draw_Text( ( col[5], row[3] ), 'give it a name,', black, 0 )
- draw_Text( ( col[5], row[4] ), 'and save it manualy.', black, 0 )
-
-####--------------------------------------------------------------------------
-###--------------------------------------------------------------------------
-## Draw G.U.I. -------------------------------------------------------------
-#--------------------------------------------------------------------------
-def drawgui():
- global guitabs, ledcolor, FullScreen, AutoUpd, RandMod, RSeed, filemessage
- global Effect_Ctrl, Filter_Mode, Falloff, PreView, rand_H, rand_S, rand_L, rand_I
-
- glClearColor(background[0],background[1],background[2],background[3])
- glClear(GL_COLOR_BUFFER_BIT)
- scissorbox=Buffer(GL_FLOAT,4)
- glGetFloatv(GL_SCISSOR_BOX,scissorbox)
- scissbleft=int(scissorbox[0])
- scissbbase=int(scissorbox[1])
- scissbwidth=int(scissorbox[2])
- scissbheight=int(scissorbox[3])
- xstart = 5
- ystart = 5
- xgap = 5
- ygap = 5
- if FullScreen.val==1:
- guiwidth = scissbwidth-10
- guiheight = scissbheight-25
- if guiwidth < size_x/2:
- guiwidth = size_x/2
- if guiheight < size_y/2:
- guiheight = size_y/2
- else:
- guiwidth = size_x
- guiheight = size_y
- col,row = [],[]
- xpart = ( ( guiwidth-xstart ) / columns )
- ypart = ( ( guiheight-ystart ) / rows )
- width = []
- for c in xrange( columns ):
- col.append( xgap + xpart * c + xstart )
- width.append( xpart*(c+1)-xgap )
- height = [ (ypart-ygap)/2 , ypart-ygap, (ypart*3-ygap)/2, ypart*2-ygap, (ypart*5-ygap)/2 ]
- for r in xrange( rows ):
- row.append( ygap + ypart * r + ystart )
- row.reverse()
-
- ###-------------------------
- ## Draw G.U.I.:
- draw_BackPanel( 'Another Noise Tool 1.05', xstart, ystart, guiwidth, guiheight + ygap, lightgrey )
-
- FullScreen = Toggle("", Scrn_Evt, guiwidth-32, guiheight+ygap+3, 15, 15, FullScreen.val ,"FullScreen" )
- PushButton( "X", End_Evt, guiwidth-16, guiheight+ygap+3, 15, 15, "Exit" )
- draw_Text(( guiwidth-(guiwidth/2)-width[0], guiheight+ygap+5 ), filemessage, white, 0 )
-
- # gui tabs
- guitabs[0] = Toggle("Main", gt0_Evt, col[0], row[0], width[1], height[1], guitabs[0].val ,"Main / Mesh settings" )
- guitabs[1] = Toggle("Noise", gt1_Evt, col[2], row[0], width[1], height[1], guitabs[1].val ,"Noise settings" )
- guitabs[2] = Toggle("Effect", gt2_Evt, col[4], row[0], width[1], height[1], guitabs[2].val ,"Add Effect" )
- guitabs[3] = Toggle("Height", gt3_Evt, col[6], row[0], width[1], height[1], guitabs[3].val ,"Height Filter" )
- guitabs[4] = Toggle("Options", gt4_Evt, col[8], row[0], width[1], height[1], guitabs[4].val ,"Options" )
-
- if guitabs[0].val !=0: MeshButtons( col, row, width, height )
- elif guitabs[1].val !=0: NoiseButtons( col, row, width, height )
- elif guitabs[2].val !=0: EffectButtons( col, row, width, height )
- elif guitabs[3].val !=0: FilterButtons( col, row, width, height )
- elif guitabs[4].val !=0: OptionButtons( col, row, width, height )
- else: # some info
- draw_Panel( col[0], row[0]-5, col[9]+width[0], row[10]-10, black )
- draw_Text( ( col[0]+5, row[1] ), 'Another Noise Tool v.1.05', ledcolors[0], 2 )
- draw_Text( ( col[0]+5, row[2] ), 'by: Jimmy Hazevoet, 01/2005-03/2007', ledcolors[1], 2 )
- draw_Text( ( col[0]+5, row[3] ), 'v.1.05: build/tested in: Blender 2.43 (Wndws)', ledcolors[2], 1 )
- draw_Text( ( col[0]+5, row[4] ), 'HotKeys: ----------------------------', ledcolors[3], 2 )
- draw_Text( ( col[0]+5, row[5] ), 'Space = Update mesh', ledcolors[4], 2 )
- draw_Text( ( col[0]+5, row[6] ), 'V = Update Image', ledcolors[5], 2 )
- draw_Text( ( col[0]+5, row[7] ), 'R = Randomise', ledcolors[6], 2 )
- draw_Text( ( col[0]+5, row[8] ), 'L = Load from file', ledcolors[7], 2 )
- draw_Text( ( col[0]+5, row[9] ), 'S = Save to file', ledcolors[8], 2 )
- draw_Text( ( col[0]+5, row[10] ),'Q = Quit', ledcolors[9], 2 )
-
- # auto/generate/randomise buttons
- rand_on_off = 0
- if rand_H.val !=0: rand_on_off = 1
- elif rand_I.val !=0: rand_on_off = 1
- elif rand_S.val !=0: rand_on_off = 1
- elif rand_L.val !=0: rand_on_off = 1
- else: rand_on_off = 0
- if rand_on_off != 0:
- if RandMod.val in [1,2]:
- PushButton( "Randomise", Rndm_Evt, col[2], row[12], width[2], height[2] , "Randomise Noise ( KEY: R )")
- else: RSeed = Number("Seed: ", Rndm_Evt, col[2], row[12], width[2], height[2], RSeed.val, 0, 255 , "Random Seed: If seed = 0, the current time will be used as seed." )
- AutoUpd = Toggle("Auto", No_Evt, col[0], row[12], width[1], height[2], AutoUpd.val ,"Automatic update" )
- PushButton("Update", Upd_Evt, col[5], row[12], width[4], height[2] , "Generate / Update. ( KEY: SPACE )")
- else:
- AutoUpd = Toggle("Auto", No_Evt, col[0], row[12], width[1], height[2], AutoUpd.val ,"Automatic update" )
- PushButton("Update", Upd_Evt, col[2], row[12], width[7], height[2] , "Generate / Update. ( KEY: SPACE )")
- ####---------------------------------------------------------------------------
-
-###---------------------------------------------------------------------------
-##---------------------------------------------------------------------------
-# Key Events:
-
-def events(evt, val):
- global PreView, txtFile, AutoUpd, PreView
-
- ## hotkey: Q = Quit
- if (evt == QKEY and not val):
- name = "Quit ?%t|No %x0|Yes %x1"
- result = Blender.Draw.PupMenu(name)
- if result==1:
- Exit()
-
- ## hotkey: Space = Generate/Update terrain
- if (evt == SPACEKEY and not val):
- do_it()
-
- ## hotkey: R = Randomise noise
- if (evt in [ RKEY ] and not val):
- if AutoUpd.val != 0:
- do_it_random()
- else:
- randomiseNoise()
- Draw()
-
- ## hotkey: V = Update image
- if PreView[0].val != 0:
- if (evt in [ VKEY, RKEY ] and not val):
- do_it_preview()
-
- ## hotkey: L = Load from file
- if (evt == LKEY and not val):
- loadmenu = "Load file ?%t|" + txtFile.val
- loadresult = Blender.Draw.PupMenu(loadmenu)
- if loadresult==1:
- LoadPreset(txtFile.val)
- if AutoUpd.val != 0:
- do_it()
- else: Draw()
-
- ## hotkey: S = Save to file
- if (evt == SKEY and not val):
- savemenu = "Save file ?%t|" + txtFile.val
- saveresult = Blender.Draw.PupMenu(savemenu)
- if saveresult==1:
- SavePreset(txtFile.val)
- Draw()
-
-###---------------------------------------------------------------------------
-##---------------------------------------------------------------------------
-# Button events:
-
-def bevents(evt):
- global txtFile, effect_image, PreView, fileinfo, filemessage
- global Filter_Mode, Ipo_Filter_Ctrl, iponame, thiscurve, selectedcurve
- global antfilename, terrainname
- global actob, actme
-
- # quit/reset event
- if (evt == End_Evt ):
- name = "OK ?%t|Reset %x1|Quit %x2"
- result = Blender.Draw.PupMenu(name)
- if result==1:
- Set_ReSet_Values()
- Draw()
- elif result==2:
- Exit()
-
- ## file info string event
- if (evt == UseMe_Evt ):
- result = Blender.Draw.PupStrInput("Info: ", fileinfo, 96)
- if result:
- fileinfo = result
- Draw()
- else: return
-
- ## none event
- if (evt in [No_Evt, Scrn_Evt] ):
- Draw()
-
- ## image event
- if (evt == Im_Evt ):
- do_it_preview()
-
- ## generate/update event
- if (evt == Upd_Evt ):
- if PreView[0].val != 0:
- do_it_preview()
- do_it()
-
- ## mesh button event
- if (evt == Msh_Evt):
- if AutoUpd.val != 0:
- do_it()
- else: Draw()
-
- ## button event
- if (evt == Btn_Evt ):
- if AutoUpd.val != 0:
- if PreView[0].val != 0:
- do_it_preview()
- do_it()
- else: Draw()
-
- ## randomise event
- if (evt == Rndm_Evt ):
- if AutoUpd.val != 0:
- do_it_random()
- else:
- randomiseNoise()
- if PreView[0].val != 0:
- do_it_preview()
- Draw()
-
- ###---------------------------------------------------------
- ## Effect Image Load/Select:
- if (evt == Load_Evt ):
- Blender.Window.FileSelector ( load_image, 'LOAD IMAGE')
- if (evt == Sel_Evt ):
- try: effect_image = Image_Menu()
- except: pass
- if AutoUpd.val != 0:
- do_it()
- else: Draw()
-
- ###---------------------------------------------------------
- ## Make New IPOCurve to use as Filter:
- if (evt == New_Ipo_Evt ):
- objname = Create("ANT_Ipo_Empty")
- iponame = Create("ANT_IPO")
- block = []
- block.append("Enter new names")
- block.append("and hit OK button")
- block.append(("OB: ", objname, 0, 30, "New Ipo Object Name. (Object type = 'Empty')"))
- block.append(("IP: ", iponame, 0, 30, "New Ipo DataBlock Name"))
- block.append("Open IpoCurveEditor")
- block.append("select Ipo DataBlock" )
- block.append("'Pin' the view" )
- block.append("and edit the curves." )
- retval = PupBlock("Make A.N.T. IpoCurve Object", block)
- if retval !=0:
- ANTAutoIpo( objname.val, iponame.val )
- Ipo_Filter_Ctrl[0].val = iponame.val
-
- ###---------------------------------------------------------
- ## get IPOCurve to use as Filter:
- if (evt in [Ipo_Evt, New_Ipo_Evt] ):
- if Filter_Mode.val == 2:
- if AutoUpd.val != 0:
- try:
- ipoblockname = Ipo.Get( Ipo_Filter_Ctrl[0].val )
- thiscurve = ipoblockname.getCurves()
- selectedcurve = thiscurve[ Ipo_Filter_Ctrl[1].val ]
- if PreView[0].val != 0:
- do_it_preview()
- #if AutoUpd.val != 0:
- do_it()
- except: pass
- else:
- try:
- ipoblockname = Ipo.Get( Ipo_Filter_Ctrl[0].val )
- thiscurve = ipoblockname.getCurves()
- selectedcurve = thiscurve[ Ipo_Filter_Ctrl[1].val ]
- if PreView[0].val != 0:
- do_it_preview()
- else:
- Draw()
- except: pass
-
- ###---------------------------------------------------------
- ## gui tabs
- if (evt == gt0_Evt ):
- if guitabs[0].val == 1:
- guitabs[1].val = ( 0 )
- guitabs[2].val = ( 0 )
- guitabs[3].val = ( 0 )
- guitabs[4].val = ( 0 )
- Draw()
- if (evt == gt1_Evt ):
- if guitabs[1].val == 1:
- guitabs[0].val = ( 0 )
- guitabs[2].val = ( 0 )
- guitabs[3].val = ( 0 )
- guitabs[4].val = ( 0 )
- Draw()
- if (evt == gt2_Evt ):
- if guitabs[2].val == 1:
- guitabs[0].val = ( 0 )
- guitabs[1].val = ( 0 )
- guitabs[3].val = ( 0 )
- guitabs[4].val = ( 0 )
- Draw()
- if (evt == gt3_Evt ):
- if guitabs[3].val == 1:
- guitabs[0].val = ( 0 )
- guitabs[1].val = ( 0 )
- guitabs[2].val = ( 0 )
- guitabs[4].val = ( 0 )
- Draw()
- if (evt == gt4_Evt ):
- if guitabs[4].val == 1:
- guitabs[0].val = ( 0 )
- guitabs[1].val = ( 0 )
- guitabs[2].val = ( 0 )
- guitabs[3].val = ( 0 )
- Draw()
-
- ###---------------------------------------------------------
- ## load and save all settings:
- if (evt == SelFile_Evt ):
- Blender.Window.FileSelector ( callback, "Select .ant File")
- if (evt == LoadFile_Evt ):
- loadmenu = "Load file ?%t|" + txtFile.val
- loadresult = Blender.Draw.PupMenu(loadmenu)
- if loadresult==1:
- LoadPreset(txtFile.val)
- Draw()
- if AutoUpd.val != 0:
- do_it()
- if (evt == SaveFile_Evt ):
- savemenu = "Save file ?%t|" + txtFile.val
- saveresult = Blender.Draw.PupMenu(savemenu)
- if saveresult==1:
- SavePreset(txtFile.val)
- Draw()
-
- ###---------------------------------------------------------
- # New Grid
- ###-------------------------
- if (evt == New_Evt):
- scn = Blender.Scene.GetCurrent()
- gridname = Create("Terrain")
- gridres = Create(256)
- curspos = Create(0)
- block = []
- block.append(("OB: ", gridname, 0, 30, "New Object Name."))
- block.append(("Resol: ", gridres, 4, 1024, "New grid resolution"))
- block.append(("At Cursor", curspos, "New grid at cursor position"))
- retval = PupBlock("New Grid Mesh", block)
- if retval !=0:
- MakeGridMesh( gridres.val, gridname.val, curspos.val, scn )
- obj = scn.objects.active
- if obj.type == 'Mesh':
- actob=[]
- actme=[]
- actob.append( obj )
- actme.append( actob[0].getData(mesh=1) )
- Blender.Redraw()
-
- ###---------------------------------------------------------
- # Assign Grid
- ###-------------------------
- if (evt == App_Evt):
- scn = Blender.Scene.GetCurrent()
- obj = scn.objects.active
- if obj:
- if obj.type == 'Mesh':
- actob=[]
- actme=[]
- actob.append( obj )
- actme.append( actob[0].getData(mesh=1) )
- Draw()
-
- ###-------------------------
- if (evt not in [LoadFile_Evt,SaveFile_Evt] ):
- filemessage = ''
- #Draw()
-
- ### end events. -------------------------
-
-####-------------------------------------------------------------------------------------
-###-------------------------------------------------------------------------------------
-##-------------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------------
-
-##----------------------------------
-# A.N.T. Auto Ipo generator:
-def ANTAutoIpo( objname, iponame ):
- scn=Scene.GetCurrent()
- # Deselect all objects:
- scn.objects.selected=[]
- # Create new 'ANT_IPO_OBJECT':
- obj = scn.objects.new('Empty', objname )
- obj.setDrawMode(8)
- obj.select(1)
- obj.layers = Window.ViewLayers()
- # Set current frame at 1:
- frame = Get('curframe')
- if frame !=1:
- Set('curframe',1)
- frame = Get('curframe')
- # Insert IpoKeys:
- obj.setLocation(0.0, 0.0, 0.0)
- obj.insertIpoKey(0)
- Set('curframe',101)
- obj.setLocation(100.0, 100.0, 100.0)
- obj.insertIpoKey(0)
- Set('curframe',1)
- # Set Ipo name:
- ip = obj.getIpo()
- ip.name = iponame
- #-------------------------
- print "New ANT_IPO: " + objname +" (Object) and " + iponame + " (Ipo DataBlock) Created!"
- #-------------------------
-
-##-------------------------------------------------------------------------------------
-
-##-------------------------
-# Generate random numbers:
-def randnum(low,high):
- global RandMod, RSeed
- if RandMod.val == 0:
- # Noise.random setRandomSeed
- s = Noise.setRandomSeed( RSeed.val )
- num = Noise.random()
- num = num*(high-low)
- num = num+low
- elif RandMod.val == 1:
- # Mathutils.Rand
- num = Mathutils.Rand(low,high)
- else:
- # BPyMathutils Mersenne Twister genrand
- num = genrand()
- num = num*(high-low)
- num = num+low
- return num
-
-##-------------------------
-# Randomise noise: height, size and location:
-def randomiseNoise():
- global rand_I, rand_H, rand_S, rand_L, NSize, iScale, Offset, Invert, Lx, Ly, Sx, Sy
-
- if rand_I.val !=0:
- iScale[0] = Create( randnum( 0.2 , 3.0 ) )
- Offset[0] = Create( randnum(-1.0 , 1.0 ) )
- if rand_H.val !=0:
- iScale[2] = Create( randnum( 0.10 , 1.0 ) )
- Offset[2] = Create( randnum(-0.25 , 0.25 ) )
- if rand_S.val !=0:
- NSize[0] = Create( randnum( 0.25 , 2.5 ) )
- #Sx[0] = Create( randnum( 0.5 , 1.5 ) )
- #Sy[0] = Create( randnum( 0.5 , 1.5 ) )
- if rand_L.val !=0:
- Lx[0] = Create( randnum( -10000 , 10000 ) )
- Ly[0] = Create( randnum( -10000 , 10000 ) )
-
-##-------------------------------------------------------------------------------------
-
-###--------------------------
-# Load Image:
-def load_image( ImageFileName ):
- Image.Load( ImageFileName )
-
-###--------------------------
-# Select Image Menu:
-def Image_Menu():
- try:
- names=[]
- imagelist = Image.Get()
- imagelist.reverse()
- for numbers, obnames in enumerate( imagelist ):
- n = obnames.getName()
- names.append( n )
- imlistText = string.join( [ '|' + str(names[key]) + '%x' + str(key) for key in xrange(numbers+1) ], '' )
- image_menu = Blender.Draw.PupMenu( "Images: %t" + imlistText )
- if image_menu == -1:
- return ''
- return imagelist[ image_menu ].getName()
- except:
- return 'No image found!'
-
-###--------------------------
-# Get Image Pixels:
-def Image_Func( x,y ):
- try:
- pic = Image.Get( effect_image )
- except:
- return 0.0
- w, h = pic.getSize()
- x, y = x,-y
- x = int(w * ((x + 1.0) % 2.0) / 2.0)
- y = int((h-1) - h * ((y + 1.0) % 2.0) / 2.0)
- c = pic.getPixelF( x,y )
- return ( c[0] + c[1] + c[2] ) / 3.0
-
-##-------------------------------------------------------------------------------------
-
-# Transpose noise coords:
-def Trans((x,y,z), size, loc ):
- x = ( x / size[1] / size[0] + loc[0] )
- y = ( y / size[2] / size[0] + loc[1] )
- z = 0.0 #( z / size[3] / size[0] + loc[2] )
- return x,y,z
-
-# Transpose effect coords:
-def Trans_Effect((x,y,z), size, loc ):
- x = ( x * size[1] * size[0] + loc[0] )
- y = ( y * size[2] * size[0] + loc[1] )
- z = 0.0
- return x,y,z
-
-# Height scale:
-def HeightScale( input, iscale, offset, invert ):
- if invert !=0:
- return (1.0-input) * iscale + offset
- else:
- return input * iscale + offset
-
-# dist.
-def Dist(x,y):
- return sqrt( (x*x)+(y*y) )
-
-##-----------------------------------
-# bias types:
-def no_bias(a):
- return a
-def sin_bias(a):
- return 0.5 + 0.5 * sin(a)
-def cos_bias(a):
- return 0.5 + 0.5 * cos(a)
-def tri_bias(a):
- b = 2 * phi
- a = 1 - 2 * abs(floor((a * (1/b))+0.5) - (a*(1/b)))
- return a
-def saw_bias(a):
- b = 2 * phi
- n = int(a/b)
- a -= n * b
- if a < 0: a += b
- return a / b
-# sharpen types:
-def soft(a):
- return a
-def sharp(a):
- return a**0.5
-def sharper(a):
- return sharp(sharp(a))
-Bias_Types = [ sin_bias, cos_bias, tri_bias, saw_bias, no_bias ]
-Sharp_Types = [ soft, sharp, sharper ]
-
-##-----------------------------------
-# clamp height
-def clamp( height, min, max ):
- if ( height < min ): height = min
- if ( height > max ): height = max
- return height
-
-##-----------------------------------
-# Mix modes
-def maximum( a, b ):
- if ( a > b ): b = a
- return b
-def minimum( a, b ):
- if ( a < b ): b = a
- return b
-
-def Mix_Modes( (i,j),(x,y,z) , a,b, mixfactor, mode ):
- a = a * ( 1.0 - mixfactor )
- b = b * ( 1.0 + mixfactor )
- if mode == 0: return ( b ) #0 effect only
- elif mode == 1: return ( a*(1.0-0.5) + (b*0.5) ) #1 mix
- elif mode == 2: return ( a + b ) #2 add
- elif mode == 3: return ( a - b ) #3 sub.
- elif mode == 4: return ( a * b ) #4 mult.
- elif mode == 5: return (abs( a - b )) #5 abs diff.
- elif mode == 6: return 1.0-((1.0-a)*(1.0-b)/1.0) #6 screen
- elif mode == 7: return ( a + b ) % 1.0 #7 addmodulo
- elif mode == 8: return min( a, b ) #8 min.
- elif mode == 9: return max( a, b ) #9 max.
- elif mode == 10: #10 warp: effect
- noise = mixfactor * Noise_Function(x,y,z)
- return Effects( (i,j),(x+noise,y+noise,z) )
- elif mode == 11: #11 warp: noise
- effect = mixfactor * Effects( (i,j),(x,y,z) )
- return Noise_Function( x+effect, y+effect, z )
- else: return a
-
-###----------------------------------------------------------------------
-# Effect functions:
-
-# Effect_Basis_Function:
-def Effect_Basis_Function((x,y), type, bias ):
-
- iscale = 1.0
- offset = 0.0
- ## gradient:
- if type == 0:
- effect = offset + iscale * ( Bias_Types[ bias ]( x + y ) )
- ## waves / bumps:
- if type == 1:
- effect = offset + iscale * 0.5 * ( Bias_Types[ bias ]( x*phi ) + Bias_Types[ bias ]( y*phi ) )
- ## zigzag:
- if type == 2:
- effect = offset + iscale * Bias_Types[ bias ]( offset + iscale * sin( x*phi + sin( y*phi ) ) )
- ## wavy:
- if type == 3:
- effect = offset + iscale * ( Bias_Types[ bias ]( cos( x ) + sin( y ) + cos( x*2+y*2 ) - sin( -x*4+y*4) ) )
- ## sine bump:
- if type == 4:
- effect = offset + iscale * 1-Bias_Types[ bias ](( sin( x*phi ) + sin( y*phi ) ))
- ## dots:
- if type == 5:
- effect = offset + iscale * ( Bias_Types[ bias ](x*phi*2) * Bias_Types[ bias ](y*phi*2) )-0.5
- ## rings / dome:
- if type == 6:
- effect = offset + iscale * ( Bias_Types[ bias ]( 1.0-(x*x+y*y) ) )
- ## spiral:
- if type == 7:
- effect = offset + iscale * Bias_Types[ bias ](( x*sin( x*x+y*y ) + y*cos( x*x+y*y ) ))*0.5
- ## square / piramide:
- if type == 8:
- effect = offset + iscale * Bias_Types[ bias ](1.0-sqrt( (x*x)**10 + (y*y)**10 )**0.1)
- ## blocks:
- if type == 9:
- effect = ( 0.5-max( Bias_Types[ bias ](x*phi) , Bias_Types[ bias ](y*phi) ))
- if effect > 0.0: effect = 1.0
- effect = offset + iscale * effect
- ## grid:
- if type == 10:
- effect = ( 0.025-min( Bias_Types[ bias ](x*phi) , Bias_Types[ bias ](y*phi) ))
- if effect > 0.0: effect = 1.0
- effect = offset + iscale * effect
- ## tech:
- if type == 11:
- a = ( max( Bias_Types[ bias ](x*pi) , Bias_Types[ bias ](y*pi) ))
- b = ( max( Bias_Types[ bias ](x*pi*2+2) , Bias_Types[ bias ](y*pi*2+2) ))
- effect = ( min( Bias_Types[ bias ](a) , Bias_Types[ bias ](b) ))*3.0-2.0
- if effect > 0.5: effect = 1.0
- effect = offset + iscale * effect
-
- ## crackle:
- if type == 12:
- t = turbulence(( x, y, 0 ), 6, 0, 0 ) * 0.25
- effect = vlNoise(( x, y, t ), 0.25, 0, 8 )
- if effect > 0.5: effect = 0.5
- effect = offset + iscale * ( effect )
- ## sparse cracks noise:
- if type == 13:
- effect = 2.5 * abs( noise((x*0.5,y*0.5, 0 ), 1 ) )-0.1
- if effect > 0.25: effect = 0.25
- effect = offset + iscale * ( effect * 2.5 )
- ## shattered rock noise:
- if type == 14:
- effect = 0.5 + noise((x,y,0), 7 )
- if effect > 0.75: effect = 0.75
- effect = offset + iscale * effect
- ## lunar noise:
- if type == 15:
- effect = 0.25 + 1.5 * voronoi(( x+2, y+2, 0 ), 1 )[0][0]
- if effect > 0.5: effect = 0.5
- effect = offset + iscale * ( effect * 2.0 )
- ## cosine noise:
- if type == 16:
- effect = cos( 5*noise(( x, y, 0 ), 0 ) )
- effect = offset + iscale * ( effect*0.5 )
- ## spikey noise:
- if type == 17:
- n = 0.5 + 0.5 * turbulence(( x*5, y*5, 0 ), 8, 0, 0 )
- effect = ( ( n*n )**5 )
- effect = offset + iscale * effect
- ## stone noise:
- if type == 18:
- effect = offset + iscale *( noise((x*2,y*2, 0 ), 0 ) * 1.5 - 0.75)
- ## Flat Turb:
- if type == 19:
- t = turbulence(( x, y, 0 ), 6, 0, 0 )
- effect = t*2.0
- if effect > 0.25: effect = 0.25
- effect = offset + iscale * ( effect )
- ## Flat Voroni:
- if type == 20:
- t = 1-noise(( x, y, 0 ), 3 )
- effect = t*2-1.75
- if effect > 0.25: effect = 0.25
- effect = offset + iscale * ( effect )
-
- if effect < 0.0: effect = 0.0
- return effect
-
-# fractalize Effect_Basis_Function: ------------------------------
-def Effect_Function((x,y), type,bias, turb, depth,frequency,amplitude ):
-
- ## effect distortion:
- if turb != 0.0:
- t = vTurbulence(( x, y, 0 ), 6, 0, 0 )
- x = x + ( 0.5 + 0.5 * t[0] ) * turb
- y = y + ( 0.5 + 0.5 * t[1] ) * turb
-
- result = Effect_Basis_Function((x,y), type, bias )
- ## fractalize effect:
- if depth != 0:
- i=0
- while i < depth:
- i+=1
- x *= frequency
- y *= frequency
- amplitude = amplitude / i
- result += Effect_Basis_Function( (x,y), type, bias ) * amplitude
- return result
-
-###--------------------------------------------------
-# Custom effect:
-def CustomEffect( x,y,z,h ):
- global CustomFX
- try:
- a = eval( CustomFX[0].val )
- b = eval( CustomFX[1].val )
- result = eval( CustomFX[2].val )
- return result
- except:
- return 0.0
-
-###--------------------------------------------------
-## Effect Selector:
-
-def Effects( (i,j),(x,y,z), h=0.0 ):
- global Effect_Type, Effect_Ctrl, iScale, Offset, Invert
- global NSize, Lx, Ly, Lz, Sx, Sy, Sz, marbleTwo, turbTwo, vlnoiTwo, Basis, musgrTwo
-
- x,y,z = Trans_Effect((x,y,z),( NSize[1].val, Sx[1].val, Sy[1].val, 0 ),( Lx[1].val, Ly[1].val, 0 ) )
- basis = Basis[1].val
- if basis == 9: basis = 14
- vbasis = vlnoiTwo[1].val
- if vbasis == 9: vbasis = 14
- if Effect_Ctrl[0].val == 1:
- try: effect = Image_Func( x,y )
- except: effect = 0.0
- elif Effect_Ctrl[0].val == 2: effect = 0.5+0.5*turbulence(( x,y,z ),turbTwo[0].val, turbTwo[1].val, basis, turbTwo[2].val, turbTwo[3].val )
- elif Effect_Ctrl[0].val == 3: effect = 0.5+0.5*vlNoise(( x,y,z ),vlnoiTwo[0].val, vbasis, basis )
- elif Effect_Ctrl[0].val == 4: effect = 0.5*marbleNoise((x,y,z), marbleTwo[0].val, basis, marbleTwo[2].val, marbleTwo[3].val, marbleTwo[4].val, marbleTwo[5].val )
- elif Effect_Ctrl[0].val == 5: effect = 0.5*multiFractal(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, basis )
- elif Effect_Ctrl[0].val == 6: effect = 0.5*ridgedMFractal(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, musgrTwo[3].val, musgrTwo[4].val, basis )
- elif Effect_Ctrl[0].val == 7: effect = 0.5*hybridMFractal(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, musgrTwo[3].val, musgrTwo[4].val, basis )
- elif Effect_Ctrl[0].val == 8: effect = 0.5*heteroTerrain(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, musgrTwo[3].val, basis )*0.5
- elif Effect_Ctrl[0].val == 9: effect = 0.5*fBm(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, basis )+0.5
- elif Effect_Ctrl[0].val > 9 and Effect_Ctrl[0].val < 31:
- effect = Effect_Function((x,y), Effect_Ctrl[0].val-10, Effect_Ctrl[3].val, Effect_Ctrl[4].val, Effect_Ctrl[5].val, Effect_Ctrl[6].val, Effect_Ctrl[7].val )
- elif Effect_Ctrl[0].val == 31: effect = Effect_Ctrl[8].val * random()
- elif Effect_Ctrl[0].val == 32: effect = Effect_Ctrl[8].val
- elif Effect_Ctrl[0].val == 33: effect = CustomEffect( x,y,z, h )
- effect = HeightScale( effect, iScale[1].val , Offset[1].val, Invert[1].val )
- return effect*2.0
-
-###----------------------------------------------------------------------
-# Noise:
-##-----------------------------------
-
-## voronoi_turbulence:
-def voroTurbMode((x,y,z), voro, mode ):
- if mode == 0: # soft
- return voronoi(( x,y,z ),voro[0], voro[1] )[0][0]
- if mode == 1: # hard
- return ( abs( 0.5-voronoi(( x,y,z ),voro[0], voro[1] )[0][0] ) )+0.5
-def voronoi_turbulence((x,y,z), voro, tur ):
- result = voroTurbMode((x,y,z), voro, tur[1] )
- depth = tur[0]
- amp = tur[2]
- freq = tur[3]
- i=0
- for i in xrange( depth ):
- i+=1
- result += voroTurbMode( ( x*(freq*i), y*(freq*i), z ), voro, tur[1] )* ( amp*0.5/i )
- return (result*4.0-2.0)
-
-## DistortedNoise / vlNoise_turbulence:
-def vlnTurbMode((x,y,z), vlno, basis, mode ):
- if mode == 0: # soft
- return vlNoise(( x,y,z ),vlno[0], vlno[1], basis )
- if mode == 1: # hard
- return ( abs( -vlNoise(( x,y,z ),vlno[0], vlno[1], basis ) ) )
-def vlNoise_turbulence((x,y,z), vlno, tur, basis ):
- result = vlnTurbMode((x,y,z), vlno, basis, tur[1] )
- depth = tur[0]
- amp = tur[2]
- freq = tur[3]
- i=0
- for i in xrange( depth ):
- i+=1
- result += vlnTurbMode( ( x*(freq*i), y*(freq*i), z ), vlno, basis, tur[1] ) * ( amp*0.5/i )
- return result*2.0+0.5
-
-## marbleNoise:
-def marbleNoise( (x,y,z), depth, basis, turb, bias, sharpnes, rescale ):
- m = ( x * rescale + y * rescale + z ) * 5
- height = m + turb * turbulence( ( x ,y ,z ), depth, 0, basis, 0.5, 2.0 )
- height = Bias_Types[ bias ]( height )
- if bias != 4:
- height = Sharp_Types[ sharpnes ]( height )
- return height*2.0
-
-## lava_multiFractal:
-def lava_multiFractal( ( x,y,z ),Ha, La, Oc, distort, Basis ):
- m = multiFractal( ( x,y,z ), Ha, La, Oc, Basis)
- d = m * distort
- m2 = 0.5 * multiFractal( ( x+d,y+d,d*0.5 ), Ha, La, Oc, Basis)
- return (m * m2)**0.5
-
-## slopey_noise:
-def slopey_noise((x,y,z), H, lacunarity, octaves, distort, basis ):
- x=x*2
- y=y*2
- turb = fBm((x,y,z), H, lacunarity, octaves, 2 ) * 0.5
- map = 0.5 + noise( ( x+turb, y+turb, z ), basis )
- result = map + turb * distort
- return result
-
-## duo_multiFractal:
-def double_multiFractal((x,y,z), H, lacunarity, octaves, offset, gain, basis ):
- n1 = multiFractal( (x*1.5+1,y*1.5+1,z), 1.0, 1.0, 1.0, basis[0] ) * offset
- n2 = multiFractal( (x-1,y-1,z), H, lacunarity, octaves, basis[1] ) * gain
- result = ( n1*n1 + n2*n2 )*0.5
- return result
-
-## distorted_heteroTerrain:
-def distorted_heteroTerrain((x,y,z), H, lacunarity, octaves, offset, distort, basis ):
- h1 = ( heteroTerrain((x,y,z), 1.0, 2.0, 1.0, 1.0, basis[0] ) * 0.5 )
- h2 = ( heteroTerrain(( x, y, h1*distort ), H, lacunarity, octaves, offset, basis[1] ) * 0.25 )
- result = ( h1*h1 + h2*h2 )
- return result
-
-## SlickRock:
-def SlickRock((x,y,z), H, lacunarity, octaves, offset, gain, basis ):
- n = multiFractal( (x,y,z), 1.0, 2.0, 1.0, basis[0] )
- r = ridgedMFractal((x,y,n*0.5), H, lacunarity, octaves, offset, gain, basis[1] )*0.5
- return n+(n*r)
-
-## terra_turbulence:
-def terra_turbulence((x,y,z), depth, hard, basis, amp, freq ):
- t2 = turbulence( ( x, y, z ), depth, hard , basis, amp, freq )
- return (t2*t2*t2)+0.5
-
-## rocky_fBm:
-def rocky_fBm((x,y,z), H, lacunarity, octaves, basis ):
- turb = fBm((x,y,z), H, lacunarity, octaves, 2 ) * 0.25
- coords = ( x+turb, y+turb, z )
- map = noise( coords, 7 )
- result = map + fBm( coords, H, lacunarity, octaves, basis ) + 1.0
- return result
-
-## Shattered_hTerrain:
-def Shattered_hTerrain((x,y,z), H, lacunarity, octaves, offset, distort, basis ):
- d = ( turbulence( ( x, y, z ), 6, 0, 0, 0.5, 2.0 ) * 0.5 + 0.5 )*distort*0.25
- t0 = ( turbulence( ( x+d, y+d, z ), 0, 0, 7, 0.5, 2.0 ) + 0.5 )
- t2 = ( heteroTerrain(( x*2, y*2, t0*0.5 ), H, lacunarity, octaves, offset, basis ) )
- return (( t0*t2 )+t2*0.5)*0.75
-
-## vlhTerrain
-def vlhTerrain((x,y,z), H, lacunarity, octaves, offset, basis, vlbasis, distort ):
- ht = heteroTerrain(( x, y, z ), H, lacunarity, octaves, offset, basis )*0.5
- vl = ht * vlNoise((x,y,z), distort, basis, vlbasis )*0.5+0.5
- return vl * ht
-
-####---------------------------------------.
-### StatsByAlt, double terrain basis mode:
-def TerrainBasisMode((x,y,z), basis, mode ):
- if mode == 0: # noise
- return noise((x,y,z),basis)
- if mode == 1: # noise ridged
- return ( 1.0-abs( noise((x,y,z),basis) ) )-0.5
- if mode == 2: # vlNoise
- return vlNoise((x,y,z), 1.0, 0, basis )
- else: # vlNoise ridged
- return ( 1.0-abs( vlNoise((x,y,z), 1.0, 0, basis ) ) )-0.5
-
-#### StatsByAlt terrain:
-def StatsByAltTerrain((x,y,z), exp, lacu, octs, offset, amp, basis, mode ):
- result = 0.5 * (offset + TerrainBasisMode((x,y,z), basis, mode ) )
- octs = int( octs )
- i = 0
- for i in xrange( 1, octs ):
- i += 1
- result += result * amp * 0.5 * (offset + TerrainBasisMode((x,y,z), basis, mode ) )
- x *= lacu
- y *= lacu
- amp /= ( exp * 0.5 ) * i
- return result
-
-##### double terrain:
-def doubleTerrain((x,y,z), exp, lacu, octs, offset, threshold, basis, mode ):
- result = amp = freq = 1.0
- #octs = int( octs )
- offset*=0.5
- i = 1
- signal = result = 0.5 * (offset + TerrainBasisMode((x,y,z), basis, mode ) )
- for i in xrange( 1, octs ):
- i += 1
- x = x * lacu
- y = y * lacu
- freq *= lacu
- amp = pow( freq, -exp )
- amp *= i
- weight = signal / threshold
- if weight > 1.0: weight = 1.0
- if weight < 0.0: weigth = 0.0
- signal = weight * 0.5 * ( offset + TerrainBasisMode((x,y,z), basis, mode ) )
- result += amp * signal
- return result * 2.0
-
-##------------------------------------------------------------
-# Noise Functions:
-def Noise_Function(x,y,z):
- global Basis, NType, musgr, vlnoi, voron, turbOne, marbleOne, tBasismod
- global vlBasis, Distort, VFunc, VExp, VDep
- global iScale, Offset, Invert, NSize, Lx, Ly, Sx, Sy
-
- x,y,z = Trans((x,y,z),( NSize[0].val, Sx[0].val, Sy[0].val, 0 ),( Lx[0].val, Ly[0].val, 0 ) )
- basis = Basis[0].val
- if basis == 9: basis = 14
- vbasis = vlnoi[1].val
- if vbasis == 9: vbasis = 14
- if NType.val == 0: z = multiFractal(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, basis )
- elif NType.val == 1: z = ridgedMFractal(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, basis )
- elif NType.val == 2: z = hybridMFractal(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, basis )
- elif NType.val == 3: z = heteroTerrain(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, basis )*0.5
- elif NType.val == 4: z = fBm(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, basis )+0.5
- elif NType.val == 5: z = turbulence(( x,y,z ),turbOne[0].val, turbOne[1].val, basis, turbOne[2].val, turbOne[3].val )+0.5
- elif NType.val == 6: z = voronoi_turbulence((x,y,z),(voron[0].val,voron[1].val),(turbOne[0].val,turbOne[1].val,turbOne[2].val,turbOne[3].val) )*0.5+0.5
- elif NType.val == 7: z = vlNoise_turbulence((x,y,z),(vlnoi[0].val,vbasis), (turbOne[0].val,turbOne[1].val,turbOne[2].val,turbOne[3].val), basis )*0.5+0.5
- elif NType.val == 8: z = noise(( x,y,z ),basis )+0.5
- elif NType.val == 9: z = cellNoise(( x,y,z ))+0.5
- elif NType.val == 10: z = marbleNoise(( x,y,z), marbleOne[0].val, basis, marbleOne[2].val, marbleOne[3].val, marbleOne[4].val, marbleOne[5].val )
- elif NType.val == 11: z = lava_multiFractal(( x,y,z ), musgr[0].val, musgr[1].val, musgr[2].val, vlnoi[0].val, basis )
- elif NType.val == 12: z = slopey_noise(( x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, vlnoi[0].val, basis )+0.5
- elif NType.val == 13: z = double_multiFractal(( x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, (vbasis,basis) )
- elif NType.val == 14: z = distorted_heteroTerrain((x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, vlnoi[0].val, (vbasis,basis) )
- elif NType.val == 15: z = SlickRock(( x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, (vbasis,basis) )
- elif NType.val == 16: z = terra_turbulence(( x,y,z), turbOne[0].val, turbOne[1].val, basis, turbOne[2].val, turbOne[3].val )
- elif NType.val == 17: z = rocky_fBm(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, basis )
- elif NType.val == 18: z = StatsByAltTerrain( (x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val*0.5, basis, tBasismod.val )
- elif NType.val == 19: z = doubleTerrain( (x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[5].val, basis, tBasismod.val )
- elif NType.val == 20: z = Shattered_hTerrain((x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, vlnoi[0].val, basis )
- elif NType.val == 21: z = vlhTerrain((x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, basis, vbasis, vlnoi[0].val )
- else: z = 0.0
- return HeightScale( z, iScale[0].val , Offset[0].val, Invert[0].val )
-
-###----------------------------------------------------------------------
-##-----------------------------------
-# Filter functions:
-
-##-----------------------------------
-# Filter: Clamp height
-def Clamp_Max( height, max ):
- if ( height > max ): height = max
- return height
-def Clamp_Min( height, min ):
- if ( height < min ): height = min
- return height
-
-##-----------------------------------
-# Filters: terrace / posterise / peaked / bias:
-def Def_Filter((x,y,z), input, numb, type ):
- if type == 0:
- s = ( sin( input*numb*phi ) * ( 0.1/numb*phi ) )
- return ( input * (1.0-0.5) + s*0.5 ) * 2.0
- elif type == 1:
- s = -abs( sin( input*(numb*0.5)*phi ) * ( 0.1/(numb*0.5)*phi ) )
- return ( input * (1.0-0.5) + s*0.5 ) * 2.0
- elif type == 2:
- s = abs( sin( input*(numb*0.5)*phi ) * ( 0.1/(numb*0.5)*phi ) )
- return ( input * (1.0-0.5) + s*0.5 ) * 2.0
- elif type == 3:
- numb = numb*0.5
- s = ( int( input*numb ) * 1.0/numb )
- return ( input * (1.0-0.5) + s*0.5 ) * 2.0
- elif type == 4:
- numb = numb*0.5
- s = ( int( input*numb ) * 1.0/numb )
- return ( s ) * 2.0
- elif type == 5:
- s = ( sin( input*(2*numb)*phi ) * ( 0.1/(2*numb)*phi ) )
- l = ( input * (1.0-0.5) + s*0.5 ) * 2.0
- p = ( ( l*numb*0.25 ) * ( l*numb*0.25 ) )**2
- return ( l * (1.0-0.5) + p*0.5 ) * 2.0
- elif type == 6:
- return ( input*numb*0.25 )**4
- elif type == 7:
- return 2.0-exp( 1.0-(input*numb/3.0) )
- elif type == 8:
- return sin_bias( input*numb )*2.0
- elif type == 9:
- return cos_bias( input*numb )*2.0
- elif type == 10:
- return tri_bias( input*numb )*2.0
- elif type == 11:
- return saw_bias( input*numb )*2.0
- elif type == 12:
- return Clamp_Max( input, numb )
- else:
- return input
-
-##-----------------------------------
-# Filter: Edge falloff
-def EdgeFalloff( (x,y,z), height, type ):
- global Falloff, iScale, Offset
-
- x = x / Falloff[1].val
- y = y / Falloff[2].val
-
- if Falloff[3].val != 0:
- sealevel = (Min.val-Offset[2].val)*2.0/iScale[2].val
- else:
- sealevel = 0.0
-
- falltypes = ( 0, sqrt(x*x+y*y), sqrt((x*x)**2+(y*y)**2), sqrt((x*x)**10+(y*y)**10), sqrt(y*y), sqrt(x*x), abs(x-y), abs(x+y), ((x*x)**10+(y*y)**10)**0.1, ((x*x)+(y*y)) )
-
- dist = falltypes[ type ]
- if Falloff[4].val != 0:
- dist = 1.0 - dist
- radius = 1.0
- height = height - sealevel
- if( dist < radius ):
- dist = dist / radius
- dist = ( (dist) * (dist) * ( 3-2*(dist) ) )
- height = ( height - height * dist ) + sealevel
- else:
- height = sealevel
-
- if Falloff[3].val != 0:
- height = Clamp_Min( height, sealevel )
- else:
- height = Clamp_Min( height, Min.val )
-
- return height
-
-##-----------------------------------
-# Filter: Custom height filter:
-def CustomFilter( x,y,z, h ):
- global CustomFilt
- try:
- a = eval(CustomFilt[0].val)
- b = eval(CustomFilt[1].val)
- result = eval(CustomFilt[2].val)
- return result
- except:
- return 0.0
-
-#####-------------------------------------------------------------------------------------#####
-####-------------------------------------------------------------------------------------####
-### Combine Functions: (get noise, Add effect, filter height and return result) ###
-##-------------------------------------------------------------------------------------##
-
-def Combine_Functions( (i,j),(x,y,z) ):
- global Effect_Ctrl, Blend_Effect, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order
- global iScale, Offset, Invert, Min, Max, Falloff
-
- # get noise height:
- height = Noise_Function(x,y,0.0)
-
- ### Filter On
- if Filter_Mode.val !=0:
- ### 0= Default Filter Order: Noise>Effect>Filter ---------------------
- if Filter_Order.val ==0:
- # mix noise with effect:
- if Effect_Ctrl[0].val !=0:
- height = Mix_Modes( (i,j),(x,y,z), height , Effects( (i,j),(x,y,z),height ), Effect_Ctrl[2].val, Effect_Ctrl[1].val )
- # edge fallof:
- if Falloff[0].val !=0:
- height = EdgeFalloff( (x,y,z), height, Falloff[0].val )
- #else: pass
-
- if Filter_Mode.val !=0:
- # height Def_Filter (Terrace/peaked/bias):
- if Filter_Mode.val ==1:
- height = Def_Filter((x,y,z), height, Def_Filter_Ctrl[ 1 ].val, Def_Filter_Ctrl[ 0 ].val )
-
- ## 'IPOCurve' height filter:
- elif Filter_Mode.val ==2:
- try:
- height = selectedcurve.evaluate( 1 + ( height*Ipo_Filter_Ctrl[2].val/2 ) )*2.0/Ipo_Filter_Ctrl[3].val
- except:
- height = height
-
- ## Custom filter:
- elif Filter_Mode.val ==3:
- height = CustomFilter( x,y,z, height )
-
- ### 1= Changed Filter Order: Noise>Filter>Effect ---------------------
- if Filter_Order.val !=0:
- # mix noise with effect:
- if Effect_Ctrl[0].val !=0:
- height = Mix_Modes( (i,j),(x,y,z), height , Effects( (i,j),(x,y,z),height ), Effect_Ctrl[2].val, Effect_Ctrl[1].val )
- # edge fallof:
- if Falloff[0].val !=0:
- height = EdgeFalloff( (x,y,z), height, Falloff[0].val )
- #else: pass
-
- ### Filter Off ---------------------
- else:
- # mix noise with effect:
- if Effect_Ctrl[0].val !=0:
- height = Mix_Modes( (i,j),(x,y,z), height , Effects( (i,j),(x,y,z),height ), Effect_Ctrl[2].val, Effect_Ctrl[1].val )
- # edge fallof:
- if Falloff[0].val !=0:
- height = EdgeFalloff( (x,y,z), height, Falloff[0].val )
-
- # height scale:
- height = HeightScale( height, 0.5*iScale[2].val , Offset[2].val, Invert[2].val )
-
- # clamp height min. max.:
- if Falloff[0].val !=1:
- height = Clamp_Min( height, Min.val )
- height = Clamp_Max( height, Max.val )
-
- # return height:
- return height
-
-
-#------------------------------------------------------------
-##------------------------------------------------------------
-### Render Noise to a Image('NAME') (you must create one first)
-##------------------------------------------------------------
-#------------------------------------------------------------
-
-def HeightFieldImage():
- global PreView, previewname
-
- iname = previewname.val
- try:
- pic = Image.Get( iname )
- except:
- #print iname, ' No Image with this name'
- PupMenu( 'No Image with this name' )
- return
- res = pic.getMaxXY()
- for i in xrange( res[0] ):
- x = i - (res[0]) / 2.0
- x = (x*2.0) / (res[0])
- for j in xrange( res[1] ):
- y = j - (res[1]) / 2.0
- y = (y*2.0) / (res[1])
- height = PreView[2].val + PreView[1].val * Combine_Functions( (i,j),(x,y,0) )
- if height > 1.0: height = 1.0
- if height < 0.0: height = 0.0
- pic.setPixelF( i, j, ( height,height,height, 1.0 ) )
-
-
-#------------------------------------------------------------
-##------------------------------------------------------------
-### Mesh
-##------------------------------------------------------------
-#------------------------------------------------------------
-
-#------------------------------------------------------------
-## Mesh: make new grid
-###------------------------------------------------------------
-
-def MakeGridMesh( RESOL=32, NAME='GridMesh', CURSORPOS=0, SCENE=None ):
- # scene, object, mesh ---------------------------------------
- if not SCENE:
- SCENE = Blender.Scene.GetCurrent()
- SCENE.objects.selected=[]
- newme = Blender.Mesh.New( NAME )
- newob = SCENE.objects.new( newme, NAME )
- n = RESOL
- # verts ---------------------------------------
- v=[]
- for i in xrange( n ):
- x = i-(n-1)/2.0
- x = x*2.0/(n-1)
- for j in xrange( n ):
- y = j-(n-1)/2.0
- y = y*2.0/(n-1)
- v.append( [ x, y, 0 ] )
- newme.verts.extend(v)
- # faces ---------------------------------------
- f=[]
- for i in xrange( n-1 ):
- for j in xrange( n-1 ):
- f.append( [ i*n+j,\
- (i+1)*n+j,\
- (i+1)*n+j+1,\
- i*n+j+1 ] )
-
- newme.faces.extend(f, smooth=True)
- #---------------------------------------
- newme.calcNormals()
- #---------------------------------------
- if CURSORPOS !=0:
- newob.loc = Window.GetCursorPos()
- newob.select(1)
-
-#------------------------------------------------------------
-## Mesh: Grid vert displace / update terrain
-###------------------------------------------------------------
-
-def displace( OB, ME, WORLD=0 ):
- if WORLD == 1:
- wx,wy,wz = OB.getLocation( 'worldspace' )
- elif WORLD ==2:
- l = OB.getLocation( 'worldspace' )
- w = Window.GetCursorPos()
- wx,wy,wz = l[0]-w[0], l[1]-w[1], l[2]-w[2]
- else:
- wx,wy,wz = 0,0,0
-
- for v in ME.verts:
- co = v.co
- co[2] = Combine_Functions( (co[0]+wx,co[1]+wy),(co[0]+wx, co[1]+wy, 0.0+wz) )
- ME.update()
- ME.calcNormals()
- #OB.makeDisplayList()
-
-
-#----------------------------------------------------------------------------------------------------
-##----------------------------------------------------------------------------------------------------
-###----------------------------------------------------------------------------------------------------
-####----------------------------------------------------------------------------------------------------
-###----------------------------------------------------------------------------------------------------
-## Do_it:
-#--------------------------------------
-
-#--------------------------------------
-def do_it():
- global PreView, actme, actob, WorldSpaceCo
- if actme !=[]:
- if print_time !=0:
- t= sys.time()
- Window.WaitCursor(1)
- in_editmode = Window.EditMode()
- if in_editmode: Window.EditMode(0)
- if PreView[0].val != 0:
- do_it_preview()
- displace( actob[0], actme[0], WorldSpaceCo.val )
- Window.RedrawAll()
- else:
- displace( actob[0], actme[0], WorldSpaceCo.val )
- Window.RedrawAll()
- if in_editmode: Window.EditMode(1)
- Window.WaitCursor(0)
- if print_time !=0:
- print 'Generate Mesh: done in %.6f' % (sys.time()-t)
-
-#--------------------------------------
-def do_it_random():
- global PreView, actme, actob
- if actme !=[]:
- if print_time !=0:
- t= sys.time()
- Window.WaitCursor(1)
- in_editmode = Window.EditMode()
- if in_editmode: Window.EditMode(0)
- randomiseNoise()
- if PreView[0].val != 0:
- do_it_preview()
- displace( actob[0], actme[0], WorldSpaceCo.val )
- Window.RedrawAll()
- else:
- displace( actob[0], actme[0], WorldSpaceCo.val )
- Window.RedrawAll()
- if in_editmode: Window.EditMode(1)
- Window.WaitCursor(0)
- if print_time !=0:
- print 'Generate Mesh: done in %.6f' % (sys.time()-t)
-
-#--------------------------------------
-def do_it_preview():
- if print_time !=0:
- t= sys.time()
- HeightFieldImage()
- Window.RedrawAll()
- if print_time !=0:
- print 'Generate Image: done in %.6f' % (sys.time()-t)
-
-###---------------------------------------------------------
-###---------------------------------------------------------
-## load and save:
-#-------------------------
-
-def callback( filename ):
- txtFile.val = filename
- Register(drawgui, events, bevents)
-def writeln(f,x):
- f.write(str(x))
- f.write("\n")
-def readint(f):
- return int(f.readline())
-def readfloat(f):
- return float(f.readline())
-def readstr(f):
- s = (f.readline())
- return strip(s)
-
-#--------------------------------------------------
-# Save settings to .ant file
-def SavePreset(FName):
- global iScale, Offset, Invert, NSize, Sx, Sy, Lx, Ly
- global NType, Basis, musgr, tBasismod, vlnoi, vlnoiTwo, voron, turbOne, turbTwo, marbleOne, marbleTwo, musgrTwo
- global CustomFX, effect_image, Effect_Ctrl, Min, Max, Falloff, CustomFilt, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order
- global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I, filemessage, fileinfo
-
- try:
- f = open(FName,'w')
- writeln(f,CurVersion)
- except:
- filemessage = "Unable to save file."
- return
-
- writeln(f,fileinfo)
- writeln(f,iScale[0].val)
- writeln(f,iScale[1].val)
- writeln(f,iScale[2].val)
- writeln(f,Offset[0].val)
- writeln(f,Offset[1].val)
- writeln(f,Offset[2].val)
- writeln(f,Invert[0].val)
- writeln(f,Invert[1].val)
- writeln(f,Invert[2].val)
- writeln(f,NSize[0].val)
- writeln(f,NSize[1].val)
- writeln(f,Sx[0].val)
- writeln(f,Sx[1].val)
- writeln(f,Sy[0].val)
- writeln(f,Sy[1].val)
- writeln(f,Lx[0].val)
- writeln(f,Lx[1].val)
- writeln(f,Ly[0].val)
- writeln(f,Ly[1].val)
- writeln(f,NType.val)
- writeln(f,Basis[0].val)
- writeln(f,Basis[1].val)
- writeln(f,musgr[0].val)
- writeln(f,musgr[1].val)
- writeln(f,musgr[2].val)
- writeln(f,musgr[3].val)
- writeln(f,musgr[4].val)
- writeln(f,musgr[5].val)
- writeln(f,tBasismod.val)
- writeln(f,vlnoi[0].val)
- writeln(f,vlnoi[1].val)
- writeln(f,vlnoiTwo[0].val)
- writeln(f,vlnoiTwo[1].val)
- writeln(f,voron[0].val)
- writeln(f,voron[1].val)
- writeln(f,turbOne[0].val)
- writeln(f,turbOne[1].val)
- writeln(f,turbOne[2].val)
- writeln(f,turbOne[3].val)
- writeln(f,turbTwo[0].val)
- writeln(f,turbTwo[1].val)
- writeln(f,turbTwo[2].val)
- writeln(f,turbTwo[3].val)
- writeln(f,marbleOne[0].val)
- writeln(f,marbleOne[1].val)
- writeln(f,marbleOne[2].val)
- writeln(f,marbleOne[3].val)
- writeln(f,marbleOne[4].val)
- writeln(f,marbleOne[5].val)
- writeln(f,marbleTwo[0].val)
- writeln(f,marbleTwo[1].val)
- writeln(f,marbleTwo[2].val)
- writeln(f,marbleTwo[3].val)
- writeln(f,marbleTwo[4].val)
- writeln(f,marbleTwo[5].val)
- writeln(f,musgrTwo[0].val)
- writeln(f,musgrTwo[1].val)
- writeln(f,musgrTwo[2].val)
- writeln(f,musgrTwo[3].val)
- writeln(f,musgrTwo[4].val)
- writeln(f,effect_image)
- writeln(f,Effect_Ctrl[0].val)
- writeln(f,Effect_Ctrl[1].val)
- writeln(f,Effect_Ctrl[2].val)
- writeln(f,Effect_Ctrl[3].val)
- writeln(f,Effect_Ctrl[4].val)
- writeln(f,Effect_Ctrl[5].val)
- writeln(f,Effect_Ctrl[6].val)
- writeln(f,Effect_Ctrl[7].val)
- writeln(f,Effect_Ctrl[8].val)
- writeln(f,CustomFX[0].val)
- writeln(f,CustomFX[1].val)
- writeln(f,CustomFX[2].val)
- writeln(f,Min.val)
- writeln(f,Max.val)
- writeln(f,Falloff[0].val)
- writeln(f,Falloff[1].val)
- writeln(f,Falloff[2].val)
- writeln(f,Falloff[3].val)
- writeln(f,Falloff[4].val)
- writeln(f,Filter_Mode.val)
- writeln(f,Filter_Order.val)
- writeln(f,CustomFilt[0].val)
- writeln(f,CustomFilt[1].val)
- writeln(f,CustomFilt[2].val)
- writeln(f,Def_Filter_Ctrl[0].val)
- writeln(f,Def_Filter_Ctrl[1].val)
- writeln(f,Ipo_Filter_Ctrl[0].val)
- writeln(f,Ipo_Filter_Ctrl[1].val)
- writeln(f,Ipo_Filter_Ctrl[2].val)
- writeln(f,Ipo_Filter_Ctrl[3].val)
- writeln(f,RandMod.val)
- writeln(f,RSeed.val)
- writeln(f,rand_H.val)
- writeln(f,rand_I.val)
- writeln(f,rand_S.val)
- writeln(f,rand_L.val)
- filemessage = 'Settings saved to file.'
- f.close()
-
-#--------------------------------------------------
-# load settings from .ant file
-def LoadPreset(FName):
- global iScale, Offset, Invert, NSize, Sx, Sy, Lx, Ly
- global NType, Basis, musgr, tBasismod, vlnoi, vlnoiTwo, voron, turbOne, turbTwo, marbleOne, marbleTwo, musgrTwo
- global CustomFX, effect_image, Effect_Ctrl, Min, Max, Falloff, CustomFilt, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order
- global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I, filemessage, fileinfo
-
- try:
- f = open(FName,'r')
- FVersion = readstr(f)
- except:
- filemessage = "Unable to open file."
- return
-
- fileinfo = readstr(f)
- iScale[0].val = readfloat(f)
- iScale[1].val = readfloat(f)
- iScale[2].val = readfloat(f)
- Offset[0].val = readfloat(f)
- Offset[1].val = readfloat(f)
- Offset[2].val = readfloat(f)
- Invert[0].val = readint(f)
- Invert[1].val = readint(f)
- Invert[2].val = readint(f)
- NSize[0].val = readfloat(f)
- NSize[1].val = readfloat(f)
- Sx[0].val = readfloat(f)
- Sx[1].val = readfloat(f)
- Sy[0].val = readfloat(f)
- Sy[1].val = readfloat(f)
- Lx[0].val = readfloat(f)
- Lx[1].val = readfloat(f)
- Ly[0].val = readfloat(f)
- Ly[1].val = readfloat(f)
- NType.val = readint(f)
- Basis[0].val = readint(f)
- Basis[1].val = readint(f)
- musgr[0].val = readfloat(f)
- musgr[1].val = readfloat(f)
- musgr[2].val = readint(f)
- musgr[3].val = readfloat(f)
- musgr[4].val = readfloat(f)
- musgr[5].val = readfloat(f)
- tBasismod.val = readint(f)
- vlnoi[0].val = readfloat(f)
- vlnoi[1].val = readint(f)
- vlnoiTwo[0].val = readfloat(f)
- vlnoiTwo[1].val = readint(f)
- voron[0].val = readint(f)
- voron[1].val = readfloat(f)
- turbOne[0].val = readint(f)
- turbOne[1].val = readint(f)
- turbOne[2].val = readfloat(f)
- turbOne[3].val = readfloat(f)
- turbTwo[0].val = readint(f)
- turbTwo[1].val = readint(f)
- turbTwo[2].val = readfloat(f)
- turbTwo[3].val = readfloat(f)
- marbleOne[0].val = readint(f)
- marbleOne[1].val = readint(f)
- marbleOne[2].val = readfloat(f)
- marbleOne[3].val = readint(f)
- marbleOne[4].val = readint(f)
- marbleOne[5].val = readfloat(f)
- marbleTwo[0].val = readint(f)
- marbleTwo[1].val = readint(f)
- marbleTwo[2].val = readfloat(f)
- marbleTwo[3].val = readint(f)
- marbleTwo[4].val = readint(f)
- marbleTwo[5].val = readfloat(f)
- musgrTwo[0].val = readfloat(f)
- musgrTwo[1].val = readfloat(f)
- musgrTwo[2].val = readint(f)
- musgrTwo[3].val = readfloat(f)
- musgrTwo[4].val = readfloat(f)
- effect_image = readstr(f)
- Effect_Ctrl[0].val = readint(f)
- Effect_Ctrl[1].val = readint(f)
- Effect_Ctrl[2].val = readfloat(f)
- Effect_Ctrl[3].val = readint(f)
- Effect_Ctrl[4].val = readfloat(f)
- Effect_Ctrl[5].val = readint(f)
- Effect_Ctrl[6].val = readfloat(f)
- Effect_Ctrl[7].val = readfloat(f)
- Effect_Ctrl[8].val = readfloat(f)
- CustomFX[0].val = readstr(f)
- CustomFX[1].val = readstr(f)
- CustomFX[2].val = readstr(f)
- Min.val = readfloat(f)
- Max.val = readfloat(f)
- Falloff[0].val = readint(f)
- Falloff[1].val = readfloat(f)
- Falloff[2].val = readfloat(f)
- Falloff[3].val = readint(f)
- Falloff[4].val = readint(f)
- Filter_Mode.val = readint(f)
- Filter_Order.val = readint(f)
- CustomFilt[0].val = readstr(f)
- CustomFilt[1].val = readstr(f)
- CustomFilt[2].val = readstr(f)
- Def_Filter_Ctrl[0].val = readint(f)
- Def_Filter_Ctrl[1].val = readfloat(f)
- Ipo_Filter_Ctrl[0].val = readstr(f)
- Ipo_Filter_Ctrl[1].val = readint(f)
- Ipo_Filter_Ctrl[2].val = readfloat(f)
- Ipo_Filter_Ctrl[3].val = readfloat(f)
- RandMod.val = readint(f)
- RSeed.val = readint(f)
- rand_H.val = readint(f)
- rand_I.val = readint(f)
- rand_S.val = readint(f)
- rand_L.val = readint(f)
- filemessage = 'Settings loaded from file.'
- f.close()
-
-##---------------------------------------------------------------------------
-# Register:
-
-Register( drawgui, events, bevents )
-###--------------------------------------------------------------------------
- \ No newline at end of file
diff --git a/release/scripts/xsi_export.py b/release/scripts/xsi_export.py
deleted file mode 100644
index d86d8cb82cf..00000000000
--- a/release/scripts/xsi_export.py
+++ /dev/null
@@ -1,1227 +0,0 @@
-#!BPY
-
-
-"""
-Name: 'SoftImage XSI (.xsi)...'
-Blender: 236
-Group: 'Export'
-Tooltip: 'Export to a SoftImage XSI file'
-"""
-
-__author__ = ("Elira")
-__url__ = ["Author's site, http://www.creative-realms.net/~elira/blender.html",
-"SoftImage's site, www.softimage.com", "blenderartists.org"]
-__email__ = ["scripts"]
-__version__ = "2005/11/01"
-
-
-__bpydoc__ = """\
-This script exports to the XSI format.
-
-Usage:
-
-Run this script from "File->Export" menu.
-
-Note:<br>
-- Updates by Mal Duffin, to assist with XSI to Shockwave 3D conversion.
-"""
-
-# $Id: xsi_export.py,v 1.4.6 2005/11/01
-#
-#------------------------------------------------------------------------
-# XSI exporter for blender 2.36 or above
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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 *****
-#
-
-
-#
-# ---------------------------------------------------------------------------
-# XSI Export V 1.4.1 by Elira (at) creative-realms (dot) net
-#
-# Updates by Mal Duffin, to assist with XSI to Shockwave 3D conversion
-# ---------------------------------------------------------------------------
-# 0.0.0 - This header and having blender ID the file.
-# 0.1.0 - Output the statis xsi header elements
-# 0.2.0 - create a full shell output (no content just structure)
-# 0.3.0 - output used materials from the full materials list
-# 0.4.0 - output the object model minor data
-# 0.5.0 - output the object shape data, storing a uv table
-# 0.6.0 - output the triangle lists (uv references stored uv table)
-# 0.7.0 - convert output to genuine file writes.
-# 1.0.0 - Admit this script exists and wait for flames
-# 1.1.0 - Correctly export mesh shapes
-# 1.2.0 - Mesh positioning corrected, added back normals
-# 1.3.0 - conditionally output uv co-ordinates
-# 1.4.0 - export vertex paint colours.
-# ---------------------------------------------------------------------------
-# 1.4.1 - added basic normal export code,
-# to get XSI to Shockwave 3D converter working ( Mal Duffin )
-# 1.4.2 - invalid mesh checking
-# better normal exporting
-# general code clean up
-# 1.4.3 - basic light exporting
-# fix for ambient light being ignored by Shockwave 3D converter
-# 1.4.4 - basic camera exporting
-# 1.4.5 - exports normals correctly
-# 1.4.6 - exports multiple materials per object
-# ---------------------------------------------------------------------------
-# TO DO
-# - Support texturing
-# - for both methods of texturing ( render method, and Game Engine method )
-# ---------------------------------------------------------------------------
-# add required modules
-
-import Blender
-from Blender import sys as bsys
-from Blender import Mathutils
-from Blender import Lamp
-from Blender import Camera
-import math
-
-
-
-# ---------------------------------------------------------------------------
-# globals to make things a lot lot easier
-OBJ = [] # the object list
-MAT = [] # the materials list
-UVC = [] # uv vert co-ords
-UVI = [] # uv vert index
-VCC = [] # vert colour co-ords
-VCI = [] # vert colour index
-FD = [] # file handle
-NORMALS = [] # normal list
-mats = []
-EXPORT_DIR = ''
-WORLD = Blender.World.GetCurrent()
-
-# ---------------------------------------------------------------------------
-# get_path returns the path portion o/wf the supplied filename.
-# ---------------------------------------------------------------------------
-def get_path(file):
- l=len(file)
- r=0
- for i in range(l, 0, -1):
- if r == 0:
- if file[i-1] == "/" or file[i-1] == "\\":
- r = i
- return file[:r]
-
-
-
-# ---------------------------------------------------------------------------
-# r2d - radians to degrees
-# ---------------------------------------------------------------------------
-def r2d(r):
- return round(r*180.0/math.pi,4)
-
-
-
-# ---------------------------------------------------------------------------
-# d2r - degrees to radians
-# ---------------------------------------------------------------------------
-def d2r(d):
- return (d*math.pi)/180.0
-
-
-
-# ---------------------------------------------------------------------------
-# get_filename returns the filename
-# ---------------------------------------------------------------------------
-def get_filename(file):
- l=len(file)
- r=0
- for i in range(l, 0, -1):
- if r == 0:
- if file[i-1] == "/" or file[i-1] == "\\":
- r = i
- return file[r:]
-
-
-# ---------------------------------------------------------------------------
-# find materials returns all materials on an object.
-# ---------------------------------------------------------------------------
-def get_materials(obj):
-
- # any materials attached to the object itself
- mats = obj.getMaterials(0)
-
- if 'Mesh' != obj.type:
- return mats
-
- # now drop down to the mesh level
- #mesh = Blender.NMesh.GetRaw(obj.data.name)
-
- mats.extend(obj.getData(mesh=1).materials)
-
- # return the materials list
-
- # Is this correct!!?? - None materials raise an error otherwise
- # but it might screw up the indicies.. TODO... check the exported files.
- return [m for m in mats if m]
-
-# ---------------------------------------------------------------------------
-# do_header writes out the header data
-# ---------------------------------------------------------------------------
-def do_header():
-
- global FD
-
- # this says which xsi version
- FD.write("xsi 0300txt 0032\n\n")
-
- # static fileinfo block
- FD.write("SI_FileInfo {\n")
- FD.write(" \"Blender Scene\",\n")
- FD.write(" \"Blender User\",\n")
- FD.write(" \"Now\",\n")
- FD.write(" \"xsi_export Blender Scene Exporter\",\n")
- FD.write("}\n\n")
-
- # static scene block
- FD.write("SI_Scene no_name {\n")
- FD.write(" \"FRAMES\",\n")
- FD.write(" 0.000000,\n")
- FD.write(" 100.000000,\n")
- FD.write(" 30.000000,\n")
- FD.write("}\n\n")
-
- # static co-ordinate system block
- FD.write("SI_CoordinateSystem coord {\n")
- FD.write(" 1,\n")
- FD.write(" 0,\n")
- FD.write(" 1,\n")
- FD.write(" 0,\n")
- FD.write(" 5,\n")
- FD.write(" 2,\n")
- FD.write("}\n\n")
-
- # static angle block
- FD.write("SI_Angle {\n")
- FD.write(" 0,\n")
- FD.write("}\n\n")
-
- # static ambience block
- if WORLD: ambient = WORLD.getAmb()
- else: ambient = 0,0,0
-
- FD.write("SI_Ambience {\n")
- FD.write(" %f,\n" % ambient[0])
- FD.write(" %f,\n" % ambient[1])
- FD.write(" %f,\n" % ambient[2])
- FD.write("}\n\n")
-
-
-
-# ---------------------------------------------------------------------------
-# do_materiallibrary writes out the materials subsection.
-# ---------------------------------------------------------------------------
-def do_materiallibrary():
-
- global OBJ, MAT, FD
-
- # set some flags first
- mnum = 0
-
- # run through every material, how many used?
- for mat in MAT:
- nmat = mat.name
-
- # first, is this material on any of the objects.
- f = 0
- for obj in OBJ:
- ml = get_materials(obj)
- for mli in ml:
- nmli = mli.name
- if nmli == nmat:
- f = 1
- mnum += 1
- break
- if f == 1:
- break
-
- bCreateDefault = 0
- # if none then exit
- if not mnum:
- bCreateDefault = 1
-# return
-
- # get to work create the materiallibrary wrapper and fill.
- FD.write("SI_MaterialLibrary {\n")
- FD.write(" " + str(mnum) + ",\n")
-
- # run through every material, write the used ones
- for mat in MAT:
- nmat = mat.name
-
- # find out if on any object, if so we write.
- f = 0
- for obj in OBJ:
- ml = get_materials(obj)
- for mli in ml:
- nmli = mli.name
- if nmli == nmat:
- do_material(mat)
- f = 1
- break
- if f == 1:
- break
-
- if bCreateDefault == 1:
- do_material ( 0 )
-
- # clean up
- FD.write("}\n\n")
-
-
-def removeSpacesFromName(name):
- name = name.replace ( " ", "_" )
- return name
-
-
-# ---------------------------------------------------------------------------
-# do_material writes out this material.
-# ---------------------------------------------------------------------------
-def do_material(mat):
-
- global FD
-
- if mat == 0:
- name = "__default"
- cr = 1.0
- cg = 1.0
- cb = 1.0
- ca = 1.0
- sp = 0.0
- sr = 0.0
- sg = 0.0
- sb = 0.0
- em = 0.0
- am = 1.0
- sm = 0
- else:
-
-
- # get the name first
- name = mat.name
-
- # face colour r, g, b, a
- # power (spec decay) fl
- # spec colour r, g, b
- # emmisive colourm r, g, b
- # shading model int constant, lambert, phong, blinn, shadow, vertex
- # ambient colour r, g, b
-
- # get and print the base material block
- cr, cg, cb = mat.getRGBCol()
- ca = mat.getAlpha()
-
- sp = 0.0
- sr, sg, sb = mat.getSpecCol()
- em = mat.getEmit()
- am = mat.getAmb()
-
- # how do we render this material? start with constant (0)
- sm = 0
- fl = mat.getMode()
- if fl & Blender.Material.Modes['VCOL_PAINT']:
- sm = 5
-
-
- FD.write(" SI_Material " + removeSpacesFromName(name) + " {\n")
- FD.write(" %f,\n" % cr)
- FD.write(" %f,\n" % cg)
- FD.write(" %f,\n" % cb)
- FD.write(" %f,\n" % ca)
- FD.write(" %f,\n" % sp)
- FD.write(" %f,\n" % sr)
- FD.write(" %f,\n" % sg)
- FD.write(" %f,\n" % sb)
- FD.write(" %f,\n" % em)
- FD.write(" %f,\n" % em)
- FD.write(" %f,\n" % em)
- FD.write(" %d,\n" % sm)
- #FD.write(" %f,\n" % am)
- #FD.write(" %f,\n" % am)
- #FD.write(" %f,\n" % am)
- FD.write(" %f,\n" % cr)
- FD.write(" %f,\n" % cg)
- FD.write(" %f,\n" % cb)
-
- if mat != 0:
- # if this material has a texture, then add here
- mtex = mat.getTextures()
- for mt in mtex:
- if mt:
- do_texture(mt)
-
- FD.write(" }\n")
-
-
-
-# ---------------------------------------------------------------------------
-# do_texture writes out this texture if usable.
-# ---------------------------------------------------------------------------
-def do_texture(mtex):
- global FD
-
-
- # get our texture
- tex = mtex.tex
- tn = tex.name
-
-
- # what type of texture, we are limitd
- if tex.type != Blender.Texture.Types.IMAGE:
- return
-
-
- FD.write(" SI_Texture2D " + tn + " {\n")
-
- img = tex.getImage()
- iname = get_filename(img.getFilename())
-
- FD.write(" \"" + iname + "\",\n")
-
- # mapping type ? uv map wrapped is 4, how to detect?
- # start with a simple xy mapping ie 0
- FD.write(" 4,\n")
-
- if img.has_data: ix, iy = img.getSize()
- else: ix, iy = 512,512
-
- # image width, and height
- FD.write(" %d,\n" % ix)
- FD.write(" %d,\n" % iy)
- # u crop min/max, v crop min/max
- mincu, mincv, maxcu, maxcv = tex.crop
- FD.write(" %d,\n" % ( mincu * ix ) )
- FD.write(" %d,\n" % ( maxcu * ix - 1 ) )
- FD.write(" %d,\n" % ( mincv * iy ) )
- FD.write(" %d,\n" % ( maxcv * iy - 1) )
- # uv swap
- uvs =0
- if (tex.flags & Blender.Texture.Flags.FLIPBLEND):
- uvs = 1
- FD.write(" %d,\n" % uvs )
- # u/v repeat
- if img.has_data: iru = img.getXRep()
- else: iru = 1
- FD.write(" %d,\n" % iru )
- if img.has_data: irv = img.getYRep()
- else: irv = 1
-
- FD.write(" %d,\n" % irv )
- # u/v alt - 0, 0
- FD.write(" 0,\n" )
- FD.write(" 0,\n" )
- # u/v scale - 1,1
- FD.write(" 1.000000,\n" )
- FD.write(" 1.000000,\n" )
- # u/v offset - 0,0
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
- # proj mat 4x4 1 0 0 0, 0 1 0 0, 0 0 1 0, 0 0 0 1 is default
- FD.write(" 1.000000,\n" )
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
-
- FD.write(" 0.000000,\n" )
- FD.write(" 1.000000,\n" )
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
-
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
- FD.write(" 1.000000,\n" )
- FD.write(" 0.000000,\n" )
-
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
- FD.write(" 0.000000,\n" )
- FD.write(" 1.000000,\n" )
-
- # blending type - 3
- FD.write(" 3,\n" )
- # blending - 1
- FD.write(" 1.000000,\n" )
- # ambient - 0
- FD.write(" 0.000000,\n" )
- # diffuse - 1
- FD.write(" 1.000000,\n" )
- # speculara - 0
- FD.write(" 0.000000,\n" )
- # transparent - 0
- FD.write(" 0.000000,\n" )
- # reflective - 0
- FD.write(" 0.000000,\n" )
- # roughness - 0
- FD.write(" 0.000000,\n" )
-
- # close off this texture
- FD.write(" }\n")
-
-
-
-# ---------------------------------------------------------------------------
-# do_model_transform dumps out the transform data
-# ---------------------------------------------------------------------------
-def do_model_transform(obj):
-
- global FD
-
- # now output
- FD.write(" SI_Transform SRT-" + removeSpacesFromName( obj.name ) + " {\n" )
-
-
-
- # write out the object size? (scaling)
- FD.write(" %f,\n" % obj.SizeX )
- FD.write(" %f,\n" % obj.SizeY )
- FD.write(" %f,\n" % obj.SizeZ )
-
- # write out the object rotation
- FD.write(" %f,\n" % r2d(obj.RotX) )
- FD.write(" %f,\n" % r2d(obj.RotY) )
- FD.write(" %f,\n" % r2d(obj.RotZ) )
-
- # this is the position of the object's axis
- FD.write(" %f,\n" % obj.LocX )
- FD.write(" %f,\n" % obj.LocY )
- FD.write(" %f,\n" % obj.LocZ )
- FD.write(" }\n\n")
-
-
-
-# ---------------------------------------------------------------------------
-# do_model_visibility marks if the model is visible or not???
-# ---------------------------------------------------------------------------
-def do_model_visibility(obj):
-
- global FD
-
- # for now this is a static block
- FD.write(" SI_Visibility {\n" )
- FD.write(" 1,\n" )
- FD.write(" }\n\n" )
-
-
-
-# ---------------------------------------------------------------------------
-# do_model_material sets the global material for the model
-# ---------------------------------------------------------------------------
-def do_model_material(obj):
-
- global FD
-
- # do we have one?
- ml = get_materials(obj)
-
-
- n = 0
- for mli in ml:
- if mli:
- n+=1
- if n == 1:
- mat=mli
-
-
- # if no materials just go back
- if n == 0:
- return
-
- # for now we grab the first material on the list.
-
- for mat in ml:
- FD.write(" SI_GlobalMaterial {\n" )
- FD.write(" \"" + removeSpacesFromName(mat.name) + "\",\n" )
- FD.write(" \"NODE\",\n" )
- FD.write(" }\n\n" )
-
-
-# ---------------------------------------------------------------------------
-# do_collect_uv, makes an easy to use list out of the uv data
-# todo, remove duplicates and compress the list size, xsi supports this.
-# ---------------------------------------------------------------------------
-def do_collect_uv(mesh):
-
- global UVC, UVI
-
- # reset the uv details first.
- UVI = []
- UVC = []
-
- #print "Textures..."
- #mtex = mat.getTextures()
- #for mt in mtex:
- # print mt
-
-
- # if no uv data then return
- if not mesh.hasFaceUV():
- return
-
- # run through all the faces
- j = 0
- for f in mesh.faces:
- for uv in f.uv:
- UVI.append(j)
- UVC.append(uv)
- j+=1
- UVI.append(-1)
-
-
-
-# ---------------------------------------------------------------------------
-# do_collect_colour, makes an easy to use list out of the colour data
-# todo, remove duplicates and compress the list size, xsi supports this.
-# ---------------------------------------------------------------------------
-def do_collect_colour(mesh):
-
- global VCC, VCI
-
- # reset the uv details first.
- VCC = []
- VCI = []
-
- # if no uv data then return
- if not mesh.hasVertexColours():
- return
-
- # run through all the faces
- j = 0
- for f in mesh.faces:
- for c in f.col:
- VCI.append(j)
- VCC.append(c)
- j+=1
- VCI.append(-1)
-
-
-
-# ---------------------------------------------------------------------------
-# do_mesh_shape outputs the shape data
-# ---------------------------------------------------------------------------
-def do_mesh_shape(obj):
-
- global UVC, UVI, VCC, VCI, FD, NORMALS
-
- # Grab the mesh itself
- mesh = obj.data
-
- # get the world matrix
- matrix = obj.getMatrix('worldspace')
-
- # we need to decide about vertex and uv details first.
- do_collect_uv(mesh)
- do_collect_colour(mesh)
-
- # output the shell
- elements=2
- if len(UVC):
- elements+=1
- if len(VCC):
- elements+=1
- FD.write(" SI_Shape SHP-" + removeSpacesFromName ( obj.name ) + "-ORG {\n" )
- FD.write(" %d,\n" % elements )
- FD.write(" \"ORDERED\",\n\n" )
-
- # vertices first
- FD.write(" %d,\n" % len(mesh.verts) )
- FD.write(" \"POSITION\",\n" )
- for v in mesh.verts:
- FD.write(" %f,%f,%f,\n" % (v.co[0], v.co[1], v.co[2]) )
- FD.write("\n")
-
-
- print " MESH NAME = " + mesh.name
-
- NORMALS = []
- for f in mesh.faces:
- NORMALS.append ( f.no )
- for v in mesh.verts:
- aTemp = [v.no[0], v.no[1], v.no[2]]
- NORMALS.append ( aTemp )
-
-
- FD.write(" %d,\n" % len(NORMALS) )
- FD.write(" \"NORMAL\",\n" )
-
- for n in NORMALS:
- FD.write(" %f,%f,%f,\n" % ( n[0], n[1], n[2] ) )
-
- # if vertex colour data then process
- if mesh.hasVertexColours():
-
- # put out the co-ord header
- FD.write(" %d,\n" % len(VCC) )
- FD.write(" \"COLOR\",\n" )
-
- # now output them
- for vc in VCC:
- FD.write(" %f,%f,%f,%f,\n" % (vc.r/255.0, vc.g/255.0, vc.b/255.0, vc.a/255.0) )
-
-
-
- # if uv data then process
- if mesh.hasFaceUV():
- # put out the co-ord header
- FD.write(" %d,\n" % len(UVC) )
- FD.write(" \"TEX_COORD_UV\",\n" )
-
- # now output them
- for uv in UVC:
- FD.write(" %f,%f\n" % (uv[0], uv[1]) )
-
- # close off
- FD.write(" }\n" )
-
-
-
-# ---------------------------------------------------------------------------
-# do_mesh_faces outputs the faces data
-# ---------------------------------------------------------------------------
-def do_mesh_faces(obj):
-
- global FD, UVI, VCI, mats
-
- # do we have a texture?
- ml = get_materials(obj)
- n = 0
- for mli in ml:
- if mli:
- n+=1
- if n == 1:
- mat=mli
-
- # Grab the mesh itself
- # mesh = Blender.NMesh.GetRaw(obj.data.name)
-
- # mesh = Blender.NMesh.GetRawFromObject(obj.name)
-
- mesh = obj.data
-
-
-
- tris = []
- normalX = []
- mats = []
- for f in mesh.faces:
- tris.extend ( triangulate_face(f) )
- aVal = triangulate_normals(mesh,f)
-
- for v in aVal:
- normalX.append ( v )
-
-
- triangles = len(tris)
-
- if n == 0:
- FD.write(" SI_TriangleList " + removeSpacesFromName(obj.name) + " {\n")
- FD.write(" %d,\n" % triangles)
-
- ostring=" \"NORMAL"
- if len(VCI):
- ostring += "|COLOR"
- if len(UVC):
- ostring += "|TEX_COORD_UV"
- ostring += "\",\n"
- FD.write(ostring)
-
- FD.write(" \"\",\n\n")
-
- for t in tris:
- FD.write(" %d,%d,%d,\n" % (t[0], t[2], t[1]))
-
- FD.write("\n")
-
- for n in normalX:
- FD.write(" %d,%d,%d,\n" % ( n[0], n[1], n[2] ) )
-
- # finally close this triangle list off
- FD.write(" }\n\n")
-
-
-
- print "total materials"
- print ml
-
- for mIndex in range (0,len(ml)):
- mat = ml[mIndex]
- print "checking materials"
- print mat
-
- aTriCount = 0
- for tIndex in range ( 0, len ( tris ) ):
- aMat = mats[tIndex]
- if aMat == mIndex:
- aTriCount = aTriCount + 1
-
- #
- # output the shell
- FD.write(" SI_TriangleList " + removeSpacesFromName(obj.name) + " {\n")
- # FD.write(" %d,\n" % triangles)
- FD.write(" %d,\n" % aTriCount)
-
- ostring=" \"NORMAL"
- if len(VCI):
- ostring += "|COLOR"
- if len(UVC):
- ostring += "|TEX_COORD_UV"
- ostring += "\",\n"
- FD.write(ostring)
-
-
- FD.write(" \"" + removeSpacesFromName ( mat.name ) + "\",\n\n")
-
-# FD.write(" \"\",\n\n")
-
-
- for tIndex in range ( 0, len ( tris ) ):
- aMat = mats[tIndex]
- if mIndex == aMat:
- t = tris[tIndex]
- FD.write(" %d,%d,%d,\n" % (t[0], t[2], t[1]))
-
- FD.write("\n")
-
-
-
-# for n in normalX:
- for tIndex in range ( 0, len ( tris ) ):
- aMat = mats[tIndex]
- if mIndex == aMat:
- n = normalX[tIndex]
- FD.write(" %d,%d,%d,\n" % ( n[0], n[1], n[2] ) )
-
-
-
- # if we have it, put out the colour vertex list
- # ostring = " "
- # for i in range(len(VCI)):
- # if a -1 its end of line, write.
- # if VCI[i] == -1:
- # ostring = ostring + "\n"
- # FD.write(ostring)
- # ostring=" "
- # else:
- # ostring = ostring + "%d," % VCI[i]
-
- # The final set is to work out the uv list, its one set per face
- # ostring = " "
- # for i in range(len(UVI)):
- # # if a -1 its end of line, write.
- # if UVI[i] == -1:
- # ostring = ostring + "\n"
- # FD.write(ostring)
- # ostring=" "
- # else:
- # ostring = ostring + "%d," % UVI[i]
-
- # finally close this triangle list off
- FD.write(" }\n\n")
-
-
-def getNormalInfo(mesh, faceInfo):
- global NORMALS
- aNL = []
- for fi in faceInfo:
- aN = []
-
- aFace = mesh.faces[fi[0]]
-
- print aFace
-
- if (aFace.smooth):
- aN.append ( NORMALS.index ( aFace.v.no[0] ) )
- aN.append ( NORMALS.index ( aFace.v.no[1] ) )
- aN.append ( NORMALS.index ( aFace.v.no[2] ) )
- else:
- aN.append ( NORMALS.index ( aFace.no ) )
- aN.append ( NORMALS.index ( aFace.no ) )
- aN.append ( NORMALS.index ( aFace.no ) )
-
-# aN.append ( NORMALS.index ( mesh.faces[fi[0]].no ) )
-# aN.append ( NORMALS.index ( mesh.faces[fi[0]].no ) )
-# aN.append ( NORMALS.index ( mesh.faces[fi[0]].no ) )
-
- aNL.append ( aN )
- return aNL
-
-
-
-# copy of code to triangulate mesh
-##################################
-def triangulate_face(f):
- if len(f.v) <= 3:
- #newFaces = [ [f.v[0].index, f.v[1].index, f.v[2].index] ]
- newFaces = [ [f.v[0].index, f.v[2].index, f.v[1].index] ]
- mats.append ( f.materialIndex )
- else:
- #newFaces = [ [f.v[0].index, f.v[1].index, f.v[2].index] ]
- #newFaces.append ( [f.v[3].index, f.v[0].index, f.v[2].index] )
- newFaces = [ [f.v[0].index, f.v[2].index, f.v[1].index] ]
- newFaces.append ( [f.v[3].index, f.v[2].index, f.v[0].index] )
- mats.append ( f.materialIndex )
- mats.append ( f.materialIndex )
-
- return newFaces
-
-# copy of code to triangulate mesh
-##################################
-def triangulate_normals(mesh, f):
-
- if len(f.v) <= 3:
- if f.smooth:
- n1 = get_normal_index ( mesh, [f.v[0].no[0], f.v[0].no[1], f.v[0].no[2]] )
- n2 = get_normal_index ( mesh, [f.v[1].no[0], f.v[1].no[1], f.v[1].no[2]] )
- n3 = get_normal_index ( mesh, [f.v[2].no[0], f.v[2].no[1], f.v[2].no[2]] )
- newNormals = [[ n1, n2, n3 ]]
- else:
- n1 = get_normal_index ( mesh, [f.no[0], f.no[1], f.no[2]] )
- newNormals = [[ n1, n1, n1 ]]
- else:
- if f.smooth:
- n1 = get_normal_index ( mesh, [f.v[0].no[0], f.v[0].no[1], f.v[0].no[2]] )
- n2 = get_normal_index ( mesh, [f.v[1].no[0], f.v[1].no[1], f.v[1].no[2]] )
- n3 = get_normal_index ( mesh, [f.v[2].no[0], f.v[2].no[1], f.v[2].no[2]] )
- n4 = get_normal_index ( mesh, [f.v[3].no[0], f.v[3].no[1], f.v[3].no[2]] )
- newNormals = [ [ n1, n2, n3 ] ]
- newNormals.append ( [ n4, n1, n3 ] )
-
-# newNormals = [[ n1, n3, n2 ]]
-# newNormals.append ( [ n4, n3, n1 ] )
- else:
- n1 = get_normal_index ( mesh, [f.no[0], f.no[1], f.no[2]] )
- newNormals = [[ n1, n1, n1 ]]
- newNormals.append ( [ n1, n1, n1 ] )
-
- return newNormals
-
-
-
-##################################
-def get_normal_index(mesh,normal):
- global NORMALS
-
- indx=NORMALS.index(normal)
- return indx
-
-
-# ---------------------------------------------------------------------------
-# do_model_mesh outputs the shape/triangelist wrapper block
-# ---------------------------------------------------------------------------
-def do_model_mesh(obj):
-
- global FD
-
- # output the shell
- FD.write(" SI_Mesh MSH-" + removeSpacesFromName(obj.name) + " {\n")
-
- # todo, add calc normals and calc uv here
- # these can be used in both the following sections.
-
- # next the shape
- do_mesh_shape(obj)
-
- # finally the trangle list
- do_mesh_faces(obj)
-
- # finally close this mesh off
- FD.write(" }\n\n")
-
-
-
-# ---------------------------------------------------------------------------
-# do_model actually outputs a mesh model
-# ---------------------------------------------------------------------------
-def do_model(obj):
-
- global FD
-
- # we only want meshes for now.
- if 'Mesh' != obj.type:
- return
-
- # check if the mesh is valid
- if validMesh(obj) <> 0:
- print "INVALID MESH " + obj.name
- return
-
-
- print "Exporting model " + obj.name
-
- # start model
- FD.write(" SI_Model MDL-" + removeSpacesFromName(obj.name) + " {\n")
-
- # do transform
- do_model_transform(obj)
-
- # do visibility
- do_model_visibility(obj)
-
- # do global material
- do_model_material(obj)
-
- # do the mesh
- do_model_mesh(obj)
-
- # close this model
- FD.write(" }\n")
-
-#
-# check for invalid mesh ( faces that have < 3 vertices )
-#
-
-def validMesh (obj):
- mesh = obj.data
- for f in mesh.faces:
- if len(f.v) < 3:
- print "MESH HAS FACES WITH < 3 VERTICES"
- return 1
- if len (mesh.faces) == 0:
- print "MESH HAS NO FACES"
- return 1
-
- return 0
-
-# ---------------------------------------------------------------------------
-# do_models is the process which allows us to write out a bunch of models
-# ---------------------------------------------------------------------------
-def do_models():
-
- global OBJ, MAT, FD
-
- #create the full scene wrapper object
- FD.write("SI_Model MDL-SceneRoot {\n")
- FD.write(" SI_Transform SRT-SceneRoot {\n" )
- FD.write(" 1.000000,\n")
- FD.write(" 1.000000,\n")
- FD.write(" 1.000000,\n")
- FD.write(" -90.000000,\n")
- FD.write(" 0.000000,\n")
- FD.write(" 0.000000,\n")
- FD.write(" 0.000000,\n")
- FD.write(" 0.000000,\n")
- FD.write(" 0.000000,\n")
- FD.write(" }\n\n")
-
- # now process the actual selected meshes themselves
- for obj in OBJ:
- do_model(obj)
-
- for obj in OBJ:
- do_light(obj)
-
- for obj in OBJ:
- do_camera(obj)
-
- do_light_ambient ()
-
- # finally close off the model list
- FD.write("}\n")
-
-
-# ---------------------------------------------------------------------------
-# do_light actually outputs a light model
-# ---------------------------------------------------------------------------
-def do_light(obj):
-
- global FD
-
- # we only want lights for now.
- if 'Lamp' != obj.type:
- return
-
- print "Exporting light " + obj.name
-
- aLampType = 1
-
- lmpName=Lamp.Get(obj.getData(name_only=1))
- lmpType=lmpName.getType()
-
- if lmpType == Lamp.Types.Lamp:
- aLampType = 0
- elif lmpType == Lamp.Types.Spot:
- aLampType = 0
- elif lmpType == Lamp.Types.Sun:
- aLampType = 1
- else:
- aLampType = 0
-
- # start model
- FD.write(" SI_Light " + removeSpacesFromName(obj.name) + " {\n")
-
- # do type
- FD.write(" %d,\n" % aLampType)
-
- lampName= obj.data
- colour = lampName.col
-
- # do color
- FD.write(" %f,\n" % colour[0] )
- FD.write(" %f,\n" % colour[1] )
- FD.write(" %f,\n" % colour[2] )
-
- # do position
-
- FD.write(" %f,\n" % obj.LocX )
- FD.write(" %f,\n" % obj.LocY )
- FD.write(" %f,\n" % obj.LocZ )
-
-
- # close this model
- FD.write(" }\n")
-
-
-# ---------------------------------------------------------------------------
-# do_light actually outputs a light model
-# ---------------------------------------------------------------------------
-def do_camera(obj):
-
- global FD
-
- # we only want cameras for now.
- if 'Camera' != obj.type:
- return
-
- print "Exporting camera " + obj.name
-
-
-
- # start model
- FD.write(" SI_Camera " + removeSpacesFromName(obj.name) + " {\n")
-
-
- cameraName=obj.data
-
- # colour = cameraName.col
-
- # do position
-
- FD.write(" %f,\n" % obj.LocX )
- FD.write(" %f,\n" % obj.LocY )
- FD.write(" %f,\n" % obj.LocZ )
-
- # looking at
-
- FD.write(" %f,\n" % 0.0 )
- FD.write(" %f,\n" % 0.0 )
- FD.write(" %f,\n" % 0.0 )
-
- # roll
- FD.write(" %f,\n" % 0.0 )
-
- aLens = cameraName.getLens()
-
- # field of view
- FD.write(" %f,\n" % aLens )
-
- # near plane
- FD.write(" %f,\n" % 1.0 )
-
- # far plane
- FD.write(" %f,\n" % 10000000.0 )
-
-
- # close this model
- FD.write(" }\n")
-
-
-
-# ---------------------------------------------------------------------------
-# write out the ambient light ( for Shockwave 3D converter )
-# ---------------------------------------------------------------------------
-
-def do_light_ambient():
- if WORLD: ambient = WORLD.getAmb()
- else: ambient = 0,0,0
-
- FD.write(" SI_Light ambient_sw3d {\n")
-
- FD.write(" 9,\n")
- FD.write(" %f,\n" % ambient[0])
- FD.write(" %f,\n" % ambient[1])
- FD.write(" %f,\n" % ambient[2])
- FD.write(" 0.00000000,\n")
- FD.write(" 0.00000000,\n")
- FD.write(" 0.00000000,\n")
-
- FD.write(" }\n")
-
-
-
-# ---------------------------------------------------------------------------
-# export_xsi is the wrapper function to process the loading of an xsi model.
-# ---------------------------------------------------------------------------
-def export_xsi(filename):
-
- global OBJ, MAT, FD, EXPORT_DIR
-
- # safety check
- if filename.find('.xsi', -4) <= 0:
- print "XSI not found"
- filename += '.xsi'
-
-
- export_dir = bsys.dirname(filename)
- if export_dir != EXPORT_DIR:
- EXPORT_DIR = export_dir
-
- # open our output
- FD = open(filename, 'w')
-
- # get the selected objects, otherwise get them all
- #OBJ = Blender.Object.GetSelected()
- #if not OBJ:
-
- OBJ = list(Blender.Scene.GetCurrent().objects) #Blender.Object.Get()
-
- # we need some objects, if none specified stop
- if not OBJ:
- return
-
- # if any exist, grab the materials
- MAT = Blender.Material.Get()
-
- # output the header data
- do_header()
-
- # output the materials used by the selected objects.
- do_materiallibrary()
-
- # we punch out the models, that is, the meshes themselves
- do_models()
-
-
- # finally close our file
- FD.close()
-
-
-
-# ---------------------------------------------------------------------------
-# Lets trigger it off now
-# Blender.Window.FileSelector(export_xsi, 'Export SoftImage XSI')
-
-fname = bsys.makename(ext=".xsi")
-if EXPORT_DIR <> '':
- fname = bsys.join(EXPORT_DIR, bsys.basename(fname))
-
-Blender.Window.FileSelector(export_xsi, "Export SoftImage XSI", fname)
diff --git a/source/Makefile b/source/Makefile
index dab037d1749..45a15e822dc 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -98,7 +98,11 @@ COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a
COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a
COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a
COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
+COMLIB += $(OCGDIR)/blender/ikplugin/$(DEBUG_DIR)libikplugin.a
COMLIB += $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a
+COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a
+COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl.a
+COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl_util.a
COMLIB += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
COMLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a
COMLIB += $(OCGDIR)/blender/avi/$(DEBUG_DIR)libavi.a
@@ -245,7 +249,7 @@ PULIB += $(OCGDIR)/blender/ed_graph/$(DEBUG_DIR)libed_graph.a
PULIB += $(OCGDIR)/blender/ed_node/$(DEBUG_DIR)libed_node.a
PULIB += $(OCGDIR)/blender/ed_outliner/$(DEBUG_DIR)libed_outliner.a
PULIB += $(OCGDIR)/blender/ed_time/$(DEBUG_DIR)libed_time.a
-PULIB += $(OCGDIR)/blender/ed_preview/$(DEBUG_DIR)libed_preview.a
+PULIB += $(OCGDIR)/blender/ed_render/$(DEBUG_DIR)libed_render.a
PULIB += $(OCGDIR)/blender/ed_view3d/$(DEBUG_DIR)libed_view3d.a
PULIB += $(OCGDIR)/blender/ed_interface/$(DEBUG_DIR)libed_interface.a
PULIB += $(OCGDIR)/blender/ed_object/$(DEBUG_DIR)libed_object.a
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index 703c5acd8a2..99297714fd2 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -40,6 +40,7 @@ ADD_SUBDIRECTORY(makesrna)
ADD_SUBDIRECTORY(readblenfile)
ADD_SUBDIRECTORY(render)
ADD_SUBDIRECTORY(blenfont)
+ADD_SUBDIRECTORY(ikplugin)
IF(WITH_OPENEXR)
ADD_SUBDIRECTORY(imbuf/intern/openexr)
diff --git a/source/blender/Makefile b/source/blender/Makefile
index 31636f838c3..6bc874c3c93 100644
--- a/source/blender/Makefile
+++ b/source/blender/Makefile
@@ -34,7 +34,7 @@ DIRS = windowmanager editors blenloader readblenfile
DIRS += avi imbuf render blenlib blenkernel blenpluginapi
DIRS += makesdna makesrna
DIRS += python nodes gpu
-DIRS += blenfont
+DIRS += blenfont ikplugin
ifeq ($(WITH_QUICKTIME), true)
DIRS += quicktime
diff --git a/source/blender/SConscript b/source/blender/SConscript
index a064850c170..3625678f610 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -16,8 +16,9 @@ SConscript(['avi/SConscript',
'readblenfile/SConscript',
'render/SConscript',
'nodes/SConscript',
+ 'ikplugin/SConscript',
'windowmanager/SConscript',
- 'blenfont/SConscript'])
+ 'blenfont/SConscript'])
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index 844a6899bf5..9b7e950526d 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -32,6 +32,7 @@ SET(INC
IF(WITH_INTERNATIONAL)
SET(INC ${INC} ${GETTEXT_INC})
+ ADD_DEFINITIONS(-DINTERNATIONAL)
ENDIF(WITH_INTERNATIONAL)
IF(WIN32)
diff --git a/source/blender/blenfont/Makefile b/source/blender/blenfont/Makefile
index 70dd2e5052b..43eda027855 100644
--- a/source/blender/blenfont/Makefile
+++ b/source/blender/blenfont/Makefile
@@ -28,3 +28,7 @@ SOURCEDIR = source/blender/blenfont
DIRS = intern
include nan_subdirs.mk
+
+ifeq ($(INTERNATIONAL), true)
+ CPPFLAGS += -DINTERNATIONAL
+endif
diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript
index d070d985247..91edc46ba8b 100644
--- a/source/blender/blenfont/SConscript
+++ b/source/blender/blenfont/SConscript
@@ -9,9 +9,13 @@ incs += ' #/extern/glew/include'
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_GETTEXT_INC']
-defs = ''
+defs = []
if sys.platform == 'win32':
- defs += ' _WIN32 USE_GETTEXT_DLL'
+ defs.append('_WIN32')
+ defs.append('USE_GETTEXT_DLL')
+
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('INTERNATIONAL')
env.BlenderLib ( 'bf_blenfont', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[210,210] )
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 8cb237a19ac..db88d84d0b5 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -102,7 +102,7 @@ void BLF_exit(void)
blf_font_exit();
}
-int blf_search(char *name)
+static int blf_search(char *name)
{
FontBLF *font;
int i;
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index b4d902ff428..aac6cd7d2fc 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -51,7 +51,7 @@
static ListBase global_font_dir= { NULL, NULL };
-DirBLF *blf_dir_find(const char *path)
+static DirBLF *blf_dir_find(const char *path)
{
DirBLF *p;
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 2cd72809579..8721e49f06b 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -353,8 +353,8 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
pen_x += delta.x >> 6;
}
- gbox.xmin= g->box.xmin + pen_x;
- gbox.xmax= g->box.xmax + pen_x;
+ gbox.xmin= pen_x;
+ gbox.xmax= pen_x + g->advance;
gbox.ymin= g->box.ymin + pen_y;
gbox.ymax= g->box.ymax + pen_y;
@@ -453,7 +453,7 @@ void blf_font_free(FontBLF *font)
MEM_freeN(font);
}
-void blf_font_fill(FontBLF *font)
+static void blf_font_fill(FontBLF *font)
{
font->aspect= 1.0f;
font->pos[0]= 0.0f;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index f3db3ddc9a5..7d1e43a38df 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -136,7 +136,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
MEM_freeN(gc);
}
-void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
+static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
{
int tot_mem, i;
unsigned char *buf;
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 024172d6db4..ed684eda46f 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -60,17 +60,14 @@ char global_messagepath[1024];
char global_language[32];
char global_encoding_name[32];
-
-void BLF_lang_init(void)
+#if defined(__APPLE__)
+void BLF_lang_init(void) /* Apple Only, todo - use BLI_gethome_folder */
{
-#ifdef __APPLE__
char *bundlepath;
-#endif
strcpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT);
/* set messagepath directory */
-
#ifndef LOCALEDIR
#define LOCALEDIR "/usr/share/locale"
#endif
@@ -81,44 +78,52 @@ void BLF_lang_init(void)
BLI_make_file_string("/", global_messagepath, BLI_gethome(), ".blender/locale");
if (!BLI_exist(global_messagepath)) { /* locale not in home dir */
-#ifdef WIN32
- BLI_make_file_string("/", global_messagepath, BLI_gethome(), "/locale");
- if (!BLI_exist(global_messagepath)) {
-#endif
-#ifdef __APPLE__
/* message catalogs are stored inside the application bundle */
bundlepath= BLI_getbundle();
strcpy(global_messagepath, bundlepath);
strcat(global_messagepath, "/Contents/Resources/locale");
if (!BLI_exist(global_messagepath)) { /* locale not in bundle (now that's odd..) */
-#endif
strcpy(global_messagepath, LOCALEDIR);
if (!BLI_exist(global_messagepath)) { /* locale not in LOCALEDIR */
strcpy(global_messagepath, "message"); /* old compatibility as last */
}
-#ifdef WIN32
}
-#endif
-#ifdef __APPLE__
- }
-#endif
}
}
}
-
-void BLF_lang_set(const char *str)
+#elif defined(_WIN32)
+void BLF_lang_init(void) /* Windows Only, todo - use BLI_gethome_folder */
{
-#if defined (_WIN32) || defined(__APPLE__)
- char envstr[12];
+ strcpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT);
+
+ strcpy(global_messagepath, ".blender/locale");
+
+ if (!BLI_exist(global_messagepath)) { /* locale not in current dir */
+ BLI_make_file_string("/", global_messagepath, BLI_gethome(), ".blender/locale");
- sprintf(envstr, "LANG=%s", str);
- envstr[strlen(envstr)]= '\0';
-#ifdef _WIN32
- gettext_putenv(envstr);
+ if (!BLI_exist(global_messagepath)) { /* locale not in home dir */
+ BLI_make_file_string("/", global_messagepath, BLI_gethome(), "/locale");
+ }
+ }
+}
#else
- putenv(envstr);
+void BLF_lang_init(void) /* not win or mac */
+{
+ char *messagepath= BLI_gethome_folder("locale", BLI_GETHOME_ALL);
+
+ if(messagepath)
+ strncpy(global_messagepath, messagepath, sizeof(global_messagepath));
+ else
+ global_messagepath[0]= '\0';
+
+}
#endif
+
+void BLF_lang_set(const char *str)
+{
+#if defined (_WIN32) || defined(__APPLE__)
+ BLI_setenv("LANG", str);
#else
char *locreturn= setlocale(LC_ALL, str);
if (locreturn == NULL) {
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 4724ee19aaa..17b56864d1e 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -41,6 +41,7 @@ struct bAction;
struct bActionGroup;
struct FCurve;
struct bPose;
+struct bItasc;
struct bPoseChannel;
struct Object;
struct Scene;
@@ -51,7 +52,7 @@ struct ID;
extern "C" {
#endif
-/* Action API ----------------- */
+/* Action Lib Stuff ----------------- */
/* Allocate a new bAction with the given name */
struct bAction *add_empty_action(const char name[]);
@@ -65,6 +66,31 @@ void free_action(struct bAction *act);
// XXX is this needed?
void make_local_action(struct bAction *act);
+
+/* Action API ----------------- */
+
+/* types of transforms applied to the given item
+ * - these are the return falgs for action_get_item_transforms()
+ */
+typedef enum eAction_TransformFlags {
+ /* location */
+ ACT_TRANS_LOC = (1<<0),
+ /* rotation */
+ ACT_TRANS_ROT = (1<<1),
+ /* scaling */
+ ACT_TRANS_SCALE = (1<<2),
+
+ /* all flags */
+ ACT_TRANS_ALL = (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE),
+} eAction_TransformFlags;
+
+/* Return flags indicating which transforms the given object/posechannel has
+ * - if 'curves' is provided, a list of links to these curves are also returned
+ * whose nodes WILL NEED FREEING
+ */
+short action_get_item_transforms(struct bAction *act, struct Object *ob, struct bPoseChannel *pchan, ListBase *curves);
+
+
/* Some kind of bounding box operation on the action */
void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers);
@@ -73,6 +99,9 @@ short action_has_motion(const struct bAction *act);
/* Action Groups API ----------------- */
+/* Get the active action-group for an Action */
+struct bActionGroup *get_active_actiongroup(struct bAction *act);
+
/* Make the given Action Group the active one */
void set_active_action_group(struct bAction *act, struct bActionGroup *agrp, short select);
@@ -126,11 +155,21 @@ struct bPoseChannel *get_active_posechannel(struct Object *ob);
*/
struct bPoseChannel *verify_pose_channel(struct bPose* pose, const char* name);
-
+/* Copy the data from the action-pose (src) into the pose */
+void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
/* sets constraint flags */
void update_pose_constraint_flags(struct bPose *pose);
+/* return the name of structure pointed by pose->ikparam */
+const char *get_ikparam_name(struct bPose *pose);
+
+/* allocate and initialize pose->ikparam according to pose->iksolver */
+void init_pose_ikparam(struct bPose *pose);
+
+/* initialize a bItasc structure with default value */
+void init_pose_itasc(struct bItasc *itasc);
+
/* clears BONE_UNKEYED flags for frame changing */
// XXX to be depreceated for a more general solution in animsys...
void framechange_poses_clear_unkeyed(void);
@@ -153,16 +192,6 @@ void copy_pose_result(struct bPose *to, struct bPose *from);
/* clear all transforms */
void rest_pose(struct bPose *pose);
-/* Game Engine ------------------------- */
-
-/* exported for game engine */
-void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, short mode*/); /* was blend_poses */
-void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
-
-/* functions used by the game engine */
-void game_copy_pose(struct bPose **dst, struct bPose *src);
-void game_free_pose(struct bPose *pose);
-
#ifdef __cplusplus
};
#endif
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 4b1e758da54..32c5ff81740 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -39,14 +39,7 @@ struct PartEff;
struct Scene;
struct ListBase;
-typedef struct DupliObject {
- struct DupliObject *next, *prev;
- struct Object *ob;
- unsigned int origlay;
- int index, no_draw, type, animated;
- float mat[4][4], omat[4][4];
- float orco[3], uv[2];
-} DupliObject;
+#include "DNA_object_types.h"
void free_path(struct Path *path);
void calc_curvepath(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 1cbb2331782..e5d0c4274b3 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -89,6 +89,7 @@ void where_is_armature (struct bArmature *arm);
void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone);
void armature_rebuild_pose(struct Object *ob, struct bArmature *arm);
void where_is_pose (struct Scene *scene, struct Object *ob);
+void where_is_pose_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
/* 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);
@@ -102,10 +103,8 @@ void armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], flo
void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc);
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
-/* Animation functions */
-struct PoseTree *ik_tree_to_posetree(struct Object *ob, struct Bone *bone);
-void solve_posetree(PoseTree *tree);
-void free_posetree(PoseTree *tree);
+/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
+void BKE_rotMode_change_values(float quat[4], float eul[3], short oldMode, short newMode);
/* B-Bone support */
typedef struct Mat4 {
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index d60737d62fe..3549d3e372d 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -43,7 +43,7 @@ struct bContext;
struct ReportList;
#define BLENDER_VERSION 250
-#define BLENDER_SUBVERSION 3
+#define BLENDER_SUBVERSION 4
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_boids.h b/source/blender/blenkernel/BKE_boids.h
index acceff863b9..fb65c9c8920 100644
--- a/source/blender/blenkernel/BKE_boids.h
+++ b/source/blender/blenkernel/BKE_boids.h
@@ -35,9 +35,7 @@
#include "DNA_boid_types.h"
typedef struct BoidBrainData {
- Scene *scene;
- struct Object *ob;
- struct ParticleSystem *psys;
+ struct ParticleSimulationData *sim;
struct ParticleSettings *part;
float timestep, cfra, dfra;
float wanted_co[3], wanted_speed;
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 4d24a2433b3..f302618e60d 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -60,10 +60,10 @@ typedef enum {
BRUSH_PRESET_MAX
} BrushCurvePreset;
void brush_curve_preset(struct Brush *b, BrushCurvePreset preset);
-float brush_curve_strength(struct Brush *br, float p, const float len);
+float brush_curve_strength_clamp(struct Brush *br, float p, const float len);
+float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
/* sampling */
-float brush_sample_falloff(struct Brush *brush, float dist);
void brush_sample_tex(struct Brush *brush, float *xy, float *rgba);
void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf);
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index e4eed084a3d..5ca8ad892ac 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -139,7 +139,16 @@ void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3],
/////////////////////////////////////////////////
// used in effect.c
/////////////////////////////////////////////////
-CollisionModifierData **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj);
+Object **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj);
+
+typedef struct ColliderCache {
+ struct ColliderCache *next, *prev;
+ struct Object *ob;
+ struct CollisionModifierData *collmd;
+} ColliderCache;
+
+struct ListBase *get_collider_cache(struct Scene *scene, Object *self);
+void free_collider_cache(struct ListBase **colliders);
/////////////////////////////////////////////////
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index a0061173438..126816f5a95 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -38,6 +38,9 @@ struct Scene;
struct bPoseChannel;
/* ---------------------------------------------------------------------------- */
+#ifdef __cplusplus
+extern "C" {
+#endif
/* special struct for use in constraint evaluation */
typedef struct bConstraintOb {
@@ -131,6 +134,9 @@ void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan,
void get_constraint_target_matrix(struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index e242ead3b87..44f8238d4d9 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -96,19 +96,27 @@ void draw_all_deps(void);
/* ********** API *************** */
/* Note that the DAG never executes changes in Objects, only sets flags in Objects */
+ /* (re)-create dependency graph for scene */
void DAG_scene_sort(struct Scene *sce);
/* flag all objects that need recalc because they're animated */
void DAG_scene_update_flags(struct Scene *sce, unsigned int lay);
- /* flag all objects that need recalc because they're animated, influencing this object only */
-void DAG_object_update_flags(struct Scene *sce, struct Object *ob, unsigned int lay);
-
/* flushes all recalc flags in objects down the dependency tree */
void DAG_scene_flush_update(struct Scene *sce, unsigned int lay, int time);
+
+ /* flag all IDs that need recalc because they're animated, influencing
+ this ID only. only for objects currently */
+void DAG_id_update_flags(struct ID *id);
/* flushes all recalc flags for this object down the dependency tree,
- but not the DAG only supports objects and object data currently */
+ but note the DAG only supports objects and object data currently */
void DAG_id_flush_update(struct ID *id, short flag);
+ /* when setting manual RECALC flags, call this afterwards */
+void DAG_ids_flush_update(int time);
+ /* (re)-create dependency graph for armature pose */
void DAG_pose_sort(struct Object *ob);
+
+ /* callback for editors module to do updates */
+void DAG_editors_update_cb(void (*func)(struct Main *bmain, struct ID *id));
#endif
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index e21e83bf5cf..83ec7c13946 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -32,6 +32,7 @@
#define BKE_EFFECT_H
#include "DNA_object_types.h"
+#include "DNA_modifier_types.h"
struct Object;
struct Scene;
@@ -40,20 +41,72 @@ struct ListBase;
struct Particle;
struct Group;
struct RNG;
+struct ParticleSimulationData;
+struct ParticleData;
+struct ParticleKey;
-struct PartDeflect *object_add_collision_fields(void);
+struct EffectorWeights *BKE_add_effector_weights(struct Group *group);
+struct PartDeflect *object_add_collision_fields(int type);
-typedef struct pEffectorCache {
- struct pEffectorCache *next, *prev;
- Object *ob;
-
- /* precalculated variables */
- float oldloc[3], oldspeed[3];
- float scale, time_scale;
- float guide_dist;
+/* Input to effector code */
+typedef struct EffectedPoint {
+ float *loc;
+ float *vel;
+ float *ave; /* angular velocity for particles with dynamic rotation */
+ float *rot; /* rotation quaternion for particles with dynamic rotation */
+ float vel_to_frame;
+ float vel_to_sec;
+
+ /* only for particles */
+ float size, charge;
+
+ unsigned int flag;
+ int index;
+
+ struct ParticleSystem *psys; /* particle system the point belongs to */
+} EffectedPoint;
+
+typedef struct GuideEffectorData {
+ float vec_to_point[3];
+ float strength;
+} GuideEffectorData;
+
+typedef struct EffectorData {
+ /* Effector point */
+ float loc[3];
+ float nor[3];
+ float vel[3];
+
+ float vec_to_point[3];
+ float distance, falloff;
+
+ /* only for effector particles */
+ float size, charge;
+
+ /* only for vortex effector with surface falloff */
+ float nor2[3], vec_to_point2[3];
+
+ int *index; /* point index */
+} EffectorData;
+
+/* used for calculating the effector force */
+typedef struct EffectorCache {
+ struct EffectorCache *next, *prev;
+
+ struct Scene *scene;
+ struct Object *ob;
+ struct ParticleSystem *psys;
+ struct SurfaceModifierData *surmd;
- Object obcopy; /* for restoring transformation data */
-} pEffectorCache;
+ struct PartDeflect *pd;
+
+ /* precalculated for guides */
+ struct GuideEffectorData *guide_data;
+ float guide_loc[4], guide_dir[3], guide_radius;
+
+ float frame;
+ int flag;
+} EffectorCache;
void free_effect(struct Effect *eff);
void free_effects(struct ListBase *lb);
@@ -61,23 +114,33 @@ struct Effect *copy_effect(struct Effect *eff);
void copy_effects(struct ListBase *lbn, struct ListBase *lb);
void deselectall_eff(struct Object *ob);
-/* particle deflector */
-#define PE_WIND_AS_SPEED 0x00000001
-
struct PartEff *give_parteff(struct Object *ob);
-struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *obsrc, struct Group *group);
-void pdEndEffectors(struct ListBase *lb);
-void pdDoEffectors(struct Scene *scene, struct ListBase *lb, float *opco, float *force,
- float *speed, float cur_time, float loc_time, unsigned int flags);
+
+
+void free_partdeflect(struct PartDeflect *pd);
+struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights);
+void pdEndEffectors(struct ListBase **effectors);
+void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
+
+void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
+void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
+void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
+
+/* needed for boids */
+float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights);
+int closest_point_on_surface(struct SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel);
+int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity);
/* required for particle_system.c */
-void do_physical_effector(struct Scene *scene, struct Object *ob, float *opco, short type, float force_val, float distance,
- float falloff, float size, float damp, float *eff_velocity, float *vec_to_part,
- float *velocity, float *field, int planar, struct RNG *rng, float noise_factor,
- float charge, float pa_size);
-float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float *vec_to_part);
+//void do_physical_effector(struct EffectorData *eff, struct EffectorPoint *point, float *total_force);
+//float effector_falloff(struct EffectorData *eff, struct EffectorPoint *point, struct EffectorWeights *weights);
+/* EffectedPoint->flag */
+#define PE_WIND_AS_SPEED 1
+#define PE_DYNAMIC_ROTATION 2
+/* EffectorData->flag */
+#define PE_VELOCITY_TO_IMPULSE 1
#endif
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index cda64c6b241..94d0864024b 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -35,6 +35,8 @@ struct DriverTarget;
struct BezTriple;
+#include "DNA_curve_types.h"
+
/* ************** Keyframe Tools ***************** */
// XXX this stuff is defined in BKE_ipo.h too, so maybe skip for now?
@@ -153,6 +155,11 @@ void copy_fcurves(ListBase *dst, ListBase *src);
/* find matching F-Curve in the given list of F-Curves */
struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
+/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+int binarysearch_bezt_index(struct BezTriple array[], float frame, int arraylen, short *replace);
+
/* get the time extents for F-Curve */
void calc_fcurve_range(struct FCurve *fcu, float *min, float *max);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 816baa20467..85c3c716b8b 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -107,6 +107,11 @@ struct RenderResult;
/* always call to make signals work */
struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
+/* same as above, but can be used to retrieve images being rendered in
+ * a thread safe way, always call both acquire and release */
+struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r);
+void BKE_image_release_ibuf(struct Image *ima, void *lock);
+
/* returns existing Image when filename/type is same (frame optional) */
struct Image *BKE_add_image_file(const char *name, int frame);
@@ -125,6 +130,9 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
/* called on frame change or before render */
void BKE_image_user_calc_imanr(struct ImageUser *iuser, int cfra, int fieldnr);
+/* produce image export path */
+int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size);
+
/* fix things in ImageUser when new image gets assigned */
void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
@@ -132,7 +140,8 @@ void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser);
/* for multilayer images as well as for render-viewer */
-struct RenderResult *BKE_image_get_renderresult(struct Scene *scene, struct Image *ima);
+struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima);
+void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima);
/* goes over all textures that use images */
void BKE_image_free_all_textures(void);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 54722dac910..0e978128cf6 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -77,6 +77,7 @@ void IPOnames_to_pupstring(char **str, char *title, char *extraops, struct ListB
void flag_listbase_ids(ListBase *lb, short flag, short value);
void flag_all_listbases_ids(short flag, short value);
+void recalc_all_library_objects(struct Main *main);
void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) );
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index cbb37918d04..b1e7dcaff02 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -42,7 +42,7 @@ struct bNode;
struct bNodeLink;
struct bNodeSocket;
struct bNodeStack;
-struct uiBlock;
+struct uiLayout;
struct rctf;
struct ListBase;
struct RenderData;
@@ -52,6 +52,7 @@ struct Tex;
struct GPUMaterial;
struct GPUNode;
struct GPUNodeStack;
+struct PointerRNA;
/* ************** NODE TYPE DEFINITIONS ***** */
@@ -82,7 +83,7 @@ typedef struct bNodeType {
void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **);
/* this line is set on startup of blender */
- int (*butfunc)(struct uiBlock *, struct bNodeTree *, struct bNode *, struct rctf *);
+ void (*uifunc)(struct uiLayout *, struct PointerRNA *ptr);
void (*initfunc)(struct bNode *);
void (*freestoragefunc)(struct bNode *);
@@ -425,7 +426,7 @@ extern struct ListBase node_all_textures;
/* API */
int ntreeTexTagAnimated(struct bNodeTree *ntree);
void ntreeTexSetPreviewFlag(int);
-void ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, short thread, struct Tex *tex, short which_output, int cfra);
+void ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, short thread, struct Tex *tex, short which_output, int cfra, int preview);
void ntreeTexCheckCyclics(struct bNodeTree *ntree);
char* ntreeTexOutputMenu(struct bNodeTree *ntree);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index c22778f5a30..e0259ff10dd 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -61,37 +61,33 @@ struct BVHTreeRayHit;
#define PARTICLE_P ParticleData *pa; int p
#define LOOP_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
+#define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST))
+#define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP)))
-typedef struct ParticleEffectorCache {
- struct ParticleEffectorCache *next, *prev;
- struct Object *ob;
-
- /* precalculated variables for guides */
- float firstloc[4], firstdir[3];
- float *distances;
- float *locations;
- /* precalculated variables for deflection */
- float ob_minmax[6];
- float *face_minmax;
- float *vert_cos;
- /* precalculated variables for boids */
- struct KDTree *tree;
+#define PSYS_FRAND_COUNT 1024
+#define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT]
- short type, psys_nbr;
-
- struct Object obcopy; /* for restoring transformation data */
- struct RNG *rng; /* random noise generator for e.g. wind */
-} ParticleEffectorCache;
+/* fast but sure way to get the modifier*/
+#define PARTICLE_PSMD ParticleSystemModifierData *psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
-typedef struct ParticleReactEvent {
- struct ParticleReactEvent *next, *prev;
- int event, pa_num;
- Object *ob;
+/* common stuff that many particle functions need */
+typedef struct ParticleSimulationData {
+ struct Scene *scene;
+ struct Object *ob;
struct ParticleSystem *psys;
- struct ParticleKey state;
-
- float time, size;
-}ParticleReactEvent;
+ struct ParticleSystemModifierData *psmd;
+ struct ListBase *colliders;
+} ParticleSimulationData;
+
+//typedef struct ParticleReactEvent {
+// struct ParticleReactEvent *next, *prev;
+// int event, pa_num;
+// Object *ob;
+// struct ParticleSystem *psys;
+// struct ParticleKey state;
+//
+// float time, size;
+//}ParticleReactEvent;
typedef struct ParticleTexture{
float ivel; /* used in reset */
@@ -118,11 +114,8 @@ typedef struct ParticleCacheKey{
typedef struct ParticleThreadContext {
/* shared */
- struct Scene *scene;
- struct Object *ob;
+ struct ParticleSimulationData sim;
struct DerivedMesh *dm;
- struct ParticleSystemModifierData *psmd;
- struct ParticleSystem *psys;
struct Material *ma;
/* distribution */
@@ -166,53 +159,52 @@ typedef struct ParticleBillboardData
int lock, num;
int totnum;
short align, uv_split, anim, split_offset;
-}
-ParticleBillboardData;
+} ParticleBillboardData;
/* container for moving data between deflet_particle and particle_intersect_face */
typedef struct ParticleCollision
{
- struct Object *ob, *ob_t; // collided and current objects
- struct CollisionModifierData *md; // collision modifier for ob_t;
+ struct Object *ob, *hit_ob; // collided and current objects
+ struct CollisionModifierData *md, *hit_md; // collision modifiers for current and hit object;
float nor[3]; // normal at collision point
float vel[3]; // velocity of collision point
float co1[3], co2[3]; // ray start and end points
float ray_len; // original length of co2-co1, needed for collision time evaluation
float t; // time of previous collision, needed for substracting face velocity
-}
-ParticleCollision;
+} ParticleCollision;
+
+typedef struct ParticleDrawData {
+ float *vdata, *vd; /* vertice data */
+ float *ndata, *nd; /* normal data */
+ float *cdata, *cd; /* color data */
+ float *vedata, *ved; /* velocity data */
+ float *ma_r, *ma_g, *ma_b;
+ int tot_vec_size, flag;
+ int totpoint, totve;
+} ParticleDrawData;
+
+#define PARTICLE_DRAW_DATA_UPDATED 1
/* ----------- functions needed outside particlesystem ---------------- */
/* particle.c */
int count_particles(struct ParticleSystem *psys);
int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
-int psys_count_keys(struct ParticleSystem *psys);
-char *psys_menu_string(struct Object *ob, int for_sb);
struct ParticleSystem *psys_get_current(struct Object *ob);
+/* for rna */
short psys_get_current_num(struct Object *ob);
void psys_set_current_num(Object *ob, int index);
struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
-//struct ParticleSystem *psys_get(struct Object *ob, int index);
-struct ParticleData *psys_get_selected_particle(struct ParticleSystem *psys, int *index);
-struct ParticleKey *psys_get_selected_key(struct ParticleSystem *psys, int pa_index, int *key_index);
-void psys_change_act(void *ob_v, void *act_v);
-struct Object *psys_get_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
-void psys_disable_all(struct Object *ob);
-void psys_enable_all(struct Object *ob);
-int psys_ob_has_hair(struct Object *ob);
+
+struct Object *psys_get_lattice(struct ParticleSimulationData *sim);
+
int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
-void psys_free_boid_rules(struct ListBase *list);
+/* free */
void psys_free_settings(struct ParticleSettings *part);
-void free_child_path_cache(struct ParticleSystem *psys);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
-void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
-void free_keyed_keys(struct ParticleSystem *psys);
-void psys_free_particles(struct ParticleSystem *psys);
void psys_free(struct Object * ob, struct ParticleSystem * psys);
-void psys_free_children(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_restore(struct Object *ob, struct ParticleSystem *psys);
@@ -231,48 +223,39 @@ void object_add_particle_system(struct Scene *scene, struct Object *ob);
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
-void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
void make_local_particlesettings(struct ParticleSettings *part);
-struct LinkNode *psys_using_settings(struct Scene *scene, struct ParticleSettings *part, int flush_update);
void psys_reset(struct ParticleSystem *psys, int mode);
-void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys);
+void psys_find_parents(struct ParticleSimulationData *sim);
-void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra);
+void psys_cache_paths(struct ParticleSimulationData *sim, float cfra);
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra);
-void psys_cache_child_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
-int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
-float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size);
-float psys_get_timestep(struct ParticleSettings *part);
+void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate);
+int do_guides(struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
+void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
+float psys_get_timestep(struct ParticleSimulationData *sim);
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
-void psys_get_particle_on_path(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int pa_num, struct ParticleKey *state, int vel);
-int psys_get_particle_state(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int p, struct ParticleKey *state, int always);
+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);
+
+/* for anim.c */
void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco);
-void psys_get_dupli_path_transform(struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
+void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
-ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
-int psys_threads_init_distribution(ParticleThread *threads, struct Scene *scene, struct DerivedMesh *dm, int from);
-int psys_threads_init_path(ParticleThread *threads, struct Scene *scene, float cfra, int editupdate);
+ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
void psys_threads_free(ParticleThread *threads);
-void psys_thread_distribute_particle(ParticleThread *thread, struct ParticleData *pa, struct ChildParticle *cpa, int p);
-void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i);
-
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
/* particle_system.c */
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
-void psys_count_keyed_targets(struct Object *ob, struct ParticleSystem *psys);
-void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, struct Object **target_ob, struct ParticleSystem **target_psys);
-
-void psys_init_effectors(struct Scene *scene, struct Object *obsrc, struct Group *group, struct ParticleSystem *psys);
-void psys_end_effectors(struct ParticleSystem *psys);
+void psys_count_keyed_targets(struct ParticleSimulationData *sim);
+void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
-void psys_end_temp_pointcache(struct ParticleSystem *psys);
-void psys_get_pointcache_start_end(struct Scene *scene, struct ParticleSystem *psys, int *sfra, int *efra);
+void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);
void psys_check_boid_data(struct ParticleSystem *psys);
@@ -280,40 +263,40 @@ void particle_system_update(struct Scene *scene, struct Object *ob, struct Parti
/* ----------- functions needed only inside particlesystem ------------ */
/* particle.c */
+void psys_disable_all(struct Object *ob);
+void psys_enable_all(struct Object *ob);
+
+void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
+void free_keyed_keys(struct ParticleSystem *psys);
+void psys_free_particles(struct ParticleSystem *psys);
+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_key_to_object(struct Object *ob, struct ParticleKey *key, float imat[][4]);
-//void psys_key_to_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
-//void psys_key_from_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
-//void psys_face_mat(struct DerivedMesh *dm, struct ParticleData *pa, float mat[][4]);
void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
-//void psys_vec_rot_from_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
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_free_pdd(struct ParticleSystem *psys);
+
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
-void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
+void psys_get_texture(struct ParticleSimulationData *sim, struct Material *ma, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
-float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, int index, float *fw, float *values);
void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time);
+/* only in edisparticle.c*/
int psys_intersect_dm(struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint);
+/* BLI_bvhtree_ray_cast callback */
void particle_intersect_face(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
/* particle_system.c */
-void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
-
-int effector_find_co(struct Scene *scene, float *pco, struct SurfaceModifierData *sur, struct Object *ob, struct PartDeflect *pd, float *co, float *nor, float *vel, int *index);
-void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra);
-
+void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p);
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
-void reset_particle(struct Scene *scene, struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob,
- float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot);
-
+void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
/* psys_reset */
#define PSYS_RESET_ALL 1
@@ -321,12 +304,6 @@ void reset_particle(struct Scene *scene, struct ParticleData *pa, struct Particl
#define PSYS_RESET_CHILDREN 3
#define PSYS_RESET_CACHE_MISS 4
-/* ParticleEffectorCache->type */
-#define PSYS_EC_EFFECTOR 1
-#define PSYS_EC_DEFLECT 2
-#define PSYS_EC_PARTICLE 4
-#define PSYS_EC_REACTOR 8
-
/* index_dmcache */
#define DMCACHE_NOTFOUND -1
#define DMCACHE_ISCHILD -2
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 4fcb7c881be..ee04d4f47bc 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -230,11 +230,11 @@ void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2);
/* area/regions */
struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
+void BKE_screen_area_free(struct ScrArea *sa);
-void BKE_screen_area_free(struct ScrArea *sa);
-
+/* screen */
void free_screen(struct bScreen *sc);
-
+unsigned int BKE_screen_visible_layers(struct bScreen *screen);
#endif
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index e9f6eb21e36..cbce4663d6f 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -71,7 +71,7 @@ void sound_update_playing(struct bContext *C);
void sound_scrub(struct bContext *C);
#ifdef AUD_CAPI
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end);
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume);
#endif
void sound_stop_all(struct bContext *C);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index bd14053d121..185e32ecdfa 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -48,6 +48,8 @@ int reopen_text (struct Text *text);
struct Text* add_text (char *file, const char *relpath);
struct Text* copy_text (struct Text *ta);
void unlink_text (struct Main *bmain, struct Text *text);
+void clear_text(struct Text *text);
+void write_text(struct Text *text, char *str);
char* txt_to_buf (struct Text *text);
void txt_clean_text (struct Text *text);
@@ -74,7 +76,7 @@ void txt_delete_selected (struct Text *text);
void txt_sel_all (struct Text *text);
void txt_sel_line (struct Text *text);
char* txt_sel_to_buf (struct Text *text);
-void txt_insert_buf (struct Text *text, char *in_buffer);
+void txt_insert_buf (struct Text *text, const char *in_buffer);
void txt_print_undo (struct Text *text);
void txt_undo_add_toop (struct Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc);
void txt_do_undo (struct Text *text);
@@ -102,6 +104,14 @@ struct TextMarker *txt_next_marker (struct Text *text, struct TextMarker *marke
struct TextMarker *txt_prev_marker_color (struct Text *text, struct TextMarker *marker);
struct TextMarker *txt_next_marker_color (struct Text *text, struct TextMarker *marker);
+/* utility functions, could be moved somewhere more generic but are python/text related */
+int text_check_bracket(char ch);
+int text_check_delim(char ch);
+int text_check_digit(char ch);
+int text_check_identifier(char ch);
+int text_check_whitespace(char ch);
+
+
/* Undo opcodes */
/* Simple main cursor movement */
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index 4d43518901e..7d8cb41db82 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -193,5 +193,54 @@
#define SET_INT_IN_POINTER(i) ((void*)(intptr_t)(i))
#define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i))
+/*little array macro library. example of usage:
+
+int *arr = NULL;
+V_DECLARE(arr);
+int i;
+
+for (i=0; i<10; i++) {
+ V_GROW(arr);
+ arr[i] = something;
+}
+V_FREE(arr);
+
+arrays are buffered, using double-buffering (so on each reallocation,
+the array size is doubled). supposedly this should give good Big Oh
+behaviour, though it may not be the best in practice.
+*/
+
+#define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp
+
+/*in the future, I plan on having V_DECLARE allocate stack memory it'll
+ use at first, and switch over to heap when it needs more. that'll mess
+ up cases where you'd want to use this API to build a dynamic list for
+ non-local use, so all such cases should use this macro.*/
+#define V_DYNDECLARE(vec) V_DECLARE(vec)
+
+/*this returns the entire size of the array, including any buffering.*/
+#define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec)))
+
+/*this returns the logical size of the array, not including buffering.*/
+#define V_COUNT(vec) _##vec##_count
+
+/*grow the array by one. zeroes the new elements.*/
+#define V_GROW(vec) \
+ V_SIZE(vec) > _##vec##_count ? _##vec##_count++ : \
+ ((_##vec##_tmp = MEM_callocN(sizeof(*vec)*(_##vec##_count*2+2), #vec " " __FILE__ " ")),\
+ (vec && memcpy(_##vec##_tmp, vec, sizeof(*vec) * _##vec##_count)),\
+ (vec && (MEM_freeN(vec),1)),\
+ (vec = _##vec##_tmp),\
+ _##vec##_count++)
+
+#define V_FREE(vec) if (vec) MEM_freeN(vec);
+
+/*resets the logical size of an array to zero, but doesn't
+ free the memory.*/
+#define V_RESET(vec) _##vec##_count=0
+
+/*set the count of the array*/
+#define V_SETCOUNT(vec, count) _##vec##_count = (count)
+
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 68aed2b0184..f60cade61ed 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -30,12 +30,10 @@ SET(INC
. ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna
../render/extern/include ../../../intern/decimation/extern
../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
- ../../../intern/iksolver/extern ../blenloader
+ ../../../intern/iksolver/extern ../blenloader ../ikplugin
../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern
../../../intern/bsp/extern ../blenfont
../../../intern/audaspace/intern
- ../../../extern/lzo/minilzo
- ../../../extern/lzma
${ZLIB_INC}
)
@@ -76,6 +74,16 @@ IF(NOT WITH_ELBEEM)
ADD_DEFINITIONS(-DDISABLE_ELBEEM)
ENDIF(NOT WITH_ELBEEM)
+IF(WITH_LZO)
+ SET(INC ${INC} ../../../extern/lzo/minilzo)
+ ADD_DEFINITIONS(-DWITH_LZO)
+ENDIF(WITH_LZO)
+
+IF(WITH_LZMA)
+ SET(INC ${INC} ../../../extern/lzma)
+ ADD_DEFINITIONS(-DWITH_LZMA)
+ENDIF(WITH_LZMA)
+
IF(WIN32)
SET(INC ${INC} ${PTHREADS_INC})
ENDIF(WIN32)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 1f42390504d..63631ddc40f 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -5,14 +5,12 @@ sources = env.Glob('intern/*.c')
incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include ../blenlib ../blenfont ../makesdna'
incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna'
-incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes'
+incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes'
incs += ' #/intern/iksolver/extern ../blenloader'
incs += ' #/extern/bullet2/src'
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
incs += ' ../gpu #/extern/glew/include'
incs += ' #/intern/smoke/extern'
-incs += ' #/extern/lzo/minilzo'
-incs += ' #/extern/lzma'
incs += ' #/intern/audaspace/intern'
incs += ' ' + env['BF_OPENGL_INC']
@@ -61,7 +59,15 @@ if env['BF_NO_ELBEEM']:
if env['WITH_BF_LCMS']:
defs.append('WITH_LCMS')
-
+
+if env['WITH_BF_LZO']:
+ incs += ' #/extern/lzo/minilzo'
+ defs.append('WITH_LZO')
+
+if env['WITH_BF_LZMA']:
+ incs += ' #/extern/lzma'
+ defs.append('WITH_LZMA')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile
index 6c2edc9e25f..26b9b9ef0dd 100644
--- a/source/blender/blenkernel/intern/Makefile
+++ b/source/blender/blenkernel/intern/Makefile
@@ -47,6 +47,7 @@ CPPFLAGS += -I$(NAN_AUDASPACE)/include
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../imbuf
+CPPFLAGS += -I../../ikplugin
# This mod uses the BLI and BLO module
CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../blenloader
@@ -85,14 +86,24 @@ CPPFLAGS += -I../../gpu
# path to our own external headerfiles
CPPFLAGS += -I..
-# path to bullet2, for cloth
-CPPFLAGS += -I$(NAN_BULLET2)/include
CPPFLAGS += -I$(NAN_FREETYPE)/include
CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2
+# path to bullet2, for cloth
+ifeq ($(NAN_USE_BULLET), true)
+ CPPFLAGS += -I$(NAN_BULLET2)/include
+endif
+
# lzo and lzma, for pointcache
-CPPFLAGS += -I$(NAN_LZO)/minilzo
-CPPFLAGS += -I$(NAN_LZMA)
+ifeq ($(WITH_LZO),true)
+ CPPFLAGS += -I$(NAN_LZO)/minilzo
+ CPPFLAGS += -DWITH_LZO
+endif
+
+ifeq ($(WITH_LZO),true)
+ CPPFLAGS += -I$(NAN_LZMA)
+ CPPFLAGS += -DWITH_LZMA
+endif
ifeq ($(WITH_FFMPEG),true)
CPPFLAGS += -DWITH_FFMPEG
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 47de044ea25..b8dc9fd049d 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -62,6 +62,7 @@
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "BIK_api.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -212,6 +213,7 @@ bAction *copy_action (bAction *src)
return dst;
}
+/* *************** Action Groups *************** */
/* Get the active action-group for an Action */
bActionGroup *get_active_actiongroup (bAction *act)
@@ -404,7 +406,7 @@ bActionGroup *action_groups_find_named (bAction *act, const char name[])
return NULL;
}
-/* ************************ Pose channels *************** */
+/* *************** Pose channels *************** */
/* usually used within a loop, so we got a N^2 slowdown */
bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
@@ -450,7 +452,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f;
chan->limitmax[0]= chan->limitmax[1]= chan->limitmax[2]= 180.0f;
chan->stiffness[0]= chan->stiffness[1]= chan->stiffness[2]= 0.0f;
-
+ chan->ikrotweight = chan->iklinweight = 0.0f;
Mat4One(chan->constinv);
BLI_addtail(&pose->chanbase, chan);
@@ -476,7 +478,18 @@ bPoseChannel *get_active_posechannel (Object *ob)
return NULL;
}
-
+const char *get_ikparam_name(bPose *pose)
+{
+ if (pose) {
+ switch (pose->iksolver) {
+ case IKSOLVER_LEGACY:
+ return NULL;
+ case IKSOLVER_ITASC:
+ return "bItasc";
+ }
+ }
+ return NULL;
+}
/* dst should be freed already, makes entire duplicate */
void copy_pose (bPose **dst, bPose *src, int copycon)
{
@@ -498,7 +511,10 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
outPose= MEM_callocN(sizeof(bPose), "pose");
BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
-
+ outPose->iksolver = src->iksolver;
+ outPose->ikdata = NULL;
+ outPose->ikparam = MEM_dupallocN(src->ikparam);
+
if (copycon) {
for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
@@ -510,6 +526,39 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
*dst=outPose;
}
+void init_pose_itasc(bItasc *itasc)
+{
+ if (itasc) {
+ itasc->iksolver = IKSOLVER_ITASC;
+ itasc->minstep = 0.01f;
+ itasc->maxstep = 0.06f;
+ itasc->numiter = 100;
+ itasc->numstep = 4;
+ itasc->precision = 0.005f;
+ itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION|ITASC_SIMULATION;
+ itasc->feedback = 20.f;
+ itasc->maxvel = 50.f;
+ itasc->solver = ITASC_SOLVER_SDLS;
+ itasc->dampmax = 0.5;
+ itasc->dampeps = 0.15;
+ }
+}
+void init_pose_ikparam(bPose *pose)
+{
+ bItasc *itasc;
+ switch (pose->iksolver) {
+ case IKSOLVER_ITASC:
+ itasc = MEM_callocN(sizeof(bItasc), "itasc");
+ init_pose_itasc(itasc);
+ pose->ikparam = itasc;
+ break;
+ case IKSOLVER_LEGACY:
+ default:
+ pose->ikparam = NULL;
+ break;
+ }
+}
+
void free_pose_channels(bPose *pose)
{
bPoseChannel *pchan;
@@ -533,133 +582,15 @@ void free_pose(bPose *pose)
/* free pose-groups */
if (pose->agroups.first)
BLI_freelistN(&pose->agroups);
-
- /* free pose */
- MEM_freeN(pose);
- }
-}
-
-void game_copy_pose(bPose **dst, bPose *src)
-{
- bPose *out;
- bPoseChannel *pchan, *outpchan;
- GHash *ghash;
-
- /* the game engine copies the current armature pose and then swaps
- * the object pose pointer. this makes it possible to change poses
- * without affecting the original blender data. */
-
- if (!src) {
- *dst=NULL;
- return;
- }
- else if (*dst==src) {
- printf("copy_pose source and target are the same\n");
- *dst=NULL;
- return;
- }
-
- out= MEM_dupallocN(src);
- out->agroups.first= out->agroups.last= NULL;
- BLI_duplicatelist(&out->chanbase, &src->chanbase);
-
- /* remap pointers */
- ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-
- pchan= src->chanbase.first;
- outpchan= out->chanbase.first;
- for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
- BLI_ghash_insert(ghash, pchan, outpchan);
-
- for (pchan=out->chanbase.first; pchan; pchan=pchan->next) {
- pchan->parent= BLI_ghash_lookup(ghash, pchan->parent);
- pchan->child= BLI_ghash_lookup(ghash, pchan->child);
- pchan->path= NULL;
- }
-
- BLI_ghash_free(ghash, NULL, NULL);
-
- *dst=out;
-}
+ /* free IK solver state */
+ BIK_clear_data(pose);
-/* Only allowed for Poses with identical channels */
-void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/)
-{
- short mode= ACTSTRIPMODE_BLEND;
-
- bPoseChannel *dchan;
- const bPoseChannel *schan;
- bConstraint *dcon, *scon;
- float dstweight;
- int i;
+ /* free IK solver param */
+ if (pose->ikparam)
+ MEM_freeN(pose->ikparam);
- switch (mode){
- case ACTSTRIPMODE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case ACTSTRIPMODE_ADD:
- dstweight = 1.0F;
- break;
- default :
- dstweight = 1.0F;
- }
-
- schan= src->chanbase.first;
- for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
- if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
- /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
-
- /* Do the transformation blend */
- if (schan->flag & POSE_ROT) {
- /* quat interpolation done separate */
- if (schan->rotmode == PCHAN_ROT_QUAT) {
- float dquat[4], squat[4];
-
- QUATCOPY(dquat, dchan->quat);
- QUATCOPY(squat, schan->quat);
- if (mode==ACTSTRIPMODE_BLEND)
- QuatInterpol(dchan->quat, dquat, squat, srcweight);
- else {
- QuatMulFac(squat, srcweight);
- QuatMul(dchan->quat, dquat, squat);
- }
-
- NormalQuat(dchan->quat);
- }
- }
-
- for (i=0; i<3; i++) {
- /* blending for loc and scale are pretty self-explanatory... */
- if (schan->flag & POSE_LOC)
- dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
- if (schan->flag & POSE_SIZE)
- dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
-
- /* euler-rotation interpolation done here instead... */
- // FIXME: are these results decent?
- if ((schan->flag & POSE_ROT) && (schan->rotmode))
- dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
- }
- dchan->flag |= schan->flag;
- }
- for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
- /* no 'add' option for constraint blending */
- dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
- }
- }
-
- /* this pose is now in src time */
- dst->ctime= src->ctime;
-}
-
-void game_free_pose(bPose *pose)
-{
- if (pose) {
- /* we don't free constraints, those are owned by the original pose */
- if(pose->chanbase.first)
- BLI_freelistN(&pose->chanbase);
-
+ /* free pose */
MEM_freeN(pose);
}
}
@@ -818,7 +749,7 @@ void pose_remove_group (Object *ob)
}
}
-/* ************** time ****************** */
+/* ************** F-Curve Utilities for Actions ****************** */
/* Check if the given action has any keyframes */
short action_has_motion(const bAction *act)
@@ -916,6 +847,98 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
}
}
+/* Return flags indicating which transforms the given object/posechannel has
+ * - if 'curves' is provided, a list of links to these curves are also returned
+ */
+short action_get_item_transforms (bAction *act, Object *ob, bPoseChannel *pchan, ListBase *curves)
+{
+ PointerRNA ptr;
+ FCurve *fcu;
+ char *basePath=NULL;
+ short flags=0;
+
+ /* build PointerRNA from provided data to obtain the paths to use */
+ if (pchan)
+ RNA_pointer_create((ID *)ob, &RNA_PoseChannel, pchan, &ptr);
+ else if (ob)
+ RNA_id_pointer_create((ID *)ob, &ptr);
+ else
+ return 0;
+
+ /* get the basic path to the properties of interest */
+ basePath= RNA_path_from_ID_to_struct(&ptr);
+ if (basePath == NULL)
+ return 0;
+
+ /* search F-Curves for the given properties
+ * - we cannot use the groups, since they may not be grouped in that way...
+ */
+ for (fcu= act->curves.first; fcu; fcu= fcu->next) {
+ char *bPtr=NULL, *pPtr=NULL;
+
+ /* if enough flags have been found, we can stop checking unless we're also getting the curves */
+ if ((flags == ACT_TRANS_ALL) && (curves == NULL))
+ break;
+
+ /* just in case... */
+ if (fcu->rna_path == NULL)
+ continue;
+
+ /* step 1: check for matching base path */
+ bPtr= strstr(fcu->rna_path, basePath);
+
+ if (bPtr) {
+ /* step 2: check for some property with transforms
+ * - to speed things up, only check for the ones not yet found
+ * unless we're getting the curves too
+ * - if we're getting the curves, the BLI_genericNodeN() creates a LinkData
+ * node wrapping the F-Curve, which then gets added to the list
+ * - once a match has been found, the curve cannot possibly be any other one
+ */
+ if ((curves) || (flags & ACT_TRANS_LOC) == 0) {
+ pPtr= strstr(fcu->rna_path, "location");
+ if ((pPtr) && (pPtr >= bPtr)) {
+ flags |= ACT_TRANS_LOC;
+
+ if (curves)
+ BLI_addtail(curves, BLI_genericNodeN(fcu));
+ continue;
+ }
+ }
+
+ if ((curves) || (flags & ACT_TRANS_SCALE) == 0) {
+ pPtr= strstr(fcu->rna_path, "scale");
+ if ((pPtr) && (pPtr >= bPtr)) {
+ flags |= ACT_TRANS_SCALE;
+
+ if (curves)
+ BLI_addtail(curves, BLI_genericNodeN(fcu));
+ continue;
+ }
+ }
+
+ if ((curves) || (flags & ACT_TRANS_ROT) == 0) {
+ pPtr= strstr(fcu->rna_path, "rotation");
+ if ((pPtr) && (pPtr >= bPtr)) {
+ flags |= ACT_TRANS_ROT;
+
+ if (curves)
+ BLI_addtail(curves, BLI_genericNodeN(fcu));
+ continue;
+ }
+ }
+ }
+ }
+
+ /* free basePath */
+ MEM_freeN(basePath);
+
+ /* return flags found */
+ return flags;
+}
+
+/* ************** Pose Management Tools ****************** */
+
/* Copy the data from the action-pose (src) into the pose */
/* both args are assumed to be valid */
/* exported to game engine */
@@ -1158,138 +1181,6 @@ static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src,
VecAddf(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset);
}
-typedef struct NlaIpoChannel {
- struct NlaIpoChannel *next, *prev;
- float val;
- void *poin;
- int type;
-} NlaIpoChannel;
-
-void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime)
-{
- bActionChannel *achan= get_action_channel(act, name);
- IpoCurve *icu;
- NlaIpoChannel *nic;
-
- if(achan==NULL) return;
-
- if(achan->ipo) {
- calc_ipo(achan->ipo, ctime);
-
- for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
- /* skip IPO_BITS, is for layers and cannot be blended */
- if(icu->vartype != IPO_BITS) {
- nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel");
- BLI_addtail(lb, nic);
- nic->val= icu->curval;
- nic->poin= get_ipo_poin(id, icu, &nic->type);
- }
- }
- }
-
- /* constraint channels only for objects */
- if(GS(id->name)==ID_OB) {
- Object *ob= (Object *)id;
- bConstraint *con;
- bConstraintChannel *conchan;
-
- for (con=ob->constraints.first; con; con=con->next) {
- conchan = get_constraint_channel(&achan->constraintChannels, con->name);
-
- if(conchan && conchan->ipo) {
- calc_ipo(conchan->ipo, ctime);
-
- icu= conchan->ipo->curve.first; // only one ipo now
- if(icu) {
- nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel constr");
- BLI_addtail(lb, nic);
- nic->val= icu->curval;
- nic->poin= &con->enforce;
- nic->type= IPO_FLOAT;
- }
- }
- }
- }
-}
-
-static NlaIpoChannel *find_nla_ipochannel(ListBase *lb, void *poin)
-{
- NlaIpoChannel *nic;
-
- if(poin) {
- for(nic= lb->first; nic; nic= nic->next) {
- if(nic->poin==poin)
- return nic;
- }
- }
- return NULL;
-}
-
-
-static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int mode)
-{
- NlaIpoChannel *snic, *dnic, *next;
- float dstweight;
-
- switch (mode){
- case ACTSTRIPMODE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case ACTSTRIPMODE_ADD:
- dstweight = 1.0F;
- break;
- default :
- dstweight = 1.0F;
- }
-
- for(snic= src->first; snic; snic= next) {
- next= snic->next;
-
- dnic= find_nla_ipochannel(dst, snic->poin);
- if(dnic==NULL) {
- /* remove from src list, and insert in dest */
- BLI_remlink(src, snic);
- BLI_addtail(dst, snic);
- }
- else {
- /* we do the blend */
- dnic->val= dstweight*dnic->val + srcweight*snic->val;
- }
- }
-}
-
-int execute_ipochannels(ListBase *lb)
-{
- NlaIpoChannel *nic;
- int count = 0;
-
- for(nic= lb->first; nic; nic= nic->next) {
- if(nic->poin) {
- write_ipo_poin(nic->poin, nic->type, nic->val);
- count++;
- }
- }
- return count;
-}
-
-/* nla timing */
-
-/* this now only used for repeating cycles, to enable fields and blur. */
-/* the whole time control in blender needs serious thinking... */
-static float nla_time(Scene *scene, float cfra, float unit)
-{
- extern float bluroffs; // bad construct, borrowed from object.c for now
- extern float fieldoffs;
-
- /* motion blur & fields */
- cfra+= unit*(bluroffs+fieldoffs);
-
- /* global time */
- cfra*= scene->r.framelen;
-
- return cfra;
-}
-
/* added "sizecorr" here, to allow armatures to be scaled and still have striding.
Only works for uniform scaling. In general I'd advise against scaling armatures ever though! (ton)
*/
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 8cb88cdb786..bd779935d55 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -280,17 +280,27 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
if (quat) {
float totfac, q1[4], q2[4];
+ /* checks for totfac are needed when 'fac' is 1.0 key_curve_position_weights can assign zero
+ * to more then one index in data which can give divide by zero error */
+/*
totfac= data[0]+data[1];
- QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
+ if(totfac>0.000001) QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
+ else QUATCOPY(q1, p1->quat);
+
NormalQuat(q1);
totfac= data[2]+data[3];
- QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
+ if(totfac>0.000001) QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
+ else QUATCOPY(q1, p3->quat);
NormalQuat(q2);
totfac = data[0]+data[1]+data[2]+data[3];
- QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
+ if(totfac>0.000001) QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
+ else QUATCOPY(quat, q2);
NormalQuat(quat);
+ */
+ // XXX - find some way to make quat interpolation work correctly, above code fails in rare but nasty cases.
+ QUATCOPY(quat, p1->quat);
}
if(radius)
@@ -766,12 +776,12 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
GroupObject *go;
Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
DupliObject *dob;
+ ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)};
ParticleSettings *part;
ParticleData *pa;
ChildParticle *cpa=0;
ParticleKey state;
ParticleCacheKey *cache;
- ParticleSystemModifierData *psmd;
float ctime, pa_time, scale = 1.0f;
float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
float (*obmat)[4], (*oldobmat)[4];
@@ -784,7 +794,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
if(level>MAX_DUPLI_RECUR) return;
part=psys->part;
- psmd= psys_get_modifier(par, psys);
if(part==0)
return;
@@ -816,7 +825,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
totpart = psys->totcached;
}
- psys->lattice = psys_get_lattice(scene, par, psys);
+ psys->lattice = psys_get_lattice(&sim);
/* gather list of objects or single object */
if(part->ren_as==PART_DRAW_GR) {
@@ -887,11 +896,11 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
/* hair we handle separate and compute transform based on hair keys */
if(a < totpart) {
cache = psys->pathcache[a];
- psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
+ psys_get_dupli_path_transform(&sim, pa, 0, cache, pamat, &scale);
}
else {
cache = psys->childcache[a-totpart];
- psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
+ psys_get_dupli_path_transform(&sim, 0, cpa, cache, pamat, &scale);
}
VECCOPY(pamat[3], cache->co);
@@ -901,7 +910,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
else {
/* first key */
state.time = ctime;
- if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
+ if(psys_get_particle_state(&sim, a, &state, 0) == 0)
continue;
QuatToMat4(state.rot, pamat);
@@ -921,7 +930,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
Mat4CpyMat4(dob->omat, obcopylist[b].obmat);
if(G.rendering)
- psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
+ psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
}
else {
@@ -940,7 +949,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated);
Mat4CpyMat4(dob->omat, oldobmat);
if(G.rendering)
- psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
+ psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 2d6a97c48ae..ab902bbbae5 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -40,6 +40,7 @@
#include "BLI_dynstr.h"
#include "DNA_anim_types.h"
+#include "DNA_scene_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -71,7 +72,7 @@ static short id_has_animdata (ID *id)
switch (GS(id->name)) {
/* has AnimData */
case ID_OB:
- case ID_MB: case ID_CU:
+ case ID_MB: case ID_CU: case ID_AR:
case ID_KE:
case ID_PA:
case ID_MA: case ID_TE: case ID_NT:
@@ -186,8 +187,6 @@ AnimData *BKE_copy_animdata (AnimData *adt)
dadt= MEM_dupallocN(adt);
/* make a copy of action - at worst, user has to delete copies... */
- // XXX review this... it might not be optimal behaviour yet...
- //id_us_plus((ID *)dadt->action);
dadt->action= copy_action(adt->action);
dadt->tmpact= copy_action(adt->tmpact);
@@ -210,26 +209,113 @@ static void make_local_strips(ListBase *strips)
{
NlaStrip *strip;
- for(strip=strips->first; strip; strip=strip->next) {
- if(strip->act) make_local_action(strip->act);
- if(strip->remap && strip->remap->target) make_local_action(strip->remap->target);
-
+ for (strip=strips->first; strip; strip=strip->next) {
+ if (strip->act) make_local_action(strip->act);
+ //if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
+
make_local_strips(&strip->strips);
}
}
+/* Use local copy instead of linked copy of various ID-blocks */
void BKE_animdata_make_local(AnimData *adt)
{
NlaTrack *nlt;
+
+ /* Actions - Active and Temp */
+ if (adt->action) make_local_action(adt->action);
+ if (adt->tmpact) make_local_action(adt->tmpact);
+ /* Remaps */
+ if (adt->remap && adt->remap->target) make_local_action(adt->remap->target);
+
+ /* Drivers */
+ // TODO: need to remap the ID-targets too?
+
+ /* NLA Data */
+ for (nlt=adt->nla_tracks.first; nlt; nlt=nlt->next)
+ make_local_strips(&nlt->strips);
+}
- if(adt->action) make_local_action(adt->action);
- if(adt->tmpact) make_local_action(adt->tmpact);
- if(adt->remap && adt->remap->target) make_local_action(adt->remap->target);
+/* Path Validation -------------------------------------------- */
- for(nlt=adt->nla_tracks.first; nlt; nlt=nlt->next)
- make_local_strips(&nlt->strips);
+#if 0
+/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */
+static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath)
+{
+
+
+ return oldpath; // FIXME!!!
+}
+
+/* Check RNA-Paths for a list of F-Curves */
+static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *curves)
+{
+ FCurve *fcu;
+
+ /* we need to check every curve... */
+ for (fcu= curves->first; fcu; fcu= fcu->next) {
+ /* firstly, handle the F-Curve's own path */
+ fcu->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, fcu->rna_path);
+
+ /* driver? */
+ if (fcu->driver) {
+ ChannelDriver *driver= fcu->driver;
+ DriverTarget *dtar;
+
+ /* driver targets */
+ for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
+ dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path);
+ }
+ }
+ }
}
+/* Fix all RNA-Paths for Actions linked to NLA Strips */
+static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *strips)
+{
+ NlaStrip *strip;
+
+ /* recursively check strips, fixing only actions... */
+ for (strip= strips->first; strip; strip= strip->next) {
+ /* fix strip's action */
+ if (strip->act)
+ fcurves_path_rename_fix(owner_id, modPtr, newName, &strip->act->curves);
+ /* ignore own F-Curves, since those are local... */
+
+ /* check sub-strips (if metas) */
+ nlastrips_path_rename_fix(owner_id, modPtr, newName, &strip->strips);
+ }
+}
+
+/* Fix all RNA-Paths in the AnimData block used by the given ID block
+ * - the pointer of interest must not have had its new name assigned already, otherwise
+ * path matching for this will never work
+ */
+void BKE_animdata_fix_paths_rename (ID *owner_id, PointerRNA *modPtr, char *newName)
+{
+ AnimData *adt= BKE_animdata_from_id(owner_id);
+ NlaTrack *nlt;
+
+ /* if no AnimData, no need to proceed */
+ if (ELEM4(NULL, owner_id, adt, modPtr, newName))
+ return;
+
+ /* Active action and temp action */
+ if (adt->action)
+ fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->action->curves);
+ if (adt->tmpact)
+ fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->tmpact->curves);
+
+ /* Drivers - Drivers are really F-Curves */
+ fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->drivers);
+
+ /* NLA Data - Animation Data for Strips */
+ for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
+
+ }
+}
+#endif
+
/* *********************************** */
/* KeyingSet API */
@@ -438,7 +524,7 @@ void BKE_keyingsets_free (ListBase *list)
* - path: original path string (as stored in F-Curve data)
* - dst: destination string to write data to
*/
-short animsys_remap_path (AnimMapper *remap, char *path, char **dst)
+static short animsys_remap_path (AnimMapper *remap, char *path, char **dst)
{
/* is there a valid remapping table to use? */
//if (remap) {
@@ -1378,7 +1464,11 @@ static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt, float ct
*
* Unresolved things:
* - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids or nodal system? but stored where?
- * - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
+ * - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
+ *
+ * Current Status:
+ * - Currently (as of September 2009), overrides we haven't needed to (fully) implement overrides.
+ * However, the code fo this is relatively harmless, so is left in the code for now.
*/
/* Evaluation loop for evaluation animation data
@@ -1485,7 +1575,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
}
/* nodes */
- // TODO...
+ EVAL_ANIM_IDS(main->nodetree.first, ADT_RECALC_ANIM);
/* textures */
EVAL_ANIM_IDS(main->tex.first, ADT_RECALC_ANIM);
@@ -1517,10 +1607,16 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
AnimData *adt= BKE_animdata_from_id(id);
Curve *cu= (Curve *)id;
+ /* set ctime variable for curve */
cu->ctime= ctime;
+
+ /* now execute animation data on top of this as per normal */
BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM);
}
+ /* armatures */
+ EVAL_ANIM_IDS(main->armature.first, ADT_RECALC_ANIM);
+
/* meshes */
// TODO...
@@ -1529,15 +1625,28 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
/* objects */
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
- * this tagged by Depsgraph on framechange
+ * this tagged by Depsgraph on framechange. This optimisation means that objects
+ * linked from other (not-visible) scenes will not need their data calculated.
*/
- EVAL_ANIM_IDS(main->object.first, /*ADT_RECALC_ANIM*/0);
+ EVAL_ANIM_IDS(main->object.first, 0);
/* worlds */
EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM);
/* scenes */
- EVAL_ANIM_IDS(main->scene.first, ADT_RECALC_ANIM);
+ for (id= main->scene.first; id; id= id->next) {
+ AnimData *adt= BKE_animdata_from_id(id);
+ Scene *scene= (Scene *)id;
+
+ /* do compositing nodes first (since these aren't included in main tree) */
+ if (scene->nodetree) {
+ AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree);
+ BKE_animsys_evaluate_animdata((ID *)scene->nodetree, adt2, ctime, ADT_RECALC_ANIM);
+ }
+
+ /* now execute scene animation data as per normal */
+ BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM);
+ }
}
/* ***************************************** */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index c880925aa94..6220835a620 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -66,10 +66,9 @@
#include "BKE_object.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "BIK_api.h"
#include "BKE_sketch.h"
-#include "IK_solver.h"
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -1280,6 +1279,65 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float
Mat4MulMat4(delta_mat, pose_mat, imat);
}
+/* **************** Rotation Mode Conversions ****************************** */
+/* Used for Objects and Pose Channels, since both can have multiple rotation representations */
+
+/* Called from RNA when rotation mode changes
+ * - the result should be that the rotations given in the provided pointers have had conversions
+ * applied (as appropriate), such that the rotation of the element hasn't 'visually' changed
+ *
+ * - as in SDNA data, quat is used to store quaternions AND axis-angle rotations...
+ */
+void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, short newMode)
+{
+ /* check if any change - if so, need to convert data */
+ if (newMode > 0) { /* to euler */
+ if (oldMode == ROT_MODE_AXISANGLE) {
+ /* axis-angle to euler */
+ AxisAngleToEulO(&quat[1], quat[0], eul, newMode);
+ }
+ else if (oldMode == ROT_MODE_QUAT) {
+ /* quat to euler */
+ QuatToEulO(quat, eul, newMode);
+ }
+ /* else { no conversion needed } */
+ }
+ else if (newMode == ROT_MODE_QUAT) { /* to quat */
+ if (oldMode == ROT_MODE_AXISANGLE) {
+ /* axis angle to quat */
+ float q[4];
+
+ /* copy to temp var first, since quats and axis-angle are stored in same place */
+ QuatCopy(q, quat);
+ AxisAngleToQuat(q, &quat[1], quat[0]);
+ }
+ else if (oldMode > 0) {
+ /* euler to quat */
+ EulOToQuat(eul, oldMode, quat);
+ }
+ /* else { no conversion needed } */
+ }
+ else { /* to axis-angle */
+ if (oldMode > 0) {
+ /* euler to axis angle */
+ EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]);
+ }
+ else if (oldMode == ROT_MODE_QUAT) {
+ /* quat to axis angle */
+ float q[4];
+
+ /* copy to temp var first, since quats and axis-angle are stored in same place */
+ QuatCopy(q, quat);
+ QuatToAxisAngle(q, &quat[1], &quat[0]);
+ }
+
+ /* when converting to axis-angle, we need a special exception for the case when there is no axis */
+ if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) {
+ /* for now, rotate around y-axis then (so that it simply becomes the roll) */
+ quat[2]= 1.0f;
+ }
+ }
+}
/* **************** The new & simple (but OK!) armature evaluation ********* */
@@ -1569,409 +1627,10 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
DAG_pose_sort(ob);
ob->pose->flag &= ~POSE_RECALC;
+ ob->pose->flag |= POSE_WAS_REBUILT;
}
-/* ********************** THE IK SOLVER ******************* */
-
-
-
-/* allocates PoseTree, and links that to root bone/channel */
-/* Note: detecting the IK chain is duplicate code... in drawarmature.c and in transform_conversions.c */
-static void initialize_posetree(struct Object *ob, bPoseChannel *pchan_tip)
-{
- bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan;
- PoseTree *tree;
- PoseTarget *target;
- bConstraint *con;
- bKinematicConstraint *data= NULL;
- int a, segcount= 0, size, newsize, *oldparent, parent;
-
- /* find IK constraint, and validate it */
- for(con= pchan_tip->constraints.first; con; con= con->next) {
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
- data=(bKinematicConstraint*)con->data;
- if (data->flag & CONSTRAINT_IK_AUTO) break;
- if (data->tar==NULL) continue;
- if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0) continue;
- if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0)) break;
- }
- }
- if(con==NULL) return;
-
- /* exclude tip from chain? */
- if(!(data->flag & CONSTRAINT_IK_TIP))
- pchan_tip= pchan_tip->parent;
-
- /* Find the chain's root & count the segments needed */
- for (curchan = pchan_tip; curchan; curchan=curchan->parent){
- pchan_root = curchan;
-
- curchan->flag |= POSE_CHAIN; // don't forget to clear this
- chanlist[segcount]=curchan;
- segcount++;
-
- if(segcount==data->rootbone || segcount>255) break; // 255 is weak
- }
- if (!segcount) return;
-
- /* setup the chain data */
-
- /* we make tree-IK, unless all existing targets are in this chain */
- for(tree= pchan_root->iktree.first; tree; tree= tree->next) {
- for(target= tree->targets.first; target; target= target->next) {
- curchan= tree->pchan[target->tip];
- if(curchan->flag & POSE_CHAIN)
- curchan->flag &= ~POSE_CHAIN;
- else
- break;
- }
- if(target) break;
- }
-
- /* create a target */
- target= MEM_callocN(sizeof(PoseTarget), "posetarget");
- target->con= con;
- pchan_tip->flag &= ~POSE_CHAIN;
-
- if(tree==NULL) {
- /* make new tree */
- tree= MEM_callocN(sizeof(PoseTree), "posetree");
-
- tree->iterations= data->iterations;
- tree->totchannel= segcount;
- tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);
-
- tree->pchan= MEM_callocN(segcount*sizeof(void*), "ik tree pchan");
- tree->parent= MEM_callocN(segcount*sizeof(int), "ik tree parent");
- for(a=0; a<segcount; a++) {
- tree->pchan[a]= chanlist[segcount-a-1];
- tree->parent[a]= a-1;
- }
- target->tip= segcount-1;
-
- /* AND! link the tree to the root */
- BLI_addtail(&pchan_root->iktree, tree);
- }
- else {
- tree->iterations= MAX2(data->iterations, tree->iterations);
- tree->stretch= tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);
-
- /* skip common pose channels and add remaining*/
- size= MIN2(segcount, tree->totchannel);
- for(a=0; a<size && tree->pchan[a]==chanlist[segcount-a-1]; a++);
- parent= a-1;
-
- segcount= segcount-a;
- target->tip= tree->totchannel + segcount - 1;
-
- if (segcount > 0) {
- /* resize array */
- newsize= tree->totchannel + segcount;
- oldchan= tree->pchan;
- oldparent= tree->parent;
-
- tree->pchan= MEM_callocN(newsize*sizeof(void*), "ik tree pchan");
- tree->parent= MEM_callocN(newsize*sizeof(int), "ik tree parent");
- memcpy(tree->pchan, oldchan, sizeof(void*)*tree->totchannel);
- memcpy(tree->parent, oldparent, sizeof(int)*tree->totchannel);
- MEM_freeN(oldchan);
- MEM_freeN(oldparent);
-
- /* add new pose channels at the end, in reverse order */
- for(a=0; a<segcount; a++) {
- tree->pchan[tree->totchannel+a]= chanlist[segcount-a-1];
- tree->parent[tree->totchannel+a]= tree->totchannel+a-1;
- }
- tree->parent[tree->totchannel]= parent;
-
- tree->totchannel= newsize;
- }
-
- /* move tree to end of list, for correct evaluation order */
- BLI_remlink(&pchan_root->iktree, tree);
- BLI_addtail(&pchan_root->iktree, tree);
- }
-
- /* add target to the tree */
- BLI_addtail(&tree->targets, target);
-}
-
-/* called from within the core where_is_pose loop, all animsystems and constraints
-were executed & assigned. Now as last we do an IK pass */
-static void execute_posetree(Object *ob, PoseTree *tree)
-{
- float R_parmat[3][3], identity[3][3];
- float iR_parmat[3][3];
- float R_bonemat[3][3];
- float goalrot[3][3], goalpos[3];
- float rootmat[4][4], imat[4][4];
- float goal[4][4], goalinv[4][4];
- float irest_basis[3][3], full_basis[3][3];
- float end_pose[4][4], world_pose[4][4];
- float length, basis[3][3], rest_basis[3][3], start[3], *ikstretch=NULL;
- float resultinf=0.0f;
- int a, flag, hasstretch=0, resultblend=0;
- bPoseChannel *pchan;
- IK_Segment *seg, *parent, **iktree, *iktarget;
- IK_Solver *solver;
- PoseTarget *target;
- bKinematicConstraint *data, *poleangledata=NULL;
- Bone *bone;
-
- if (tree->totchannel == 0)
- return;
-
- iktree= MEM_mallocN(sizeof(void*)*tree->totchannel, "ik tree");
-
- for(a=0; a<tree->totchannel; a++) {
- pchan= tree->pchan[a];
- bone= pchan->bone;
-
- /* set DoF flag */
- flag= 0;
- if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP))
- flag |= IK_XDOF;
- if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP))
- flag |= IK_YDOF;
- if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP))
- flag |= IK_ZDOF;
-
- if(tree->stretch && (pchan->ikstretch > 0.0)) {
- flag |= IK_TRANS_YDOF;
- hasstretch = 1;
- }
-
- seg= iktree[a]= IK_CreateSegment(flag);
-
- /* find parent */
- if(a == 0)
- parent= NULL;
- else
- parent= iktree[tree->parent[a]];
-
- IK_SetParent(seg, parent);
-
- /* get the matrix that transforms from prevbone into this bone */
- Mat3CpyMat4(R_bonemat, pchan->pose_mat);
-
- /* gather transformations for this IK segment */
-
- if (pchan->parent)
- Mat3CpyMat4(R_parmat, pchan->parent->pose_mat);
- else
- Mat3One(R_parmat);
-
- /* bone offset */
- if (pchan->parent && (a > 0))
- VecSubf(start, pchan->pose_head, pchan->parent->pose_tail);
- else
- /* only root bone (a = 0) has no parent */
- start[0]= start[1]= start[2]= 0.0f;
-
- /* change length based on bone size */
- length= bone->length*VecLength(R_bonemat[1]);
-
- /* compute rest basis and its inverse */
- Mat3CpyMat3(rest_basis, bone->bone_mat);
- Mat3CpyMat3(irest_basis, bone->bone_mat);
- Mat3Transp(irest_basis);
-
- /* compute basis with rest_basis removed */
- Mat3Inv(iR_parmat, R_parmat);
- Mat3MulMat3(full_basis, iR_parmat, R_bonemat);
- Mat3MulMat3(basis, irest_basis, full_basis);
-
- /* basis must be pure rotation */
- Mat3Ortho(basis);
-
- /* transform offset into local bone space */
- Mat3Ortho(iR_parmat);
- Mat3MulVecfl(iR_parmat, start);
-
- IK_SetTransform(seg, start, rest_basis, basis, length);
-
- if (pchan->ikflag & BONE_IK_XLIMIT)
- IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]);
- if (pchan->ikflag & BONE_IK_YLIMIT)
- IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]);
- if (pchan->ikflag & BONE_IK_ZLIMIT)
- IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]);
-
- IK_SetStiffness(seg, IK_X, pchan->stiffness[0]);
- IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
- IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);
-
- if(tree->stretch && (pchan->ikstretch > 0.0f)) {
- float ikstretch = pchan->ikstretch*pchan->ikstretch;
- IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0f-ikstretch, 0.99f));
- IK_SetLimit(seg, IK_TRANS_Y, 0.001f, 1e10);
- }
- }
-
- solver= IK_CreateSolver(iktree[0]);
-
- /* set solver goals */
-
- /* first set the goal inverse transform, assuming the root of tree was done ok! */
- pchan= tree->pchan[0];
- if (pchan->parent)
- /* transform goal by parent mat, so this rotation is not part of the
- segment's basis. otherwise rotation limits do not work on the
- local transform of the segment itself. */
- Mat4CpyMat4(rootmat, pchan->parent->pose_mat);
- else
- Mat4One(rootmat);
- VECCOPY(rootmat[3], pchan->pose_head);
-
- Mat4MulMat4 (imat, rootmat, ob->obmat);
- Mat4Invert (goalinv, imat);
-
- for (target=tree->targets.first; target; target=target->next) {
- float polepos[3];
- int poleconstrain= 0;
-
- data= (bKinematicConstraint*)target->con->data;
-
- /* 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(target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
-
- /* and set and transform goal */
- Mat4MulMat4(goal, rootmat, goalinv);
-
- VECCOPY(goalpos, goal[3]);
- Mat3CpyMat4(goalrot, goal);
-
- /* same for pole vector target */
- if(data->poletar) {
- get_constraint_target_matrix(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 */
- break;
- }
- else {
- Mat4MulMat4(goal, rootmat, goalinv);
- VECCOPY(polepos, goal[3]);
- poleconstrain= 1;
-
- /* for pole targets, we blend the result of the ik solver
- * instead of the target position, otherwise we can't get
- * a smooth transition */
- resultblend= 1;
- resultinf= target->con->enforce;
-
- if(data->flag & CONSTRAINT_IK_GETANGLE) {
- poleangledata= data;
- data->flag &= ~CONSTRAINT_IK_GETANGLE;
- }
- }
- }
-
- /* do we need blending? */
- if (!resultblend && target->con->enforce!=1.0f) {
- float q1[4], q2[4], q[4];
- float fac= target->con->enforce;
- float mfac= 1.0f-fac;
-
- pchan= tree->pchan[target->tip];
-
- /* end effector in world space */
- Mat4CpyMat4(end_pose, pchan->pose_mat);
- VECCOPY(end_pose[3], pchan->pose_tail);
- Mat4MulSerie(world_pose, goalinv, ob->obmat, end_pose, 0, 0, 0, 0, 0);
-
- /* blend position */
- goalpos[0]= fac*goalpos[0] + mfac*world_pose[3][0];
- goalpos[1]= fac*goalpos[1] + mfac*world_pose[3][1];
- goalpos[2]= fac*goalpos[2] + mfac*world_pose[3][2];
-
- /* blend rotation */
- Mat3ToQuat(goalrot, q1);
- Mat4ToQuat(world_pose, q2);
- QuatInterpol(q, q1, q2, mfac);
- QuatToMat3(q, goalrot);
- }
-
- iktarget= iktree[target->tip];
-
- if(data->weight != 0.0f) {
- if(poleconstrain)
- IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
- polepos, data->poleangle*(float)M_PI/180.0f, (poleangledata == data));
- IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
- }
- if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0f))
- if((data->flag & CONSTRAINT_IK_AUTO)==0)
- IK_SolverAddGoalOrientation(solver, iktarget, goalrot,
- data->orientweight);
- }
-
- /* solve */
- IK_Solve(solver, 0.0f, tree->iterations);
-
- if(poleangledata)
- poleangledata->poleangle= IK_SolverGetPoleAngle(solver)*180.0f/(float)M_PI;
-
- IK_FreeSolver(solver);
-
- /* gather basis changes */
- tree->basis_change= MEM_mallocN(sizeof(float[3][3])*tree->totchannel, "ik basis change");
- if(hasstretch)
- ikstretch= MEM_mallocN(sizeof(float)*tree->totchannel, "ik stretch");
-
- for(a=0; a<tree->totchannel; a++) {
- IK_GetBasisChange(iktree[a], tree->basis_change[a]);
-
- if(hasstretch) {
- /* have to compensate for scaling received from parent */
- float parentstretch, stretch;
-
- pchan= tree->pchan[a];
- parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0f;
-
- if(tree->stretch && (pchan->ikstretch > 0.0f)) {
- float trans[3], length;
-
- IK_GetTranslationChange(iktree[a], trans);
- length= pchan->bone->length*VecLength(pchan->pose_mat[1]);
-
- ikstretch[a]= (length == 0.0f)? 1.0f: (trans[1]+length)/length;
- }
- else
- ikstretch[a] = 1.0f;
-
- stretch= (parentstretch == 0.0f)? 1.0f: ikstretch[a]/parentstretch;
-
- VecMulf(tree->basis_change[a][0], stretch);
- VecMulf(tree->basis_change[a][1], stretch);
- VecMulf(tree->basis_change[a][2], stretch);
- }
-
- if(resultblend && resultinf!=1.0f) {
- Mat3One(identity);
- Mat3BlendMat3(tree->basis_change[a], identity,
- tree->basis_change[a], resultinf);
- }
-
- IK_FreeSegment(iktree[a]);
- }
-
- MEM_freeN(iktree);
- if(ikstretch) MEM_freeN(ikstretch);
-}
-
-void free_posetree(PoseTree *tree)
-{
- BLI_freelistN(&tree->targets);
- if(tree->pchan) MEM_freeN(tree->pchan);
- if(tree->parent) MEM_freeN(tree->parent);
- if(tree->basis_change) MEM_freeN(tree->basis_change);
- MEM_freeN(tree);
-}
-
/* ********************** THE POSE SOLVER ******************* */
@@ -1991,7 +1650,7 @@ void chan_calc_mat(bPoseChannel *chan)
/* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
EulOToMat3(chan->eul, chan->rotmode, rmat);
}
- else if (chan->rotmode == PCHAN_ROT_AXISANGLE) {
+ else if (chan->rotmode == ROT_MODE_AXISANGLE) {
/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat);
}
@@ -2012,41 +1671,6 @@ void chan_calc_mat(bPoseChannel *chan)
}
}
-/* transform from bone(b) to bone(b+1), store in chan_mat */
-static void make_dmats(bPoseChannel *pchan)
-{
- if (pchan->parent) {
- float iR_parmat[4][4];
- Mat4Invert(iR_parmat, pchan->parent->pose_mat);
- Mat4MulMat4(pchan->chan_mat, pchan->pose_mat, iR_parmat); // delta mat
- }
- else Mat4CpyMat4(pchan->chan_mat, pchan->pose_mat);
-}
-
-/* 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
-{
- float vec[3], ikmat[4][4];
-
- Mat4CpyMat3(ikmat, ik_mat);
-
- if (pchan->parent)
- Mat4MulSerie(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat, NULL, NULL, NULL, NULL, NULL);
- else
- Mat4MulMat4(pchan->pose_mat, ikmat, pchan->chan_mat);
-
- /* calculate head */
- VECCOPY(pchan->pose_head, pchan->pose_mat[3]);
- /* calculate tail */
- VECCOPY(vec, pchan->pose_mat[1]);
- VecMulf(vec, pchan->bone->length);
- VecAddf(pchan->pose_tail, pchan->pose_head, vec);
-
- pchan->flag |= POSE_DONE;
-}
-
/* NLA strip modifiers */
static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseChannel *pchan)
{
@@ -2172,7 +1796,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
/* The main armature solver, does all constraints excluding IK */
/* pchan is validated, as having bone and parent pointer */
-static void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime)
+void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime)
{
Bone *bone, *parbone;
bPoseChannel *parchan;
@@ -2312,48 +1936,27 @@ void where_is_pose (Scene *scene, Object *ob)
else {
Mat4Invert(ob->imat, ob->obmat); // imat is needed
- /* 1. construct the PoseTrees, clear flags */
+ /* 1. clear flags */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- pchan->flag &= ~(POSE_DONE|POSE_CHAIN);
- if(pchan->constflag & PCHAN_HAS_IK) // flag is set on editing constraints
- initialize_posetree(ob, pchan); // will attach it to root!
+ pchan->flag &= ~(POSE_DONE|POSE_CHAIN|POSE_IKTREE);
}
-
- /* 2. the main loop, channels are already hierarchical sorted from root to children */
+ /* 2. construct the IK tree */
+ BIK_initialize_tree(scene, ob, ctime);
+
+ /* 3. the main loop, channels are already hierarchical sorted from root to children */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- /* 3. if we find an IK root, we handle it separated */
- if(pchan->iktree.first) {
- while(pchan->iktree.first) {
- PoseTree *tree= pchan->iktree.first;
- int a;
-
- /* 4. walk over the tree for regular solving */
- for(a=0; a<tree->totchannel; a++) {
- if(!(tree->pchan[a]->flag & POSE_DONE)) // successive trees can set the flag
- where_is_pose_bone(scene, ob, tree->pchan[a], ctime);
- }
- /* 5. execute the IK solver */
- execute_posetree(ob, tree);
-
- /* 6. apply the differences to the channels,
- we need to calculate the original differences first */
- for(a=0; a<tree->totchannel; a++)
- make_dmats(tree->pchan[a]);
-
- for(a=0; a<tree->totchannel; a++)
- /* sets POSE_DONE */
- where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
-
- /* 7. and free */
- BLI_remlink(&pchan->iktree, tree);
- free_posetree(tree);
- }
+ /* 4. if we find an IK root, we handle it separated */
+ if(pchan->flag & POSE_IKTREE) {
+ BIK_execute_tree(scene, ob, pchan, ctime);
}
+ /* 5. otherwise just call the normal solver */
else if(!(pchan->flag & POSE_DONE)) {
where_is_pose_bone(scene, ob, pchan, ctime);
}
}
+ /* 6. release the IK tree */
+ BIK_release_tree(scene, ob, ctime);
}
/* calculating deform matrices */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 18f065b59d9..76824d3a34a 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -47,6 +47,7 @@
#include "BLI_blenlib.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
+#include "BKE_collision.h"
#include "BKE_effect.h"
#include "BKE_boids.h"
#include "BKE_particle.h"
@@ -72,112 +73,91 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
{
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule;
BoidSettings *boids = bbd->part->boids;
- ParticleEffectorCache *ec;
Object *priority_ob = NULL;
BoidParticle *bpa = pa->boid;
+ EffectedPoint epoint;
+ ListBase *effectors = bbd->sim->psys->effectors;
+ EffectorCache *cur, *eff = NULL;
+ EffectorData efd, cur_efd;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
float priority = 0.0f, len = 0.0f;
int ret = 0;
- /* first find out goal/predator with highest priority */
- /* if rule->ob specified use it */
- if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
- PartDeflect *pd = gabr->ob->pd;
- float vec_to_part[3];
-
- if(pd && pd->forcefield == PFIELD_BOID) {
- effector_find_co(bbd->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL);
-
- VecSubf(vec_to_part, pa->prev_state.co, loc);
+ pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
- priority = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
- }
- else
- priority = 1.0;
-
- priority = 1.0;
- priority_ob = gabr->ob;
- }
- else for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
- if(ec->type & PSYS_EC_EFFECTOR) {
- Object *eob = ec->ob;
- PartDeflect *pd = eob->pd;
-
- /* skip current object */
- if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
- continue;
-
- if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) {
- float vec_to_part[3], temp;
-
- effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL);
-
- VecSubf(vec_to_part, pa->prev_state.co, loc);
-
- temp = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
-
- if(temp == 0.0f)
- ; /* do nothing */
- else if(temp > priority) {
- priority = temp;
- priority_ob = eob;
- len = VecLength(vec_to_part);
- }
- /* choose closest object with same priority */
- else if(temp == priority) {
- float len2 = VecLength(vec_to_part);
-
- if(len2 < len) {
- priority_ob = eob;
- len = len2;
- }
+ /* first find out goal/predator with highest priority */
+ if(effectors) for(cur = effectors->first; cur; cur=cur->next) {
+ Object *eob = cur->ob;
+ PartDeflect *pd = cur->pd;
+
+ if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
+ if(gabr->ob == eob) {
+ /* TODO: objects without any effector and effectors with multiple points */
+ if(get_effector_data(cur, &efd, &epoint, 0)) {
+ if(cur->pd && cur->pd->forcefield == PFIELD_BOID)
+ priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights);
+ else
+ priority = 1.0;
+
+ eff = cur;
}
+ break;
+ }
+ }
+ else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
+ ; /* skip current object */
+ else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(eff, &efd, &epoint, 0)) {
+ float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights);
+
+ if(temp == 0.0f)
+ ; /* do nothing */
+ else if(temp > priority) {
+ priority = temp;
+ eff = cur;
+ efd = cur_efd;
+ len = efd.distance;
+ }
+ /* choose closest object with same priority */
+ else if(temp == priority && efd.distance < len) {
+ eff = cur;
+ efd = cur_efd;
+ len = efd.distance;
}
}
}
/* then use that effector */
if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */
- Object *eob = priority_ob;
+ Object *eob = eff->ob;
PartDeflect *pd = eob->pd;
- float vec_to_part[3];
- float surface = 0.0f;
- float nor[3];
+ float surface = pd->shape == PFIELD_SHAPE_SURFACE ? 1.0f : 0.0f;
if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
/* estimate future location of target */
- surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL);
-
- VecSubf(vec_to_part, pa->prev_state.co, loc);
- len = Normalize(vec_to_part);
+ get_effector_data(eff, &efd, &epoint, 1);
- VecMulf(vec, len / (val->max_speed * bbd->timestep));
- VecAddf(loc, loc, vec);
- VecSubf(vec_to_part, pa->prev_state.co, loc);
- }
- else {
- surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL);
-
- VecSubf(vec_to_part, pa->prev_state.co, loc);
- len = VecLength(vec_to_part);
+ VecMulf(efd.vel, efd.distance / (val->max_speed * bbd->timestep));
+ VecAddf(efd.loc, efd.loc, efd.vel);
+ VecSubf(efd.vec_to_point, pa->prev_state.co, efd.loc);
+ efd.distance = VecLength(efd.vec_to_point);
}
if(rule->type == eBoidRuleType_Goal && boids->options & BOID_ALLOW_CLIMB && surface!=0.0f) {
if(!bbd->goal_ob || bbd->goal_priority < priority) {
bbd->goal_ob = eob;
- VECCOPY(bbd->goal_co, loc);
- VECCOPY(bbd->goal_nor, nor);
+ VECCOPY(bbd->goal_co, efd.loc);
+ VECCOPY(bbd->goal_nor, efd.nor);
}
}
else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
priority > 2.0f * gabr->fear_factor) {
/* detach from surface and try to fly away from danger */
- VECCOPY(vec_to_part, bpa->gravity);
- VecMulf(vec_to_part, -1.0f);
+ VECCOPY(efd.vec_to_point, bpa->gravity);
+ VecMulf(efd.vec_to_point, -1.0f);
}
- VECCOPY(bbd->wanted_co, vec_to_part);
+ VECCOPY(bbd->wanted_co, efd.vec_to_point);
VecMulf(bbd->wanted_co, mul);
bbd->wanted_speed = val->max_speed * priority;
@@ -188,8 +168,8 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
surface *= pa->size * boids->height;
- if(len2 > 0.0f && len - surface < len2) {
- len2 = (len - surface)/len2;
+ if(len2 > 0.0f && efd.distance - surface < len2) {
+ len2 = (efd.distance - surface)/len2;
bbd->wanted_speed *= pow(len2, boids->landing_smoothness);
}
}
@@ -204,9 +184,9 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
{
BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision*) rule;
KDTreeNearest *ptn = NULL;
- ParticleEffectorCache *ec;
ParticleTarget *pt;
BoidParticle *bpa = pa->boid;
+ ColliderCache *coll;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float co1[3], vel1[3], co2[3], vel2[3];
float len, t, inp, t_min = 2.0f;
@@ -214,7 +194,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
int ret = 0;
//check deflector objects first
- if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS) {
+ if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) {
ParticleCollision col;
BVHTreeRayHit hit;
float radius = val->personal_space * pa->size, ray_dir[3];
@@ -228,20 +208,16 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
hit.dist = col.ray_len = VecLength(ray_dir);
/* find out closest deflector object */
- for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
- if(ec->type & PSYS_EC_DEFLECT) {
- Object *eob = ec->ob;
-
- /* don't check with current ground object */
- if(eob == bpa->ground)
- continue;
+ for(coll = bbd->sim->colliders->first; coll; coll=coll->next) {
+ /* don't check with current ground object */
+ if(coll->ob == bpa->ground)
+ continue;
- col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
- col.ob_t = eob;
+ col.ob = coll->ob;
+ col.md = coll->collmd;
- if(col.md && col.md->bvhtree)
- BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
- }
+ if(col.md && col.md->bvhtree)
+ BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
/* then avoid that object */
if(hit.index>=0) {
@@ -261,12 +237,12 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
//check boids in own system
if(acbr->options & BRULE_ACOLL_WITH_BOIDS)
{
- neighbors = BLI_kdtree_range_search(bbd->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
+ neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
if(neighbors > 1) for(n=1; n<neighbors; n++) {
VECCOPY(co1, pa->prev_state.co);
VECCOPY(vel1, pa->prev_state.vel);
- VECCOPY(co2, (bbd->psys->particles + ptn[n].index)->prev_state.co);
- VECCOPY(vel2, (bbd->psys->particles + ptn[n].index)->prev_state.vel);
+ VECCOPY(co2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.co);
+ VECCOPY(vel2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.vel);
VecSubf(loc, co1, co2);
@@ -303,8 +279,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
if(ptn){ MEM_freeN(ptn); ptn=NULL; }
/* check boids in other systems */
- for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
- ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
+ for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
+ ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
if(epsys) {
neighbors = BLI_kdtree_range_search(epsys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
@@ -362,11 +338,11 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
ParticleTarget *pt;
float len = 2.0f * val->personal_space * pa->size + 1.0f;
float vec[3] = {0.0f, 0.0f, 0.0f};
- int neighbors = BLI_kdtree_range_search(bbd->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
+ int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
int ret = 0;
if(neighbors > 1 && ptn[1].dist!=0.0f) {
- VecSubf(vec, pa->prev_state.co, bbd->psys->particles[ptn[1].index].state.co);
+ VecSubf(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co);
VecMulf(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist);
VecAddf(bbd->wanted_co, bbd->wanted_co, vec);
bbd->wanted_speed = val->max_speed;
@@ -376,8 +352,8 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
if(ptn){ MEM_freeN(ptn); ptn=NULL; }
/* check other boid systems */
- for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
- ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
+ for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
+ ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
if(epsys) {
neighbors = BLI_kdtree_range_search(epsys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
@@ -400,14 +376,14 @@ static int rule_flock(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
{
KDTreeNearest ptn[11];
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
- int neighbors = BLI_kdtree_find_n_nearest(bbd->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn);
+ int neighbors = BLI_kdtree_find_n_nearest(bbd->sim->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn);
int n;
int ret = 0;
if(neighbors > 1) {
for(n=1; n<neighbors; n++) {
- VecAddf(loc, loc, bbd->psys->particles[ptn[n].index].prev_state.co);
- VecAddf(vec, vec, bbd->psys->particles[ptn[n].index].prev_state.vel);
+ VecAddf(loc, loc, bbd->sim->psys->particles[ptn[n].index].prev_state.co);
+ VecAddf(vec, vec, bbd->sim->psys->particles[ptn[n].index].prev_state.vel);
}
VecMulf(loc, 1.0f/((float)neighbors - 1.0f));
@@ -429,8 +405,8 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader*) rule;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float mul, len;
- int n = (flbr->queue_size <= 1) ? bbd->psys->totpart : flbr->queue_size;
- int i, ret = 0, p = pa - bbd->psys->particles;
+ int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
+ int i, ret = 0, p = pa - bbd->sim->psys->particles;
if(flbr->ob) {
float vec2[3], t;
@@ -475,8 +451,8 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
/* not blocking so try to follow leader */
if(p && flbr->options & BRULE_LEADER_IN_LINE) {
- VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel);
- VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co);
+ VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel);
+ VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co);
}
else {
VECCOPY(loc, flbr->oloc);
@@ -496,10 +472,10 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
float vec2[3], t, t_min = 3.0f;
/* first check we're not blocking any leaders */
- for(i = 0; i< bbd->psys->totpart; i+=n){
- VECCOPY(vec, bbd->psys->particles[i].prev_state.vel);
+ for(i = 0; i< bbd->sim->psys->totpart; i+=n){
+ VECCOPY(vec, bbd->sim->psys->particles[i].prev_state.vel);
- VecSubf(loc, pa->prev_state.co, bbd->psys->particles[i].prev_state.co);
+ VecSubf(loc, pa->prev_state.co, bbd->sim->psys->particles[i].prev_state.co);
mul = Inpf(vec, vec);
@@ -539,12 +515,12 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
/* not blocking so try to follow leader */
if(flbr->options & BRULE_LEADER_IN_LINE) {
- VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel);
- VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co);
+ VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel);
+ VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co);
}
else {
- VECCOPY(vec, bbd->psys->particles[p - p%n].prev_state.vel);
- VECCOPY(loc, bbd->psys->particles[p - p%n].prev_state.co);
+ VECCOPY(vec, bbd->sim->psys->particles[p - p%n].prev_state.vel);
+ VECCOPY(loc, bbd->sim->psys->particles[p - p%n].prev_state.co);
}
/* fac is seconds behind leader */
@@ -584,7 +560,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
/* leveling */
if(asbr->level > 0.0f) {
- Projf(vec, bbd->wanted_co, bbd->psys->part->acc);
+ Projf(vec, bbd->wanted_co, bbd->sim->psys->part->acc);
VecMulf(vec, asbr->level);
VecSubf(bbd->wanted_co, bbd->wanted_co, vec);
}
@@ -601,7 +577,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
/* leveling */
if(asbr->level > 0.0f) {
- Projf(vec, bbd->wanted_co, bbd->psys->part->acc);
+ Projf(vec, bbd->wanted_co, bbd->sim->psys->part->acc);
VecMulf(vec, asbr->level);
VecSubf(bbd->wanted_co, bbd->wanted_co, vec);
}
@@ -627,9 +603,9 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
int n, ret = 0;
/* calculate own group strength */
- int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
+ int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
for(n=0; n<neighbors; n++) {
- bpa = bbd->psys->particles[ptn[n].index].boid;
+ bpa = bbd->sim->psys->particles[ptn[n].index].boid;
health += bpa->data.health;
}
@@ -638,8 +614,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
if(ptn){ MEM_freeN(ptn); ptn=NULL; }
/* add other friendlies and calculate enemy strength and find closest enemy */
- for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
- ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
+ for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
+ ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
if(epsys) {
epars = epsys->particles;
@@ -756,25 +732,28 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
if(bpa->data.mode == eBoidMode_Climbing) {
SurfaceModifierData *surmd = NULL;
float x[3], v[3];
-
+
surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface );
/* take surface velocity into account */
- effector_find_co(bbd->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL);
+ closest_point_on_surface(surmd, pa->state.co, x, NULL, v);
VecAddf(x, x, v);
/* get actual position on surface */
- effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
+ closest_point_on_surface(surmd, x, ground_co, ground_nor, NULL);
return bpa->ground;
}
else {
float zvec[3] = {0.0f, 0.0f, 2000.0f};
ParticleCollision col;
+ ColliderCache *coll;
BVHTreeRayHit hit;
- ParticleEffectorCache *ec;
float radius = 0.0f, t, ray_dir[3];
+ if(!bbd->sim->colliders)
+ return NULL;
+
VECCOPY(col.co1, pa->state.co);
VECCOPY(col.co2, pa->state.co);
VecAddf(col.co1, col.co1, zvec);
@@ -785,16 +764,12 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
hit.dist = col.ray_len = VecLength(ray_dir);
/* find out upmost deflector object */
- for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
- if(ec->type & PSYS_EC_DEFLECT) {
- Object *eob = ec->ob;
+ for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
+ col.ob = coll->ob;
+ col.md = coll->collmd;
- col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
- col.ob_t = eob;
-
- if(col.md && col.md->bvhtree)
- BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
- }
+ if(col.md && col.md->bvhtree)
+ BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
/* then use that object */
if(hit.index>=0) {
@@ -802,7 +777,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
VecLerpf(ground_co, col.co1, col.co2, t);
VECCOPY(ground_nor, col.nor);
Normalize(ground_nor);
- return col.ob;
+ return col.hit_ob;
}
else {
/* default to z=0 */
@@ -941,7 +916,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f;
/* create random seed for every particle & frame */
- BLI_srandom(bbd->psys->seed + p);
+ BLI_srandom(bbd->sim->psys->seed + p);
rand = BLI_rand();
BLI_srandom((int)bbd->cfra + rand);
@@ -1068,6 +1043,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
BoidSettings *boids = bbd->part->boids;
BoidParticle *bpa = pa->boid;
BoidValues val;
+ EffectedPoint epoint;
float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3];
float dvec[3], bvec[3];
float new_dir[3], new_speed;
@@ -1077,7 +1053,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f};
float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep;
- int p = pa - bbd->psys->particles;
+ int p = pa - bbd->sim->psys->particles;
set_boid_values(&val, boids, pa);
@@ -1208,7 +1184,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
}
/* account for effectors */
- do_effectors(p, pa, &pa->state, bbd->scene, bbd->ob, bbd->psys, pa->state.co, force, tvel, bbd->dfra, bbd->cfra);
+ pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
+ pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL);
if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
float length = Normalize(force);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index bce4e1120be..115d31b587c 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -44,6 +44,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_rand.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
@@ -78,7 +79,7 @@ Brush *add_brush(const char *name)
brush->smooth_stroke_radius= 75;
brush->smooth_stroke_factor= 0.9;
brush->rate= 0.1f;
- brush->innerradius= 0.5f;
+ brush->jitter= 0.0f;
brush->clone.alpha= 0.5;
brush->sculpt_tool = SCULPT_TOOL_DRAW;
@@ -379,36 +380,6 @@ void brush_check_exists(Brush **brush, const char *name)
}
/* Brush Sampling */
-
-/*static float taylor_approx_cos(float f)
-{
- f = f*f;
- f = 1.0f - f/2.0f + f*f/24.0f;
- return f;
-}*/
-
-float brush_sample_falloff(Brush *brush, float dist)
-{
- float a, outer, inner;
-
- outer = brush->size >> 1;
- inner = outer*brush->innerradius;
-
- if (dist <= inner) {
- return brush->alpha;
- }
- else if ((dist < outer) && (inner < outer)) {
- a = sqrt((dist - inner)/(outer - inner));
- return (1 - a)*brush->alpha;
-
- /* formula used by sculpt, with taylor approx
- a = 0.5f*(taylor_approx_cos(3.0f*(dist - inner)/(outer - inner)) + 1.0f);
- return a*brush->alpha; */
- }
- else
- return 0.0f;
-}
-
void brush_sample_tex(Brush *brush, float *xy, float *rgba)
{
MTex *mtex= brush->mtex[brush->texact];
@@ -446,6 +417,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o
ImBuf *ibuf;
float xy[2], dist, rgba[4], *dstf;
int x, y, rowbytes, xoff, yoff, imbflag;
+ int maxsize = brush->size >> 1;
char *dst, crgb[3];
imbflag= (flt)? IB_rectfloat: IB_rect;
@@ -470,7 +442,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
VECCOPY(dstf, brush->rgb);
- dstf[3]= brush_sample_falloff(brush, dist);
+ dstf[3]= brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
}
else if (texfall == 1) {
brush_sample_tex(brush, xy, dstf);
@@ -483,7 +455,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o
dstf[0] = rgba[0]*brush->rgb[0];
dstf[1] = rgba[1]*brush->rgb[1];
dstf[2] = rgba[2]*brush->rgb[2];
- dstf[3] = rgba[3]*brush_sample_falloff(brush, dist);
+ dstf[3] = rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
}
}
}
@@ -506,7 +478,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o
dst[0]= crgb[0];
dst[1]= crgb[1];
dst[2]= crgb[2];
- dst[3]= FTOCHAR(brush_sample_falloff(brush, dist));
+ dst[3]= FTOCHAR(brush->alpha*brush_curve_strength(brush, dist, maxsize));
}
else if (texfall == 1) {
brush_sample_tex(brush, xy, rgba);
@@ -522,7 +494,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o
dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]);
dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]);
dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]);
- dst[3] = FTOCHAR(rgba[3]*brush_sample_falloff(brush, dist));
+ dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize));
}
}
}
@@ -542,7 +514,7 @@ typedef struct BrushPainterCache {
int lastsize;
float lastalpha;
- float lastinnerradius;
+ float lastjitter;
ImBuf *ibuf;
ImBuf *texibuf;
@@ -567,7 +539,7 @@ struct BrushPainter {
float startsize;
float startalpha;
- float startinnerradius;
+ float startjitter;
float startspacing;
BrushPainterCache cache;
@@ -583,7 +555,7 @@ BrushPainter *brush_painter_new(Brush *brush)
painter->startsize = brush->size;
painter->startalpha = brush->alpha;
- painter->startinnerradius = brush->innerradius;
+ painter->startjitter = brush->jitter;
painter->startspacing = brush->spacing;
return painter;
@@ -617,7 +589,7 @@ void brush_painter_free(BrushPainter *painter)
brush->size = painter->startsize;
brush->alpha = painter->startalpha;
- brush->innerradius = painter->startinnerradius;
+ brush->jitter = painter->startjitter;
brush->spacing = painter->startspacing;
if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
@@ -711,7 +683,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
}
}
-void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
+static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
{
Brush *brush= painter->brush;
BrushPainterCache *cache= &painter->cache;
@@ -773,7 +745,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
short flt;
if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha)
- || (brush->innerradius != cache->lastinnerradius)) {
+ || (brush->jitter != cache->lastjitter)) {
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
cache->ibuf= NULL;
@@ -798,7 +770,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
cache->lastsize= brush->size;
cache->lastalpha= brush->alpha;
- cache->lastinnerradius= brush->innerradius;
+ cache->lastjitter= brush->jitter;
}
else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
@@ -820,20 +792,34 @@ static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pres
brush->alpha = MAX2(0.0, painter->startalpha*pressure);
if (brush->flag & BRUSH_SIZE_PRESSURE)
brush->size = MAX2(1.0, painter->startsize*pressure);
- if (brush->flag & BRUSH_RAD_PRESSURE)
- brush->innerradius = MAX2(0.0, painter->startinnerradius*pressure);
+ if (brush->flag & BRUSH_JITTER_PRESSURE)
+ brush->jitter = MAX2(0.0, painter->startjitter*pressure);
if (brush->flag & BRUSH_SPACING_PRESSURE)
brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure));
}
+static void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
+{
+ if(brush->jitter){
+ jitterpos[0] = pos[0] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
+ jitterpos[1] = pos[1] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
+ }
+ else {
+ VECCOPY2D(jitterpos, pos);
+ }
+}
+
int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
{
Brush *brush= painter->brush;
int totpaintops= 0;
- if (pressure == 0.0f)
- pressure = 1.0f; /* zero pressure == not using tablet */
-
+ 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];
@@ -884,7 +870,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
}
#endif
else {
- float startdistance, spacing, step, paintpos[2], dmousepos[2];
+ float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
float t, len, press;
/* compute brush spacing adapted to brush size, spacing may depend
@@ -909,11 +895,13 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush_apply_pressure(painter, brush, press);
spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f;
+ brush_jitter_pos(brush, paintpos, finalpos);
+
if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, paintpos);
+ brush_painter_refresh_cache(painter, finalpos);
totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, paintpos);
+ func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
painter->lastpaintpos[0]= paintpos[0];
painter->lastpaintpos[1]= paintpos[1];
@@ -936,10 +924,14 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
while (painter->accumtime >= brush->rate) {
brush_apply_pressure(painter, brush, pressure);
+
+ brush_jitter_pos(brush, pos, finalpos);
+
if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, paintpos);
+ brush_painter_refresh_cache(painter, finalpos);
+
totpaintops +=
- func(user, painter->cache.ibuf, painter->lastmousepos, pos);
+ func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
painter->accumtime -= brush->rate;
}
@@ -953,17 +945,30 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush->alpha = painter->startalpha;
brush->size = painter->startsize;
- brush->innerradius = painter->startinnerradius;
+ 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 brush_curve_strength_clamp(Brush *br, float p, const float len)
+{
+ if(p >= len) p= 1.0f;
+ else p= p/len;
+
+ p= curvemapping_evaluateF(br->curve, 0, p);
+ if(p < 0.0) p= 0.0f;
+ else if(p > 1.0f) p= 1.0f;
+ return p;
+}
+/* same as above but can return negative values if the curve enables
+ * used for sculpt only */
float brush_curve_strength(Brush *br, float p, const float len)
{
- if(p > len) p= len;
- return curvemapping_evaluateF(br->curve, 0, p/len);
+ if(p >= len) p= 1.0f;
+ else p= p/len;
+ return curvemapping_evaluateF(br->curve, 0, p);
}
/* TODO: should probably be unified with BrushPainter stuff? */
@@ -1030,7 +1035,7 @@ static struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
for(i=0; i<side; ++i) {
for(j=0; j<side; ++j) {
float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
- im->rect_float[i*side + j]= brush_curve_strength(br, magn, half);
+ im->rect_float[i*side + j]= brush_curve_strength_clamp(br, magn, half);
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index d25c329f49f..74f88a77e63 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -95,7 +95,7 @@ static CM_SOLVER_DEF solvers [] =
static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm);
static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
+static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
@@ -153,9 +153,12 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->defgoal = 0.0f;
clmd->sim_parms->goalspring = 1.0f;
clmd->sim_parms->goalfrict = 0.0f;
+
+ if(!clmd->sim_parms->effector_weights)
+ clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
}
-BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
+static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
{
unsigned int i;
BVHTree *bvhtree;
@@ -196,7 +199,7 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
return bvhtree;
}
-BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
+static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
{
unsigned int i;
BVHTree *bvhtree;
@@ -402,6 +405,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
VECCOPY(verts->xconst, mvert[i].co);
Mat4MulVecfl(ob->obmat, verts->xconst);
}
+
+ effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights);
tstart();
@@ -411,6 +416,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
tend();
+ pdEndEffectors(&effectors);
+
// printf ( "%f\n", ( float ) tval() );
return ret;
@@ -998,7 +1005,7 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
return 0;
}
-void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
+static void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
{
unsigned int i = 0;
@@ -1031,7 +1038,7 @@ void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgeli
BLI_edgehash_free ( cloth->edgehash, NULL );
}
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
+static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
{
Cloth *cloth = clmd->clothObject;
ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
@@ -1160,25 +1167,66 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
BLI_linklist_prepend ( &cloth->springs, spring );
}
- // bending springs
- search2 = cloth->springs;
- for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
- {
- if ( !search2 )
- break;
+ if(numfaces) {
+ // bending springs
+ search2 = cloth->springs;
+ for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
+ {
+ if ( !search2 )
+ break;
- tspring2 = search2->link;
- search = edgelist[tspring2->kl];
- while ( search )
+ tspring2 = search2->link;
+ search = edgelist[tspring2->kl];
+ while ( search )
+ {
+ tspring = search->link;
+ index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) );
+
+ // check for existing spring
+ // check also if startpoint is equal to endpoint
+ if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) )
+ && ( index2!=tspring2->ij ) )
+ {
+ spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if(!spring)
+ {
+ cloth_free_errorsprings(cloth, edgehash, edgelist);
+ return 0;
+ }
+
+ spring->ij = MIN2(tspring2->ij, index2);
+ spring->kl = MAX2(tspring2->ij, index2);
+ VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ spring->restlen = sqrt ( INPR ( temp, temp ) );
+ spring->type = CLOTH_SPRING_TYPE_BENDING;
+ spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
+ BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL );
+ bend_springs++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
+ }
+ search = search->next;
+ }
+ search2 = search2->next;
+ }
+ }
+ else if(struct_springs > 2) {
+ /* bending springs for hair strands */
+ /* The current algorightm only goes through the edges in order of the mesh edges list */
+ /* and makes springs between the outer vert of edges sharing a vertice. This works just */
+ /* fine for hair, but not for user generated string meshes. This could/should be later */
+ /* extended to work with non-ordered edges so that it can be used for general "rope */
+ /* dynamics" without the need for the vertices or edges to be ordered through the length*/
+ /* of the strands. -jahka */
+ search = cloth->springs;
+ search2 = search->next;
+ while(search && search2)
{
tspring = search->link;
- index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) );
-
- // check for existing spring
- // check also if startpoint is equal to endpoint
- if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) )
- && ( index2!=tspring2->ij ) )
- {
+ tspring2 = search2->link;
+
+ if(tspring->ij == tspring2->kl) {
spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
if(!spring)
@@ -1187,20 +1235,20 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
return 0;
}
- spring->ij = MIN2(tspring2->ij, index2);
- spring->kl = MAX2(tspring2->ij, index2);
+ spring->ij = tspring2->ij;
+ spring->kl = tspring->kl;
VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
- BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL );
bend_springs++;
BLI_linklist_prepend ( &cloth->springs, spring );
}
+
search = search->next;
+ search2 = search2->next;
}
- search2 = search2->next;
}
/* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 37e9c93a108..8c664bc1a57 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -45,9 +45,9 @@
#include "BKE_modifier.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
-
+#ifdef USE_BULLET
#include "Bullet-C-Api.h"
-
+#endif
#include "BLI_kdopbvh.h"
#include "BKE_collision.h"
@@ -313,7 +313,7 @@ gsl_poly_solve_quadratic (double a, double b, double c,
* See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation"
* page 4, left column
*/
-int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] )
+static int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] )
{
int num_sols = 0;
@@ -427,7 +427,7 @@ int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3
// w3 is not perfect
-void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
+static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
{
double tempV1[3], tempV2[3], tempV4[3];
double a,b,c,d,e,f;
@@ -726,7 +726,7 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap
return collpair;
}
-int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
{
int result = 0;
Cloth *cloth1;
@@ -891,7 +891,7 @@ static void findClosestPointsEE(float *x1, float *x2, float *x3, float *x4, floa
}
// calculates the distance of 2 edges
-float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal)
+static float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal)
{
float line1[3], line2[3], cross[3];
float length;
@@ -1065,7 +1065,7 @@ float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3
return 0;
}
-int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
+static int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
{
EdgeCollPair edgecollpair;
Cloth *cloth1=NULL;
@@ -1275,7 +1275,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat
return result;
}
-int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+static int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
{
Cloth *cloth1;
cloth1 = clmd->clothObject;
@@ -1296,15 +1296,15 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col
// return all collision objects in scene
// collision object will exclude self
-CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *numcollobj)
+Object **get_collisionobjects(Scene *scene, Object *self, int *numcollobj)
{
Base *base=NULL;
- CollisionModifierData **objs = NULL;
+ Object **objs = NULL;
Object *coll_ob = NULL;
CollisionModifierData *collmd = NULL;
int numobj = 0, maxobj = 100;
- objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ objs = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
// check all collision objects
for ( base = scene->base.first; base; base = base->next )
{
@@ -1330,16 +1330,16 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu
{
// realloc
int oldmax = maxobj;
- CollisionModifierData **tmp;
+ Object **tmp;
maxobj *= 2;
- tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
- memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(Object *)*oldmax);
MEM_freeN(objs);
objs = tmp;
}
- objs[numobj] = collmd;
+ objs[numobj] = coll_ob;
numobj++;
}
else
@@ -1374,15 +1374,15 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu
{
// realloc
int oldmax = maxobj;
- CollisionModifierData **tmp;
+ Object **tmp;
maxobj *= 2;
- tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
- memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(Object *)*oldmax);
MEM_freeN(objs);
objs = tmp;
}
- objs[numobj] = collmd;
+ objs[numobj] = coll_ob;
numobj++;
}
}
@@ -1392,7 +1392,98 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu
return objs;
}
-void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+ListBase *get_collider_cache(Scene *scene, Object *self)
+{
+ Base *base=NULL;
+ ListBase *objs = NULL;
+ Object *coll_ob = NULL;
+ CollisionModifierData *collmd = NULL;
+ ColliderCache *col;
+
+ // check all collision objects
+ for ( base = scene->base.first; base; base = base->next )
+ {
+ /*Only proceed for mesh object in same layer */
+ if(base->object->type!=OB_MESH)
+ continue;
+
+ if(self && (base->lay & self->lay)==0)
+ continue;
+
+
+ coll_ob = base->object;
+
+ if(coll_ob == self)
+ continue;
+
+ if(coll_ob->pd && coll_ob->pd->deflect)
+ {
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+ }
+ else
+ collmd = NULL;
+
+ if ( collmd )
+ {
+ if(objs == NULL)
+ objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+
+ col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = coll_ob;
+ col->collmd = collmd;
+ /* make sure collider is properly set up */
+ collision_move_object(collmd, 1.0, 0.0);
+ BLI_addtail(objs, col);
+ }
+ else if ( coll_ob->dup_group )
+ {
+ GroupObject *go;
+ Group *group = coll_ob->dup_group;
+
+ for ( go= group->gobject.first; go; go= go->next )
+ {
+ coll_ob = go->ob;
+ collmd = NULL;
+
+ if(coll_ob == self)
+ continue;
+
+ if(coll_ob->pd && coll_ob->pd->deflect)
+ {
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+ }
+ else
+ collmd = NULL;
+
+ if ( !collmd )
+ continue;
+
+ if( !collmd->bvhtree)
+ continue;
+
+ if(objs == NULL)
+ objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+
+ col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = coll_ob;
+ col->collmd = collmd;
+ /* make sure collider is properly set up */
+ collision_move_object(collmd, 1.0, 0.0);
+ BLI_addtail(objs, col);
+ }
+ }
+ }
+ return objs;
+}
+void free_collider_cache(ListBase **colliders)
+{
+ if(*colliders) {
+ BLI_freelistN(*colliders);
+ MEM_freeN(*colliders);
+ *colliders = NULL;
+ }
+}
+static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
{
int i;
@@ -1405,7 +1496,7 @@ void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModi
}
}
-int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
+static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
{
Cloth *cloth = clmd->clothObject;
int i=0, j = 0, numfaces = 0, numverts = 0;
@@ -1459,7 +1550,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
int ret = 0, ret2 = 0;
- CollisionModifierData **collobjs = NULL;
+ Object **collobjs = NULL;
int numcollobj = 0;
if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
@@ -1498,7 +1589,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
// check all collision objects
for(i = 0; i < numcollobj; i++)
{
- CollisionModifierData *collmd = collobjs[i];
+ Object *collob= collobjs[i];
+ CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
BVHTreeOverlap *overlap = NULL;
int result = 0;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index e5c0b3947de..8846fe77809 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -685,9 +685,19 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
ct->flag= CONSTRAINT_TAR_TEMP; \
\
if (ct->tar) { \
- if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_BONE; \
- else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_VERT; \
- else ct->type = CONSTRAINT_OBTYPE_OBJECT; \
+ if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) { \
+ bPoseChannel *pchan= get_pose_channel(ct->tar->pose, ct->subtarget); \
+ ct->type = CONSTRAINT_OBTYPE_BONE; \
+ ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \
+ }\
+ else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \
+ ct->type = CONSTRAINT_OBTYPE_VERT; \
+ ct->rotOrder = EULER_ORDER_DEFAULT; \
+ } \
+ else {\
+ ct->type = CONSTRAINT_OBTYPE_OBJECT; \
+ ct->rotOrder= ct->tar->rotmode; \
+ } \
} \
\
BLI_addtail(list, ct); \
@@ -1045,6 +1055,7 @@ static void kinematic_new_data (void *cdata)
data->weight= (float)1.0;
data->orientweight= (float)1.0;
data->iterations = 500;
+ data->dist= (float)1.0;
data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
}
@@ -1180,7 +1191,10 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
if (cu->path && cu->path->data) {
if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
/* animated position along curve depending on time */
- curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset;
+ if (cob->scene)
+ curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset;
+ else
+ curvetime= ctime - data->offset;
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
* but this will only work if it actually is animated...
@@ -1580,7 +1594,8 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
VECCOPY(loc, cob->matrix[3]);
Mat4ToSize(cob->matrix, size);
- Mat4ToEulO(ct->matrix, eul, ct->rotOrder);
+ /* to allow compatible rotations, must get both rotations in the order of the owner... */
+ Mat4ToEulO(ct->matrix, eul, cob->rotOrder);
Mat4ToEulO(cob->matrix, obeul, cob->rotOrder);
if ((data->flag & ROTLIKE_X)==0)
@@ -3631,7 +3646,7 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
/* these we can skip completely (invalid constraints...) */
if (cti == NULL) continue;
- if (con->flag & CONSTRAINT_DISABLE) continue;
+ if (con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF)) continue;
/* these constraints can't be evaluated anyway */
if (cti->evaluate_constraint == NULL) continue;
/* influence == 0 should be ignored */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index eec3cb73d8a..2ce877bd847 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -68,7 +68,7 @@
/* globals */
/* local */
-int cu_isectLL(float *v1, float *v2, float *v3, float *v4,
+static int cu_isectLL(float *v1, float *v2, float *v3, float *v4,
short cox, short coy,
float *labda, float *mu, float *vec);
@@ -977,7 +977,7 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i
}
}
-void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride)
+static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride)
{
/* note that these are not purpendicular to the curve
* they need to be rotated for this,
@@ -1363,7 +1363,7 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
}
}
-int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec)
+static int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec)
{
/* return:
-1: colliniar
@@ -1616,7 +1616,7 @@ static void bevel_list_flip_tangents(BevList *bl)
nr= bl->nr;
while(nr--) {
- if(VecAngle2(bevp0->tan, bevp1->tan) > 90)
+ if(RAD2DEG(VecAngle2(bevp0->tan, bevp1->tan)) > 90)
VecNegf(bevp1->tan);
bevp0= bevp1;
@@ -1882,7 +1882,7 @@ static void make_bevel_list_3D_tangent(BevList *bl)
}
}
-void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode)
+static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode)
{
switch(twist_mode) {
case CU_TWIST_TANGENT:
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 6a14762e0ed..a8cec6070a0 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -78,6 +78,7 @@
#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "MEM_guardedalloc.h"
@@ -520,8 +521,8 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* softbody collision */
if((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE))
- if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob))
- dag_add_collision_field_relation(dag, scene, ob, node);
+ if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob) || ob->particlesystem.first)
+ dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */
if (ob->type==OB_MBALL) {
Object *mom= find_basis_mball(scene, ob);
@@ -553,13 +554,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
psys= ob->particlesystem.first;
if(psys) {
- ParticleEffectorCache *nec;
GroupObject *go;
for(; psys; psys=psys->next) {
BoidRule *rule = NULL;
BoidState *state = NULL;
ParticleSettings *part= psys->part;
+ ListBase *effectors = NULL;
+ EffectorCache *eff;
dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
@@ -591,34 +593,17 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
- psys_end_effectors(psys);
- psys_init_effectors(scene, ob, psys->part->eff_group, psys);
+ effectors = pdInitEffectors(scene, ob, psys, part->effector_weights);
- for(nec= psys->effectors.first; nec; nec= nec->next) {
- Object *ob1= nec->ob;
-
- if(nec->type & PSYS_EC_EFFECTOR) {
- node2 = dag_get_node(dag, ob1);
- if(ob1->pd->forcefield==PFIELD_GUIDE)
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Field");
- else
- dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Particle Field");
- }
- else if(nec->type & PSYS_EC_DEFLECT) {
- node2 = dag_get_node(dag, ob1);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Collision");
- }
- else if(nec->type & PSYS_EC_PARTICLE) {
- node2 = dag_get_node(dag, ob1);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Field");
- }
-
- if(nec->type & PSYS_EC_REACTOR) {
- node2 = dag_get_node(dag, ob1);
- dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Reactor");
+ if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
+ if(eff->psys) {
+ node2 = dag_get_node(dag, eff->ob);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Field");
}
}
+ pdEndEffectors(&effectors);
+
if(part->boids) {
for(state = part->boids->states.first; state; state=state->next) {
for(rule = state->rules.first; rule; rule=rule->next) {
@@ -1606,6 +1591,21 @@ void graph_print_adj_list(void)
/* ************************ API *********************** */
+/* mechanism to allow editors to be informed of depsgraph updates,
+ to do their own updates based on changes... */
+static void (*EditorsUpdateCb)(Main *bmain, ID *id)= NULL;
+
+void DAG_editors_update_cb(void (*func)(Main *bmain, ID *id))
+{
+ EditorsUpdateCb= func;
+}
+
+static void dag_editors_update(Main *bmain, ID *id)
+{
+ if(EditorsUpdateCb)
+ EditorsUpdateCb(bmain, id);
+}
+
/* groups with objects in this scene need to be put in the right order as well */
static void scene_sort_groups(Scene *sce)
{
@@ -2142,30 +2142,58 @@ void DAG_scene_update_flags(Scene *scene, unsigned int lay)
}
-void DAG_id_flush_update(ID *id, short flag)
+static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay)
{
- Main *bmain= G.main;
wmWindowManager *wm;
wmWindow *win;
- Scene *sce;
- Object *obt, *ob= NULL;
- short idtype;
/* only one scene supported currently, making more scenes work
correctly requires changes beyond just the dependency graph */
+ *sce= NULL;
+ *lay= 0;
+
if((wm= bmain->wm.first)) {
- /* if we have a windowmanager, use sce from first window */
+ /* if we have a windowmanager, look into windows */
for(win=wm->windows.first; win; win=win->next) {
- sce= (win->screen)? win->screen->scene: NULL;
-
- if(sce)
- break;
+ if(win->screen) {
+ if(!*sce) *sce= win->screen->scene;
+ *lay |= BKE_screen_visible_layers(win->screen);
+ }
}
}
- else
+ else {
/* if not, use the first sce */
- sce= bmain->scene.first;
+ *sce= bmain->scene.first;
+ if(*sce) *lay= (*sce)->lay;
+
+ /* XXX for background mode, we should get the scen
+ from somewhere, for the -S option, but it's in
+ the context, how to get it here? */
+ }
+}
+
+void DAG_ids_flush_update(int time)
+{
+ Main *bmain= G.main;
+ Scene *sce;
+ unsigned int lay;
+
+ dag_current_scene_layers(bmain, &sce, &lay);
+
+ if(sce)
+ DAG_scene_flush_update(sce, lay, time);
+}
+
+void DAG_id_flush_update(ID *id, short flag)
+{
+ Main *bmain= G.main;
+ Scene *sce;
+ Object *obt, *ob= NULL;
+ short idtype;
+ unsigned int lay;
+
+ dag_current_scene_layers(bmain, &sce, &lay);
if(!id || !sce || !sce->theDag)
return;
@@ -2173,7 +2201,7 @@ void DAG_id_flush_update(ID *id, short flag)
/* set flags & pointcache for object */
if(GS(id->name) == ID_OB) {
ob= (Object*)id;
- ob->recalc |= flag;
+ ob->recalc |= (flag & OB_RECALC);
BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
if(flag & OB_RECALC_DATA) {
@@ -2210,13 +2238,27 @@ void DAG_id_flush_update(ID *id, short flag)
}
}
}
+
+ /* set flags based on particle settings */
+ if(idtype == ID_PA) {
+ ParticleSystem *psys;
+ for(obt=bmain->object.first; obt; obt= obt->id.next) {
+ for(psys=obt->particlesystem.first; psys; psys=psys->next) {
+ if(&psys->part->id == id) {
+ BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
+ obt->recalc |= (flag & OB_RECALC);
+ psys->recalc |= (flag & PSYS_RECALC);
+ }
+ }
+ }
+ }
+
+ /* update editors */
+ dag_editors_update(bmain, id);
}
/* flush to other objects that depend on this one */
-// XXX if(G.curscreen)
-// DAG_scene_flush_update(sce, dag_screen_view3d_layers(), 0);
-// else
- DAG_scene_flush_update(sce, sce->lay, 0);
+ DAG_scene_flush_update(sce, lay, 0);
}
/* recursively descends tree, each node only checked once */
@@ -2251,10 +2293,25 @@ static int parent_check_node(DagNode *node, int curtime)
/* all nodes that influence this object get tagged, for calculating the exact
position of this object at a given timeframe */
-void DAG_object_update_flags(Scene *sce, Object *ob, unsigned int lay)
+void DAG_id_update_flags(ID *id)
{
+ Main *bmain= G.main;
+ Scene *sce;
DagNode *node;
DagAdjList *itA;
+ Object *ob;
+ unsigned int lay;
+
+ dag_current_scene_layers(bmain, &sce, &lay);
+
+ if(!id || !sce || !sce->theDag)
+ return;
+
+ /* objects only currently */
+ if(GS(id->name) != ID_OB)
+ return;
+
+ ob= (Object*)id;
/* tag nodes unchecked */
for(node = sce->theDag->DagNode.first; node; node= node->next)
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index d87dbc833c5..266a528dc57 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1131,7 +1131,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
}
-void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
+static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
{
if(cu->flag & CU_3D) return;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index e3c4f12184e..7cc65de827a 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -48,12 +48,15 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_jitter.h"
+#include "BLI_listbase.h"
+#include "BLI_noise.h"
#include "BLI_rand.h"
#include "PIL_time.h"
@@ -68,6 +71,7 @@
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_group.h"
@@ -79,11 +83,13 @@
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "RE_render_ext.h"
+#include "RE_shader_ext.h"
/* fluid sim particle import */
#ifndef DISABLE_ELBEEM
@@ -95,17 +101,46 @@
//XXX #include "BIF_screen.h"
-PartDeflect *object_add_collision_fields(void)
+EffectorWeights *BKE_add_effector_weights(Group *group)
+{
+ EffectorWeights *weights = MEM_callocN(sizeof(EffectorWeights), "EffectorWeights");
+ int i;
+
+ for(i=0; i<NUM_PFIELD_TYPES; i++)
+ weights->weight[i] = 1.0f;
+
+ weights->global_gravity = 1.0f;
+
+ weights->group = group;
+
+ return weights;
+}
+PartDeflect *object_add_collision_fields(int type)
{
PartDeflect *pd;
pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
+ pd->forcefield = type;
pd->pdef_sbdamp = 0.1f;
pd->pdef_sbift = 0.2f;
pd->pdef_sboft = 0.02f;
pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer()))+1) % 128;
pd->f_strength = 1.0f;
+ pd->f_damp = 1.0f;
+ pd->f_size = 1.0f;
+
+ /* set sensible defaults based on type */
+ switch(type) {
+ case PFIELD_VORTEX:
+ pd->shape = PFIELD_SHAPE_PLANE;
+ break;
+ case PFIELD_WIND:
+ pd->shape = PFIELD_SHAPE_PLANE;
+ pd->f_flow = 1.0f; /* realistic wind behavior */
+ break;
+ }
+ pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION;
return pd;
}
@@ -156,93 +191,216 @@ void free_effects(ListBase *lb)
}
/* -------------------------- Effectors ------------------ */
+void free_partdeflect(PartDeflect *pd)
+{
+ if(!pd)
+ return;
+
+ if(pd->tex)
+ pd->tex->id.us--;
-static void add_to_effectorcache(ListBase *lb, Scene *scene, Object *ob, Object *obsrc)
+ if(pd->rng)
+ rng_free(pd->rng);
+
+ MEM_freeN(pd);
+}
+
+static void precalculate_effector(EffectorCache *eff)
{
- pEffectorCache *ec;
- PartDeflect *pd= ob->pd;
-
- if(pd->forcefield == PFIELD_GUIDE) {
- if(ob->type==OB_CURVE && obsrc->type==OB_MESH) { /* guides only do mesh particles */
- Curve *cu= ob->data;
- if(cu->flag & CU_PATH) {
- if(cu->path==NULL || cu->path->data==NULL)
- makeDispListCurveTypes(scene, ob, 0);
- if(cu->path && cu->path->data) {
- ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
- ec->ob= ob;
- BLI_addtail(lb, ec);
- }
+ unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
+ if(!eff->pd->rng)
+ eff->pd->rng = rng_new(eff->pd->seed + cfra);
+ else
+ rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
+
+ if(eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) {
+ Curve *cu= eff->ob->data;
+ if(cu->flag & CU_PATH) {
+ if(cu->path==NULL || cu->path->data==NULL)
+ makeDispListCurveTypes(eff->scene, eff->ob, 0);
+
+ if(cu->path && cu->path->data) {
+ where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius);
+ Mat4MulVecfl(eff->ob->obmat, eff->guide_loc);
+ Mat4Mul3Vecfl(eff->ob->obmat, eff->guide_dir);
}
}
}
- else if(pd->forcefield) {
-
- if(pd->forcefield == PFIELD_WIND)
- {
- pd->rng = rng_new(pd->seed);
- }
-
- ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
- ec->ob= ob;
- BLI_addtail(lb, ec);
+ else if(eff->pd->shape == PFIELD_SHAPE_SURFACE) {
+ eff->surmd = (SurfaceModifierData *)modifiers_findByType ( eff->ob, eModifierType_Surface );
+ }
+ else if(eff->psys)
+ psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
+}
+static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
+{
+ EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
+ eff->scene = scene;
+ eff->ob = ob;
+ eff->psys = psys;
+ eff->pd = pd;
+ eff->frame = -1;
+
+ precalculate_effector(eff);
+
+ return eff;
+}
+static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src)
+{
+ EffectorCache *eff = NULL;
+
+ if( ob == ob_src || weights->weight[ob->pd->forcefield] == 0.0f )
+ return;
+
+ if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal )
+ return;
+
+ if(*effectors == NULL)
+ *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
+
+ eff = new_effector_cache(scene, ob, NULL, ob->pd);
+
+ BLI_addtail(*effectors, eff);
+}
+static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src)
+{
+ ParticleSettings *part= psys->part;
+
+ if( !psys_check_enabled(ob, psys) )
+ return;
+
+ if( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0)
+ return;
+
+ if( part->pd && part->pd->forcefield && weights->weight[part->pd->forcefield] != 0.0f) {
+ if(*effectors == NULL)
+ *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
+
+ BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd));
+ }
+
+ if (part->pd2 && part->pd2->forcefield && weights->weight[part->pd2->forcefield] != 0.0f) {
+ if(*effectors == NULL)
+ *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
+
+ BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd2));
}
}
/* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(Scene *scene, Object *obsrc, Group *group)
+ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src, EffectorWeights *weights)
{
- static ListBase listb={NULL, NULL};
- pEffectorCache *ec;
Base *base;
- unsigned int layer= obsrc->lay;
+ unsigned int layer= ob_src->lay;
+ ListBase *effectors = NULL;
- if(group) {
+ if(weights->group) {
GroupObject *go;
- for(go= group->gobject.first; go; go= go->next) {
- if( (go->ob->lay & layer) && go->ob->pd && go->ob!=obsrc) {
- add_to_effectorcache(&listb, scene, go->ob, obsrc);
+ for(go= weights->group->gobject.first; go; go= go->next) {
+ if( (go->ob->lay & layer) ) {
+ if( go->ob->pd && go->ob->pd->forcefield )
+ add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src);
+
+ if( go->ob->particlesystem.first ) {
+ ParticleSystem *psys= go->ob->particlesystem.first;
+
+ for( ; psys; psys=psys->next )
+ add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src);
+ }
}
}
}
else {
for(base = scene->base.first; base; base= base->next) {
- if( (base->lay & layer) && base->object->pd && base->object!=obsrc) {
- add_to_effectorcache(&listb, scene, base->object, obsrc);
+ if( (base->lay & layer) ) {
+ if( base->object->pd && base->object->pd->forcefield )
+ add_object_to_effectors(&effectors, scene, weights, base->object, ob_src);
+
+ if( base->object->particlesystem.first ) {
+ ParticleSystem *psys= base->object->particlesystem.first;
+
+ for( ; psys; psys=psys->next )
+ add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src);
+ }
}
}
}
-
- /* make a full copy */
- for(ec= listb.first; ec; ec= ec->next) {
- ec->obcopy= *(ec->ob);
- }
-
- if(listb.first)
- return &listb;
-
- return NULL;
+ return effectors;
}
-void pdEndEffectors(ListBase *lb)
+void pdEndEffectors(ListBase **effectors)
{
- if(lb) {
- pEffectorCache *ec;
- /* restore full copy */
- for(ec= lb->first; ec; ec= ec->next)
- {
- if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND))
- rng_free(ec->ob->pd->rng);
-
- *(ec->ob)= ec->obcopy;
+ if(*effectors) {
+ EffectorCache *eff = (*effectors)->first;
+
+ for(; eff; eff=eff->next) {
+ if(eff->guide_data)
+ MEM_freeN(eff->guide_data);
}
- BLI_freelistN(lb);
+ BLI_freelistN(*effectors);
+ MEM_freeN(*effectors);
+ *effectors = NULL;
}
}
+void pd_point_from_particle(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, EffectedPoint *point)
+{
+ point->loc = state->co;
+ point->vel = state->vel;
+ point->index = pa - sim->psys->particles;
+ point->size = pa->size;
+ /* TODO: point->charge */
+ point->charge = 1.0f;
+
+ point->vel_to_sec = 1.0f;
+ point->vel_to_frame = psys_get_timestep(sim);
+
+ point->flag = 0;
+
+ if(sim->psys->part->flag & PART_ROT_DYN) {
+ point->ave = state->ave;
+ point->rot = state->rot;
+ }
+ else
+ point->ave = point->rot = NULL;
+
+ point->psys = sim->psys;
+}
+
+void pd_point_from_loc(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
+{
+ point->loc = loc;
+ point->vel = vel;
+ point->index = index;
+ point->size = 0.0f;
+
+ point->vel_to_sec = (float)scene->r.frs_sec;
+ point->vel_to_frame = 1.0f;
+
+ point->flag = 0;
+
+ point->ave = point->rot = NULL;
+ point->psys = NULL;
+}
+void pd_point_from_soft(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
+{
+ point->loc = loc;
+ point->vel = vel;
+ point->index = index;
+ point->size = 0.0f;
+
+ point->vel_to_sec = (float)scene->r.frs_sec;
+ point->vel_to_frame = 1.0f;
+
+ point->flag = PE_WIND_AS_SPEED;
+
+ point->ave = point->rot = NULL;
+
+ point->psys = NULL;
+}
/************************************************/
/* Effectors */
/************************************************/
@@ -256,26 +414,33 @@ static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BV
}
// get visibility of a wind ray
-static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir)
+static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, EffectorData *efd, EffectedPoint *point)
{
- CollisionModifierData **collobjs = NULL;
- int numcollobj = 0, i;
+ ListBase *colls = colliders;
+ ColliderCache *col;
float norm[3], len = 0.0;
- float visibility = 1.0;
-
- collobjs = get_collisionobjects(scene, ob, &numcollobj);
+ float visibility = 1.0, absorption = 0.0;
- if(!collobjs)
- return 0;
+ if(!(eff->pd->flag & PFIELD_VISIBILITY))
+ return visibility;
+
+ if(!colls)
+ colls = get_collider_cache(eff->scene, NULL);
+
+ if(!colls)
+ return visibility;
- VECCOPY(norm, dir);
+ VECCOPY(norm, efd->vec_to_point);
VecNegf(norm);
len = Normalize(norm);
// check all collision objects
- for(i = 0; i < numcollobj; i++)
+ for(col = colls->first; col; col = col->next)
{
- CollisionModifierData *collmd = collobjs[i];
+ CollisionModifierData *collmd = col->collmd;
+
+ if(col->ob == eff->ob)
+ continue;
if(collmd->bvhtree)
{
@@ -285,18 +450,21 @@ static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir
hit.dist = len + FLT_EPSILON;
// check if the way is blocked
- if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0)
+ if(BLI_bvhtree_ray_cast(collmd->bvhtree, point->loc, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0)
{
+ absorption= col->ob->pd->absorption;
+
// visibility is only between 0 and 1, calculated from 1-absorption
- visibility *= MAX2(0.0, MIN2(1.0, (1.0-((float)collmd->absorption)*0.01)));
+ visibility *= CLAMPIS(1.0f-absorption, 0.0f, 1.0f);
if(visibility <= 0.0f)
break;
}
}
}
-
- MEM_freeN(collobjs);
+
+ if(!colliders)
+ free_collider_cache(&colls);
return visibility;
}
@@ -344,43 +512,39 @@ static float falloff_func_rad(PartDeflect *pd, float fac)
return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
}
-float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
+float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, EffectorWeights *weights)
{
- float eff_dir[3], temp[3];
- float falloff=1.0, fac, r_fac;
-
- if(pd->forcefield==PFIELD_LENNARDJ)
- return falloff; /* Lennard-Jones field has it's own falloff built in */
+ float temp[3];
+ float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f;
+ float fac, r_fac;
- VecCopyf(eff_dir,eff_velocity);
- Normalize(eff_dir);
+ fac = Inpf(efd->nor, efd->vec_to_point);
- if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
+ if(eff->pd->zdir == PFIELD_Z_POS && fac < 0.0f)
falloff=0.0f;
- else switch(pd->falloff){
+ else if(eff->pd->zdir == PFIELD_Z_NEG && fac > 0.0f)
+ falloff=0.0f;
+ else switch(eff->pd->falloff){
case PFIELD_FALL_SPHERE:
- fac=VecLength(vec_to_part);
- falloff= falloff_func_dist(pd, fac);
+ falloff*= falloff_func_dist(eff->pd, efd->distance);
break;
case PFIELD_FALL_TUBE:
- fac=Inpf(vec_to_part,eff_dir);
- falloff= falloff_func_dist(pd, ABS(fac));
+ falloff*= falloff_func_dist(eff->pd, ABS(fac));
if(falloff == 0.0f)
break;
- VECADDFAC(temp,vec_to_part,eff_dir,-fac);
- r_fac=VecLength(temp);
- falloff*= falloff_func_rad(pd, r_fac);
+ VECADDFAC(temp, efd->vec_to_point, efd->nor, -fac);
+ r_fac= VecLength(temp);
+ falloff*= falloff_func_rad(eff->pd, r_fac);
break;
case PFIELD_FALL_CONE:
- fac=Inpf(vec_to_part,eff_dir);
- falloff= falloff_func_dist(pd, ABS(fac));
+ falloff*= falloff_func_dist(eff->pd, ABS(fac));
if(falloff == 0.0f)
break;
- r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
- falloff*= falloff_func_rad(pd, r_fac);
+ r_fac=saacos(fac/VecLength(efd->vec_to_point))*180.0f/(float)M_PI;
+ falloff*= falloff_func_rad(eff->pd, r_fac);
break;
}
@@ -388,127 +552,391 @@ float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
return falloff;
}
-void do_physical_effector(Scene *scene, Object *ob, float *opco, short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise_factor, float charge, float pa_size)
+int closest_point_on_surface(SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel)
{
- float mag_vec[3]={0,0,0};
- float temp[3], temp2[3];
- float eff_vel[3];
- float noise = 0, visibility;
-
- // calculate visibility
- visibility = eff_calc_visibility(scene, ob, opco, vec_to_part);
- if(visibility <= 0.0)
- return;
- falloff *= visibility;
+ BVHTreeNearest nearest;
- VecCopyf(eff_vel,eff_velocity);
- Normalize(eff_vel);
+ nearest.index = -1;
+ nearest.dist = FLT_MAX;
- switch(type){
- case PFIELD_WIND:
- VECCOPY(mag_vec,eff_vel);
-
- // add wind noise here, only if we have wind
- if((noise_factor > 0.0f) && (force_val > FLT_EPSILON))
- noise = wind_func(rng, noise_factor);
+ BLI_bvhtree_find_nearest(surmd->bvhtree->tree, co, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
+
+ if(nearest.index != -1) {
+ VECCOPY(surface_co, nearest.co);
+
+ if(surface_nor) {
+ VECCOPY(surface_nor, nearest.no);
+ }
+
+ if(surface_vel) {
+ MFace *mface = CDDM_get_face(surmd->dm, nearest.index);
- VecMulf(mag_vec,(force_val+noise)*falloff);
- VecAddf(field,field,mag_vec);
- break;
+ VECCOPY(surface_vel, surmd->v[mface->v1].co);
+ VecAddf(surface_vel, surface_vel, surmd->v[mface->v2].co);
+ VecAddf(surface_vel, surface_vel, surmd->v[mface->v3].co);
+ if(mface->v4)
+ VecAddf(surface_vel, surface_vel, surmd->v[mface->v4].co);
- case PFIELD_FORCE:
- if(planar)
- Projf(mag_vec,vec_to_part,eff_vel);
- else
- VecCopyf(mag_vec,vec_to_part);
+ VecMulf(surface_vel, mface->v4 ? 0.25f : 0.333f);
+ }
+ return 1;
+ }
- Normalize(mag_vec);
+ return 0;
+}
+int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int real_velocity)
+{
+ float cfra = eff->scene->r.cfra;
+ int ret = 0;
- VecMulf(mag_vec,force_val*falloff);
- VecAddf(field,field,mag_vec);
- break;
+ if(eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd) {
+ /* closest point in the object surface is an effector */
+ float vec[3];
- case PFIELD_VORTEX:
- Crossf(mag_vec,eff_vel,vec_to_part);
+ /* using velocity corrected location allows for easier sliding over effector surface */
+ VecCopyf(vec, point->vel);
+ VecMulf(vec, point->vel_to_frame);
+ VecAddf(vec, vec, point->loc);
- Normalize(mag_vec);
+ ret = closest_point_on_surface(eff->surmd, vec, efd->loc, efd->nor, real_velocity ? efd->vel : NULL);
- VecMulf(mag_vec,force_val*distance*falloff);
- VecAddf(field,field,mag_vec);
+ efd->size = 0.0f;
+ }
+ else if(eff->pd->shape==PFIELD_SHAPE_POINTS) {
- break;
- case PFIELD_MAGNET:
- if(planar)
- VecCopyf(temp,eff_vel);
- else
- /* magnetic field of a moving charge */
- Crossf(temp,eff_vel,vec_to_part);
+ if(eff->ob->derivedFinal) {
+ DerivedMesh *dm = eff->ob->derivedFinal;
- Normalize(temp);
+ dm->getVertCo(dm, *efd->index, efd->loc);
+ dm->getVertNo(dm, *efd->index, efd->nor);
- Crossf(temp2,velocity,temp);
- VecAddf(mag_vec,mag_vec,temp2);
+ Mat4MulVecfl(eff->ob->obmat, efd->loc);
+ Mat4Mul3Vecfl(eff->ob->obmat, efd->nor);
- VecMulf(mag_vec,force_val*falloff);
- VecAddf(field,field,mag_vec);
- break;
- case PFIELD_HARMONIC:
- if(planar)
- Projf(mag_vec,vec_to_part,eff_vel);
- else
- VecCopyf(mag_vec,vec_to_part);
+ Normalize(efd->nor);
- VecMulf(mag_vec,force_val*falloff);
- VecSubf(field,field,mag_vec);
+ efd->size = 0.0f;
- VecCopyf(mag_vec,velocity);
- VecMulf(mag_vec,damp*2.0f*(float)sqrt(force_val));
- VecSubf(field,field,mag_vec);
- break;
- case PFIELD_CHARGE:
- if(planar)
- Projf(mag_vec,vec_to_part,eff_vel);
- else
- VecCopyf(mag_vec,vec_to_part);
+ /**/
+ ret = 1;
+ }
+ }
+ else if(eff->psys) {
+ ParticleSimulationData sim = {eff->scene, eff->ob, eff->psys, NULL, NULL};
+ ParticleData *pa = eff->psys->particles + *efd->index;
+ ParticleKey state;
+
+ /* exclude the particle itself for self effecting particles */
+ if(eff->psys == point->psys && *efd->index == point->index)
+ ;
+ else {
+ /* TODO: time from actual previous calculated frame (step might not be 1) */
+ state.time = cfra - 1.0;
+ ret = psys_get_particle_state(&sim, *efd->index, &state, 0);
+
+ /* TODO */
+ //if(eff->pd->forcefiled == PFIELD_HARMONIC && ret==0) {
+ // if(pa->dietime < eff->psys->cfra)
+ // eff->flag |= PE_VELOCITY_TO_IMPULSE;
+ //}
+
+ VECCOPY(efd->loc, state.co);
+ VECCOPY(efd->nor, state.vel);
+ if(real_velocity) {
+ VECCOPY(efd->vel, state.vel);
+ }
- Normalize(mag_vec);
+ efd->size = pa->size;
+ }
+ }
+ else {
+ /* use center of object for distance calculus */
+ Object *ob = eff->ob;
+ Object obcopy = *ob;
+
+ where_is_object_time(eff->scene, ob, cfra);
+
+ /* use z-axis as normal*/
+ VECCOPY(efd->nor, ob->obmat[2]);
+ Normalize(efd->nor);
+
+ /* for vortex the shape chooses between old / new force */
+ if(eff->pd->shape == PFIELD_SHAPE_PLANE) {
+ /* efd->loc is closes point on effector xy-plane */
+ float temp[3];
+ VecSubf(temp, point->loc, ob->obmat[3]);
+ Projf(efd->loc, temp, efd->nor);
+ VecSubf(efd->loc, point->loc, efd->loc);
+ }
+ else {
+ VECCOPY(efd->loc, ob->obmat[3]);
+ }
- VecMulf(mag_vec,charge*force_val*falloff);
- VecAddf(field,field,mag_vec);
- break;
- case PFIELD_LENNARDJ:
- {
- float fac;
+ if(real_velocity) {
+ VECCOPY(efd->vel, ob->obmat[3]);
+
+ where_is_object_time(eff->scene, ob, cfra - 1.0);
+
+ VecSubf(efd->vel, efd->vel, ob->obmat[3]);
+ }
+
+ *eff->ob = obcopy;
+
+ efd->size = 0.0f;
+
+ ret = 1;
+ }
+
+ if(ret) {
+ VecSubf(efd->vec_to_point, point->loc, efd->loc);
+ efd->distance = VecLength(efd->vec_to_point);
+
+ /* for some effectors we need the object center every time */
+ VecSubf(efd->vec_to_point2, point->loc, eff->ob->obmat[3]);
+ VECCOPY(efd->nor2, eff->ob->obmat[2]);
+ Normalize(efd->nor2);
+ }
+
+ return ret;
+}
+static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p)
+{
+ if(eff->pd->shape == PFIELD_SHAPE_POINTS) {
+ efd->index = p;
+
+ *p = 0;
+ *tot = eff->ob->derivedFinal ? eff->ob->derivedFinal->numVertData : 1;
+
+ if(*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) {
+ *p = point->index % *tot;
+ *tot = *p+1;
+ }
+ }
+ else if(eff->psys) {
+ efd->index = p;
+
+ *p = 0;
+ *tot = eff->psys->totpart;
+
+ if(eff->pd->forcefield == PFIELD_CHARGE) {
+ /* Only the charge of the effected particle is used for
+ interaction, not fall-offs. If the fall-offs aren't the
+ same this will be unphysical, but for animation this
+ could be the wanted behavior. If you want physical
+ correctness the fall-off should be spherical 2.0 anyways.
+ */
+ efd->charge = eff->pd->f_strength;
+ }
+ else if(eff->pd->forcefield == PFIELD_HARMONIC) {
+ /* every particle is mapped to only one harmonic effector particle */
+ *p= point->index % eff->psys->totpart;
+ *tot= *p + 1;
+ }
+ }
+ else {
+ *p = 0;
+ *tot = 1;
+ }
+}
+static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
+{
+ TexResult result[4];
+ float tex_co[3], strength, force[3];
+ float nabla = eff->pd->tex_nabla;
+ int hasrgb;
+ short mode = eff->pd->tex_mode;
+
+ if(!eff->pd->tex)
+ return;
+
+ result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0;
+
+ strength= eff->pd->f_strength * efd->falloff;
+
+ VECCOPY(tex_co,point->loc);
+
+ if(eff->pd->flag & PFIELD_TEX_2D) {
+ float fac=-Inpf(tex_co, efd->nor);
+ VECADDFAC(tex_co, tex_co, efd->nor, fac);
+ }
+
+ if(eff->pd->flag & PFIELD_TEX_OBJECT) {
+ Mat4Mul3Vecfl(eff->ob->obmat, tex_co);
+ }
+
+ hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL,NULL, 1, result);
+
+ if(hasrgb && mode==PFIELD_TEX_RGB) {
+ force[0] = (0.5f - result->tr) * strength;
+ force[1] = (0.5f - result->tg) * strength;
+ force[2] = (0.5f - result->tb) * strength;
+ }
+ else {
+ strength/=nabla;
+
+ tex_co[0] += nabla;
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+1);
+
+ tex_co[0] -= nabla;
+ tex_co[1] += nabla;
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+2);
- if(planar) {
- Projf(mag_vec,vec_to_part,eff_vel);
- distance = VecLength(mag_vec);
+ tex_co[1] -= nabla;
+ tex_co[2] += nabla;
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+3);
+
+ if(mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we dont have rgb fall back to grad */
+ force[0] = (result[0].tin - result[1].tin) * strength;
+ force[1] = (result[0].tin - result[2].tin) * strength;
+ force[2] = (result[0].tin - result[3].tin) * strength;
+ }
+ else { /*PFIELD_TEX_CURL*/
+ float dbdy, dgdz, drdz, dbdx, dgdx, drdy;
+
+ dbdy = result[2].tb - result[0].tb;
+ dgdz = result[3].tg - result[0].tg;
+ drdz = result[3].tr - result[0].tr;
+ dbdx = result[1].tb - result[0].tb;
+ dgdx = result[1].tg - result[0].tg;
+ drdy = result[2].tr - result[0].tr;
+
+ force[0] = (dbdy - dgdz) * strength;
+ force[1] = (drdz - dbdx) * strength;
+ force[2] = (dgdx - drdy) * strength;
+ }
+ }
+
+ if(eff->pd->flag & PFIELD_TEX_2D){
+ float fac = -Inpf(force, efd->nor);
+ VECADDFAC(force, force, efd->nor, fac);
+ }
+
+ VecAddf(total_force, total_force, force);
+}
+void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
+{
+ PartDeflect *pd = eff->pd;
+ RNG *rng = pd->rng;
+ float force[3]={0,0,0};
+ float temp[3];
+ float fac;
+ float strength = pd->f_strength;
+ float damp = pd->f_damp;
+ float noise_factor = pd->f_noise;
+
+ if(noise_factor > 0.0f) {
+ strength += wind_func(rng, noise_factor);
+
+ if(ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG))
+ damp += wind_func(rng, noise_factor);
+ }
+
+ VECCOPY(force, efd->vec_to_point);
+
+ switch(pd->forcefield){
+ case PFIELD_WIND:
+ Normalize(force);
+ strength *= (Inpf(force, efd->nor) >= 0.0f ? 1.0f : -1.0f);
+ VecMulf(force, strength * efd->falloff);
+ break;
+ case PFIELD_FORCE:
+ Normalize(force);
+ VecMulf(force, strength * efd->falloff);
+ break;
+ case PFIELD_VORTEX:
+ /* old vortex force */
+ if(pd->shape == PFIELD_SHAPE_POINT) {
+ Crossf(force, efd->nor, efd->vec_to_point);
+ Normalize(force);
+ VecMulf(force, strength * efd->distance * efd->falloff);
}
+ else {
+ /* new vortex force */
+ Crossf(temp, efd->nor2, efd->vec_to_point2);
+ VecMulf(temp, strength * efd->falloff);
+
+ Crossf(force, efd->nor2, temp);
+ VecMulf(force, strength * efd->falloff);
+
+ VECADDFAC(temp, temp, point->vel, -point->vel_to_sec);
+ VecAddf(force, force, temp);
+ }
+ break;
+ case PFIELD_MAGNET:
+ if(eff->pd->shape == PFIELD_SHAPE_POINT)
+ /* magnetic field of a moving charge */
+ Crossf(temp, efd->nor, efd->vec_to_point);
else
- VecCopyf(mag_vec,vec_to_part);
-
- /* at this distance the field is 60 times weaker than maximum */
- if(distance > 2.22 * (size+pa_size))
- break;
+ VecCopyf(temp, efd->nor);
- fac = pow((size+pa_size)/distance,6.0);
+ Normalize(temp);
+ VecMulf(temp, strength * efd->falloff);
+ Crossf(force, point->vel, temp);
+ VecMulf(force, point->vel_to_sec);
+ break;
+ case PFIELD_HARMONIC:
+ VecMulf(force, -strength * efd->falloff);
+ VecCopyf(temp, point->vel);
+ VecMulf(temp, -damp * 2.0f * (float)sqrt(fabs(strength)) * point->vel_to_sec);
+ VecAddf(force, force, temp);
+ break;
+ case PFIELD_CHARGE:
+ VecMulf(force, point->charge * strength * efd->falloff);
+ break;
+ case PFIELD_LENNARDJ:
+ fac = pow((efd->size + point->size) / efd->distance, 6.0);
- fac = - fac * (1.0 - fac) / distance;
+ fac = - fac * (1.0 - fac) / efd->distance;
/* limit the repulsive term drastically to avoid huge forces */
fac = ((fac>2.0) ? 2.0 : fac);
- /* 0.003715 is the fac value at 2.22 times (size+pa_size),
- substracted to avoid discontinuity at the border
- */
- VecMulf(mag_vec, force_val * (fac-0.0037315));
- VecAddf(field,field,mag_vec);
+ VecMulf(force, strength * fac);
break;
- }
case PFIELD_BOID:
/* Boid field is handled completely in boids code. */
+ return;
+ case PFIELD_TURBULENCE:
+ if(pd->flag & PFIELD_GLOBAL_CO) {
+ VECCOPY(temp, point->loc);
+ }
+ else {
+ VECADD(temp, efd->vec_to_point2, efd->nor2);
+ }
+ force[0] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[0], temp[1], temp[2], 2,0,2);
+ force[1] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[1], temp[2], temp[0], 2,0,2);
+ force[2] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[2], temp[0], temp[1], 2,0,2);
+ VecMulf(force, strength * efd->falloff);
+ break;
+ case PFIELD_DRAG:
+ VECCOPY(force, point->vel);
+ fac = Normalize(force) * point->vel_to_sec;
+
+ strength = MIN2(strength, 2.0f);
+ damp = MIN2(damp, 2.0f);
+
+ VecMulf(force, -efd->falloff * fac * (strength * fac + damp));
break;
}
+
+ if(pd->flag & PFIELD_DO_LOCATION) {
+ VECADDFAC(total_force, total_force, force, 1.0f/point->vel_to_sec);
+
+ if(ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) {
+ VECADDFAC(total_force, total_force, point->vel, -pd->f_flow * efd->falloff);
+ }
+ }
+
+ if(pd->flag & PFIELD_DO_ROTATION && point->ave && point->rot) {
+ float xvec[3] = {1.0f, 0.0f, 0.0f};
+ float dave[3];
+ QuatMulVecf(point->rot, xvec);
+ Crossf(dave, xvec, force);
+ if(pd->f_flow != 0.0f) {
+ VECADDFAC(dave, dave, point->ave, -pd->f_flow * efd->falloff);
+ }
+ VecAddf(point->ave, point->ave, dave);
+ }
}
/* -------- pdDoEffectors() --------
@@ -525,7 +953,7 @@ void do_physical_effector(Scene *scene, Object *ob, float *opco, short type, flo
guide = old speed of particle
*/
-void pdDoEffectors(Scene *scene, ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags)
+void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse)
{
/*
Modifies the force on a particle according to its
@@ -540,43 +968,45 @@ void pdDoEffectors(Scene *scene, ListBase *lb, float *opco, float *force, float
(particles are guided along a curve bezier or old nurbs)
(is independent of other effectors)
*/
- Object *ob;
- pEffectorCache *ec;
- PartDeflect *pd;
-
- float distance, vec_to_part[3];
- float falloff;
+ EffectorCache *eff;
+ EffectorData efd;
+ int p=0, tot = 1;
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
/* Check for min distance here? (yes would be cool to add that, ton) */
- for(ec = lb->first; ec; ec= ec->next) {
+ if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
/* object effectors were fully checked to be OK to evaluate! */
- ob= ec->ob;
- pd= ob->pd;
-
- /* Get IPO force strength and fall off values here */
- where_is_object_time(scene, ob, cur_time);
-
- /* use center of object for distance calculus */
- VecSubf(vec_to_part, opco, ob->obmat[3]);
- distance = VecLength(vec_to_part);
- falloff=effector_falloff(pd,ob->obmat[2],vec_to_part);
-
- if(falloff<=0.0f)
- ; /* don't do anything */
- else {
- float field[3]={0,0,0}, tmp[3];
- VECCOPY(field, force);
- do_physical_effector(scene, ob, opco, pd->forcefield,pd->f_strength,distance,
- falloff, pd->f_dist, pd->f_damp, ob->obmat[2], vec_to_part,
- speed,force, pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise, 0.0f, 0.0f);
-
- // for softbody backward compatibility
- if(flags & PE_WIND_AS_SPEED){
- VECSUB(tmp, force, field);
- VECSUB(speed, speed, tmp);
+ get_effector_tot(eff, &efd, point, &tot, &p);
+
+ for(; p<tot; p++) {
+ if(get_effector_data(eff, &efd, point, 0)) {
+ efd.falloff= effector_falloff(eff, &efd, point, weights);
+
+ if(efd.falloff > 0.0f)
+ efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point);
+
+ if(efd.falloff <= 0.0f)
+ ; /* don't do anything */
+ else if(eff->pd->forcefield == PFIELD_TEXTURE)
+ do_texture_effector(eff, &efd, point, force);
+ else {
+ float temp1[3]={0,0,0}, temp2[3];
+ VECCOPY(temp1, force);
+
+ do_physical_effector(eff, &efd, point, force);
+
+ // for softbody backward compatibility
+ if(point->flag & PE_WIND_AS_SPEED && impulse){
+ VECSUB(temp2, force, temp1);
+ VECSUB(impulse, impulse, temp2);
+ }
+ }
+ }
+ else if(eff->flag & PE_VELOCITY_TO_IMPULSE && impulse) {
+ /* special case for harmonic effector */
+ VECADD(impulse, impulse, efd.vel);
}
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 31f6e2c6067..0ecd1fe912b 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -200,6 +200,85 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array
return NULL;
}
+/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
+#define BEZT_BINARYSEARCH_THRESH 0.00001f
+
+/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace)
+{
+ int start=0, end=arraylen;
+ int loopbreaker= 0, maxloop= arraylen * 2;
+
+ /* initialise replace-flag first */
+ *replace= 0;
+
+ /* sneaky optimisations (don't go through searching process if...):
+ * - keyframe to be added is to be added out of current bounds
+ * - keyframe to be added would replace one of the existing ones on bounds
+ */
+ if ((arraylen <= 0) || (array == NULL)) {
+ printf("Warning: binarysearch_bezt_index() encountered invalid array \n");
+ return 0;
+ }
+ else {
+ /* check whether to add before/after/on */
+ float framenum;
+
+ /* 'First' Keyframe (when only one keyframe, this case is used) */
+ framenum= array[0].vec[1][0];
+ if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
+ *replace = 1;
+ return 0;
+ }
+ else if (frame < framenum)
+ return 0;
+
+ /* 'Last' Keyframe */
+ framenum= array[(arraylen-1)].vec[1][0];
+ if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
+ *replace= 1;
+ return (arraylen - 1);
+ }
+ else if (frame > framenum)
+ return arraylen;
+ }
+
+
+ /* most of the time, this loop is just to find where to put it
+ * 'loopbreaker' is just here to prevent infinite loops
+ */
+ for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
+ /* compute and get midpoint */
+ int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
+ float midfra= array[mid].vec[1][0];
+
+ /* check if exactly equal to midpoint */
+ if (IS_EQT(frame, midfra, BEZT_BINARYSEARCH_THRESH)) {
+ *replace = 1;
+ return mid;
+ }
+
+ /* repeat in upper/lower half */
+ if (frame > midfra)
+ start= mid + 1;
+ else if (frame < midfra)
+ end= mid - 1;
+ }
+
+ /* print error if loop-limit exceeded */
+ if (loopbreaker == (maxloop-1)) {
+ printf("Error: binarysearch_bezt_index() was taking too long \n");
+
+ // include debug info
+ printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
+ }
+
+ /* not found, so return where to place it */
+ return start;
+}
+
/* Calculate the extents of F-Curve's data */
void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax)
{
@@ -916,7 +995,7 @@ void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
}
/* find root ('zero') */
-int findzero (float x, float q0, float q1, float q2, float q3, float *o)
+static int findzero (float x, float q0, float q1, float q2, float q3, float *o)
{
double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
int nr= 0;
@@ -1010,7 +1089,7 @@ int findzero (float x, float q0, float q1, float q2, float q3, float *o)
}
}
-void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
+static void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
{
float t, c0, c1, c2, c3;
int a;
@@ -1026,7 +1105,8 @@ void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
}
}
-void berekenx (float *f, float *o, int b)
+#if 0
+static void berekenx (float *f, float *o, int b)
{
float t, c0, c1, c2, c3;
int a;
@@ -1041,6 +1121,7 @@ void berekenx (float *f, float *o, int b)
o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
}
}
+#endif
/* -------------------------- */
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index ad9e481ffd2..aa163b821c8 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -80,6 +80,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
if(!fss)
return;
+ fss->fmd = fluidmd;
fss->type = OB_FLUIDSIM_ENABLE;
fss->show_advancedoptions = 0;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 411b2448dea..4e05bf45d3d 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -129,7 +129,7 @@ wcsleninu8(wchar_t *src)
}
int
-utf8slen(char *src)
+static utf8slen(char *src)
{
int size = 0, index = 0;
unsigned char c;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index cdb175ed661..09d150341b2 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -277,7 +277,7 @@ static Image *image_alloc(const char *name, short source, short type)
ima->xrep= ima->yrep= 1;
ima->aspx= ima->aspy= 1.0;
- ima->gen_x= 256; ima->gen_y= 256;
+ ima->gen_x= 1024; ima->gen_y= 1024;
ima->gen_type= 1; /* no defines yet? */
ima->source= source;
@@ -1472,9 +1472,11 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
iuser->ok= 1;
break;
case IMA_SIGNAL_SRC_CHANGE:
- if(ima->type==IMA_TYPE_MULTILAYER)
- image_free_buffers(ima);
- else if(ima->source==IMA_SRC_GENERATED) {
+ if(ima->type == IMA_TYPE_UV_TEST)
+ if(ima->source != IMA_SRC_GENERATED)
+ ima->type= IMA_TYPE_IMAGE;
+
+ if(ima->source==IMA_SRC_GENERATED) {
if(ima->gen_x==0 || ima->gen_y==0) {
ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
if(ibuf) {
@@ -1483,6 +1485,9 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
}
}
}
+
+ image_free_buffers(ima);
+
ima->ok= 1;
if(iuser)
iuser->ok= 1;
@@ -1559,15 +1564,22 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
return rpass;
}
-RenderResult *BKE_image_get_renderresult(struct Scene *scene, Image *ima)
+RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima)
{
if(ima->rr)
return ima->rr;
- if(ima->type==IMA_TYPE_R_RESULT)
- return RE_GetResult(RE_GetRender(scene->id.name));
+ else if(ima->type==IMA_TYPE_R_RESULT)
+ return RE_AcquireResultRead(RE_GetRender(scene->id.name));
return NULL;
}
+void BKE_image_release_renderresult(struct Scene *scene, Image *ima)
+{
+ if(ima->rr);
+ else if(ima->type==IMA_TYPE_R_RESULT)
+ RE_ReleaseResult(RE_GetRender(scene->id.name));
+}
+
/* after imbuf load, openexr type can return with a exrhandle open */
/* in that case we have to build a render-result */
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
@@ -1868,16 +1880,25 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
/* showing RGBA result itself (from compo/sequence) or
like exr, using layers etc */
/* always returns a single ibuf, also during render progress */
-static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
+static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_r)
{
Render *re= NULL;
RenderResult *rr= NULL;
+ /* if we the caller is not going to release the lock, don't give the image */
+ if(!lock_r)
+ return NULL;
+
if(iuser && iuser->scene) {
re= RE_GetRender(iuser->scene->id.name);
- rr= RE_GetResult(re);
+ rr= RE_AcquireResultRead(re);
+
+ /* release is done in BKE_image_release_ibuf using lock_r */
+ *lock_r= re;
}
- if(rr==NULL) return NULL;
+
+ if(rr==NULL)
+ return NULL;
if(RE_RenderInProgress(re)) {
ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
@@ -1888,6 +1909,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
}
+
return ibuf;
}
else {
@@ -1902,7 +1924,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
pass= (iuser)? iuser->pass: 0;
/* this gives active layer, composite or seqence result */
- RE_GetResultImage(RE_GetRender(iuser->scene->id.name), &rres);
+ RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name), &rres);
rect= (unsigned int *)rres.rect32;
rectf= rres.rectf;
dither= iuser->scene->r.dither_intensity;
@@ -1949,10 +1971,14 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
ibuf->zbuf_float= rres.rectz;
ibuf->flags |= IB_zbuffloat;
ibuf->dither= dither;
-
+
+ RE_ReleaseResultImage(re);
+
ima->ok= IMA_OK_LOADED;
return ibuf;
}
+
+ RE_ReleaseResultImage(re);
}
return NULL;
@@ -2006,8 +2032,9 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
}
/* Checks optional ImageUser and verifies/creates ImBuf. */
-/* returns ibuf */
-ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+/* use this one if you want to get a render result in progress,
+ * if not, use BKE_image_get_ibuf which doesn't require a release */
+ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf= NULL;
float color[] = {0, 0, 0, 1};
@@ -2023,6 +2050,9 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
* things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
* That means, the last two steps must be, 1) add the ibuf to the list and
* 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
+
+ if(lock_r)
+ *lock_r= NULL;
/* quick reject tests */
if(ima==NULL)
@@ -2090,16 +2120,17 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
else if(ima->source == IMA_SRC_GENERATED) {
/* generated is: ibuf is allocated dynamically */
/* UV testgrid or black or solid etc */
- if(ima->gen_x==0) ima->gen_x= 256;
- if(ima->gen_y==0) ima->gen_y= 256;
+ if(ima->gen_x==0) ima->gen_x= 1024;
+ if(ima->gen_y==0) ima->gen_y= 1024;
ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 0, ima->gen_type, color);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok= IMA_OK_LOADED;
}
else if(ima->source == IMA_SRC_VIEWER) {
if(ima->type==IMA_TYPE_R_RESULT) {
- /* always verify entirely */
- ibuf= image_get_render_result(ima, iuser);
+ /* always verify entirely, and potentially
+ returns pointer to release later */
+ ibuf= image_get_render_result(ima, iuser, lock_r);
}
else if(ima->type==IMA_TYPE_COMPOSITE) {
/* Composite Viewer, all handled in compositor */
@@ -2121,6 +2152,17 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
return ibuf;
}
+void BKE_image_release_ibuf(Image *ima, void *lock)
+{
+ /* for getting image during threaded render, need to release */
+ if(lock)
+ RE_ReleaseResult(lock);
+}
+
+ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+{
+ return BKE_image_acquire_ibuf(ima, iuser, NULL);
+}
void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
{
@@ -2170,3 +2212,103 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
}
}
+/*
+ Produce image export path.
+
+ Fails returning 0 if image filename is empty or if destination path
+ matches image path (i.e. both are the same file).
+
+ Trailing slash in dest_dir is optional.
+
+ Logic:
+
+ - if an image is "below" current .blend file directory, rebuild the
+ same dir structure in dest_dir
+
+ For example //textures/foo/bar.png becomes
+ [dest_dir]/textures/foo/bar.png.
+
+ - if an image is not "below" current .blend file directory,
+ disregard it's path and copy it in the same directory where 3D file
+ goes.
+
+ For example //../foo/bar.png becomes [dest_dir]/bar.png.
+
+ This logic will help ensure that all image paths are relative and
+ that a user gets his images in one place. It'll also provide
+ consistent behaviour across exporters.
+ */
+int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size)
+{
+ char path[FILE_MAX];
+ char dir[FILE_MAX];
+ char base[FILE_MAX];
+ char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
+ char dest_path[FILE_MAX];
+ char rel_dir[FILE_MAX];
+ int len;
+
+ if (abs)
+ abs[0]= 0;
+
+ if (rel)
+ rel[0]= 0;
+
+ BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
+
+ if (!strlen(im->name)) {
+ if (G.f & G_DEBUG) printf("Invalid image type.\n");
+ return 0;
+ }
+
+ BLI_strncpy(path, im->name, sizeof(path));
+
+ /* expand "//" in filename and get absolute path */
+ BLI_convertstringcode(path, G.sce);
+
+ /* get the directory part */
+ BLI_split_dirfile_basic(path, dir, base);
+
+ len= strlen(blend_dir);
+
+ rel_dir[0] = 0;
+
+ /* if image is "below" current .blend file directory */
+ if (!strncmp(path, blend_dir, len)) {
+
+ /* if image is _in_ current .blend file directory */
+ if (!strcmp(dir, blend_dir)) {
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+ /* "below" */
+ else {
+ /* rel = image_path_dir - blend_dir */
+ BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
+
+ BLI_join_dirfile(dest_path, dest_dir, rel_dir);
+ BLI_join_dirfile(dest_path, dest_path, base);
+ }
+
+ }
+ /* image is out of current directory */
+ else {
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+
+ if (abs)
+ BLI_strncpy(abs, dest_path, abs_size);
+
+ if (rel) {
+ strncat(rel, rel_dir, rel_size);
+ strncat(rel, base, rel_size);
+ }
+
+ /* return 2 if src=dest */
+ if (!strcmp(path, dest_path)) {
+ if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
+ return 2;
+ }
+
+ return 1;
+}
+
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 0bce71b57eb..de215ae4af9 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -33,6 +33,7 @@
#include "DNA_cloth_types.h"
#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
#include "BKE_effect.h"
#include "BKE_global.h"
@@ -43,7 +44,7 @@
#include <windows.h>
static LARGE_INTEGER _itstart, _itend;
static LARGE_INTEGER ifreq;
-void itstart(void)
+static void itstart(void)
{
static int first = 1;
if(first) {
@@ -52,7 +53,7 @@ void itstart(void)
}
QueryPerformanceCounter(&_itstart);
}
-void itend(void)
+static void itend(void)
{
QueryPerformanceCounter(&_itend);
}
@@ -74,7 +75,7 @@ double itval()
{
gettimeofday(&_itstart, &itz);
}
-void itend(void)
+static void itend(void)
{
gettimeofday(&_itend,&itz);
}
@@ -155,7 +156,7 @@ DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vec
/* printf vector[3] on console: for debug output */
-void print_fvector(float m3[3])
+static void print_fvector(float m3[3])
{
printf("%f\n%f\n%f\n\n",m3[0],m3[1],m3[2]);
}
@@ -297,7 +298,7 @@ DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], f
// 3x3 matrix
///////////////////////////
/* printf 3x3 matrix on console: for debug output */
-void print_fmatrix(float m3[3][3])
+static void print_fmatrix(float m3[3][3])
{
printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]);
printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]);
@@ -496,7 +497,8 @@ DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float fro
// SPARSE SYMMETRIC big matrix with 3x3 matrix entries
///////////////////////////
/* printf a big matrix on console: for debug output */
-void print_bfmatrix(fmatrix3x3 *m3)
+#if 0
+static void print_bfmatrix(fmatrix3x3 *m3)
{
unsigned int i = 0;
@@ -505,6 +507,8 @@ void print_bfmatrix(fmatrix3x3 *m3)
print_fmatrix(m3[i].m);
}
}
+#endif
+
/* create big matrix */
DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
{
@@ -887,7 +891,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
}
}
-int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
+static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
{
// Solves for unknown X in equation AX=B
unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
@@ -970,7 +974,7 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
}
/*
// version 1.3
-int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
+static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
{
unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
@@ -1038,7 +1042,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
}
*/
// version 1.4
-int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
+static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
{
unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
@@ -1391,7 +1395,7 @@ static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
n[2]= n1[0]*n2[1]-n1[1]*n2[0];
}
-float calculateVertexWindForce(float wind[3], float vertexnormal[3])
+static float calculateVertexWindForce(float wind[3], float vertexnormal[3])
{
return (INPR(wind, vertexnormal));
}
@@ -1417,7 +1421,6 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
int i = 0;
int j = 0;
int k = 0;
- lfVector temp;
INIT_MINMAX(gmin, gmax);
@@ -1480,15 +1483,19 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
Cloth *cloth = clmd->clothObject;
int i = 0;
float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
- float gravity[3];
+ float gravity[3] = {0.0f, 0.0f, 0.0f};
float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
MFace *mfaces = cloth->mfaces;
unsigned int numverts = cloth->numverts;
LinkNode *search = cloth->springs;
lfVector *winvec;
+ EffectedPoint epoint;
- VECCOPY(gravity, clmd->sim_parms->gravity);
- mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
+ /* global acceleration (gravitation) */
+ if(clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ VECCOPY(gravity, clmd->scene->physics_settings.gravity);
+ mul_fvector_S(gravity, gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity); /* scale gravity force */
+ }
/* set dFdX jacobi matrix to zero */
init_bfmatrix(dFdX, ZERO);
@@ -1523,10 +1530,9 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
// precalculate wind forces
for(i = 0; i < cloth->numverts; i++)
- {
- float speed[3] = {0.0f, 0.0f,0.0f};
-
- pdDoEffectors(clmd->scene, effectors, lX[i], winvec[i], speed, frame, 0.0f, 0);
+ {
+ pd_point_from_loc(clmd->scene, (float*)lX[i], (float*)lV[i], i, &epoint);
+ pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
}
for(i = 0; i < cloth->numfaces; i++)
@@ -1595,7 +1601,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
// printf("\n");
}
-void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *M, fmatrix3x3 *bigI)
+static void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *M, fmatrix3x3 *bigI)
{
unsigned int numverts = dFdV[0].vcount;
@@ -1654,9 +1660,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
while(step < tf)
{
// calculate forces
- effectors= pdInitEffectors(clmd->scene, ob, NULL);
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M);
- if(effectors) pdEndEffectors(effectors);
// calculate new velocity
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
@@ -1739,9 +1743,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
cp_lfvector(id->V, id->Vnew, numverts);
// calculate
- effectors= pdInitEffectors(clmd->scene, ob, NULL);
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
- if(effectors) pdEndEffectors(effectors);
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 2f0e0931588..6717f5560be 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -213,17 +213,17 @@ static char *ob_adrcodes_to_paths (int adrcode, int *array_index)
*array_index= 2; return "delta_location";
case OB_ROT_X:
- *array_index= 0; return "rotation";
+ *array_index= 0; return "rotation_euler";
case OB_ROT_Y:
- *array_index= 1; return "rotation";
+ *array_index= 1; return "rotation_euler";
case OB_ROT_Z:
- *array_index= 2; return "rotation";
+ *array_index= 2; return "rotation_euler";
case OB_DROT_X:
- *array_index= 0; return "delta_rotation";
+ *array_index= 0; return "delta_rotation_euler";
case OB_DROT_Y:
- *array_index= 1; return "delta_rotation";
+ *array_index= 1; return "delta_rotation_euler";
case OB_DROT_Z:
- *array_index= 2; return "delta_rotation";
+ *array_index= 2; return "delta_rotation_euler";
case OB_SIZE_X:
*array_index= 0; return "scale";
@@ -281,23 +281,23 @@ static char *pchan_adrcodes_to_paths (int adrcode, int *array_index)
/* result depends on adrcode */
switch (adrcode) {
case AC_QUAT_W:
- *array_index= 0; return "rotation";
+ *array_index= 0; return "rotation_quaternion";
case AC_QUAT_X:
- *array_index= 1; return "rotation";
+ *array_index= 1; return "rotation_quaternion";
case AC_QUAT_Y:
- *array_index= 2; return "rotation";
+ *array_index= 2; return "rotation_quaternion";
case AC_QUAT_Z:
- *array_index= 3; return "rotation";
+ *array_index= 3; return "rotation_quaternion";
case AC_EUL_X:
- *array_index= 0; return "euler_rotation";
+ *array_index= 0; return "rotation_euler";
case AC_EUL_Y:
- *array_index= 1; return "euler_rotation";
+ *array_index= 1; return "rotation_euler";
case AC_EUL_Z:
- *array_index= 2; return "euler_rotation";
+ *array_index= 2; return "rotation_euler";
case -1: /* special case for euler-rotations used by old drivers */
- *array_index= 0; return "euler_rotation";
+ *array_index= 0; return "rotation_euler";
case AC_LOC_X:
*array_index= 0; return "location";
@@ -820,7 +820,7 @@ static char *particle_adrcodes_to_paths (int adrcode, int *array_index)
* - array_index - index in property's array (if applicable) to use
* - return - the allocated path...
*/
-char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index)
+static char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index)
{
DynStr *path= BLI_dynstr_new();
char *propname=NULL, *rpath=NULL;
@@ -1047,10 +1047,6 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
}
}
-
- /* free old driver */
- MEM_freeN(idriver);
-
/* return the new one */
return cdriver;
}
@@ -1122,11 +1118,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
/* allocate memory for a new F-Curve */
fcu= MEM_callocN(sizeof(FCurve), "FCurve");
- /* convert driver - will free the old one... */
- if (icu->driver) {
+ /* convert driver */
+ if (icu->driver)
fcu->driver= idriver_to_cdriver(icu->driver);
- icu->driver= NULL;
- }
/* copy flags */
if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE;
@@ -1214,6 +1208,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
/* interpolation can only be constant... */
dst->ipo= BEZT_IPO_CONST;
+ /* 'hide' flag is now used for keytype - only 'keyframes' existed before */
+ dst->hide= BEZT_KEYTYPE_KEYFRAME;
+
/* correct values, by checking if the flag of interest is set */
if ( ((int)(dst->vec[1][1])) & (abp->bit) )
dst->vec[0][1]= dst->vec[1][1]= dst->vec[2][1] = 1.0f;
@@ -1230,10 +1227,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
/* add new F-Curve to list */
fcurve_add_to_list(groups, list, fcurve, actname);
}
-
- /* free old data of curve now that it's no longer needed for converting any more curves */
- if (icu->bezt) MEM_freeN(icu->bezt);
- if (icu->bp) MEM_freeN(icu->bezt);
}
else {
/* get rna-path
@@ -1264,6 +1257,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
if (icu->ipo != IPO_MIXED)
dst->ipo= icu->ipo;
+ /* 'hide' flag is now used for keytype - only 'keyframes' existed before */
+ dst->hide= BEZT_KEYTYPE_KEYFRAME;
+
/* correct values for euler rotation curves - they were degrees/10 */
// XXX for now, just make them into radians as RNA sets/reads directly in that form
if ( ((icu->blocktype == ID_OB) && ELEM3(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) ||
@@ -1296,9 +1292,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
}
}
}
-
- /* free this data now */
- MEM_freeN(icu->bezt);
}
else if (icu->bp) {
/* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */
@@ -1319,7 +1312,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
*/
static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase *animgroups, ListBase *anim, ListBase *drivers)
{
- IpoCurve *icu, *icn;
+ IpoCurve *icu;
/* sanity check */
if (ELEM3(NULL, ipo, anim, drivers))
@@ -1341,25 +1334,44 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase
}
/* loop over IPO-Curves, freeing as we progress */
- for (icu= ipo->curve.first; icu; icu= icn) {
- /* get link to next (for later) */
- icn= icu->next;
-
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
/* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves),
* we figure out the best place to put the channel, then tell the curve-converter to just dump there
*/
if (icu->driver) {
/* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */
- if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON))
+ if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) {
icu_to_fcurves(NULL, drivers, icu, actname, constname);
- else
+ }
+ else {
MEM_freeN(icu->driver);
+ icu->driver= NULL;
+ }
}
else
icu_to_fcurves(animgroups, anim, icu, actname, constname);
+ }
+
+ /* if this IPO block doesn't have any users after this one, free... */
+ ipo->id.us--;
+ if ( (ipo->id.us == 0) || ((ipo->id.us == 1) && (ipo->id.flag & LIB_FAKEUSER)) )
+ {
+ IpoCurve *icn;
- /* free this IpoCurve now that it's been converted */
- BLI_freelinkN(&ipo->curve, icu);
+ for (icu= ipo->curve.first; icu; icu= icn) {
+ icn= icu->next;
+
+ /* free driver */
+ if (icu->driver)
+ MEM_freeN(icu->driver);
+
+ /* free old data of curve now that it's no longer needed for converting any more curves */
+ if (icu->bezt) MEM_freeN(icu->bezt);
+ if (icu->bp) MEM_freeN(icu->bezt);
+
+ /* free this IPO-Curve */
+ BLI_freelinkN(&ipo->curve, icu);
+ }
}
}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 730a12bea09..a957be4704c 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -524,30 +524,13 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
{
Curve *cu= par->data;
- float fac, loc[4], dir[3], cent[3], radius;
- short upflag, index;
-
- if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) {
- upflag= OB_POSZ;
- cent[0]= 0.0;
- cent[1]= co[1];
- cent[2]= co[2];
- index= 0;
- }
- else if(axis==MOD_CURVE_POSY || axis==MOD_CURVE_NEGY) {
- upflag= OB_POSZ;
- cent[0]= co[0];
- cent[1]= 0.0;
- cent[2]= co[2];
- index= 1;
- }
- else {
- upflag= OB_POSY;
- cent[0]= co[0];
- cent[1]= co[1];
- cent[2]= 0.0;
- index= 2;
- }
+ float fac, loc[4], dir[3], new_quat[4], radius;
+ short /*upflag, */ index;
+
+ index= axis-1;
+ if(index>2)
+ index -= 3; /* negative */
+
/* to be sure, mostly after file load */
if(cu->path==NULL) {
makeDispListCurveTypes(scene, par, 0);
@@ -555,7 +538,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
}
/* options */
- if(ELEM3(axis, OB_NEGX, OB_NEGY, OB_NEGZ)) {
+ if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
if(cu->flag & CU_STRETCH)
fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
else
@@ -579,9 +562,10 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
}
#endif // XXX old animation system
- if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */
- float q[4], mat[3][3], quat[4];
-
+ if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */
+ float quat[4], cent[3];
+
+#if 0 // XXX - 2.4x Z-Up, Now use bevel tilt.
if(cd->no_rot_axis) /* set by caller */
dir[cd->no_rot_axis-1]= 0.0f;
@@ -597,22 +581,104 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
q[2]= -fac*dir[1];
q[3]= -fac*dir[2];
QuatMul(quat, q, quat);
- }
- QuatToMat3(quat, mat);
-
- if(cu->flag & CU_PATH_RADIUS) {
- float tmat[3][3], rmat[3][3];
- Mat3Scale(tmat, radius);
- Mat3MulMat3(rmat, mat, tmat);
- Mat3CpyMat3(mat, rmat);
}
+#endif
- /* local rotation */
- Mat3MulVecfl(mat, cent);
+
+ static float q_x90d[4] = {0.70710676908493, 0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
+ static float q_y90d[4] = {0.70710676908493, 0.0, 0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
+ static float q_z90d[4] = {0.70710676908493, 0.0, 0.0, 0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
+
+ static float q_nx90d[4] = {0.70710676908493, -0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
+ static float q_ny90d[4] = {0.70710676908493, 0.0, -0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
+ static float q_nz90d[4] = {0.70710676908493, 0.0, 0.0, -0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
+
+
+ if(cd->no_rot_axis) { /* set by caller */
+
+ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then
+ * changing the axis before calculating the tilt but serves much the same purpose */
+ float dir_flat[3]={0,0,0}, q[4];
+ VECCOPY(dir_flat, dir);
+ dir_flat[cd->no_rot_axis-1]= 0.0f;
+
+ Normalize(dir);
+ Normalize(dir_flat);
+
+ RotationBetweenVectorsToQuat(q, dir, dir_flat); /* Could this be done faster? */
+
+ QuatMul(new_quat, q, new_quat);
+ }
+
+
+ /* Logic for 'cent' orientation *
+ *
+ * The way 'co' is copied to 'cent' may seem to have no meaning, but it does.
+ *
+ * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark.
+ * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise
+ * Notice X,Y,Z Up all have light colors and each ordered CCW.
+ *
+ * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
+ * */
+
+ switch(axis) {
+ case MOD_CURVE_POSX:
+ QuatMul(quat, new_quat, q_y90d);
+
+ cent[0]= 0.0;
+ cent[1]= co[2];
+ cent[2]= co[1];
+ break;
+ case MOD_CURVE_NEGX:
+ QuatMul(quat, new_quat, q_ny90d);
+
+ cent[0]= 0.0;
+ cent[1]= -co[1];
+ cent[2]= co[2];
+
+ break;
+ case MOD_CURVE_POSY:
+ QuatMul(quat, new_quat, q_x90d);
+
+ cent[0]= co[2];
+ cent[1]= 0.0;
+ cent[2]= -co[0];
+ break;
+ case MOD_CURVE_NEGY:
+ QuatMul(quat, new_quat, q_nx90d);
+
+ cent[0]= -co[0];
+ cent[1]= 0.0;
+ cent[2]= -co[2];
+ break;
+ case MOD_CURVE_POSZ:
+ QuatMul(quat, new_quat, q_z90d);
+
+ cent[0]= co[1];
+ cent[1]= -co[0];
+ cent[2]= 0.0;
+ break;
+ case MOD_CURVE_NEGZ:
+ QuatMul(quat, new_quat, q_nz90d);
+
+ cent[0]= co[0];
+ cent[1]= -co[1];
+ cent[2]= 0.0;
+ break;
+ }
+
+ /* scale if enabled */
+ if(cu->flag & CU_PATH_RADIUS)
+ VecMulf(cent, radius);
+ /* local rotation */
+ NormalQuat(quat);
+ QuatMulVecf(quat, cent);
+
/* translation */
VECADD(co, cent, loc);
-
+
if(quatp)
QUATCOPY(quatp, quat);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 02d92a62b59..0f65be207d9 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -455,6 +455,15 @@ void flag_all_listbases_ids(short flag, short value)
while(a--) flag_listbase_ids(lbarray[a], flag, value);
}
+void recalc_all_library_objects(Main *main)
+{
+ Object *ob;
+
+ /* flag for full recalc */
+ for(ob=main->object.first; ob; ob=ob->id.next)
+ if(ob->id.lib)
+ ob->recalc |= OB_RECALC;
+}
/* note: MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb)
@@ -631,42 +640,15 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
}
/* by spec, animdata is first item after ID */
-/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */
+/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
static void id_copy_animdata(ID *id)
{
- switch(GS(id->name)) {
- case ID_OB:
- ((Object *)id)->adt= BKE_copy_animdata(((Object *)id)->adt);
- break;
- case ID_CU:
- ((Curve *)id)->adt= BKE_copy_animdata(((Curve *)id)->adt);
- break;
- case ID_CA:
- ((Camera *)id)->adt= BKE_copy_animdata(((Camera *)id)->adt);
- break;
- case ID_KE:
- ((Key *)id)->adt= BKE_copy_animdata(((Key *)id)->adt);
- break;
- case ID_LA:
- ((Lamp *)id)->adt= BKE_copy_animdata(((Lamp *)id)->adt);
- break;
- case ID_MA:
- ((Material *)id)->adt= BKE_copy_animdata(((Material *)id)->adt);
- break;
- case ID_NT:
- ((bNodeTree *)id)->adt= BKE_copy_animdata(((bNodeTree *)id)->adt);
- break;
- case ID_SCE:
- ((Scene *)id)->adt= BKE_copy_animdata(((Scene *)id)->adt);
- break;
- case ID_TE:
- ((Tex *)id)->adt= BKE_copy_animdata(((Tex *)id)->adt);
- break;
- case ID_WO:
- ((World *)id)->adt= BKE_copy_animdata(((World *)id)->adt);
- break;
- }
+ AnimData *adt= BKE_animdata_from_id(id);
+ if (adt) {
+ IdAdtTemplate *iat = (IdAdtTemplate *)id;
+ iat->adt= BKE_copy_animdata(iat->adt);
+ }
}
/* used everywhere in blenkernel and text.c */
@@ -696,8 +678,9 @@ void *copy_libblock(void *rt)
id->newid= idn;
idn->flag |= LIB_NEW;
if (id->properties) idn->properties = IDP_CopyProperty(id->properties);
-
- id_copy_animdata(id);
+
+ /* the duplicate should get a copy of the animdata */
+ id_copy_animdata(idn);
return idn;
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index e6f9ac2f404..cbd306f6d87 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -159,9 +159,9 @@ void init_material(Material *ma)
ma->sss_radius[0]= 1.0f;
ma->sss_radius[1]= 1.0f;
ma->sss_radius[2]= 1.0f;
- ma->sss_col[0]= 0.8f;
- ma->sss_col[1]= 0.8f;
- ma->sss_col[2]= 0.8f;
+ ma->sss_col[0]= 1.0f;
+ ma->sss_col[1]= 1.0f;
+ ma->sss_col[2]= 1.0f;
ma->sss_error= 0.05f;
ma->sss_scale= 0.1f;
ma->sss_ior= 1.3f;
@@ -172,15 +172,15 @@ void init_material(Material *ma)
ma->vol.density = 1.0f;
ma->vol.emission = 0.0f;
- ma->vol.absorption = 1.0f;
ma->vol.scattering = 1.0f;
+ ma->vol.reflection = 1.0f;
+ ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
+ ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
- ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
ma->vol.density_scale = 1.0f;
ma->vol.depth_cutoff = 0.01f;
ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
ma->vol.stepsize = 0.2f;
- ma->vol.shade_stepsize = 0.2f;
ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
ma->vol.precache_resolution = 50;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index c92eda6d169..431543f8dbd 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -542,7 +542,8 @@ void set_mesh(Object *ob, Mesh *me)
if(ob->type==OB_MESH) {
old= ob->data;
- old->id.us--;
+ if (old)
+ old->id.us--;
ob->data= me;
id_us_plus((ID *)me);
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index f06173264ee..3b47c2f1830 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -214,7 +214,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tcmd->name, cmd->name, 32);
}
-CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CurveModifierData *cmd = (CurveModifierData *)md;
CustomDataMask dataMask = 0;
@@ -290,7 +290,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tlmd->name, lmd->name, 32);
}
-CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
CustomDataMask dataMask = 0;
@@ -1104,7 +1104,7 @@ static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sc
}
}
-float vertarray_size(MVert *mvert, int numVerts, int axis)
+static float vertarray_size(MVert *mvert, int numVerts, int axis)
{
int i;
float min_co, max_co;
@@ -1771,7 +1771,7 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, S
/* finds the best possible flipped name. For renaming; check for unique names afterwards */
/* if strip_number: removes number extensions */
-void vertgroup_flip_name (char *name, int strip_number)
+static void vertgroup_flip_name (char *name, int strip_number)
{
int len;
char prefix[128]={""}; /* The part before the facing */
@@ -3401,7 +3401,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
}
-CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
{
BevelModifierData *bmd = (BevelModifierData *)md;
CustomDataMask dataMask = 0;
@@ -3481,7 +3481,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
}
-CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
{
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
CustomDataMask dataMask = 0;
@@ -3825,7 +3825,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
tumd->aspecty = umd->aspecty;
}
-CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
@@ -4278,7 +4278,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
}
-int smoothModifier_isDisabled(ModifierData *md)
+static int smoothModifier_isDisabled(ModifierData *md)
{
SmoothModifierData *smd = (SmoothModifierData*) md;
short flag;
@@ -4291,7 +4291,7 @@ int smoothModifier_isDisabled(ModifierData *md)
return 0;
}
-CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
CustomDataMask dataMask = 0;
@@ -4508,7 +4508,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
}
-int castModifier_isDisabled(ModifierData *md)
+static int castModifier_isDisabled(ModifierData *md)
{
CastModifierData *cmd = (CastModifierData*) md;
short flag;
@@ -4520,7 +4520,7 @@ int castModifier_isDisabled(ModifierData *md)
return 0;
}
-CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CastModifierData *cmd = (CastModifierData *)md;
CustomDataMask dataMask = 0;
@@ -5151,7 +5151,7 @@ static void waveModifier_updateDepgraph(
}
}
-CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
{
WaveModifierData *wmd = (WaveModifierData *)md;
CustomDataMask dataMask = 0;
@@ -5487,7 +5487,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
}
-CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
@@ -5602,7 +5602,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(thmd->subtarget, hmd->subtarget, 32);
}
-CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
{
HookModifierData *hmd = (HookModifierData *)md;
CustomDataMask dataMask = 0;
@@ -5947,7 +5947,7 @@ static void clothModifier_updateDepgraph(
}
}
-CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
@@ -5971,6 +5971,8 @@ static void clothModifier_copyData(ModifierData *md, ModifierData *target)
tclmd->point_cache = NULL;
tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
+ if(clmd->sim_parms->effector_weights)
+ tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
tclmd->clothObject = NULL;
@@ -5992,8 +5994,11 @@ static void clothModifier_freeData(ModifierData *md)
cloth_free_modifier_extern (clmd);
- if(clmd->sim_parms)
+ if(clmd->sim_parms) {
+ if(clmd->sim_parms->effector_weights)
+ MEM_freeN(clmd->sim_parms->effector_weights);
MEM_freeN(clmd->sim_parms);
+ }
if(clmd->coll_parms)
MEM_freeN(clmd->coll_parms);
@@ -6371,7 +6376,7 @@ static DerivedMesh *booleanModifier_applyModifier(
return derivedData;
}
-CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
@@ -6419,7 +6424,7 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ
tpsmd->psys = psmd->psys;
}
-CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
{
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
CustomDataMask dataMask = 0;
@@ -6601,6 +6606,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
{
DerivedMesh *dm = derivedData, *result;
ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
+ ParticleSimulationData sim;
ParticleSystem * psys=0;
ParticleData *pa=0, *pars=0;
MFace *mface, *orig_mface;
@@ -6635,6 +6641,11 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
if(totpart==0)
return derivedData;
+ sim.scene = md->scene;
+ sim.ob = pimd->ob;
+ sim.psys = psys;
+ sim.psmd = psys_get_modifier(pimd->ob, psys);
+
if(pimd->flag & eParticleInstanceFlag_UseSize) {
int p;
float *si;
@@ -6662,7 +6673,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
maxvert=totvert*totpart;
maxface=totface*totpart;
- psys->lattice=psys_get_lattice(md->scene, ob, psys);
+ psys->lattice=psys_get_lattice(&sim);
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){
@@ -6712,7 +6723,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
mv->co[axis] = 0.0;
}
- psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
+ psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);
Normalize(state.vel);
@@ -6734,7 +6745,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
}
else{
state.time=-1.0;
- psys_get_particle_state(md->scene, pimd->ob, psys, first_particle + i/totvert, &state,1);
+ psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
}
QuatMulVecf(state.rot,mv->co);
@@ -6832,7 +6843,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md)
{
return 1;
}
-CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
{
ExplodeModifierData *emd= (ExplodeModifierData*) md;
CustomDataMask dataMask = 0;
@@ -7416,6 +7427,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
DerivedMesh *explode, *dm=to_explode;
MFace *mf=0;
ParticleSettings *part=psmd->psys->part;
+ ParticleSimulationData sim = {scene, ob, psmd->psys, psmd};
ParticleData *pa=NULL, *pars=psmd->psys->particles;
ParticleKey state;
EdgeHash *vertpahash;
@@ -7431,7 +7443,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
totvert= dm->getNumVerts(dm);
totpart= psmd->psys->totpart;
- timestep= psys_get_timestep(part);
+ timestep= psys_get_timestep(&sim);
//if(part->flag & PART_GLOB_TIME)
cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
@@ -7474,7 +7486,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
/* getting back to object space */
Mat4Invert(imat,ob->obmat);
- psmd->psys->lattice = psys_get_lattice(scene, ob, psmd->psys);
+ psmd->psys->lattice = psys_get_lattice(&sim);
/* duplicate & displace vertices */
ehi= BLI_edgehashIterator_new(vertpahash);
@@ -7502,7 +7514,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
Mat4MulVecfl(ob->obmat,loc0);
state.time=cfra;
- psys_get_particle_state(scene, ob, psmd->psys, i, &state,1);
+ psys_get_particle_state(&sim, i, &state, 1);
vertco=CDDM_get_vert(explode,v)->co;
@@ -7591,7 +7603,7 @@ static DerivedMesh * explodeModifier_applyModifier(
{
DerivedMesh *dm = derivedData;
ExplodeModifierData *emd= (ExplodeModifierData*) md;
- ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);;
+ ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);
if(psmd){
ParticleSystem * psys=psmd->psys;
@@ -7746,7 +7758,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
tmmd->object = mmd->object;
}
-CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
CustomDataMask dataMask = 0;
@@ -8126,7 +8138,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
tsmd->subsurfLevels = smd->subsurfLevels;
}
-CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
CustomDataMask dataMask = 0;
@@ -8503,6 +8515,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->initData = smoothModifier_initData;
mti->copyData = smoothModifier_copyData;
mti->requiredDataMask = smoothModifier_requiredDataMask;
+ mti->isDisabled = smoothModifier_isDisabled;
mti->deformVerts = smoothModifier_deformVerts;
mti->deformVertsEM = smoothModifier_deformVertsEM;
@@ -8513,6 +8526,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->initData = castModifier_initData;
mti->copyData = castModifier_copyData;
mti->requiredDataMask = castModifier_requiredDataMask;
+ mti->isDisabled = castModifier_isDisabled;
mti->foreachObjectLink = castModifier_foreachObjectLink;
mti->updateDepgraph = castModifier_updateDepgraph;
mti->deformVerts = castModifier_deformVerts;
@@ -9137,19 +9151,6 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
return i;
}
-int modifiers_usesPointCache(Object *ob)
-{
- ModifierData *md = ob->modifiers.first;
-
- for (; md; md=md->next) {
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- if (mti->flags & eModifierTypeFlag_UsesPointCache) {
- return 1;
- }
- }
- return 0;
-}
-
void modifier_freeTemporaryData(ModifierData *md)
{
if(md->type == eModifierType_Armature) {
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 37e7e55050a..e7159b82d49 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -596,7 +596,7 @@ static void find_displacer_edges(MultiresDisplacer *d, DerivedMesh *dm, Displace
}
/* Returns in out the corners [0-3] that use v1 and v2 */
-void find_face_corners(MFace *f, int v1, int v2, int out[2])
+static void find_face_corners(MFace *f, int v1, int v2, int out[2])
{
int i, end = f->v4 ? 4 : 3;
@@ -1259,7 +1259,7 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, i
***************************/
/* Does not actually free lvl itself */
-void multires_free_level(MultiresLevel *lvl)
+static void multires_free_level(MultiresLevel *lvl)
{
if(lvl) {
if(lvl->faces) MEM_freeN(lvl->faces);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 480c79fbc1a..3979586fb19 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -219,6 +219,9 @@ void copy_nladata (ListBase *dst, ListBase *src)
if ELEM(NULL, dst, src)
return;
+ /* clear out the destination list first for precautions... */
+ dst->first= dst->last= NULL;
+
/* copy each NLA-track, one at a time */
for (nlt= src->first; nlt; nlt= nlt->next) {
/* make a copy, and add the copy to the destination list */
@@ -1048,7 +1051,7 @@ short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max)
/* Is the given NLA-strip the first one to occur for the given AnimData block */
// TODO: make this an api method if necesary, but need to add prefix first
-short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
+static short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
{
NlaTrack *nlt;
NlaStrip *ns;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 90ea53d4364..aa12894feb9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1953,6 +1953,7 @@ static void composit_end_exec(bNodeTree *ntree, int is_group)
if(ns->data) {
printf("freed leftover buffer from stack\n");
free_compbuf(ns->data);
+ ns->data= NULL;
}
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 8fe7beeb247..579466ea626 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -91,6 +91,7 @@
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
+#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_group.h"
#include "BKE_icons.h"
@@ -127,8 +128,8 @@ void clear_workob(Object *workob)
{
memset(workob, 0, sizeof(Object));
- workob->size[0]= workob->size[1]= workob->size[2]= 1.0;
-
+ workob->size[0]= workob->size[1]= workob->size[2]= 1.0f;
+ workob->rotmode= ROT_MODE_EUL;
}
void copy_baseflags(struct Scene *scene)
@@ -298,11 +299,8 @@ void free_object(Object *ob)
free_constraints(&ob->constraints);
- if(ob->pd){
- if(ob->pd->tex)
- ob->pd->tex->id.us--;
- MEM_freeN(ob->pd);
- }
+ free_partdeflect(ob->pd);
+
if(ob->soft) sbFree(ob->soft);
if(ob->bsoft) bsbFree(ob->bsoft);
if(ob->gpulamp.first) GPU_lamp_free(ob);
@@ -1038,6 +1036,11 @@ Object *add_object(struct Scene *scene, int type)
ob->data= add_obdata_from_type(type);
ob->lay= scene->lay;
+
+ /* objects should default to having Euler XYZ rotations,
+ * but rotations default to quaternions
+ */
+ ob->rotmode= ROT_MODE_EUL;
base= scene_add_base(scene, ob);
scene_select_base(scene, base);
@@ -1064,6 +1067,9 @@ SoftBody *copy_softbody(SoftBody *sb)
sbn->pointcache= BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches);
+ if(sb->effector_weights)
+ sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
+
return sbn;
}
@@ -1124,11 +1130,9 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
psysn->pathcache= NULL;
psysn->childcache= NULL;
psysn->edit= NULL;
- psysn->effectors.first= psysn->effectors.last= 0;
psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
- psysn->reactevents.first = psysn->reactevents.last = NULL;
psysn->renderdata = NULL;
psysn->pointcache= BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches);
@@ -1263,7 +1267,7 @@ Object *copy_object(Object *ob)
/* increase user numbers */
id_us_plus((ID *)obn->data);
id_us_plus((ID *)obn->dup_group);
- // FIXME: add this for animdata too...
+
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
@@ -1273,6 +1277,8 @@ Object *copy_object(Object *ob)
obn->pd= MEM_dupallocN(ob->pd);
if(obn->pd->tex)
id_us_plus(&(obn->pd->tex->id));
+ if(obn->pd->rng)
+ obn->pd->rng = MEM_dupallocN(ob->pd->rng);
}
obn->soft= copy_softbody(ob->soft);
obn->bsoft = copy_bulletsoftbody(ob->bsoft);
@@ -1406,7 +1412,7 @@ int object_data_is_libdata(Object *ob)
/* *************** PROXY **************** */
/* when you make proxy, ensure the exposed layers are extern */
-void armature_set_id_extern(Object *ob)
+static void armature_set_id_extern(Object *ob)
{
bArmature *arm= ob->data;
bPoseChannel *pchan;
@@ -1553,13 +1559,11 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
cfra+= bluroffs+fieldoffs;
/* global time */
- cfra*= scene->r.framelen;
+ if (scene)
+ cfra*= scene->r.framelen;
#if 0 // XXX old animation system
if (ob) {
- if (no_speed_curve==0 && ob->ipo)
- cfra= calc_ipo_time(ob->ipo, cfra);
-
/* ofset frames */
if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0)
cfra-= give_timeoffset(ob);
@@ -1574,29 +1578,44 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
void object_scale_to_mat3(Object *ob, float mat[][3])
{
float vec[3];
- if(ob->ipo) {
- vec[0]= ob->size[0]+ob->dsize[0];
- vec[1]= ob->size[1]+ob->dsize[1];
- vec[2]= ob->size[2]+ob->dsize[2];
- SizeToMat3(vec, mat);
- }
- else {
- SizeToMat3(ob->size, mat);
- }
+
+ vec[0]= ob->size[0]+ob->dsize[0];
+ vec[1]= ob->size[1]+ob->dsize[1];
+ vec[2]= ob->size[2]+ob->dsize[2];
+ SizeToMat3(vec, mat);
}
+// TODO: this should take rotation orders into account later...
void object_rot_to_mat3(Object *ob, float mat[][3])
{
- float vec[3];
- if(ob->ipo) {
- vec[0]= ob->rot[0]+ob->drot[0];
- vec[1]= ob->rot[1]+ob->drot[1];
- vec[2]= ob->rot[2]+ob->drot[2];
- EulToMat3(vec, mat);
+ float rmat[3][3], dmat[3][3];
+
+ /* initialise the delta-rotation matrix, which will get (pre)multiplied
+ * with the rotation matrix to yield the appropriate rotation
+ */
+ Mat3One(dmat);
+
+ /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
+ if (ob->rotmode > 0) {
+ /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
+ EulOToMat3(ob->rot, ob->rotmode, rmat);
+ EulOToMat3(ob->drot, ob->rotmode, dmat);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
+ AxisAngleToMat3(&ob->quat[1], ob->quat[0], rmat);
+ AxisAngleToMat3(&ob->dquat[1], ob->dquat[0], dmat);
}
else {
- EulToMat3(ob->rot, mat);
+ /* quats are normalised before use to eliminate scaling issues */
+ NormalQuat(ob->quat);
+ QuatToMat3(ob->quat, rmat);
+ QuatToMat3(ob->dquat, dmat);
}
+
+ /* combine these rotations */
+ // XXX is this correct? if errors, change the order of multiplication...
+ Mat3MulMat3(mat, dmat, rmat);
}
void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
@@ -1609,19 +1628,7 @@ void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
object_scale_to_mat3(ob, smat);
/* rot */
- /* Quats arnt used yet */
- /*if(ob->transflag & OB_QUAT) {
- if(ob->ipo) {
- QuatMul(q1, ob->quat, ob->dquat);
- QuatToMat3(q1, rmat);
- }
- else {
- QuatToMat3(ob->quat, rmat);
- }
- }
- else {*/
- object_rot_to_mat3(ob, rmat);
- /*}*/
+ object_rot_to_mat3(ob, rmat);
Mat3MulMat3(mat, rmat, smat);
}
@@ -1633,12 +1640,9 @@ void object_to_mat4(Object *ob, float mat[][4])
Mat4CpyMat3(mat, tmat);
- VECCOPY(mat[3], ob->loc);
- if(ob->ipo) {
- mat[3][0]+= ob->dloc[0];
- mat[3][1]+= ob->dloc[1];
- mat[3][2]+= ob->dloc[2];
- }
+ mat[3][0]= ob->loc[0] + ob->dloc[0];
+ mat[3][1]= ob->loc[1] + ob->dloc[1];
+ mat[3][2]= ob->loc[2] + ob->dloc[2];
}
int enable_cu_speed= 1;
@@ -1919,31 +1923,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
if(ob==NULL) return;
-#if 0 // XXX old animation system
- /* this is needed to be able to grab objects with ipos, otherwise it always freezes them */
- stime= bsystem_time(scene, ob, ctime, 0.0);
- if(stime != ob->ctime) {
-
- ob->ctime= stime;
-
- if(ob->ipo) {
- calc_ipo(ob->ipo, stime);
- execute_ipo((ID *)ob, ob->ipo);
- }
- else
- do_all_object_actions(scene, ob);
-
- /* do constraint ipos ..., note it needs stime (0 = all ipos) */
- do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 0);
- }
- else {
- /* but, the drivers have to be done */
- if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo, stime);
- /* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */
- do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1);
- }
-#endif // XXX old animation system
-
/* execute drivers only, as animation has already been done */
BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
@@ -2562,7 +2541,7 @@ int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3
static int pc_cmp(void *a, void *b)
{
LinkData *ad = a, *bd = b;
- if((int)ad->data > (int)bd->data)
+ if(GET_INT_FROM_POINTER(ad->data) > GET_INT_FROM_POINTER(bd->data))
return 1;
else return 0;
}
@@ -2576,14 +2555,14 @@ int object_insert_ptcache(Object *ob)
for(link=ob->pc_ids.first, i = 0; link; link=link->next, i++)
{
- int index =(int)link->data;
+ int index = GET_INT_FROM_POINTER(link->data);
if(i < index)
break;
}
link = MEM_callocN(sizeof(LinkData), "PCLink");
- link->data = (void *)i;
+ link->data = SET_INT_IN_POINTER(i);
BLI_addtail(&ob->pc_ids, link);
return i;
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index bd0b1a5e36e..0de97b9c703 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -236,7 +236,7 @@ void packAll(Main *bmain, ReportList *reports)
// attempt to create a function that generates an unique filename
// this will work when all funtions in fileops.c understand relative filenames...
-char *find_new_name(char *name)
+static char *find_new_name(char *name)
{
char tempname[FILE_MAXDIR + FILE_MAXFILE];
char *newname;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 7c5b2b82b4b..f17d2fbdcac 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -46,19 +46,24 @@ const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
Paint *paint_get_active(Scene *sce)
{
- if(sce && sce->basact && sce->basact->object) {
+ if(sce) {
ToolSettings *ts = sce->toolsettings;
-
- switch(sce->basact->object->mode) {
- case OB_MODE_SCULPT:
- return &ts->sculpt->paint;
- case OB_MODE_VERTEX_PAINT:
- return &ts->vpaint->paint;
- case OB_MODE_WEIGHT_PAINT:
- return &ts->wpaint->paint;
- case OB_MODE_TEXTURE_PAINT:
- return &ts->imapaint.paint;
+
+ if(sce->basact && sce->basact->object) {
+ switch(sce->basact->object->mode) {
+ case OB_MODE_SCULPT:
+ return &ts->sculpt->paint;
+ case OB_MODE_VERTEX_PAINT:
+ return &ts->vpaint->paint;
+ case OB_MODE_WEIGHT_PAINT:
+ return &ts->wpaint->paint;
+ case OB_MODE_TEXTURE_PAINT:
+ return &ts->imapaint.paint;
+ }
}
+
+ /* default to image paint */
+ return &ts->imapaint.paint;
}
return NULL;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 2d3e3210afc..f4f5a1364a3 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -53,7 +53,7 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_kdtree.h"
-#include "BLI_linklist.h"
+#include "BLI_listbase.h"
#include "BLI_rand.h"
#include "BLI_threads.h"
@@ -61,6 +61,7 @@
#include "BKE_boids.h"
#include "BKE_cloth.h"
+#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_lattice.h"
@@ -69,7 +70,7 @@
#include "BKE_particle.h"
#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
-#include "BKE_softbody.h"
+#include "BKE_cloth.h"
#include "BKE_material.h"
#include "BKE_key.h"
#include "BKE_library.h"
@@ -81,12 +82,11 @@
#include "RE_render_ext.h"
-static void key_from_object(Object *ob, ParticleKey *key);
static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index,
float *fuv, float *orco, ParticleTexture *ptex, int event);
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
-static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part,
+static void do_child_modifiers(ParticleSimulationData *sim,
ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa,
float *orco, float mat[4][4], ParticleKey *state, float t);
@@ -96,11 +96,9 @@ int count_particles(ParticleSystem *psys){
PARTICLE_P;
int tot=0;
- LOOP_PARTICLES {
- if(pa->alive == PARS_KILLED);
- else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
+ LOOP_SHOWN_PARTICLES {
+ if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
- else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP));
else tot++;
}
return tot;
@@ -110,55 +108,13 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
PARTICLE_P;
int tot=0;
- LOOP_PARTICLES {
- if(pa->alive == PARS_KILLED);
- else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
+ LOOP_SHOWN_PARTICLES {
+ if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
- else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP));
else if(p%totgr==cur) tot++;
}
return tot;
}
-int psys_count_keys(ParticleSystem *psys)
-{
- PARTICLE_P;
- int totkey=0;
-
- LOOP_PARTICLES
- totkey += pa->totkey;
-
- return totkey;
-}
-/* remember to free the pointer returned from this! */
-char *psys_menu_string(Object *ob, int for_sb)
-{
- ParticleSystem *psys;
- DynStr *ds;
- char *str, num[6];
- int i;
-
- ds = BLI_dynstr_new();
-
- if(for_sb)
- BLI_dynstr_append(ds, "|Object%x-1");
-
- for(i=0,psys=ob->particlesystem.first; psys; i++,psys=psys->next){
-
- BLI_dynstr_append(ds, "|");
- sprintf(num,"%i. ",i+1);
- BLI_dynstr_append(ds, num);
- BLI_dynstr_append(ds, psys->part->id.name+2);
- sprintf(num,"%%x%i",i+1);
- BLI_dynstr_append(ds, num);
- }
-
- str = BLI_dynstr_get_cstring(ds);
-
- BLI_dynstr_free(ds);
-
- return str;
-}
-
/* we allocate path cache memory in chunks instead of a big continguous
* chunk, windows' memory allocater fails to find big blocks of memory often */
@@ -258,30 +214,13 @@ Object *psys_find_object(Scene *scene, ParticleSystem *psys)
return NULL;
}
-/* change object's active particle system */
-void psys_change_act(void *ob_v, void *act_v)
-{
- Object *ob = ob_v;
- ParticleSystem *npsys, *psys;
- short act = *((short*)act_v)-1;
-
- if(act>=0){
- npsys=BLI_findlink(&ob->particlesystem,act);
- psys=psys_get_current(ob);
-
- if(psys)
- psys->flag &= ~PSYS_CURRENT;
- if(npsys)
- npsys->flag |= PSYS_CURRENT;
- }
-}
-Object *psys_get_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
+Object *psys_get_lattice(ParticleSimulationData *sim)
{
Object *lattice=0;
- if(psys_in_edit_mode(scene, psys)==0){
+ if(psys_in_edit_mode(sim->scene, sim->psys)==0){
- ModifierData *md = (ModifierData*)psys_get_modifier(ob,psys);
+ ModifierData *md = (ModifierData*)psys_get_modifier(sim->ob, sim->psys);
for(; md; md=md->next){
if(md->type==eModifierType_Lattice){
@@ -310,20 +249,20 @@ void psys_enable_all(Object *ob)
for(; psys; psys=psys->next)
psys->flag &= ~PSYS_DISABLED;
}
-int psys_ob_has_hair(Object *ob)
-{
- ParticleSystem *psys = ob->particlesystem.first;
-
- for(; psys; psys=psys->next)
- if(psys->part->type == PART_HAIR)
- return 1;
-
- return 0;
-}
int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
{
return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit));
}
+static void psys_create_frand(ParticleSystem *psys)
+{
+ int i;
+ float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms");
+
+ BLI_srandom(psys->seed);
+
+ for(i=0; i<1024; i++, rand++)
+ *rand = BLI_frand();
+}
int psys_check_enabled(Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd;
@@ -345,6 +284,14 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
}
else if(!(psmd->modifier.mode & eModifierMode_Realtime))
return 0;
+
+ /* perhaps not the perfect place, but we have to be sure the rands are there before usage */
+ if(!psys->frand)
+ psys_create_frand(psys);
+ else if(psys->recalc & PSYS_RECALC_RESET) {
+ MEM_freeN(psys->frand);
+ psys_create_frand(psys);
+ }
return 1;
}
@@ -354,15 +301,11 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
/************************************************/
void psys_free_settings(ParticleSettings *part)
{
- if(part->pd) {
- MEM_freeN(part->pd);
- part->pd = NULL;
- }
-
- if(part->pd2) {
- MEM_freeN(part->pd2);
- part->pd2 = NULL;
- }
+ free_partdeflect(part->pd);
+ free_partdeflect(part->pd2);
+
+ if(part->effector_weights)
+ MEM_freeN(part->effector_weights);
boid_free_settings(part->boids);
}
@@ -424,7 +367,7 @@ void free_keyed_keys(ParticleSystem *psys)
}
}
}
-void free_child_path_cache(ParticleSystem *psys)
+static void free_child_path_cache(ParticleSystem *psys)
{
psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs);
psys->childcache = NULL;
@@ -478,6 +421,26 @@ void psys_free_particles(ParticleSystem *psys)
psys->totpart= 0;
}
}
+void psys_free_pdd(ParticleSystem *psys)
+{
+ if(psys->pdd) {
+ if(psys->pdd->cdata)
+ MEM_freeN(psys->pdd->cdata);
+ psys->pdd->cdata = NULL;
+
+ if(psys->pdd->vdata)
+ MEM_freeN(psys->pdd->vdata);
+ psys->pdd->vdata = NULL;
+
+ if(psys->pdd->ndata)
+ MEM_freeN(psys->pdd->ndata);
+ psys->pdd->ndata = NULL;
+
+ if(psys->pdd->vedata)
+ MEM_freeN(psys->pdd->vedata);
+ psys->pdd->vedata = NULL;
+ }
+}
/* free everything */
void psys_free(Object *ob, ParticleSystem * psys)
{
@@ -499,9 +462,6 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys->child = 0;
psys->totchild = 0;
}
-
- if(psys->effectors.first)
- psys_end_effectors(psys);
// check if we are last non-visible particle system
for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){
@@ -527,10 +487,19 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys->pointcache = NULL;
BLI_freelistN(&psys->targets);
- BLI_freelistN(&psys->reactevents);
BLI_kdtree_free(psys->tree);
+ pdEndEffectors(&psys->effectors);
+
+ if(psys->frand)
+ MEM_freeN(psys->frand);
+
+ if(psys->pdd) {
+ psys_free_pdd(psys);
+ MEM_freeN(psys->pdd);
+ }
+
MEM_freeN(psys);
}
}
@@ -722,12 +691,12 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
{
DerivedMesh *dm= ctx->dm;
- Mesh *me= (Mesh*)(ctx->ob->data);
+ Mesh *me= (Mesh*)(ctx->sim.ob->data);
MFace *mf, *mface;
MVert *mvert;
ParticleRenderData *data;
ParticleRenderElem *elems, *elem;
- ParticleSettings *part= ctx->psys->part;
+ ParticleSettings *part= ctx->sim.psys->part;
float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp;
float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport;
double vprate;
@@ -736,10 +705,10 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
if(part->ren_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
return tot;
- if(!ctx->psys->renderdata)
+ if(!ctx->sim.psys->renderdata)
return tot;
- data= ctx->psys->renderdata;
+ data= ctx->sim.psys->renderdata;
if(data->timeoffset)
return 0;
if(!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
@@ -816,7 +785,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
/* set simplification parameters per original face */
for(a=0, elem=elems; a<totorigface; a++, elem++) {
- area = psys_render_projected_area(ctx->psys, facecenter[a], facearea[a], vprate, &viewport);
+ area = psys_render_projected_area(ctx->sim.psys, facecenter[a], facearea[a], vprate, &viewport);
arearatio= fac*area/facearea[a];
if((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
@@ -1438,7 +1407,7 @@ void psys_interpolate_mcol(MCol *mcol, int quad, float *w, MCol *mc)
}
}
-float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values)
+static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values)
{
if(values==0 || index==-1)
return 0.0;
@@ -1922,124 +1891,135 @@ static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clu
VecLerpf(state->co,state->co,par->co,clump);
}
}
+void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
+{
+ EffectedPoint point;
+ ParticleKey state;
+ EffectorData efd;
+ EffectorCache *eff;
+ ParticleSystem *psys = sim->psys;
+ EffectorWeights *weights = sim->psys->part->effector_weights;
+ GuideEffectorData *data;
+ PARTICLE_P;
-int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase *lb)
+ if(!effectors)
+ return;
+
+ LOOP_PARTICLES {
+ psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,state.co,0,0,0,0,0);
+ pd_point_from_particle(sim, pa, &state, &point);
+
+ for(eff = effectors->first; eff; eff=eff->next) {
+ if(eff->pd->forcefield != PFIELD_GUIDE)
+ continue;
+
+ if(!eff->guide_data)
+ eff->guide_data = MEM_callocN(sizeof(GuideEffectorData)*psys->totpart, "GuideEffectorData");
+
+ data = eff->guide_data + p;
+
+ VECSUB(efd.vec_to_point, state.co, eff->guide_loc);
+ VECCOPY(efd.nor, eff->guide_dir);
+ efd.distance = VecLength(efd.vec_to_point);
+
+ VECCOPY(data->vec_to_point, efd.vec_to_point);
+ data->strength = effector_falloff(eff, &efd, &point, weights);
+ }
+ }
+}
+int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
{
+ EffectorCache *eff;
PartDeflect *pd;
- ParticleEffectorCache *ec;
- Object *eob;
Curve *cu;
ParticleKey key, par;
+ GuideEffectorData *data;
- float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0;
- float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f};
- float veffect[3]={0.0,0.0,0.0}, guidetime;
-
- effect[0]=effect[1]=effect[2]=0.0;
+ float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
+ float guidevec[4], guidedir[3], rot2[4], temp[3];
+ float guidetime, radius, angle, totstrength = 0.0f;
+ float vec_to_point[3];
- if(lb->first){
- for(ec = lb->first; ec; ec= ec->next){
- eob= ec->ob;
- if(ec->type & PSYS_EC_EFFECTOR){
- pd=eob->pd;
- if(pd->forcefield==PFIELD_GUIDE){
- cu = (Curve*)eob->data;
+ if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
+ pd = eff->pd;
- distance=ec->distances[pa_num];
- mindist=pd->f_strength;
+ if(pd->forcefield != PFIELD_GUIDE)
+ continue;
- VECCOPY(pa_loc, ec->locations+3*pa_num);
- VECCOPY(pa_zero,pa_loc);
- VECADD(pa_zero,pa_zero,ec->firstloc);
+ data = eff->guide_data + index;
- guidetime=time/(1.0-pd->free_end);
+ if(data->strength <= 0.0f)
+ continue;
- /* WARNING: bails out with continue here */
- if(((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) || guidetime>1.0f) continue;
+ guidetime = time / (1.0 - pd->free_end);
- if(guidetime>1.0f) continue;
+ if(guidetime>1.0f)
+ continue;
- /* calculate contribution factor for this guide */
- f_force=1.0f;
- if(distance<=mindist);
- else if(pd->flag & PFIELD_USEMAX) {
- if(mindist>=pd->maxdist) f_force= 0.0f;
- else if(pd->f_power!=0.0f){
- f_force= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
- f_force = (float)pow(f_force, pd->f_power);
- }
- }
- else if(pd->f_power!=0.0f){
- f_force= 1.0f/(1.0f + distance-mindist);
- f_force = (float)pow(f_force, pd->f_power);
- }
+ cu = (Curve*)eff->ob->data;
- if(pd->flag & PFIELD_GUIDE_PATH_ADD)
- where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius);
- else
- where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius);
+ if(pd->flag & PFIELD_GUIDE_PATH_ADD) {
+ if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius)==0)
+ return 0;
+ }
+ else {
+ if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius)==0)
+ return 0;
+ }
- Mat4MulVecfl(ec->ob->obmat,guidevec);
- Mat4Mul3Vecfl(ec->ob->obmat,guidedir);
+ Mat4MulVecfl(eff->ob->obmat, guidevec);
+ Mat4Mul3Vecfl(eff->ob->obmat, guidedir);
- Normalize(guidedir);
+ Normalize(guidedir);
- if(guidetime!=0.0){
- /* curve direction */
- Crossf(temp, ec->firstdir, guidedir);
- angle=Inpf(ec->firstdir,guidedir)/(VecLength(ec->firstdir));
- angle=saacos(angle);
- VecRotToQuat(temp,angle,rot2);
- QuatMulVecf(rot2,pa_loc);
+ VECCOPY(vec_to_point, data->vec_to_point);
- /* curve tilt */
- VecRotToQuat(guidedir,guidevec[3]-ec->firstloc[3],rot2);
- QuatMulVecf(rot2,pa_loc);
+ if(guidetime != 0.0){
+ /* curve direction */
+ Crossf(temp, eff->guide_dir, guidedir);
+ angle = Inpf(eff->guide_dir, guidedir)/(VecLength(eff->guide_dir));
+ angle = saacos(angle);
+ VecRotToQuat(temp, angle, rot2);
+ QuatMulVecf(rot2, vec_to_point);
- //vectoquat(guidedir, pd->kink_axis, (pd->kink_axis+1)%3, q);
- //QuatMul(par.rot,rot2,q);
- }
- //else{
- // par.rot[0]=1.0f;
- // par.rot[1]=par.rot[2]=par.rot[3]=0.0f;
- //}
-
- /* curve taper */
- if(cu->taperobj)
- VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100));
-
- else{ /* curve size*/
- if(cu->flag & CU_PATH_RADIUS) {
- VecMulf(pa_loc, radius);
- }
- }
- par.co[0]=par.co[1]=par.co[2]=0.0f;
- VECCOPY(key.co,pa_loc);
- do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0);
- do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f);
- VECCOPY(pa_loc,key.co);
-
- VECADD(pa_loc,pa_loc,guidevec);
- VECSUB(pa_loc,pa_loc,pa_zero);
- VECADDFAC(effect,effect,pa_loc,f_force);
- VECADDFAC(veffect,veffect,guidedir,f_force);
- totforce+=f_force;
- }
- }
+ /* curve tilt */
+ VecRotToQuat(guidedir, guidevec[3] - eff->guide_loc[3], rot2);
+ QuatMulVecf(rot2, vec_to_point);
}
- if(totforce!=0.0){
- if(totforce>1.0)
- VecMulf(effect,1.0f/totforce);
- CLAMP(totforce,0.0,1.0);
- VECADD(effect,effect,pa_zero);
- VecLerpf(state->co,state->co,effect,totforce);
+ /* curve taper */
+ if(cu->taperobj)
+ VecMulf(vec_to_point, calc_taper(eff->scene, cu->taperobj, (int)(data->strength*guidetime*100.0), 100));
- Normalize(veffect);
- VecMulf(veffect,VecLength(state->vel));
- VECCOPY(state->vel,veffect);
- return 1;
+ else{ /* curve size*/
+ if(cu->flag & CU_PATH_RADIUS) {
+ VecMulf(vec_to_point, radius);
+ }
}
+ par.co[0] = par.co[1] = par.co[2] = 0.0f;
+ VECCOPY(key.co, vec_to_point);
+ do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0);
+ do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f);
+ VECCOPY(vec_to_point, key.co);
+
+ VECADD(vec_to_point, vec_to_point, guidevec);
+ //VECSUB(pa_loc,pa_loc,pa_zero);
+ VECADDFAC(effect, effect, vec_to_point, data->strength);
+ VECADDFAC(veffect, veffect, guidedir, data->strength);
+ totstrength += data->strength;
+ }
+
+ if(totstrength != 0.0){
+ if(totstrength > 1.0)
+ VecMulf(effect, 1.0f / totstrength);
+ CLAMP(totstrength, 0.0, 1.0);
+ //VECADD(effect,effect,pa_zero);
+ VecLerpf(state->co, state->co, effect, totstrength);
+
+ Normalize(veffect);
+ VecMulf(veffect, VecLength(state->vel));
+ VECCOPY(state->vel, veffect);
+ return 1;
}
return 0;
}
@@ -2075,20 +2055,24 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
VECADDFAC(state->co,state->co,mat[0],rough[0]);
VECADDFAC(state->co,state->co,mat[1],rough[1]);
}
-static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
+static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
{
- float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
+ float force[3] = {0.0f,0.0f,0.0f};
ParticleKey eff_key;
- ParticleData *pa;
+ EffectedPoint epoint;
+
+ /* Don't apply effectors for dynamic hair, otherwise the effectors don't get applied twice. */
+ if(sim->psys->flag & PSYS_HAIR_DYNAMICS)
+ return;
VECCOPY(eff_key.co,(ca-1)->co);
VECCOPY(eff_key.vel,(ca-1)->vel);
QUATCOPY(eff_key.rot,(ca-1)->rot);
- pa= psys->particles+i;
- do_effectors(i, pa, &eff_key, scene, ob, psys, rootco, force, vel, dfra, cfra);
+ pd_point_from_particle(sim, sim->psys->particles+i, &eff_key, &epoint);
+ pdDoEffectors(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL);
- VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
+ VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps);
VecAddf(force, force, vec);
@@ -2155,12 +2139,12 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
}
return vg;
}
-void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys)
+void psys_find_parents(ParticleSimulationData *sim)
{
- ParticleSettings *part=psys->part;
+ ParticleSettings *part=sim->psys->part;
KDTree *tree;
ChildParticle *cpa;
- int p, totparent,totchild=psys->totchild;
+ int p, totparent,totchild=sim->psys->totchild;
float co[3], orco[3];
int from=PART_FROM_FACE;
totparent=(int)(totchild*part->parents*0.3);
@@ -2170,15 +2154,15 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys
tree=BLI_kdtree_new(totparent);
- for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
- psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
+ for(p=0,cpa=sim->psys->child; p<totparent; p++,cpa++){
+ psys_particle_on_emitter(sim->psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
BLI_kdtree_insert(tree, p, orco, NULL);
}
BLI_kdtree_balance(tree);
for(; p<totchild; p++,cpa++){
- psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
+ psys_particle_on_emitter(sim->psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
cpa->parent=BLI_kdtree_find_nearest(tree, orco, NULL, NULL);
}
@@ -2216,11 +2200,11 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa
VECCOPY(nor, vnor);
}
-int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate)
+static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate)
{
ParticleThreadContext *ctx= threads[0].ctx;
- Object *ob= ctx->ob;
- ParticleSystem *psys= ctx->psys;
+/* Object *ob= ctx->sim.ob; */
+ ParticleSystem *psys= ctx->sim.psys;
ParticleSettings *part = psys->part;
ParticleEditSettings *pset = &scene->toolsettings->particle;
int totparent=0, between=0;
@@ -2253,10 +2237,10 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
if(totchild==0) return 0;
/* init random number generator */
- if(ctx->psys->part->flag & PART_ANIM_BRANCHING)
- seed= 31415926 + ctx->psys->seed + (int)cfra;
+ if(ctx->sim.psys->part->flag & PART_ANIM_BRANCHING)
+ seed= 31415926 + ctx->sim.psys->seed + (int)cfra;
else
- seed= 31415926 + ctx->psys->seed;
+ seed= 31415926 + ctx->sim.psys->seed;
if(part->flag & PART_BRANCHING || ctx->editupdate || totchild < 10000)
totthread= 1;
@@ -2274,7 +2258,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
ctx->parent_pass= 0;
ctx->cfra= cfra;
- psys->lattice = psys_get_lattice(scene, ob, psys);
+ psys->lattice = psys_get_lattice(&ctx->sim);
/* cache all relevant vertex groups if they exist */
if(part->from!=PART_FROM_PARTICLE){
@@ -2300,11 +2284,11 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
}
/* note: this function must be thread safe, except for branching! */
-void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i)
+static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i)
{
ParticleThreadContext *ctx= thread->ctx;
- Object *ob= ctx->ob;
- ParticleSystem *psys = ctx->psys;
+ Object *ob= ctx->sim.ob;
+ ParticleSystem *psys = ctx->sim.psys;
ParticleSettings *part = psys->part;
ParticleCacheKey **cache= psys->childcache;
ParticleCacheKey **pcache= psys->pathcache;
@@ -2373,7 +2357,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
cpa_fuv = cpa->fuv;
cpa_from = PART_FROM_FACE;
- psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
+ psys_particle_on_emitter(ctx->sim.psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
if(part->path_start==0.0f) {
/* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
@@ -2383,7 +2367,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
pa = psys->particles + cpa->parent;
- psys_mat_hair_to_global(ob, ctx->psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
pa=0;
}
@@ -2405,9 +2389,9 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
cpa_num=pa->num;
cpa_fuv=pa->fuv;
- psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
+ psys_particle_on_emitter(ctx->sim.psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
- psys_mat_hair_to_global(ob, ctx->psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
}
keys->steps = ctx->steps;
@@ -2424,7 +2408,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
/* get different child parameters from textures & vgroups */
get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
- if(ptex.exist < cpa->rand[1]) {
+ if(ptex.exist < PSYS_FRAND(i + 24)) {
keys->steps = -1;
return;
}
@@ -2473,7 +2457,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
if(part->flag & PART_CHILD_EFFECT) {
for(k=0,state=keys; k<=ctx->steps; k++,state++) {
if(k) {
- do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
+ do_path_effectors(&ctx->sim, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
}
else {
VecSubf(eff_vec,(state+1)->co,state->co);
@@ -2499,7 +2483,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
}
/* apply different deformations to the child path */
- do_child_modifiers(ctx->scene, ob, psys, part, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)state, t);
+ do_child_modifiers(&ctx->sim, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)state, t);
/* TODO: better branching */
//if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING)
@@ -2576,7 +2560,7 @@ static void *exec_child_path_cache(void *data)
{
ParticleThread *thread= (ParticleThread*)data;
ParticleThreadContext *ctx= thread->ctx;
- ParticleSystem *psys= ctx->psys;
+ ParticleSystem *psys= ctx->sim.psys;
ParticleCacheKey **cache= psys->childcache;
ChildParticle *cpa;
int i, totchild= ctx->totchild, first= 0;
@@ -2593,21 +2577,21 @@ static void *exec_child_path_cache(void *data)
return 0;
}
-void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate)
+void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupdate)
{
- ParticleSettings *part = psys->part;
+ ParticleSettings *part = sim->psys->part;
ParticleThread *pthreads;
ParticleThreadContext *ctx;
ParticleCacheKey **cache;
ListBase threads;
int i, totchild, totparent, totthread;
- if(psys->flag & PSYS_GLOBAL_HAIR)
+ if(sim->psys->flag & PSYS_GLOBAL_HAIR)
return;
- pthreads= psys_threads_create(scene, ob, psys);
+ pthreads= psys_threads_create(sim);
- if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) {
+ if(!psys_threads_init_path(pthreads, sim->scene, cfra, editupdate)) {
psys_threads_free(pthreads);
return;
}
@@ -2616,14 +2600,14 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
totchild= ctx->totchild;
totparent= ctx->totparent;
- if(editupdate && psys->childcache && !(part->flag & PART_BRANCHING) && totchild == psys->totchildcache) {
- cache = psys->childcache;
+ if(editupdate && sim->psys->childcache && !(part->flag & PART_BRANCHING) && totchild == sim->psys->totchildcache) {
+ cache = sim->psys->childcache;
}
else {
/* clear out old and create new empty path cache */
- free_child_path_cache(psys);
- psys->childcache= psys_alloc_path_cache_buffers(&psys->childcachebufs, totchild, ctx->steps+1);
- psys->totchildcache = totchild;
+ free_child_path_cache(sim->psys);
+ sim->psys->childcache= psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps+1);
+ sim->psys->totchildcache = totchild;
}
totthread= pthreads[0].tot;
@@ -2661,27 +2645,29 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
/* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */
/* -Makes child strands possible and creates them too into the cache. */
/* -Cached path data is also used to determine cut position for the editmode tool. */
-void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra)
+void psys_cache_paths(ParticleSimulationData *sim, float cfra)
{
- ParticleCacheKey *ca, **cache= psys->pathcache;
- ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
+ PARTICLE_PSMD;
+ ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
+ ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
- ParticleEditSettings *pset = &scene->toolsettings->particle;
+ ParticleCacheKey *ca, **cache= psys->pathcache;
DerivedMesh *hair_dm = psys->hair_out_dm;
- ParticleData *pa = psys->particles;
ParticleKey result;
Material *ma;
ParticleInterpolationData pind;
+
+ PARTICLE_P;
float birthtime = 0.0, dietime = 0.0;
- float t, time = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec;
+ float t, time = 0.0, dfra = 1.0, frs_sec = sim->scene->r.frs_sec;
float col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
float prev_tangent[3], hairmat[4][4];
float rotmat[3][3];
- int k,i;
+ int k;
int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step));
int totpart = psys->totpart;
float length, vec[3];
@@ -2693,7 +2679,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
return;
- if(psys_in_edit_mode(scene, psys))
+ if(psys_in_edit_mode(sim->scene, psys))
if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0)
return;
@@ -2706,8 +2692,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
psys_free_path_cache(psys, psys->edit);
cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1);
- psys->lattice = psys_get_lattice(scene, ob, psys);
- ma= give_current_material(ob, psys->part->omat);
+ psys->lattice = psys_get_lattice(sim);
+ ma= give_current_material(sim->ob, psys->part->omat);
if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
VECCOPY(col, &ma->r)
@@ -2720,12 +2706,9 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
}
/*---first main loop: create all actual particles' paths---*/
- for(i=0; i<totpart; i++, pa++){
- if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST)
- continue;
-
+ LOOP_SHOWN_PARTICLES {
if(!psys->totchild) {
- BLI_srandom(psys->seed + i);
+ BLI_srandom(psys->seed + p);
pa_length = 1.0f - part->randlength * BLI_frand();
if(vg_length)
pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length);
@@ -2737,15 +2720,15 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
pind.dm = hair_dm;
- memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
+ memset(cache[p], 0, sizeof(*cache[p])*(steps+1));
- cache[i]->steps = steps;
+ cache[p]->steps = steps;
/*--get the first data points--*/
- init_particle_interpolation(ob, psys, pa, &pind);
+ init_particle_interpolation(sim->ob, sim->psys, pa, &pind);
/* hairmat is needed for for non-hair particle too so we get proper rotations */
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, psmd->dm, psys->part->from, pa, hairmat);
VECCOPY(rotmat[0], hairmat[2]);
VECCOPY(rotmat[1], hairmat[1]);
VECCOPY(rotmat[2], hairmat[0]);
@@ -2761,26 +2744,26 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
}
if(birthtime >= dietime) {
- cache[i]->steps = -1;
+ cache[p]->steps = -1;
continue;
}
dietime = birthtime + pa_length * (dietime - birthtime);
/*--interpolate actual path from data points--*/
- for(k=0, ca=cache[i]; k<=steps; k++, ca++){
+ for(k=0, ca=cache[p]; k<=steps; k++, ca++){
time = (float)k / (float)steps;
t = birthtime + time * (dietime - birthtime);
result.time = -t;
- do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
+ do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, &result);
/* dynamic hair is in object space */
/* keyed and baked are allready in global space */
if(hair_dm)
- Mat4MulVecfl(ob->obmat, result.co);
+ Mat4MulVecfl(sim->ob->obmat, result.co);
else if(!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR))
Mat4MulVecfl(hairmat, result.co);
@@ -2790,23 +2773,23 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
/*--modify paths and calculate rotation & velocity--*/
- VecSubf(vec,(cache[i]+1)->co,cache[i]->co);
+ VecSubf(vec,(cache[p]+1)->co,cache[p]->co);
length = VecLength(vec);
effector= 1.0f;
if(vg_effector)
effector*= psys_particle_value_from_verts(psmd->dm,psys->part->from,pa,vg_effector);
- for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
+ for(k=0, ca=cache[p]; k<=steps; k++, ca++) {
if(!(psys->flag & PSYS_GLOBAL_HAIR)) {
/* apply effectors */
if(!(psys->part->flag & PART_CHILD_EFFECT) && k)
- do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
+ do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec);
/* apply guide curves to path data */
- if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
+ if(sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT)==0)
/* ca is safe to cast, since only co and vel are used */
- do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
+ do_guides(sim->psys->effectors, (ParticleKey*)ca, p, (float)k/(float)steps);
/* apply lattice */
if(psys->lattice)
@@ -3022,23 +3005,7 @@ void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, flo
if(time) *time=key->time;
}
/*-------changing particle keys from space to another-------*/
-void psys_key_to_object(Object *ob, ParticleKey *key, float imat[][4]){
- float q[4], imat2[4][4];
-
- if(imat==0){
- Mat4Invert(imat2,ob->obmat);
- imat=imat2;
- }
-
- VECADD(key->vel,key->vel,key->co);
-
- Mat4MulVecfl(imat,key->co);
- Mat4MulVecfl(imat,key->vel);
- Mat4ToQuat(imat,q);
-
- VECSUB(key->vel,key->vel,key->co);
- QuatMul(key->rot,q,key->rot);
-}
+#if 0
static void key_from_object(Object *ob, ParticleKey *key){
float q[4];
@@ -3051,6 +3018,7 @@ static void key_from_object(Object *ob, ParticleKey *key){
VECSUB(key->vel,key->vel,key->co);
QuatMul(key->rot,q,key->rot);
}
+#endif
static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4])
{
@@ -3229,8 +3197,6 @@ void object_remove_particle_system(Scene *scene, Object *ob)
}
static void default_particle_settings(ParticleSettings *part)
{
- int i;
-
part->type= PART_EMITTER;
part->distr= PART_DISTR_JIT;
part->draw_as = PART_DRAW_REND;
@@ -3241,7 +3207,7 @@ static void default_particle_settings(ParticleSettings *part)
part->flag=PART_REACT_MULTIPLE|PART_HAIR_GEOMETRY|PART_EDISTR|PART_TRAND;
part->sta= 1.0;
- part->end= 100.0;
+ part->end= 200.0;
part->lifetime= 50.0;
part->jitfac= 1.0;
part->totpart= 1000;
@@ -3291,10 +3257,6 @@ static void default_particle_settings(ParticleSettings *part)
part->keyed_loops = 1;
- for(i=0; i<10; i++)
- part->effector_weight[i]=1.0f;
-
-
#if 0 // XXX old animation system
part->ipo = NULL;
#endif // XXX old animation system
@@ -3303,6 +3265,9 @@ static void default_particle_settings(ParticleSettings *part)
part->simplify_rate= 1.0f;
part->simplify_transition= 0.1f;
part->simplify_viewport= 0.8;
+
+ if(!part->effector_weights)
+ part->effector_weights = BKE_add_effector_weights(NULL);
}
@@ -3390,59 +3355,6 @@ void make_local_particlesettings(ParticleSettings *part)
}
}
}
-void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
-{
- Base *base = scene->base.first;
- ParticleSystem *psys;
- int flush;
-
- for(base = scene->base.first; base; base = base->next) {
- flush = 0;
- for(psys = base->object->particlesystem.first; psys; psys=psys->next) {
- if(psys->part == part) {
- psys->recalc |= recalc;
- flush++;
- }
- }
- if(flush)
- DAG_id_flush_update(&base->object->id, OB_RECALC_DATA);
- }
-}
-
-LinkNode *psys_using_settings(struct Scene *scene, ParticleSettings *part, int flush_update)
-{
- Object *ob, *tob;
- ParticleSystem *psys, *tpsys;
- LinkNode *node= NULL;
- int found;
-
- /* update all that have same particle settings */
- for(ob=G.main->object.first; ob; ob=ob->id.next) {
- found= 0;
-
- for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- if(psys->part == part) {
- BLI_linklist_append(&node, psys);
- found++;
- }
- else if(psys->part->type == PART_REACTOR){
- tob= (psys->target_ob)? psys->target_ob: ob;
- tpsys= BLI_findlink(&tob->particlesystem, psys->target_psys-1);
-
- if(tpsys && tpsys->part==part) {
- BLI_linklist_append(&node, tpsys);
- found++;
- }
- }
- }
-
- if(flush_update && found)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
-
- return node;
-}
-
/************************************************/
/* Textures */
@@ -3498,9 +3410,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
mtex=ma->mtex[m];
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
float def=mtex->def_var;
- float var=mtex->varfac;
short blend=mtex->blendtype;
- short neg=mtex->pmaptoneg;
if((mtex->texco & TEXCO_UV) && fw) {
if(!get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texco))
@@ -3515,18 +3425,18 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
ptex->time=0.0;
setvars|=MAP_PA_TIME;
}
- ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,var,blend,neg & MAP_PA_TIME);
+ ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,mtex->timefac,blend);
}
if((event & mtex->pmapto) & MAP_PA_LENGTH)
- ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
+ ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
if((event & mtex->pmapto) & MAP_PA_CLUMP)
- ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
+ ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
if((event & mtex->pmapto) & MAP_PA_KINK)
- ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
+ ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
if((event & mtex->pmapto) & MAP_PA_ROUGH)
- ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,var,blend,neg & MAP_PA_ROUGH);
+ ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,mtex->roughfac,blend);
if((event & mtex->pmapto) & MAP_PA_DENS)
- ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
+ ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
}
}
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
@@ -3540,7 +3450,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
}
if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
}
-void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event)
+void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *pa, ParticleTexture *ptex, int event)
{
MTex *mtex;
int m;
@@ -3550,19 +3460,17 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
if(ma) for(m=0; m<MAX_MTEX; m++){
mtex=ma->mtex[m];
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
- float var=mtex->varfac;
float def=mtex->def_var;
short blend=mtex->blendtype;
- short neg=mtex->pmaptoneg;
- if((mtex->texco & TEXCO_UV) && ELEM(psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
- if(!get_particle_uv(psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
+ if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
/* failed to get uv's, let's try orco's */
- psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
+ psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
}
}
else {
- psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
+ psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
}
externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3);
@@ -3570,29 +3478,31 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
if((event & mtex->pmapto) & MAP_PA_TIME){
/* the first time has to set the base value for time regardless of blend mode */
if((setvars&MAP_PA_TIME)==0){
- ptex->time *= 1.0f - var;
- ptex->time += var * ((neg & MAP_PA_TIME)? 1.0f - value : value);
+ int flip= (mtex->timefac < 0.0f);
+ float timefac= fabsf(mtex->timefac);
+ ptex->time *= 1.0f - timefac;
+ ptex->time += timefac * ((flip)? 1.0f - value : value);
setvars |= MAP_PA_TIME;
}
else
- ptex->time= texture_value_blend(def,ptex->time,value,var,blend,neg & MAP_PA_TIME);
+ ptex->time= texture_value_blend(def,ptex->time,value,mtex->timefac,blend);
}
if((event & mtex->pmapto) & MAP_PA_LIFE)
- ptex->life= texture_value_blend(def,ptex->life,value,var,blend,neg & MAP_PA_LIFE);
+ ptex->life= texture_value_blend(def,ptex->life,value,mtex->lifefac,blend);
if((event & mtex->pmapto) & MAP_PA_DENS)
- ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
+ ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
if((event & mtex->pmapto) & MAP_PA_SIZE)
- ptex->size= texture_value_blend(def,ptex->size,value,var,blend,neg & MAP_PA_SIZE);
+ ptex->size= texture_value_blend(def,ptex->size,value,mtex->sizefac,blend);
if((event & mtex->pmapto) & MAP_PA_IVEL)
- ptex->ivel= texture_value_blend(def,ptex->ivel,value,var,blend,neg & MAP_PA_IVEL);
+ ptex->ivel= texture_value_blend(def,ptex->ivel,value,mtex->ivelfac,blend);
if((event & mtex->pmapto) & MAP_PA_PVEL)
- texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,var,blend);
+ texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,mtex->pvelfac,blend);
if((event & mtex->pmapto) & MAP_PA_LENGTH)
- ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
+ ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
if((event & mtex->pmapto) & MAP_PA_CLUMP)
- ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
+ ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
if((event & mtex->pmapto) & MAP_PA_KINK)
- ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_CLUMP);
+ ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
}
}
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
@@ -3607,38 +3517,9 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
/************************************************/
/* Particle State */
/************************************************/
-float psys_get_timestep(ParticleSettings *part)
+float psys_get_timestep(ParticleSimulationData *sim)
{
- return 0.04f*part->timetweak;
-}
-/* part->size should be updated with possible ipo effection before this is called */
-float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, IpoCurve *icu_size, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, float *vg_size)
-{
- ParticleTexture ptex;
- float size=1.0f;
-
- BLI_srandom(psys->seed + (pa - psys->particles) + 100);
-
- if(ma && part->from!=PART_FROM_PARTICLE){
- ptex.size=size;
- psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_SIZE);
- size=ptex.size;
- }
-
-#if 0 // XXX old animation system
- if(icu_size){
- calc_icu(icu_size,pa->time);
- size*=icu_size->curval;
- }
-#endif // XXX old animation system
-
- if(vg_size)
- size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size);
-
- if(part->randsize!=0.0)
- size*= 1.0f - part->randsize * BLI_frand();
-
- return size*part->size;
+ return 0.04f * sim->psys->part->timetweak;
}
float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *birthtime, float *dietime)
{
@@ -3653,7 +3534,7 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra,
w++;
}
- life = part->lifetime*(1.0f-part->randlife*cpa->rand[1]);
+ life = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(cpa - psys->child + 25));
}
else{
ParticleData *pa = psys->particles + cpa->parent;
@@ -3702,13 +3583,16 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
size*=part->childsize;
if(part->childrandsize!=0.0)
- size *= 1.0f - part->childrandsize*cpa->rand[2];
+ size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26);
return size;
}
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex)
{
- ptex->length= 1.0f - part->randlength*cpa->rand[0];
+ ParticleSystem *psys = ctx->sim.psys;
+ int i = cpa - psys->child;
+
+ ptex->length= 1.0f - part->randlength * PSYS_FRAND(i + 26);
ptex->clump=1.0;
ptex->kink=1.0;
ptex->rough1= 1.0;
@@ -3717,13 +3601,13 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
ptex->exist= 1.0;
ptex->effector= 1.0;
- ptex->length*= part->clength_thres < cpa->rand[1] ? part->clength : 1.0f;
+ ptex->length*= part->clength_thres < PSYS_FRAND(i + 27) ? part->clength : 1.0f;
get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,ptex,
MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
- if(ptex->exist < cpa->rand[1])
+ if(ptex->exist < PSYS_FRAND(i + 24))
return;
if(ctx->vg_length)
@@ -3741,18 +3625,20 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
if(ctx->vg_effector)
ptex->effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector);
}
-static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t)
+static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t)
{
+ ParticleSettings *part = sim->psys->part;
+ int i = cpa - sim->psys->child;
int guided = 0;
if(part->flag & PART_CHILD_EFFECT)
/* state is safe to cast, since only co and vel are used */
- guided = do_guide(scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors));
+ guided = do_guides(sim->psys->effectors, (ParticleKey*)state, cpa->parent, t);
if(guided==0){
if(part->kink)
do_prekink(state, par, par_rot, t, part->kink_freq * ptex->kink, part->kink_shape,
- part->kink_amp, part->kink, part->kink_axis, ob->obmat);
+ part->kink_amp, part->kink, part->kink_axis, sim->ob->obmat);
do_clump(state, par, t, part->clumpfac, part->clumppow, ptex->clump);
}
@@ -3761,17 +3647,18 @@ static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, P
do_rough(orco, mat, t, ptex->rough1*part->rough1, part->rough1_size, 0.0, state);
if(part->rough2 != 0.0 && ptex->rough2 != 0.0)
- do_rough(cpa->rand, mat, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state);
+ do_rough(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state);
if(part->rough_end != 0.0 && ptex->roughe != 0.0)
- do_rough_end(cpa->rand, mat, t, ptex->roughe*part->rough_end, part->rough_end_shape, state);
+ do_rough_end(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, ptex->roughe*part->rough_end, part->rough_end_shape, state);
}
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
-void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel)
+void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, int vel)
{
- ParticleSettings *part = psys->part;
- ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- Material *ma = give_current_material(ob, part->omat);
+ PARTICLE_PSMD;
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = sim->psys->part;
+ Material *ma = give_current_material(sim->ob, part->omat);
ParticleData *pa;
ChildParticle *cpa;
ParticleTexture ptex;
@@ -3779,7 +3666,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
ParticleThreadContext ctx; /* fake thread context for child modifiers */
ParticleInterpolationData pind;
- float t, frs_sec = scene->r.frs_sec;
+ float t, frs_sec = sim->scene->r.frs_sec;
float co[3], orco[3];
float hairmat[4][4];
int totparent = 0;
@@ -3807,17 +3694,17 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
pind.cache = cached ? psys->pointcache : NULL;
pind.epoint = NULL;
pind.dm = psys->hair_out_dm;
- init_particle_interpolation(ob, psys, pa, &pind);
+ init_particle_interpolation(sim->ob, psys, pa, &pind);
do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state);
if(!keyed && !cached) {
if((pa->flag & PARS_REKEY)==0) {
- psys_mat_hair_to_global(ob, psmd->dm, part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, sim->psmd->dm, part->from, pa, hairmat);
Mat4MulVecfl(hairmat, state->co);
Mat4Mul3Vecfl(hairmat, state->vel);
- if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
- do_guide(scene, state, p, state->time, &psys->effectors);
+ if(sim->psys->effectors && (part->flag & PART_CHILD_GUIDE)==0) {
+ do_guides(sim->psys->effectors, state, p, state->time);
/* TODO: proper velocity handling */
}
@@ -3850,7 +3737,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
/* get parent states */
while(w<4 && cpa->pa[w]>=0){
keys[w].time = state->time;
- psys_get_particle_on_path(scene, ob, psys, cpa->pa[w], keys+w, 1);
+ psys_get_particle_on_path(sim, cpa->pa[w], keys+w, 1);
w++;
}
@@ -3870,14 +3757,14 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
pa = psys->particles + cpa->parent;
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
pa=0;
}
else{
/* get the parent state */
keys->time = state->time;
- psys_get_particle_on_path(scene, ob, psys, cpa->parent, keys,1);
+ psys_get_particle_on_path(sim, cpa->parent, keys,1);
/* get the original coordinates (orco) for texture usage */
pa=psys->particles+cpa->parent;
@@ -3888,7 +3775,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0);
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
}
/* correct child ipo timing */
@@ -3937,7 +3824,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
copy_particle_key(&tstate, state, 1);
/* apply different deformations to the child path */
- do_child_modifiers(scene, ob, psys, part, &ptex, par, par->rot, cpa, orco, hairmat, state, t);
+ do_child_modifiers(sim, &ptex, par, par->rot, cpa, orco, hairmat, state, t);
/* try to estimate correct velocity */
if(vel){
@@ -3946,13 +3833,13 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
if(t>=0.001f){
tstate.time=t-0.001f;
- psys_get_particle_on_path(scene,ob,psys,p,&tstate,0);
+ psys_get_particle_on_path(sim,p,&tstate,0);
VECSUB(state->vel,state->co,tstate.co);
Normalize(state->vel);
}
else{
tstate.time=t+0.001f;
- psys_get_particle_on_path(scene, ob,psys,p,&tstate,0);
+ psys_get_particle_on_path(sim,p,&tstate,0);
VECSUB(state->vel,tstate.co,state->co);
Normalize(state->vel);
}
@@ -3962,39 +3849,50 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
}
}
/* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */
-int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int always){
- ParticleSettings *part=psys->part;
- ParticleData *pa=0;
+int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always){
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ ParticleData *pa = NULL;
+ ChildParticle *cpa = NULL;
float cfra;
- int totpart=psys->totpart, between=0;
+ int totpart = psys->totpart;
/* negative time means "use current time" */
- if(state->time>0)
- cfra=state->time;
- else
- cfra= bsystem_time(scene, 0, (float)scene->r.cfra,0.0);
+ cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0);
- if(psys->totchild && p>=totpart){
- if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
- between=1;
- }
- else
- pa=psys->particles+(psys->child+p-totpart)->parent;
- }
- else
- pa=psys->particles+p;
-
- if(between){
- state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra,NULL,NULL);
+ if(p>=totpart){
+ if(!psys->totchild)
+ return 0;
- if(always==0)
- if((state->time<0.0 && (part->flag & PART_UNBORN)==0)
- || (state->time>1.0 && (part->flag & PART_DIED)==0))
+ if(part->from != PART_FROM_PARTICLE && part->childtype == PART_CHILD_FACES){
+ if(!(psys->flag & PSYS_KEYED))
return 0;
+
+ cpa = psys->child + p - totpart;
+
+ state->time = psys_get_child_time(psys, cpa, cfra, NULL, NULL);
+
+ if(!always)
+ if((state->time < 0.0 && !(part->flag & PART_UNBORN))
+ || (state->time > 1.0 && !(part->flag & PART_DIED)))
+ return 0;
+
+ state->time= (cfra - (part->sta + (part->end - part->sta) * PSYS_FRAND(p + 23))) / (part->lifetime * PSYS_FRAND(p + 24));
+
+ psys_get_particle_on_path(sim, p, state,1);
+ return 1;
+ }
+ else {
+ cpa = sim->psys->child + p - totpart;
+ pa = sim->psys->particles + cpa->parent;
+ }
}
- else{
- if(pa->alive==PARS_KILLED) return 0;
- if(always==0)
+ else {
+ pa = sim->psys->particles + p;
+ }
+
+ if(pa) {
+ if(!always)
if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
return 0;
@@ -4002,38 +3900,28 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
state->time = MIN2(state->time, pa->dietime);
}
- if(psys->flag & PSYS_KEYED){
- if(between){
- ChildParticle *cpa=psys->child+p-totpart;
- state->time= (cfra-(part->sta+(part->end-part->sta)*cpa->rand[0]))/(part->lifetime*cpa->rand[1]);
- }
- else
- state->time= -cfra;
-
- psys_get_particle_on_path(scene, ob, psys, p, state,1);
+ if(sim->psys->flag & PSYS_KEYED){
+ state->time= -cfra;
+ psys_get_particle_on_path(sim, p, state,1);
return 1;
}
else{
- if(between)
- return 0; /* currently not supported */
- else if(psys->totchild && p>=psys->totpart){
- ChildParticle *cpa=psys->child+p-psys->totpart;
+ if(cpa){
ParticleKey *key1;
float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime;
- pa = psys->particles + cpa->parent;
key1=&pa->state;
offset_child(cpa, key1, state, part->childflat, part->childrad);
CLAMP(t,0.0,1.0);
if(part->kink) /* TODO: part->kink_freq*pa_kink */
- do_prekink(state,key1,key1->rot,t,part->kink_freq,part->kink_shape,part->kink_amp,part->kink,part->kink_axis,ob->obmat);
+ do_prekink(state,key1,key1->rot,t,part->kink_freq,part->kink_shape,part->kink_amp,part->kink,part->kink_axis,sim->ob->obmat);
/* TODO: pa_clump vgroup */
do_clump(state,key1,t,part->clumpfac,part->clumppow,1.0);
if(psys->lattice)
- calc_latt_deform(psys->lattice, state->co,1.0f);
+ calc_latt_deform(sim->psys->lattice, state->co,1.0f);
}
else{
if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED))
@@ -4044,7 +3932,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
/* let's interpolate to try to be as accurate as possible */
if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) {
ParticleKey keys[4];
- float dfra, keytime, frs_sec = scene->r.frs_sec;
+ float dfra, keytime, frs_sec = sim->scene->r.frs_sec;
if(pa->prev_state.time >= pa->state.time) {
/* prev_state is wrong so let's not use it, this can happen at frame 1 or particle birth */
@@ -4079,8 +3967,8 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
}
}
- if(psys->lattice)
- calc_latt_deform(psys->lattice, state->co,1.0f);
+ if(sim->psys->lattice)
+ calc_latt_deform(sim->psys->lattice, state->co,1.0f);
}
return 1;
@@ -4136,8 +4024,11 @@ void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemMo
}
}
-void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, 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], float *scale)
{
+ Object *ob = sim->ob;
+ ParticleSystem *psys = sim->psys;
+ ParticleSystemModifierData *psmd = sim->psmd;
float loc[3], nor[3], vec[3], side[3], len, obrotmat[4][4], qmat[4][4];
float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
@@ -4145,7 +4036,7 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys
len= Normalize(vec);
if(pa)
- psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+ psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
else
psys_particle_on_emitter(psmd,
(psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index fb12cfe3147..d757372f17b 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -58,7 +58,7 @@
#include "BLI_blenlib.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
-#include "BLI_linklist.h"
+#include "BLI_listbase.h"
#include "BLI_threads.h"
#include "BKE_anim.h"
@@ -122,7 +122,6 @@ static int get_current_display_percentage(ParticleSystem *psys)
void psys_reset(ParticleSystem *psys, int mode)
{
- ParticleSettings *part= psys->part;
PARTICLE_P;
if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
@@ -133,9 +132,6 @@ void psys_reset(ParticleSystem *psys, int mode)
psys->totkeyed= 0;
psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
- if(psys->reactevents.first)
- BLI_freelistN(&psys->reactevents);
-
if(psys->edit && psys->free_edit) {
psys->free_edit(psys->edit);
psys->edit = NULL;
@@ -165,20 +161,22 @@ void psys_reset(ParticleSystem *psys, int mode)
psys->pointcache->simframe= 0;
}
-static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
+static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
{
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
ParticleData *newpars = NULL;
BoidParticle *newboids = NULL;
PARTICLE_P;
int totpart, totsaved = 0;
if(new_totpart<0) {
- if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
- totpart= psys->part->grid_res;
+ if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT) {
+ totpart= part->grid_res;
totpart*=totpart*totpart;
}
else
- totpart=psys->part->totpart;
+ totpart=part->totpart;
}
else
totpart=new_totpart;
@@ -213,6 +211,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
if(pa->hair) MEM_freeN(pa->hair);
MEM_freeN(psys->particles);
+ psys_free_pdd(psys);
}
psys->particles=newpars;
@@ -606,13 +605,13 @@ static int binary_search_distribution(float *sum, int n, float value)
/* note: this function must be thread safe, for from == PART_FROM_CHILD */
#define ONLY_WORKING_WITH_PA_VERTS 0
-void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
+static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
{
ParticleThreadContext *ctx= thread->ctx;
- Object *ob= ctx->ob;
+ Object *ob= ctx->sim.ob;
DerivedMesh *dm= ctx->dm;
ParticleData *tpa;
- ParticleSettings *part= ctx->psys->part;
+/* ParticleSettings *part= ctx->sim.psys->part; */
float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3];
float cur_d, min_d, randu, randv;
int from= ctx->from;
@@ -625,7 +624,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
pa->num= ctx->index[p];
pa->fuv[0] = 1.0f;
pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
- //pa->verts[0] = pa->verts[1] = pa->verts[2] = 0;
#if ONLY_WORKING_WITH_PA_VERTS
if(ctx->tree){
@@ -653,7 +651,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
ctx->jitoff[i]++;
- //ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel);
break;
case PART_DISTR_RAND:
randu= rng_getFloat(thread->rng);
@@ -663,12 +660,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
}
pa->foffset= 0.0f;
- /*
- pa->verts[0] = mface->v1;
- pa->verts[1] = mface->v2;
- pa->verts[2] = mface->v3;
- */
-
/* experimental */
if(from==PART_FROM_VOLUME){
MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
@@ -724,10 +715,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
}
}
else if(from == PART_FROM_PARTICLE) {
- //pa->verts[0]=0; /* not applicable */
- //pa->verts[1]=0;
- //pa->verts[2]=0;
-
tpa=ctx->tpars+ctx->index[p];
pa->num=ctx->index[p];
pa->fuv[0]=tpa->fuv[0];
@@ -743,42 +730,30 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
cpa->num=0;
cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
- cpa->rand[0]=cpa->rand[1]=cpa->rand[2]=0.0f;
return;
}
mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE);
- //switch(distr){
- // case PART_DISTR_JIT:
- // i=index[p];
- // psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mf->v4, cpa->fuv);
- // ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel);
- // break;
- // case PART_DISTR_RAND:
- randu= rng_getFloat(thread->rng);
- randv= rng_getFloat(thread->rng);
- psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
- // break;
- //}
+ randu= rng_getFloat(thread->rng);
+ randv= rng_getFloat(thread->rng);
+ psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
- cpa->rand[0] = rng_getFloat(thread->rng);
- cpa->rand[1] = rng_getFloat(thread->rng);
- cpa->rand[2] = rng_getFloat(thread->rng);
cpa->num = ctx->index[p];
if(ctx->tree){
KDTreeNearest ptn[10];
- int w,maxw, do_seams;
+ int w,maxw;//, do_seams;
float maxd,mind,dd,totw=0.0;
int parent[10];
float pweight[10];
- do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);
+ /*do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);*/
psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
- maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
+ //maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
+ maxw = BLI_kdtree_find_n_nearest(ctx->tree,4,orco1,ornor1,ptn);
maxd=ptn[maxw-1].dist;
mind=ptn[0].dist;
@@ -788,70 +763,68 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
for(w=0; w<maxw; w++){
parent[w]=ptn[w].index;
pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
- //pweight[w]= (1.0f - ptn[w].dist*ptn[w].dist/(maxd*maxd));
- //pweight[w] *= pweight[w];
}
for(;w<10; w++){
parent[w]=-1;
pweight[w]=0.0f;
}
- if(do_seams){
- ParticleSeam *seam=ctx->seams;
- float temp[3],temp2[3],tan[3];
- float inp,cur_len,min_len=10000.0f;
- int min_seam=0, near_vert=0;
- /* find closest seam */
- for(i=0; i<ctx->totseam; i++, seam++){
- VecSubf(temp,co1,seam->v0);
- inp=Inpf(temp,seam->dir)/seam->length2;
- if(inp<0.0f){
- cur_len=VecLenf(co1,seam->v0);
- }
- else if(inp>1.0f){
- cur_len=VecLenf(co1,seam->v1);
- }
- else{
- VecCopyf(temp2,seam->dir);
- VecMulf(temp2,inp);
- cur_len=VecLenf(temp,temp2);
- }
- if(cur_len<min_len){
- min_len=cur_len;
- min_seam=i;
- if(inp<0.0f) near_vert=-1;
- else if(inp>1.0f) near_vert=1;
- else near_vert=0;
- }
- }
- seam=ctx->seams+min_seam;
-
- VecCopyf(temp,seam->v0);
-
- if(near_vert){
- if(near_vert==-1)
- VecSubf(tan,co1,seam->v0);
- else{
- VecSubf(tan,co1,seam->v1);
- VecCopyf(temp,seam->v1);
- }
-
- Normalize(tan);
- }
- else{
- VecCopyf(tan,seam->tan);
- VecSubf(temp2,co1,temp);
- if(Inpf(tan,temp2)<0.0f)
- VecNegf(tan);
- }
- for(w=0; w<maxw; w++){
- VecSubf(temp2,ptn[w].co,temp);
- if(Inpf(tan,temp2)<0.0f){
- parent[w]=-1;
- pweight[w]=0.0f;
- }
- }
+ //if(do_seams){
+ // ParticleSeam *seam=ctx->seams;
+ // float temp[3],temp2[3],tan[3];
+ // float inp,cur_len,min_len=10000.0f;
+ // int min_seam=0, near_vert=0;
+ // /* find closest seam */
+ // for(i=0; i<ctx->totseam; i++, seam++){
+ // VecSubf(temp,co1,seam->v0);
+ // inp=Inpf(temp,seam->dir)/seam->length2;
+ // if(inp<0.0f){
+ // cur_len=VecLenf(co1,seam->v0);
+ // }
+ // else if(inp>1.0f){
+ // cur_len=VecLenf(co1,seam->v1);
+ // }
+ // else{
+ // VecCopyf(temp2,seam->dir);
+ // VecMulf(temp2,inp);
+ // cur_len=VecLenf(temp,temp2);
+ // }
+ // if(cur_len<min_len){
+ // min_len=cur_len;
+ // min_seam=i;
+ // if(inp<0.0f) near_vert=-1;
+ // else if(inp>1.0f) near_vert=1;
+ // else near_vert=0;
+ // }
+ // }
+ // seam=ctx->seams+min_seam;
+ //
+ // VecCopyf(temp,seam->v0);
+ //
+ // if(near_vert){
+ // if(near_vert==-1)
+ // VecSubf(tan,co1,seam->v0);
+ // else{
+ // VecSubf(tan,co1,seam->v1);
+ // VecCopyf(temp,seam->v1);
+ // }
+
+ // Normalize(tan);
+ // }
+ // else{
+ // VecCopyf(tan,seam->tan);
+ // VecSubf(temp2,co1,temp);
+ // if(Inpf(tan,temp2)<0.0f)
+ // VecNegf(tan);
+ // }
+ // for(w=0; w<maxw; w++){
+ // VecSubf(temp2,ptn[w].co,temp);
+ // if(Inpf(tan,temp2)<0.0f){
+ // parent[w]=-1;
+ // pweight[w]=0.0f;
+ // }
+ // }
- }
+ //}
for(w=0,i=0; w<maxw && i<4; w++){
if(parent[w]>=0){
@@ -877,7 +850,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
static void *exec_distribution(void *data)
{
ParticleThread *thread= (ParticleThread*)data;
- ParticleSystem *psys= thread->ctx->psys;
+ ParticleSystem *psys= thread->ctx->sim.psys;
ParticleData *pa;
ChildParticle *cpa;
int p, totpart;
@@ -944,11 +917,11 @@ static int compare_orig_index(const void *p1, const void *p2)
/* 6. and we're done! */
/* This is to denote functionality that does not yet work with mesh - only derived mesh */
-int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
+static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
{
ParticleThreadContext *ctx= threads[0].ctx;
- Object *ob= ctx->ob;
- ParticleSystem *psys= ctx->psys;
+ Object *ob= ctx->sim.ob;
+ ParticleSystem *psys= ctx->sim.psys;
Object *tob;
ParticleData *pa=0, *tpars= 0;
ParticleSettings *part;
@@ -1000,49 +973,49 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
totpart=get_psys_tot_child(scene, psys);
cfrom=from=PART_FROM_FACE;
- if(part->flag&PART_CHILD_SEAMS){
- MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE);
- MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
- int totedge=dm->getNumEdges(dm);
+ //if(part->flag&PART_CHILD_SEAMS){
+ // MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE);
+ // MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
+ // int totedge=dm->getNumEdges(dm);
- for(p=0, ed=medge; p<totedge; p++,ed++)
- if(ed->flag&ME_SEAM)
- totseam++;
+ // for(p=0, ed=medge; p<totedge; p++,ed++)
+ // if(ed->flag&ME_SEAM)
+ // totseam++;
- if(totseam){
- ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams");
- float temp[3],temp2[3];
+ // if(totseam){
+ // ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams");
+ // float temp[3],temp2[3];
- for(p=0, ed=medge; p<totedge; p++,ed++){
- if(ed->flag&ME_SEAM){
- VecCopyf(cur_seam->v0,(mvert+ed->v1)->co);
- VecCopyf(cur_seam->v1,(mvert+ed->v2)->co);
+ // for(p=0, ed=medge; p<totedge; p++,ed++){
+ // if(ed->flag&ME_SEAM){
+ // VecCopyf(cur_seam->v0,(mvert+ed->v1)->co);
+ // VecCopyf(cur_seam->v1,(mvert+ed->v2)->co);
- VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0);
+ // VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0);
- cur_seam->length2=VecLength(cur_seam->dir);
- cur_seam->length2*=cur_seam->length2;
+ // cur_seam->length2=VecLength(cur_seam->dir);
+ // cur_seam->length2*=cur_seam->length2;
- temp[0]=(float)((mvert+ed->v1)->no[0]);
- temp[1]=(float)((mvert+ed->v1)->no[1]);
- temp[2]=(float)((mvert+ed->v1)->no[2]);
- temp2[0]=(float)((mvert+ed->v2)->no[0]);
- temp2[1]=(float)((mvert+ed->v2)->no[1]);
- temp2[2]=(float)((mvert+ed->v2)->no[2]);
+ // temp[0]=(float)((mvert+ed->v1)->no[0]);
+ // temp[1]=(float)((mvert+ed->v1)->no[1]);
+ // temp[2]=(float)((mvert+ed->v1)->no[2]);
+ // temp2[0]=(float)((mvert+ed->v2)->no[0]);
+ // temp2[1]=(float)((mvert+ed->v2)->no[1]);
+ // temp2[2]=(float)((mvert+ed->v2)->no[2]);
- VecAddf(cur_seam->nor,temp,temp2);
- Normalize(cur_seam->nor);
+ // VecAddf(cur_seam->nor,temp,temp2);
+ // Normalize(cur_seam->nor);
- Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor);
+ // Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor);
- Normalize(cur_seam->tan);
+ // Normalize(cur_seam->tan);
- cur_seam++;
- }
- }
- }
-
- }
+ // cur_seam++;
+ // }
+ // }
+ // }
+ //
+ //}
}
else{
/* no need to figure out distribution */
@@ -1064,10 +1037,6 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
length=VecLength(cpa->fuv);
}
- cpa->rand[0]=BLI_frand();
- cpa->rand[1]=BLI_frand();
- cpa->rand[2]=BLI_frand();
-
cpa->num=-1;
}
}
@@ -1346,7 +1315,6 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
jitlevel= totpart/tot;
if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
if(jitlevel<3) jitlevel= 3;
- //if(jitlevel>100) jitlevel= 100;
}
jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
@@ -1365,7 +1333,7 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
ctx->tree= tree;
ctx->seams= seams;
ctx->totseam= totseam;
- ctx->psys= psys;
+ ctx->sim.psys= psys;
ctx->index= index;
ctx->jit= jit;
ctx->jitlevel= jitlevel;
@@ -1386,7 +1354,7 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
if(!children || psys->totchild < 10000)
totthread= 1;
- seed= 31415926 + ctx->psys->seed;
+ seed= 31415926 + ctx->sim.psys->seed;
for(i=0; i<totthread; i++) {
threads[i].rng= rng_new(seed);
threads[i].tot= totthread;
@@ -1395,16 +1363,17 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
return 1;
}
-static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Object *ob, ParticleSystem *psys, int from)
+static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
{
+ DerivedMesh *finaldm = sim->psmd->dm;
ListBase threads;
ParticleThread *pthreads;
ParticleThreadContext *ctx;
int i, totthread;
- pthreads= psys_threads_create(scene, ob, psys);
+ pthreads= psys_threads_create(sim);
- if(!psys_threads_init_distribution(pthreads, scene, finaldm, from)) {
+ if(!psys_threads_init_distribution(pthreads, sim->scene, finaldm, from)) {
psys_threads_free(pthreads);
return;
}
@@ -1421,7 +1390,7 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec
else
exec_distribution(&pthreads[0]);
- psys_calc_dmcache(ob, finaldm, psys);
+ psys_calc_dmcache(sim->ob, finaldm, sim->psys);
ctx= pthreads[0].ctx;
if(ctx->dm != finaldm)
@@ -1431,8 +1400,9 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec
}
/* ready for future use, to emit particles without geometry */
-static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from)
+static void distribute_particles_on_shape(ParticleSimulationData *sim, int from)
{
+ ParticleSystem *psys = sim->psys;
PARTICLE_P;
fprintf(stderr,"Shape emission not yet possible!\n");
@@ -1443,22 +1413,22 @@ static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int
pa->num= -1;
}
}
-static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys, int from)
+static void distribute_particles(ParticleSimulationData *sim, int from)
{
- ParticleSystemModifierData *psmd=0;
+ PARTICLE_PSMD;
int distr_error=0;
- psmd=psys_get_modifier(ob,psys);
if(psmd){
if(psmd->dm)
- distribute_particles_on_dm(psmd->dm, scene, ob, psys, from);
+ distribute_particles_on_dm(sim, from);
else
distr_error=1;
}
else
- distribute_particles_on_shape(ob,psys,from);
+ distribute_particles_on_shape(sim, from);
if(distr_error){
+ ParticleSystem *psys = sim->psys;
PARTICLE_P;
fprintf(stderr,"Particle distribution error!\n");
@@ -1472,26 +1442,23 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys,
}
/* threaded child particle distribution and path caching */
-ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys)
+ParticleThread *psys_threads_create(ParticleSimulationData *sim)
{
ParticleThread *threads;
ParticleThreadContext *ctx;
int i, totthread;
- if(scene->r.mode & R_FIXED_THREADS)
- totthread= scene->r.threads;
+ if(sim->scene->r.mode & R_FIXED_THREADS)
+ totthread= sim->scene->r.threads;
else
totthread= BLI_system_thread_count();
threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
- ctx->scene= scene;
- ctx->ob= ob;
- ctx->psys= psys;
- ctx->psmd= psys_get_modifier(ob, psys);
- ctx->dm= ctx->psmd->dm;
- ctx->ma= give_current_material(ob, psys->part->omat);
+ ctx->sim = *sim;
+ ctx->dm= ctx->sim.psmd->dm;
+ ctx->ma= give_current_material(sim->ob, sim->psys->part->omat);
memset(threads, 0, sizeof(ParticleThread)*totthread);
@@ -1523,9 +1490,9 @@ void psys_threads_free(ParticleThread *threads)
if(ctx->vg_roughe)
MEM_freeN(ctx->vg_roughe);
- if(ctx->psys->lattice){
- end_latt_deform(ctx->psys->lattice);
- ctx->psys->lattice= NULL;
+ if(ctx->sim.psys->lattice){
+ end_latt_deform(ctx->sim.psys->lattice);
+ ctx->sim.psys->lattice= NULL;
}
/* distribution */
@@ -1551,37 +1518,34 @@ void psys_threads_free(ParticleThread *threads)
}
/* set particle parameters that don't change during particle's life */
-void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
+void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
{
- ParticleSettings *part;
+ ParticleSettings *part = sim->psys->part;
ParticleTexture ptex;
Material *ma=0;
//IpoCurve *icu=0; // XXX old animation system
int totpart;
- float rand;
- part=psys->part;
-
- totpart=psys->totpart;
+ totpart=sim->psys->totpart;
ptex.life=ptex.size=ptex.exist=ptex.length=1.0;
ptex.time=(float)p/(float)totpart;
- BLI_srandom(psys->seed+p);
+ BLI_srandom(sim->psys->seed + p + 125);
if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){
- ma=give_current_material(ob,part->omat);
+ ma=give_current_material(sim->ob,part->omat);
/* TODO: needs some work to make most blendtypes generally usefull */
- psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_INIT);
+ psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT);
}
pa->lifetime= part->lifetime*ptex.life;
if(part->type==PART_HAIR)
pa->time= 0.0f;
- else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
- pa->time= 300000.0f; /* max frame */
+ //else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
+ // pa->time= 300000.0f; /* max frame */
else{
//icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME);
//if(icu){
@@ -1605,10 +1569,8 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
}
#endif // XXX old animation system
- /* need to get every rand even if we don't use them so that randoms don't affect each other */
- rand= BLI_frand();
if(part->randlife!=0.0)
- pa->lifetime*= 1.0f - part->randlife*rand;
+ pa->lifetime*= 1.0f - part->randlife * BLI_frand();
}
pa->dietime= pa->time+pa->lifetime;
@@ -1625,13 +1587,14 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
/* usage other than straight after distribute has to handle this index by itself - jahka*/
//pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */
}
-static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
+static void initialize_all_particles(ParticleSimulationData *sim)
{
//IpoCurve *icu=0; // XXX old animation system
+ ParticleSystem *psys = sim->psys;
PARTICLE_P;
LOOP_PARTICLES
- initialize_particle(pa,p,ob,psys,psmd);
+ initialize_particle(sim, pa, p);
if(psys->part->type != PART_FLUID) {
#if 0 // XXX old animation system
@@ -1688,66 +1651,51 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
}
}
/* sets particle to the emitter surface with initial velocity & rotation */
-void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob,
- float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot)
+void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
{
+ Object *ob = sim->ob;
+ ParticleSystem *psys = sim->psys;
ParticleSettings *part;
ParticleTexture ptex;
ParticleKey state;
//IpoCurve *icu=0; // XXX old animation system
- float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
+ float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
- float q_phase[4], length, r_phase;
+ float q_phase[4], r_phase;
+ int p = pa - psys->particles;
part=psys->part;
ptex.ivel=1.0;
- BLI_srandom(psys->seed + (pa - psys->particles));
-
/* we need to get every random even if they're not used so that they don't effect eachother */
- /* while loops are to have a spherical distribution (avoid cubic distribution) */
- length=2.0f;
- while(length>1.0){
- r_vel[0]=2.0f*(BLI_frand()-0.5f);
- r_vel[1]=2.0f*(BLI_frand()-0.5f);
- r_vel[2]=2.0f*(BLI_frand()-0.5f);
- length=VecLength(r_vel);
- }
-
- length=2.0f;
- while(length>1.0){
- r_ave[0]=2.0f*(BLI_frand()-0.5f);
- r_ave[1]=2.0f*(BLI_frand()-0.5f);
- r_ave[2]=2.0f*(BLI_frand()-0.5f);
- length=VecLength(r_ave);
- }
-
- r_rot[0]=2.0f*(BLI_frand()-0.5f);
- r_rot[1]=2.0f*(BLI_frand()-0.5f);
- r_rot[2]=2.0f*(BLI_frand()-0.5f);
- r_rot[3]=2.0f*(BLI_frand()-0.5f);
-
+ r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
+ r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
+ r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
+
+ r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
+ r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
+ r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
+
+ r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
+ r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
+ r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
+ r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
NormalQuat(r_rot);
- r_phase = BLI_frand();
+ r_phase = PSYS_FRAND(p + 20);
if(part->from==PART_FROM_PARTICLE){
- Object *tob;
- ParticleSystem *tpsys=0;
+ ParticleSimulationData tsim = {sim->scene, psys->target_ob ? psys->target_ob : ob, NULL, NULL};
float speed;
- tob=psys->target_ob;
- if(tob==0)
- tob=ob;
-
- tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1);
+ tsim.psys = BLI_findlink(&tsim.ob->particlesystem, sim->psys->target_psys-1);
state.time = pa->time;
if(pa->num == -1)
memset(&state, 0, sizeof(state));
else
- psys_get_particle_state(scene, tob,tpsys,pa->num,&state,1);
+ psys_get_particle_state(&tsim, pa->num, &state, 1);
psys_get_from_key(&state, loc, nor, rot, 0);
QuatMulVecf(rot, vtan);
@@ -1764,23 +1712,20 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
}
else{
/* get precise emitter matrix if particle is born */
- if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= psys->cfra)
- where_is_object_time(scene, ob,pa->time);
+ if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra)
+ where_is_object_time(sim->scene, sim->ob, pa->time);
/* get birth location from object */
if(part->tanfac!=0.0)
- psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
+ psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
else
- psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
-
- /* save local coordinates for later */
- VECCOPY(tloc,loc);
+ psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
/* get possible textural influence */
- psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL);
+ psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL);
- if(vg_vel && pa->num != -1)
- ptex.ivel*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_vel);
+ //if(vg_vel && pa->num != -1)
+ // ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel);
/* particles live in global space so */
/* let's convert: */
@@ -1788,21 +1733,18 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
Mat4MulVecfl(ob->obmat,loc);
/* -normal */
- VECADD(nor,tloc,nor);
- Mat4MulVecfl(ob->obmat,nor);
- VECSUB(nor,nor,loc);
+ Mat4Mul3Vecfl(ob->obmat,nor);
Normalize(nor);
/* -tangent */
if(part->tanfac!=0.0){
- float phase=vg_rot?2.0f*(psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
+ //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
+ float phase=0.0f;
VecMulf(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
fac=-(float)sin(M_PI*(part->tanphase+phase));
VECADDFAC(vtan,vtan,utan,fac);
- VECADD(vtan,tloc,vtan);
- Mat4MulVecfl(ob->obmat,vtan);
- VECSUB(vtan,vtan,loc);
+ Mat4Mul3Vecfl(ob->obmat,vtan);
VECCOPY(utan,nor);
VecMulf(utan,Inpf(vtan,nor));
@@ -1851,13 +1793,9 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
/* and gravity in r_ve */
bpa->gravity[0] = bpa->gravity[1] = 0.0f;
bpa->gravity[2] = -1.0f;
- if(part->acc[2]!=0.0f)
- bpa->gravity[2] = part->acc[2];
-
- //pa->r_ve[0] = pa->r_ve[1] = 0.0f;
- //pa->r_ve[2] = -1.0f;
- //if(part->acc[2]!=0.0f)
- // pa->r_ve[2] = part->acc[2];
+ if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
+ && sim->scene->physics_settings.gravity[2]!=0.0f)
+ bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
/* calculate rotation matrix */
Projf(dvec, r_vel, pa->state.ave);
@@ -1897,8 +1835,9 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
VECADDFAC(vel,vel,nor,part->normfac);
/* *emitter tangent */
- if(psmd && part->tanfac!=0.0)
- VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_tan):1.0f));
+ if(sim->psmd && part->tanfac!=0.0)
+ VECADDFAC(vel,vel,vtan,part->tanfac);
+ //VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f));
/* *texture */
/* TODO */
@@ -1918,9 +1857,6 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
//}
VecMulf(vel,ptex.ivel);
-
- //if(ELEM(part->phystype, PART_PHYS_GRADU_EX, PART_PHYS_GRADU_SIM))
- // VecAddf(vel,vel,part->acc);
VECCOPY(pa->state.vel,vel);
@@ -1998,26 +1934,28 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
pa->dietime = pa->time + pa->lifetime;
- if(pa->time >= cfra)
+ if(pa->time > cfra)
pa->alive = PARS_UNBORN;
+ else if(pa->dietime <= cfra)
+ pa->alive = PARS_DEAD;
+ else
+ pa->alive = PARS_ALIVE;
pa->state.time = cfra;
-
-// pa->flag &= ~PARS_STICKY;
}
-static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
+static void reset_all_particles(ParticleSimulationData *sim, float dtime, float cfra, int from)
{
ParticleData *pa;
- int p, totpart=psys->totpart;
- float *vg_vel=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
- float *vg_tan=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
- float *vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
+ int p, totpart=sim->psys->totpart;
+ //float *vg_vel=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_VEL);
+ //float *vg_tan=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_TAN);
+ //float *vg_rot=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_ROT);
- for(p=from, pa=psys->particles+from; p<totpart; p++, pa++)
- reset_particle(scene, pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
+ for(p=from, pa=sim->psys->particles+from; p<totpart; p++, pa++)
+ reset_particle(sim, pa, dtime, cfra);
- if(vg_vel)
- MEM_freeN(vg_vel);
+ //if(vg_vel)
+ // MEM_freeN(vg_vel);
}
/************************************************/
/* Particle targets */
@@ -2042,15 +1980,15 @@ ParticleSystem *psys_get_target_system(Object *ob, ParticleTarget *pt)
/* Keyed particles */
/************************************************/
/* Counts valid keyed targets */
-void psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
+void psys_count_keyed_targets(ParticleSimulationData *sim)
{
- ParticleSystem *kpsys;
+ ParticleSystem *psys = sim->psys, *kpsys;
ParticleTarget *pt = psys->targets.first;
int keys_valid = 1;
psys->totkeyed = 0;
for(; pt; pt=pt->next) {
- kpsys = psys_get_target_system(ob, pt);
+ kpsys = psys_get_target_system(sim->ob, pt);
if(kpsys && kpsys->totpart) {
psys->totkeyed += keys_valid;
@@ -2065,9 +2003,10 @@ void psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
psys->totkeyed *= psys->flag & PSYS_KEYED_TIMING ? 1 : psys->part->keyed_loops;
}
-static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
+static void set_keyed_keys(ParticleSimulationData *sim)
{
- ParticleSystem *kpsys = psys;
+ ParticleSystem *psys = sim->psys;
+ ParticleSimulationData ksim = {sim->scene, NULL, NULL, NULL};
ParticleTarget *pt;
PARTICLE_P;
ParticleKey *key;
@@ -2097,16 +2036,14 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
pt = psys->targets.first;
for(k=0; k<totkeys; k++) {
- if(pt->ob)
- kpsys = BLI_findlink(&pt->ob->particlesystem, pt->psys - 1);
- else
- kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1);
+ ksim.ob = pt->ob ? pt->ob : sim->ob;
+ ksim.psys = BLI_findlink(&ksim.ob->particlesystem, pt->psys - 1);
LOOP_PARTICLES {
key = pa->keys + k;
key->time = -1.0; /* use current time */
- psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1);
+ psys_get_particle_state(&ksim, p%ksim.psys->totpart, key, 1);
if(psys->flag & PSYS_KEYED_TIMING){
key->time = pa->time + pt->time;
@@ -2132,111 +2069,109 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
/************************************************/
/* Reactors */
/************************************************/
-static void push_reaction(Object* ob, ParticleSystem *psys, int pa_num, int event, ParticleKey *state)
-{
- Object *rob;
- ParticleSystem *rpsys;
- ParticleSettings *rpart;
- ParticleData *pa;
- ListBase *lb=&psys->effectors;
- ParticleEffectorCache *ec;
- ParticleReactEvent *re;
-
- if(lb->first) for(ec = lb->first; ec; ec= ec->next){
- if(ec->type & PSYS_EC_REACTOR){
- /* all validity checks already done in add_to_effectors */
- rob=ec->ob;
- rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
- rpart=rpsys->part;
- if(rpsys->part->reactevent==event){
- pa=psys->particles+pa_num;
- re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
- re->event=event;
- re->pa_num = pa_num;
- re->ob = ob;
- re->psys = psys;
- re->size = pa->size;
- copy_particle_key(&re->state,state,1);
-
- switch(event){
- case PART_EVENT_DEATH:
- re->time=pa->dietime;
- break;
- case PART_EVENT_COLLIDE:
- re->time=state->time;
- break;
- case PART_EVENT_NEAR:
- re->time=state->time;
- break;
- }
-
- BLI_addtail(&rpsys->reactevents, re);
- }
- }
- }
-}
-static void react_to_events(ParticleSystem *psys, int pa_num)
-{
- ParticleSettings *part=psys->part;
- ParticleData *pa=psys->particles+pa_num;
- ParticleReactEvent *re=psys->reactevents.first;
- int birth=0;
- float dist=0.0f;
-
- for(re=psys->reactevents.first; re; re=re->next){
- birth=0;
- if(part->from==PART_FROM_PARTICLE){
- if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
- if(re->event==PART_EVENT_NEAR){
- ParticleData *tpa = re->psys->particles+re->pa_num;
- float pa_time=tpa->time + pa->foffset*tpa->lifetime;
- if(re->time >= pa_time){
- pa->time=pa_time;
- pa->dietime=pa->time+pa->lifetime;
- }
- }
- else{
- pa->time=re->time;
- pa->dietime=pa->time+pa->lifetime;
- }
- }
- }
- else{
- dist=VecLenf(pa->state.co, re->state.co);
- if(dist <= re->size){
- if(pa->alive==PARS_UNBORN){
- pa->time=re->time;
- pa->dietime=pa->time+pa->lifetime;
- birth=1;
- }
- if(birth || part->flag&PART_REACT_MULTIPLE){
- float vec[3];
- VECSUB(vec,pa->state.co, re->state.co);
- if(birth==0)
- VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
- VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
- VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
- }
- if(birth)
- VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
- }
- }
- }
-}
-void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_ob, ParticleSystem **target_psys)
-{
- Object *tob;
-
- tob=psys->target_ob;
- if(tob==0)
- tob=ob;
-
- *target_psys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
- if(*target_psys)
- *target_ob=tob;
- else
- *target_ob=0;
-}
+//static void push_reaction(ParticleSimulationData *sim, int pa_num, int event, ParticleKey *state)
+//{
+// Object *rob;
+// ParticleSystem *rpsys;
+// ParticleSettings *rpart;
+// ParticleData *pa;
+// ListBase *lb=&sim->psys->effectors;
+// ParticleEffectorCache *ec;
+// ParticleReactEvent *re;
+//
+// if(lb->first) for(ec = lb->first; ec; ec= ec->next){
+// if(ec->type & PSYS_EC_REACTOR){
+// /* all validity checks already done in add_to_effectors */
+// rob=ec->ob;
+// rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
+// rpart=rpsys->part;
+// if(rpsys->part->reactevent==event){
+// pa=sim->psys->particles+pa_num;
+// re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
+// re->event=event;
+// re->pa_num = pa_num;
+// re->ob = sim->ob;
+// re->psys = sim->psys;
+// re->size = pa->size;
+// copy_particle_key(&re->state,state,1);
+//
+// switch(event){
+// case PART_EVENT_DEATH:
+// re->time=pa->dietime;
+// break;
+// case PART_EVENT_COLLIDE:
+// re->time=state->time;
+// break;
+// case PART_EVENT_NEAR:
+// re->time=state->time;
+// break;
+// }
+//
+// BLI_addtail(&rpsys->reactevents, re);
+// }
+// }
+// }
+//}
+//static void react_to_events(ParticleSystem *psys, int pa_num)
+//{
+// ParticleSettings *part=psys->part;
+// ParticleData *pa=psys->particles+pa_num;
+// ParticleReactEvent *re=psys->reactevents.first;
+// int birth=0;
+// float dist=0.0f;
+//
+// for(re=psys->reactevents.first; re; re=re->next){
+// birth=0;
+// if(part->from==PART_FROM_PARTICLE){
+// if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
+// if(re->event==PART_EVENT_NEAR){
+// ParticleData *tpa = re->psys->particles+re->pa_num;
+// float pa_time=tpa->time + pa->foffset*tpa->lifetime;
+// if(re->time >= pa_time){
+// pa->time=pa_time;
+// pa->dietime=pa->time+pa->lifetime;
+// }
+// }
+// else{
+// pa->time=re->time;
+// pa->dietime=pa->time+pa->lifetime;
+// }
+// }
+// }
+// else{
+// dist=VecLenf(pa->state.co, re->state.co);
+// if(dist <= re->size){
+// if(pa->alive==PARS_UNBORN){
+// pa->time=re->time;
+// pa->dietime=pa->time+pa->lifetime;
+// birth=1;
+// }
+// if(birth || part->flag&PART_REACT_MULTIPLE){
+// float vec[3];
+// VECSUB(vec,pa->state.co, re->state.co);
+// if(birth==0)
+// VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
+// VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
+// VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
+// }
+// if(birth)
+// VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
+// }
+// }
+// }
+//}
+//void psys_get_reactor_target(ParticleSimulationData *sim, Object **target_ob, ParticleSystem **target_psys)
+//{
+// Object *tob;
+//
+// tob = sim->psys->target_ob ? sim->psys->target_ob : sim->ob;
+//
+// *target_psys = BLI_findlink(&tob->particlesystem, sim->psys->target_psys-1);
+// if(*target_psys)
+// *target_ob=tob;
+// else
+// *target_ob=0;
+//}
/************************************************/
/* Point Cache */
/************************************************/
@@ -2252,7 +2187,7 @@ void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
BKE_ptcache_disk_to_mem(&pid);
}
-void psys_clear_temp_pointcache(ParticleSystem *psys)
+static void psys_clear_temp_pointcache(ParticleSystem *psys)
{
if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0)
return;
@@ -2270,555 +2205,52 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
/************************************************/
/* Effectors */
/************************************************/
-static void update_particle_tree(ParticleSystem *psys)
+void psys_update_particle_tree(ParticleSystem *psys, float cfra)
{
if(psys) {
PARTICLE_P;
- if(!psys->tree || psys->tree_frame != psys->cfra) {
+ if(!psys->tree || psys->tree_frame != cfra) {
BLI_kdtree_free(psys->tree);
psys->tree = BLI_kdtree_new(psys->totpart);
- LOOP_PARTICLES {
- if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE)
- continue;
-
- BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
- }
- BLI_kdtree_balance(psys->tree);
-
- psys->tree_frame = psys->cfra;
- }
- }
-}
-static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
-{
- TexResult result[4];
- float tex_co[3], strength, mag_vec[3];
- int hasrgb;
- if(tex==NULL) return;
-
- result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0;
-
- strength= force_val*falloff;///(float)pow((double)distance,(double)power);
-
- VECCOPY(tex_co,pa_co);
-
- if(is_2d){
- float fac=-Inpf(tex_co,obmat[2]);
- VECADDFAC(tex_co,tex_co,obmat[2],fac);
- }
-
- if(object){
- VecSubf(tex_co,tex_co,obmat[3]);
- Mat4Mul3Vecfl(obmat,tex_co);
- }
-
- hasrgb = multitex_ext(tex, tex_co, NULL,NULL, 1, result);
-
- if(hasrgb && mode==PFIELD_TEX_RGB){
- mag_vec[0]= (0.5f-result->tr)*strength;
- mag_vec[1]= (0.5f-result->tg)*strength;
- mag_vec[2]= (0.5f-result->tb)*strength;
- }
- else{
- strength/=nabla;
-
- tex_co[0]+= nabla;
- multitex_ext(tex, tex_co, NULL,NULL, 1, result+1);
-
- tex_co[0]-= nabla;
- tex_co[1]+= nabla;
- multitex_ext(tex, tex_co, NULL,NULL, 1, result+2);
-
- tex_co[1]-= nabla;
- tex_co[2]+= nabla;
- multitex_ext(tex, tex_co, NULL,NULL, 1, result+3);
-
- if(mode==PFIELD_TEX_GRAD || !hasrgb){ /* if we dont have rgb fall back to grad */
- mag_vec[0]= (result[0].tin-result[1].tin)*strength;
- mag_vec[1]= (result[0].tin-result[2].tin)*strength;
- mag_vec[2]= (result[0].tin-result[3].tin)*strength;
- }
- else{ /*PFIELD_TEX_CURL*/
- float dbdy,dgdz,drdz,dbdx,dgdx,drdy;
-
- dbdy= result[2].tb-result[0].tb;
- dgdz= result[3].tg-result[0].tg;
- drdz= result[3].tr-result[0].tr;
- dbdx= result[1].tb-result[0].tb;
- dgdx= result[1].tg-result[0].tg;
- drdy= result[2].tr-result[0].tr;
-
- mag_vec[0]=(dbdy-dgdz)*strength;
- mag_vec[1]=(drdz-dbdx)*strength;
- mag_vec[2]=(dgdx-drdy)*strength;
- }
- }
-
- if(is_2d){
- float fac=-Inpf(mag_vec,obmat[2]);
- VECADDFAC(mag_vec,mag_vec,obmat[2],fac);
- }
-
- VecAddf(field,field,mag_vec);
-}
-static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys)
-{
- ParticleEffectorCache *ec;
- PartDeflect *pd= ob->pd;
- short type=0,i;
-
- if(pd && ob != obsrc){
- if(pd->forcefield == PFIELD_GUIDE) {
- if(ob->type==OB_CURVE) {
- Curve *cu= ob->data;
- if(cu->flag & CU_PATH) {
- if(cu->path==NULL || cu->path->data==NULL)
- makeDispListCurveTypes(scene, ob, 0);
- if(cu->path && cu->path->data) {
- type |= PSYS_EC_EFFECTOR;
- }
- }
- }
- }
- else if(pd->forcefield)
- {
- type |= PSYS_EC_EFFECTOR;
- }
- }
-
- if(pd && pd->deflect)
- type |= PSYS_EC_DEFLECT;
-
- if(type){
- ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
- ec->ob= ob;
- ec->type=type;
- ec->distances=0;
- ec->locations=0;
- ec->rng = rng_new(1);
- rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
-
- BLI_addtail(lb, ec);
- }
-
- type=0;
-
- /* add particles as different effectors */
- if(ob->particlesystem.first){
- ParticleSystem *epsys=ob->particlesystem.first;
- ParticleSettings *epart=0;
- Object *tob;
-
- for(i=0; epsys; epsys=epsys->next,i++){
- if(!psys_check_enabled(ob, epsys))
- continue;
- type=0;
- if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
- epart=epsys->part;
-
- if((epsys->part->pd && epsys->part->pd->forcefield)
- || (epsys->part->pd2 && epsys->part->pd2->forcefield))
- {
- type=PSYS_EC_PARTICLE;
- }
-
- if(epart->type==PART_REACTOR) {
- tob=epsys->target_ob;
- if(tob==0)
- tob=ob;
- if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==psys)
- type|=PSYS_EC_REACTOR;
- }
-
- if(type){
- ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
- ec->ob= ob;
- ec->type=type;
- ec->psys_nbr=i;
- ec->rng = rng_new(1);
- rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer())));
-
- BLI_addtail(lb, ec);
- }
- }
- }
-
- }
-}
-
-static void psys_init_effectors_recurs(Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys, ListBase *listb, int level)
-{
- Group *group;
- GroupObject *go;
- unsigned int layer= obsrc->lay;
-
- if(level>MAX_DUPLI_RECUR) return;
-
- if(ob->lay & layer) {
- if(ob->pd || ob->particlesystem.first)
- add_to_effectors(listb, scene, ob, obsrc, psys);
-
- if(ob->dup_group) {
- group= ob->dup_group;
- for(go= group->gobject.first; go; go= go->next)
- psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, level+1);
- }
- }
-}
-
-void psys_init_effectors(Scene *scene, Object *obsrc, Group *group, ParticleSystem *psys)
-{
- ListBase *listb= &psys->effectors;
- Base *base;
-
- listb->first=listb->last=0;
-
- if(group) {
- GroupObject *go;
-
- for(go= group->gobject.first; go; go= go->next)
- psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, 0);
- }
- else {
- for(base = scene->base.first; base; base= base->next)
- psys_init_effectors_recurs(scene, base->object, obsrc, psys, listb, 0);
- }
-}
-
-void psys_end_effectors(ParticleSystem *psys)
-{
- /* NOTE:
- ec->ob is not valid in here anymore! - dg
- */
- ParticleEffectorCache *ec = psys->effectors.first;
-
- for(; ec; ec= ec->next){
- if(ec->distances)
- MEM_freeN(ec->distances);
-
- if(ec->locations)
- MEM_freeN(ec->locations);
-
- if(ec->face_minmax)
- MEM_freeN(ec->face_minmax);
-
- if(ec->vert_cos)
- MEM_freeN(ec->vert_cos);
-
- if(ec->tree)
- BLI_kdtree_free(ec->tree);
-
- if(ec->rng)
- rng_free(ec->rng);
- }
-
- BLI_freelistN(&psys->effectors);
-}
-
-static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
-{
- ListBase *lb=&psys->effectors;
- ParticleEffectorCache *ec;
- ParticleSettings *part=psys->part;
- PARTICLE_P;
- int totpart;
- float vec2[3],loc[3],radius,*co=0;
-
- for(ec= lb->first; ec; ec= ec->next) {
- PartDeflect *pd= ec->ob->pd;
- co = NULL;
-
- if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE
- && part->phystype!=PART_PHYS_BOIDS) {
- float vec[4];
-
- where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius);
-
- Mat4MulVecfl(ec->ob->obmat,vec);
- Mat4Mul3Vecfl(ec->ob->obmat,vec2);
-
- QUATCOPY(ec->firstloc,vec);
- VECCOPY(ec->firstdir,vec2);
-
- /* TODO - use 'radius' to adjust the effector */
-
- totpart=psys->totpart;
-
- if(totpart){
- ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
- ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
-
- LOOP_PARTICLES {
- if(part->from == PART_FROM_PARTICLE) {
- VECCOPY(loc, pa->fuv);
- }
+ LOOP_SHOWN_PARTICLES {
+ if(pa->alive == PARS_ALIVE) {
+ if(pa->state.time == cfra)
+ BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL);
else
- psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
-
- Mat4MulVecfl(ob->obmat,loc);
- ec->distances[p]=VecLenf(loc,vec);
- VECSUB(loc,loc,vec);
- VECCOPY(ec->locations+3*p,loc);
- }
- }
- }
- else if(ec->type==PSYS_EC_PARTICLE){
- Object *eob = ec->ob;
- ParticleSystem *epsys = BLI_findlink(&eob->particlesystem,ec->psys_nbr);
- ParticleSettings *epart = epsys->part;
- ParticleData *epa;
- int p, totepart = epsys->totpart;
-
- if(psys->part->phystype==PART_PHYS_BOIDS){
- ParticleKey state;
- PartDeflect *pd;
-
- pd= epart->pd;
- if(pd->forcefield==PFIELD_FORCE && totepart){
- KDTree *tree;
-
- tree=BLI_kdtree_new(totepart);
- ec->tree=tree;
-
- for(p=0, epa=epsys->particles; p<totepart; p++,epa++)
- if(epa->alive==PARS_ALIVE && psys_get_particle_state(scene, eob,epsys,p,&state,0))
- BLI_kdtree_insert(tree, p, state.co, NULL);
-
- BLI_kdtree_balance(tree);
+ BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
}
}
+ BLI_kdtree_balance(psys->tree);
- }
- else if(ec->type==PSYS_EC_DEFLECT) {
- CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
- if(collmd)
- collision_move_object(collmd, 1.0, 0.0);
+ psys->tree_frame = psys->cfra;
}
}
}
-int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object *ob, PartDeflect *pd, float *co, float *nor, float *vel, int *index)
+static void psys_update_effectors(ParticleSimulationData *sim)
{
- SurfaceModifierData *surmd = NULL;
- int ret = 0;
-
- if(sur)
- surmd = sur;
- else if(pd && pd->flag&PFIELD_SURFACE)
- {
- surmd = (SurfaceModifierData *)modifiers_findByType ( ob, eModifierType_Surface );
- }
-
- if(surmd) {
- /* closest point in the object surface is an effector */
- BVHTreeNearest nearest;
-
- nearest.index = -1;
- nearest.dist = FLT_MAX;
-
- BLI_bvhtree_find_nearest(surmd->bvhtree->tree, pco, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
-
- if(nearest.index != -1) {
- VECCOPY(co, nearest.co);
-
- if(nor) {
- VECCOPY(nor, nearest.no);
- }
-
- if(vel) {
- MFace *mface = CDDM_get_face(surmd->dm, nearest.index);
-
- VECCOPY(vel, surmd->v[mface->v1].co);
- VecAddf(vel, vel, surmd->v[mface->v2].co);
- VecAddf(vel, vel, surmd->v[mface->v3].co);
- if(mface->v4)
- VecAddf(vel, vel, surmd->v[mface->v4].co);
-
- VecMulf(vel, mface->v4 ? 0.25f : 0.333f);
- }
-
- if(index)
- *index = nearest.index;
-
- ret = 1;
- }
- else {
- co[0] = co[1] = co[2] = 0.0f;
-
- if(nor)
- nor[0] = nor[1] = nor[2] = 0.0f;
-
- if(vel)
- vel[0] = vel[1] = vel[2] = 0.0f;
- }
- }
- else {
- /* use center of object for distance calculus */
- VECCOPY(co, ob->obmat[3]);
-
- if(nor) {
- VECCOPY(nor, ob->obmat[2]);
- }
-
- if(vel) {
- Object obcopy = *ob;
-
- VECCOPY(vel, ob->obmat[3]);
-
- where_is_object_time(scene, ob, scene->r.cfra - 1.0);
-
- VecSubf(vel, vel, ob->obmat[3]);
-
- *ob = obcopy;
- }
- }
-
- return ret;
-}
-/* calculate forces that all effectors apply to a particle*/
-void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra)
-{
- Object *eob;
- ParticleSystem *epsys;
- ParticleSettings *epart;
- ParticleData *epa;
- ParticleKey estate;
- PartDeflect *pd;
- ListBase *lb=&psys->effectors;
- ParticleEffectorCache *ec;
- float distance, vec_to_part[3], pco[3], co[3];
- float falloff, charge = 0.0f, strength;
- int p, face_index=-1;
-
- /* check all effector objects for interaction */
- if(lb->first){
- if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){
- /* Only the charge of the effected particle is used for
- interaction, not fall-offs. If the fall-offs aren't the
- same this will be unphysical, but for animation this
- could be the wanted behavior. If you want physical
- correctness the fall-off should be spherical 2.0 anyways.
- */
- charge = psys->part->pd->f_strength;
- }
- if(psys->part->pd2 && psys->part->pd2->forcefield==PFIELD_CHARGE){
- charge += psys->part->pd2->f_strength;
- }
- for(ec = lb->first; ec; ec= ec->next){
- eob= ec->ob;
- if(ec->type & PSYS_EC_EFFECTOR){
- pd=eob->pd;
- if(psys->part->type!=PART_HAIR && psys->part->integrator)
- where_is_object_time(scene, eob,cfra);
-
- if(pd && pd->flag&PFIELD_SURFACE) {
- float velocity[3];
- /* using velocity corrected location allows for easier sliding over effector surface */
- VecCopyf(velocity, state->vel);
- VecMulf(velocity, psys_get_timestep(psys->part));
- VecAddf(pco, state->co, velocity);
- }
- else
- VECCOPY(pco, state->co);
-
- effector_find_co(scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index);
-
- VecSubf(vec_to_part, state->co, co);
-
- distance = VecLength(vec_to_part);
-
- falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);
-
- strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
-
- if(falloff<=0.0f)
- ; /* don't do anything */
- else if(pd->forcefield==PFIELD_TEXTURE) {
- do_texture_effector(pd->tex, pd->tex_mode, pd->flag&PFIELD_TEX_2D, pd->tex_nabla,
- pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
- strength, falloff, force_field);
- } else {
- do_physical_effector(scene, eob, state->co, pd->forcefield,strength,distance,
- falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
- state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size);
- }
- }
- if(ec->type & PSYS_EC_PARTICLE){
- int totepart, i;
- epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
- epart= epsys->part;
- pd=epart->pd;
- totepart= epsys->totpart;
-
- if(totepart <= 0)
- continue;
-
- if(pd && pd->forcefield==PFIELD_HARMONIC){
- /* every particle is mapped to only one harmonic effector particle */
- p= pa_no%epsys->totpart;
- totepart= p+1;
- }
- else{
- p=0;
- }
-
- epsys->lattice= psys_get_lattice(scene, ob, psys);
-
- for(; p<totepart; p++){
- /* particle skips itself as effector */
- if(epsys==psys && p == pa_no) continue;
-
- epa = epsys->particles + p;
- estate.time=cfra;
- if(psys_get_particle_state(scene, eob,epsys,p,&estate,0)){
- VECSUB(vec_to_part, state->co, estate.co);
- distance = VecLength(vec_to_part);
-
- for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) {
- if(pd==NULL || pd->forcefield==0) continue;
-
- falloff=effector_falloff(pd,estate.vel,vec_to_part);
-
- strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
-
- if(falloff<=0.0f)
- ; /* don't do anything */
- else
- do_physical_effector(scene, eob, state->co, pd->forcefield,strength,distance,
- falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
- state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size);
- }
- }
- else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
- /* first step after key release */
- psys_get_particle_state(scene, eob,epsys,p,&estate,1);
- VECADD(vel,vel,estate.vel);
- /* TODO: add rotation handling here too */
- }
- }
-
- if(epsys->lattice){
- end_latt_deform(epsys->lattice);
- epsys->lattice= NULL;
- }
- }
- }
- }
+ pdEndEffectors(&sim->psys->effectors);
+ sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights);
+ precalc_guides(sim, sim->psys->effectors);
}
/************************************************/
/* Newtonian physics */
/************************************************/
/* gathers all forces that effect particles and calculates a new state for the particle */
-static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra)
+static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra, float cfra)
{
+ ParticleSettings *part = sim->psys->part;
+ ParticleData *pa = sim->psys->particles + p;
+ EffectedPoint epoint;
ParticleKey states[5], tkey;
- float force[3],tvel[3],dx[4][3],dv[4][3];
- float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=psys->cfra;
+ float timestep = psys_get_timestep(sim);
+ float force[3],impulse[3],dx[4][3],dv[4][3];
+ float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra;
int i, steps=1;
/* maintain angular velocity */
@@ -2843,10 +2275,11 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
for(i=0; i<steps; i++){
force[0]=force[1]=force[2]=0.0;
- tvel[0]=tvel[1]=tvel[2]=0.0;
+ impulse[0]=impulse[1]=impulse[2]=0.0;
/* add effectors */
- if(part->type != PART_HAIR)
- do_effectors(pa_no,pa,states+i,scene, ob, psys,states->co,force,tvel,dfra,fra);
+ pd_point_from_particle(sim, pa, states+i, &epoint);
+ if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
+ pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
/* calculate air-particle interaction */
if(part->dragfac!=0.0f){
@@ -2865,10 +2298,17 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
VecMulf(force,1.0f/pa_mass);
/* add global acceleration (gravitation) */
- VECADD(force,force,part->acc);
+ if(sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY
+ /* normal gravity is too strong for hair so it's disabled by default */
+ && (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
+ float gravity[3];
+ VECCOPY(gravity, sim->scene->physics_settings.gravity);
+ VecMulf(gravity, part->effector_weights->global_gravity);
+ VECADD(force,force,gravity);
+ }
/* calculate next state */
- VECADD(states[i].vel,states[i].vel,tvel);
+ VECADD(states[i].vel,states[i].vel,impulse);
switch(part->integrator){
case PART_INT_EULER:
@@ -2879,7 +2319,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
if(i==0){
VECADDFAC(states[1].co,states->co,states->vel,dtime*0.5f);
VECADDFAC(states[1].vel,states->vel,force,dtime*0.5f);
- fra=psys->cfra+0.5f*dfra;
+ fra=sim->psys->cfra+0.5f*dfra;
}
else{
VECADDFAC(pa->state.co,states->co,states[1].vel,dtime);
@@ -2896,7 +2336,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
VECADDFAC(states[1].co,states->co,dx[0],0.5f);
VECADDFAC(states[1].vel,states->vel,dv[0],0.5f);
- fra=psys->cfra+0.5f*dfra;
+ fra=sim->psys->cfra+0.5f*dfra;
break;
case 1:
VECADDFAC(dx[1],states->vel,dv[0],0.5f);
@@ -2941,6 +2381,8 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
if(part->dampfac!=0.0)
VecMulf(pa->state.vel,1.0f-part->dampfac);
+ VECCOPY(pa->state.ave, states->ave);
+
/* finally we do guides */
time=(cfra-pa->time)/pa->lifetime;
CLAMP(time,0.0,1.0);
@@ -2950,7 +2392,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
tkey.time=pa->state.time;
if(part->type != PART_HAIR) {
- if(do_guide(scene, &tkey, pa_no, time, &psys->effectors)) {
+ if(do_guides(sim->psys->effectors, &tkey, p, time)) {
VECCOPY(pa->state.co,tkey.co);
/* guides don't produce valid velocity */
VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
@@ -3181,7 +2623,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
VECCOPY(col->vel,vel);
- col->ob = col->ob_t;
+ col->hit_ob = col->ob;
+ col->hit_md = col->md;
}
}
}
@@ -3198,7 +2641,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
VECCOPY(col->vel,vel);
- col->ob = col->ob_t;
+ col->hit_ob = col->ob;
+ col->hit_md = col->md;
}
}
}
@@ -3214,15 +2658,16 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
/* angular momentum <-> linear momentum and swept sphere - mesh collisions */
/* 1. check for all possible deflectors for closest intersection on particle path */
/* 2. if deflection was found kill the particle or calculate new coordinates */
-static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, int p, float timestep, float dfra, float cfra){
- Object *ob = NULL, *skip_ob = NULL;
- ListBase *lb=&psys->effectors;
- ParticleEffectorCache *ec;
- ParticleKey reaction_state;
+static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){
+ Object *ground_ob = NULL;
+ ParticleSettings *part = sim->psys->part;
+ ParticleData *pa = sim->psys->particles + p;
ParticleCollision col;
+ ColliderCache *coll;
BVHTreeRayHit hit;
float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
+ float timestep = psys_get_timestep(sim);
int deflections=0, max_deflections=10;
VECCOPY(col.co1, pa->prev_state.co);
@@ -3234,11 +2679,11 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
BoidParticle *bpa = pa->boid;
radius = pa->size;
boid_z = pa->state.co[2];
- skip_ob = bpa->ground;
+ ground_ob = bpa->ground;
}
/* 10 iterations to catch multiple deflections */
- if(lb->first) while(deflections < max_deflections){
+ if(sim->colliders) while(deflections < max_deflections){
/* 1. */
VECSUB(ray_dir, col.co2, col.co1);
@@ -3250,32 +2695,25 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
if(hit.dist == 0.0f)
hit.dist = col.ray_len = 0.000001f;
- for(ec=lb->first; ec; ec=ec->next){
- if(ec->type & PSYS_EC_DEFLECT){
- ob= ec->ob;
-
- /* for boids: don't check with current ground object */
- if(ob==skip_ob)
- continue;
-
- /* particles should not collide with emitter at birth */
- if(ob==pob && pa->time < cfra && pa->time >= psys->cfra)
- continue;
+ for(coll = sim->colliders->first; coll; coll=coll->next){
+ /* for boids: don't check with current ground object */
+ if(coll->ob == ground_ob)
+ continue;
- if(part->type!=PART_HAIR)
- where_is_object_time(scene,ob,cfra);
+ /* particles should not collide with emitter at birth */
+ if(coll->ob == sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
+ continue;
- col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
- col.ob_t = ob;
+ col.ob = coll->ob;
+ col.md = coll->collmd;
- if(col.md && col.md->bvhtree)
- BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
- }
+ if(col.md && col.md->bvhtree)
+ BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
/* 2. */
if(hit.index>=0) {
- PartDeflect *pd = col.ob->pd;
+ PartDeflect *pd = col.hit_ob->pd;
int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
float co[3]; /* point of collision */
float vec[3]; /* movement through collision */
@@ -3302,9 +2740,6 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
/* particle is dead so we don't need to calculate further */
deflections=max_deflections;
-
- /* store for reactors */
- copy_particle_key(&reaction_state, &pa->state, 0);
}
else {
float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
@@ -3400,9 +2835,9 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
}
/* store state for reactors */
- VECCOPY(reaction_state.co, co);
- VecLerpf(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt);
- QuatInterpol(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt);
+ //VECCOPY(reaction_state.co, co);
+ //VecLerpf(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt);
+ //QuatInterpol(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt);
/* set coordinates for next iteration */
VECCOPY(col.co1, co);
@@ -3424,8 +2859,8 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
}
deflections++;
- reaction_state.time = cfra - (1.0f - dt) * dfra;
- push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state);
+ //reaction_state.time = cfra - (1.0f - dt) * dfra;
+ //push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state);
}
else
return;
@@ -3435,43 +2870,44 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
/* Hair */
/************************************************/
/* check if path cache or children need updating and do it if needed */
-static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
{
- ParticleSettings *part=psys->part;
- ParticleEditSettings *pset=&scene->toolsettings->particle;
- int distr=0,alloc=0,skip=0;
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
+ int distr=0, alloc=0, skip=0;
- if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
+ if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
alloc=1;
- if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)))
+ if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
distr=1;
if(distr){
if(alloc)
- realloc_particles(ob,psys,psys->totpart);
+ realloc_particles(sim, sim->psys->totpart);
- if(get_psys_tot_child(scene, psys)) {
+ if(get_psys_tot_child(sim->scene, psys)) {
/* don't generate children while computing the hair keys */
if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
- distribute_particles(scene, ob, psys, PART_FROM_CHILD);
+ distribute_particles(sim, PART_FROM_CHILD);
if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
- psys_find_parents(ob,psmd,psys);
+ psys_find_parents(sim);
}
}
}
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
skip = 1; /* only hair, keyed and baked stuff can have paths */
- else if(part->ren_as != PART_DRAW_PATH)
+ else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
skip = 1; /* particle visualization must be set as path */
else if(!psys->renderdata) {
if(part->draw_as != PART_DRAW_REND)
skip = 1; /* draw visualization */
else if(psys->pointcache->flag & PTCACHE_BAKING)
skip = 1; /* no need to cache paths while baking dynamics */
- else if(psys_in_edit_mode(scene, psys)) {
+ else if(psys_in_edit_mode(sim->scene, psys)) {
if((pset->flag & PE_DRAW_PART)==0)
skip = 1;
else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
@@ -3480,7 +2916,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
}
if(!skip) {
- psys_cache_paths(scene, ob, psys, cfra);
+ psys_cache_paths(sim, cfra);
/* for render, child particle paths are computed on the fly */
if(part->childtype) {
@@ -3490,15 +2926,16 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
skip = 1;
if(!skip)
- psys_cache_child_paths(scene, ob, psys, cfra, 0);
+ psys_cache_child_paths(sim, cfra, 0);
}
}
else if(psys->pathcache)
psys_free_path_cache(psys, NULL);
}
-static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
+static void do_hair_dynamics(ParticleSimulationData *sim)
{
+ ParticleSystem *psys = sim->psys;
DerivedMesh *dm = psys->hair_in_dm;
MVert *mvert = NULL;
MEdge *medge = NULL;
@@ -3521,7 +2958,8 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par
LOOP_PARTICLES
totpoint += pa->totkey;
- totedge = totpoint - psys->totpart;
+ totedge = totpoint;
+ totpoint += psys->totpart;
if(dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) {
dm->release(dm);
@@ -3540,14 +2978,39 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par
psys->clmd->sim_parms->vgroup_mass = 1;
/* make vgroup for pin roots etc.. */
- psys->particles->hair_index = 0;
+ psys->particles->hair_index = 1;
LOOP_PARTICLES {
if(p)
- pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey;
+ pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey + 1;
- psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
for(k=0, key=pa->hair; k<pa->totkey; k++,key++) {
+
+ /* create fake root before actual root to resist bending */
+ if(k==0) {
+ float temp[3];
+ VECSUB(temp, key->co, (key+1)->co);
+ VECCOPY(mvert->co, key->co);
+ VECADD(mvert->co, mvert->co, temp);
+ Mat4MulVecfl(hairmat, mvert->co);
+ mvert++;
+
+ medge->v1 = pa->hair_index - 1;
+ medge->v2 = pa->hair_index;
+ medge++;
+
+ if(dvert) {
+ if(!dvert->totweight) {
+ dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight");
+ dvert->totweight = 1;
+ }
+
+ dvert->dw->weight = 1.0f;
+ dvert++;
+ }
+ }
+
VECCOPY(mvert->co, key->co);
Mat4MulVecfl(hairmat, mvert->co);
mvert++;
@@ -3576,19 +3039,23 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par
psys->hair_out_dm->release(psys->hair_out_dm);
psys->clmd->point_cache = psys->pointcache;
+ psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
- psys->hair_out_dm = clothModifier_do(psys->clmd, scene, ob, dm, 0, 0);
+ psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0);
+
+ psys->clmd->sim_parms->effector_weights = NULL;
}
-static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+static void hair_step(ParticleSimulationData *sim, float cfra)
{
- ParticleSettings *part = psys->part;
+ ParticleSystem *psys = sim->psys;
+/* ParticleSettings *part = psys->part; */
PARTICLE_P;
float disp = (float)get_current_display_percentage(psys)/100.0f;
BLI_srandom(psys->seed);
LOOP_PARTICLES {
- if(BLI_frand() > disp)
+ if(PSYS_FRAND(p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -3596,36 +3063,33 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
if(psys->recalc & PSYS_RECALC_RESET) {
/* need this for changing subsurf levels */
- psys_calc_dmcache(ob, psmd->dm, psys);
+ psys_calc_dmcache(sim->ob, sim->psmd->dm, psys);
if(psys->clmd)
- cloth_free_modifier(ob, psys->clmd);
+ cloth_free_modifier(sim->ob, psys->clmd);
}
- if(psys->effectors.first)
- psys_end_effectors(psys);
-
/* dynamics with cloth simulation */
if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS)
- do_hair_dynamics(scene, ob, psys, psmd);
+ do_hair_dynamics(sim);
- psys_init_effectors(scene, ob, part->eff_group, psys);
- if(psys->effectors.first)
- precalc_effectors(scene, ob,psys,psmd,cfra);
+ psys_update_effectors(sim);
- psys_update_path_cache(scene, ob,psmd,psys,cfra);
+ psys_update_path_cache(sim, cfra);
psys->flag |= PSYS_HAIR_UPDATED;
}
-static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){
+static void save_hair(ParticleSimulationData *sim, float cfra){
+ Object *ob = sim->ob;
+ ParticleSystem *psys = sim->psys;
HairKey *key, *root;
PARTICLE_P;
int totpart;
- Mat4Invert(ob->imat,ob->obmat);
+ Mat4Invert(ob->imat, ob->obmat);
- psys->lattice= psys_get_lattice(scene, ob, psys);
+ psys->lattice= psys_get_lattice(sim);
if(psys->totpart==0) return;
@@ -3648,7 +3112,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
if(pa->totkey) {
VECSUB(key->co, key->co, root->co);
- psys_vec_rot_to_face(psmd->dm, pa, key->co);
+ psys_vec_rot_to_face(sim->psmd->dm, pa, key->co);
}
key->time = pa->state.time;
@@ -3666,13 +3130,13 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
/* System Core */
/************************************************/
/* unbaked particles are calculated dynamically */
-static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra,
- float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size)
+static void dynamics_step(ParticleSimulationData *sim, float cfra)
{
+ ParticleSystem *psys = sim->psys;
ParticleSettings *part=psys->part;
KDTree *tree=0;
- IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
- Material *ma=give_current_material(ob,part->omat);
+ //IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
+/* Material *ma=give_current_material(sim->ob, part->omat); */
BoidBrainData bbd;
PARTICLE_P;
float timestep;
@@ -3688,7 +3152,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
totpart=psys->totpart;
- timestep=psys_get_timestep(part);
+ timestep = psys_get_timestep(sim);
dtime= dfra*timestep;
ctime= cfra*timestep;
ipotime= cfra; // XXX old animation system
@@ -3702,12 +3166,10 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
if(dfra<0.0){
float *vg_size=0;
- if(part->type==PART_REACTOR)
- vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
-
- LOOP_PARTICLES {
- if(pa->flag & PARS_UNEXIST) continue;
+ //if(part->type==PART_REACTOR)
+ // vg_size=psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
+ LOOP_EXISTING_PARTICLES {
/* set correct ipo timing */
#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
@@ -3716,25 +3178,18 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
execute_ipo((ID *)part, part->ipo);
}
#endif // XXX old animation system
- pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
+ pa->size = part->size;
+ if(part->randsize > 0.0)
+ pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
- reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
+ reset_particle(sim, pa, dtime, cfra);
- if(cfra>pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){
- pa->loop=(short)((cfra-pa->time)/pa->lifetime);
- pa->alive=PARS_UNBORN;
+ if(cfra > pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){
+ pa->loop = (short)((cfra-pa->time)/pa->lifetime);
+ pa->alive = PARS_UNBORN;
}
else{
pa->loop = 0;
- if(cfra <= pa->time)
- pa->alive = PARS_UNBORN;
- /* without dynamics the state is allways known so no need to kill */
- else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)){
- if(cfra < pa->dietime)
- pa->alive = PARS_ALIVE;
- }
- else
- pa->alive = PARS_KILLED;
}
}
@@ -3743,40 +3198,32 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
}
else{
BLI_srandom(31415926 + (int)cfra + psys->seed);
-
- /* update effectors */
- if(psys->effectors.first)
- psys_end_effectors(psys);
- psys_init_effectors(scene, ob, part->eff_group, psys);
-
- if(psys->effectors.first)
- precalc_effectors(scene, ob,psys,psmd,cfra);
+ psys_update_effectors(sim);
+
+ if(part->type != PART_HAIR)
+ sim->colliders = get_collider_cache(sim->scene, NULL);
if(part->phystype==PART_PHYS_BOIDS){
ParticleTarget *pt = psys->targets.first;
- bbd.scene = scene;
- bbd.ob = ob;
- bbd.psys = psys;
+ bbd.sim = sim;
bbd.part = part;
bbd.cfra = cfra;
bbd.dfra = dfra;
bbd.timestep = timestep;
- update_particle_tree(psys);
+ psys_update_particle_tree(psys, cfra);
boids_precalc_rules(part, cfra);
for(; pt; pt=pt->next) {
if(pt->ob)
- update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1));
+ psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
}
}
/* main loop: calculate physics for all particles */
- LOOP_PARTICLES {
- if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
-
+ LOOP_SHOWN_PARTICLES {
copy_particle_key(&pa->prev_state,&pa->state,1);
/* set correct ipo timing */
@@ -3787,23 +3234,19 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
execute_ipo((ID *)part, part->ipo);
}
#endif // XXX old animation system
- pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
+ //update_particle_settings(psys, part, &tpart, pa);
+
+ pa->size = part->size;
+ if(part->randsize > 0.0)
+ pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
- /* reactions can change birth time so they need to be checked first */
- if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
- react_to_events(psys,p);
+ ///* reactions can change birth time so they need to be checked first */
+ //if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
+ // react_to_events(psys,p);
birthtime = pa->time + pa->loop * pa->lifetime;
dietime = birthtime + pa->lifetime;
- /* allways reset particles to emitter before birth */
- if(pa->alive==PARS_UNBORN
- || pa->alive==PARS_KILLED
- || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
- || birthtime >= psys->cfra){
- reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
- }
-
pa_dfra = dfra;
pa_dtime = dtime;
@@ -3816,6 +3259,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
}
else if(birthtime <= cfra && birthtime >= psys->cfra){
/* particle is born some time between this and last step*/
+ reset_particle(sim, pa, dtime, cfra);
pa->alive = PARS_ALIVE;
pa_dfra = cfra - birthtime;
pa_dtime = pa_dfra*timestep;
@@ -3824,18 +3268,22 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
/* nothing to be done when particle is dead */
}
+ /* only reset unborn particles if they're shown */
+ if(pa->alive==PARS_UNBORN && part->flag & PART_UNBORN)
+ reset_particle(sim, pa, dtime, cfra);
if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
switch(part->phystype){
case PART_PHYS_NEWTON:
/* do global forces & effectors */
- apply_particle_forces(scene, p, pa, ob, psys, part, timestep,pa_dfra,cfra);
+ apply_particle_forces(sim, p, pa_dfra, cfra);
/* deflection */
- deflect_particle(scene, ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra);
+ if(sim->colliders)
+ deflect_particle(sim, p, pa_dfra, cfra);
/* rotations */
- rotate_particle(part,pa,pa_dfra,timestep);
+ rotate_particle(part, pa, pa_dfra, timestep);
break;
case PART_PHYS_BOIDS:
{
@@ -3845,18 +3293,19 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
boid_body(&bbd, pa);
/* deflection */
- deflect_particle(scene,ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra);
+ if(sim->colliders)
+ deflect_particle(sim, p, pa_dfra, cfra);
}
break;
}
}
if(pa->alive == PARS_DYING){
- push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state);
+ //push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state);
if(part->flag & PART_LOOP && part->type!=PART_HAIR){
pa->loop++;
- reset_particle(scene, pa,psys,psmd,ob,0.0,cfra,vg_vel,vg_tan,vg_rot);
+ reset_particle(sim, pa, 0.0, cfra);
pa->alive=PARS_ALIVE;
}
else{
@@ -3867,40 +3316,33 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
else
pa->state.time=cfra;
- push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
+ //push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
}
}
+
+ free_collider_cache(&sim->colliders);
}
- if(psys->reactevents.first)
- BLI_freelistN(&psys->reactevents);
if(tree)
BLI_kdtree_free(tree);
}
/* updates cached particles' alive & other flags etc..*/
-static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+static void cached_step(ParticleSimulationData *sim, float cfra)
{
- ParticleSettings *part=psys->part;
- ParticleKey state;
- IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
- Material *ma=give_current_material(ob,part->omat);
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ //IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
+/* Material *ma = give_current_material(sim->ob,part->omat); */
PARTICLE_P;
float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra
BLI_srandom(psys->seed);
if(part->from!=PART_FROM_PARTICLE)
- vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
+ vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
- if(psys->effectors.first)
- psys_end_effectors(psys);
-
- //if(part->flag & (PART_BAKED_GUIDES+PART_BAKED_DEATHS)){
- psys_init_effectors(scene, ob, part->eff_group, psys);
- if(psys->effectors.first)
- precalc_effectors(scene, ob,psys,psmd,cfra);
- //}
+ psys_update_effectors(sim);
disp= (float)get_current_display_percentage(psys)/100.0f;
@@ -3912,9 +3354,13 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
execute_ipo((ID *)part, part->ipo);
}
#endif // XXX old animation system
- pa->size= psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
+ //update_settings_with_particle(psys, part, pa);
- psys->lattice= psys_get_lattice(scene, ob, psys);
+ pa->size = part->size;
+ if(part->randsize > 0.0)
+ pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+
+ psys->lattice= psys_get_lattice(sim);
if(part->flag & PART_LOOP && part->type!=PART_HAIR)
pa->loop = (short)((cfra - pa->time) / pa->lifetime);
@@ -3925,25 +3371,16 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
dietime = birthtime + (1 + pa->loop) * (pa->dietime - pa->time);
/* update alive status and push events */
- if(pa->time >= cfra) {
- pa->alive = pa->time==cfra ? PARS_ALIVE : PARS_UNBORN;
- if((psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
- reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL);
+ if(pa->time > cfra) {
+ pa->alive = PARS_UNBORN;
+ if(part->flag & PART_UNBORN && (psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
+ reset_particle(sim, pa, 0.0f, cfra);
}
else if(dietime <= cfra){
- if(dietime > psys->cfra){
- state.time = dietime;
- psys_get_particle_state(scene, ob,psys,p,&state,1);
- push_reaction(ob,psys,p,PART_EVENT_DEATH,&state);
- }
pa->alive = PARS_DEAD;
}
else{
pa->alive = PARS_ALIVE;
- state.time = cfra;
- psys_get_particle_state(scene, ob,psys,p,&state,1);
- state.time = cfra;
- push_reaction(ob,psys,p,PART_EVENT_NEAR,&state);
}
if(psys->lattice){
@@ -3951,43 +3388,41 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
psys->lattice= NULL;
}
- if(BLI_frand() > disp)
+ if(PSYS_FRAND(p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
}
/* make sure that children are up to date */
- if(psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) {
- realloc_particles(ob, psys, psys->totpart);
- distribute_particles(scene, ob, psys, PART_FROM_CHILD);
+ if(psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) {
+ realloc_particles(sim, psys->totpart);
+ distribute_particles(sim, PART_FROM_CHILD);
}
- psys_update_path_cache(scene, ob,psmd,psys,cfra);
+ psys_update_path_cache(sim, cfra);
if(vg_size)
MEM_freeN(vg_size);
}
-static void psys_changed_type(Object *ob, ParticleSystem *psys)
+static void psys_changed_type(ParticleSimulationData *sim)
{
- ParticleSettings *part;
+ ParticleSettings *part = sim->psys->part;
PTCacheID pid;
- part= psys->part;
-
- BKE_ptcache_id_from_particles(&pid, ob, psys);
+ BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
/* system type has changed so set sensible defaults and clear non applicable flags */
if(part->from == PART_FROM_PARTICLE) {
- if(part->type != PART_REACTOR)
- part->from = PART_FROM_FACE;
+ //if(part->type != PART_REACTOR)
+ part->from = PART_FROM_FACE;
if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
part->distr = PART_DISTR_JIT;
}
if(part->phystype != PART_PHYS_KEYED)
- psys->flag &= ~PSYS_KEYED;
+ sim->psys->flag &= ~PSYS_KEYED;
if(part->type == PART_HAIR) {
if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
@@ -4002,13 +3437,13 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys)
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
}
else {
- free_hair(ob, psys, 1);
+ free_hair(sim->ob, sim->psys, 1);
CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime));
CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime));
}
- psys_reset(psys, PSYS_RESET_ALL);
+ psys_reset(sim->psys, PSYS_RESET_ALL);
}
void psys_check_boid_data(ParticleSystem *psys)
{
@@ -4034,24 +3469,24 @@ void psys_check_boid_data(ParticleSystem *psys)
pa->boid = NULL;
}
}
-static void psys_changed_physics(Object *ob, ParticleSystem *psys)
+static void psys_changed_physics(ParticleSimulationData *sim)
{
- ParticleSettings *part = psys->part;
+ ParticleSettings *part = sim->psys->part;
if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
PTCacheID pid;
- BKE_ptcache_id_from_particles(&pid, ob, psys);
+ BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
}
else {
- free_keyed_keys(psys);
- psys->flag &= ~PSYS_KEYED;
+ free_keyed_keys(sim->psys);
+ sim->psys->flag &= ~PSYS_KEYED;
}
if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
BoidState *state;
- psys_check_boid_data(psys);
+ psys_check_boid_data(sim->psys);
part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
boid_default_settings(part->boids);
@@ -4066,8 +3501,9 @@ static void psys_changed_physics(Object *ob, ParticleSystem *psys)
BLI_addtail(&part->boids->states, state);
}
}
-static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, int cfra)
+static void particles_fluid_step(ParticleSimulationData *sim, int cfra)
{
+ ParticleSystem *psys = sim->psys;
if(psys->particles){
MEM_freeN(psys->particles);
psys->particles = 0;
@@ -4077,7 +3513,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
/* fluid sim particle import handling, actual loading of particles from file */
#ifndef DISABLE_ELBEEM
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(sim->ob, eModifierType_Fluidsim);
if( fluidmd && fluidmd->fss) {
FluidsimSettings *fss= fluidmd->fss;
@@ -4087,7 +3523,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
char *suffix2 = ".gz";
char filename[256];
char debugStrBuffer[256];
- int curFrame = scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
+ int curFrame = sim->scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
int p, j, numFileParts, totpart;
int readMask, activeParts = 0, fileParts = 0;
gzFile gzf;
@@ -4115,11 +3551,11 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
part->totpart= totpart;
part->sta=part->end = 1.0f;
- part->lifetime = scene->r.efra + 1;
+ part->lifetime = sim->scene->r.efra + 1;
/* initialize particles */
- realloc_particles(ob, psys, part->totpart);
- initialize_all_particles(ob, psys, 0);
+ realloc_particles(sim, part->totpart);
+ initialize_all_particles(sim);
// set up reading mask
readMask = fss->typeFlags;
@@ -4175,10 +3611,11 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
/* Calculates the next state for all particles of the system */
/* In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)*/
-static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
+static void system_step(ParticleSimulationData *sim, float cfra)
{
- ParticleSettings *part;
- PointCache *cache;
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ PointCache *cache = psys->pointcache;
PTCacheID pid;
PARTICLE_P;
int totpart, oldtotpart, totchild, oldtotchild;
@@ -4186,20 +3623,17 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
int framenr, framedelta, startframe, endframe;
- part= psys->part;
- cache= psys->pointcache;
-
- framenr= (int)scene->r.cfra;
+ framenr= (int)sim->scene->r.cfra;
framedelta= framenr - cache->simframe;
/* set suitable cache range automatically */
if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0 && !(psys->flag & PSYS_HAIR_DYNAMICS))
- psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe);
+ psys_get_pointcache_start_end(sim->scene, sim->psys, &cache->startframe, &cache->endframe);
- BKE_ptcache_id_from_particles(&pid, ob, psys);
- BKE_ptcache_id_time(&pid, scene, 0.0f, &startframe, &endframe, NULL);
+ BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
+ BKE_ptcache_id_time(&pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
- psys_clear_temp_pointcache(psys);
+ psys_clear_temp_pointcache(sim->psys);
/* update ipo's */
#if 0 // XXX old animation system
@@ -4211,14 +3645,14 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
/* hair if it's already done is handled separate */
if(part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)) {
- hair_step(scene, ob, psmd, psys, cfra);
+ hair_step(sim, cfra);
psys->cfra = cfra;
psys->recalc = 0;
return;
}
/* fluid is also handled separate */
else if(part->type == PART_FLUID) {
- particles_fluid_step(scene, ob, psys, framenr);
+ particles_fluid_step(sim, framenr);
psys->cfra = cfra;
psys->recalc = 0;
return;
@@ -4243,6 +3677,13 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
else if(framenr > endframe) {
framenr= endframe;
}
+
+ if(framenr == startframe) {
+ BKE_ptcache_id_reset(sim->scene, &pid, PTCACHE_RESET_OUTDATED);
+ cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+ }
}
/* verify if we need to reallocate */
@@ -4255,7 +3696,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
totpart = part->grid_res*part->grid_res*part->grid_res;
else
totpart = psys->part->totpart;
- totchild = get_psys_tot_child(scene, psys);
+ totchild = get_psys_tot_child(sim->scene, psys);
if(oldtotpart != totpart || oldtotchild != totchild) {
only_children_changed = (oldtotpart == totpart);
@@ -4272,45 +3713,45 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
if(init) {
if(distr) {
if(alloc) {
- realloc_particles(ob, psys, totpart);
+ realloc_particles(sim, totpart);
- if(usecache && !only_children_changed) {
+ if(oldtotpart && usecache && !only_children_changed) {
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
- BKE_ptcache_id_from_particles(&pid, ob, psys);
+ BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
}
}
if(!only_children_changed)
- distribute_particles(scene, ob, psys, part->from);
+ distribute_particles(sim, part->from);
if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
/* don't generate children while growing hair - waste of time */
psys_free_children(psys);
- else if(get_psys_tot_child(scene, psys))
- distribute_particles(scene, ob, psys, PART_FROM_CHILD);
+ else if(get_psys_tot_child(sim->scene, psys))
+ distribute_particles(sim, PART_FROM_CHILD);
}
if(!only_children_changed) {
free_keyed_keys(psys);
- initialize_all_particles(ob, psys, psmd);
+ initialize_all_particles(sim);
if(alloc) {
- reset_all_particles(scene, ob, psys, psmd, 0.0, cfra, oldtotpart);
+ reset_all_particles(sim, 0.0, cfra, oldtotpart);
}
}
/* flag for possible explode modifiers after this system */
- psmd->flag |= eParticleSystemFlag_Pars;
+ sim->psmd->flag |= eParticleSystemFlag_Pars;
}
/* try to read from the cache */
if(usecache) {
- int result = BKE_ptcache_read_cache(&pid, cfra, scene->r.frs_sec);
+ int result = BKE_ptcache_read_cache(&pid, cfra, sim->scene->r.frs_sec);
if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
- cached_step(scene, ob, psmd, psys, cfra);
+ cached_step(sim, cfra);
psys->cfra=cfra;
psys->recalc = 0;
@@ -4334,7 +3775,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
pa->alive = PARS_ALIVE;
}
}
- else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
+ else if(cfra != startframe && (sim->ob->id.lib || (cache->flag & PTCACHE_BAKED))) {
psys_reset(psys, PSYS_RESET_CACHE_MISS);
psys->cfra=cfra;
psys->recalc = 0;
@@ -4352,14 +3793,14 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
BKE_ptcache_write_cache(&pid, startframe);
if(part->phystype==PART_PHYS_KEYED)
- psys_count_keyed_targets(ob,psys);
+ psys_count_keyed_targets(sim);
/* initialize vertex groups */
if(part->from!=PART_FROM_PARTICLE) {
- vg_vel= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
- vg_tan= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
- vg_rot= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
- vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
+ vg_vel= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_VEL);
+ vg_tan= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_TAN);
+ vg_rot= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_ROT);
+ vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
}
/* set particles to be not calculated TODO: can't work with pointcache */
@@ -4367,7 +3808,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
BLI_srandom(psys->seed);
LOOP_PARTICLES {
- if(BLI_frand() > disp)
+ if(PSYS_FRAND(p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -4383,7 +3824,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
for(dframe=-totframesback; dframe<=0; dframe++) {
/* ok now we're all set so let's go */
- dynamics_step(scene, ob, psys, psmd, cfra+dframe, vg_vel, vg_tan, vg_rot, vg_size);
+ dynamics_step(sim, cfra+dframe);
psys->cfra = cfra+dframe;
}
}
@@ -4400,8 +3841,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
/* for keyed particles the path is allways known so it can be drawn */
if(part->phystype==PART_PHYS_KEYED) {
- set_keyed_keys(scene, ob, psys);
- psys_update_path_cache(scene, ob, psmd, psys,(int)cfra);
+ set_keyed_keys(sim);
+ psys_update_path_cache(sim,(int)cfra);
}
else if(psys->pathcache)
psys_free_path_cache(psys, NULL);
@@ -4431,30 +3872,33 @@ static int hair_needs_recalc(ParticleSystem *psys)
/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
{
- ParticleSystemModifierData *psmd;
+ ParticleSimulationData sim = {scene, ob, psys, NULL, NULL};
float cfra;
+ /* drawdata is outdated after ANY change */
+ if(psys->pdd) psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
+
if(!psys_check_enabled(ob, psys))
return;
cfra= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f);
- psmd= psys_get_modifier(ob, psys);
+ sim.psmd= psys_get_modifier(ob, psys);
/* system was already updated from modifier stack */
- if(psmd->flag & eParticleSystemFlag_psys_updated) {
- psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ if(sim.psmd->flag & eParticleSystemFlag_psys_updated) {
+ sim.psmd->flag &= ~eParticleSystemFlag_psys_updated;
/* make sure it really was updated to cfra */
if(psys->cfra == cfra)
return;
}
- if(!psmd->dm)
+ if(!sim.psmd->dm)
return;
if(psys->recalc & PSYS_RECALC_TYPE)
- psys_changed_type(ob, psys);
+ psys_changed_type(&sim);
else if(psys->recalc & PSYS_RECALC_PHYS)
- psys_changed_physics(ob, psys);
+ psys_changed_physics(&sim);
/* (re-)create hair */
if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) {
@@ -4468,15 +3912,15 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
for(i=0; i<=psys->part->hair_step; i++){
hcfra=100.0f*(float)i/(float)psys->part->hair_step;
- system_step(scene, ob, psys, psmd, hcfra);
- save_hair(scene, ob, psys, psmd, hcfra);
+ system_step(&sim, hcfra);
+ save_hair(&sim, hcfra);
}
psys->flag |= PSYS_HAIR_DONE;
}
/* the main particle system step */
- system_step(scene, ob, psys, psmd, cfra);
+ system_step(&sim, cfra);
/* save matrix for duplicators */
Mat4Invert(psys->imat, ob->obmat);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index f351f8a4335..bffe4566f74 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -56,15 +56,23 @@
#include "BKE_smoke.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
+#include "BIK_api.h"
#include "BLI_blenlib.h"
/* both in intern */
#include "smoke_API.h"
+
+#ifdef WITH_LZO
#include "minilzo.h"
+#else
+/* used for non-lzo cases */
+#define LZO_OUT_LEN(size) ((size) + (size) / 16 + 64 + 3)
+#endif
+#ifdef WITH_LZMA
#include "LzmaLib.h"
-
+#endif
/* needed for directory lookup */
/* untitled blend's need getpid for a unique name */
@@ -79,6 +87,20 @@
static void ptcache_data_to(void **data, int type, int index, void *to);
static void ptcache_data_from(void **data, int type, void *from);
+#define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); }
+#define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); }
+
+int ptcache_data_size[] = {
+ sizeof(int), // BPHYS_DATA_INDEX
+ 3 * sizeof(float), // BPHYS_DATA_LOCATION:
+ 3 * sizeof(float), // BPHYS_DATA_VELOCITY:
+ 4 * sizeof(float), // BPHYS_DATA_ROTATION:
+ 3 * sizeof(float), // BPHYS_DATA_AVELOCITY: /* also BPHYS_DATA_XCONST */
+ sizeof(float), // BPHYS_DATA_SIZE:
+ 3 * sizeof(float), // BPHYS_DATA_TIMES:
+ sizeof(BoidData) // case BPHYS_DATA_BOIDS:
+};
+
/* Common functions */
static int ptcache_read_basic_header(PTCacheFile *pf)
{
@@ -110,8 +132,8 @@ static int ptcache_write_softbody(int index, void *soft_v, void **data)
SoftBody *soft= soft_v;
BodyPoint *bp = soft->bpoint + index;
- ptcache_data_from(data, BPHYS_DATA_LOCATION, bp->pos);
- ptcache_data_from(data, BPHYS_DATA_VELOCITY, bp->vec);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, bp->pos);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, bp->vec);
return 1;
}
@@ -125,8 +147,8 @@ static void ptcache_read_softbody(int index, void *soft_v, void **data, float fr
memcpy(bp->vec, data + 3, 3 * sizeof(float));
}
else {
- ptcache_data_to(data, BPHYS_DATA_LOCATION, 0, bp->pos);
- ptcache_data_to(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, bp->pos);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
}
}
static void ptcache_interpolate_softbody(int index, void *soft_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
@@ -181,25 +203,25 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
return 0;
}
- ptcache_data_from(data, BPHYS_DATA_INDEX, &index);
- ptcache_data_from(data, BPHYS_DATA_LOCATION, pa->state.co);
- ptcache_data_from(data, BPHYS_DATA_VELOCITY, pa->state.vel);
- ptcache_data_from(data, BPHYS_DATA_ROTATION, pa->state.rot);
- ptcache_data_from(data, BPHYS_DATA_AVELOCITY, pa->state.ave);
- ptcache_data_from(data, BPHYS_DATA_SIZE, &pa->size);
- ptcache_data_from(data, BPHYS_DATA_TIMES, times);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, pa->state.vel);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, pa->state.rot);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_AVELOCITY, pa->state.ave);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times);
if(boid)
- ptcache_data_from(data, BPHYS_DATA_BOIDS, &boid->data);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
return 1;
}
void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, float time)
{
- ptcache_data_to(data, BPHYS_DATA_LOCATION, index, key->co);
- ptcache_data_to(data, BPHYS_DATA_VELOCITY, index, key->vel);
- ptcache_data_to(data, BPHYS_DATA_ROTATION, index, key->rot);
- ptcache_data_to(data, BPHYS_DATA_AVELOCITY, index, key->ave);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, index, key->co);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, index, key->vel);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_ROTATION, index, key->rot);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_AVELOCITY, index, key->ave);
key->time = time;
}
static void ptcache_read_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
@@ -220,18 +242,18 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra);
if(data[BPHYS_DATA_SIZE])
- ptcache_data_to(data, BPHYS_DATA_SIZE, 0, &pa->size);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
if(data[BPHYS_DATA_TIMES]) {
float times[3];
- ptcache_data_to(data, BPHYS_DATA_TIMES, 0, &times);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, &times);
pa->time = times[0];
pa->dietime = times[1];
pa->lifetime = times[2];
}
if(boid)
- ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &boid->data);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_BOIDS, 0, &boid->data);
/* determine velocity from previous location */
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
@@ -270,6 +292,9 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
else
BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
+ if(cfra > pa->time)
+ cfra1 = MAX2(cfra1, pa->time);
+
dfra = cfra2 - cfra1;
VecMulf(keys[1].vel, dfra / frs_sec);
@@ -307,6 +332,132 @@ static int ptcache_totwrite_particle(void *psys_v)
return totwrite;
}
+//static int ptcache_write_particle_stream(PTCacheFile *pf, PTCacheMem *pm, void *psys_v)
+//{
+// ParticleSystem *psys= psys_v;
+// ParticleData *pa = psys->particles;
+// BoidParticle *boid = NULL;
+// float times[3];
+// int i = 0;
+//
+// if(!pf && !pm)
+// return 0;
+//
+// for(i=0; i<psys->totpart; i++, pa++) {
+//
+// if(data[BPHYS_DATA_INDEX]) {
+// int step = psys->pointcache->step;
+// /* No need to store unborn or died particles */
+// if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
+// continue;
+// }
+//
+// times[0] = pa->time;
+// times[1] = pa->dietime;
+// times[2] = pa->lifetime;
+//
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, pa->state.vel);
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, pa->state.rot);
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_AVELOCITY, pa->state.ave);
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size);
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times);
+//
+// boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
+// if(boid)
+// PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
+//
+// if(pf && !ptcache_file_write_data(pf))
+// return 0;
+//
+// if(pm)
+// BKE_ptcache_mem_incr_pointers(pm);
+// }
+//
+// return 1;
+//}
+//static void ptcache_read_particle_stream(PTCacheFile *pf, PTCacheMem *pm, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
+//{
+// ParticleSystem *psys= psys_v;
+// ParticleData *pa = psys->particles + index;
+// BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
+//
+// if(cfra > pa->state.time)
+// memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey));
+//
+// if(old_data){
+// /* old format cache */
+// memcpy(&pa->state, old_data, sizeof(ParticleKey));
+// return;
+// }
+//
+// BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra);
+//
+// if(data[BPHYS_DATA_SIZE])
+// PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
+//
+// if(data[BPHYS_DATA_TIMES]) {
+// float times[3];
+// PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, &times);
+// pa->time = times[0];
+// pa->dietime = times[1];
+// pa->lifetime = times[2];
+// }
+//
+// if(boid)
+// PTCACHE_DATA_TO(data, BPHYS_DATA_BOIDS, 0, &boid->data);
+//
+// /* determine velocity from previous location */
+// if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
+// if(cfra > pa->prev_state.time) {
+// VecSubf(pa->state.vel, pa->state.co, pa->prev_state.co);
+// VecMulf(pa->state.vel, (cfra - pa->prev_state.time) / frs_sec);
+// }
+// else {
+// VecSubf(pa->state.vel, pa->prev_state.co, pa->state.co);
+// VecMulf(pa->state.vel, (pa->prev_state.time - cfra) / frs_sec);
+// }
+// }
+//
+// /* determine rotation from velocity */
+// if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
+// vectoquat(pa->state.vel, OB_POSX, OB_POSZ, pa->state.rot);
+// }
+//}
+//static void ptcache_interpolate_particle_stream(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
+//{
+// ParticleSystem *psys= psys_v;
+// ParticleData *pa = psys->particles + index;
+// ParticleKey keys[4];
+// float dfra;
+//
+// cfra = MIN2(cfra, pa->dietime);
+// cfra1 = MIN2(cfra1, pa->dietime);
+// cfra2 = MIN2(cfra2, pa->dietime);
+//
+// if(cfra1 == cfra2)
+// return;
+//
+// memcpy(keys+1, &pa->state, sizeof(ParticleKey));
+// if(old_data)
+// memcpy(keys+2, old_data, sizeof(ParticleKey));
+// else
+// BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
+//
+// dfra = cfra2 - cfra1;
+//
+// VecMulf(keys[1].vel, dfra / frs_sec);
+// VecMulf(keys[2].vel, dfra / frs_sec);
+//
+// psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
+// QuatInterpol(pa->state.rot, keys[1].rot,keys[2].rot, (cfra - cfra1) / dfra);
+//
+// VecMulf(pa->state.vel, frs_sec / dfra);
+//
+// pa->state.time = cfra;
+//}
+//
/* Cloth functions */
static int ptcache_write_cloth(int index, void *cloth_v, void **data)
{
@@ -314,9 +465,9 @@ static int ptcache_write_cloth(int index, void *cloth_v, void **data)
Cloth *cloth= clmd->clothObject;
ClothVertex *vert = cloth->verts + index;
- ptcache_data_from(data, BPHYS_DATA_LOCATION, vert->x);
- ptcache_data_from(data, BPHYS_DATA_VELOCITY, vert->v);
- ptcache_data_from(data, BPHYS_DATA_XCONST, vert->xconst);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, vert->x);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, vert->v);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_XCONST, vert->xconst);
return 1;
}
@@ -332,9 +483,9 @@ static void ptcache_read_cloth(int index, void *cloth_v, void **data, float frs_
memcpy(vert->v, data + 6, 3 * sizeof(float));
}
else {
- ptcache_data_to(data, BPHYS_DATA_LOCATION, 0, vert->x);
- ptcache_data_to(data, BPHYS_DATA_VELOCITY, 0, vert->v);
- ptcache_data_to(data, BPHYS_DATA_XCONST, 0, vert->xconst);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, vert->x);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, vert->v);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst);
}
}
static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
@@ -484,20 +635,25 @@ static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size);
static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode)
{
int r = 0;
- unsigned char compressed;
- LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
- unsigned int out_len = LZO_OUT_LEN(in_len);
+ unsigned char compressed = 0;
+ unsigned int out_len= 0;
unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
size_t sizeOfIt = 5;
+#ifdef WITH_LZO
+ out_len= LZO_OUT_LEN(in_len);
if(mode == 1) {
+ LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
+
r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem);
if (!(r == LZO_E_OK) || (out_len >= in_len))
compressed = 0;
else
compressed = 1;
}
- else if(mode == 2) {
+#endif
+#ifdef WITH_LZMA
+ if(mode == 2) {
r = LzmaCompress(out, (size_t *)&out_len, in, in_len,//assume sizeof(char)==1....
props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
@@ -507,7 +663,8 @@ static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned i
else
compressed = 2;
}
-
+#endif
+
ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char));
if(compressed) {
ptcache_file_write(pf, &out_len, 1, sizeof(unsigned int));
@@ -570,9 +727,9 @@ static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
SmokeDomainSettings *sds = smd->domain;
if(sds->wt) {
- unsigned int res_big_array[3];
- unsigned int res_big;
- unsigned int res = sds->res[0]*sds->res[1]*sds->res[2];
+ int res_big_array[3];
+ int res_big;
+ int res = sds->res[0]*sds->res[1]*sds->res[2];
float *dens, *densold, *tcu, *tcv, *tcw;
unsigned int in_len = sizeof(float)*(unsigned int)res;
unsigned int in_len_big;
@@ -621,16 +778,19 @@ static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigne
in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
+#ifdef WITH_LZO
if(compressed == 1)
r = lzo1x_decompress(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
- else if(compressed == 2)
+#endif
+#ifdef WITH_LZMA
+ if(compressed == 2)
{
size_t leni = in_len, leno = out_len;
ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
}
-
+#endif
MEM_freeN(in);
}
else {
@@ -678,8 +838,8 @@ static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
SmokeDomainSettings *sds = smd->domain;
if(sds->fluid) {
- unsigned int res = sds->res[0]*sds->res[1]*sds->res[2];
- unsigned int res_big, res_big_array[3];
+ int res = sds->res[0]*sds->res[1]*sds->res[2];
+ int res_big, res_big_array[3];
float *dens, *densold, *tcu, *tcv, *tcw;
unsigned int out_len = sizeof(float)*(unsigned int)res;
unsigned int out_len_big;
@@ -987,7 +1147,7 @@ static int ptcache_file_read_data(PTCacheFile *pf)
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
- if(pf->data_types & (1<<i) && !ptcache_file_read(pf, pf->cur[i], 1, BKE_ptcache_data_size(i)))
+ if(pf->data_types & (1<<i) && !ptcache_file_read(pf, pf->cur[i], 1, ptcache_data_size[i]))
return 0;
}
@@ -998,7 +1158,7 @@ static int ptcache_file_write_data(PTCacheFile *pf)
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
- if(pf->data_types & (1<<i) && !ptcache_file_write(pf, pf->cur[i], 1, BKE_ptcache_data_size(i)))
+ if(pf->data_types & (1<<i) && !ptcache_file_write(pf, pf->cur[i], 1, ptcache_data_size[i]))
return 0;
}
@@ -1045,38 +1205,7 @@ static int ptcache_file_write_header_begin(PTCacheFile *pf)
/* Data pointer handling */
int BKE_ptcache_data_size(int data_type)
{
- switch(data_type) {
- case BPHYS_DATA_INDEX:
- return sizeof(int);
- case BPHYS_DATA_LOCATION:
- case BPHYS_DATA_VELOCITY:
- case BPHYS_DATA_AVELOCITY: /* also BPHYS_DATA_XCONST */
- case BPHYS_DATA_TIMES:
- return 3 * sizeof(float);
- case BPHYS_DATA_ROTATION:
- return 4 * sizeof(float);
- case BPHYS_DATA_SIZE:
- return sizeof(float);
- case BPHYS_DATA_BOIDS:
- return sizeof(BoidData);
- default:
- return 0;
- }
-}
-static void ptcache_data_to(void **data, int type, int index, void *to)
-{
- if(data[type]) {
- if(index)
- memcpy(to, (char*)data[type] + index * BKE_ptcache_data_size(type), BKE_ptcache_data_size(type));
- else
- memcpy(to, data[type], BKE_ptcache_data_size(type));
- }
-}
-
-static void ptcache_data_from(void **data, int type, void *from)
-{
- if(data[type])
- memcpy(data[type], from, BKE_ptcache_data_size(type));
+ return ptcache_data_size[data_type];
}
static void ptcache_file_init_pointers(PTCacheFile *pf)
@@ -1108,7 +1237,7 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
for(i=0; i<BPHYS_TOT_DATA; i++) {
if(pm->cur[i])
- pm->cur[i] = (char*)pm->cur[i] + BKE_ptcache_data_size(i);
+ pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
}
}
static void ptcache_alloc_data(PTCacheMem *pm)
@@ -1119,7 +1248,7 @@ static void ptcache_alloc_data(PTCacheMem *pm)
for(i=0; i<BPHYS_TOT_DATA; i++) {
if(data_types & (1<<i))
- pm->data[i] = MEM_callocN(totpoint * BKE_ptcache_data_size(i), "PTCache Data");
+ pm->data[i] = MEM_callocN(totpoint * ptcache_data_size[i], "PTCache Data");
}
}
static void ptcache_free_data(void *data[])
@@ -1136,7 +1265,7 @@ static void ptcache_copy_data(void *from[], void *to[])
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
if(from[i])
- memcpy(to[i], from[i], BKE_ptcache_data_size(i));
+ memcpy(to[i], from[i], ptcache_data_size[i]);
}
}
@@ -1898,6 +2027,9 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
}
}
+ if (ob->type == OB_ARMATURE)
+ BIK_clear_cache(ob->pose);
+
return reset;
}
@@ -2119,6 +2251,26 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
if((cache->flag & PTCACHE_BAKED)==0) {
if(pid->type==PTCACHE_TYPE_PARTICLES)
psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
+ else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) {
+ /* get all pids from the object and search for smoke low res */
+ ListBase pidlist2;
+ PTCacheID *pid2;
+ BKE_ptcache_ids_from_object(&pidlist2, pid->ob);
+ for(pid2=pidlist2.first; pid2; pid2=pid2->next) {
+ if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+ {
+ if(pid2->cache && !(pid2->cache->flag & PTCACHE_BAKED)) {
+ if(bake || pid2->cache->flag & PTCACHE_REDO_NEEDED)
+ BKE_ptcache_id_clear(pid2, PTCACHE_CLEAR_ALL, 0);
+ if(bake) {
+ pid2->cache->flag |= PTCACHE_BAKING;
+ pid2->cache->flag &= ~PTCACHE_BAKED;
+ }
+ }
+ }
+ }
+ BLI_freelistN(&pidlist2);
+ }
if(bake || cache->flag & PTCACHE_REDO_NEEDED)
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 391adfb762a..e524359d2bc 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -230,7 +230,7 @@ char *BKE_reports_string(ReportList *reports, ReportType level)
DynStr *ds;
char *cstring;
- if(!reports)
+ if(!reports || !reports->list.first)
return NULL;
ds= BLI_dynstr_new();
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index de2118af202..5cd554725ff 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -128,6 +128,9 @@ void init_sensor(bSensor *sens)
case SENS_PROPERTY:
sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
break;
+ case SENS_ARMATURE:
+ sens->data= MEM_callocN(sizeof(bArmatureSensor), "armsens");
+ break;
case SENS_ACTUATOR:
sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
break;
@@ -455,6 +458,9 @@ void init_actuator(bActuator *act)
case ACT_STATE:
act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
break;
+ case ACT_ARMATURE:
+ act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
+ break;
default:
; /* this is very severe... I cannot make any memory for this */
/* logic brick... */
@@ -596,6 +602,8 @@ void sca_remove_ob_poin(Object *obt, Object *ob)
bEditObjectActuator *eoa;
bPropertyActuator *pa;
bMessageActuator *ma;
+ bParentActuator *para;
+ bArmatureActuator *aa;
sens= obt->sensors.first;
while(sens) {
@@ -634,7 +642,15 @@ void sca_remove_ob_poin(Object *obt, Object *ob)
ma= act->data;
if(ma->toObject==ob) ma->toObject= NULL;
break;
-
+ case ACT_PARENT:
+ para = act->data;
+ if (para->ob==ob) para->ob = NULL;
+ break;
+ case ACT_ARMATURE:
+ aa = act->data;
+ if (aa->target == ob) aa->target = NULL;
+ if (aa->subtarget == ob) aa->subtarget = NULL;
+ break;
}
act= act->next;
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 6f9ed3e0978..4f72ca96f5f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -400,6 +400,10 @@ Scene *add_scene(char *name)
sce->toolsettings->proportional_size = 1.0f;
+ sce->physics_settings.gravity[0] = 0.0f;
+ sce->physics_settings.gravity[1] = 0.0f;
+ sce->physics_settings.gravity[2] = -9.81f;
+ sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
sce->unit.scale_length = 1.0f;
@@ -419,7 +423,11 @@ Scene *add_scene(char *name)
pset->brush[PE_BRUSH_CUT].strength= 100;
sce->jumpframe = 10;
- sce->r.audio.mixrate = 44100;
+ sce->r.ffcodecdata.audio_mixrate = 44100;
+
+ sce->audio.distance_model = 2.0;
+ sce->audio.doppler_factor = 1.0;
+ sce->audio.speed_of_sound = 343.3;
strcpy(sce->r.backbuf, "//backbuf");
strcpy(sce->r.pic, U.renderdir);
@@ -774,11 +782,11 @@ static void scene_update(Scene *sce, unsigned int lay)
DAG_scene_update_flags(sce, lay); // only stuff that moves or needs display still
/* All 'standard' (i.e. without any dependencies) animation is handled here,
- * with an 'local' to 'macro' order of evaluation. This should ensure that
- * settings stored nestled within a hierarchy (i.e. settings in a Texture block
- * can be overridden by settings from Scene, which owns the Texture through a hierarchy
- * such as Scene->World->MTex/Texture) can still get correctly overridden.
- */
+ * with an 'local' to 'macro' order of evaluation. This should ensure that
+ * settings stored nestled within a hierarchy (i.e. settings in a Texture block
+ * can be overridden by settings from Scene, which owns the Texture through a hierarchy
+ * such as Scene->World->MTex/Texture) can still get correctly overridden.
+ */
BKE_animsys_evaluate_all_animation(G.main, ctime);
for(base= sce->base.first; base; base= base->next) {
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index cc740d7fb3d..661d0da1550 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -33,8 +33,10 @@
#include "MEM_guardedalloc.h"
+#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
#include "BLI_blenlib.h"
@@ -321,4 +323,23 @@ void free_screen(bScreen *sc)
BLI_freelistN(&sc->areabase);
}
+/* for depsgraph */
+unsigned int BKE_screen_visible_layers(bScreen *screen)
+{
+ ScrArea *sa;
+ unsigned int layer= 0;
+
+ if(!screen)
+ return layer;
+
+ /* get all used view3d layers */
+ for(sa= screen->areabase.first; sa; sa= sa->next)
+ if(sa->spacetype==SPACE_VIEW3D)
+ layer |= ((View3D *)sa->spacedata.first)->lay;
+
+ if(!layer)
+ return screen->scene->lay;
+
+ return layer;
+}
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index c6b714c3125..b80df60e726 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -127,7 +127,7 @@ void new_tstripdata(Sequence *seq)
/* free */
-void free_proxy_seq(Sequence *seq)
+static void free_proxy_seq(Sequence *seq)
{
if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
IMB_free_anim(seq->strip->proxy->anim);
@@ -682,7 +682,7 @@ void clear_scene_in_allseqs(Scene *sce)
}
}
-char *give_seqname_by_type(int type)
+static char *give_seqname_by_type(int type)
{
switch(type) {
case SEQ_META: return "Meta";
@@ -949,7 +949,7 @@ static TStripElem* alloc_tstripdata(int len, const char * name)
return se;
}
-TStripElem *give_tstripelem(Sequence *seq, int cfra)
+static TStripElem *give_tstripelem(Sequence *seq, int cfra)
{
TStripElem *se;
int nr;
@@ -1297,7 +1297,7 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
se->ibuf = 0;
}
-void seq_proxy_rebuild(Scene *scene, Sequence * seq)
+static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
{
int cfra;
float rsize = seq->strip->proxy->size;
@@ -2067,7 +2067,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(rendering)
BLI_strncpy(sce->id.name+2, scenename, 64);
- RE_GetResultImage(re, &rres);
+ RE_AcquireResultImage(re, &rres);
if(rres.rectf) {
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
@@ -2080,6 +2080,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
}
+
+ RE_ReleaseResultImage(re);
BIF_end_render_callbacks();
@@ -2623,7 +2625,7 @@ ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown
}
/* check used when we need to change seq->blend_mode but not to effect or audio strips */
-int seq_can_blend(Sequence *seq)
+static int seq_can_blend(Sequence *seq)
{
if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
return 1;
@@ -2749,7 +2751,7 @@ static void *seq_prefetch_thread(void * This_)
return 0;
}
-void seq_start_threads(Scene *scene)
+static void seq_start_threads(Scene *scene)
{
int i;
@@ -2782,7 +2784,7 @@ void seq_start_threads(Scene *scene)
BLI_init_threads(0, 0, 0);
}
-void seq_stop_threads()
+static void seq_stop_threads()
{
PrefetchThread *tslot;
PrefetchQueueElem *e;
@@ -2850,7 +2852,7 @@ void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
pthread_mutex_unlock(&wakeup_lock);
}
-void seq_wait_for_prefetch_ready()
+static void seq_wait_for_prefetch_ready()
{
PrefetchThread *tslot;
@@ -2984,7 +2986,7 @@ static void free_anim_seq(Sequence *seq)
}
}
-void free_imbuf_seq_except(Scene *scene, int cfra)
+static void free_imbuf_seq_except(Scene *scene, int cfra)
{
Editing *ed= seq_give_editing(scene, FALSE);
Sequence *seq;
@@ -3178,7 +3180,7 @@ void free_imbuf_seq()
}
#endif
-void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
+static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
{
/* force update of all sequences with this ipo, on ipo changes */
Editing *ed= seq_give_editing(scene, FALSE);
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index af79fd74ae8..4f7a8cda81b 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -167,6 +167,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
// calc other res with max_res provided
VECSUB(size, max, min);
+ // printf("size: %f, %f, %f\n", size[0], size[1], size[2]);
+
// prevent crash when initializing a plane as domain
if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
return 0;
@@ -210,6 +212,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
}
}
+ // printf("smd->domain->dx: %f\n", smd->domain->dx);
+
// TODO: put in failsafe if res<=0 - dg
// printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
@@ -224,8 +228,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1);
smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1);
smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1);
- printf("smd->domain->amplify: %d\n", smd->domain->amplify);
- printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n");
+ // printf("smd->domain->amplify: %d\n", smd->domain->amplify);
+ // printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n");
}
if(!smd->domain->shadow)
@@ -236,7 +240,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
if(smd->domain->wt)
{
smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength));
- printf("smoke_initWaveletBlenderRNA\n");
+ // printf("smoke_initWaveletBlenderRNA\n");
}
return 1;
}
@@ -522,7 +526,7 @@ void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *faces, int
}
}
-void smokeModifier_freeDomain(SmokeModifierData *smd)
+static void smokeModifier_freeDomain(SmokeModifierData *smd)
{
if(smd->domain)
{
@@ -546,7 +550,7 @@ void smokeModifier_freeDomain(SmokeModifierData *smd)
}
}
-void smokeModifier_freeFlow(SmokeModifierData *smd)
+static void smokeModifier_freeFlow(SmokeModifierData *smd)
{
if(smd->flow)
{
@@ -563,7 +567,7 @@ void smokeModifier_freeFlow(SmokeModifierData *smd)
}
}
-void smokeModifier_freeCollision(SmokeModifierData *smd)
+static void smokeModifier_freeCollision(SmokeModifierData *smd)
{
if(smd->coll)
{
@@ -595,11 +599,6 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd)
smoke_turbulence_free(smd->domain->wt);
smd->domain->wt = NULL;
}
-
- smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID;
- smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
- smd->domain->point_cache[1]->simframe= 0;
- smd->domain->point_cache[1]->last_exact= 0;
}
void smokeModifier_reset(struct SmokeModifierData *smd)
@@ -617,11 +616,9 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
smoke_free(smd->domain->fluid);
smd->domain->fluid = NULL;
}
-
- smd->domain->point_cache[0]->flag &= ~PTCACHE_SIMULATION_VALID;
+
smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED;
- smd->domain->point_cache[0]->simframe= 0;
- smd->domain->point_cache[0]->last_exact= 0;
+ smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
smokeModifier_reset_turbulence(smd);
@@ -744,7 +741,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
}
// forward decleration
-void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct);
+static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct);
static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
static int get_lamp(Scene *scene, float *light)
{
@@ -835,13 +832,12 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
size_t i = 0;
size_t index = 0;
int badcell = 0;
- if(pa->alive == PARS_KILLED) continue;
- else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
+ if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
// VECCOPY(pos, pa->state.co);
// Mat4MulVecfl (ob->imat, pos);
- // 1. get corresponding cell
+ // 1. get corresponding cell
get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0);
// check if cell is valid (in the domain boundary)
for(i = 0; i < 3; i++)
@@ -1102,75 +1098,52 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
+ SmokeDomainSettings *sds = smd->domain;
+ float light[3];
PointCache *cache = NULL;
PTCacheID pid;
PointCache *cache_wt = NULL;
PTCacheID pid_wt;
+ int startframe, endframe, framenr;
float timescale;
int cache_result = 0, cache_result_wt = 0;
- int startframe, endframe, framenr, badloading = 0;
- SmokeDomainSettings *sds = smd->domain;
- float light[3];
framenr = scene->r.cfra;
- cache = sds->point_cache[0];
+ // printf("time: %d\n", scene->r.cfra);
+
+ if(framenr == smd->time)
+ return;
+ cache = sds->point_cache[0];
BKE_ptcache_id_from_smoke(&pid, ob, smd);
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
cache_wt = sds->point_cache[1];
BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
- /* handle continuous simulation with the play button */
- if(BKE_ptcache_get_continue_physics())
+ if(!smd->domain->fluid)
{
- // TODO
- return;
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
}
if(framenr < startframe)
- {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
-
- cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
- cache_wt->simframe= 0;
- cache_wt->last_exact= 0;
-
- // we got back in time, reset smoke in this case (TODO: use cache later)
- // smd->time = scene->r.cfra;
- // smokeModifier_reset(smd);
-
return;
- }
- else if(framenr > endframe)
- {
- framenr = endframe;
-
- // we load last valid frame here
- // and don't update the smd->time variable later
- badloading = 1;
- }
- if(!(cache->flag & PTCACHE_SIMULATION_VALID))
- {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- }
- if(sds->wt && !(cache_wt->flag & PTCACHE_SIMULATION_VALID))
- {
- BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
- }
+ if(framenr > endframe)
+ return;
- if(smd->time == -1 && framenr!= startframe)
+ if(!smd->domain->fluid && (framenr != startframe))
return;
+ // printf("startframe: %d, framenr: %d\n", startframe, framenr);
+
if(!smokeModifier_init(smd, ob, scene, dm))
+ {
+ printf("bad smokeModifier_init\n");
return;
-
- if(!smd->domain->fluid)
- return;
+ }
/* try to read from cache */
cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
@@ -1178,138 +1151,58 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(cache_result == PTCACHE_READ_EXACT)
{
- SmokeDomainSettings *sds = smd->domain;
-
cache->flag |= PTCACHE_SIMULATION_VALID;
cache->simframe= framenr;
- sds->v3dnum = framenr;
-
- if(!badloading)
- smd->time = scene->r.cfra;
- // check for wt cache
if(sds->wt)
{
cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
- // printf("cache_result_wt: %d\n", cache_result_wt);
-
- // error handling
+
if(cache_result_wt == PTCACHE_READ_EXACT)
{
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
cache_wt->simframe= framenr;
}
- else if(cache_result_wt==PTCACHE_READ_OLD)
- {
- BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
- cache_wt->flag |= PTCACHE_SIMULATION_VALID;
- }
- else if(ob->id.lib || (cache_wt->flag & PTCACHE_BAKED))
- {
- // if baked and nothing in cache, do nothing
- cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
- cache_wt->simframe= 0;
- cache_wt->last_exact= 0;
- }
}
-
- // printf("PTCACHE_READ_EXACT\n");
return;
}
- else if(cache_result==PTCACHE_READ_OLD)
- {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
- cache->flag |= PTCACHE_SIMULATION_VALID;
-
- BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
- cache_wt->flag |= PTCACHE_SIMULATION_VALID;
- }
- else if(ob->id.lib || (cache->flag & PTCACHE_BAKED))
- {
- // if baked and nothing in cache, do nothing
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
-
- cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
- cache_wt->simframe= 0;
- cache_wt->last_exact= 0;
-
- // printf("PTCACHE_BAKED\n");
- return;
- }
- /*
- else if((cache_result==0) && ((startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID || (framenr == smd->time))))
- {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
-
- return;
- }*/
-
- // printf("framenr: %d, time: %f\n", framenr, smd->time);
- /* do simulation */
-
- // low res
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
-
- if(sds->wt)
- {
- cache_wt->flag |= PTCACHE_SIMULATION_VALID;
- cache_wt->simframe= framenr;
- }
-
- tstart();
-
- if(sds->flags & MOD_SMOKE_DISSOLVE)
- {
- smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
- }
+ tstart();
smoke_calc_domain(scene, ob, smd);
// set new time
smd->time = scene->r.cfra;
- // frame 1 is start, don't simulate anything
- if(smd->time == 1)
- {
- // set new time
- smd->time = scene->r.cfra;
-
- BKE_ptcache_write_cache(&pid, framenr);
- if(sds->wt)
- BKE_ptcache_write_cache(&pid_wt, framenr);
-
- if(get_lamp(scene, light))
- smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
+ /* do simulation */
- // printf("smd->time: %f\n", smd->time);
- return;
- }
+ // low res
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
// simulate the actual smoke (c++ code in intern/smoke)
- smoke_step(sds->fluid, smd->time);
+ // DG: interesting commenting this line + deactivating loading of noise files
+ if(framenr!=startframe)
+ smoke_step(sds->fluid, smd->time);
+
+ // create shadows before writing cache so we get nice shadows for sstartframe, too
+ if(get_lamp(scene, light))
+ smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
+
BKE_ptcache_write_cache(&pid, framenr);
if(sds->wt)
{
+ if(framenr!=startframe)
+ smoke_turbulence_step(sds->wt, sds->fluid);
- if(sds->flags & MOD_SMOKE_DISSOLVE)
- smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
-
- smoke_turbulence_step(sds->wt, sds->fluid);
+ cache_wt->flag |= PTCACHE_SIMULATION_VALID;
+ cache_wt->simframe= framenr;
BKE_ptcache_write_cache(&pid_wt, framenr);
}
- if(get_lamp(scene, light))
- smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
-
tend();
- // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
+ printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
}
}
@@ -1449,7 +1342,7 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int
}
}
-void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct)
+static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct)
{
int x, y, z;
float bv[6];
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 450a64d72eb..089f2a5ebfb 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1550,11 +1550,14 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
float f,windfactor = 0.25f;
/*see if we have wind*/
if(do_effector) {
+ EffectedPoint epoint;
float speed[3]={0.0f,0.0f,0.0f};
float pos[3];
VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
- pdDoEffectors(scene, do_effector, pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ pd_point_from_soft(scene, pos, vel, -1, &epoint);
+ pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
+
VecMulf(speed,windfactor);
VecAddf(vel,vel,speed);
}
@@ -1589,14 +1592,13 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
{
SoftBody *sb = ob->soft;
- ListBase *do_effector= NULL;
+ ListBase *do_effector = NULL;
- do_effector= pdInitEffectors(scene, ob,NULL);
+ do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
if (sb){
_scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
}
- if(do_effector)
- pdEndEffectors(do_effector);
+ pdEndEffectors(&do_effector);
}
static void *exec_scan_for_ext_spring_forces(void *data)
@@ -1614,7 +1616,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
int i, totthread,left,dec;
int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
- do_effector= pdInitEffectors(scene, ob,NULL);
+ do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
/* figure the number of threads while preventing pretty pointless threading overhead */
if(scene->r.mode & R_FIXED_THREADS)
@@ -1661,9 +1663,8 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
exec_scan_for_ext_spring_forces(&sb_threads[0]);
/* clean up */
MEM_freeN(sb_threads);
-
- if(do_effector)
- pdEndEffectors(do_effector);
+
+ pdEndEffectors(&do_effector);
}
@@ -2226,19 +2227,22 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* done goal stuff */
/* gravitation */
- if (sb){
- float gravity = sb->grav * sb_grav_force_scale(ob);
- bp->force[2]-= gravity*bp->mass; /* individual mass of node here */
+ if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
+ float gravity[3];
+ VECCOPY(gravity, scene->physics_settings.gravity);
+ VecMulf(gravity, sb_grav_force_scale(ob)*bp->mass*sb->effector_weights->global_gravity); /* individual mass of node here */
+ VecAddf(bp->force, bp->force, gravity);
}
/* particle field & vortex */
if(do_effector) {
+ EffectedPoint epoint;
float kd;
float force[3]= {0.0f, 0.0f, 0.0f};
float speed[3]= {0.0f, 0.0f, 0.0f};
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
-
- pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
+ pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
/* apply forcefield*/
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
@@ -2341,6 +2345,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
left = totpoint;
dec = totpoint/totthread +1;
for(i=0; i<totthread; i++) {
+ sb_threads[i].scene = scene;
sb_threads[i].ob = ob;
sb_threads[i].forcetime = forcetime;
sb_threads[i].timenow = timenow;
@@ -2381,7 +2386,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
*/
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bproot;
- ListBase *do_effector;
+ ListBase *do_effector = NULL;
float iks, gravity;
float fieldfactor = -1.0f, windfactor = 0.25;
int do_deflector,do_selfcollision,do_springcollision,do_aero;
@@ -2401,7 +2406,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
sb_sfesf_threads_run(scene, ob, timenow,sb->totspring,NULL);
/* after spring scan because it uses Effoctors too */
- do_effector= pdInitEffectors(scene, ob,NULL);
+ do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights);
if (do_deflector) {
float defforce[3];
@@ -2414,7 +2419,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
/* finish matrix and solve */
- if(do_effector) pdEndEffectors(do_effector);
+ pdEndEffectors(&do_effector);
}
@@ -2443,8 +2448,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
BodyPoint *bp;
BodyPoint *bproot;
BodySpring *bs;
- ListBase *do_effector;
- float iks, ks, kd, gravity;
+ ListBase *do_effector = NULL;
+ float iks, ks, kd, gravity[3] = {0.0f,0.0f,0.0f};
float fieldfactor = -1.0f, windfactor = 0.25f;
float tune = sb->ballstiff;
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
@@ -2460,7 +2465,10 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
*/
- gravity = sb->grav * sb_grav_force_scale(ob);
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
+ VECCOPY(gravity, scene->physics_settings.gravity);
+ VecMulf(gravity, sb_grav_force_scale(ob)*sb->effector_weights->global_gravity);
+ }
/* check conditions for various options */
do_deflector= query_external_colliders(scene, ob);
@@ -2473,7 +2481,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow);
/* after spring scan because it uses Effoctors too */
- do_effector= pdInitEffectors(scene, ob,NULL);
+ do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
if (do_deflector) {
float defforce[3];
@@ -2631,16 +2639,17 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/* gravitation */
- bp->force[2]-= gravity*bp->mass; /* individual mass of node here */
+ VECADDFAC(bp->force, bp->force, gravity, bp->mass); /* individual mass of node here */
/* particle field & vortex */
if(do_effector) {
+ EffectedPoint epoint;
float force[3]= {0.0f, 0.0f, 0.0f};
float speed[3]= {0.0f, 0.0f, 0.0f};
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
-
- pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
+ pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
/* apply forcefield*/
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
@@ -2819,7 +2828,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
/* cleanup */
#endif
- if(do_effector) pdEndEffectors(do_effector);
+ pdEndEffectors(&do_effector);
}
}
@@ -3635,6 +3644,9 @@ SoftBody *sbNew(Scene *scene)
sb->pointcache = BKE_ptcache_add(&sb->ptcaches);
+ if(!sb->effector_weights)
+ sb->effector_weights = BKE_add_effector_weights(NULL);
+
return sb;
}
@@ -3644,6 +3656,8 @@ void sbFree(SoftBody *sb)
free_softbody_intern(sb);
BKE_ptcache_free_list(&sb->ptcaches);
sb->pointcache = NULL;
+ if(sb->effector_weights)
+ MEM_freeN(sb->effector_weights);
MEM_freeN(sb);
}
@@ -3684,6 +3698,9 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
BodyPoint *bp;
int a;
+ if(!sb || !sb->bpoint)
+ return;
+
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
/* store where goals are now */
VECCOPY(bp->origS, bp->origE);
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 2d5d8dad7a8..6ac9b020f21 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -340,7 +340,7 @@ void sound_update_playing(struct bContext *C)
for(handle = scene->sound_handles.first; handle; handle = handle->next)
{
- if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute)
+ if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute || (scene->audio.flag & AUDIO_MUTE))
{
if(handle->state == AUD_STATUS_PLAYING)
{
@@ -421,7 +421,7 @@ void sound_scrub(struct bContext *C)
int cfra = CFRA;
float fps = FPS;
- if(scene->r.audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
+ if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
{
AUD_lock();
@@ -443,7 +443,7 @@ void sound_scrub(struct bContext *C)
}
}
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end)
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume)
{
AUD_Device* mixdown = AUD_openReadDevice(specs);
SoundHandle *handle;
@@ -453,6 +453,8 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e
end++;
+ AUD_setDeviceVolume(mixdown, volume);
+
for(handle = scene->sound_handles.first; handle; handle = handle->next)
{
if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->handle)
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index dac426de4eb..8bf0f6b8bdf 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -130,8 +130,10 @@ undo position
static void txt_pop_first(Text *text);
static void txt_pop_last(Text *text);
static void txt_undo_add_op(Text *text, int op);
-static void txt_undo_add_block(Text *text, int op, char *buf);
+static void txt_undo_add_block(Text *text, int op, const char *buf);
static void txt_delete_line(Text *text, TextLine *line);
+static void txt_delete_sel (Text *text);
+static void txt_make_dirty (Text *text);
/***/
@@ -537,6 +539,30 @@ void unlink_text(Main *bmain, Text *text)
text->id.us= 0;
}
+void clear_text(Text *text) /* called directly from rna */
+{
+ int oldstate;
+
+ oldstate = txt_get_undostate( );
+ txt_set_undostate( 1 );
+ txt_sel_all( text );
+ txt_delete_sel(text);
+ txt_set_undostate( oldstate );
+
+ txt_make_dirty(text);
+}
+
+void write_text(Text *text, char *str) /* called directly from rna */
+{
+ int oldstate;
+
+ oldstate = txt_get_undostate( );
+ txt_insert_buf( text, str );
+ txt_move_eof( text, 0 );
+ txt_set_undostate( oldstate );
+
+ txt_make_dirty(text);
+}
/*****************************/
/* Editing utility functions */
@@ -570,17 +596,15 @@ static TextLine *txt_new_line(char *str)
return tmp;
}
-static TextLine *txt_new_linen(char *str, int n)
+static TextLine *txt_new_linen(const char *str, int n)
{
TextLine *tmp;
- if(!str) str= "";
-
tmp= (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
tmp->line= MEM_mallocN(n+1, "textline_string");
tmp->format= NULL;
- BLI_strncpy(tmp->line, str, n+1);
+ BLI_strncpy(tmp->line, (str)? str: "", n+1);
tmp->len= strlen(tmp->line);
tmp->next= tmp->prev= NULL;
@@ -1315,7 +1339,7 @@ char *txt_sel_to_buf (Text *text)
return buf;
}
-void txt_insert_buf(Text *text, char *in_buffer)
+void txt_insert_buf(Text *text, const char *in_buffer)
{
int i=0, l=0, j, u, len;
TextLine *add;
@@ -1544,7 +1568,7 @@ static void txt_undo_add_op(Text *text, int op)
text->undo_buf[text->undo_pos+1]= 0;
}
-static void txt_undo_add_block(Text *text, int op, char *buf)
+static void txt_undo_add_block(Text *text, int op, const char *buf)
{
int length;
@@ -2808,3 +2832,60 @@ TextMarker *txt_next_marker(Text *text, TextMarker *marker) {
}
return NULL; /* Only if marker==NULL */
}
+
+
+/*******************************/
+/* Character utility functions */
+/*******************************/
+
+int text_check_bracket(char ch)
+{
+ int a;
+ char opens[] = "([{";
+ char close[] = ")]}";
+
+ for(a=0; a<(sizeof(opens)-1); a++) {
+ if(ch==opens[a])
+ return a+1;
+ else if(ch==close[a])
+ return -(a+1);
+ }
+ return 0;
+}
+
+int text_check_delim(char ch)
+{
+ int a;
+ char delims[] = "():\"\' ~!%^&*-+=[]{};/<>|.#\t,";
+
+ for(a=0; a<(sizeof(delims)-1); a++) {
+ if(ch==delims[a])
+ return 1;
+ }
+ return 0;
+}
+
+int text_check_digit(char ch)
+{
+ if(ch < '0') return 0;
+ if(ch <= '9') return 1;
+ return 0;
+}
+
+int text_check_identifier(char ch)
+{
+ if(ch < '0') return 0;
+ if(ch <= '9') return 1;
+ if(ch < 'A') return 0;
+ if(ch <= 'Z' || ch == '_') return 1;
+ if(ch < 'a') return 0;
+ if(ch <= 'z') return 1;
+ return 0;
+}
+
+int text_check_whitespace(char ch)
+{
+ if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
+ return 1;
+ return 0;
+}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index d7616ec8a9a..3b8ae9a6c7f 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -559,6 +559,36 @@ void default_mtex(MTex *mtex)
mtex->norfac= 1.0;
mtex->varfac= 1.0;
mtex->dispfac=0.2;
+ mtex->colspecfac= 1.0f;
+ mtex->mirrfac= 1.0f;
+ mtex->alphafac= 1.0f;
+ mtex->difffac= 1.0f;
+ mtex->specfac= 1.0f;
+ mtex->emitfac= 1.0f;
+ mtex->hardfac= 1.0f;
+ mtex->raymirrfac= 1.0f;
+ mtex->translfac= 1.0f;
+ mtex->ambfac= 1.0f;
+ mtex->colemitfac= 1.0f;
+ mtex->colreflfac= 1.0f;
+ mtex->coltransfac= 1.0f;
+ mtex->densfac= 1.0f;
+ mtex->scatterfac= 1.0f;
+ mtex->reflfac= 1.0f;
+ mtex->shadowfac= 1.0f;
+ mtex->zenupfac= 1.0f;
+ mtex->zendownfac= 1.0f;
+ mtex->blendfac= 1.0f;
+ mtex->timefac= 1.0f;
+ mtex->lengthfac= 1.0f;
+ mtex->clumpfac= 1.0f;
+ mtex->kinkfac= 1.0f;
+ mtex->roughfac= 1.0f;
+ mtex->padensfac= 1.0f;
+ mtex->lifefac= 1.0f;
+ mtex->sizefac= 1.0f;
+ mtex->ivelfac= 1.0f;
+ mtex->pvelfac= 1.0f;
mtex->normapspace= MTEX_NSPACE_TANGENT;
}
@@ -984,6 +1014,7 @@ struct VoxelData *BKE_add_voxeldata(void)
vd->interp_type= TEX_VD_LINEAR;
vd->file_format= TEX_VD_SMOKE;
vd->int_multiplier = 1.0;
+ vd->extend = TEX_CLIP;
vd->object = NULL;
return vd;
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index f8e3b3c5ad2..1f72c894cc8 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -75,7 +75,7 @@ static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0, sizeof(buDum
/* Lengths */
static struct bUnitDef buMetricLenDef[] = {
{"kilometer", "kilometers", "km", NULL, "Kilometers", 1000.0, 0.0, B_UNIT_DEF_NONE},
- {"hectometer", "hectometers", "hm", NULL, "10 Meters", 100.0, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"hectometer", "hectometers", "hm", NULL, "100 Meters", 100.0, 0.0, B_UNIT_DEF_SUPPRESS},
{"dekameter", "dekameters", "dkm",NULL, "10 Meters", 10.0, 0.0, B_UNIT_DEF_SUPPRESS},
{"meter", "meters", "m", NULL, "Meters", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"decimetre", "decimetres", "dm", NULL, "10 Centimeters", 0.1, 0.0, B_UNIT_DEF_SUPPRESS},
@@ -485,7 +485,7 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
if(unit==NULL)
unit= unit_default(usys);
- /* add the unit prefic and re-run, use brackets incase there was an expression given */
+ /* add the unit prefix and re-run, use brackets incase there was an expression given */
if(snprintf(str_tmp, sizeof(str_tmp), "(%s)%s", str, unit->name) < sizeof(str_tmp)) {
strncpy(str, str_tmp, len_max);
return bUnit_ReplaceString(str, len_max, NULL, scale_pref, system, type);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index e7164dc4794..1953058fddf 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -148,7 +148,7 @@ static int write_audio_frame(void)
#else
pkt.pts = c->coded_frame->pts;
#endif
- fprintf(stderr, "Audio Frame PTS: %lld\n", pkt.pts);
+ fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts);
pkt.stream_index = audio_stream->index;
pkt.flags |= PKT_FLAG_KEY;
@@ -265,7 +265,7 @@ static void write_video_frame(RenderData *rd, AVFrame* frame)
#else
packet.pts = c->coded_frame->pts;
#endif
- fprintf(stderr, "Video Frame PTS: %lld\n", packet.pts);
+ fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
} else {
fprintf(stderr, "Video Frame PTS: not set\n");
}
@@ -559,7 +559,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->codec_id = codec_id;
c->codec_type = CODEC_TYPE_AUDIO;
- c->sample_rate = rd->audio.mixrate;
+ c->sample_rate = rd->ffcodecdata.audio_mixrate;
c->bit_rate = ffmpeg_audio_bitrate*1000;
c->channels = 2;
codec = avcodec_find_encoder(c->codec_id);
@@ -613,7 +613,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
}
/* essential functions -- start, append, end */
-void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
+static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
{
/* Handle to the output file */
AVFormatContext* of;
@@ -734,7 +734,7 @@ void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
if (ffmpeg_type == FFMPEG_DV) {
fmt->audio_codec = CODEC_ID_PCM_S16LE;
- if (ffmpeg_multiplex_audio && rd->audio.mixrate != 48000) {
+ if (ffmpeg_multiplex_audio && rd->ffcodecdata.audio_mixrate != 48000) {
G.afbreek = 1;
//XXX error("FFMPEG only supports 48khz / stereo "
// "audio for DV!");
@@ -831,7 +831,6 @@ static void makeffmpegstring(RenderData* rd, char* string) {
}
}
-
void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty)
{
ffmpeg_autosplit_count = 0;
@@ -844,8 +843,8 @@ void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty)
AUD_Specs specs;
specs.channels = c->channels;
specs.format = AUD_FORMAT_S16;
- specs.rate = rd->audio.mixrate;
- audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra);
+ specs.rate = rd->ffcodecdata.audio_mixrate;
+ audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra, rd->ffcodecdata.audio_volume);
}
}
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index c2d707f60f0..1d275e70a17 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -178,7 +178,7 @@ float power_of_2(float val);
*/
/* Defines for rotation orders
- * WARNING: must match the ePchan_RotMode in DNA_action_types.h
+ * WARNING: must match the eRotationModes in DNA_action_types.h
* order matters - types are saved to file!
*/
typedef enum eEulerRotationOrders {
@@ -364,7 +364,8 @@ void printvec4f(char *str, float v[4]);
void VecAddf(float *v, float *v1, float *v2);
void VecSubf(float *v, float *v1, float *v2);
void VecMulVecf(float *v, float *v1, float *v2);
-void VecLerpf(float *target, float *a, float *b, float t);
+void VecLerpf(float *target, const float *a, const float *b, const float t);
+void VecLerp3f(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]);
void VecMidf(float *v, float *v1, float *v2);
void VecOrthoBasisf(float *v, float *v1, float *v2);
@@ -375,7 +376,8 @@ void Vec2Mulf(float *v1, float f);
void Vec2Addf(float *v, float *v1, float *v2);
void Vec2Subf(float *v, float *v1, float *v2);
void Vec2Copyf(float *v1, float *v2);
-void Vec2Lerpf(float *target, float *a, float *b, float t);
+void Vec2Lerpf(float *target, const float *a, const float *b, const float t);
+void Vec2Lerp3f(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]);
void AxisAngleToQuat(float q[4], float axis[3], float angle);
void QuatToAxisAngle(float q[4], float axis[3], float *angle);
@@ -401,7 +403,7 @@ float VecAngle2(float *v1, float *v2);
float VecAngle3(float *v1, float *v2, float *v3);
float NormalizedVecAngle2(float *v1, float *v2);
-float VecAngle3_2D(float *v1, float *v2, float *v3);
+float Vec2Angle3(float *v1, float *v2, float *v3);
float NormalizedVecAngle2_2D(float *v1, float *v2);
void NormalShortToFloat(float *out, short *in);
@@ -454,6 +456,8 @@ void i_window(
#define BLI_CS_REC709 1
#define BLI_CS_CIE 2
+#define RAD2DEG(_rad) ((_rad)*(180.0/M_PI))
+
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv);
@@ -525,6 +529,8 @@ int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]);
float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]);
+float AngleToLength(const float angle);
+
typedef struct DualQuat {
float quat[4];
float trans[4];
diff --git a/source/blender/blenlib/BLI_bfile.h b/source/blender/blenlib/BLI_bfile.h
new file mode 100644
index 00000000000..92543558a19
--- /dev/null
+++ b/source/blender/blenlib/BLI_bfile.h
@@ -0,0 +1,138 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by Stichting Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * BFILE* based abstraction of file access.
+ */
+
+#ifndef BLI_BFILE_H
+#define BLI_BFILE_H
+
+/* For fopen's FILE */
+#include <stdio.h>
+
+/**
+ Defines for the bflags param.
+ */
+/* Special handling: */
+/* For "symmetry" of flags */
+#define BFILE_NORMAL (0)
+/* No supervision, just translate // if needed, RISKY */
+#define BFILE_RAW (1<<0)
+/* Path is relative to config dirs */
+#define BFILE_CONFIG (1<<1)
+/* Path is for current session temp file */
+#define BFILE_TEMP (1<<2)
+
+/* Config handling, special cases: */
+#define BFILE_USERONLY (1<<3)
+#define BFILE_SYSONLY (1<<4)
+
+/* Compression to apply on close: */
+#define BFILE_GZIP (1<<5)
+
+/**
+ File descriptor for Blender abstracted file access.
+ */
+typedef struct {
+ FILE *stream;
+ int fd;
+
+ /* Anything below should not be touched directly */
+ int uflags; /* Special options requested by upper level, copy of bflags */
+ char *fpath; /* Final/requested path name */
+ char *tpath; /* Temp path name if applicable */
+ int type; /* Own flags, common classification of open and fopen */
+ int error; /* An op caused an error, unsafe to replace older files */
+} BFILE;
+
+/**
+ Open a BFILE* with fopen()-like syntax.
+ */
+BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags);
+
+/**
+ Open a BFILE* with open()-like syntax.
+ */
+BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags);
+
+/**
+ Get the FILE* associated with the BFILE*.
+ */
+FILE *BLI_bfile_file_from_bfile(BFILE *bfile);
+
+/**
+ Get the fd associated with the BFILE*.
+ */
+int BLI_bfile_fd_from_bfile(BFILE *bfile);
+
+/**
+ write()-like using BFILE*.
+ */
+ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count);
+
+/**
+ read()-like using BFILE*.
+ */
+ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count);
+
+/**
+ fwrite()-like using BFILE*.
+ */
+size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f);
+
+/**
+ fread()-like using BFILE*.
+ */
+size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f);
+
+/**
+ Close a BFILE, to match close() and fclose().
+ */
+void BLI_bfile_close(BFILE *bfile);
+
+/**
+ Clear error status.
+ Call it only if the error has been really handled.
+ */
+void BLI_bfile_clear_error(BFILE *bfile);
+
+/**
+ Set the error status.
+ Call it to mark writing by a 3rd party failed (libjpeg reported error, ie).
+ */
+void BLI_bfile_set_error(BFILE *bfile, int error);
+
+/*
+TODO
+Maybe also provide more OS/libc things like:
+fflush
+fprintf and related
+fscanf
+fgetc/fputc and related
+fseek and related
+
+Probably good to do:
+readdir (compacted list showing all files for a "directory" (user versions on top of system's))
+*/
+
+#endif /* ifndef BLI_BFILE_H */
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index c77e82f0a2b..c9a8b1b841f 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -32,6 +32,10 @@
#ifndef BLI_GHASH_H
#define BLI_GHASH_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct GHash;
typedef struct GHash GHash;
@@ -125,5 +129,9 @@ int BLI_ghashutil_strcmp (void *a, void *b);
unsigned int BLI_ghashutil_inthash (void *ptr);
int BLI_ghashutil_intcmp(void *a, void *b);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index d0b106b59c3..21b4c83bd88 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -34,6 +34,7 @@
//#include "DNA_listbase.h"
struct ListBase;
+struct LinkData;
#ifdef __cplusplus
extern "C" {
@@ -56,6 +57,9 @@ int BLI_countlist(struct ListBase *listbase);
void BLI_freelinkN(struct ListBase *listbase, void *vlink);
void BLI_duplicatelist(struct ListBase *list1, struct ListBase *list2); /* copy from 2 to 1 */
+/* create a generic list node containing link to provided data */
+struct LinkData *BLI_genericNodeN(void *data);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 8babb5fe780..ace9ddd729f 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -31,14 +31,15 @@
#ifndef BLI_THREADS_H
#define BLI_THREADS_H
-/* one custom lock available now. can be extended */
-#define LOCK_IMAGE 0
-#define LOCK_CUSTOM1 1
+#include <pthread.h>
/* for tables, button in UI, etc */
#define BLENDER_MAX_THREADS 8
struct ListBase;
+
+/* Threading API */
+
void BLI_init_threads (struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
int BLI_available_threads(struct ListBase *threadbase);
int BLI_available_thread_index(struct ListBase *threadbase);
@@ -48,18 +49,46 @@ void BLI_remove_thread_index(struct ListBase *threadbase, int index);
void BLI_remove_threads(struct ListBase *threadbase);
void BLI_end_threads (struct ListBase *threadbase);
-void BLI_lock_thread (int type);
-void BLI_unlock_thread (int type);
+/* System Information */
+
+int BLI_system_thread_count(void); /* gets the number of threads the system can make use of */
+
+/* Global Mutex Locks
+ *
+ * One custom lock available now. can be extended. */
+
+#define LOCK_IMAGE 0
+#define LOCK_PREVIEW 1
+#define LOCK_CUSTOM1 2
+
+void BLI_lock_thread(int type);
+void BLI_unlock_thread(int type);
+
+/* Mutex Lock */
+
+typedef pthread_mutex_t ThreadMutex;
+
+void BLI_mutex_init(ThreadMutex *mutex);
+void BLI_mutex_lock(ThreadMutex *mutex);
+void BLI_mutex_unlock(ThreadMutex *mutex);
+void BLI_mutex_end(ThreadMutex *mutex);
-int BLI_system_thread_count( void ); /* gets the number of threads the system can make use of */
+/* Read/Write Mutex Lock */
- /* exported by preview render, it has to ensure render buffers are not freed while draw */
-void BLI_lock_malloc_thread(void);
-void BLI_unlock_malloc_thread(void);
+#define THREAD_LOCK_READ 1
+#define THREAD_LOCK_WRITE 2
-/* ThreadedWorker is a simple tool for dispatching work to a limited number of threads in a transparent
- * fashion from the caller's perspective
- * */
+typedef pthread_rwlock_t ThreadRWMutex;
+
+void BLI_rw_mutex_init(ThreadRWMutex *mutex);
+void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode);
+void BLI_rw_mutex_unlock(ThreadRWMutex *mutex);
+void BLI_rw_mutex_end(ThreadRWMutex *mutex);
+
+/* ThreadedWorker
+ *
+ * A simple tool for dispatching work to a limited number of threads
+ * in a transparent fashion from the caller's perspective. */
struct ThreadedWorker;
diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h
index f9a84e071e7..1ce7a8cdb77 100644
--- a/source/blender/blenlib/BLI_util.h
+++ b/source/blender/blenlib/BLI_util.h
@@ -42,7 +42,14 @@ struct ListBase;
struct direntry;
char *BLI_gethome(void);
-char *BLI_gethome_folder(char *folder_name);
+char *BLI_gethome_folder(char *folder_name, int flag);
+
+/* BLI_gethome_folder flag */
+#define BLI_GETHOME_LOCAL 1<<1 /* relative location for portable binaries */
+#define BLI_GETHOME_SYSTEM 1<<2 /* system location, or set from the BLENDERPATH env variable (UNIX only) */
+#define BLI_GETHOME_USER 1<<3 /* home folder ~/.blender */
+#define BLI_GETHOME_ALL (BLI_GETHOME_SYSTEM|BLI_GETHOME_LOCAL|BLI_GETHOME_USER)
+
void BLI_setenv(const char *env, const char *val);
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index b46ebebacd5..757b3605203 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -28,7 +28,13 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
+
+#ifndef __WINSTUFF_H__
+#define __WINSTUFF_H__
+
+#ifndef FREE_WINDOWS
#pragma warning(once: 4761 4305 4244 4018)
+#endif
#define WIN32_LEAN_AND_MEAN
@@ -56,10 +62,7 @@
#undef small
-#ifndef __WINSTUFF_H__
-#define __WINSTUFF_H__
-
- // These definitions are also in arithb for simplicity
+// These definitions are also in arithb for simplicity
#ifdef __cplusplus
extern "C" {
@@ -91,6 +94,16 @@ extern "C" {
typedef unsigned int mode_t;
#endif
+/* mingw using _SSIZE_T_ to declare ssize_t type */
+#ifndef _SSIZE_T_
+#define _SSIZE_T_
+/* python uses HAVE_SSIZE_T */
+#ifndef HAVE_SSIZE_T
+#define HAVE_SSIZE_T 1
+typedef long ssize_t;
+#endif
+#endif
+
struct dirent {
int d_ino;
int d_off;
diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c
new file mode 100644
index 00000000000..a7ce1df5712
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_bfile.c
@@ -0,0 +1,236 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by Stichting Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * BFILE* based abstraction for file access.
+ */
+
+#include <string.h>
+
+#ifndef WIN32
+ #include <unistd.h>
+#else
+ #include <io.h>
+ #include "BLI_winstuff.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_bfile.h"
+
+// This would provide config paths and their oldest viable version
+// so if there is an uncompatible change, user's old versions are not loaded
+//#include "bfile_tables.h"
+
+/* Internal bfile type flags */
+#define BTF_OPEN (0)
+#define BTF_FOPEN (1<<0)
+#define BTF_READ (1<<1)
+#define BTF_WRITE (1<<2)
+#define BTF_AT_END (1<<3)
+#define BTF_DISCARD (1<<4)
+
+
+void fill_paths(BFILE *bfile, const char *path) {
+ char* source_path = NULL;
+ int bflags = bfile->uflags;
+
+ if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
+// bfile->fpath is path with // replaced
+ }
+ if(bflags & BFILE_TEMP) {
+// bfile->fpath is tempdir+path
+ }
+ if(bflags & BFILE_CONFIG) {
+// bfile->fpath is userdir+version+path
+// source_path is first hit in (if using fallback to older versions)
+// userdir+curversion+path (... userdir+limitversion+path) sysdir+path
+// (limitversion is based in path, using some kind of regex or "tables")
+ }
+
+ if(bfile->type & BTF_WRITE && !(bflags & BFILE_RAW)) {
+ /* Generate temp path */
+ // bfile->tpath is fpath+randstring
+ if(!(bfile->type & BTF_DISCARD)) {
+ /* Copy data to tpath */
+ if(source_path) {
+ // copy it from older version or sys version
+ }
+ }
+ } else {
+ bfile->tpath = bfile->fpath;
+ }
+}
+
+BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) {
+ BFILE *bfile;
+
+ bfile = MEM_mallocN(sizeof(BFILE), "bfile-fopen");
+ bfile->type = BTF_FOPEN;
+ bfile->uflags = bflags;
+
+ /* From fopen() doc, we can guess some logic:
+ r BTF_READ
+ r+ BTF_READ | BTF_WRITE
+ w BTF_DISCARD | BTF_WRITE
+ w+ BTF_DISCARD | BTF_WRITE | BTF_READ
+ a BTF_AT_END | BTF_WRITE
+ a+ BTF_AT_END | BTF_WRITE | BTF_READ
+ */
+ if(strchr(mode, 'r'))
+ bfile->type |= BTF_READ;
+ if(strchr(mode, 'w'))
+ bfile->type |= (BTF_DISCARD | BTF_WRITE);
+ if(strchr(mode, 'a'))
+ bfile->type |= (BTF_AT_END | BTF_WRITE);
+ if(strchr(mode, '+'))
+ bfile->type |= (BTF_READ | BTF_WRITE);
+
+ fill_paths(bfile, path);
+
+ bfile->stream = fopen(bfile->tpath, mode);
+ // detect failed fopen
+ bfile->fd = fileno(bfile->stream);
+ return bfile;
+}
+
+
+BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags) {
+ BFILE *bfile;
+
+ bfile = MEM_mallocN(sizeof(BFILE), "bfile-open");
+ bfile->type = BTF_OPEN;
+ bfile->uflags = bflags;
+
+ /* Easy mapping for open() */
+ if(flags & O_RDONLY)
+ bfile->type |= BTF_READ;
+ if(flags & O_WRONLY)
+ bfile->type |= BTF_WRITE;
+ if(flags & O_RDWR)
+ bfile->type |= (BTF_READ | BTF_WRITE);
+ if(flags & O_APPEND)
+ bfile->type |= BTF_AT_END;
+ if(flags & O_TRUNC)
+ bfile->type |= BTF_DISCARD;
+
+ fill_paths(bfile, pathname);
+
+ bfile->fd = open(bfile->tpath, flags);
+ // detect failed open
+// bfile->stream = fdopen(bfile->fd, XXX); /* MSWindows _fdopen? */
+ return bfile;
+}
+
+
+FILE *BLI_bfile_file_from_bfile(BFILE *bfile) {
+ return bfile->stream;
+}
+
+
+int BLI_bfile_fd_from_bfile(BFILE *bfile) {
+ return bfile->fd;
+}
+
+
+ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count) {
+ ssize_t ret;
+
+ ret = write((f->fd), buf, count);
+ if (ret == -1) {
+ f->error = 1;
+ }
+
+ return ret;
+}
+
+
+ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) {
+ ssize_t ret;
+
+ ret = read((f->fd), buf, count);
+ if (ret == -1) {
+ f->error = 1;
+ }
+
+ return ret;
+}
+
+
+size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f) {
+ size_t ret;
+
+ ret = fwrite(ptr, size, nmemb, f->stream);
+ if (ret < 0) {
+ f->error = 1;
+ }
+
+ return ret;
+}
+
+
+size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
+ size_t ret;
+
+ ret = fread(ptr, size, nmemb, f->stream);
+ if ((ret < 0) && ferror(f->stream)) {
+ f->error = 1;
+ }
+
+ return ret;
+}
+
+
+void BLI_bfile_close(BFILE *bfile) {
+ if((bfile->type | BTF_WRITE) &&
+ !(bfile->uflags | BFILE_RAW)) {
+ /* Make sure data is on disk */
+ /* Move to final name if no errors */
+ }
+
+ /* Normal close */
+
+ /* Cleanup */
+ if(bfile->fpath) {
+ MEM_freeN(bfile->fpath);
+ }
+ if(bfile->tpath) {
+ MEM_freeN(bfile->tpath);
+ }
+}
+
+
+void BLI_bfile_clear_error(BFILE *bfile) {
+ bfile->error = 0;
+}
+
+
+void BLI_bfile_set_error(BFILE *bfile, int error) {
+ /* No cheating, use clear_error() for 0 */
+ if (error) {
+ bfile->error = error;
+ }
+}
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 61d9cce1a58..48bbfc12370 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -329,7 +329,7 @@ static void sort(BVHNode **a0, int begin, int end, int axis)
bvh_insertionsort(a, begin, end, axis);
}
}
-void sort_along_axis(BVHTree *tree, int start, int end, int axis)
+static void sort_along_axis(BVHTree *tree, int start, int end, int axis)
{
sort(tree->nodes, start, end, axis);
}
@@ -337,7 +337,7 @@ void sort_along_axis(BVHTree *tree, int start, int end, int axis)
//after a call to this function you can expect one of:
// every node to left of a[n] are smaller or equal to it
// every node to the right of a[n] are greater or equal to it
-int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){
+static int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){
int begin = _begin, end = _end, cut;
while(end-begin > 3)
{
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
index 1f3a861ba6a..ccf79ed42dc 100644
--- a/source/blender/blenlib/intern/BLI_kdtree.c
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -337,7 +337,7 @@ int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTree
return found;
}
-int range_compare(const void * a, const void * b)
+static int range_compare(const void * a, const void * b)
{
const KDTreeNearest *kda = a;
const KDTreeNearest *kdb = b;
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 9e769e19674..26bbbf040f3 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -2187,23 +2187,40 @@ void VecMulVecf(float *v, float *v1, float *v2)
v[2] = v1[2] * v2[2];
}
-void VecLerpf(float *target, float *a, float *b, float t)
+void VecLerpf(float *target, const float *a, const float *b, const float t)
{
- float s = 1.0f-t;
+ const float s = 1.0f-t;
target[0]= s*a[0] + t*b[0];
target[1]= s*a[1] + t*b[1];
target[2]= s*a[2] + t*b[2];
}
-void Vec2Lerpf(float *target, float *a, float *b, float t)
+void Vec2Lerpf(float *target, const float *a, const float *b, const float t)
{
- float s = 1.0f-t;
+ const float s = 1.0f-t;
target[0]= s*a[0] + t*b[0];
target[1]= s*a[1] + t*b[1];
}
+/* weight 3 vectors, (VecWeightf in 2.4x)
+ * 'w' must be unit length but is not a vector, just 3 weights */
+void VecLerp3f(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
+{
+ p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
+ p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
+ p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2];
+}
+
+/* weight 3 2D vectors, (Vec2Weightf in 2.4x)
+ * 'w' must be unit length but is not a vector, just 3 weights */
+void Vec2Lerp3f(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3])
+{
+ p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
+ p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
+}
+
void VecMidf(float *v, float *v1, float *v2)
{
v[0]= 0.5f*(v1[0]+ v2[0]);
@@ -3548,10 +3565,10 @@ float VecAngle3(float *v1, float *v2, float *v3)
Normalize(vec1);
Normalize(vec2);
- return NormalizedVecAngle2(vec1, vec2) * (float)(180.0/M_PI);
+ return NormalizedVecAngle2(vec1, vec2);
}
-float VecAngle3_2D(float *v1, float *v2, float *v3)
+float Vec2Angle3(float *v1, float *v2, float *v3)
{
float vec1[2], vec2[2];
@@ -3564,7 +3581,7 @@ float VecAngle3_2D(float *v1, float *v2, float *v3)
Normalize2(vec1);
Normalize2(vec2);
- return NormalizedVecAngle2_2D(vec1, vec2) * (float)(180.0/M_PI);
+ return NormalizedVecAngle2_2D(vec1, vec2);
}
/* Return the shortest angle in degrees between the 2 vectors */
@@ -3577,7 +3594,7 @@ float VecAngle2(float *v1, float *v2)
Normalize(vec1);
Normalize(vec2);
- return NormalizedVecAngle2(vec1, vec2)* (float)(180.0/M_PI);
+ return NormalizedVecAngle2(vec1, vec2);
}
float NormalizedVecAngle2(float *v1, float *v2)
@@ -4093,19 +4110,19 @@ void spheremap(float x, float y, float z, float *u, float *v)
/* proposed api by ton and zr, not used yet */
#if 0
/* ***************** m1 = m2 ***************** */
-void cpy_m3_m3(float m1[][3], float m2[][3])
+static void cpy_m3_m3(float m1[][3], float m2[][3])
{
memcpy(m1[0], m2[0], 9*sizeof(float));
}
/* ***************** m1 = m2 ***************** */
-void cpy_m4_m4(float m1[][4], float m2[][4])
+static void cpy_m4_m4(float m1[][4], float m2[][4])
{
memcpy(m1[0], m2[0], 16*sizeof(float));
}
/* ***************** identity matrix ***************** */
-void ident_m4(float m[][4])
+static void ident_m4(float m[][4])
{
m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0;
@@ -4116,7 +4133,7 @@ void ident_m4(float m[][4])
}
/* ***************** m1 = m2 (pre) * m3 (post) ***************** */
-void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
+static void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
{
float m[3][3];
@@ -4136,7 +4153,7 @@ void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
}
/* ***************** m1 = m2 (pre) * m3 (post) ***************** */
-void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
+static void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
{
float m[4][4];
@@ -4164,7 +4181,7 @@ void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
}
/* ***************** m1 = inverse(m2) ***************** */
-void inv_m3_m3(float m1[][3], float m2[][3])
+static void inv_m3_m3(float m1[][3], float m2[][3])
{
short a,b;
float det;
@@ -4187,7 +4204,7 @@ void inv_m3_m3(float m1[][3], float m2[][3])
}
/* ***************** m1 = inverse(m2) ***************** */
-int inv_m4_m4(float inverse[][4], float mat[][4])
+static int inv_m4_m4(float inverse[][4], float mat[][4])
{
int i, j, k;
double temp;
@@ -4240,7 +4257,7 @@ int inv_m4_m4(float inverse[][4], float mat[][4])
}
/* ***************** v1 = v2 * mat ***************** */
-void mul_v3_v3m4(float *v1, float *v2, float mat[][4])
+static void mul_v3_v3m4(float *v1, float *v2, float mat[][4])
{
float x, y;
@@ -4715,7 +4732,7 @@ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float
VecSubf(c, v3t, v1);
VecSubf(a, v2, v1);
- VecSubf(b, v4t, v3);
+ VecSubf(b, v4t, v3t);
Crossf(ab, a, b);
Crossf(cb, c, b);
@@ -4823,6 +4840,15 @@ static float lambda_cp_line(float p[3], float l1[3], float l2[3])
}
#endif
+/* useful to calculate an even width shell, by taking the angle between 2 planes.
+ * The return value is a scale on the offset.
+ * no angle between planes is 1.0, as the angle between the 2 planes approches 180d
+ * the distance gets very high, 180d would be inf, but this case isn't valid */
+float AngleToLength(const float angle)
+{
+ return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle * (M_PI/180.0f)));
+}
+
/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */
void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
{
diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c
index 858aa6e60bf..4820f5529c1 100644
--- a/source/blender/blenlib/intern/dynlib.c
+++ b/source/blender/blenlib/intern/dynlib.c
@@ -23,8 +23,6 @@
* The Original Code is: all of this file, with exception of below:
*
* Contributor(s): Peter O'Gorman
- * The functions osxdlopen() and osxerror()
- * are Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -102,202 +100,6 @@ void PIL_dynlib_close(PILdynlib *lib) {
free(lib);
}
-#else
-#ifdef __APPLE__ /* MacOS X */
-
-#include <mach-o/dyld.h>
-#include <dlfcn.h>
-#include <stdarg.h>
-
-#define ERR_STR_LEN 256
-
-struct PILdynlib {
- void *handle;
-};
-
-static char *osxerror(int setget, const char *str, ...)
-{
- static char errstr[ERR_STR_LEN];
- static int err_filled = 0;
- char *retval;
- NSLinkEditErrors ler;
- int lerno;
- const char *dylderrstr;
- const char *file;
- va_list arg;
- if (setget <= 0)
- {
- va_start(arg, str);
- strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
- vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
- va_end(arg);
- /* We prefer to use the dyld error string if setget is 0 */
- if (setget == 0) {
- NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
-// printf("dyld: %s\n",dylderrstr);
- if (dylderrstr && strlen(dylderrstr))
- strncpy(errstr,dylderrstr,ERR_STR_LEN);
- }
- err_filled = 1;
- retval = NULL;
- }
- else
- {
- if (!err_filled)
- retval = NULL;
- else
- retval = errstr;
- err_filled = 0;
- }
- return retval;
-}
-
-static void *osxdlopen(const char *path, int mode)
-{
- void *module = 0;
- NSObjectFileImage ofi = 0;
- NSObjectFileImageReturnCode ofirc;
- static int (*make_private_module_public) (NSModule module) = 0;
- unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE;
-
- /* If we got no path, the app wants the global namespace, use -1 as the marker
- in this case */
- if (!path)
- return (void *)-1;
-
- /* Create the object file image, works for things linked with the -bundle arg to ld */
- ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
- switch (ofirc)
- {
- case NSObjectFileImageSuccess:
- /* It was okay, so use NSLinkModule to link in the image */
- if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
- module = NSLinkModule(ofi, path,flags);
- /* Don't forget to destroy the object file image, unless you like leaks */
- NSDestroyObjectFileImage(ofi);
- /* If the mode was global, then change the module, this avoids
- multiply defined symbol errors to first load private then make
- global. Silly, isn't it. */
- if ((mode & RTLD_GLOBAL))
- {
- if (!make_private_module_public)
- {
- _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
- (unsigned long *)&make_private_module_public);
- }
- make_private_module_public(module);
- }
- break;
- case NSObjectFileImageInappropriateFile:
- /* It may have been a dynamic library rather than a bundle, try to load it */
- module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
- break;
- case NSObjectFileImageFailure:
- osxerror(0,"Object file setup failure : \"%s\"", path);
- return 0;
- case NSObjectFileImageArch:
- osxerror(0,"No object for this architecture : \"%s\"", path);
- return 0;
- case NSObjectFileImageFormat:
- osxerror(0,"Bad object file format : \"%s\"", path);
- return 0;
- case NSObjectFileImageAccess:
- osxerror(0,"Can't read object file : \"%s\"", path);
- return 0;
- }
- if (!module)
- osxerror(0, "Can not open \"%s\"", path);
- return module;
-}
-
-PILdynlib *PIL_dynlib_open(char *name) {
- void *handle= osxdlopen(name, RTLD_LAZY);
-
- if (handle) {
- PILdynlib *lib= malloc(sizeof(*lib));
- lib->handle= handle;
-
- return lib;
- } else {
- return NULL;
- }
-}
-
-void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname)
-{
- int sym_len = strlen(symname);
- void *value = NULL;
- char *malloc_sym = NULL;
- NSSymbol *nssym = 0;
- malloc_sym = malloc(sym_len + 2);
- if (malloc_sym)
- {
- sprintf(malloc_sym, "_%s", symname);
- /* If the lib->handle is -1, if is the app global context */
- if (lib->handle == (void *)-1)
- {
- /* Global context, use NSLookupAndBindSymbol */
- if (NSIsSymbolNameDefined(malloc_sym))
- {
- nssym = NSLookupAndBindSymbol(malloc_sym);
- }
- }
- /* Now see if the lib->handle is a struch mach_header* or not, use NSLookupSymbol in image
- for libraries, and NSLookupSymbolInModule for bundles */
- else
- {
- /* Check for both possible magic numbers depending on x86/ppc byte order */
- if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
- (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
- {
- if (NSIsSymbolNameDefinedInImage((struct mach_header *)lib->handle, malloc_sym))
- {
- nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle,
- malloc_sym,
- NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
- | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
- }
-
- }
- else
- {
- nssym = NSLookupSymbolInModule(lib->handle, malloc_sym);
- }
- }
- if (!nssym)
- {
- osxerror(0, "symname \"%s\" Not found", symname);
- }
- value = NSAddressOfSymbol(nssym);
- free(malloc_sym);
- }
- else
- {
- osxerror(-1, "Unable to allocate memory");
- }
- return value;
-}
-
-char *PIL_dynlib_get_error_as_string(PILdynlib* lib)
-{
- return osxerror(1, (char *)NULL);
-}
-
-void PIL_dynlib_close(PILdynlib *lib)
-{
- if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
- (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
- {
- osxerror(-1, "Can't remove dynamic libraries on darwin");
- }
- if (!NSUnLinkModule(lib->handle, 0))
- {
- osxerror(0, "unable to unlink module %s", NSNameOfModule(lib->handle));
- }
-
- free(lib);
-}
-
#else /* Unix */
#include <dlfcn.h>
@@ -334,4 +136,4 @@ void PIL_dynlib_close(PILdynlib *lib) {
}
#endif
-#endif
+
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 985700efda1..cb5632df569 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -65,7 +65,7 @@ static FT_Library library;
static FT_Error err;
-void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
+static void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
{
// Blender
struct Nurb *nu;
@@ -275,7 +275,7 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
}
}
-int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
+static int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
{
// Freetype2
FT_Face face;
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
index cc15c499290..49a3cad53f1 100644
--- a/source/blender/blenlib/intern/graph.c
+++ b/source/blender/blenlib/intern/graph.c
@@ -354,7 +354,7 @@ void BLI_ReflagSubgraph(BGraph *graph, int old_subgraph, int new_subgraph)
/*************************************** CYCLE DETECTION ***********************************************/
-int detectCycle(BNode *node, BArc *src_arc)
+static int detectCycle(BNode *node, BArc *src_arc)
{
int value = 0;
@@ -520,7 +520,7 @@ void BLI_calcGraphLength(BGraph *graph)
/********************************* SYMMETRY DETECTION **************************************************/
-void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit);
+static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit);
void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3])
{
@@ -935,7 +935,7 @@ static void markdownSecondarySymmetry(BGraph *graph, BNode *node, int depth, int
}
}
-void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit)
+static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit)
{
int i;
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 3194593374f..b3a4722d6d9 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -359,3 +359,17 @@ void BLI_duplicatelist(ListBase *list1, ListBase *list2) /* copy from 2 to 1 */
}
}
+/* create a generic list node containing link to provided data */
+LinkData *BLI_genericNodeN (void *data)
+{
+ LinkData *ld;
+
+ if (data == NULL)
+ return NULL;
+
+ /* create new link, and make it hold the given data */
+ ld= MEM_callocN(sizeof(LinkData), "BLI_genericNodeN()");
+ ld->data= data;
+
+ return ld;
+}
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 0bd30a69d05..66e9a65dba5 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -42,9 +42,9 @@
#endif
/* local */
-float noise3_perlin(float vec[3]);
-float turbulence_perlin(float *point, float lofreq, float hifreq);
-float turbulencep(float noisesize, float x, float y, float z, int nr);
+static float noise3_perlin(float vec[3]);
+static float turbulence_perlin(float *point, float lofreq, float hifreq);
+static float turbulencep(float noisesize, float x, float y, float z, int nr);
#define HASHVEC(x,y,z) hashvectf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255]
@@ -915,7 +915,7 @@ float g[512+2][3]= {
r1 = r0 - 1.;
-float noise3_perlin(float vec[3])
+static float noise3_perlin(float vec[3])
{
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
@@ -976,7 +976,7 @@ float noise3_perlin(float vec[3])
return 1.5 * lerp(sz, c, d); /* interpolate in z */
}
-float turbulence_perlin(float *point, float lofreq, float hifreq)
+static float turbulence_perlin(float *point, float lofreq, float hifreq)
{
float freq, t, p[3];
@@ -1029,7 +1029,7 @@ float BLI_hnoisep(float noisesize, float x, float y, float z)
return noise3_perlin(vec);
}
-float turbulencep(float noisesize, float x, float y, float z, int nr)
+static float turbulencep(float noisesize, float x, float y, float z, int nr)
{
float vec[3];
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index ed3e07b7f7e..b5c6a5a3b4e 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -98,6 +98,7 @@ A sample loop can look like this (pseudo c);
************************************************ */
static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _preview_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER;
static int thread_levels= 0; /* threads can be invoked inside threads */
@@ -112,12 +113,12 @@ typedef struct ThreadSlot {
int avail;
} ThreadSlot;
-void BLI_lock_malloc_thread(void)
+static void BLI_lock_malloc_thread(void)
{
pthread_mutex_lock(&_malloc_lock);
}
-void BLI_unlock_malloc_thread(void)
+static void BLI_unlock_malloc_thread(void)
{
pthread_mutex_unlock(&_malloc_lock);
}
@@ -143,7 +144,9 @@ void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot)
tslot->avail= 1;
}
- MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
+ if(thread_levels == 0)
+ MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
+
thread_levels++;
}
}
@@ -252,21 +255,7 @@ void BLI_end_threads(ListBase *threadbase)
}
}
-void BLI_lock_thread(int type)
-{
- if (type==LOCK_IMAGE)
- pthread_mutex_lock(&_image_lock);
- else if (type==LOCK_CUSTOM1)
- pthread_mutex_lock(&_custom1_lock);
-}
-
-void BLI_unlock_thread(int type)
-{
- if (type==LOCK_IMAGE)
- pthread_mutex_unlock(&_image_lock);
- else if(type==LOCK_CUSTOM1)
- pthread_mutex_unlock(&_custom1_lock);
-}
+/* System Information */
/* how many threads are native on this system? */
int BLI_system_thread_count( void )
@@ -300,6 +289,75 @@ int BLI_system_thread_count( void )
return t;
}
+/* Global Mutex Locks */
+
+void BLI_lock_thread(int type)
+{
+ if (type==LOCK_IMAGE)
+ pthread_mutex_lock(&_image_lock);
+ else if (type==LOCK_PREVIEW)
+ pthread_mutex_lock(&_preview_lock);
+ else if (type==LOCK_CUSTOM1)
+ pthread_mutex_lock(&_custom1_lock);
+}
+
+void BLI_unlock_thread(int type)
+{
+ if (type==LOCK_IMAGE)
+ pthread_mutex_unlock(&_image_lock);
+ else if (type==LOCK_PREVIEW)
+ pthread_mutex_unlock(&_preview_lock);
+ else if(type==LOCK_CUSTOM1)
+ pthread_mutex_unlock(&_custom1_lock);
+}
+
+/* Mutex Locks */
+
+void BLI_mutex_init(ThreadMutex *mutex)
+{
+ pthread_mutex_init(mutex, NULL);
+}
+
+void BLI_mutex_lock(ThreadMutex *mutex)
+{
+ pthread_mutex_lock(mutex);
+}
+
+void BLI_mutex_unlock(ThreadMutex *mutex)
+{
+ pthread_mutex_unlock(mutex);
+}
+
+void BLI_mutex_end(ThreadMutex *mutex)
+{
+ pthread_mutex_destroy(mutex);
+}
+
+/* Read/Write Mutex Lock */
+
+void BLI_rw_mutex_init(ThreadRWMutex *mutex)
+{
+ pthread_rwlock_init(mutex, NULL);
+}
+
+void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
+{
+ if(mode == THREAD_LOCK_READ)
+ pthread_rwlock_rdlock(mutex);
+ else
+ pthread_rwlock_wrlock(mutex);
+}
+
+void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
+{
+ pthread_rwlock_unlock(mutex);
+}
+
+void BLI_rw_mutex_end(ThreadRWMutex *mutex)
+{
+ pthread_rwlock_destroy(mutex);
+}
+
/* ************************************************ */
typedef struct ThreadedWorker {
@@ -316,7 +374,7 @@ typedef struct WorkParam {
int index;
} WorkParam;
-void *exec_work_fnct(void *v_param)
+static void *exec_work_fnct(void *v_param)
{
WorkParam *p = (WorkParam*)v_param;
void *value;
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index c7bb7a54457..f6fa4f1ebd2 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -856,98 +856,123 @@ char *BLI_gethome(void) {
#endif
}
-/* this function returns the path to a blender folder, if it exists,
- * trying in this order:
- *
- * path_to_executable/release/folder_name (in svn)
- * ./release/folder_name (in svn)
- * $HOME/.blender/folder_name
- * path_to_executable/.blender/folder_name
- *
- * returns NULL if none is found. */
+/* this function returns the path to a blender folder, if it exists
+ * utility functions for BLI_gethome_folder */
-char *BLI_gethome_folder(char *folder_name)
+/* #define PATH_DEBUG */ /* for testing paths that are checked */
+
+static int test_data_path(char *targetpath, char *path_base, char *path_sep, char *folder_name)
+{
+ char tmppath[FILE_MAXDIR];
+
+ if(path_sep) BLI_join_dirfile(tmppath, path_base, path_sep);
+ else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
+
+ BLI_make_file_string("/", targetpath, tmppath, folder_name);
+
+ if (BLI_exists(targetpath)) {
+#ifdef PATH_DEBUG
+ printf("\tpath found: %s\n", targetpath);
+#endif
+ return 1;
+ }
+ else {
+#ifdef PATH_DEBUG
+ printf("\tpath missing: %s\n", targetpath);
+#endif
+ targetpath[0] = '\0';
+ return 0;
+ }
+}
+
+static int gethome_path_local(char *targetpath, char *folder_name)
{
extern char bprogname[]; /* argv[0] from creator.c */
- static char homedir[FILE_MAXDIR] = "";
- static char fulldir[FILE_MAXDIR] = "";
- char tmpdir[FILE_MAXDIR];
char bprogdir[FILE_MAXDIR];
+ char cwd[FILE_MAXDIR];
char *s;
int i;
-
+
+#ifdef PATH_DEBUG
+ printf("gethome_path_local...\n");
+#endif
+
+ /* try release/folder_name (binary relative) */
/* use argv[0] (bprogname) to get the path to the executable */
s = BLI_last_slash(bprogname);
-
i = s - bprogname + 1;
BLI_strncpy(bprogdir, bprogname, i);
- /* try path_to_executable/release/folder_name (in svn) */
- if (folder_name) {
- BLI_snprintf(tmpdir, sizeof(tmpdir), "release/%s", folder_name);
- BLI_make_file_string("/", fulldir, bprogdir, tmpdir);
- if (BLI_exists(fulldir)) return fulldir;
- else fulldir[0] = '\0';
- }
+ /* try release/folder_name (CWD relative) */
+ if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name))
+ return 1;
- /* try ./release/folder_name (in svn) */
- if(folder_name) {
- BLI_snprintf(fulldir, sizeof(fulldir), "./release/%s", folder_name);
- if (BLI_exists(fulldir)) return fulldir;
- else fulldir[0] = '\0';
- }
+ if(test_data_path(targetpath, bprogdir, "release", folder_name))
+ return 1;
- /* BLI_gethome() can return NULL if env vars are not set */
- s = BLI_gethome();
+ /* try ./.blender/folder_name */
+ if(test_data_path(targetpath, bprogdir, ".blender", folder_name))
+ return 1;
+
+ return 0;
+}
- if(!s) { /* bail if no $HOME */
- printf("$HOME is NOT set\n");
- return NULL;
- }
+static int gethome_path_user(char *targetpath, char *folder_name)
+{
+ char *home_path= BLI_gethome();
- if(strstr(s, ".blender"))
- BLI_strncpy(homedir, s, FILE_MAXDIR);
- else
- BLI_make_file_string("/", homedir, s, ".blender");
+#ifdef PATH_DEBUG
+ printf("gethome_path_user...\n");
+#endif
+
+ /* try $HOME/folder_name */
+ return test_data_path(targetpath, home_path, ".blender", folder_name);
+}
- /* if $HOME/.blender/folder_name exists, return it */
- if(BLI_exists(homedir)) {
- if (folder_name) {
- BLI_make_file_string("/", fulldir, homedir, folder_name);
- if(BLI_exists(fulldir))
- return fulldir;
- }
- else
- return homedir;
- }
- else
- homedir[0] = '\0';
-
- /* using tmpdir to preserve homedir (if) found above:
- * the ideal is to have a home dir with folder_name dir inside
- * it, but if that isn't available, it's possible to
- * have a 'broken' home dir somewhere and a folder_name dir in the
- * svn sources */
- BLI_make_file_string("/", tmpdir, bprogdir, ".blender");
-
- if(BLI_exists(tmpdir)) {
- if(folder_name) {
- BLI_make_file_string("/", fulldir, tmpdir, folder_name);
- if(BLI_exists(fulldir)) {
- BLI_strncpy(homedir, tmpdir, FILE_MAXDIR);
- return fulldir;
- }
- else {
- homedir[0] = '\0';
- fulldir[0] = '\0';
- }
- }
- else return homedir;
+static int gethome_path_system(char *targetpath, char *folder_name)
+{
+ extern char blender_path[]; /* unix prefix eg. /usr/share/blender/2.5 creator.c */
+
+ if(!blender_path[0])
+ return 0;
+
+#ifdef PATH_DEBUG
+ printf("gethome_path_system...\n");
+#endif
+
+ /* try $BLENDERPATH/folder_name */
+ return test_data_path(targetpath, blender_path, NULL, folder_name);
+}
+
+char *BLI_gethome_folder(char *folder_name, int flag)
+{
+ static char fulldir[FILE_MAXDIR] = "";
+
+ /* first check if this is a redistributable bundle */
+ if(flag & BLI_GETHOME_LOCAL) {
+ if (gethome_path_local(fulldir, folder_name))
+ return fulldir;
}
+ /* then check if the OS has blender data files installed in a global location */
+ if(flag & BLI_GETHOME_SYSTEM) {
+ if (gethome_path_system(fulldir, folder_name))
+ return fulldir;
+ }
+
+ /* now check the users home dir for data files */
+ if(flag & BLI_GETHOME_USER) {
+ if (gethome_path_user(fulldir, folder_name))
+ return fulldir;
+ }
+
return NULL;
}
+#ifdef PATH_DEBUG
+#undef PATH_DEBUG
+#endif
+
void BLI_setenv(const char *env, const char*val)
{
/* SGI or free windows */
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 4fafac29a6f..52295dc3092 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -36,7 +36,6 @@ extern "C" {
struct bScreen;
struct direntry;
-struct FileList;
struct LinkNode;
struct Main;
struct MemFile;
@@ -45,6 +44,7 @@ struct Scene;
struct SpaceFile;
struct SpaceImaSel;
struct UserDef;
+struct bContext;
typedef struct BlendHandle BlendHandle;
@@ -197,12 +197,23 @@ BLO_blendhandle_close(
/***/
-char *BLO_gethome(void);
+#define GROUP_MAX 32
+
int BLO_has_bfile_extension(char *str);
-void BLO_library_append(BlendHandle **libfiledata, struct direntry* filelist, int totfile,
- char *dir, char* file, short flag, int idcode, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);
+/* return ok when a blenderfile, in dir is the filename,
+ * in group the type of libdata
+ */
+int BLO_is_a_library(char *path, char *dir, char *group);
+
+struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, char *dir);
+void BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, char *name, int idcode, short flag);
+void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag);
+
+/* deprecated */
+#if 1
void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);
+#endif
BlendFileData* blo_read_blendafterruntime(int file, char *name, int actualsize, struct ReportList *reports);
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 9cd45a268da..3d21bb54e2b 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -99,7 +99,6 @@ static IDType idtypes[]= {
{ ID_IP, "Ipo", IDTYPE_FLAGS_ISLINKABLE},
{ ID_KE, "Key", 0},
{ ID_LA, "Lamp", IDTYPE_FLAGS_ISLINKABLE},
- { ID_LF, "Life", 0},
{ ID_LI, "Library", 0},
{ ID_LT, "Lattice", IDTYPE_FLAGS_ISLINKABLE},
{ ID_MA, "Material", IDTYPE_FLAGS_ISLINKABLE},
@@ -110,7 +109,6 @@ static IDType idtypes[]= {
{ ID_SCE, "Scene", IDTYPE_FLAGS_ISLINKABLE},
{ ID_SCR, "Screen", 0},
{ ID_SEQ, "Sequence", 0},
- { ID_SE, "Sector", 0},
{ ID_SO, "Sound", IDTYPE_FLAGS_ISLINKABLE},
{ ID_TE, "Texture", IDTYPE_FLAGS_ISLINKABLE},
{ ID_TXT, "Text", IDTYPE_FLAGS_ISLINKABLE},
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 99285fefb4d..6fce17a4892 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -113,6 +113,7 @@
#include "BKE_cloth.h"
#include "BKE_colortools.h"
#include "BKE_constraint.h"
+#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
@@ -1065,6 +1066,46 @@ int BLO_has_bfile_extension(char *str)
return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend")||BLI_testextensie(str, ".blend.gz"));
}
+int BLO_is_a_library(char *path, char *dir, char *group)
+{
+ /* return ok when a blenderfile, in dir is the filename,
+ * in group the type of libdata
+ */
+ int len;
+ char *fd;
+
+ strcpy(dir, path);
+ len= strlen(dir);
+ if(len<7) return 0;
+ if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
+
+ group[0]= 0;
+ dir[len-1]= 0;
+
+ /* Find the last slash */
+ fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+
+ if(fd==0) return 0;
+ *fd= 0;
+ if(BLO_has_bfile_extension(fd+1)) {
+ /* the last part of the dir is a .blend file, no group follows */
+ *fd= '/'; /* put back the removed slash separating the dir and the .blend file name */
+ }
+ else {
+ char *gp = fd+1; // in case we have a .blend file, gp points to the group
+
+ /* Find the last slash */
+ fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+ if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
+
+ /* now we know that we are in a blend file and it is safe to
+ assume that gp actually points to a group */
+ if (BLI_streq("Screen", gp)==0)
+ BLI_strncpy(group, gp, GROUP_MAX);
+ }
+ return 1;
+}
+
/* ************** OLD POINTERS ******************* */
static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
@@ -2143,6 +2184,8 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data = ((bKinematicConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
data->poletar = newlibadr(fd, id->lib, data->poletar);
+ con->lin_error = 0.f;
+ con->rot_error = 0.f;
}
break;
case CONSTRAINT_TYPE_TRACKTO:
@@ -2290,6 +2333,7 @@ static void lib_link_armature(FileData *fd, Main *main)
while(arm) {
if(arm->id.flag & LIB_NEEDLINK) {
+ if (arm->adt) lib_link_animdata(fd, &arm->id, arm->adt);
arm->id.flag -= LIB_NEEDLINK;
}
arm= arm->id.next;
@@ -2316,6 +2360,7 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
link_list(fd, &arm->bonebase);
arm->edbo= NULL;
arm->sketch = NULL;
+ arm->adt= newdataadr(fd, arm->adt);
bone=arm->bonebase.first;
while (bone) {
@@ -2999,6 +3044,10 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
part->bb_ob = newlibadr(fd, part->id.lib, part->bb_ob);
+
+ if(part->effector_weights)
+ part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
+
if(part->boids) {
BoidState *state = part->boids->states.first;
BoidRule *rule;
@@ -3034,6 +3083,11 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
part->pd= newdataadr(fd, part->pd);
part->pd2= newdataadr(fd, part->pd2);
+ if(part->effector_weights)
+ part->effector_weights = newdataadr(fd, part->effector_weights);
+ else
+ part->effector_weights = BKE_add_effector_weights(part->eff_group);
+
part->boids= newdataadr(fd, part->boids);
if(part->boids) {
@@ -3110,18 +3164,19 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
}
- psys->child=newdataadr(fd,psys->child);
- psys->effectors.first=psys->effectors.last=0;
+ psys->child = newdataadr(fd,psys->child);
+ psys->effectors = NULL;
link_list(fd, &psys->targets);
psys->edit = NULL;
psys->free_edit = NULL;
- psys->pathcache = 0;
- psys->childcache = 0;
- psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
- psys->childcachebufs.first = psys->childcachebufs.last = 0;
- psys->reactevents.first = psys->reactevents.last = 0;
+ psys->pathcache = NULL;
+ psys->childcache = NULL;
+ psys->pathcachebufs.first = psys->pathcachebufs.last = NULL;
+ psys->childcachebufs.first = psys->childcachebufs.last = NULL;
+ psys->frand = NULL;
+ psys->pdd = NULL;
direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache);
@@ -3570,6 +3625,11 @@ static void lib_link_object(FileData *fd, Main *main)
else if(act->type==ACT_STATE) {
/* bStateActuator *statea = act->data; */
}
+ else if(act->type==ACT_ARMATURE) {
+ bArmatureActuator *arma= act->data;
+ arma->target= newlibadr(fd, ob->id.lib, arma->target);
+ arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget);
+ }
act= act->next;
}
@@ -3590,12 +3650,24 @@ static void lib_link_object(FileData *fd, Main *main)
smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
}
}
+
+ {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(clmd)
+ {
+ clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group);
+ }
+ }
/* texture field */
if(ob->pd)
if(ob->pd->tex)
ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex);
+ if(ob->soft)
+ ob->soft->effector_weights->group = newlibadr(fd, ob->id.lib, ob->soft->effector_weights->group);
+
lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
lib_link_modifiers(fd, ob);
}
@@ -3631,6 +3703,10 @@ static void direct_link_pose(FileData *fd, bPose *pose)
pchan->iktree.first= pchan->iktree.last= NULL;
pchan->path= NULL;
}
+ pose->ikdata = NULL;
+ if (pose->ikparam != NULL) {
+ pose->ikparam= newdataadr(fd, pose->ikparam);
+ }
}
static void direct_link_modifiers(FileData *fd, ListBase *lb)
@@ -3671,6 +3747,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
if(clmd->sim_parms->presets > 10)
clmd->sim_parms->presets = 0;
}
+
+ if(clmd->sim_parms->effector_weights)
+ clmd->sim_parms->effector_weights = newdataadr(fd, clmd->sim_parms->effector_weights);
+ else
+ clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
}
else if (md->type==eModifierType_Fluidsim) {
@@ -3892,6 +3973,8 @@ static void direct_link_object(FileData *fd, Object *ob)
}
ob->pd= newdataadr(fd, ob->pd);
+ if(ob->pd)
+ ob->pd->rng=NULL;
ob->soft= newdataadr(fd, ob->soft);
if(ob->soft) {
SoftBody *sb= ob->soft;
@@ -3909,6 +3992,11 @@ static void direct_link_object(FileData *fd, Object *ob)
}
}
+ if(sb->effector_weights)
+ sb->effector_weights = newdataadr(fd, sb->effector_weights);
+ else
+ sb->effector_weights = BKE_add_effector_weights(NULL);
+
direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache);
}
ob->bsoft= newdataadr(fd, ob->bsoft);
@@ -4328,6 +4416,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->timers.first= win->timers.last= NULL;
win->queue.first= win->queue.last= NULL;
win->handlers.first= win->handlers.last= NULL;
+ win->modalhandlers.first= win->modalhandlers.last= NULL;
win->subwindows.first= win->subwindows.last= NULL;
win->gesture.first= win->gesture.last= NULL;
@@ -4642,7 +4731,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
v3d->layact= v3d->localvd->layact;
MEM_freeN(v3d->localvd);
v3d->localvd= NULL;
- v3d->localview= 0;
}
*/
}
@@ -4785,7 +4873,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->ri= NULL;
rv3d->sms= NULL;
rv3d->smooth_timer= NULL;
- rv3d->lastmode= 0;
}
}
@@ -4820,6 +4907,10 @@ static void view3d_split_250(View3D *v3d, ListBase *regions)
QUATCOPY(rv3d->viewquat, v3d->viewquat);
}
}
+
+ /* this was not initialized correct always */
+ if(v3d->twtype == 0)
+ v3d->twtype= V3D_MANIP_TRANSLATE;
}
static void direct_link_screen(FileData *fd, bScreen *sc)
@@ -6095,7 +6186,70 @@ static void do_versions_gpencil_2_50(Main *main, bScreen *screen)
}
}
+static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype)
+{
+ MTex *mtex;
+ float varfac, colfac;
+ int a, neg;
+
+ if(!mtex_array)
+ return;
+ for(a=0; a<MAX_MTEX; a++) {
+ if(mtex_array[a]) {
+ mtex= mtex_array[a];
+
+ neg= mtex->maptoneg;
+ varfac= mtex->varfac;
+ colfac= mtex->colfac;
+
+ if(neg & MAP_DISP) mtex->dispfac= -mtex->dispfac;
+ if(neg & MAP_NORM) mtex->norfac= -mtex->norfac;
+ if(neg & MAP_WARP) mtex->warpfac= -mtex->warpfac;
+
+ mtex->colspecfac= (neg & MAP_COLSPEC)? -colfac: colfac;
+ mtex->mirrfac= (neg & MAP_COLMIR)? -colfac: colfac;
+ mtex->alphafac= (neg & MAP_ALPHA)? -varfac: varfac;
+ mtex->difffac= (neg & MAP_REF)? -varfac: varfac;
+ mtex->specfac= (neg & MAP_SPEC)? -varfac: varfac;
+ mtex->emitfac= (neg & MAP_EMIT)? -varfac: varfac;
+ mtex->hardfac= (neg & MAP_HAR)? -varfac: varfac;
+ mtex->raymirrfac= (neg & MAP_RAYMIRR)? -varfac: varfac;
+ mtex->translfac= (neg & MAP_TRANSLU)? -varfac: varfac;
+ mtex->ambfac= (neg & MAP_AMB)? -varfac: varfac;
+ mtex->colemitfac= (neg & MAP_EMISSION_COL)? -colfac: colfac;
+ mtex->colreflfac= (neg & MAP_REFLECTION_COL)? -colfac: colfac;
+ mtex->coltransfac= (neg & MAP_TRANSMISSION_COL)? -colfac: colfac;
+ mtex->densfac= (neg & MAP_DENSITY)? -varfac: varfac;
+ mtex->scatterfac= (neg & MAP_SCATTERING)? -varfac: varfac;
+ mtex->reflfac= (neg & MAP_REFLECTION)? -varfac: varfac;
+
+ mtex->timefac= (neg & MAP_PA_TIME)? -varfac: varfac;
+ mtex->lengthfac= (neg & MAP_PA_LENGTH)? -varfac: varfac;
+ mtex->clumpfac= (neg & MAP_PA_CLUMP)? -varfac: varfac;
+ mtex->kinkfac= (neg & MAP_PA_KINK)? -varfac: varfac;
+ mtex->roughfac= (neg & MAP_PA_ROUGH)? -varfac: varfac;
+ mtex->padensfac= (neg & MAP_PA_DENS)? -varfac: varfac;
+ mtex->lifefac= (neg & MAP_PA_LIFE)? -varfac: varfac;
+ mtex->sizefac= (neg & MAP_PA_SIZE)? -varfac: varfac;
+ mtex->ivelfac= (neg & MAP_PA_IVEL)? -varfac: varfac;
+ mtex->pvelfac= (neg & MAP_PA_PVEL)? -varfac: varfac;
+
+ mtex->shadowfac= (neg & LAMAP_SHAD)? -colfac: colfac;
+
+ mtex->zenupfac= (neg & WOMAP_ZENUP)? -colfac: colfac;
+ mtex->zendownfac= (neg & WOMAP_ZENDOWN)? -colfac: colfac;
+ mtex->blendfac= (neg & WOMAP_BLEND)? -varfac: varfac;
+
+ if(idtype == ID_MA)
+ mtex->colfac= (neg & MAP_COL)? -colfac: colfac;
+ else if(idtype == ID_LA)
+ mtex->colfac= (neg & LAMAP_COL)? -colfac: colfac;
+ else if(idtype == ID_WO)
+ mtex->colfac= (neg & WOMAP_HORIZ)? -colfac: colfac;
+ }
+ }
+}
static void do_versions(FileData *fd, Library *lib, Main *main)
{
@@ -9305,10 +9459,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
*/
//do_versions_ipos_to_animato(main);
- /* toolsettings */
- for(scene= main->scene.first; scene; scene= scene->id.next)
- scene->r.audio = scene->audio;
-
/* shader, composit and texture node trees have id.name empty, put something in
* to have them show in RNA viewer and accessible otherwise.
*/
@@ -9322,7 +9472,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
strcpy(sce->nodetree->id.name, "NTComposit Nodetree");
/* move to cameras */
- if(sce->r.scemode & R_PANORAMA) {
+ if(sce->r.mode & R_PANORAMA) {
for(base=sce->base.first; base; base=base->next) {
ob= newlibadr(fd, lib, base->object);
@@ -9332,7 +9482,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- sce->r.scemode &= ~R_PANORAMA;
+ sce->r.mode &= ~R_PANORAMA;
}
}
/* and texture trees */
@@ -9518,15 +9668,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (ma->vol.stepsize < 0.0001f) {
ma->vol.density = 1.0f;
ma->vol.emission = 0.0f;
- ma->vol.absorption = 1.0f;
ma->vol.scattering = 1.0f;
ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
- ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
ma->vol.density_scale = 1.0f;
ma->vol.depth_cutoff = 0.01f;
ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
ma->vol.stepsize = 0.2f;
- ma->vol.shade_stepsize = 0.2f;
ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
ma->vol.precache_resolution = 50;
@@ -9644,6 +9791,105 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) {
+ Scene *sce;
+ Object *ob;
+ Material *ma;
+ Lamp *la;
+ World *wo;
+ Tex *tex;
+ ParticleSettings *part;
+ int do_gravity = 0;
+
+ for(sce = main->scene.first; sce; sce = sce->id.next)
+ if(sce->unit.scale_length == 0.0f)
+ sce->unit.scale_length= 1.0f;
+
+ for(ob = main->object.first; ob; ob = ob->id.next) {
+ /* fluid-sim stuff */
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+ if (fluidmd) fluidmd->fss->fmd = fluidmd;
+
+ /* rotation modes were added, but old objects would now default to being 'quaternion based' */
+ ob->rotmode= ROT_MODE_EUL;
+ }
+
+ for(ma = main->mat.first; ma; ma=ma->id.next) {
+ if(ma->vol.reflection == 0.f) {
+ ma->vol.reflection = 1.f;
+ ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
+ ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
+ }
+
+ do_version_mtex_factor_2_50(ma->mtex, ID_MA);
+ }
+
+ for(la = main->lamp.first; la; la=la->id.next)
+ do_version_mtex_factor_2_50(la->mtex, ID_LA);
+
+ for(wo = main->world.first; wo; wo=wo->id.next)
+ do_version_mtex_factor_2_50(wo->mtex, ID_WO);
+
+ for(tex = main->tex.first; tex; tex=tex->id.next)
+ if(tex->vd)
+ if(tex->vd->extend == 0)
+ tex->vd->extend = TEX_CLIP;
+
+ for(sce= main->scene.first; sce; sce= sce->id.next)
+ {
+ if(sce->audio.main == 0.0)
+ sce->audio.main = 1.0;
+
+ sce->r.ffcodecdata.audio_mixrate = sce->audio.mixrate;
+ sce->r.ffcodecdata.audio_volume = sce->audio.main;
+ sce->audio.distance_model = 2.0;
+ sce->audio.doppler_factor = 1.0;
+ sce->audio.speed_of_sound = 343.3;
+ }
+
+ /* Add default gravity to scenes */
+ for(sce= main->scene.first; sce; sce= sce->id.next) {
+ if((sce->physics_settings.flag & PHYS_GLOBAL_GRAVITY) == 0
+ && VecLength(sce->physics_settings.gravity) == 0.0f) {
+
+ sce->physics_settings.gravity[0] = sce->physics_settings.gravity[1] = 0.0f;
+ sce->physics_settings.gravity[2] = -9.81f;
+ sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
+ do_gravity = 1;
+ }
+ }
+
+ /* Assign proper global gravity weights for dynamics (only z-coordinate is taken into account) */
+ if(do_gravity) for(part= main->particle.first; part; part= part->id.next)
+ part->effector_weights->global_gravity = part->acc[2]/-9.81f;
+
+ for(ob = main->object.first; ob; ob = ob->id.next) {
+ ModifierData *md;
+
+ if(do_gravity) {
+ for(md= ob->modifiers.first; md; md= md->next) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ if(clmd)
+ clmd->sim_parms->effector_weights->global_gravity = clmd->sim_parms->gravity[2]/-9.81;
+ }
+
+ if(ob->soft)
+ ob->soft->effector_weights->global_gravity = ob->soft->grav/9.81;
+ }
+
+ /* Normal wind shape is plane */
+ if(ob->pd) {
+ if(ob->pd->forcefield == PFIELD_WIND)
+ ob->pd->shape = PFIELD_SHAPE_PLANE;
+
+ if(ob->pd->flag & PFIELD_PLANAR)
+ ob->pd->shape = PFIELD_SHAPE_PLANE;
+ else if(ob->pd->flag & PFIELD_SURFACE)
+ ob->pd->shape = PFIELD_SHAPE_SURFACE;
+ }
+ }
+ }
+
/* put 2.50 compatibility code here until next subversion bump */
{
}
@@ -10361,6 +10607,9 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
{
Bone *curBone;
+ if(arm->adt)
+ expand_animdata(fd, mainvar, arm->adt);
+
for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
expand_bones(fd, mainvar, curBone);
}
@@ -10509,11 +10758,19 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
bObjectActuator *oa= act->data;
expand_doit(fd, mainvar, oa->reference);
}
+ else if(act->type==ACT_ADD_OBJECT) {
+ bAddObjectActuator *aoa= act->data;
+ expand_doit(fd, mainvar, aoa->ob);
+ }
else if(act->type==ACT_SCENE) {
bSceneActuator *sa= act->data;
expand_doit(fd, mainvar, sa->camera);
expand_doit(fd, mainvar, sa->scene);
}
+ else if(act->type==ACT_2DFILTER) {
+ bTwoDFilterActuator *tdfa= act->data;
+ expand_doit(fd, mainvar, tdfa->text);
+ }
else if(act->type==ACT_ACTION) {
bActionActuator *aa= act->data;
expand_doit(fd, mainvar, aa->act);
@@ -10530,6 +10787,14 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
bMessageActuator *ma= act->data;
expand_doit(fd, mainvar, ma->toObject);
}
+ else if(act->type==ACT_PARENT) {
+ bParentActuator *pa= act->data;
+ expand_doit(fd, mainvar, pa->ob);
+ }
+ else if(act->type==ACT_ARMATURE) {
+ bArmatureActuator *arma= act->data;
+ expand_doit(fd, mainvar, arma->target);
+ }
act= act->next;
}
@@ -10729,8 +10994,9 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
}
-static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode, short flag)
+static void append_named_part(const bContext *C, Main *mainl, FileData *fd, char *name, int idcode, short flag)
{
+ Scene *scene= CTX_data_scene(C);
Object *ob;
Base *base;
BHead *bhead;
@@ -10746,9 +11012,9 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
if(strcmp(idname+2, name)==0) {
- id= is_yet_read(fd, mainvar, bhead);
+ id= is_yet_read(fd, mainl, bhead);
if(id==NULL) {
- read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
+ read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
}
else {
printf("append: already linked\n");
@@ -10763,13 +11029,18 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
base= MEM_callocN( sizeof(Base), "app_nam_part");
BLI_addtail(&scene->base, base);
- if(id==NULL) ob= mainvar->object.last;
+ if(id==NULL) ob= mainl->object.last;
else ob= (Object *)id;
- /* XXX use context to find view3d->lay */
- //if((flag & FILE_ACTIVELAY)) {
- // scene->lay;
- //}
+ /* link at active layer (view3d->lay if in context, else scene->lay */
+ if((flag & FILE_ACTIVELAY)) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d) {
+ ob->lay = v3d->layact;
+ } else {
+ ob->lay = scene->lay;
+ }
+ }
base->lay= ob->lay;
base->object= ob;
ob->id.us++;
@@ -10788,6 +11059,12 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
}
}
+void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, char *name, int idcode, short flag)
+{
+ FileData *fd= (FileData*)(*bh);
+ append_named_part(C, mainl, fd, name, idcode, flag);
+}
+
static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
{
BHead *bhead;
@@ -10810,11 +11087,10 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
/* common routine to append/link something from a library */
-static Library* library_append(Main *mainvar, Scene *scene, char* file, char *dir, int idcode,
- int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
+static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
{
+ Main *mainvar= CTX_data_main(C);
Main *mainl;
- Library *curlib;
/* make mains */
blo_split_main(&(*fd)->mainlist, mainvar);
@@ -10824,19 +11100,69 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
- curlib= mainl->curlib;
+ return mainl;
+}
+
+Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir)
+{
+ FileData *fd= (FileData*)(*bh);
+ return library_append_begin(C, &fd, dir);
+}
+
+static void append_do_cursor(Scene *scene, Library *curlib, short flag)
+{
+ Base *centerbase;
+ Object *ob;
+ float *curs, centerloc[3], vec[3], min[3], max[3];
+ int count= 0;
+
+ /* when not linking (appending)... */
+ if(flag & FILE_LINK)
+ return;
+
+ /* we're not appending at cursor */
+ if((flag & FILE_ATCURSOR) == 0)
+ return;
- if(totsel==0) {
- append_named_part(*fd, mainl, scene, file, idcode, flag);
+ /* find the center of everything appended */
+ INIT_MINMAX(min, max);
+ centerbase= (scene->base.first);
+ while(centerbase) {
+ if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+ VECCOPY(vec, centerbase->object->loc);
+ DO_MINMAX(vec, min, max);
+ count++;
+ }
+ centerbase= centerbase->next;
}
- else {
- int a;
- for(a=0; a<totfile; a++) {
- if(filelist[a].flags & ACTIVE) {
- append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
- }
+ /* we haven't found any objects to move to cursor */
+ if(!count)
+ return;
+
+ /* move from the center of the appended objects to cursor */
+ centerloc[0]= (min[0]+max[0])/2;
+ centerloc[1]= (min[1]+max[1])/2;
+ centerloc[2]= (min[2]+max[2])/2;
+ curs = scene->cursor;
+ VECSUB(centerloc,curs,centerloc);
+
+ /* now translate the center of the objects */
+ centerbase= (scene->base.first);
+ while(centerbase) {
+ if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+ ob= centerbase->object;
+ ob->loc[0] += centerloc[0];
+ ob->loc[1] += centerloc[1];
+ ob->loc[2] += centerloc[2];
}
+ centerbase= centerbase->next;
}
+}
+
+static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag)
+{
+ Main *mainvar= CTX_data_main(C);
+ Scene *scene= CTX_data_scene(C);
/* make main consistant */
expand_main(*fd, mainl);
@@ -10844,6 +11170,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
/* do this when expand found other libs */
read_libraries(*fd, &(*fd)->mainlist);
+ /* make the lib path relative if required */
if(flag & FILE_STRINGCODE) {
/* use the full path, this could have been read by other library even */
@@ -10866,7 +11193,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
if (flag & FILE_LINK) {
give_base_to_objects(mainvar, scene, NULL, 0);
} else {
- give_base_to_objects(mainvar, scene, curlib, 1);
+ give_base_to_objects(mainvar, scene, mainl->curlib, 1);
}
} else {
give_base_to_objects(mainvar, scene, NULL, 0);
@@ -10882,14 +11209,23 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
*fd = NULL;
}
- return curlib;
+ append_do_cursor(scene, mainl->curlib, flag);
+}
+
+void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
+{
+ FileData *fd= (FileData*)(*bh);
+ library_append_end(C, mainl, &fd, idcode, flag);
+ *bh= (BlendHandle*)fd;
}
/* this is a version of BLO_library_append needed by the BPython API, so
* scripts can load data from .blend files -- see Blender.Library module.*/
/* append to scene */
/* this should probably be moved into the Python code anyway */
-
+/* tentatively removed, Python should be able to use the split functions too: */
+/* BLO_library_append_begin, BLO_library_append_end, BLO_library_append_named_part */
+#if 0
void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports)
{
@@ -10906,88 +11242,7 @@ void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
*bh= (BlendHandle*)fd;
}
-
-/* append to scene */
-void BLO_library_append(BlendHandle** bh, struct direntry* filelist, int totfile,
- char *dir, char* file, short flag, int idcode, Main *mainvar, Scene *scene, ReportList *reports)
-{
- FileData *fd= (FileData*)(*bh);
- Library *curlib;
- Base *centerbase;
- Object *ob;
- int a, totsel=0;
-
- /* are there files selected? */
- for(a=0; a<totfile; a++) {
- if(filelist[a].flags & ACTIVE) {
- totsel++;
- }
- }
-
- if(totsel==0) {
- /* is the indicated file in the filelist? */
- if(file[0]) {
- for(a=0; a<totfile; a++) {
- if( strcmp(filelist[a].relname, file)==0) break;
- }
- if(a==totfile) {
- BKE_report(reports, RPT_ERROR, "Wrong indicated name");
- return;
- }
- }
- else {
- BKE_report(reports, RPT_ERROR, "Nothing indicated");
- return;
- }
- }
- /* now we have or selected, or an indicated file */
-
- if(flag & FILE_AUTOSELECT) scene_deselect_all(scene);
-
- fd->reports= reports;
- curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag );
- if(fd) fd->reports= NULL;
-
- *bh= (BlendHandle*)fd;
-
- /* when not linking (appending)... */
- if((flag & FILE_LINK)==0) {
- if(flag & FILE_ATCURSOR) {
- float *curs, centerloc[3], vec[3], min[3], max[3];
- int count= 0;
-
- INIT_MINMAX(min, max);
-
- centerbase= (scene->base.first);
- while(centerbase) {
- if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
- VECCOPY(vec, centerbase->object->loc);
- DO_MINMAX(vec, min, max);
- count++;
- }
- centerbase= centerbase->next;
- }
- if(count) {
- centerloc[0]= (min[0]+max[0])/2;
- centerloc[1]= (min[1]+max[1])/2;
- centerloc[2]= (min[2]+max[2])/2;
- curs = scene->cursor;
- VECSUB(centerloc,curs,centerloc);
-
- centerbase= (scene->base.first);
- while(centerbase) {
- if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
- ob= centerbase->object;
- ob->loc[0] += centerloc[0];
- ob->loc[1] += centerloc[1];
- ob->loc[2] += centerloc[2];
- }
- centerbase= centerbase->next;
- }
- }
- }
- }
-}
+#endif
/* ************* READ LIBRARY ************** */
@@ -11031,9 +11286,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
printf("read library: lib %s\n", mainptr->curlib->name);
fd= blo_openblenderfile(mainptr->curlib->filename, &reports);
- fd->reports= basefd->reports;
if (fd) {
+ fd->reports= basefd->reports;
+
if (fd->libmap)
oldnewmap_free(fd->libmap);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 98db27182ab..52870420833 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -620,6 +620,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
if (part->adt) write_animdata(wd, part->adt);
writestruct(wd, DATA, "PartDeflect", 1, part->pd);
writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
+ writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights);
if(part->boids && part->phystype == PART_PHYS_BOIDS) {
BoidState *state = part->boids->states.first;
@@ -712,6 +713,9 @@ static void write_sensors(WriteData *wd, ListBase *lb)
case SENS_PROPERTY:
writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
break;
+ case SENS_ARMATURE:
+ writestruct(wd, DATA, "bArmatureSensor", 1, sens->data);
+ break;
case SENS_ACTUATOR:
writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
break;
@@ -830,6 +834,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
case ACT_STATE:
writestruct(wd, DATA, "bStateActuator", 1, act->data);
break;
+ case ACT_ARMATURE:
+ writestruct(wd, DATA, "bArmatureActuator", 1, act->data);
+ break;
default:
; /* error: don't know how to write this file */
}
@@ -1093,8 +1100,16 @@ static void write_pose(WriteData *wd, bPose *pose)
for (grp=pose->agroups.first; grp; grp=grp->next)
writestruct(wd, DATA, "bActionGroup", 1, grp);
+ /* write IK param */
+ if (pose->ikparam) {
+ const char *structname = get_ikparam_name(pose);
+ if (structname)
+ writestruct(wd, DATA, structname, 1, pose->ikparam);
+ }
+
/* Write this pose */
writestruct(wd, DATA, "bPose", 1, pose);
+
}
static void write_defgroups(WriteData *wd, ListBase *defbase)
@@ -1126,6 +1141,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
+ writestruct(wd, DATA, "EffectorWeights", 1, clmd->sim_parms->effector_weights);
write_pointcaches(wd, &clmd->ptcaches);
}
else if(md->type==eModifierType_Smoke) {
@@ -1213,7 +1229,10 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
writestruct(wd, DATA, "SoftBody", 1, ob->soft);
- if(ob->soft) write_pointcaches(wd, &ob->soft->ptcaches);
+ if(ob->soft) {
+ write_pointcaches(wd, &ob->soft->ptcaches);
+ writestruct(wd, DATA, "EffectorWeights", 1, ob->soft->effector_weights);
+ }
writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft);
write_particlesystems(wd, &ob->particlesystem);
@@ -2116,6 +2135,8 @@ static void write_armatures(WriteData *wd, ListBase *idbase)
writestruct(wd, ID_AR, "bArmature", 1, arm);
if (arm->id.properties) IDP_WriteProperty(arm->id.properties, wd);
+ if (arm->adt) write_animdata(wd, arm->adt);
+
/* Direct data */
bone= arm->bonebase.first;
while(bone) {
diff --git a/source/blender/blenpluginapi/CMakeLists.txt b/source/blender/blenpluginapi/CMakeLists.txt
index 1c5e2697c01..e6087a001f8 100644
--- a/source/blender/blenpluginapi/CMakeLists.txt
+++ b/source/blender/blenpluginapi/CMakeLists.txt
@@ -30,6 +30,10 @@ SET(INC
. .. ../../../intern/guardedalloc ../blenlib ../imbuf ../makesdna
)
+IF(WIN32)
+ SET(INC ${INC} ${PTHREADS_INC})
+ENDIF(WIN32)
+
IF(WITH_QUICKTIME)
SET(INC ${INC} ${QUICKTIME_INC})
ADD_DEFINITIONS(-DWITH_QUICKTIME)
diff --git a/source/blender/blenpluginapi/SConscript b/source/blender/blenpluginapi/SConscript
index af69b4519b4..b310bcb95ec 100644
--- a/source/blender/blenpluginapi/SConscript
+++ b/source/blender/blenpluginapi/SConscript
@@ -11,4 +11,11 @@ if env['WITH_BF_QUICKTIME']:
defs.append('WITH_QUICKTIME')
incs += ' ' + env['BF_QUICKTIME_INC']
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( libname = 'bf_blenpluginapi', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [170] )
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt
index 066d42e723e..d13d7ce2ff2 100644
--- a/source/blender/editors/CMakeLists.txt
+++ b/source/blender/editors/CMakeLists.txt
@@ -40,6 +40,7 @@ SET(INC ../windowmanager
../nodes
../gpu
../blenfont
+ ../ikplugin
)
IF(WITH_GAMEENGINE)
diff --git a/source/blender/editors/Makefile b/source/blender/editors/Makefile
index 6a9d695ab0e..e259168a4ef 100644
--- a/source/blender/editors/Makefile
+++ b/source/blender/editors/Makefile
@@ -43,7 +43,7 @@ DIRS = armature \
metaball \
gpencil \
physics \
- preview \
+ render \
uvedit \
space_outliner \
space_time \
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index ccffbdb15d5..226e9247f91 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -14,7 +14,7 @@ SConscript(['datafiles/SConscript',
'curve/SConscript',
'gpencil/SConscript',
'physics/SConscript',
- 'preview/SConscript',
+ 'render/SConscript',
'sound/SConscript',
'space_buttons/SConscript',
'space_file/SConscript',
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index e3418fa194f..8f8700cc43b 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -461,6 +461,9 @@ static void acf_object_name(bAnimListElem *ale, char *name)
/* check if some setting exists for this channel */
static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
{
+ Base *base= (Base *)ale->data;
+ Object *ob= base->object;
+
switch (setting) {
/* muted only in NLA */
case ACHANNEL_SETTING_MUTE:
@@ -468,7 +471,7 @@ static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int
/* visible only in Graph Editor */
case ACHANNEL_SETTING_VISIBLE:
- return ((ac) && (ac->spacetype == SPACE_IPO));
+ return ((ac) && (ac->spacetype == SPACE_IPO) && (ob->adt));
/* only select and expand supported otherwise */
case ACHANNEL_SETTING_SELECT:
@@ -759,7 +762,7 @@ static int acf_fillactd_setting_flag(int setting, short *neg)
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
- return ACT_SELECTED;
+ return ADT_UI_SELECTED;
case ACHANNEL_SETTING_EXPAND: /* expanded */
*neg= 1;
@@ -774,13 +777,18 @@ static int acf_fillactd_setting_flag(int setting, short *neg)
static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type)
{
bAction *act= (bAction *)ale->data;
+ AnimData *adt= ale->adt;
/* clear extra return data first */
*type= 0;
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
- GET_ACF_FLAG_PTR(act->flag);
+ if (adt) {
+ GET_ACF_FLAG_PTR(adt->flag);
+ }
+ else
+ return 0;
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(act->flag);
@@ -998,6 +1006,9 @@ static int acf_dsmat_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1016,6 +1027,7 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(ma->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (ma->adt)
@@ -1067,6 +1079,9 @@ static int acf_dslam_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1085,6 +1100,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(la->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (la->adt)
@@ -1136,6 +1152,9 @@ static int acf_dscam_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1154,6 +1173,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(ca->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (ca->adt)
@@ -1205,6 +1225,9 @@ static int acf_dscur_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1223,6 +1246,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(cu->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (cu->adt)
@@ -1274,6 +1298,9 @@ static int acf_dsskey_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1292,6 +1319,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(key->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (key->adt)
@@ -1343,6 +1371,9 @@ static int acf_dswor_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1361,6 +1392,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(wo->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (wo->adt)
@@ -1412,6 +1444,9 @@ static int acf_dspart_setting_flag(int setting, short *neg)
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
default: /* unsupported */
return 0;
@@ -1430,6 +1465,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(part->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (part->adt)
@@ -1482,6 +1518,9 @@ static int acf_dsmball_setting_flag(int setting, short *neg)
*neg= 1;
return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
+
default: /* unsupported */
return 0;
}
@@ -1499,6 +1538,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ
case ACHANNEL_SETTING_EXPAND: /* expanded */
GET_ACF_FLAG_PTR(mb->flag);
+ case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (mb->adt)
@@ -1526,6 +1566,80 @@ static bAnimChannelType ACF_DSMBALL=
acf_dsmball_setting_ptr /* pointer for setting */
};
+/* Armature Expander ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dsarm_icon(bAnimListElem *ale)
+{
+ return ICON_ARMATURE_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid */
+static int acf_dsarm_setting_flag(int setting, short *neg)
+{
+ /* clear extra return data first */
+ *neg= 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return ARM_DS_EXPAND;
+
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
+
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg= 1;
+ return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
+
+ default: /* unsupported */
+ return 0;
+ }
+}
+
+/* get pointer to the setting */
+static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+ bArmature *arm= (bArmature *)ale->data;
+
+ /* clear extra return data first */
+ *type= 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ GET_ACF_FLAG_PTR(arm->flag);
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (arm->adt)
+ GET_ACF_FLAG_PTR(arm->adt->flag)
+ else
+ return NULL;
+
+ default: /* unsupported */
+ return NULL;
+ }
+}
+
+/* metaball expander type define */
+static bAnimChannelType ACF_DSARM=
+{
+ acf_generic_dataexpand_backdrop,/* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_dsarm_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsarm_setting_flag, /* flag for setting */
+ acf_dsarm_setting_ptr /* pointer for setting */
+};
+
+
/* ShapeKey Entry ------------------------------------------- */
// XXX ... this is currently obsolete...
@@ -1709,6 +1823,7 @@ void ANIM_init_channel_typeinfo_data (void)
animchannelTypeInfo[type++]= &ACF_DSWOR; /* World Channel */
animchannelTypeInfo[type++]= &ACF_DSPART; /* Particle Channel */
animchannelTypeInfo[type++]= &ACF_DSMBALL; /* MetaBall Channel */
+ animchannelTypeInfo[type++]= &ACF_DSARM; /* Armature Channel */
animchannelTypeInfo[type++]= NULL; /* ShapeKey */ // XXX this is no longer used for now...
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 72d8f71bc26..83f5fca5af5 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -91,6 +91,7 @@
/* -------------------------- Exposed API ----------------------------------- */
/* Set the given animation-channel as the active one for the active context */
+// TODO: extend for animdata types...
void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type)
{
ListBase anim_data = {NULL, NULL};
@@ -130,11 +131,29 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
}
break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ /* need to verify that this data is valid for now */
+ if (ale->adt) {
+ ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE);
+ }
+ }
+ break;
}
}
/* set active flag */
- if (channel_data != NULL) {
+ if (channel_data) {
switch (channel_type) {
case ANIMTYPE_GROUP:
{
@@ -154,6 +173,23 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
nlt->flag |= NLATRACK_ACTIVE;
}
break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ /* need to verify that this data is valid for now */
+ if (ale->adt)
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+ break;
}
}
@@ -174,7 +210,7 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
int filter;
/* filter data */
- filter= ANIMFILTER_VISIBLE;
+ filter= ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS;
ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
/* See if we should be selecting or deselecting */
@@ -189,12 +225,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
sel= ACHANNEL_SETFLAG_CLEAR;
break;
case ANIMTYPE_OBJECT:
+ #if 0 /* for now, do not take object selection into account, since it gets too annoying */
if (ale->flag & SELECT)
sel= ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_FILLACTD:
- if (ale->flag & ACT_SELECTED)
- sel= ACHANNEL_SETFLAG_CLEAR;
+ #endif
break;
case ANIMTYPE_GROUP:
if (ale->flag & AGRP_SELECTED)
@@ -208,6 +242,22 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
if (ale->flag & NLATRACK_SELECTED)
sel= ACHANNEL_SETFLAG_CLEAR;
break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ sel= ACHANNEL_SETFLAG_CLEAR;
+ }
+ break;
}
}
}
@@ -220,23 +270,26 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
Scene *scene= (Scene *)ale->data;
ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
+
+ if (scene->adt) {
+ ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED);
+ }
}
break;
case ANIMTYPE_OBJECT:
+ #if 0 /* for now, do not take object selection into account, since it gets too annoying */
{
Base *base= (Base *)ale->data;
Object *ob= base->object;
ACHANNEL_SET_FLAG(base, sel, SELECT);
ACHANNEL_SET_FLAG(ob, sel, SELECT);
- }
- break;
- case ANIMTYPE_FILLACTD:
- {
- bAction *act= (bAction *)ale->data;
- ACHANNEL_SET_FLAG(act, sel, ACT_SELECTED);
+ if (ob->adt) {
+ ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED);
+ }
}
+ #endif
break;
case ANIMTYPE_GROUP:
{
@@ -262,6 +315,25 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
nlt->flag &= ~NLATRACK_ACTIVE;
}
break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ /* need to verify that this data is valid for now */
+ if (ale->adt) {
+ ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED);
+ ale->adt->flag &= ~ADT_UI_ACTIVE;
+ }
+ }
+ break;
}
}
@@ -1310,18 +1382,22 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
}
/* action to take depends on what channel we've got */
+ // WARNING: must keep this in sync with the equivalent function in nla_channels.c
switch (ale->type) {
case ANIMTYPE_SCENE:
{
Scene *sce= (Scene *)ale->data;
+ AnimData *adt= sce->adt;
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
sce->flag ^= SCE_DS_SELECTED;
+ if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
sce->flag |= SCE_DS_SELECTED;
+ if (adt) adt->flag |= ADT_UI_SELECTED;
}
notifierFlags |= ND_ANIMCHAN_SELECT;
@@ -1333,34 +1409,75 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
Scene *sce= (Scene *)ads->source;
Base *base= (Base *)ale->data;
Object *ob= base->object;
+ AnimData *adt= ob->adt;
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
base->flag ^= SELECT;
ob->flag= base->flag;
+
+ if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
Base *b;
- /* deleselect all */
+ /* deselect all */
+ // TODO: should this deselect all other types of channels too?
for (b= sce->base.first; b; b= b->next) {
b->flag &= ~SELECT;
b->object->flag= b->flag;
+ if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE);
}
/* select object now */
base->flag |= SELECT;
ob->flag |= SELECT;
+ if (adt) adt->flag |= ADT_UI_SELECTED;
}
/* xxx should be ED_base_object_activate(), but we need context pointer for that... */
//set_active_base(base);
+ if ((adt) && (adt->flag & ADT_UI_SELECTED))
+ adt->flag |= ADT_UI_ACTIVE;
notifierFlags |= ND_ANIMCHAN_SELECT;
}
break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ /* sanity checking... */
+ if (ale->adt) {
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this AnimData block only */
+ ale->adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ /* select AnimData block by itself */
+ ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ ale->adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* set active? */
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+ notifierFlags |= ND_ANIMCHAN_SELECT;
+ }
+ break;
+
case ANIMTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)ale->data;
@@ -1572,7 +1689,7 @@ void ED_operatortypes_animchannels(void)
void ED_keymap_animchannels(wmWindowManager *wm)
{
- ListBase *keymap = WM_keymap_listbase(wm, "Animation_Channels", 0, 0);
+ wmKeyMap *keymap = WM_keymap_find(wm, "Animation_Channels", 0, 0);
/* selection */
/* click-select */
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index af2355b91a5..62341a5d6ae 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -43,6 +43,7 @@
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -57,26 +58,17 @@
/* ***************** depsgraph calls and anim updates ************* */
/* ***************** only these can be called from editors ******** */
-/* generic update flush, reads from context Screen (layers) and scene */
-/* this is for compliancy, later it can do all windows etc */
void ED_anim_dag_flush_update(const bContext *C)
{
- Scene *scene= CTX_data_scene(C);
- bScreen *screen= CTX_wm_screen(C);
-
- DAG_scene_flush_update(scene, ED_screen_view3d_layers(screen), 0);
+ DAG_ids_flush_update(0);
}
/* flushes changes from object to all relations in scene */
void ED_anim_object_flush_update(const bContext *C, Object *ob)
{
- Scene *scene= CTX_data_scene(C);
- bScreen *screen= CTX_wm_screen(C);
-
- DAG_object_update_flags(scene, ob, ED_screen_view3d_layers(screen));
+ DAG_id_update_flags(&ob->id);
}
-
/* **************************** pose <-> action syncing ******************************** */
/* Summary of what needs to be synced between poses and actions:
* 1) Flags
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 6388106fdb5..507bf03e7ef 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -55,6 +55,7 @@
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
+#include "ED_types.h"
#include "ED_util.h"
#include "WM_api.h"
@@ -316,3 +317,52 @@ void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, s
}
/* *************************************************** */
+/* ANIMATION EDITOR UI-WIDGETS */
+
+/* ui button event */
+#define B_REDR 1
+
+/* standard header buttons for Animation Editors */
+short ANIM_headerUI_standard_buttons (const bContext *C, bDopeSheet *ads, uiBlock *block, short xco, short yco)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ short nlaActive= ((sa) && (sa->spacetype==SPACE_NLA));
+
+ /* check if the DopeSheet data exists, just in case... */
+ if (ads) {
+ /* more 'generic' filtering options */
+ if (nlaActive) uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Only display selected Objects");
+ if (nlaActive) uiDefIconButBitI(block, TOGN, ADS_FILTER_NLA_NOACT, B_REDR, ICON_ACTION, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Include AnimData blocks with no NLA Data");
+ if (nlaActive) uiBlockEndAlign(block);
+ xco += 5;
+
+ /* datatype based */
+ // TODO: only show the datablocks which exist
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Scene Animation");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display World Animation");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Material Data");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Lamp Data");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Camera Data");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Curve Data");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display MetaBall Data");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Armature Data");
+ uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Particle Data");
+ uiBlockEndAlign(block);
+ xco += 30;
+ }
+ else {
+ // XXX this case shouldn't happen at all... for now, just pad out same amount of space
+ printf("ERROR: dopesheet data not available when drawing Animation Editor header \n");
+ xco += 11*XIC + 30;
+ }
+
+ // TODO: include auto-snapping menu here too...
+
+ /* return the width of the buttons */
+ return xco;
+}
+
+/* *************************************************** */
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 55fb1ccace0..13b050e4497 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -52,6 +52,7 @@
#include "DNA_ID.h"
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
@@ -412,7 +413,9 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
}\
}
-
+/* quick macro to test if an anim-channel representing an AnimData block is suitably active */
+#define ANIMCHANNEL_ACTIVEOK(ale) \
+ ( !(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
/* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
#define ANIMCHANNEL_SELOK(test_func) \
@@ -979,10 +982,13 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
/* include material-expand widget? */
// hmm... do we need to store the index of this material in the array anywhere?
if (filter_mode & ANIMFILTER_CHANNELS) {
- ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(ma) {
+ ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma);
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ items++;
+ }
}
}
@@ -1036,11 +1042,14 @@ static int animdata_filter_dopesheet_particles (ListBase *anim_data, bDopeSheet
/* add particle settings? */
if (FILTER_PART_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- if ((filter_mode & ANIMFILTER_CHANNELS)){
- ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ if ((filter_mode & ANIMFILTER_CHANNELS)) {
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(psys->part) {
+ ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part);
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ items++;
+ }
}
}
@@ -1101,6 +1110,14 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
expanded= FILTER_MBALL_OBJD(mb);
}
break;
+ case OB_ARMATURE: /* ------- Armature ---------- */
+ {
+ bArmature *arm= (bArmature *)ob->data;
+
+ type= ANIMTYPE_DSARM;
+ expanded= FILTER_ARM_OBJD(arm);
+ }
+ break;
}
/* special exception for drivers instead of action */
@@ -1108,9 +1125,12 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
expanded= EXPANDED_DRVD(adt);
/* include data-expand widget? */
- if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
- ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat);
- if (ale) BLI_addtail(anim_data, ale);
+ if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(iat) {
+ ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
}
/* add object-data animation channels? */
@@ -1140,10 +1160,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
/* check if filtering by selection */
if ANIMCHANNEL_SELOK((base->flag & SELECT)) {
- ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, NULL);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(ob) {
+ ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, (ID *)ob);
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ items++;
+ }
}
}
}
@@ -1203,8 +1226,21 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
ANIMDATA_FILTER_CASES(key,
{ /* AnimData blocks - do nothing... */ },
{ /* nla */
- /* add NLA tracks */
- items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
+ /* include shapekey-expand widget? */
+ if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(key) {
+ ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ items++;
+ }
+ }
+ }
+
+ /* add NLA tracks - only if expanded or so */
+ if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))
+ items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
},
{ /* drivers */
/* include shapekey-expand widget? */
@@ -1224,10 +1260,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
{ /* action (keyframes) */
/* include shapekey-expand widget? */
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(key) {
+ ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ items++;
+ }
}
}
@@ -1297,6 +1336,19 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
}
}
break;
+ case OB_ARMATURE: /* ------- Armature ---------- */
+ {
+ bArmature *arm= (bArmature *)ob->data;
+
+ if ((ads->filterflag & ADS_FILTER_NOARM) == 0) {
+ ANIMDATA_FILTER_CASES(arm,
+ { /* AnimData blocks - do nothing... */ },
+ obdata_ok= 1;,
+ obdata_ok= 1;,
+ obdata_ok= 1;)
+ }
+ }
+ break;
}
if (obdata_ok)
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
@@ -1652,6 +1704,23 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);)
}
break;
+ case OB_ARMATURE: /* ------- Armature ---------- */
+ {
+ bArmature *arm= (bArmature *)ob->data;
+ dataOk= 0;
+ ANIMDATA_FILTER_CASES(arm,
+ if ((ads->filterflag & ADS_FILTER_NOARM)==0) {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(arm);
+ dataOk=0;
+ },
+ dataOk= !(ads->filterflag & ADS_FILTER_NOARM);,
+ dataOk= !(ads->filterflag & ADS_FILTER_NOARM);,
+ dataOk= !(ads->filterflag & ADS_FILTER_NOARM);)
+ }
+ break;
default: /* --- other --- */
dataOk= 0;
break;
@@ -1734,6 +1803,12 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
dataOk= ANIMDATA_HAS_KEYS(mb);
}
break;
+ case OB_ARMATURE: /* -------- Armature ---------- */
+ {
+ bArmature *arm= (bArmature *)ob->data;
+ dataOk= ANIMDATA_HAS_KEYS(arm);
+ }
+ break;
default: /* --- other --- */
dataOk= 0;
break;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index d33eece52c9..6c44086af41 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -458,7 +458,7 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
mm->event_type= evt->type;
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
/* reset frs delta */
RNA_int_set(op->ptr, "frames", 0);
@@ -992,7 +992,7 @@ void ED_operatortypes_marker(void)
/* called in screen_ops.c:ED_keymap_screen() */
void ED_marker_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Markers", 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
@@ -1002,6 +1002,7 @@ void ED_marker_keymap(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "MARKER_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index fedbe12c0e6..a4038028062 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -162,7 +162,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
change_frame_apply(C, op);
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -193,7 +193,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
/* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init
* the modal op) doesn't work for some reason
*/
- if (event->val==0) {
+ if (event->val==KM_RELEASE) {
change_frame_exit(C, op);
return OPERATOR_FINISHED;
}
@@ -399,6 +399,8 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_add_driver_button);
WM_operatortype_append(ANIM_OT_remove_driver_button);
+ WM_operatortype_append(ANIM_OT_copy_driver_button);
+ WM_operatortype_append(ANIM_OT_paste_driver_button);
WM_operatortype_append(ANIM_OT_add_keyingset_button);
WM_operatortype_append(ANIM_OT_remove_keyingset_button);
@@ -406,7 +408,7 @@ void ED_operatortypes_anim(void)
void ED_keymap_anim(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Animation", 0, 0);
/* frame management */
/* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 8b9224511ba..363a5a80f00 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -80,6 +80,10 @@
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
* for the given Animation Data block. This assumes that all the destinations are valid.
+ *
+ * - add: 0 - don't add anything if not found,
+ * 1 - add new Driver FCurve,
+ * -1 - add new Driver FCurve without driver stuff (for pasting)
*/
FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_index, short add)
{
@@ -115,11 +119,14 @@ FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_ind
fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path));
fcu->array_index= array_index;
- /* add some new driver data */
- fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
-
- /* add simple generator modifier for driver so that there is some visible representation */
- add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
+ /* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
+ if (add > 0) {
+ /* add some new driver data */
+ fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
+
+ /* add simple generator modifier for driver so that there is some visible representation */
+ add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
+ }
/* just add F-Curve to end of driver list */
BLI_addtail(&adt->drivers, fcu);
@@ -144,7 +151,7 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
- printf("Insert Key: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
+ printf("Add Driver: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
return 0;
}
@@ -163,7 +170,7 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla
float fval;
if (proptype == PROP_BOOLEAN) {
- if(!array) val= RNA_property_boolean_get(&ptr, prop);
+ if (!array) val= RNA_property_boolean_get(&ptr, prop);
else val= RNA_property_boolean_get_index(&ptr, prop, array_index);
BLI_strncpy(expression, (val)? "True": "False", maxlen);
@@ -180,7 +187,6 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla
BLI_snprintf(expression, maxlen, "%.3f", fval);
}
-
}
}
@@ -218,6 +224,127 @@ short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index,
return 0;
}
+/* ************************************************** */
+/* Driver Management API - Copy/Paste Drivers */
+
+/* Copy/Paste Buffer for Driver Data... */
+static FCurve *channeldriver_copypaste_buf = NULL;
+
+/* This function frees any MEM_calloc'ed copy/paste buffer data */
+// XXX find some header to put this in!
+void free_anim_drivers_copybuf (void)
+{
+ /* free the buffer F-Curve if it exists, as if it were just another F-Curve */
+ if (channeldriver_copypaste_buf)
+ free_fcurve(channeldriver_copypaste_buf);
+ channeldriver_copypaste_buf= NULL;
+}
+
+/* Checks if there is a driver in the copy/paste buffer */
+short ANIM_driver_can_paste (void)
+{
+ return (channeldriver_copypaste_buf != NULL);
+}
+
+/* ------------------- */
+
+/* Main Driver Management API calls:
+ * Make a copy of the driver for the specified property on the given ID block
+ */
+short ANIM_copy_driver (ID *id, const char rna_path[], int array_index, short flag)
+{
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ FCurve *fcu;
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
+ printf("Copy Driver: Could not find Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
+ return 0;
+ }
+
+ /* try to get F-Curve with Driver */
+ fcu= verify_driver_fcurve(id, rna_path, array_index, 0);
+
+ /* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
+ free_anim_drivers_copybuf();
+
+ /* copy this to the copy/paste buf if it exists */
+ if (fcu && fcu->driver) {
+ /* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily
+ * so that we don't end up wasting memory storing the path which won't get used ever...
+ */
+ char *tmp_path = fcu->rna_path;
+ fcu->rna_path= NULL;
+
+ /* make a copy of the F-Curve with */
+ channeldriver_copypaste_buf= copy_fcurve(fcu);
+
+ /* restore the path */
+ fcu->rna_path= tmp_path;
+
+ /* copied... */
+ return 1;
+ }
+
+ /* done */
+ return 0;
+}
+
+/* Main Driver Management API calls:
+ * Add a new driver for the specified property on the given ID block or replace an existing one
+ * with the driver + driver-curve data from the buffer
+ */
+short ANIM_paste_driver (ID *id, const char rna_path[], int array_index, short flag)
+{
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ FCurve *fcu;
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
+ printf("Paste Driver: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
+ return 0;
+ }
+
+ /* if the buffer is empty, cannot paste... */
+ if (channeldriver_copypaste_buf == NULL) {
+ printf("Paste Driver: No Driver to paste. \n");
+ return 0;
+ }
+
+ /* create Driver F-Curve, but without data which will be copied across... */
+ fcu= verify_driver_fcurve(id, rna_path, array_index, -1);
+
+ if (fcu) {
+ /* copy across the curve data from the buffer curve
+ * NOTE: this step needs care to not miss new settings
+ */
+ /* keyframes/samples */
+ fcu->bezt= MEM_dupallocN(channeldriver_copypaste_buf->bezt);
+ fcu->fpt= MEM_dupallocN(channeldriver_copypaste_buf->fpt);
+ fcu->totvert= channeldriver_copypaste_buf->totvert;
+
+ /* modifiers */
+ copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers);
+
+ /* flags - on a per-relevant-flag basis */
+ if (channeldriver_copypaste_buf->flag & FCURVE_AUTO_HANDLES)
+ fcu->flag |= FCURVE_AUTO_HANDLES;
+ else
+ fcu->flag &= ~FCURVE_AUTO_HANDLES;
+ /* extrapolation mode */
+ fcu->extend= channeldriver_copypaste_buf->extend;
+
+ /* the 'juicy' stuff - the driver */
+ fcu->driver= fcurve_copy_driver(channeldriver_copypaste_buf->driver);
+ }
+
+ /* done */
+ return (fcu != NULL);
+}
/* ************************************************** */
/* UI-Button Interface */
@@ -272,10 +399,11 @@ void ANIM_OT_add_driver_button (wmOperatorType *ot)
/* identifiers */
ot->name= "Add Driver";
ot->idname= "ANIM_OT_add_driver_button";
+ ot->description= "Add driver(s) for the property(s) connected represented by the highlighted button.";
/* callbacks */
ot->exec= add_driver_button_exec;
- //op->poll= ???
+ //op->poll= ??? // TODO: need to have some animateable property to do this
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -335,10 +463,11 @@ void ANIM_OT_remove_driver_button (wmOperatorType *ot)
/* identifiers */
ot->name= "Remove Driver";
ot->idname= "ANIM_OT_remove_driver_button";
+ ot->description= "Remove the driver(s) for the property(s) connected represented by the highlighted button.";
/* callbacks */
ot->exec= remove_driver_button_exec;
- //op->poll= ???
+ //op->poll= ??? // TODO: need to have some driver to be able to do this...
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -347,4 +476,92 @@ void ANIM_OT_remove_driver_button (wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array.");
}
+/* Copy Driver Button Operator ------------------------ */
+
+static int copy_driver_button_exec (bContext *C, wmOperator *op)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop= NULL;
+ char *path;
+ short success= 0;
+ int index;
+
+ /* try to create driver using property retrieved from UI */
+ memset(&ptr, 0, sizeof(PointerRNA));
+ uiAnimContextProperty(C, &ptr, &prop, &index);
+
+ if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) {
+ path= RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ /* only copy the driver for the button that this was involved for */
+ success= ANIM_copy_driver(ptr.id.data, path, index, 0);
+
+ MEM_freeN(path);
+ }
+ }
+
+ /* since we're just copying, we don't really need to do anything else...*/
+ return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
+}
+
+void ANIM_OT_copy_driver_button (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Copy Driver";
+ ot->idname= "ANIM_OT_copy_driver_button";
+ ot->description= "Copy the driver for the highlighted button.";
+
+ /* callbacks */
+ ot->exec= copy_driver_button_exec;
+ //op->poll= ??? // TODO: need to have some driver to be able to do this...
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* Paste Driver Button Operator ------------------------ */
+
+static int paste_driver_button_exec (bContext *C, wmOperator *op)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop= NULL;
+ char *path;
+ short success= 0;
+ int index;
+
+ /* try to create driver using property retrieved from UI */
+ memset(&ptr, 0, sizeof(PointerRNA));
+ uiAnimContextProperty(C, &ptr, &prop, &index);
+
+ if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) {
+ path= RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ /* only copy the driver for the button that this was involved for */
+ success= ANIM_paste_driver(ptr.id.data, path, index, 0);
+
+ MEM_freeN(path);
+ }
+ }
+
+ /* since we're just copying, we don't really need to do anything else...*/
+ return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
+}
+
+void ANIM_OT_paste_driver_button (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Paste Driver";
+ ot->idname= "ANIM_OT_paste_driver_button";
+ ot->description= "Paste the driver in the copy/paste buffer for the highlighted button.";
+
+ /* callbacks */
+ ot->exec= paste_driver_button_exec;
+ //op->poll= ??? // TODO: need to have some driver to be able to do this...
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
/* ************************************************** */
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index abea38e129e..e8b25f70b06 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -316,7 +316,7 @@ static void set_touched_actkeyblock (ActKeyBlock *ab)
/* *************************** Keyframe Drawing *************************** */
/* helper function - find actkeycolumn that occurs on cframe */
-static ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe)
+ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe)
{
/* sanity checks */
if (ak == NULL)
@@ -331,6 +331,29 @@ static ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe)
return ak; /* match */
}
+/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */
+// FIXME: this is buggy... next() is ignored completely...
+ActKeyColumn *cfra_find_nearest_next_ak (ActKeyColumn *ak, float cframe, short next)
+{
+ ActKeyColumn *akn= NULL;
+
+ /* sanity checks */
+ if (ak == NULL)
+ return NULL;
+
+ /* check if this is a match, or whether it is in some subtree */
+ if (cframe < ak->cfra)
+ akn= cfra_find_nearest_next_ak(ak->left, cframe, next);
+ else if (cframe > ak->cfra)
+ akn= cfra_find_nearest_next_ak(ak->right, cframe, next);
+
+ /* if no match found (or found match), just use the current one */
+ if (akn == NULL)
+ return ak;
+ else
+ return akn;
+}
+
/* -------- */
/* coordinates for diamond shape */
@@ -396,6 +419,13 @@ void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel
}
break;
+ case BEZT_KEYTYPE_EXTREME: /* redish frames for now */
+ {
+ if (sel) glColor3f(95.0f, 0.5f, 0.5f);
+ else glColor3f(0.91f, 0.70f, 0.80f);
+ }
+ break;
+
case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */
default:
{
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index ac04dc7d1a8..65f7d845b29 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -461,6 +461,13 @@ static short snap_bezier_horizontal(BeztEditData *bed, BezTriple *bezt)
return 0;
}
+static short snap_bezier_value(BeztEditData *bed, BezTriple *bezt)
+{
+ /* value to snap to is stored in the custom data -> first float value slot */
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][1]= bed->f1;
+ return 0;
+}
BeztEditFunc ANIM_editkeyframes_snap(short type)
{
@@ -476,6 +483,8 @@ BeztEditFunc ANIM_editkeyframes_snap(short type)
return snap_bezier_nearestsec;
case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */
return snap_bezier_horizontal;
+ case SNAP_KEYS_VALUE: /* snap to given value */
+ return snap_bezier_value;
default: /* just in case */
return snap_bezier_nearest;
}
@@ -685,6 +694,13 @@ static short set_keytype_breakdown(BeztEditData *bed, BezTriple *bezt)
return 0;
}
+static short set_keytype_extreme(BeztEditData *bed, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ BEZKEYTYPE(bezt)= BEZT_KEYTYPE_EXTREME;
+ return 0;
+}
+
/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
BeztEditFunc ANIM_editkeyframes_keytype(short code)
{
@@ -692,6 +708,9 @@ BeztEditFunc ANIM_editkeyframes_keytype(short code)
case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */
return set_keytype_breakdown;
+ case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */
+ return set_keytype_extreme;
+
case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */
default:
return set_keytype_keyframe;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 7135f8802bc..10d45d53761 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -176,85 +176,6 @@ FCurve *verify_fcurve (bAction *act, const char group[], const char rna_path[],
/* -------------- BezTriple Insertion -------------------- */
-/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
-#define BEZT_INSERT_THRESH 0.00001f
-
-/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
- * Returns the index to insert at (data already at that index will be offset if replace is 0)
- */
-static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace)
-{
- int start=0, end=arraylen;
- int loopbreaker= 0, maxloop= arraylen * 2;
-
- /* initialise replace-flag first */
- *replace= 0;
-
- /* sneaky optimisations (don't go through searching process if...):
- * - keyframe to be added is to be added out of current bounds
- * - keyframe to be added would replace one of the existing ones on bounds
- */
- if ((arraylen <= 0) || (array == NULL)) {
- printf("Warning: binarysearch_bezt_index() encountered invalid array \n");
- return 0;
- }
- else {
- /* check whether to add before/after/on */
- float framenum;
-
- /* 'First' Keyframe (when only one keyframe, this case is used) */
- framenum= array[0].vec[1][0];
- if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
- *replace = 1;
- return 0;
- }
- else if (frame < framenum)
- return 0;
-
- /* 'Last' Keyframe */
- framenum= array[(arraylen-1)].vec[1][0];
- if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
- *replace= 1;
- return (arraylen - 1);
- }
- else if (frame > framenum)
- return arraylen;
- }
-
-
- /* most of the time, this loop is just to find where to put it
- * 'loopbreaker' is just here to prevent infinite loops
- */
- for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
- /* compute and get midpoint */
- int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
- float midfra= array[mid].vec[1][0];
-
- /* check if exactly equal to midpoint */
- if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH)) {
- *replace = 1;
- return mid;
- }
-
- /* repeat in upper/lower half */
- if (frame > midfra)
- start= mid + 1;
- else if (frame < midfra)
- end= mid - 1;
- }
-
- /* print error if loop-limit exceeded */
- if (loopbreaker == (maxloop-1)) {
- printf("Error: binarysearch_bezt_index() was taking too long \n");
-
- // include debug info
- printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
- }
-
- /* not found, so return where to place it */
- return start;
-}
-
/* This function adds a given BezTriple to an F-Curve. It will allocate
* memory for the array if needed, and will insert the BezTriple into a
* suitable place in chronological order.
@@ -286,8 +207,13 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag)
// TODO: perform some other operations?
}
else {
+ char oldKeyType= BEZKEYTYPE(fcu->bezt + i);
+
/* just brutally replace the values */
*(fcu->bezt + i) = *bezt;
+
+ /* special exception for keyframe type - copy value back so that this info isn't lost */
+ BEZKEYTYPE(fcu->bezt + i)= oldKeyType;
}
}
}
@@ -717,14 +643,14 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_
else if (pchan->bone->parent == NULL)
return tmat[3][array_index];
}
- else if (strstr(identifier, "euler_rotation")) {
+ else if (strstr(identifier, "rotation_euler")) {
float eul[3];
/* euler-rotation test before standard rotation, as standard rotation does quats */
Mat4ToEulO(tmat, eul, pchan->rotmode);
return eul[array_index];
}
- else if (strstr(identifier, "rotation")) {
+ else if (strstr(identifier, "rotation_quaternion")) {
float trimat[3][3], quat[4];
Mat3CpyMat4(trimat, tmat);
@@ -732,6 +658,7 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_
return quat[array_index];
}
+ // TODO: axis-angle...
}
/* as the function hasn't returned yet, read value from system in the default way */
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 60efcce4e73..81259ae7ced 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -770,7 +770,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
/* Keying Set - "Rotation" ---------- */
BI_KS_DEFINE_BEGIN("Rotation", 0)
BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
BI_KS_PATHS_END
BI_KS_DEFINE_END,
@@ -786,7 +786,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
BI_KS_DEFINE_BEGIN("LocRot", 0)
BI_KS_PATHS_BEGIN(2)
BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
BI_KS_PATHS_END
BI_KS_DEFINE_END,
@@ -794,7 +794,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
BI_KS_DEFINE_BEGIN("LocRotScale", 0)
BI_KS_PATHS_BEGIN(3)
BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scale", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
BI_KS_PATHS_END
BI_KS_DEFINE_END,
@@ -810,7 +810,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
/* Keying Set - "Rotation" ---------- */
BI_KS_DEFINE_BEGIN("VisualRot", INSERTKEY_MATRIX)
BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
BI_KS_PATHS_END
BI_KS_DEFINE_END,
@@ -818,7 +818,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
BI_KS_DEFINE_BEGIN("VisualLocRot", INSERTKEY_MATRIX)
BI_KS_PATHS_BEGIN(2)
BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
BI_KS_PATHS_END
BI_KS_DEFINE_END
};
@@ -1145,7 +1145,12 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
int arraylen, i;
/* set initial group name */
- groupname= (cks->id) ? cks->id->name+2 : NULL;
+ if (cks->id == NULL) {
+ printf("ERROR: Skipping 'Common-Key' Source. No valid ID present.\n");
+ continue;
+ }
+ else
+ groupname= cks->id->name+2;
/* construct the path */
// FIXME: this currently only works with a few hardcoded cases
@@ -1173,14 +1178,24 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
BLI_dynstr_append(pathds, ".");
/* apply some further templates? */
- if ((ksp->templates & KSP_TEMPLATE_PCHAN_ROT) && (cks->pchan)) {
- /* if this path is exactly "rotation", and the rotation mode is set to eulers,
- * use "euler_rotation" instead so that rotations will be keyed correctly
+ if (ksp->templates & KSP_TEMPLATE_ROT) {
+ /* for builtin Keying Sets, this template makes the best fitting path for the
+ * current rotation mode of the Object / PoseChannel to be used
*/
- if (strcmp(ksp->rna_path, "rotation")==0 && (cks->pchan->rotmode > 0))
- BLI_dynstr_append(pathds, "euler_rotation");
- else
- BLI_dynstr_append(pathds, ksp->rna_path);
+ if (strcmp(ksp->rna_path, "rotation")==0) {
+ /* get rotation mode */
+ short rotmode= (cks->pchan)? (cks->pchan->rotmode) :
+ (GS(cks->id->name)==ID_OB)? ( ((Object *)cks->id)->rotmode ) :
+ (0);
+
+ /* determine path to build */
+ if (rotmode == ROT_MODE_QUAT)
+ BLI_dynstr_append(pathds, "rotation_quaternion");
+ else if (rotmode == ROT_MODE_AXISANGLE)
+ BLI_dynstr_append(pathds, "rotation_axis_angle");
+ else
+ BLI_dynstr_append(pathds, "rotation_euler");
+ }
}
else {
/* just directly use the path */
diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript
index f96d25b0fe0..a7fa9d7071f 100644
--- a/source/blender/editors/armature/SConscript
+++ b/source/blender/editors/armature/SConscript
@@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include #/intern/guardedalloc'
incs += ' ../../gpu ../../makesrna #/intern/opennl/extern'
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_armature', sources, Split(incs), [], libtype=['core'], priority=[44] )
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 0c8c0e8e644..6f5a5f44d87 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -118,12 +118,20 @@ void SKETCH_OT_select(struct wmOperatorType *ot);
/* ******************************************************* */
/* PoseLib */
+
void POSELIB_OT_pose_add(struct wmOperatorType *ot);
void POSELIB_OT_pose_remove(struct wmOperatorType *ot);
void POSELIB_OT_pose_rename(struct wmOperatorType *ot);
void POSELIB_OT_browse_interactive(struct wmOperatorType *ot);
/* ******************************************************* */
+/* Pose Sliding Tools */
+
+void POSE_OT_push(struct wmOperatorType *ot);
+void POSE_OT_relax(struct wmOperatorType *ot);
+void POSE_OT_breakdown(struct wmOperatorType *ot);
+
+/* ******************************************************* */
/* editarmature.c */
struct bArmature;
struct EditBone;
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index 389a0a5174a..d465c1f8c9a 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -196,17 +196,23 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSELIB_OT_pose_remove);
WM_operatortype_append(POSELIB_OT_pose_rename);
+ /* POSE SLIDING */
+ WM_operatortype_append(POSE_OT_push);
+ WM_operatortype_append(POSE_OT_relax);
+ WM_operatortype_append(POSE_OT_breakdown);
+
/* TESTS */
WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed
}
void ED_keymap_armature(wmWindowManager *wm)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
wmKeymapItem *kmi;
/* Armature ------------------------ */
- keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
+ keymap= WM_keymap_find(wm, "Armature", 0, 0);
+ keymap->poll= ED_operator_editarmature;
/* only set in editmode armature, by space_view3d listener */
// WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
@@ -242,6 +248,7 @@ void ED_keymap_armature(wmWindowManager *wm)
WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_extrude", EKEY, KM_PRESS, 0, 0);
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_extrude", EKEY, KM_PRESS, KM_SHIFT, 0);
@@ -274,13 +281,27 @@ void ED_keymap_armature(wmWindowManager *wm)
/* Armature -> Etch-A-Ton ------------------------ */
WM_keymap_add_item(keymap, "SKETCH_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SKETCH_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SKETCH_OT_finish_stroke", SELECTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SKETCH_OT_cancel_stroke", ESCKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SKETCH_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
+ /* sketch poll checks mode */
+ WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "snap", 1);
+ WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "snap", 1);
+
/* Pose ------------------------ */
/* only set in posemode, by space_view3d listener */
- keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
+ keymap= WM_keymap_find(wm, "Pose", 0, 0);
+ keymap->poll= ED_operator_posemode;
+
+ // XXX: set parent is object-based operator, but it should also be available here...
+ WM_keymap_add_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
@@ -294,7 +315,6 @@ void ED_keymap_armature(wmWindowManager *wm)
WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
- // for now, we include hotkeys for copy/paste
WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
@@ -354,5 +374,11 @@ void ED_keymap_armature(wmWindowManager *wm)
WM_keymap_add_item(keymap, "POSELIB_OT_pose_add", LKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSELIB_OT_pose_remove", LKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSELIB_OT_pose_rename", LKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+
+ /* Pose -> Pose Sliding ------------- */
+ /* only set in posemode, by space_view3d listener */
+ WM_keymap_add_item(keymap, "POSE_OT_push", EKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_relax", EKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_breakdown", EKEY, KM_PRESS, KM_SHIFT, 0);
}
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 7d196d23c98..402715dbb02 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -1736,7 +1736,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op)
ED_armature_sync_selection(arm->edbo);
- WM_event_add_notifier(C, NC_OBJECT, obedit);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, obedit);
return OPERATOR_FINISHED;
}
@@ -2539,6 +2539,8 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *edit
VECCOPY(channew->limitmax, chanold->limitmax);
VECCOPY(channew->stiffness, chanold->stiffness);
channew->ikstretch= chanold->ikstretch;
+ channew->ikrotweight= chanold->ikrotweight;
+ channew->iklinweight= chanold->iklinweight;
/* constraints */
listnew = &channew->constraints;
@@ -2630,6 +2632,9 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
/* copy transform locks */
channew->protectflag = chanold->protectflag;
+ /* copy rotation mode */
+ channew->rotmode = chanold->rotmode;
+
/* copy bone group */
channew->agrp_index= chanold->agrp_index;
@@ -2639,6 +2644,8 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
VECCOPY(channew->limitmax, chanold->limitmax);
VECCOPY(channew->stiffness, chanold->stiffness);
channew->ikstretch= chanold->ikstretch;
+ channew->ikrotweight= chanold->ikrotweight;
+ channew->iklinweight= chanold->iklinweight;
/* constraints */
listnew = &channew->constraints;
@@ -3441,7 +3448,8 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
else
VecAddf(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z
- WM_event_add_notifier(C, NC_OBJECT, obedit);
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, obedit);
return OPERATOR_FINISHED;
}
@@ -3930,7 +3938,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op)
ED_armature_sync_selection(arm->edbo);
/* note, notifier might evolve */
- WM_event_add_notifier(C, NC_OBJECT, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
return OPERATOR_FINISHED;
}
@@ -4330,7 +4338,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
}
/* in weightpaint we select the associated vertex group too */
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (OBACT && OBACT->mode & OB_MODE_WEIGHT_PAINT) {
if (nearBone->flag & BONE_ACTIVE) {
ED_vgroup_select_by_name(OBACT, nearBone->name);
DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA);
@@ -4854,7 +4862,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
if (pchan->protectflag & OB_LOCK_ROT4D) {
/* perform clamping on a component by component basis */
if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
- pchan->quat[0]= (pchan->rotmode == PCHAN_ROT_AXISANGLE) ? 0.0f : 1.0f;
+ pchan->quat[0]= (pchan->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f;
if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
pchan->quat[1]= 0.0f;
if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
@@ -4866,11 +4874,11 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
/* perform clamping using euler form (3-components) */
float eul[3], oldeul[3], quat1[4];
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ if (pchan->rotmode == ROT_MODE_QUAT) {
QUATCOPY(quat1, pchan->quat);
QuatToEul(pchan->quat, oldeul);
}
- else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT);
}
else {
@@ -4886,14 +4894,14 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
if (pchan->protectflag & OB_LOCK_ROTZ)
eul[2]= oldeul[2];
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ if (pchan->rotmode == ROT_MODE_QUAT) {
EulToQuat(eul, pchan->quat);
/* quaternions flip w sign to accumulate rotations correctly */
if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
QuatMulf(pchan->quat, -1.0f);
}
}
- else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT);
}
else {
@@ -4902,11 +4910,11 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
}
}
else {
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ if (pchan->rotmode == ROT_MODE_QUAT) {
pchan->quat[1]=pchan->quat[2]=pchan->quat[3]= 0.0f;
pchan->quat[0]= 1.0f;
}
- else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* by default, make rotation of 0 radians around y-axis (roll) */
pchan->quat[0]=pchan->quat[1]=pchan->quat[3]= 0.0f;
pchan->quat[2]= 1.0f;
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 16e78f7c8d1..4d65059c4c6 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -2716,7 +2716,6 @@ static void finishRetarget(RigGraph *rigg)
static void adjustGraphs(bContext *C, RigGraph *rigg)
{
- Scene *scene = CTX_data_scene(C);
bArmature *arm= rigg->ob->data;
RigArc *arc;
@@ -2739,7 +2738,6 @@ static void adjustGraphs(bContext *C, RigGraph *rigg)
static void retargetGraphs(bContext *C, RigGraph *rigg)
{
- Scene *scene = CTX_data_scene(C);
bArmature *arm= rigg->ob->data;
ReebGraph *reebg = rigg->link_mesh;
RigNode *inode;
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 79d3d7b1366..74876691dac 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -1814,7 +1814,7 @@ int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
- angle = VecAngle2(s1, s2);
+ angle = RAD2DEG(VecAngle2(s1, s2));
if (angle > 60 && angle < 120)
{
@@ -1932,7 +1932,7 @@ int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
- angle = VecAngle2(s1, s2);
+ angle = RAD2DEG(VecAngle2(s1, s2));
if (angle > 120)
{
@@ -2064,7 +2064,7 @@ int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p);
}
- angle = VecAngle2(start_v, end_v);
+ angle = RAD2DEG(VecAngle2(start_v, end_v));
if (angle > 120)
{
@@ -2618,7 +2618,7 @@ static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
sk_draw_stroke(C, sketch, sketch->active_stroke, dd, snap);
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -2644,7 +2644,7 @@ static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
sk_start_draw_gesture(sketch);
sk_draw_stroke(C, sketch, sketch->gesture, dd, snap);
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -2675,7 +2675,7 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
retval = OPERATOR_CANCELLED;
break;
case LEFTMOUSE:
- if (event->val == 0)
+ if (event->val == KM_RELEASE)
{
if (gesture == 0)
{
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index a6c94bee5b1..81e67c4d46e 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -176,9 +176,9 @@ static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3
t2= cotan_weight(v2, v3, v1);
t3= cotan_weight(v3, v1, v2);
- if(VecAngle3(v2, v1, v3) > 90) obtuse= 1;
- else if(VecAngle3(v1, v2, v3) > 90) obtuse= 2;
- else if(VecAngle3(v1, v3, v2) > 90) obtuse= 3;
+ if(RAD2DEG(VecAngle3(v2, v1, v3)) > 90) obtuse= 1;
+ else if(RAD2DEG(VecAngle3(v1, v2, v3)) > 90) obtuse= 2;
+ else if(RAD2DEG(VecAngle3(v1, v3, v2)) > 90) obtuse= 3;
if (obtuse > 0) {
area= AreaT3Dfl(v1, v2, v3);
diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c
new file mode 100644
index 00000000000..c73208c54c2
--- /dev/null
+++ b/source/blender/editors/armature/poseSlide.c
@@ -0,0 +1,936 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
+#include "BLI_dlrbTree.h"
+
+#include "DNA_listBase.h"
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
+#include "BKE_object.h"
+
+#include "BKE_global.h"
+#include "BKE_context.h"
+#include "BKE_report.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BIF_gl.h"
+
+#include "ED_anim_api.h"
+#include "ED_armature.h"
+#include "ED_keyframes_draw.h"
+#include "ED_keyframing.h"
+#include "ED_keyframes_edit.h"
+#include "ED_screen.h"
+
+#include "armature_intern.h"
+
+/* **************************************************** */
+/* == POSE 'SLIDING' TOOLS ==
+ *
+ * A) Push & Relax, Breakdowner
+ * These tools provide the animator with various capabilities
+ * for interactively controlling the spacing of poses, but also
+ * for 'pushing' and/or 'relaxing' extremes as they see fit.
+ *
+ * B) Pose Sculpting
+ * This is yet to be implemented, but the idea here is to use
+ * sculpting techniques to make it easier to pose rigs by allowing
+ * rigs to be manipulated using a familiar paint-based interface.
+ */
+/* **************************************************** */
+/* A) Push & Relax, Breakdowner */
+
+/* Temporary data shared between these operators */
+typedef struct tPoseSlideOp {
+ Scene *scene; /* current scene */
+ ARegion *ar; /* region that we're operating in (needed for */
+ Object *ob; /* active object that Pose Info comes from */
+ bArmature *arm; /* armature for pose */
+
+ ListBase pfLinks; /* links between posechannels and f-curves */
+ DLRBT_Tree keys; /* binary tree for quicker searching for keyframes (when applicable) */
+
+ KeyingSet *ks_loc; /* builtin KeyingSet for keyframing locations */
+ KeyingSet *ks_rot; /* builtin KeyingSet for keyframing rotations */
+ KeyingSet *ks_scale;/* builtin KeyingSet for keyframing scale */
+
+ int cframe; /* current frame number */
+ int prevFrame; /* frame before current frame (blend-from) */
+ int nextFrame; /* frame after current frame (blend-to) */
+
+ int mode; /* sliding mode (ePoseSlide_Modes) */
+ int flag; // unused for now, but can later get used for storing runtime settings....
+
+ float percentage; /* 0-1 value for determining the influence of whatever is relevant */
+} tPoseSlideOp;
+
+/* Pose Sliding Modes */
+typedef enum ePoseSlide_Modes {
+ POSESLIDE_PUSH = 0, /* exaggerate the pose... */
+ POSESLIDE_RELAX, /* soften the pose... */
+ POSESLIDE_BREAKDOWN, /* slide between the endpoint poses, finding a 'soft' spot */
+} ePoseSlide_Modes;
+
+/* Temporary data linking PoseChannels with the F-Curves they affect */
+typedef struct tPChanFCurveLink {
+ struct tPChanFCurveLink *next, *prev;
+
+ ListBase fcurves; /* F-Curves for this PoseChannel */
+ bPoseChannel *pchan; /* Pose Channel which data is attached to */
+
+ char *pchan_path; /* RNA Path to this Pose Channel (needs to be freed when we're done) */
+
+ float oldloc[3]; /* transform values at start of operator (to be restored before each modal step) */
+ float oldrot[3];
+ float oldscale[3];
+ float oldquat[4];
+} tPChanFCurveLink;
+
+/* ------------------------------------ */
+
+/* operator init */
+static int pose_slide_init (bContext *C, wmOperator *op, short mode)
+{
+ tPoseSlideOp *pso;
+ bAction *act= NULL;
+
+ /* init slide-op data */
+ pso= op->customdata= MEM_callocN(sizeof(tPoseSlideOp), "tPoseSlideOp");
+
+ /* get info from context */
+ pso->scene= CTX_data_scene(C);
+ pso->ob= CTX_data_active_object(C);
+ pso->arm= (pso->ob)? pso->ob->data : NULL;
+ pso->ar= CTX_wm_region(C); /* only really needed when doing modal() */
+
+ pso->cframe= pso->scene->r.cfra;
+ pso->mode= mode;
+
+ /* set range info from property values - these may get overridden for the invoke() */
+ pso->percentage= RNA_float_get(op->ptr, "percentage");
+ pso->prevFrame= RNA_int_get(op->ptr, "prev_frame");
+ pso->nextFrame= RNA_int_get(op->ptr, "next_frame");
+
+ /* check the settings from the context */
+ if (ELEM4(NULL, pso->ob, pso->arm, pso->ob->adt, pso->ob->adt->action))
+ return 0;
+ else
+ act= pso->ob->adt->action;
+
+ /* for each Pose-Channel which gets affected, get the F-Curves for that channel
+ * and set the relevant transform flags...
+ */
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
+ {
+ ListBase curves = {NULL, NULL};
+ int transFlags = action_get_item_transforms(act, pso->ob, pchan, &curves);
+
+ pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
+
+ /* check if any transforms found... */
+ if (transFlags) {
+ /* make new linkage data */
+ tPChanFCurveLink *pfl= MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
+ PointerRNA ptr;
+
+ pfl->fcurves= curves;
+ pfl->pchan= pchan;
+
+ /* get the RNA path to this pchan - this needs to be freed! */
+ RNA_pointer_create((ID *)pso->ob, &RNA_PoseChannel, pchan, &ptr);
+ pfl->pchan_path= RNA_path_from_ID_to_struct(&ptr);
+
+ /* add linkage data to operator data */
+ BLI_addtail(&pso->pfLinks, pfl);
+
+ /* set pchan's transform flags */
+ if (transFlags & ACT_TRANS_LOC)
+ pchan->flag |= POSE_LOC;
+ if (transFlags & ACT_TRANS_ROT)
+ pchan->flag |= POSE_ROT;
+ if (transFlags & ACT_TRANS_SCALE)
+ pchan->flag |= POSE_SIZE;
+
+ /* store current transforms */
+ VECCOPY(pfl->oldloc, pchan->loc);
+ VECCOPY(pfl->oldrot, pchan->eul);
+ VECCOPY(pfl->oldscale, pchan->size);
+ QUATCOPY(pfl->oldquat, pchan->quat);
+ }
+ }
+ CTX_DATA_END;
+
+ /* set depsgraph flags */
+ /* make sure the lock is set OK, unlock can be accidentally saved? */
+ pso->ob->pose->flag |= POSE_LOCKED;
+ pso->ob->pose->flag &= ~POSE_DO_UNLOCK;
+
+ /* do basic initialise of RB-BST used for finding keyframes, but leave the filling of it up
+ * to the caller of this (usually only invoke() will do it, to make things more efficient).
+ */
+ BLI_dlrbTree_init(&pso->keys);
+
+ /* get builtin KeyingSets */
+ pso->ks_loc= ANIM_builtin_keyingset_get_named(NULL, "Location");
+ pso->ks_rot= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
+ pso->ks_scale= ANIM_builtin_keyingset_get_named(NULL, "Scaling");
+
+ /* return status is whether we've got all the data we were requested to get */
+ return 1;
+}
+
+/* exiting the operator - free data */
+static void pose_slide_exit (bContext *C, wmOperator *op)
+{
+ tPoseSlideOp *pso= op->customdata;
+
+ /* if data exists, clear its data and exit */
+ if (pso) {
+ tPChanFCurveLink *pfl, *pfln=NULL;
+
+ /* free the temp pchan links and their data */
+ for (pfl= pso->pfLinks.first; pfl; pfl= pfln) {
+ pfln= pfl->next;
+
+ /* free list of F-Curve reference links */
+ BLI_freelistN(&pfl->fcurves);
+
+ /* free pchan RNA Path */
+ MEM_freeN(pfl->pchan_path);
+
+ /* free link itself */
+ BLI_freelinkN(&pso->pfLinks, pfl);
+ }
+
+ /* free RB-BST for keyframes (if it contained data) */
+ BLI_dlrbTree_free(&pso->keys);
+
+ /* free data itself */
+ MEM_freeN(pso);
+ }
+
+ /* cleanup */
+ op->customdata= NULL;
+}
+
+/* ------------------------------------ */
+
+/* helper for apply() / reset() - refresh the data */
+static void pose_slide_refresh (bContext *C, tPoseSlideOp *pso)
+{
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ // FIXME: shouldn't this use the builtin stuff?
+ if ((pso->arm->flag & ARM_DELAYDEFORM)==0)
+ DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ else
+ where_is_pose(pso->scene, pso->ob);
+
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+}
+
+/* helper for apply() callabcks - find the next F-Curve with matching path... */
+static LinkData *find_next_fcurve_link (ListBase *fcuLinks, LinkData *prev, char *path)
+{
+ LinkData *first= (prev)? prev->next : (fcuLinks)? fcuLinks->first : NULL;
+ LinkData *ld;
+
+ /* check each link to see if the linked F-Curve has a matching path */
+ for (ld= first; ld; ld= ld->next) {
+ FCurve *fcu= (FCurve *)ld->data;
+
+ /* check if paths match */
+ if (strcmp(path, fcu->rna_path) == 0)
+ return ld;
+ }
+
+ /* none found */
+ return NULL;
+}
+
+/* helper for apply() - perform sliding for some 3-element vector */
+static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, float vec[3], char *propName)
+{
+ LinkData *ld=NULL;
+ char *path=NULL;
+ float cframe;
+
+ /* get the path to use... */
+ path= BLI_sprintfN("%s.%s", pfl->pchan_path, propName);
+
+ /* get the current frame number */
+ cframe= (float)pso->cframe;
+
+ /* using this path, find each matching F-Curve for the variables we're interested in */
+ while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) {
+ FCurve *fcu= (FCurve *)ld->data;
+ float sVal, eVal;
+ float w1, w2;
+ int ch;
+
+ /* get keyframe values for endpoint poses to blend with */
+ /* previous/start */
+ sVal= evaluate_fcurve(fcu, (float)pso->prevFrame);
+ /* next/end */
+ eVal= evaluate_fcurve(fcu, (float)pso->nextFrame);
+
+ /* get channel index */
+ ch= fcu->array_index;
+
+ /* calculate the relative weights of the endpoints */
+ if (pso->mode == POSESLIDE_BREAKDOWN) {
+ /* get weights from the percentage control */
+ w1= pso->percentage; /* this must come second */
+ w2= 1.0f - w1; /* this must come first */
+ }
+ else {
+ /* - these weights are derived from the relative distance of these
+ * poses from the current frame
+ * - they then get normalised so that they only sum up to 1
+ */
+ float wtot;
+
+ w1 = cframe - (float)pso->prevFrame;
+ w2 = (float)pso->nextFrame - cframe;
+
+ wtot = w1 + w2;
+ w1 = (w1/wtot);
+ w2 = (w2/wtot);
+ }
+
+ /* depending on the mode, calculate the new value
+ * - in all of these, the start+end values are multiplied by w2 and w1 (respectively),
+ * since multiplication in another order would decrease the value the current frame is closer to
+ */
+ switch (pso->mode) {
+ case POSESLIDE_PUSH: /* make the current pose more pronounced */
+ {
+ /* perform a weighted average here, favouring the middle pose
+ * - numerator should be larger than denominator to 'expand' the result
+ * - perform this weighting a number of times given by the percentage...
+ */
+ int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+
+ while (iters-- > 0) {
+ vec[ch]= ( -((sVal * w2) + (eVal * w1)) + (vec[ch] * 6.0f) ) / 5.0f;
+ }
+ }
+ break;
+
+ case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */
+ {
+ /* perform a weighted average here, favouring the middle pose
+ * - numerator should be smaller than denominator to 'relax' the result
+ * - perform this weighting a number of times given by the percentage...
+ */
+ int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+
+ while (iters-- > 0) {
+ vec[ch]= ( ((sVal * w2) + (eVal * w1)) + (vec[ch] * 5.0f) ) / 6.0f;
+ }
+ }
+ break;
+
+ case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */
+ {
+ /* perform simple linear interpolation - coefficient for start must come from pso->percentage... */
+ // TODO: make this use some kind of spline interpolation instead?
+ vec[ch]= ((sVal * w2) + (eVal * w1));
+ }
+ break;
+ }
+
+ }
+
+ /* free the temp path we got */
+ MEM_freeN(path);
+}
+
+/* helper for apply() - perform sliding for quaternion rotations (using quat blending) */
+static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
+{
+ FCurve *fcu_w=NULL, *fcu_x=NULL, *fcu_y=NULL, *fcu_z=NULL;
+ bPoseChannel *pchan= pfl->pchan;
+ LinkData *ld=NULL;
+ char *path=NULL;
+ float cframe;
+
+ /* get the path to use - this should be quaternion rotations only (needs care) */
+ path= BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation");
+
+ /* get the current frame number */
+ cframe= (float)pso->cframe;
+
+ /* using this path, find each matching F-Curve for the variables we're interested in */
+ while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) {
+ FCurve *fcu= (FCurve *)ld->data;
+
+ /* assign this F-Curve to one of the relevant pointers... */
+ switch (fcu->array_index) {
+ case 3: /* z */
+ fcu_z= fcu;
+ break;
+ case 2: /* y */
+ fcu_y= fcu;
+ break;
+ case 1: /* x */
+ fcu_x= fcu;
+ break;
+ case 0: /* w */
+ fcu_w= fcu;
+ break;
+ }
+ }
+
+ /* only if all channels exist, proceed */
+ if (fcu_w && fcu_x && fcu_y && fcu_z) {
+ float quat_prev[4], quat_next[4];
+
+ /* get 2 quats */
+ quat_prev[0] = evaluate_fcurve(fcu_w, pso->prevFrame);
+ quat_prev[1] = evaluate_fcurve(fcu_x, pso->prevFrame);
+ quat_prev[2] = evaluate_fcurve(fcu_y, pso->prevFrame);
+ quat_prev[3] = evaluate_fcurve(fcu_z, pso->prevFrame);
+
+ quat_next[0] = evaluate_fcurve(fcu_w, pso->nextFrame);
+ quat_next[1] = evaluate_fcurve(fcu_x, pso->nextFrame);
+ quat_next[2] = evaluate_fcurve(fcu_y, pso->nextFrame);
+ quat_next[3] = evaluate_fcurve(fcu_z, pso->nextFrame);
+
+ /* perform blending */
+ if (pso->mode == POSESLIDE_BREAKDOWN) {
+ /* just perform the interpol between quat_prev and quat_next using pso->percentage as a guide */
+ QuatInterpol(pchan->quat, quat_prev, quat_next, pso->percentage);
+ }
+ else {
+ float quat_interp[4], quat_orig[4];
+ int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+
+ /* perform this blending several times until a satisfactory result is reached */
+ while (iters-- > 0) {
+ /* calculate the interpolation between the endpoints */
+ QuatInterpol(quat_interp, quat_prev, quat_next, (cframe-pso->prevFrame) / (pso->nextFrame-pso->prevFrame) );
+
+ /* make a copy of the original rotation */
+ QUATCOPY(quat_orig, pchan->quat);
+
+ /* tricky interpolations - mode-dependent blending between original and new */
+ if (pso->mode == POSESLIDE_RELAX) // xxx this was the original code, so should work fine
+ QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
+ else // I'm just guessing here...
+ QuatInterpol(pchan->quat, quat_orig, quat_interp, 6.0f/5.0f);
+ }
+ }
+ }
+
+ /* free the path now */
+ MEM_freeN(path);
+}
+
+/* apply() - perform the pose sliding based on weighting various poses */
+static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso)
+{
+ tPChanFCurveLink *pfl;
+
+ /* sanitise the frame ranges */
+ if (pso->prevFrame == pso->nextFrame) {
+ /* move out one step either side */
+ pso->prevFrame--;
+ pso->nextFrame++;
+ }
+
+ /* for each link, handle each set of transforms */
+ for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) {
+ /* valid transforms for each PoseChannel should have been noted already
+ * - sliding the pose should be a straightforward exercise for location+rotation,
+ * but rotations get more complicated since we may want to use quaternion blending
+ * for quaternions instead...
+ */
+ bPoseChannel *pchan= pfl->pchan;
+
+ if (pchan->flag & POSE_LOC) {
+ /* calculate these for the 'location' vector, and use location curves */
+ pose_slide_apply_vec3(pso, pfl, pchan->loc, "location");
+ }
+
+ if (pchan->flag & POSE_SIZE) {
+ /* calculate these for the 'scale' vector, and use scale curves */
+ pose_slide_apply_vec3(pso, pfl, pchan->size, "scale");
+ }
+
+ if (pchan->flag & POSE_ROT) {
+ /* everything depends on the rotation mode */
+ if (pchan->rotmode > 0) {
+ /* eulers - so calculate these for the 'eul' vector, and use euler_rotation curves */
+ pose_slide_apply_vec3(pso, pfl, pchan->eul, "rotation_euler");
+ }
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ // TODO: need to figure out how to do this!
+ }
+ else {
+ /* quaternions - use quaternion blending */
+ pose_slide_apply_quat(pso, pfl);
+ }
+ }
+ }
+
+ /* depsgraph updates + redraws */
+ pose_slide_refresh(C, pso);
+}
+
+/* perform autokeyframing after changes were made + confirmed */
+static void pose_slide_autoKeyframe (bContext *C, tPoseSlideOp *pso)
+{
+ /* insert keyframes as necessary if autokeyframing */
+ if (autokeyframe_cfra_can_key(pso->scene, &pso->ob->id)) {
+ bCommonKeySrc cks;
+ ListBase dsources = {&cks, &cks};
+ tPChanFCurveLink *pfl;
+
+ /* init common-key-source for use by KeyingSets */
+ memset(&cks, 0, sizeof(bCommonKeySrc));
+ cks.id= &pso->ob->id;
+
+ /* iterate over each pose-channel affected, applying the changes */
+ for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) {
+ bPoseChannel *pchan= pfl->pchan;
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+
+ /* insert keyframes */
+ if (pchan->flag & POSE_LOC)
+ modify_keyframes(C, &dsources, NULL, pso->ks_loc, MODIFYKEY_MODE_INSERT, (float)pso->cframe);
+ if (pchan->flag & POSE_ROT)
+ modify_keyframes(C, &dsources, NULL, pso->ks_rot, MODIFYKEY_MODE_INSERT, (float)pso->cframe);
+ if (pchan->flag & POSE_SIZE)
+ modify_keyframes(C, &dsources, NULL, pso->ks_scale, MODIFYKEY_MODE_INSERT, (float)pso->cframe);
+ }
+ }
+}
+
+/* reset changes made to current pose */
+static void pose_slide_reset (bContext *C, tPoseSlideOp *pso)
+{
+ tPChanFCurveLink *pfl;
+
+ /* iterate over each pose-channel affected, restoring all channels to their original values */
+ for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) {
+ bPoseChannel *pchan= pfl->pchan;
+
+ /* just copy all the values over regardless of whether they changed or not */
+ VECCOPY(pchan->loc, pfl->oldloc);
+ VECCOPY(pchan->eul, pfl->oldrot);
+ VECCOPY(pchan->size, pfl->oldscale);
+ QUATCOPY(pchan->quat, pfl->oldquat);
+ }
+}
+
+/* ------------------------------------ */
+
+/* common code for invoke() methods */
+static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp *pso)
+{
+ tPChanFCurveLink *pfl;
+ AnimData *adt= pso->ob->adt;
+ wmWindow *win= CTX_wm_window(C);
+
+ /* for each link, add all its keyframes to the search tree */
+ for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) {
+ LinkData *ld;
+
+ /* do this for each F-Curve */
+ for (ld= pfl->fcurves.first; ld; ld= ld->next) {
+ FCurve *fcu= (FCurve *)ld->data;
+ fcurve_to_keylist(adt, fcu, &pso->keys, NULL);
+ }
+ }
+
+ /* consolidate these keyframes, and figure out the nearest ones */
+ BLI_dlrbTree_linkedlist_sync(&pso->keys);
+
+ /* cancel if no keyframes found... */
+ if (pso->keys.root) {
+ ActKeyColumn *ak;
+
+ /* firstly, check if the current frame is a keyframe... */
+ ak= cfra_find_actkeycolumn(pso->keys.root, pso->cframe);
+
+ if (ak == NULL) {
+ /* current frame is not a keyframe, so search */
+ ActKeyColumn *pk= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 0);
+ ActKeyColumn *nk= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 1);
+
+ /* check if we found good keyframes */
+ if ((pk == nk) && (pk != NULL)) {
+ if (pk->cfra < pso->cframe)
+ nk= nk->next;
+ else if (nk->cfra > pso->cframe)
+ pk= pk->prev;
+ }
+
+ /* new set the frames */
+ /* prev frame */
+ pso->prevFrame= (pk)? (pk->cfra) : (pso->cframe - 1);
+ RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
+ /* next frame */
+ pso->nextFrame= (nk)? (nk->cfra) : (pso->cframe + 1);
+ RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
+ }
+ else {
+ /* current frame itself is a keyframe, so just take keyframes on either side */
+ /* prev frame */
+ pso->prevFrame= (ak->prev)? (ak->prev->cfra) : (pso->cframe - 1);
+ RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
+ /* next frame */
+ pso->nextFrame= (ak->next)? (ak->next->cfra) : (pso->cframe + 1);
+ RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
+ }
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No keyframes to slide between.");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* initial apply for operator... */
+ // TODO: need to calculate percentage for initial round too...
+ pose_slide_apply(C, op, pso);
+
+ /* depsgraph updates + redraws */
+ pose_slide_refresh(C, pso);
+
+ /* set cursor to indicate modal */
+ WM_cursor_modal(win, BC_EW_SCROLLCURSOR);
+
+ /* add a modal handler for this operator */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* common code for modal() */
+static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tPoseSlideOp *pso= op->customdata;
+ wmWindow *win= CTX_wm_window(C);
+
+ switch (evt->type) {
+ case LEFTMOUSE: /* confirm */
+ {
+ /* return to normal cursor */
+ WM_cursor_restore(win);
+
+ /* insert keyframes as required... */
+ pose_slide_autoKeyframe(C, pso);
+ pose_slide_exit(C, op);
+
+ /* done! */
+ return OPERATOR_FINISHED;
+ }
+
+ case ESCKEY: /* cancel */
+ case RIGHTMOUSE:
+ {
+ /* return to normal cursor */
+ WM_cursor_restore(win);
+
+ /* reset transforms back to original state */
+ pose_slide_reset(C, pso);
+
+ /* depsgraph updates + redraws */
+ pose_slide_refresh(C, pso);
+
+ /* clean up temp data */
+ pose_slide_exit(C, op);
+
+ /* cancelled! */
+ return OPERATOR_CANCELLED;
+ }
+
+ case MOUSEMOVE: /* calculate new position */
+ {
+ /* calculate percentage based on position of mouse (we only use x-axis for now.
+ * since this is more conveninent for users to do), and store new percentage value
+ */
+ pso->percentage= (evt->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx);
+ RNA_float_set(op->ptr, "percentage", pso->percentage);
+
+ /* reset transforms (to avoid accumulation errors) */
+ pose_slide_reset(C, pso);
+
+ /* apply... */
+ pose_slide_apply(C, op, pso);
+ }
+ break;
+
+ default: /* unhandled event (maybe it was some view manip? */
+ /* allow to pass through */
+ return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ }
+
+ /* still running... */
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* common code for cancel() */
+static int pose_slide_cancel (bContext *C, wmOperator *op)
+{
+ /* cleanup and done */
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+/* common code for exec() methods */
+static int pose_slide_exec_common (bContext *C, wmOperator *op, tPoseSlideOp *pso)
+{
+ /* settings should have been set up ok for applying, so just apply! */
+ pose_slide_apply(C, op, pso);
+
+ /* insert keyframes if needed */
+ pose_slide_autoKeyframe(C, pso);
+
+ /* cleanup and done */
+ pose_slide_exit(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+/* common code for defining RNA properties */
+static void pose_slide_opdef_properties (wmOperatorType *ot)
+{
+ RNA_def_int(ot->srna, "prev_frame", 0, MINAFRAME, MAXFRAME, "Previous Keyframe", "Frame number of keyframe immediately before the current frame.", 0, 50);
+ RNA_def_int(ot->srna, "next_frame", 0, MINAFRAME, MAXFRAME, "Next Keyframe", "Frame number of keyframe immediately after the current frame.", 0, 50);
+ RNA_def_float_percentage(ot->srna, "percentage", 0.5f, 0.0f, 1.0f, "Percentage", "Weighting factor for the sliding operation", 0.3, 0.7);
+}
+
+/* ------------------------------------ */
+
+/* invoke() - for 'push' mode */
+static int pose_slide_push_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tPoseSlideOp *pso;
+
+ /* initialise data */
+ if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) {
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else
+ pso= op->customdata;
+
+ /* do common setup work */
+ return pose_slide_invoke_common(C, op, pso);
+}
+
+/* exec() - for push */
+static int pose_slide_push_exec (bContext *C, wmOperator *op)
+{
+ tPoseSlideOp *pso;
+
+ /* initialise data (from RNA-props) */
+ if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) {
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else
+ pso= op->customdata;
+
+ /* do common exec work */
+ return pose_slide_exec_common(C, op, pso);
+}
+
+void POSE_OT_push (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Push Pose";
+ ot->idname= "POSE_OT_push";
+ ot->description= "Exaggerate the current pose";
+
+ /* callbacks */
+ ot->exec= pose_slide_push_exec;
+ ot->invoke= pose_slide_push_invoke;
+ ot->modal= pose_slide_modal;
+ ot->cancel= pose_slide_cancel;
+ ot->poll= ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* Properties */
+ pose_slide_opdef_properties(ot);
+}
+
+/* ........................ */
+
+/* invoke() - for 'relax' mode */
+static int pose_slide_relax_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tPoseSlideOp *pso;
+
+ /* initialise data */
+ if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) {
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else
+ pso= op->customdata;
+
+ /* do common setup work */
+ return pose_slide_invoke_common(C, op, pso);
+}
+
+/* exec() - for relax */
+static int pose_slide_relax_exec (bContext *C, wmOperator *op)
+{
+ tPoseSlideOp *pso;
+
+ /* initialise data (from RNA-props) */
+ if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) {
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else
+ pso= op->customdata;
+
+ /* do common exec work */
+ return pose_slide_exec_common(C, op, pso);
+}
+
+void POSE_OT_relax (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Relax Pose";
+ ot->idname= "POSE_OT_relax";
+ ot->description= "Make the current pose more similar to its surrounding ones.";
+
+ /* callbacks */
+ ot->exec= pose_slide_relax_exec;
+ ot->invoke= pose_slide_relax_invoke;
+ ot->modal= pose_slide_modal;
+ ot->cancel= pose_slide_cancel;
+ ot->poll= ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* Properties */
+ pose_slide_opdef_properties(ot);
+}
+
+/* ........................ */
+
+/* invoke() - for 'breakdown' mode */
+static int pose_slide_breakdown_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tPoseSlideOp *pso;
+
+ /* initialise data */
+ if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) {
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else
+ pso= op->customdata;
+
+ /* do common setup work */
+ return pose_slide_invoke_common(C, op, pso);
+}
+
+/* exec() - for breakdown */
+static int pose_slide_breakdown_exec (bContext *C, wmOperator *op)
+{
+ tPoseSlideOp *pso;
+
+ /* initialise data (from RNA-props) */
+ if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) {
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else
+ pso= op->customdata;
+
+ /* do common exec work */
+ return pose_slide_exec_common(C, op, pso);
+}
+
+void POSE_OT_breakdown (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Pose Breakdowner";
+ ot->idname= "POSE_OT_breakdown";
+ ot->description= "Create a suitable breakdown pose on the current frame.";
+
+ /* callbacks */
+ ot->exec= pose_slide_breakdown_exec;
+ ot->invoke= pose_slide_breakdown_invoke;
+ ot->modal= pose_slide_modal;
+ ot->cancel= pose_slide_cancel;
+ ot->poll= ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* Properties */
+ pose_slide_opdef_properties(ot);
+}
+
+/* **************************************************** */
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index 46d08afa656..386cb6512a3 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -44,7 +44,6 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
@@ -62,8 +61,6 @@
#include "BKE_report.h"
#include "BKE_utildefines.h"
-#include "PIL_time.h" /* sleep */
-
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
@@ -278,24 +275,7 @@ void poselib_validate_act (bAction *act)
/* ************************************************************* */
/* Pointers to the builtin KeyingSets that we want to use */
-static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll need*/
-static short poselib_ks_need_init= 1; /* have the above been obtained yet? */
-
-/* Make sure the builtin KeyingSets are initialised properly
- * (only gets called on first run of poselib_add_current_pose).
- */
-static void poselib_get_builtin_keyingsets (void)
-{
- /* only if we haven't got these yet */
- // FIXME: this assumes that we will always get the builtin sets...
- if (poselib_ks_need_init) {
- /* LocRotScale (quaternions or eulers depending on context) */
- poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
-
- /* clear flag requesting init */
- poselib_ks_need_init= 0;
- }
-}
+static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll need */
/* ----- */
@@ -390,9 +370,6 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
/* validate name */
BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), 64);
- /* make sure we've got KeyingSets to use */
- poselib_get_builtin_keyingsets();
-
/* init common-key-source for use by KeyingSets */
memset(&cks, 0, sizeof(bCommonKeySrc));
cks.id= &ob->id;
@@ -406,6 +383,8 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
cks.pchan= pchan;
/* KeyingSet to use depends on rotation mode (but that's handled by the templates code) */
+ if (poselib_ks_locrotscale == NULL)
+ poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame);
}
}
@@ -488,6 +467,7 @@ static int poselib_remove_exec (bContext *C, wmOperator *op)
marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index"));
if (marker == NULL) {
BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+ return OPERATOR_CANCELLED;
}
/* remove relevant keyframes */
@@ -554,6 +534,7 @@ static int poselib_rename_exec (bContext *C, wmOperator *op)
marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index"));
if (marker == NULL) {
BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+ return OPERATOR_CANCELLED;
}
/* get new name */
@@ -756,13 +737,20 @@ static void poselib_apply_pose (tPoseLib_PreviewData *pld)
}
/* Auto-keys/tags bones affected by the pose used from the poselib */
-static void poselib_keytag_pose (Scene *scene, tPoseLib_PreviewData *pld)
+static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData *pld)
{
bPose *pose= pld->pose;
bPoseChannel *pchan;
bAction *act= pld->act;
bActionGroup *agrp;
+ bCommonKeySrc cks;
+ ListBase dsources = {&cks, &cks};
+
+ /* init common-key-source for use by KeyingSets */
+ memset(&cks, 0, sizeof(bCommonKeySrc));
+ cks.id= &pld->ob->id;
+
/* start tagging/keying */
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
/* only for selected action channels */
@@ -770,28 +758,21 @@ static void poselib_keytag_pose (Scene *scene, tPoseLib_PreviewData *pld)
pchan= get_pose_channel(pose, agrp->name);
if (pchan) {
-#if 0 // XXX old animation system
// TODO: use a standard autokeying function in future (to allow autokeying-editkeys to work)
- if (IS_AUTOKEY_MODE(NORMAL)) {
- ID *id= &pld->ob->id;
+ if (IS_AUTOKEY_MODE(scene, NORMAL)) {
+ /* Set keys on pose
+ * - KeyingSet to use depends on rotation mode
+ * (but that's handled by the templates code)
+ */
+ // TODO: for getting the KeyingSet used, we should really check which channels were affected
+ if (poselib_ks_locrotscale == NULL)
+ poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
- /* Set keys on pose */
- if (pchan->flag & POSE_ROT) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
- }
- if (pchan->flag & POSE_SIZE) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
- }
- if (pchan->flag & POSE_LOC) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
- }
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+
+ /* now insert the keyframe */
+ modify_keyframes(C, &dsources, NULL, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
/* clear any unkeyed tags */
if (pchan->bone)
@@ -802,7 +783,6 @@ static void poselib_keytag_pose (Scene *scene, tPoseLib_PreviewData *pld)
if (pchan->bone)
pchan->bone->flag |= BONE_UNKEYED;
}
-#endif // XXX old animation system
}
}
@@ -1345,7 +1325,7 @@ static void poselib_preview_cleanup (bContext *C, wmOperator *op)
}
else if (pld->state == PL_PREVIEW_CONFIRM) {
/* tag poses as appropriate */
- poselib_keytag_pose(scene, pld);
+ poselib_keytag_pose(C, scene, pld);
/* change active pose setting */
act->active_marker= BLI_findindex(&act->markers, marker) + 1;
@@ -1434,7 +1414,7 @@ static int poselib_preview_invoke(bContext *C, wmOperator *op, wmEvent *event)
poselib_preview_apply(C, op);
/* add temp handler if we're running as a modal operator */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 7d7f54309a8..d4b7aa149df 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -798,6 +798,8 @@ void pose_copy_menu(Scene *scene)
VECCOPY(pchan->limitmax, pchanact->limitmax);
VECCOPY(pchan->stiffness, pchanact->stiffness);
pchan->ikstretch= pchanact->ikstretch;
+ pchan->ikrotweight= pchanact->ikrotweight;
+ pchan->iklinweight= pchanact->iklinweight;
}
break;
case 8: /* Custom Bone Shape */
@@ -812,14 +814,14 @@ void pose_copy_menu(Scene *scene)
armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float tmp_quat[4];
/* need to convert to quat first (in temp var)... */
Mat4ToQuat(delta_mat, tmp_quat);
QuatToAxisAngle(tmp_quat, &pchan->quat[1], &pchan->quat[0]);
}
- else if (pchan->rotmode == PCHAN_ROT_QUAT)
+ else if (pchan->rotmode == ROT_MODE_QUAT)
Mat4ToQuat(delta_mat, pchan->quat);
else
Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode);
@@ -961,6 +963,11 @@ void POSE_OT_copy (wmOperatorType *ot)
/* ---- */
+/* Pointers to the builtin KeyingSets that we want to use */
+static KeyingSet *posePaste_ks_locrotscale = NULL; /* the only keyingset we'll need */
+
+/* ---- */
+
static int pose_paste_exec (bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
@@ -969,6 +976,13 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
char name[32];
int flip= RNA_boolean_get(op->ptr, "flipped");
+ bCommonKeySrc cks;
+ ListBase dsources = {&cks, &cks};
+
+ /* init common-key-source for use by KeyingSets */
+ memset(&cks, 0, sizeof(bCommonKeySrc));
+ cks.id= &ob->id;
+
/* sanity checks */
if ELEM(NULL, ob, ob->pose)
return OPERATOR_CANCELLED;
@@ -1009,12 +1023,12 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
}
else if (pchan->rotmode > 0) {
/* quat/axis-angle to euler */
- if (chan->rotmode == PCHAN_ROT_AXISANGLE)
+ if (chan->rotmode == ROT_MODE_AXISANGLE)
AxisAngleToEulO(&chan->quat[1], chan->quat[0], pchan->eul, pchan->rotmode);
else
QuatToEulO(chan->quat, pchan->eul, pchan->rotmode);
}
- else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* quat/euler to axis angle */
if (chan->rotmode > 0)
EulOToAxisAngle(chan->eul, chan->rotmode, &pchan->quat[1], &pchan->quat[0]);
@@ -1038,13 +1052,20 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
pchan->eul[1] *= -1;
pchan->eul[2] *= -1;
}
- else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float eul[3];
AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], eul, EULER_ORDER_DEFAULT);
eul[1]*= -1;
eul[2]*= -1;
EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]);
+
+ // experimental method (uncomment to test):
+#if 0
+ /* experimental method: just flip the orientation of the axis on x/y axes */
+ pchan->quat[1] *= -1;
+ pchan->quat[2] *= -1;
+#endif
}
else {
float eul[3];
@@ -1056,28 +1077,19 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
}
}
-#if 0 // XXX old animation system
- if (autokeyframe_cfra_can_key(ob)) {
- ID *id= &ob->id;
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+ /* Set keys on pose
+ * - KeyingSet to use depends on rotation mode
+ * (but that's handled by the templates code)
+ */
+ // TODO: for getting the KeyingSet used, we should really check which channels were affected
+ if (posePaste_ks_locrotscale == NULL)
+ posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
- /* Set keys on pose */
- // TODO: make these use keyingsets....
- if (chan->flag & POSE_ROT) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
- }
- if (chan->flag & POSE_SIZE) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
- }
- if (chan->flag & POSE_LOC) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
- }
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+
+ modify_keyframes(C, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
/* clear any unkeyed tags */
if (chan->bone)
@@ -1088,7 +1100,6 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
if (chan->bone)
chan->bone->flag |= BONE_UNKEYED;
}
-#endif // XXX old animation system
}
}
}
@@ -1933,7 +1944,7 @@ static int armature_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *ev
/* Set the visible layers for the active armature (edit and pose modes) */
static int armature_bone_layers_exec (bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_active_object(C);
+ Object *ob= CTX_data_edit_object(C);
bArmature *arm= (ob)? ob->data : NULL;
PointerRNA ptr;
int layers[16]; /* hardcoded for now - we can only have 16 armature layers, so this should be fine... */
@@ -1946,7 +1957,7 @@ static int armature_bone_layers_exec (bContext *C, wmOperator *op)
{
/* get pointer for pchan, and write flags this way */
RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr);
- RNA_boolean_set_array(&ptr, "layers", layers);
+ RNA_boolean_set_array(&ptr, "layer", layers);
}
CTX_DATA_END;
@@ -1975,175 +1986,7 @@ void ARMATURE_OT_bone_layers (wmOperatorType *ot)
RNA_def_boolean_array(ot->srna, "layers", 16, NULL, "Layers", "Armature layers that bone belongs to.");
}
-
-#if 0
-// XXX old sys
-/* for use with pose_relax only */
-static int pose_relax_icu(struct IpoCurve *icu, float framef, float *val, float *frame_prev, float *frame_next)
-{
- if (!icu) {
- return 0;
- }
- else {
- BezTriple *bezt = icu->bezt;
-
- BezTriple *bezt_prev=NULL, *bezt_next=NULL;
- float w1, w2, wtot;
- int i;
-
- for (i=0; i < icu->totvert; i++, bezt++) {
- if (bezt->vec[1][0] < framef - 0.5) {
- bezt_prev = bezt;
- } else {
- break;
- }
- }
-
- if (bezt_prev==NULL) return 0;
-
- /* advance to the next, dont need to advance i */
- bezt = bezt_prev+1;
-
- for (; i < icu->totvert; i++, bezt++) {
- if (bezt->vec[1][0] > framef + 0.5) {
- bezt_next = bezt;
- break;
- }
- }
-
- if (bezt_next==NULL) return 0;
-
- if (val) {
- w1 = framef - bezt_prev->vec[1][0];
- w2 = bezt_next->vec[1][0] - framef;
- wtot = w1 + w2;
- w1=w1/wtot;
- w2=w2/wtot;
-#if 0
- val = (bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1);
-#else
- /* apply the value with a hard coded 6th */
- *val = (((bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1)) + (*val * 5.0f)) / 6.0f;
-#endif
- }
-
- if (frame_prev) *frame_prev = bezt_prev->vec[1][0];
- if (frame_next) *frame_next = bezt_next->vec[1][0];
-
- return 1;
- }
-}
-#endif
-
-void pose_relax(Scene *scene)
-{
- Object *ob = OBACT;
- bPose *pose;
- bAction *act;
- bArmature *arm;
-
-// IpoCurve *icu_w, *icu_x, *icu_y, *icu_z;
-
- bPoseChannel *pchan;
-// bActionChannel *achan;
-// float framef = F_CFRA;
-// float frame_prev, frame_next;
-// float quat_prev[4], quat_next[4], quat_interp[4], quat_orig[4];
-
- int do_scale = 0;
- int do_loc = 0;
- int do_quat = 0;
- int flag = 0;
-// int do_x, do_y, do_z;
-
- if (!ob) return;
-
- pose = ob->pose;
- act = ob->action;
- arm = (bArmature *)ob->data;
-
- if (!pose || !act || !arm) return;
-
- for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
-
- pchan->bone->flag &= ~BONE_TRANSFORM;
-
- if (pchan->bone->layer & arm->layer) {
- if (pchan->bone->flag & BONE_SELECTED) {
- /* do we have an ipo curve? */
-#if 0 // XXX old animation system
- achan= get_action_channel(act, pchan->name);
-
- if (achan && achan->ipo) {
- /*calc_ipo(achan->ipo, ctime);*/
-
- do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_X), framef, &pchan->loc[0], NULL, NULL);
- do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Y), framef, &pchan->loc[1], NULL, NULL);
- do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Z), framef, &pchan->loc[2], NULL, NULL);
- do_loc += do_x + do_y + do_z;
-
- do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_X), framef, &pchan->size[0], NULL, NULL);
- do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Y), framef, &pchan->size[1], NULL, NULL);
- do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Z), framef, &pchan->size[2], NULL, NULL);
- do_scale += do_x + do_y + do_z;
-
- if( ((icu_w = find_ipocurve(achan->ipo, AC_QUAT_W))) &&
- ((icu_x = find_ipocurve(achan->ipo, AC_QUAT_X))) &&
- ((icu_y = find_ipocurve(achan->ipo, AC_QUAT_Y))) &&
- ((icu_z = find_ipocurve(achan->ipo, AC_QUAT_Z))) )
- {
- /* use the quatw keyframe as a basis for others */
- if (pose_relax_icu(icu_w, framef, NULL, &frame_prev, &frame_next)) {
- /* get 2 quats */
- quat_prev[0] = eval_icu(icu_w, frame_prev);
- quat_prev[1] = eval_icu(icu_x, frame_prev);
- quat_prev[2] = eval_icu(icu_y, frame_prev);
- quat_prev[3] = eval_icu(icu_z, frame_prev);
-
- quat_next[0] = eval_icu(icu_w, frame_next);
- quat_next[1] = eval_icu(icu_x, frame_next);
- quat_next[2] = eval_icu(icu_y, frame_next);
- quat_next[3] = eval_icu(icu_z, frame_next);
-
-#if 0
- /* apply the setting, completely smooth */
- QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
-#else
- /* tricky interpolation */
- QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
- QUATCOPY(quat_orig, pchan->quat);
- QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
- /* done */
-#endif
- do_quat++;
- }
- }
-
- /* apply BONE_TRANSFORM tag so that autokeying will pick it up */
- pchan->bone->flag |= BONE_TRANSFORM;
- }
-
-#endif // XXX old animation system
- }
- }
- }
-
- ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
-
- /* do auto-keying */
- if (do_loc) flag |= TFM_TRANSLATION;
- if (do_scale) flag |= TFM_RESIZE;
- if (do_quat) flag |= TFM_ROTATION;
- autokeyframe_pose_cb_func(ob, flag, 0);
-
- /* clear BONE_TRANSFORM flags */
- for (pchan=pose->chanbase.first; pchan; pchan= pchan->next)
- pchan->bone->flag &= ~ BONE_TRANSFORM;
-
- /* do depsgraph flush */
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- BIF_undo_push("Relax Pose");
-}
+/* ********************************************** */
/* for use in insertkey, ensure rotation goes other way around */
void pose_flipquats(Scene *scene)
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 8a90dace40b..77c5ed1de2c 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -163,7 +163,10 @@ void ED_operatortypes_curve(void)
void ED_keymap_curve(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Font", 0, 0);
+ wmKeyMap *keymap;
+
+ keymap= WM_keymap_find(wm, "Font", 0, 0);
+ keymap->poll= ED_operator_editfont;
/* only set in editmode font, by space_view3d listener */
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", BKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_BOLD);
@@ -212,7 +215,8 @@ void ED_keymap_curve(wmWindowManager *wm)
WM_keymap_add_item(keymap, "FONT_OT_text_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
/* only set in editmode curve, by space_view3d listener */
- keymap= WM_keymap_listbase(wm, "Curve", 0, 0);
+ keymap= WM_keymap_find(wm, "Curve", 0, 0);
+ keymap->poll= ED_operator_editsurfcurve;
WM_keymap_add_item(keymap, "OBJECT_OT_curve_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "CURVE_OT_vertex_add", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index e346ccafde3..a18815d04a6 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1078,7 +1078,7 @@ void CURVE_OT_spline_weight_set(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- RNA_def_float_percentage(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f);
+ RNA_def_float_factor(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f);
}
/******************* set radius operator ******************/
@@ -2546,7 +2546,7 @@ void CURVE_OT_handle_type_set(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type");
+ RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "Spline type");
}
/***************** make segment operator **********************/
@@ -4704,6 +4704,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname)
float *curs, cent[3],vec[3],imat[3][3],mat[3][3];
float fac,cmat[3][3], grid;
int a, b, cutype, stype;
+ int force_3d = ((Curve *)obedit->data)->flag & CU_3D; /* could be adding to an existing 3D curve */
cutype= type & CU_TYPE; // poly, bezier, nurbs, etc
stype= type & CU_PRIMITIVE;
@@ -4727,7 +4728,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname)
cent[2]-= obedit->obmat[3][2];
if(rv3d) {
- if (!(newname) || U.flag & USER_ADD_VIEWALIGNED)
+ if (!newname && U.flag & USER_ADD_VIEWALIGNED)
Mat3CpyMat4(imat, rv3d->viewmat);
else
Mat3One(imat);
@@ -4760,7 +4761,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname)
rename_id((ID *)obedit->data, "Curve");
}
if(cutype==CU_BEZIER) {
- nu->flag= CU_2D;
+ if (!force_3d) nu->flag |= CU_2D;
nu->pntsu= 2;
nu->bezt =
(BezTriple*)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1");
@@ -4869,7 +4870,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname)
rename_id((ID *)obedit->data, "CurveCircle");
}
if(cutype==CU_BEZIER) {
- nu->flag= CU_2D;
+ if (!force_3d) nu->flag |= CU_2D;
nu->pntsu= 4;
nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1");
nu->flagu= CU_CYCLIC;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index a9736f3f88d..2be567e1921 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -381,19 +381,19 @@ static int paste_file(bContext *C, ReportList *reports, char *filename)
static int paste_file_exec(bContext *C, wmOperator *op)
{
- char *filename;
+ char *path;
int retval;
- filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0);
- retval= paste_file(C, op->reports, filename);
- MEM_freeN(filename);
+ path= RNA_string_get_alloc(op->ptr, "path", NULL, 0);
+ retval= paste_file(C, op->reports, path);
+ MEM_freeN(path);
return retval;
}
static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return paste_file_exec(C, op);
WM_event_add_fileselect(C, op);
@@ -417,7 +417,7 @@ void FONT_OT_file_paste(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL);
}
/******************* paste buffer operator ********************/
diff --git a/source/blender/editors/datafiles/B.blend.c b/source/blender/editors/datafiles/B.blend.c
index 980a9ee1697..b469f0c24cb 100644
--- a/source/blender/editors/datafiles/B.blend.c
+++ b/source/blender/editors/datafiles/B.blend.c
@@ -1,759 +1,858 @@
/* DataToC output of file <B_blend> */
-int datatoc_B_blend_size= 94308;
+int datatoc_B_blend_size= 100360;
char datatoc_B_blend[]= {
- 66, 76, 69, 78,
- 68, 69, 82, 45,118, 50, 53, 48, 82, 69, 78, 68, 32, 0, 0, 0, 80,187,118,198,255,127, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 1, 0, 0, 0,250, 0, 0, 0, 83, 99,101,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 71, 76, 79, 66, 40, 0, 0, 0, 64,187,118,198,255,127, 0, 0,185, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 48, 0, 0, 0, 0,
-250, 0, 0, 0, 1, 0, 0, 1,208,233, 90, 2, 0, 0, 0, 0, 96,130, 91, 2, 0, 0, 0, 0, 0, 16, 0, 0,128, 32, 4, 0,
- 87, 77, 0, 0,224, 0, 0, 0,144,231, 90, 2, 0, 0, 0, 0, 75, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 77, 87,105,110, 77, 97,110,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-176,232, 90, 2, 0, 0, 0, 0,176,232, 90, 2, 0, 0, 0, 0,176,232, 90, 2, 0, 0, 0, 0,176,232, 90, 2, 0, 0, 0, 0,
- 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0,
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,144,131,100, 2, 0, 0, 0, 0,176,167,177, 2, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,
-176,232, 90, 2, 0, 0, 0, 0, 76, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-224,186, 91, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,208,233, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-115, 99,114,101,101,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 0, 30, 0,118, 7, 97, 4, 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,131,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 14,119, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,224,180, 2, 0, 0, 0, 0,224,224,180, 2, 0, 0, 0, 0,
- 64,132,100, 2, 0, 0, 0, 0,176,133,100, 2, 0, 0, 0, 0,112,134,100, 2, 0, 0, 0, 0,144,191,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0,208, 0, 0, 0,208,233, 90, 2, 0, 0, 0, 0,
-179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 83, 99,114,101,101,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
- 32,240, 90, 2, 0, 0, 0, 0,144,247, 90, 2, 0, 0, 0, 0, 0,248, 90, 2, 0, 0, 0, 0,160,111, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,130, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 80,149,150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,
-224,234, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0,
-180, 0, 0, 0, 1, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 97, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,
- 0,236, 90, 2, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 97, 4, 0, 0, 0, 0,
- 68, 65, 84, 65, 32, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0,
-160,235, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,
- 96,236, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,
-180, 0, 0, 0, 1, 0, 0, 0, 32,237, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-118, 7, 70, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 32,237, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,
-128,237, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 32, 0, 0, 0,128,237, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0,
- 32,237, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 80, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,
-224,237, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,128,237, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,
-180, 0, 0, 0, 1, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 12, 6, 70, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,
- 0,239, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 32, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,
-160,238, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6,100, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,
- 96,239, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 80, 3, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
-180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-118, 7, 80, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 32,240, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-144,240, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,144,240, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 0,241, 90, 2, 0, 0, 0, 0, 32,240, 90, 2, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 0,241, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-112,241, 90, 2, 0, 0, 0, 0,144,240, 90, 2, 0, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,112,241, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-224,241, 90, 2, 0, 0, 0, 0, 0,241, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,224,241, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 80,242, 90, 2, 0, 0, 0, 0,112,241, 90, 2, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 80,242, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-192,242, 90, 2, 0, 0, 0, 0,224,241, 90, 2, 0, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,192,242, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 48,243, 90, 2, 0, 0, 0, 0, 80,242, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 48,243, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-160,243, 90, 2, 0, 0, 0, 0,192,242, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,160,243, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 16,244, 90, 2, 0, 0, 0, 0, 48,243, 90, 2, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 16,244, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-128,244, 90, 2, 0, 0, 0, 0,160,243, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,128,244, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-240,244, 90, 2, 0, 0, 0, 0, 16,244, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,240,244, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 96,245, 90, 2, 0, 0, 0, 0,128,244, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 96,245, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-208,245, 90, 2, 0, 0, 0, 0,240,244, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,208,245, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 64,246, 90, 2, 0, 0, 0, 0, 96,245, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 64,246, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-176,246, 90, 2, 0, 0, 0, 0,208,245, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,176,246, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 32,247, 90, 2, 0, 0, 0, 0, 64,246, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 32,247, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
-144,247, 90, 2, 0, 0, 0, 0,176,246, 90, 2, 0, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,144,247, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 32,247, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 0,248, 90, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0,
-192,251, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0,
-160,235, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 0, 0,
- 71, 4, 0, 0, 97, 4, 0, 0, 7, 7,119, 7, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0,112,153, 76, 2, 0, 0, 0, 0,
-208,129, 91, 2, 0, 0, 0, 0,208,129, 91, 2, 0, 0, 0, 0,224,248, 90, 2, 0, 0, 0, 0, 80,250, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 78,100, 2, 0, 0, 0, 0, 64,153,118, 2, 0, 0, 0, 0,
- 68, 65, 84, 65, 40, 1, 0, 0,224,248, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 80,250, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,106, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,238, 68,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65,
- 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,119, 7,
- 26, 0,119, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,118, 7, 0, 0, 71, 4, 0, 0, 96, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-119, 7, 26, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,155, 76, 2, 0, 0, 0, 0,
- 96,164,100, 2, 0, 0, 0, 0, 96,164,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-208,138,100, 2, 0, 0, 0, 0, 64,140,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 40, 1, 0, 0, 80,250, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-224,248, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,240, 68, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 69,
- 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0,129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0,
- 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 6, 0,129, 7,
- 2, 0,112, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 97, 4, 0, 0, 97, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 96,154, 76, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65,160, 0, 0, 0,192,251, 90, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0,176, 81, 91, 2, 0, 0, 0, 0,
- 0,248, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
- 0,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, 0, 0, 0, 0, 79, 3, 0, 0,
- 4, 4,106, 1, 80, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,149, 76, 2, 0, 0, 0, 0,240, 72, 91, 2, 0, 0, 0, 0,
- 80, 80, 91, 2, 0, 0, 0, 0,160,252, 90, 2, 0, 0, 0, 0, 16,254, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,160,158,118, 2, 0, 0, 0, 0, 96,169,118, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,
-160,252, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 16,254, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,193, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,181, 67, 0, 0, 0, 0, 0, 0,248, 65,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,105, 1, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,106, 1, 31, 0,106, 1, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0,
- 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1, 31, 0, 3, 0, 1, 0,
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,152, 76, 2, 0, 0, 0, 0,112,176,178, 2, 0, 0, 0, 0,
-112,176,178, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,143,100, 2, 0, 0, 0, 0,
- 32,146,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,
- 16,254, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,252, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,128,172, 67, 0,192, 71,196, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,172, 67, 0,192, 71,196, 0, 0, 0, 0,
- 89, 1, 0, 0,106, 1, 0, 0, 18, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0,
- 0, 0, 0, 0, 88, 1, 0, 0, 18, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,106, 1, 49, 3, 89, 1, 31, 3, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,160, 90,119, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0,
- 31, 0, 0, 0, 79, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1, 49, 3, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144,150, 76, 2, 0, 0, 0, 0,176,210,178, 2, 0, 0, 0, 0,
- 96, 53,180, 2, 0, 0, 0, 0,128,255, 90, 2, 0, 0, 0, 0, 96, 55,180, 2, 0, 0, 0, 0, 80,148,100, 2, 0, 0, 0, 0,
-240,151,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 1, 0, 0,
-240, 72, 91, 2, 0, 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0, 80, 80, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0,128,236,177, 2, 0, 0, 0, 0,
-255, 20, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 48, 74, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0,160, 75, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 1, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,160, 75, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 74, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 66, 76, 69, 78, 68, 69, 82, 95,
+118, 50, 53, 48, 82, 69, 78, 68, 32, 0, 0, 0,208,245, 18, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0,
+ 83, 99,101,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 76, 79, 66, 32, 0, 0, 0,
+200,245, 18, 0,192, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 51, 3, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 1, 72, 22, 11, 7,
+160, 33, 10, 7, 0, 16, 0, 0,128, 32, 4, 0, 87, 77, 0, 0,140, 0, 0, 0,192, 75, 10, 7, 86, 1, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 77, 87,105,110, 77, 97,110, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,254, 14, 7,160,147,103, 2,160,254, 14, 7,
+160,254, 14, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,224,183,102, 2,216, 85, 5, 7, 68, 65, 84, 65,148, 0, 0, 0,160,254, 14, 7, 87, 1, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 99, 2, 1, 0, 0, 0, 0, 0, 0, 0, 72, 22, 11, 7, 0, 0, 0, 0,115, 99,114,101,
+101,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 34, 0,
+186, 4,254, 2, 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 1, 0, 0, 0, 0, 0,232, 44, 99, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,144, 76, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,208,229, 25, 7,176,202, 25, 7,152, 43, 99, 2,
+184,231, 9, 7,200, 45, 5, 7, 56, 90, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0,140, 0, 0, 0, 72, 22, 11, 7,
+186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 83, 99,114,101,101,110,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208, 79, 10, 7,
+176,183, 3, 7,232,192, 3, 7, 96,201, 2, 7,120,255, 14, 7, 72,136, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,160, 33, 10, 7,
+ 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16,111, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,208, 79, 10, 7,
+187, 0, 0, 0, 1, 0, 0, 0,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 20, 0, 0, 0,120, 63, 11, 7,187, 0, 0, 0, 1, 0, 0, 0, 8, 11, 11, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0,254, 2,
+ 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 8, 11, 11, 7,187, 0, 0, 0, 1, 0, 0, 0,200, 32, 4, 7,120, 63, 11, 7,
+ 0, 0, 0, 0,186, 4,254, 2, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,200, 32, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,
+232,251, 3, 7, 8, 11, 11, 7, 0, 0, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,232,251, 3, 7,
+187, 0, 0, 0, 1, 0, 0, 0, 48, 16, 4, 7,200, 32, 4, 7, 0, 0, 0, 0, 0, 0,227, 2, 1, 0, 0, 0, 68, 65, 84, 65,
+ 20, 0, 0, 0, 48, 16, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,216, 43, 4, 7,232,251, 3, 7, 0, 0, 0, 0,186, 4,227, 2,
+ 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,216, 43, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,160, 34, 4, 7, 48, 16, 4, 7,
+ 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,160, 34, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,
+ 88,147, 4, 7,216, 43, 4, 7, 0, 0, 0, 0,186, 4, 60, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 88,147, 4, 7,
+187, 0, 0, 0, 1, 0, 0, 0,136,121, 4, 7,160, 34, 4, 7, 0, 0, 0, 0,216, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 20, 0, 0, 0,136,121, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,104, 25, 4, 7, 88,147, 4, 7, 0, 0, 0, 0,216, 3,227, 2,
+ 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,104, 25, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, 64,160, 4, 7,136,121, 4, 7,
+ 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 64,160, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,
+ 32, 26, 15, 7,104, 25, 4, 7, 0, 0, 0, 0,216, 3, 72, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 32, 26, 15, 7,
+187, 0, 0, 0, 1, 0, 0, 0,176,183, 3, 7, 64,160, 4, 7, 0, 0, 0, 0,216, 3, 72, 2, 0, 0, 0, 0, 68, 65, 84, 65,
+ 20, 0, 0, 0,176,183, 3, 7,187, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 26, 15, 7, 0, 0, 0, 0,186, 4, 72, 2,
+ 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,232,192, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 24,226, 3, 7, 0, 0, 0, 0,
+ 8, 11, 11, 7,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 24,226, 3, 7,188, 0, 0, 0,
+ 1, 0, 0, 0, 88, 14, 4, 7,232,192, 3, 7,232,251, 3, 7,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0, 88, 14, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, 0,180, 3, 7, 24,226, 3, 7, 48, 16, 4, 7, 8, 11, 11, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,180, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,104,163, 3, 7,
+ 88, 14, 4, 7,232,251, 3, 7, 48, 16, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,104,163, 3, 7,
+188, 0, 0, 0, 1, 0, 0, 0,248,203, 3, 7, 0,180, 3, 7, 88,147, 4, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 24, 0, 0, 0,248,203, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 16,191, 3, 7,104,163, 3, 7,200, 32, 4, 7,
+ 88,147, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 16,191, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,
+144, 23, 4, 7,248,203, 3, 7,232,251, 3, 7,136,121, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,
+144, 23, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, 0,118, 4, 7, 16,191, 3, 7, 48, 16, 4, 7,136,121, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,118, 4, 7,188, 0, 0, 0, 1, 0, 0, 0,144,109, 4, 7,144, 23, 4, 7,
+104, 25, 4, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,144,109, 4, 7,188, 0, 0, 0,
+ 1, 0, 0, 0, 40,178, 3, 7, 0,118, 4, 7,232,251, 3, 7,104, 25, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0, 40,178, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,200,170, 3, 7,144,109, 4, 7,136,121, 4, 7, 64,160, 4, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,200,170, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,176,242, 3, 7,
+ 40,178, 3, 7, 88,147, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,176,242, 3, 7,
+188, 0, 0, 0, 1, 0, 0, 0, 56,248, 3, 7,200,170, 3, 7,104, 25, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 24, 0, 0, 0, 56,248, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 80, 38, 4, 7,176,242, 3, 7, 88,147, 4, 7,
+ 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 80, 38, 4, 7,188, 0, 0, 0, 1, 0, 0, 0,
+232,133, 3, 7, 56,248, 3, 7,136,121, 4, 7, 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,
+232,133, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,160,210, 2, 7, 80, 38, 4, 7,176,183, 3, 7, 48, 16, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,160,210, 2, 7,188, 0, 0, 0, 1, 0, 0, 0, 96,201, 2, 7,232,133, 3, 7,
+176,183, 3, 7,200, 32, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 96,201, 2, 7,188, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,160,210, 2, 7,176,183, 3, 7, 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 96, 0, 0, 0,120,255, 14, 7,190, 0, 0, 0, 1, 0, 0, 0, 24, 23, 11, 7, 0, 0, 0, 0,232,251, 3, 7,120, 63, 11, 7,
+ 8, 11, 11, 7, 48, 16, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0,186, 4, 0, 0,228, 2, 0, 0,254, 2, 0, 0, 7, 7,187, 4,
+ 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 56,150, 92, 2,152,180,102, 2,152,180,102, 2, 32,173, 11, 7,112,158, 24, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40, 47, 5, 7, 8, 48, 5, 7, 68, 65, 84, 65,248, 0, 0, 0, 32,173, 11, 7,191, 0, 0, 0,
+ 1, 0, 0, 0,112,158, 24, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,157, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0,
+ 0, 96,151, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68,
+ 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4,
+ 10, 0,187, 4, 26, 0,187, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,186, 4, 0, 0,228, 2, 0, 0,253, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+187, 4, 26, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,151, 92, 2,184,191, 25, 7,
+184,191, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,216, 49, 5, 7, 96, 50, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+248, 0, 0, 0,112,158, 24, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32,173, 11, 7, 0, 0, 0, 0, 0, 32,240, 68,
+ 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 69, 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0,129, 7, 0, 0,
+ 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0,
+ 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64,
+ 10, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 6, 0,129, 7, 2, 0,112, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 2, 0, 0,254, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0,224,150, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0, 24, 23, 11, 7,190, 0, 0, 0, 1, 0, 0, 0,200, 33, 11, 7,
+120,255, 14, 7, 88,147, 4, 7, 32, 26, 15, 7,176,183, 3, 7,200, 32, 4, 7, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0,
+ 0, 0, 0, 0, 71, 2, 0, 0, 4, 4,226, 0, 72, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,147, 92, 2,192,160, 9, 7,
+120,148, 10, 7,128,237, 11, 7,184,238, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0,232, 50, 5, 7,200, 51, 5, 7, 68, 65, 84, 65,
+248, 0, 0, 0,128,237, 11, 7,191, 0, 0, 0, 1, 0, 0, 0,184,238, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 67,
+ 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 98, 67, 0, 0, 0, 0, 0, 0,248, 65, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,225, 0, 0, 0,
+ 0, 0, 0, 0, 30, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,226, 0, 31, 0,226, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0, 31, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,152,149, 92, 2,160,145,246, 6,160,145,246, 6, 0, 0, 0, 0, 0, 0, 0, 0,152, 53, 5, 7,168, 54, 5, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,184,238, 11, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+128,237, 11, 7, 0, 0, 0, 0, 0, 0, 80, 67, 0, 0, 68,196, 0, 0, 0, 0, 0, 0, 0, 0,254,255, 80, 67,255,191, 5,196,
+ 0, 0, 0, 0,209, 0, 0, 0,226, 0, 0, 0, 18, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 18, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,226, 0, 41, 2,209, 0,
+ 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176, 63,100, 2, 1, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0,
+ 31, 0, 0, 0, 71, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0, 41, 2, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,148, 92, 2, 88, 22, 6, 7, 16,102, 5, 7,248, 24, 11, 7,
+ 72,159, 9, 7,144, 56, 5, 7, 40, 58, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,248, 24, 11, 7,
+189, 0, 0, 0, 1, 0, 0, 0,112, 26, 11, 7, 0, 0, 0, 0,200,148, 92, 2, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95,
+ 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95,
+ 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255,208, 0, 36, 0,
+ 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 56, 1, 0, 0,112, 26, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,232, 27, 11, 7,248, 24, 11, 7,232,164, 2, 7,
+ 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,135,255,208, 0, 61, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,232, 27, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,
+ 96, 29, 11, 7,112, 26, 11, 7,192,166, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,108, 97,121,101,114,115, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,108, 97,121,101,114,115, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,
+ 96, 29, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,216, 30, 11, 7,232, 27, 11, 7,152,168, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78,
+ 69, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78,
+ 69, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,
+110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,165,254,
+208, 0,178, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 26, 0, 0, 0, 80, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,216, 30, 11, 7,189, 0, 0, 0, 1, 0, 0, 0, 80, 32, 11, 7, 96, 29, 11, 7,
+112,170, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 16, 77, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, 16, 77, 91, 2, 0, 0, 0, 0,
-146, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,
-226,215,163,188, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32,193, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32, 65, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
-184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0,
- 98,127,249, 67,129,255, 71, 66, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32,193, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
-184,175, 31, 65, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,254,208, 0, 58, 0, 20, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 80, 32, 11, 7,189, 0, 0, 0,
+ 1, 0, 0, 0,104,153, 9, 7,216, 30, 11, 7, 72,172, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,104, 97,
+100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,104, 97,
+100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,213,253,208, 0,102, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 56, 1, 0, 0,104,153, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,224,154, 9, 7, 80, 32, 11, 7, 32,174, 2, 7, 0, 0, 0, 0,
+ 83, 67, 69, 78, 69, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 32, 1, 0, 0, 80, 80, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-240, 72, 91, 2, 0, 0, 0, 0, 48, 74, 91, 2, 0, 0, 0, 0,160, 75, 91, 2, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32, 65, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,250, 67,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 10, 0,
-159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,
-176, 81, 91, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 94, 91, 2, 0, 0, 0, 0,192,251, 90, 2, 0, 0, 0, 0,
-224,234, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 15, 15, 12, 6,100, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,240,118, 76, 2, 0, 0, 0, 0,112, 85, 91, 2, 0, 0, 0, 0,160, 92, 91, 2, 0, 0, 0, 0,
-144, 82, 91, 2, 0, 0, 0, 0, 0, 84, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-192,174,118, 2, 0, 0, 0, 0,176,185,118, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,144, 82, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 0, 84, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,104, 68,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,193, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0,224,202, 68, 0, 0,200, 65, 0,224,202, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 12, 6, 26, 0, 12, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 26, 0, 5, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,208,120, 76, 2, 0, 0, 0, 0,208,218,179, 2, 0, 0, 0, 0,208,218,179, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,155,100, 2, 0, 0, 0, 0, 96,156,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 0, 84, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 82, 91, 2, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67,
- 0, 0, 0, 0, 0, 0, 72, 66,112,189, 17,192,246, 70,125, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,
- 18, 0, 0, 0, 73, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65,
- 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, 8, 0, 12, 6, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, 26, 0, 0, 0, 99, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 74, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,224,119, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144,158,100, 2, 0, 0, 0, 0,160,163,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,200, 0, 0, 0,112, 85, 91, 2, 0, 0, 0, 0,
-162, 0, 0, 0, 1, 0, 0, 0,160, 92, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,128, 86, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0,240, 87, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,203, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 88, 6, 26, 0, 88, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 6, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0,
+ 83, 67, 69, 78, 69, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,240, 87, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 86, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 84,253,208, 0,105, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,224,154, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 88,156, 9, 7,
+104,153, 9, 7,208,177, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0, 26, 0, 0, 0, 55, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 6, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60,253,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 96, 89, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, 96, 89, 91, 2, 0, 0, 0, 0,
-146, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,
-226,215,163,188, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32,193, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32, 65, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
-184,175, 31, 65, 0, 0, 32, 65,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 91,138, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0,
- 98,127,249, 67,129,255, 71, 66, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32,193, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
-184,175, 31, 65, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 88,156, 9, 7,
+189, 0, 0, 0, 1, 0, 0, 0,208,157, 9, 7,224,154, 9, 7,168,179, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84,
+ 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84,
+ 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111,
+ 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,253,208, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 52,149,147, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 56, 1, 0, 0,208,157, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 72,159, 9, 7, 88,156, 9, 7,128,181, 2, 7,
+ 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 12,253,208, 0, 0, 0, 20, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 32, 1, 0, 0,160, 92, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-112, 85, 91, 2, 0, 0, 0, 0,128, 86, 91, 2, 0, 0, 0, 0,240, 87, 91, 2, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32, 65, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,250, 67,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 10, 0,
-159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,
- 0, 94, 91, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0,160,111, 91, 2, 0, 0, 0, 0,176, 81, 91, 2, 0, 0, 0, 0,
-160,238, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,101, 0, 0, 0, 69, 4, 0, 0, 1, 1, 12, 6,225, 3, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,192,121, 76, 2, 0, 0, 0, 0, 64,110, 91, 2, 0, 0, 0, 0, 64,110, 91, 2, 0, 0, 0, 0,
-224, 94, 91, 2, 0, 0, 0, 0,144,105, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 48,188,118, 2, 0, 0, 0, 0,224,204,118, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,224, 94, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 80, 96, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,193, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 12, 6, 26, 0, 12, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,101, 0, 0, 0,126, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 26, 0, 7, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,112,130, 76, 2, 0, 0, 0, 0,128, 47,182, 2, 0, 0, 0, 0,128, 47,182, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,167,100, 2, 0, 0, 0, 0,192,170,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 80, 96, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0,144,105, 91, 2, 0, 0, 0, 0,224, 94, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67,
- 0, 64, 55,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, 0, 0, 41,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,219, 0, 0, 0,
- 0, 0, 0, 0,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64,
- 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 0, 6, 0,220, 0,164, 2,220, 0,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, 11, 6, 0, 0,127, 0, 0, 0, 69, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,160,123, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-192, 97, 91, 2, 0, 0, 0, 0, 0,104, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,144,105, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 96, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,127, 0, 0, 0, 69, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6,199, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,176,122, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,172,100, 2, 0, 0, 0, 0, 96,186,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, 0,107, 91, 2, 0, 0, 0, 0,
-146, 0, 0, 0, 1, 0, 0, 0, 1, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 29,224, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
-225,215,163,188, 0, 0, 0, 0,238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,
-244,217, 46,191, 0, 0, 0, 0,228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-152, 60,138,193, 0, 0,128, 63,236, 4, 53, 63,244, 4, 53, 63, 0, 0, 24, 53, 0, 0, 0, 0,137,103, 59,190,118,103, 59, 62,
-227, 70,119, 63, 0, 0, 0, 0,238,217, 46, 63,221,217, 46,191,213,131,132, 62, 0, 0, 0, 0,186,213, 60, 65,168,213, 60,193,
-221, 28,143, 64, 0, 0,128, 63,102,253, 69, 63,120, 16,164,190,194,219, 46,191,247,217, 46,191,120,253, 69, 63, 67, 16,164, 62,
-191,219, 46, 63,244,217, 46, 63, 67,228, 68, 50,189,122,216, 63, 53,133,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0,
- 13, 21,138, 65,152, 60,138, 65, 15,132, 37, 63,166,125, 37, 63, 0, 96,160, 55, 0,128,139, 54, 97, 17,214,189, 77, 17,214, 61,
- 92, 58, 13, 63, 0, 0,184,179,168,135, 19,196,155,135, 19, 68, 34,158, 95,195,235, 0, 72,194,116, 93, 19, 68,103, 93, 19,196,
- 42, 94, 95, 67,248, 2, 72, 66,238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,
-244,217, 46,191, 0, 0, 0, 0,228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-152, 60,138,193, 0, 0,128, 63,102,253, 69, 63,120, 16,164,190,194,219, 46,191,247,217, 46,191,120,253, 69, 63, 67, 16,164, 62,
-191,219, 46, 63,244,217, 46, 63, 67,228, 68, 50,189,122,216, 63, 53,133,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0,
- 13, 21,138, 65,152, 60,138, 65, 55,243,195, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55,243,195, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55,243,195, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63,122,163, 59, 63,235,250, 15,191,221,141,110,190,230,113,155,190,152, 60,138, 65, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 21,212,154, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 72,159, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0,208,157, 9, 7, 88,183, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,117,110,105,116, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,117,110,105,116, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85,110,105,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,244,252,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 0,
+ 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 32, 1, 0, 0, 64,110, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32, 65, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,250, 67,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 10, 0,
-159, 0, 0, 0, 0, 0, 0, 0, 3, 0,255,255, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,
-160,111, 91, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 91, 2, 0, 0, 0, 0,
- 96,239, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, 81, 3, 0, 0, 69, 4, 0, 0, 3, 3,106, 1,245, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 32,116, 76, 2, 0, 0, 0, 0, 96,115, 91, 2, 0, 0, 0, 0,112,128, 91, 2, 0, 0, 0, 0,
-128,112, 91, 2, 0, 0, 0, 0,240,113, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,207,118, 2, 0, 0, 0, 0,144, 82,119, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,128,112, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0,240,113, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190, 67,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,181, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 1, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 66, 67, 0, 0,200, 65, 0, 0, 66, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,106, 1, 26, 0,106, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, 81, 3, 0, 0,106, 3, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1, 26, 0, 9, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 76, 2, 0, 0, 0, 0,128, 5,182, 2, 0, 0, 0, 0,128, 5,182, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,190,100, 2, 0, 0, 0, 0,208,190,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,240,113, 91, 2, 0, 0, 0, 0,
-184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,112, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,131, 67,
- 0, 0,194,194, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,172, 67, 0, 0, 73,195, 0, 0, 0, 0, 89, 1, 0, 0,106, 1, 0, 0,
- 18, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0,
- 18, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
- 18, 0, 0, 0, 2, 0, 3, 3, 0, 0, 0, 4, 6, 0,106, 1,219, 0, 89, 1,201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0,107, 3, 0, 0, 69, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1,219, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 16,117, 76, 2, 0, 0, 0, 0,192, 43,182, 2, 0, 0, 0, 0,192, 43,182, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193,100, 2, 0, 0, 0, 0, 48,195,100, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 96,115, 91, 2, 0, 0, 0, 0,
-156, 0, 0, 0, 1, 0, 0, 0, 16,121, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 8,182, 2, 0, 0, 0, 0,
-224, 8,182, 2, 0, 0, 0, 0,208,116, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,208,116, 91, 2, 0, 0, 0, 0,
-207, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 32,117, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,
- 32,117, 91, 2, 0, 0, 0, 0,206, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0,
- 19, 0, 0, 0, 1, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0,
- 21, 0, 1, 0, 1, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 48,145, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0,176,157, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,128,173, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0,128,167, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,224,171, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0, 16,163, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,176,140, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,208,139, 91, 2, 0, 0, 0, 0,
- 68, 65, 84, 65, 40, 1, 0, 0, 48,118, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0,160,119, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 55, 0, 0, 67, 67,
- 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65,
- 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,195, 0,
- 26, 0,195, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 4, 0, 0,247, 4, 0, 0, 69, 2, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-195, 0, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,
+192,160, 9, 7,158, 0, 0, 0, 1, 0, 0, 0,120,148, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 40, 1, 0, 0,160,119, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 48,118, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,150, 67, 0,192,116,196, 0, 0, 0, 0, 0, 0, 0, 0,205, 85,150, 67,
-223,204, 35,196, 26, 85,207,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 4, 6, 0,195, 0,
-156, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 4, 0, 0,247, 4, 0, 0, 95, 2, 0, 0,250, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 1, 0, 0, 16,121, 91, 2, 0, 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0,112,128, 91, 2, 0, 0, 0, 0,
- 96,115, 91, 2, 0, 0, 0, 0, 48,118, 91, 2, 0, 0, 0, 0,160,119, 91, 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 80,175, 11, 7,
+255, 20, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,224,161, 9, 7,191, 0, 0, 0, 1, 0, 0, 0,
+ 40,144, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 67,
+ 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65,
+ 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1,
+ 26, 0, 20, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,
+108, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 26, 0,
+ 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,
+ 40,144, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,224,161, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,
- 80,122, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0,192,123, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 67, 0, 0, 0, 0, 0, 0,208, 65,
+ 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 1, 26, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0,
- 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 26, 0, 0, 0, 1, 0,
+ 96,145, 10, 7, 68, 65, 84, 65,216, 2, 0, 0, 96,145, 10, 7,152, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,120,148, 10, 7,153, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,192,160, 9, 7,224,161, 9, 7, 40,144, 10, 7, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,
+ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0,200, 33, 11, 7,
+190, 0, 0, 0, 1, 0, 0, 0, 48,124, 9, 7, 24, 23, 11, 7,208, 79, 10, 7,104, 25, 4, 7, 64,160, 4, 7, 88,147, 4, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 15, 15,216, 3, 72, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,123, 92, 2, 24,152, 10, 7, 0,123, 9, 7,168,149, 10, 7,224,150, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+176, 58, 5, 7,144, 59, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,168,149, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,224,150, 10, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,128, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 56, 0, 0,118, 68, 0, 0, 0, 0,
+ 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,224,202, 68, 0, 0,200, 65, 0,224,202, 68,
+ 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,216, 3, 26, 0,216, 3,
+ 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3, 26, 0, 5, 0, 1, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,124, 92, 2,248, 23, 6, 7,248, 23, 6, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 96, 61, 5, 7,112, 62, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,224,150, 10, 7,
+191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168,149, 10, 7, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66,
+112,189, 17,192,246, 70,125, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,215, 3, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 18, 0, 0, 0, 45, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, 0, 0, 0, 2,
+ 4, 0, 0, 4, 8, 0,216, 3, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 26, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,216, 3, 46, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,123, 92, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 64, 5, 7,120, 66, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,180, 0, 0, 0, 24,152, 10, 7,168, 0, 0, 0, 1, 0, 0, 0, 0,123, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 6, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 16,153, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,176,118, 9, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,203, 68, 0, 0, 0, 0,
+ 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68,
+ 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 88, 6, 26, 0, 88, 6,
+ 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 6, 26, 0, 0, 0, 1, 0,
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,
-192,123, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,122, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0,
- 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,176,118, 9, 7,
+191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16,153, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,125, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0,
- 48,125, 91, 2, 0, 0, 0, 0,146, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191,
- 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191,
- 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194,
- 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191,
- 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0, 26, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 88, 6, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,119, 9, 7,
+ 68, 65, 84, 65,216, 2, 0, 0,232,119, 9, 7,152, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191,
+ 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191,
+ 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,224, 91,138, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,
+115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191,
+ 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52,149,147, 58, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 1, 0, 0,112,128, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 16,121, 91, 2, 0, 0, 0, 0, 80,122, 91, 2, 0, 0, 0, 0,192,123, 91, 2, 0, 0, 0, 0,
- 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0, 0,123, 9, 7,153, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 24,152, 10, 7, 16,153, 10, 7,176,118, 9, 7, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0, 48,124, 9, 7,190, 0, 0, 0,
+ 1, 0, 0, 0, 72,136, 9, 7,200, 33, 11, 7,104, 25, 4, 7,232,251, 3, 7,136,121, 4, 7, 64,160, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0,215, 3, 0, 0, 73, 0, 0, 0,226, 2, 0, 0, 1, 1,216, 3,154, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+232,124, 92, 2, 24,135, 9, 7, 24,135, 9, 7,208,124, 9, 7,160,229, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 5, 7,
+ 48, 69, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,208,124, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 8,126, 9, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 64, 90, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,118, 68, 0, 0, 0, 0, 0, 0,208, 65,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,215, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,216, 3, 26, 0,216, 3, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 73, 0, 0, 0,
+ 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3, 26, 0, 7, 0, 1, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,132, 92, 2, 32, 77,104, 2, 32, 77,104, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 71, 5, 7,152, 72, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 8,126, 9, 7,191, 0, 0, 0,
+ 1, 0, 0, 0, 48,130, 9, 7,208,124, 9, 7, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0,251,195, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 15, 67, 0, 0,251,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0,
+142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4,
+ 6, 0,160, 0, 8, 2,143, 0,246, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,159, 0, 0, 0,219, 0, 0, 0,226, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+160, 0, 8, 2, 8, 0, 5, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,129, 92, 2, 72,117,101, 2,
+136, 52,102, 2, 64,127, 9, 7,184,128, 9, 7,128, 74, 5, 7, 24, 76, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 56, 1, 0, 0, 64,127, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,184,128, 9, 7, 0, 0, 0, 0,224,129, 92, 2, 0, 0, 0, 0,
+ 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115,104,101,108,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115,104,101,108,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 84,111,111,108, 32, 83,104,101,108,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,196,255,143, 0, 36, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,184,128, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 64,127, 9, 7, 80,129, 4, 7, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101,
+ 99,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101,
+ 99,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 84,111,111,108,115, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27,254,143, 0,145, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 83, 67, 0, 0,192, 5, 0, 0, 96,130, 91, 2, 0, 0, 0, 0,144, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 83, 99,101,110,101, 0,
-116, 97,103,101, 0, 97,105,110, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 64,153, 91, 2, 0, 0, 0, 0, 48,145, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 96,136, 91, 2, 0, 0, 0, 0, 64,137, 91, 2, 0, 0, 0, 0, 96,136, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,137, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 48,130, 9, 7,
+191, 0, 0, 0, 1, 0, 0, 0,152,219, 10, 7, 8,126, 9, 7, 0, 0, 0, 0, 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0,
+ 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0,
+ 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0,
+ 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 99, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,160, 0,120, 0, 9, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,130, 92, 2,
+120, 73, 25, 7,120, 73, 25, 7, 32,218, 10, 7, 32,218, 10, 7, 0, 78, 5, 7,152, 79, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 56, 1, 0, 0, 32,218, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,131, 92, 2,
+ 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
-250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0,100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,224, 1, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 6, 0, 25, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 0, 0, 24, 0, 17, 0, 0, 0, 0, 0, 90, 0, 0, 0,
- 0, 0, 0, 0, 81, 0, 0, 0, 23, 0, 33, 0, 0, 0,128, 0, 0, 0, 8, 0, 24, 0, 10, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 48,139, 91, 2, 0, 0, 0, 0, 48,139, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
- 0, 0,200, 66, 0, 0,128, 63, 0, 0,128, 63, 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
- 5, 0, 2, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 79,112,101,114, 97,116,111,114, 0,105,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,216,255,144, 0, 16, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 98, 97, 99,107, 98,117,
-102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,152,219, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,
+160,229, 10, 7, 48,130, 9, 7, 0, 0, 0, 0, 0, 0, 75, 67, 0,128,118,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 67,
+ 0,128, 27,196, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 18, 0, 0, 0,127, 2, 0, 0, 0, 0, 0, 0,202, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 18, 0, 0, 0,127, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,220, 0,
+128, 2,203, 0,110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0,
+215, 3, 0, 0, 99, 0, 0, 0,226, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48,126, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+208,220, 10, 7, 40,228, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,
+208,220, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 72,222, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87,
+ 51, 68, 95, 80, 84, 95,111, 98,106,101, 99,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87,
+ 51, 68, 95, 80, 84, 95,111, 98,106,101, 99,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,114, 97,110,
+115,102,111,114,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26,255,
+203, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 72,222, 10, 7,189, 0, 0, 0, 1, 0, 0, 0,192,223, 10, 7,208,220, 10, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 71,114,101, 97,115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,254,203, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,192,223, 10, 7,189, 0, 0, 0,
+ 1, 0, 0, 0, 56,225, 10, 7, 72,222, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,
+118,105,101,119, 95,112,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,
+118,105,101,119, 95,112,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86,105,101,119, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,253,203, 0, 47, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 56, 1, 0, 0, 56,225, 10, 7,189, 0, 0, 0, 1, 0, 0, 0,176,226, 10, 7,192,223, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,100,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,100,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 66,252,203, 0, 39, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,176,226, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 40,228, 10, 7,
+ 56,225, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115,
+104,100,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115,
+104,100,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77,101,115,104, 32, 68,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254,250,203, 0,104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 40,228, 10, 7,
+189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,176,226, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80,
+ 84, 95, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80,
+ 84, 95, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97, 99,107,103,114,111,117,
+110,100, 32, 73,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42,252,203, 0, 0, 0,
+ 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,248, 0, 0, 0,160,229, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,152,219, 10, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 99, 0, 0, 0,226, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3,128, 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,144,125, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 81, 5, 7,
+ 40, 84, 5, 7, 0, 0, 0, 0, 0,132, 9, 7, 68, 65, 84, 65,216, 2, 0, 0, 0,132, 9, 7,152, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64,215, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28, 13,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, 74,215, 76,190, 0, 0, 0, 0,
+238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0,
+228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63,
+236, 4, 53, 63,244, 4, 53, 63, 0, 0, 24, 53, 0, 0, 0, 0,137,103, 59,190,118,103, 59, 62,227, 70,119, 63, 0, 0, 0, 0,
+238,217, 46, 63,221,217, 46,191,213,131,132, 62, 0, 0, 0, 0,186,213, 60, 65,168,213, 60,193,221, 28,143, 64, 0, 0,128, 63,
+100,253, 69, 63,248,146,157,190,223,235, 46,191,247,217, 46,191,119,253, 69, 63,197,146,157, 62,220,235, 46, 63,244,217, 46, 63,
+ 65,228, 68, 50,109,234,207, 63,107,145,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65,
+252,128, 37, 63,186,128, 37, 63, 0, 0,180, 53, 0, 0, 60, 52,154,225,222,189,131,225,222, 61,139, 11, 19, 63, 0, 0,144, 51,
+ 25,255,107,194, 1,255,107, 66,239,218,178,193,208,247,159,192,220, 91,105, 66,197, 91,105,194, 49,219,176, 65, 50, 8,160, 64,
+238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0,
+228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63,
+100,253, 69, 63,248,146,157,190,223,235, 46,191,247,217, 46,191,119,253, 69, 63,197,146,157, 62,220,235, 46, 63,244,217, 46, 63,
+ 65,228, 68, 50,109,234,207, 63,107,145,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65,
+166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+122,163, 59, 63,235,250, 15,191,221,141,110,190,230,113,155,190,152, 60,138, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83,146,243, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,
+ 24,135, 9, 7,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 12, 66,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0,255,255,
+ 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 96, 0, 0, 0, 72,136, 9, 7,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48,124, 9, 7, 32, 26, 15, 7,136,121, 4, 7,
+ 48, 16, 4, 7,176,183, 3, 7, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 73, 2, 0, 0,226, 2, 0, 0, 3, 3,226, 0,
+154, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,121, 92, 2, 88,139, 9, 7, 24,238, 10, 7,232,136, 9, 7, 32,138, 9, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0,120, 86, 5, 7, 88, 87, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,232,136, 9, 7,191, 0, 0, 0,
+ 1, 0, 0, 0, 32,138, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0,
+ 0, 0, 98, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 66, 67,
+ 0, 0,200, 65, 0, 0, 66, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4,
+ 10, 0,226, 0, 26, 0,226, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+217, 3, 0, 0,186, 4, 0, 0, 73, 2, 0, 0, 98, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+226, 0, 26, 0, 11, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,122, 92, 2, 96,150, 25, 7,
+ 96,150, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0, 40, 89, 5, 7,176, 89, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+248, 0, 0, 0, 32,138, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,232,136, 9, 7, 0, 0, 0, 0, 0,128,131, 67,
+ 0, 0,228,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 67, 0, 0,220,194, 0, 0, 0, 0,209, 0, 0, 0,226, 0, 0, 0,
+ 18, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0,
+ 18, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 18, 0, 0, 0, 2, 0, 3, 3, 0, 0, 0, 4, 6, 0,226, 0,128, 0,209, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 99, 2, 0, 0,226, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0,128, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,192,121, 92, 2,200,170, 25, 7,200,170, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,152, 91, 5, 7,168, 92, 5, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 1, 0, 0, 88,139, 9, 7,162, 0, 0, 0, 1, 0, 0, 0,112,231, 10, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,125, 25, 7,176,125, 25, 7,
+216,143, 12, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 68, 65, 84, 65, 12, 0, 0, 0,216,143, 12, 7,214, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0,160,140, 9, 7,
+ 68, 65, 84, 65,156, 0, 0, 0,160,140, 9, 7,213, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,160, 33, 10, 7,
+ 19, 0, 0, 0, 1, 0, 1, 0,160, 33, 10, 7, 20, 0, 0, 0, 1, 0, 1, 0,160, 33, 10, 7, 21, 0, 1, 0, 1, 0, 1, 0,
+160, 33, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0, 64, 39, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0,224,195, 9, 7, 0, 0, 0, 0,
+ 1, 0, 1, 0, 48, 21, 12, 7, 0, 0, 0, 0, 1, 0, 1, 0, 48,203, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,224, 45, 10, 7,
+ 0, 0, 0, 0, 1, 0, 1, 0,136,199, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,208,240, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0,
+ 56,192, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,240,143, 9, 7, 68, 65, 84, 65,248, 0, 0, 0,128,141, 9, 7,191, 0, 0, 0,
+ 1, 0, 0, 0,184,142, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 55,
+ 0, 0, 67, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,137, 67,
+ 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4,
+ 10, 0,195, 0, 26, 0,195, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 4, 0, 0,247, 4, 0, 0, 69, 2, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+195, 0, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+248, 0, 0, 0,184,142, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128,141, 9, 7, 0, 0, 0, 0, 0, 0,150, 67,
+ 0,192,116,196, 0, 0, 0, 0, 0, 0, 0, 0,205, 85,150, 67,223,204, 35,196, 26, 85,207,195, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0,
+ 0, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64,
+ 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 4, 6, 0,195, 0,156, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 4, 0, 0,247, 4, 0, 0, 95, 2, 0, 0,250, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,112,231, 10, 7,158, 0, 0, 0, 1, 0, 0, 0, 24,238, 10, 7,
+ 88,139, 9, 7,128,141, 9, 7,184,142, 9, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,116,109,112, 47, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+248, 0, 0, 0,144,232, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,200,233, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68,
+ 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 1, 0, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,200,233, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+144,232, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0,
+ 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 4, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62,
- 6, 0, 0, 0, 16, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,173, 2, 95, 0,154,153,217, 63, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,235, 10, 7, 68, 65, 84, 65,216, 2, 0, 0, 0,235, 10, 7,
+152, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,
+226,215,163,188, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 32,193, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 32, 65, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
+184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0,
+ 98,127,249, 67,129,255, 71, 66, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 32,193, 0, 0,128, 63,103,212,136, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,
+184,175, 31, 65, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,176,191, 66, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-205,204, 28, 65, 0, 0, 0, 0, 32, 0, 0, 0,128, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,224, 1, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0,128, 7, 56, 4, 68, 65, 84, 65, 40, 0, 0, 0,
- 96,136, 91, 2, 0, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0,208,136, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 6, 3,227, 1,176,157, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,
-208,136, 91, 2, 0, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0, 64,137, 91, 2, 0, 0, 0, 0, 96,136, 91, 2, 0, 0, 0, 0,
- 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,228, 3, 33, 3, 16,163, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,
- 64,137, 91, 2, 0, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,136, 91, 2, 0, 0, 0, 0,
- 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 97, 3, 61, 3, 64,153, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 64, 1, 0, 0,
-176,137, 91, 2, 0, 0, 0, 0,142, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 1, 0, 1, 0,205,204, 76, 63, 0, 0,180, 66, 9, 0, 1, 0, 0, 0,128, 63,
-111, 18,131, 58,205,204,204, 61, 0, 0, 1, 0, 32, 0, 32, 0, 32, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
- 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 80, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0,100, 0, 10, 0, 0, 0,
- 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0,
- 50, 0, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 10,215, 35, 60,205,204,204, 61, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0,205,204,204, 61,205,204,204, 61,
-102,102,166, 63, 0, 0,192, 63, 0, 0,240, 65, 72,225,122, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
- 67, 2, 0, 3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 0, 0, 0, 48,139, 91, 2, 0, 0, 0, 0,
-129, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 32, 82,101,110,100,101,114,
- 76, 97,121,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255, 15, 0, 0, 0, 0, 0,255,127, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
- 67, 65, 0, 0,152, 0, 0, 0,208,139, 91, 2, 0, 0, 0, 0, 29, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 65, 67, 97,109,101,114, 97,
- 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 63,145,137, 68, 66,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66,
-161, 14,234, 64, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0,232, 1, 0, 0,176,140, 91, 2, 0, 0, 0, 0,
- 39, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63,247,255,239, 65, 0, 0,150, 66,154,153, 25, 62, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,
-224,142, 91, 2, 0, 0, 0, 0, 2, 0, 0, 0, 46, 26,128, 63, 25, 4,240, 65, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64,
- 64, 11, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
-111, 18,131, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,240, 0, 0, 0, 24,238, 10, 7,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,112,231, 10, 7,144,232, 10, 7,
+200,233, 10, 7, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0,
+ 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 83, 67, 0, 0, 92, 5, 0, 0,160, 33, 10, 7,150, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 83, 99,101,110,101, 0,116, 97,103,101, 0, 97,105,110, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,192, 9, 7, 64, 39, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+120,188, 2, 7, 48,241, 2, 7,120,188, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,192,144, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,224,142, 91, 2, 0, 0, 0, 0,
- 54, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 2, 0, 1, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,
-243, 4, 53,191,242, 4, 53, 63,242, 4, 53,191,243, 4, 53, 63, 96,144, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,239, 10, 7,152,230,101, 2, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0,100, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,
+224, 1, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 25, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 0, 0,
+ 24, 0, 17, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 23, 0, 33, 0, 0, 0,128, 0, 0, 0, 8, 0,
+ 24, 0, 10, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,231, 9, 7, 48,231, 9, 7, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0,128, 63, 0, 0,128, 63, 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 5, 0, 2, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 98, 97,
+ 99,107, 98,117,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 24, 0, 0, 0, 96,144, 91, 2, 0, 0, 0, 0, 52, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,192,144, 91, 2, 0, 0, 0, 0,
- 19, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 0, 0,216, 1, 0, 0, 48,145, 91, 2, 0, 0, 0, 0,
-123, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 62, 0, 0,128, 62, 0, 0,128, 62, 0, 0, 0, 0,205,204,204, 61,205,204,204, 61,205,204,204, 61, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0,205,204, 28, 65, 0, 0, 0, 0, 0, 0, 32, 0,128, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,112, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0,
- 0, 0,128, 63,205,204, 76, 61, 0, 0, 5, 0, 0, 0, 0, 0, 10,215,163, 59, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0,
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,116,109,112,
+ 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 84, 88, 0, 0,176, 0, 0, 0, 80,147, 91, 2, 0, 0, 0, 0, 27, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 84,101,120,116, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 64,148, 91, 2, 0, 0, 0, 0, 64,148, 91, 2, 0, 0, 0, 0,
- 64,148, 91, 2, 0, 0, 0, 0, 64,148, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,149, 91, 2, 0, 0, 0, 0,255,255,255,255, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 64,148, 91, 2, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,148, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0,176,148, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 1, 0, 79, 66, 0, 0, 40, 4, 0, 0, 64,153, 91, 2, 0, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0,176,157, 91, 2,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67, 97,
-109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,139, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 62, 6, 0, 0, 0, 16, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,173, 2, 95, 0,154,153,217, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+152, 24, 11, 7, 1, 0, 0, 0, 1, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204, 28, 65, 0, 0, 0, 0, 32, 0, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+128, 0, 5, 0, 60, 0, 5, 0, 1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,
+224, 1, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 5, 0,128, 7, 56, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 28, 0, 0, 0,120,188, 2, 7,
+128, 0, 0, 0, 1, 0, 0, 0,136,223, 2, 7, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,236, 1, 64, 1,
+224,195, 9, 7, 68, 65, 84, 65, 28, 0, 0, 0,136,223, 2, 7,128, 0, 0, 0, 1, 0, 0, 0, 48,241, 2, 7,120,188, 2, 7,
+ 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,121, 2, 10, 2,136,199, 9, 7, 68, 65, 84, 65, 28, 0, 0, 0, 48,241, 2, 7,
+128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,136,223, 2, 7, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 38, 2, 28, 2,
+ 56,192, 9, 7, 68, 65, 84, 65, 72, 1, 0, 0, 72,239, 10, 7,147, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 1, 0, 1, 0,205,204, 76, 63, 0, 0,180, 66, 9, 0, 1, 0, 0, 0,128, 63,111, 18,131, 58,
+205,204,204, 61, 0, 0, 1, 0, 32, 0, 32, 0, 32, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 80, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, 50, 0, 50, 0, 10, 0, 0, 0,
+ 50, 0,100, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0,
+ 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60,205,204,204, 61,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0,205,204,204, 61,205,204,204, 61,102,102,166, 63, 0, 0,192, 63, 0, 0,240, 65,
+ 72,225,122, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 67, 2, 0, 3, 2, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 72, 0, 0, 0, 48,231, 9, 7,133, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 32, 82,101,
+110,100,101,114, 76, 97,121,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255, 15, 0, 0, 0, 0, 0,255,127, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 67, 65, 0, 0,
+120, 0, 0, 0,240,143, 9, 7, 29, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 67, 65, 67, 97,109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 63,145,137, 68, 66,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66,
+161, 14,234, 64, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0,124, 1, 0, 0,208,240, 10, 7, 41, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63,247,255,239, 65, 0, 0,150, 66,154,153, 25, 62, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,144,242, 10, 7,
+ 2, 0, 0, 0, 46, 26,128, 63, 25, 4,240, 65, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64, 64, 11, 3, 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,111, 18,131, 58, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,110,101,239, 64,150, 62,208,192, 78,255,170, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 42,254,141, 63,192, 57, 49, 60, 34,159, 80, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222,149, 47, 63, 53, 70, 58, 63,
-222, 56, 49,188, 0, 0, 0, 0, 86,126,162,190,227,251,159, 62, 55, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63,149, 84, 28,191,
- 51,247,227, 62, 0, 0, 0, 0,110,101,239, 64,150, 62,208,192, 78,255,170, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 1, 0,128, 63, 1, 0,128, 51,
- 1, 0, 0,179, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0,128, 63, 1, 0,128, 51, 0, 0, 0, 0, 2, 0, 0,179, 2, 0, 0,167,
- 1, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 53, 1, 0, 0, 41, 1, 0,128,168, 0, 0,128, 63, 0, 0,128, 63,157,190,215, 49,
-167,170, 4, 52, 0, 0, 0,128,129,116,157,178, 1, 0,128, 63, 33, 69, 15, 51, 0, 0, 0,128, 73,254, 67, 51,243, 97,106, 49,
- 0, 0,128, 63, 0, 0, 0,128, 3, 0, 64, 52,183,164,157, 39, 0, 0,128, 53, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0,
- 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,187,225, 16, 63, 0, 0,128, 63,205,204,204, 62,237, 54, 32, 63,
- 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 4, 7, 68, 65, 84, 65, 8, 1, 0, 0,
+144,242, 10, 7, 64, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 2, 0, 1, 0, 0, 0,128, 67, 0, 0, 0, 0,
+ 0, 0,128, 63,243, 4, 53,191,242, 4, 53, 63,242, 4, 53,191,243, 4, 53, 63,112,236, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 79, 66, 0, 0, 40, 4, 0, 0,176,157, 91, 2, 0, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 16,163, 91, 2,
- 0, 0, 0, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67,117,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,112,236, 2, 7,
+ 62, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 32, 0, 0, 0, 0, 42, 4, 7, 19, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 0, 0,104, 1, 0, 0, 64, 39, 10, 7,
+127, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 87,111,114,108,100, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0,128, 62, 0, 0,128, 62, 0, 0, 0, 0,205,204,204, 61,205,204,204, 61,
+205,204,204, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,205,204, 28, 65, 0, 0, 0, 0, 0, 0, 32, 0,128, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,112, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 32, 65, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 61, 0, 0, 5, 0, 0, 0, 0, 0, 10,215,163, 59, 0, 0, 0, 0,
+ 0, 0,128, 62, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 0, 0,120, 0, 0, 0,232, 40, 10, 7, 27, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 84,101,120,116, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 1, 0, 0, 0, 96,142, 2, 7, 96,142, 2, 7, 96,142, 2, 7, 96,142, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,160, 41, 10, 7,255,255,255,255, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0, 96,142, 2, 7, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,248, 11, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0,104,248, 11, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
+ 79, 66, 0, 0,100, 3, 0, 0, 56,192, 9, 7,118, 0, 0, 0, 1, 0, 0, 0,224,195, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 79, 66, 67, 97,109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,143, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,101,239, 64,150, 62,208,192, 78,255,170, 64,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42,254,141, 63,192, 57, 49, 60, 34,159, 80, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,222,149, 47, 63, 53, 70, 58, 63,222, 56, 49,188, 0, 0, 0, 0, 86,126,162,190,227,251,159, 62,
+ 55, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63,149, 84, 28,191, 51,247,227, 62, 0, 0, 0, 0,110,101,239, 64,150, 62,208,192,
+ 78,255,170, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,125,103,133, 51,176,219,194,178, 0, 0, 0, 0,190, 32, 66, 51, 1, 0,128, 63,
+168,200,153, 51, 0, 0, 0, 0, 32,206, 18,179,126,126,149, 50, 1, 0,128, 63, 0, 0, 0, 0,241,251,133, 52,172,182, 27,180,
+174,236,252, 51, 0, 0,128, 63, 0, 0,128, 63,157,190,215, 49,167,170, 4, 52, 0, 0, 0,128,129,116,157,178, 1, 0,128, 63,
+ 33, 69, 15, 51, 0, 0, 0,128, 73,254, 67, 51,243, 97,106, 49, 0, 0,128, 63, 0, 0, 0,128, 3, 0, 64, 52,183,164,157, 39,
+ 0, 0,128, 53, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 79, 66, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,
+187,225, 16, 63, 0, 0,128, 63,205,204,204, 62,237, 54, 32, 63, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0,100, 3, 0, 0,
+224,195, 9, 7,118, 0, 0, 0, 1, 0, 0, 0,136,199, 9, 7, 56,192, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67,117,
98,101, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,193,181, 2, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,173, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,162, 91, 2, 0, 0, 0, 0,112,162, 91, 2, 0, 0, 0, 0, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,222,149, 47, 63, 52, 70, 58, 63,
-179, 56, 49,188, 0, 0, 0,128, 86,126,162,190,227,251,159, 62, 56, 53,101, 63, 0, 0, 0,128, 7,165, 39, 63,149, 84, 28,191,
- 50,247,227, 62, 0, 0, 0,128,110,101,239, 64,151, 62,208,192, 77,255,170, 64, 0, 0,128, 63, 1, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 79, 66, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,169, 19,208, 60, 0, 0,128, 63,205,204,204, 62,229,208, 34, 62,
- 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,204,180, 2, 0, 0, 0, 0,160,185,181, 2,
- 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 8, 0, 0, 0,192,162, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,112,162, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 79, 66, 0, 0, 40, 4, 0, 0, 16,163, 91, 2, 0, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-176,157, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,140, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-154,112,130, 64,183,178,128, 63,112,236,188, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,229,123, 38, 63,
- 87, 43, 98, 61,229,229,238, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,236,148,190, 25,134,116, 63,236, 13, 98,189,
- 0, 0, 0, 0,221,102, 69,191, 57,174, 76,190, 34,194, 26, 63, 0, 0, 0, 0, 37,255, 16, 63,241,161, 95, 62,164,111, 75, 63,
- 0, 0, 0, 0,154,112,130, 64,183,178,128, 63,112,236,188, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,149, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 48, 21, 12, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,127, 10, 7,
+168,144, 9, 7, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 1, 0,128, 50, 0, 0, 0,179,
- 0, 0, 0, 0, 1, 0,128, 50, 1, 0,128, 63, 1, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 1, 0, 0, 39, 1, 0, 0, 52, 1, 0,128, 39, 0, 0,128, 63, 53,236,148,190,222,102, 69,191, 37,255, 16, 63,
- 0, 0, 0,128, 24,134,116, 63, 57,174, 76,190,240,161, 95, 62, 0, 0, 0,128,235, 13, 98,189, 34,194, 26, 63,166,111, 75, 63,
- 0, 0, 0,128,208, 19, 13, 63,234, 65,102,190, 10, 10,231,192, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
- 5, 0, 1, 0, 0, 0, 68, 0, 79, 66, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0,
- 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,169, 19,208, 60, 0, 0,128, 63,205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0,
-143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 77, 65, 0, 0,224, 2, 0, 0,128,167, 91, 2, 0, 0, 0, 0, 41, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 77, 97,116,101,114,105,
- 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 2, 0, 2, 0, 50, 0, 0, 6, 0, 0,128, 63, 0, 0,128, 63, 18, 0, 18, 0, 10,215,163, 59, 10,215,163, 59,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 3, 3, 0, 1, 3, 1, 0, 4, 0, 12, 0, 4, 0, 0, 0, 0, 63,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 63, 0, 0,128, 64, 0, 0, 0, 63,205,204,204, 61, 0, 0, 0, 63,205,204,204, 61,205,204,204, 61,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,128, 63, 0, 0,128, 63,160,170, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112,171, 91, 2, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 63,
-205,204, 76, 63,205,204, 76, 63,205,204, 76, 61,205,204,204, 61,102,102,166, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,144, 0, 0, 0,
-160,170, 91, 2, 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-224,171, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+222,149, 47, 63, 52, 70, 58, 63,179, 56, 49,188, 0, 0, 0,128, 86,126,162,190,227,251,159, 62, 56, 53,101, 63, 0, 0, 0,128,
+ 7,165, 39, 63,149, 84, 28,191, 50,247,227, 62, 0, 0, 0,128,110,101,239, 64,151, 62,208,192, 77,255,170, 64, 0, 0,128, 63,
+ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 79, 66, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,169, 19,208, 60, 0, 0,128, 63,
+205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,120,137, 25, 7,152,143, 25, 7, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,224,127, 10, 7, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,168,144, 9, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 79, 66, 0, 0,100, 3, 0, 0,136,199, 9, 7,118, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,224,195, 9, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 79, 66, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,240, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154,112,130, 64,183,178,128, 63,112,236,188, 64,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,229,123, 38, 63, 87, 43, 98, 61,229,229,238, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54,236,148,190, 25,134,116, 63,236, 13, 98,189, 0, 0, 0, 0,221,102, 69,191, 57,174, 76,190,
+ 34,194, 26, 63, 0, 0, 0, 0, 37,255, 16, 63,241,161, 95, 62,164,111, 75, 63, 0, 0, 0, 0,154,112,130, 64,183,178,128, 63,
+112,236,188, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 35,233,134, 49,251,110, 17,179, 0, 0, 0, 0, 49,158,141, 50, 1, 0,128, 63,
+126,214,237, 50, 0, 0, 0, 0,155,248, 28,178,199,139, 96,177,254,255,127, 63, 0, 0, 0, 0, 80,136,159,178,192, 4,158,178,
+209,114,143,179, 0, 0,128, 63, 53,236,148,190,222,102, 69,191, 37,255, 16, 63, 0, 0, 0,128, 24,134,116, 63, 57,174, 76,190,
+240,161, 95, 62, 0, 0, 0,128,235, 13, 98,189, 34,194, 26, 63,166,111, 75, 63, 0, 0, 0,128,208, 19, 13, 63,234, 65,102,190,
+ 10, 10,231,192, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 68, 0, 79, 66, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,
+169, 19,208, 60, 0, 0,128, 63,205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 0, 0,184, 2, 0, 0,
+ 48,203, 9, 7, 44, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 77, 97,
+116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 10,215, 35, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+205,204, 76, 62,205,204, 76, 62, 0, 0, 8, 0, 1, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,160, 63, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 2, 0, 2, 0, 50, 0, 0, 6,
+ 0, 0,128, 63, 0, 0,128, 63, 18, 0, 18, 0, 10,215,163, 59, 10,215,163, 59, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 67, 0, 0, 3, 3, 0, 1, 3, 1, 0, 4, 0, 12, 0, 4, 0, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0,128, 64,
+ 0, 0, 0, 63,205,204,204, 61, 0, 0, 0, 63,205,204,204, 61,205,204,204, 61, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 40,206, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 56,144, 2, 7, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63,205,204, 76, 61,
+205,204,204, 61,102,102,166, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,144, 0, 0, 0, 40,206, 9, 7, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,224, 45, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0,128, 63,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0,
- 68, 65, 84, 65, 40, 0, 0, 0,112,171, 91, 2, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 84, 69, 0, 0, 88, 1, 0, 0,224,171, 91, 2, 0, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 84,101,120, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0,128, 63,
+205,204, 76, 62, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,144, 2, 7, 19, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 0, 0,
+ 40, 1, 0, 0,224, 45, 10, 7, 39, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 84, 69, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0,160, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 64, 0, 0, 0, 0, 2, 0, 0, 0,
@@ -761,93 +860,83 @@ char datatoc_B_blend[]= {
8, 0, 0, 0, 1, 0, 1, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
205,204,204, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 24, 1, 0, 0,
+ 48, 21, 12, 7, 54, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117,
+ 98,101, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,131, 2, 7, 80, 27, 12, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0,248,206, 9, 7, 72, 47, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,136, 22, 12, 7, 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 24, 12, 7,
+ 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 25, 12, 7, 1, 0, 0, 0, 5, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,128, 51, 0, 0, 0,180, 0, 0, 0, 0, 4, 0,128, 63, 4, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 30, 0, 4, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 80,131, 2, 7, 0, 0, 0, 0, 1, 0, 0, 0, 48,203, 9, 7, 68, 65, 84, 65,
+ 84, 1, 0, 0,136, 22, 12, 7, 67, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0,144, 1, 0, 0,128,173, 91, 2, 0, 0, 0, 0,
- 51, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117, 98,101, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,182, 91, 2, 0, 0, 0, 0,
- 48,182, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,177, 91, 2, 0, 0, 0, 0,
-176,179, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,175, 91, 2, 0, 0, 0, 0,
- 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,178, 91, 2, 0, 0, 0, 0,
- 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,180, 91, 2, 0, 0, 0, 0,
- 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,128, 51, 0, 0, 0,180, 0, 0, 0, 0, 4, 0,128, 63,
- 4, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 30, 0, 4, 0,
- 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 8, 0, 0, 0,
-240,182, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128,167, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,104, 1, 0, 0,
- 80,175, 91, 2, 0, 0, 0, 0, 57, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,177, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,206, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,192, 0, 0, 0,
- 0,177, 91, 2, 0, 0, 0, 0, 57, 0, 0, 0, 8, 0, 0, 0, 0, 0,128, 63,255,255,127, 63, 0, 0,128,191,230, 73,230, 73,
- 26,182,255, 0, 3, 0, 0, 0, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182, 26,182,255, 0, 3, 0, 0, 0,
- 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182,255, 0, 3, 0, 0, 0,250,255,127,191, 3, 0,128, 63,
- 0, 0,128,191, 26,182,230, 73, 26,182,255, 0, 3, 0, 0, 0, 4, 0,128, 63,247,255,127, 63, 0, 0,128, 63,230, 73,230, 73,
-230, 73,255, 0, 3, 0, 0, 0,245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,230, 73,255, 0, 3, 0, 0, 0,
- 3, 0,128,191,250,255,127,191, 0, 0,128, 63, 26,182, 26,182,230, 73,255, 0, 3, 0, 0, 0,255,255,127,191, 0, 0,128, 63,
- 0, 0,128, 63, 26,182,230, 73,230, 73,255, 0, 3, 0, 0, 0, 68, 65, 84, 65,104, 1, 0, 0, 0,178, 91, 2, 0, 0, 0, 0,
- 57, 1, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,176,179, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,192, 0, 0, 0,248,206, 9, 7, 60, 0, 0, 0, 8, 0, 0, 0, 0, 0,128, 63,255,255,127, 63,
+ 0, 0,128,191,230, 73,230, 73, 26,182,255,127, 1, 0, 0, 0, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182,
+ 26,182,255,127, 1, 0, 0, 0, 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182,255,127, 1, 0, 0, 0,
+250,255,127,191, 3, 0,128, 63, 0, 0,128,191, 26,182,230, 73, 26,182,255,127, 1, 0, 0, 0, 4, 0,128, 63,247,255,127, 63,
+ 0, 0,128, 63,230, 73,230, 73,230, 73,255,127, 1, 0, 0, 0,245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,
+230, 73,255,127, 1, 0, 0, 0, 3, 0,128,191,250,255,127,191, 0, 0,128, 63, 26,182, 26,182,230, 73,255,127, 1, 0, 0, 0,
+255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73,230, 73,255,127, 1, 0, 0, 0, 68, 65, 84, 65, 84, 1, 0, 0,
+ 32, 24, 12, 7, 67, 1, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 47, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,144, 0, 0, 0,176,179, 91, 2, 0, 0, 0, 0,
- 54, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0,
- 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0, 5, 0, 0, 0,
- 0, 0, 35, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0,
- 7, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0,
- 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65,104, 1, 0, 0,
-128,180, 91, 2, 0, 0, 0, 0, 57, 1, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,182, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,144, 0, 0, 0, 72, 47, 10, 7, 57, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 35, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 35, 0, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0,
+ 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 35, 0, 68, 65, 84, 65, 84, 1, 0, 0,184, 25, 12, 7, 67, 1, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 27, 12, 7, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,120, 0, 0, 0,
- 48,182, 91, 2, 0, 0, 0, 0, 53, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0,
- 0, 0, 0, 2, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0,
- 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2,
- 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
- 7, 0, 0, 0, 0, 0, 0, 2, 85, 83, 69, 82, 64, 11, 0, 0, 32, 94,154, 1, 0, 0, 0, 0,178, 0, 0, 0, 1, 0, 0, 0,
- 33,152, 1, 0, 63, 2, 0, 0, 5, 0, 0, 0, 47,116,109,112, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,120, 0, 0, 0, 80, 27, 12, 7, 56, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0,
+ 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 2, 85, 83, 69, 82, 56, 11, 0, 0,
+ 0, 2, 68, 1,185, 0, 0, 0, 1, 0, 0, 0, 33,152, 1, 0, 63, 2, 0, 0, 5, 0, 0, 0, 47,116,109,112, 47, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 85,115,101,114,115, 47,116,111,110, 47, 68,101,115,107,116,111,112,
- 47, 0, 45,112,111,119,101,114,112, 99, 47, 98,105,110, 47, 98,108,101,110,100,101,114, 46, 97,112,112, 47, 67,111,110,116,101,
-110,116,115, 47, 82,101,115,111,117,114, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 85,115,101,114,115,
+ 47,116,111,110, 47, 68,101,115,107,116,111,112, 47, 0, 45,112,111,119,101,114,112, 99, 47, 98,105,110, 47, 98,108,101,110,100,
+101,114, 46, 97,112,112, 47, 67,111,110,116,101,110,116,115, 47, 82,101,115,111,117,114, 99,101, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -865,9 +954,9 @@ char datatoc_B_blend[]= {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -875,1002 +964,1047 @@ char datatoc_B_blend[]= {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 48, 52, 6, 0, 0, 0, 0, 0,
- 0, 0, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0,192,194, 91, 2, 0, 0, 0, 0,
-192,215, 91, 2, 0, 0, 0, 0,240,195,100, 2, 0, 0, 0, 0,240,195,100, 2, 0, 0, 0, 0, 80, 51,101, 2, 0, 0, 0, 0,
- 80, 51,101, 2, 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 2, 0, 25, 0, 0, 0, 20, 0, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0,
-205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 30, 90,100,191,154,153,153, 62,102,102,102, 63, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 31,250,254, 62, 9, 0, 0, 63,
-156,153, 25, 63, 0, 0, 0, 0,205,204, 76, 62,205,204, 76, 62,205,204, 76, 62, 0, 0,128, 63, 44,135, 22, 63, 32,133,235, 62,
-184,243,125, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 73, 76, 63, 42,135, 86, 63, 0, 0,128, 63, 0, 0, 0, 0,
- 1, 43,135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 16, 47, 93, 62, 58,180,200,190, 24, 47, 93,190, 0, 0, 0, 0,
- 14, 0, 0, 0, 25, 0, 15, 0,120, 0, 60, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, 6, 0, 15, 0,
- 8, 0, 10, 0,250, 0, 0, 0,100, 0,100, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
- 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,
- 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65,192, 20, 0, 0,192,194, 91, 2, 0, 0, 0, 0,176, 0, 0, 0, 1, 0, 0, 0,192,215, 91, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68,101,102, 97,117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255,
- 1, 0, 25, 0,231,255, 0, 0, 25, 25, 25,255,153,153,153,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255,
- 1, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0,255, 70, 70, 70,255, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255,
- 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255, 0, 0, 0,255,255,255,255,255,
- 1, 0, 15, 0,241,255, 0, 0, 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,180,180,180,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255,
- 1, 0,236,255, 0, 0, 0, 0, 25, 25, 25,255,180,180,180,255,153,153,153,255,128,128,128,255, 0, 0, 0,255,255,255,255,255,
- 1, 0,236,255, 0, 0, 0, 0, 0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255,255,255,255,255,204,204,204,255,
- 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0,255, 63, 63, 63,255, 86,128,194,255,255,255,255,255, 0, 0, 0,255, 0, 0, 0,255,
- 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, 25, 25, 25,230, 45, 45, 45,230,100,100,100,255,160,160,160,255,255,255,255,255,
- 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255,
- 0, 0, 38, 0, 0, 0, 0, 0, 25, 25, 25,255,128,128,128,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50,180, 80, 80, 80,180,100,100,100,180,128,128,128,255, 0, 0, 0,255,255,255,255,255,
- 1, 0, 5, 0,251,255, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255,
- 0, 0, 0, 0, 0, 0, 0, 0,115,190, 76,255, 90,166, 51,255,240,235,100,255,215,211, 75,255,180, 0,255,255,153, 0,230,255,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,130,130,130,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100,
- 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90,255, 0, 0, 0, 0,
-250,250,250,255, 15, 15, 15,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,180,180,180,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100,255,140, 25,255,250,250,250,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,130,130,130,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250,250,250,255,250,250,250,255,250,250,250,255,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100,
- 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 79,101, 73,255,135,177,125,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,173,173,173,255,127,112,112,100,
- 0, 0, 0, 0, 91, 91, 91,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,255,140, 25,255, 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255,
- 3, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100,
- 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 79,101, 73,255,135,177,125,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255,
- 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0,116,116,116,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81,105,135,255,109, 88,129,255, 78,152, 62,255,
- 46,143,143,255,169, 84,124,255,126,126, 80,255,162, 95,111,255,109,145,131,255,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100,
- 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
-255,255,255, 10,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,110,110,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,132,132,132,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255, 94, 94, 94,255,172,172,172,255, 17, 27, 60,100, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,195,195,195,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,153,153,153,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,
-255, 0, 0,255, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,100, 0, 0,255, 0, 0,200,255,128, 0, 80,255, 95, 95, 0,255,
- 0,100, 50,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,173,173,173,255,127,112,112,100,
- 0, 0, 0, 0, 91, 91, 91,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, 0, 0, 0, 0,
- 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255,
- 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,
-255,255,255,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,
-200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,
-150,150,150,255,129,131,144,255,127,127,127,255,142,138,145,255,120,145,120,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,100,100,100,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255,
- 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100,
- 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,
-255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,
- 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0,255,189, 17, 17,255,
-247, 10, 10,255, 0, 0, 0, 0,247, 64, 24,255,246,105, 19,255,250,153, 0,255, 0, 0, 0, 0, 30,145, 9,255, 89,183, 11,255,
-131,239, 29,255, 0, 0, 0, 0, 10, 54,148,255, 54,103,223,255, 94,193,239,255, 0, 0, 0, 0,169, 41, 78,255,193, 65,106,255,
-240, 93,145,255, 0, 0, 0, 0, 67, 12,120,255, 84, 58,163,255,135,100,213,255, 0, 0, 0, 0, 36,120, 90,255, 60,149,121,255,
-111,182,171,255, 0, 0, 0, 0, 75,112,124,255,106,134,145,255,155,194,205,255, 0, 0, 0, 0,244,201, 12,255,238,194, 54,255,
-243,255, 0,255, 0, 0, 0, 0, 30, 32, 36,255, 72, 76, 86,255,255,255,255,255, 0, 0, 0, 0,111, 47,106,255,152, 69,190,255,
-211, 48,214,255, 0, 0, 0, 0,108,142, 34,255,127,176, 34,255,187,239, 91,255, 0, 0, 0, 0,141,141,141,255,176,176,176,255,
-222,222,222,255, 0, 0, 0, 0,131, 67, 38,255,139, 88, 17,255,189,106, 17,255, 0, 0, 0, 0, 8, 49, 14,255, 28, 67, 11,255,
- 52, 98, 43,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,192, 20, 0, 0,
-192,215, 91, 2, 0, 0, 0, 0,176, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,194, 91, 2, 0, 0, 0, 0,
- 82,111,117,110,100,101,100, 0, 0,101,119, 32, 85,115,101,114, 32, 84,104,101,109,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 48, 52, 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 8, 0, 0, 2, 0, 0, 0, 68,172, 0, 0, 36, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0,168, 3, 10, 7, 40,207, 13, 7, 48, 93, 5, 7,
+ 48, 93, 5, 7,128, 94, 5, 7,128, 94, 5, 7, 32, 0, 0, 0, 1, 0, 2, 0, 25, 0, 0, 0, 20, 0, 20, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 30, 90,100,191,154,153,153, 62,102,102,102, 63, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 31,250,254, 62,
+ 9, 0, 0, 63,156,153, 25, 63, 0, 0, 0, 0,205,204, 76, 62,205,204, 76, 62,205,204, 76, 62, 0, 0,128, 63, 44,135, 22, 63,
+ 32,133,235, 62,184,243,125, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 73, 76, 63, 42,135, 86, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 43,135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 16, 47, 93, 62, 58,180,200,190, 24, 47, 93,190,
+ 0, 0, 0, 0, 14, 0, 0, 0, 25, 0, 15, 0,120, 0, 60, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0,
+ 6, 0, 15, 0, 8, 0, 10, 0,250, 0, 0, 0,100, 0,100, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,200, 21, 0, 0,168, 3, 10, 7,183, 0, 0, 0, 1, 0, 0, 0, 40,207, 13, 7, 0, 0, 0, 0,
+ 68,101,102, 97,117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0,
- 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 1, 0, 25, 0,231,255, 0, 0,
+ 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 1, 0, 15, 0,241,255, 0, 0,
25, 25, 25,255,153,153,153,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255, 1, 0, 0, 0, 25, 0, 0, 0,
0, 0, 0,255, 70, 70, 70,255, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 1, 0, 15, 0,241,255, 0, 0,
0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255, 0, 0, 0,255,255,255,255,255, 1, 0, 15, 0,241,255, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0,
25, 25, 25,255,180,180,180,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255, 1, 0,236,255, 0, 0, 0, 0,
25, 25, 25,255,180,180,180,255,153,153,153,255,128,128,128,255, 0, 0, 0,255,255,255,255,255, 1, 0,236,255, 0, 0, 0, 0,
0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255,255,255,255,255,204,204,204,255, 1, 0, 15, 0,241,255, 0, 0,
0, 0, 0,255, 63, 63, 63,255, 86,128,194,255,255,255,255,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0,
- 0, 0, 0,255, 25, 25, 25,230, 46,124,217,204,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0,
+ 0, 0, 0,255, 25, 25, 25,230, 45, 45, 45,230,100,100,100,255,160,160,160,255,255,255,255,255, 0, 0, 25, 0,236,255, 0, 0,
0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 38, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,175,175,175, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
- 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255,
- 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,
-255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,
-255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
+ 25, 25, 25,255,128,128,128,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 50, 50, 50,180, 80, 80, 80,180,100,100,100,180,128,128,128,255, 0, 0, 0,255,255,255,255,255, 1, 0, 5, 0,251,255, 0, 0,
+ 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0,
+115,190, 76,255, 90,166, 51,255,240,235,100,255,215,211, 75,255,180, 0,255,255,153, 0,230,255, 0, 0, 0, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,130,130,130,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 57, 57, 57,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90,255, 0, 0, 0, 0,250,250,250,255, 15, 15, 15,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,180,180,180,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100,255,140, 25,255,250,250,250,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,130,130,130,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250,250,250,255,250,250,250,255,250,250,250,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 82, 96,110,255,
+124,137,150,255, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
+ 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,173,173,173,255,127,112,112,100, 0, 0, 0, 0, 91, 91, 91,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-160,160,160,100,127,112,112,100,255,130, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-107,107,107,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,100,143,143,143,100, 96,192, 64,255, 94, 94, 94,255,
- 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255,255,255,255,255,255,255,255,255,
-255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 82, 96,110,255,
-124,137,150,255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-255,255,255,255,255,130, 0,255, 2, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-158,158,158,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255,
- 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,
-255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 79,101, 73,255,135,177,125,255,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,143,143,143,255,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-228,156,198,204,255,255,170,204, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,143,143,143,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255,
- 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,
-255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,255,255,255,170,255, 96,192, 64,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0,
+107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,
+124,137,150,255, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
+ 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0,116,116,116,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81,105,135,255,109, 88,129,255, 78,152, 62,255, 46,143,143,255,169, 84,124,255,
-126,126, 80,255,162, 95,111,255,109,145,131,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 53, 53,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255,
- 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,
-255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,
-255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+126,126, 80,255,162, 95,111,255,109,145,131,255,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 53, 53,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,255,255,255, 10,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-143,143,143,255,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-153,153,153,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,153,153,153,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 88, 88, 88,255,
- 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,
-255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 0, 0,100, 0, 0,255, 0, 0,200,255,128, 0, 80,255, 95, 95, 0,255, 0,100, 50,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-158,158,158,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255,
- 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,
-255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
-107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,
- 0, 0, 0, 0, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,110,110,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,132,132,132,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+ 94, 94, 94,255,172,172,172,255, 17, 27, 60,100, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,195,195,195,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+153,153,153,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 64, 64, 64,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 4, 0, 0,100, 0, 0,255, 0, 0,200,255,128, 0, 80,255, 95, 95, 0,255, 0,100, 50,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,173,173,173,255,127,112,112,100, 0, 0, 0, 0, 91, 91, 91,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,255,255,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255,
127,127,127,255,142,138,145,255,120,145,120,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-100,100,100,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
-145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
- 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255,
- 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,
-255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,
-255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+100,100,100,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255,
+ 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,
+255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,
+255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0,
0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0,255,189, 17, 17,255,247, 10, 10,255, 0, 0, 0, 0,
-247, 64, 24,255,246,105, 19,255,250,153, 0,255, 0, 0, 0, 0, 30,145, 9,255, 89,183, 11,255,131,239, 29,255, 0, 0, 0, 0,
- 10, 54,148,255, 54,103,223,255, 94,193,239,255, 0, 0, 0, 0,169, 41, 78,255,193, 65,106,255,240, 93,145,255, 0, 0, 0, 0,
- 67, 12,120,255, 84, 58,163,255,135,100,213,255, 0, 0, 0, 0, 36,120, 90,255, 60,149,121,255,111,182,171,255, 0, 0, 0, 0,
- 75,112,124,255,106,134,145,255,155,194,205,255, 0, 0, 0, 0,244,201, 12,255,238,194, 54,255,243,255, 0,255, 0, 0, 0, 0,
- 30, 32, 36,255, 72, 76, 86,255,255,255,255,255, 0, 0, 0, 0,111, 47,106,255,152, 69,190,255,211, 48,214,255, 0, 0, 0, 0,
-108,142, 34,255,127,176, 34,255,187,239, 91,255, 0, 0, 0, 0,141,141,141,255,176,176,176,255,222,222,222,255, 0, 0, 0, 0,
-131, 67, 38,255,139, 88, 17,255,189,106, 17,255, 0, 0, 0, 0, 8, 49, 14,255, 28, 67, 11,255, 52, 98, 43,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 78, 65, 49,224,211, 0, 0, 96,169,184, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, 78, 65, 77, 69,102, 10, 0, 0, 42,110,101,120,116, 0, 42,112,114,101,118, 0,
- 42,100, 97,116, 97, 0, 42,102,105,114,115,116, 0, 42,108, 97,115,116, 0,120, 0,121, 0,122, 0,119, 0,120,109,105,110, 0,
-120,109, 97,120, 0,121,109,105,110, 0,121,109, 97,120, 0, 42,112,111,105,110,116,101,114, 0,103,114,111,117,112, 0,118, 97,
-108, 0,118, 97,108, 50, 0,116,121,112,101, 0,115,117, 98,116,121,112,101, 0,102,108, 97,103, 0,110, 97,109,101, 91, 51, 50,
- 93, 0,115, 97,118,101,100, 0,100, 97,116, 97, 0,108,101,110, 0,116,111,116, 97,108,108,101,110, 0, 42,110,101,119,105,100,
- 0, 42,108,105, 98, 0,110, 97,109,101, 91, 50, 52, 93, 0,117,115, 0,105, 99,111,110, 95,105,100, 0, 42,112,114,111,112,101,
-114,116,105,101,115, 0,105,100, 0, 42,105,100, 98,108,111, 99,107, 0, 42,102,105,108,101,100, 97,116, 97, 0,110, 97,109,101,
- 91, 50, 52, 48, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 52, 48, 93, 0,116,111,116, 0,112, 97,100, 0, 42,112, 97,114,
-101,110,116, 0,119, 91, 50, 93, 0,104, 91, 50, 93, 0, 99,104, 97,110,103,101,100, 91, 50, 93, 0,112, 97,100, 48, 0,112, 97,
-100, 49, 0, 42,114,101, 99,116, 91, 50, 93, 0, 42,111, 98, 0, 98,108,111, 99,107,116,121,112,101, 0, 97,100,114, 99,111,100,
-101, 0,110, 97,109,101, 91, 49, 50, 56, 93, 0, 42, 98,112, 0, 42, 98,101,122,116, 0,109, 97,120,114, 99,116, 0,116,111,116,
-114, 99,116, 0,118, 97,114,116,121,112,101, 0,116,111,116,118,101,114,116, 0,105,112,111, 0,101,120,116,114, 97,112, 0,114,
-116, 0, 98,105,116,109, 97,115,107, 0,115,108,105,100,101, 95,109,105,110, 0,115,108,105,100,101, 95,109, 97,120, 0, 99,117,
-114,118, 97,108, 0, 42,100,114,105,118,101,114, 0, 99,117,114,118,101, 0, 99,117,114, 0,115,104,111,119,107,101,121, 0,109,
-117,116,101,105,112,111, 0,112,111,115, 0,114,101,108, 97,116,105,118,101, 0,116,111,116,101,108,101,109, 0,112, 97,100, 50,
- 0, 42,119,101,105,103,104,116,115, 0,118,103,114,111,117,112, 91, 51, 50, 93, 0,115,108,105,100,101,114,109,105,110, 0,115,
-108,105,100,101,114,109, 97,120, 0, 42, 97,100,116, 0, 42,114,101,102,107,101,121, 0,101,108,101,109,115,116,114, 91, 51, 50,
- 93, 0,101,108,101,109,115,105,122,101, 0, 98,108,111, 99,107, 0, 42,105,112,111, 0, 42,102,114,111,109, 0,116,111,116,107,
-101,121, 0,115,108,117,114,112,104, 0, 42,108,105,110,101, 0, 42,102,111,114,109, 97,116, 0, 98,108,101,110, 0,108,105,110,
-101,110,111, 0,115,116, 97,114,116, 0,101,110,100, 0,102,108, 97,103,115, 0, 99,111,108,111,114, 91, 52, 93, 0,112, 97,100,
- 91, 52, 93, 0, 42,110, 97,109,101, 0,110,108,105,110,101,115, 0,108,105,110,101,115, 0, 42, 99,117,114,108, 0, 42,115,101,
-108,108, 0, 99,117,114, 99, 0,115,101,108, 99, 0,109, 97,114,107,101,114,115, 0, 42,117,110,100,111, 95, 98,117,102, 0,117,
-110,100,111, 95,112,111,115, 0,117,110,100,111, 95,108,101,110, 0, 42, 99,111,109,112,105,108,101,100, 0,109,116,105,109,101,
- 0,115,105,122,101, 0,115,101,101,107, 0,112, 97,115,115,101,112, 97,114,116, 97,108,112,104, 97, 0, 97,110,103,108,101, 0,
- 99,108,105,112,115,116, 97, 0, 99,108,105,112,101,110,100, 0,108,101,110,115, 0,111,114,116,104,111, 95,115, 99, 97,108,101,
- 0,100,114, 97,119,115,105,122,101, 0,115,104,105,102,116,120, 0,115,104,105,102,116,121, 0, 89, 70, 95,100,111,102,100,105,
-115,116, 0, 89, 70, 95, 97,112,101,114,116,117,114,101, 0, 89, 70, 95, 98,107,104,116,121,112,101, 0, 89, 70, 95, 98,107,104,
- 98,105, 97,115, 0, 89, 70, 95, 98,107,104,114,111,116, 0, 42,100,111,102, 95,111, 98, 0,102,114, 97,109,101,110,114, 0,102,
-114, 97,109,101,115, 0,111,102,102,115,101,116, 0,115,102,114, 97, 0,102,105,101, 95,105,109, 97, 0, 99,121, 99,108, 0,111,
-107, 0,109,117,108,116,105, 95,105,110,100,101,120, 0,108, 97,121,101,114, 0,112, 97,115,115, 0,109,101,110,117,110,114, 0,
- 42,115, 99,101,110,101, 0,105, 98,117,102,115, 0, 42,103,112,117,116,101,120,116,117,114,101, 0, 42, 97,110,105,109, 0, 42,
-114,114, 0,115,111,117,114, 99,101, 0,108, 97,115,116,102,114, 97,109,101, 0,116,112, 97,103,101,102,108, 97,103, 0,116,111,
-116, 98,105,110,100, 0,120,114,101,112, 0,121,114,101,112, 0,116,119,115,116, 97, 0,116,119,101,110,100, 0, 98,105,110,100,
- 99,111,100,101, 0, 42,114,101,112, 98,105,110,100, 0, 42,112, 97, 99,107,101,100,102,105,108,101, 0, 42,112,114,101,118,105,
-101,119, 0, 42,114,101,110,100,101,114, 95,116,101,120,116, 0,108, 97,115,116,117,112,100, 97,116,101, 0,108, 97,115,116,117,
-115,101,100, 0, 97,110,105,109,115,112,101,101,100, 0,103,101,110, 95,120, 0,103,101,110, 95,121, 0,103,101,110, 95,116,121,
-112,101, 0, 97,115,112,120, 0, 97,115,112,121, 0,116,101,120, 99,111, 0,109, 97,112,116,111, 0,109, 97,112,116,111,110,101,
-103, 0, 98,108,101,110,100,116,121,112,101, 0, 42,111, 98,106,101, 99,116, 0, 42,116,101,120, 0,117,118,110, 97,109,101, 91,
- 51, 50, 93, 0,112,114,111,106,120, 0,112,114,111,106,121, 0,112,114,111,106,122, 0,109, 97,112,112,105,110,103, 0,111,102,
-115, 91, 51, 93, 0,115,105,122,101, 91, 51, 93, 0,116,101,120,102,108, 97,103, 0, 99,111,108,111,114,109,111,100,101,108, 0,
-112,109, 97,112,116,111, 0,112,109, 97,112,116,111,110,101,103, 0,110,111,114,109, 97,112,115,112, 97, 99,101, 0,119,104,105,
- 99,104, 95,111,117,116,112,117,116, 0,112, 97,100, 91, 50, 93, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114,
- 0, 99,111,108,102, 97, 99, 0,110,111,114,102, 97, 99, 0,118, 97,114,102, 97, 99, 0,100,105,115,112,102, 97, 99, 0,119, 97,
-114,112,102, 97, 99, 0,110, 97,109,101, 91, 49, 54, 48, 93, 0, 42,104, 97,110,100,108,101, 0, 42,112,110, 97,109,101, 0, 42,
-115,116,110, 97,109,101,115, 0,115,116,121,112,101,115, 0,118, 97,114,115, 0, 42,118, 97,114,115,116,114, 0, 42,114,101,115,
-117,108,116, 0, 42, 99,102,114, 97, 0,100, 97,116, 97, 91, 51, 50, 93, 0, 40, 42,100,111,105,116, 41, 40, 41, 0, 40, 42,105,
-110,115,116, 97,110, 99,101, 95,105,110,105,116, 41, 40, 41, 0, 40, 42, 99, 97,108,108, 98, 97, 99,107, 41, 40, 41, 0,118,101,
-114,115,105,111,110, 0, 97, 0,105,112,111,116,121,112,101, 0, 42,105,109, 97, 0, 42, 99,117, 98,101, 91, 54, 93, 0,105,109,
- 97,116, 91, 52, 93, 91, 52, 93, 0,111, 98,105,109, 97,116, 91, 51, 93, 91, 51, 93, 0,115,116,121,112,101, 0,118,105,101,119,
-115, 99, 97,108,101, 0,110,111,116,108, 97,121, 0, 99,117, 98,101,114,101,115, 0,100,101,112,116,104, 0,114,101, 99, 97,108,
- 99, 0,108, 97,115,116,115,105,122,101, 0,110,111,105,115,101,115,105,122,101, 0,116,117,114, 98,117,108, 0, 98,114,105,103,
-104,116, 0, 99,111,110,116,114, 97,115,116, 0,114,102, 97, 99, 0,103,102, 97, 99, 0, 98,102, 97, 99, 0,102,105,108,116,101,
-114,115,105,122,101, 0,109,103, 95, 72, 0,109,103, 95,108, 97, 99,117,110, 97,114,105,116,121, 0,109,103, 95,111, 99,116, 97,
-118,101,115, 0,109,103, 95,111,102,102,115,101,116, 0,109,103, 95,103, 97,105,110, 0,100,105,115,116, 95, 97,109,111,117,110,
-116, 0,110,115, 95,111,117,116,115, 99, 97,108,101, 0,118,110, 95,119, 49, 0,118,110, 95,119, 50, 0,118,110, 95,119, 51, 0,
-118,110, 95,119, 52, 0,118,110, 95,109,101,120,112, 0,118,110, 95,100,105,115,116,109, 0,118,110, 95, 99,111,108,116,121,112,
-101, 0,110,111,105,115,101,100,101,112,116,104, 0,110,111,105,115,101,116,121,112,101, 0,110,111,105,115,101, 98, 97,115,105,
-115, 0,110,111,105,115,101, 98, 97,115,105,115, 50, 0,105,109, 97,102,108, 97,103, 0, 99,114,111,112,120,109,105,110, 0, 99,
-114,111,112,121,109,105,110, 0, 99,114,111,112,120,109, 97,120, 0, 99,114,111,112,121,109, 97,120, 0,116,101,120,102,105,108,
-116,101,114, 0, 97,102,109, 97,120, 0,120,114,101,112,101, 97,116, 0,121,114,101,112,101, 97,116, 0,101,120,116,101,110,100,
- 0, 99,104,101, 99,107,101,114,100,105,115,116, 0,110, 97, 98,108, 97, 0,105,117,115,101,114, 0, 42,110,111,100,101,116,114,
-101,101, 0, 42,112,108,117,103,105,110, 0, 42, 99,111, 98, 97, 0, 42,101,110,118, 0,117,115,101, 95,110,111,100,101,115, 0,
-112, 97,100, 91, 55, 93, 0,108,111, 99, 91, 51, 93, 0,114,111,116, 91, 51, 93, 0,109, 97,116, 91, 52, 93, 91, 52, 93, 0,109,
-105,110, 91, 51, 93, 0,109, 97,120, 91, 51, 93, 0,109,111,100,101, 0,116,111,116,101,120, 0,115,104,100,119,114, 0,115,104,
-100,119,103, 0,115,104,100,119, 98, 0,115,104,100,119,112, 97,100, 0,101,110,101,114,103,121, 0,100,105,115,116, 0,115,112,
-111,116,115,105,122,101, 0,115,112,111,116, 98,108,101,110,100, 0,104, 97,105,110,116, 0, 97,116,116, 49, 0, 97,116,116, 50,
- 0, 42, 99,117,114,102, 97,108,108,111,102,102, 0,102, 97,108,108,111,102,102, 95,116,121,112,101, 0,115,104, 97,100,115,112,
-111,116,115,105,122,101, 0, 98,105, 97,115, 0,115,111,102,116, 0, 98,117,102,115,105,122,101, 0,115, 97,109,112, 0, 98,117,
-102,102,101,114,115, 0,102,105,108,116,101,114,116,121,112,101, 0, 98,117,102,102,108, 97,103, 0, 98,117,102,116,121,112,101,
- 0,114, 97,121, 95,115, 97,109,112, 0,114, 97,121, 95,115, 97,109,112,121, 0,114, 97,121, 95,115, 97,109,112,122, 0,114, 97,
-121, 95,115, 97,109,112, 95,116,121,112,101, 0, 97,114,101, 97, 95,115,104, 97,112,101, 0, 97,114,101, 97, 95,115,105,122,101,
- 0, 97,114,101, 97, 95,115,105,122,101,121, 0, 97,114,101, 97, 95,115,105,122,101,122, 0, 97,100, 97,112,116, 95,116,104,114,
-101,115,104, 0,114, 97,121, 95,115, 97,109,112, 95,109,101,116,104,111,100, 0,116,101,120, 97, 99,116, 0,115,104, 97,100,104,
- 97,108,111,115,116,101,112, 0,115,117,110, 95,101,102,102,101, 99,116, 95,116,121,112,101, 0,115,107,121, 98,108,101,110,100,
-116,121,112,101, 0,104,111,114,105,122,111,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,112,114,101, 97,100, 0,115,
-117,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,117,110, 95,115,105,122,101, 0, 98, 97, 99,107,115, 99, 97,116,116,
-101,114,101,100, 95,108,105,103,104,116, 0,115,117,110, 95,105,110,116,101,110,115,105,116,121, 0, 97,116,109, 95,116,117,114,
- 98,105,100,105,116,121, 0, 97,116,109, 95,105,110,115, 99, 97,116,116,101,114,105,110,103, 95,102, 97, 99,116,111,114, 0, 97,
-116,109, 95,101,120,116,105,110, 99,116,105,111,110, 95,102, 97, 99,116,111,114, 0, 97,116,109, 95,100,105,115,116, 97,110, 99,
-101, 95,102, 97, 99,116,111,114, 0,115,107,121, 98,108,101,110,100,102, 97, 99, 0,115,107,121, 95,101,120,112,111,115,117,114,
-101, 0,115,107,121, 95, 99,111,108,111,114,115,112, 97, 99,101, 0,112, 97,100, 52, 0, 89, 70, 95,110,117,109,112,104,111,116,
-111,110,115, 0, 89, 70, 95,110,117,109,115,101, 97,114, 99,104, 0, 89, 70, 95,112,104,100,101,112,116,104, 0, 89, 70, 95,117,
-115,101,113,109, 99, 0, 89, 70, 95, 98,117,102,115,105,122,101, 0, 89, 70, 95,112, 97,100, 0, 89, 70, 95, 99, 97,117,115,116,
-105, 99, 98,108,117,114, 0, 89, 70, 95,108,116,114, 97,100,105,117,115, 0, 89, 70, 95,103,108,111,119,105,110,116, 0, 89, 70,
- 95,103,108,111,119,111,102,115, 0, 89, 70, 95,103,108,111,119,116,121,112,101, 0, 89, 70, 95,112, 97,100, 50, 0, 42,109,116,
-101,120, 91, 49, 56, 93, 0,112,114, 95,116,101,120,116,117,114,101, 0,112, 97,100, 91, 51, 93, 0,109, 97,116,101,114,105, 97,
-108, 95,116,121,112,101, 0,115,112,101, 99,114, 0,115,112,101, 99,103, 0,115,112,101, 99, 98, 0,109,105,114,114, 0,109,105,
-114,103, 0,109,105,114, 98, 0, 97,109, 98,114, 0, 97,109, 98, 98, 0, 97,109, 98,103, 0, 97,109, 98, 0,101,109,105,116, 0,
- 97,110,103, 0,115,112,101, 99,116,114, 97, 0,114, 97,121, 95,109,105,114,114,111,114, 0, 97,108,112,104, 97, 0,114,101,102,
- 0,115,112,101, 99, 0,122,111,102,102,115, 0, 97,100,100, 0,116,114, 97,110,115,108,117, 99,101,110, 99,121, 0,102,114,101,
-115,110,101,108, 95,109,105,114, 0,102,114,101,115,110,101,108, 95,109,105,114, 95,105, 0,102,114,101,115,110,101,108, 95,116,
-114, 97, 0,102,114,101,115,110,101,108, 95,116,114, 97, 95,105, 0,102,105,108,116,101,114, 0,116,120, 95,108,105,109,105,116,
- 0,116,120, 95,102, 97,108,108,111,102,102, 0,114, 97,121, 95,100,101,112,116,104, 0,114, 97,121, 95,100,101,112,116,104, 95,
-116,114, 97, 0,104, 97,114, 0,115,101,101,100, 49, 0,115,101,101,100, 50, 0,103,108,111,115,115, 95,109,105,114, 0,103,108,
-111,115,115, 95,116,114, 97, 0,115, 97,109,112, 95,103,108,111,115,115, 95,109,105,114, 0,115, 97,109,112, 95,103,108,111,115,
-115, 95,116,114, 97, 0, 97,100, 97,112,116, 95,116,104,114,101,115,104, 95,109,105,114, 0, 97,100, 97,112,116, 95,116,104,114,
-101,115,104, 95,116,114, 97, 0, 97,110,105,115,111, 95,103,108,111,115,115, 95,109,105,114, 0,100,105,115,116, 95,109,105,114,
- 0,102, 97,100,101,116,111, 95,109,105,114, 0,115,104, 97,100,101, 95,102,108, 97,103, 0,109,111,100,101, 95,108, 0,102,108,
- 97,114,101, 99, 0,115,116, 97,114, 99, 0,108,105,110,101, 99, 0,114,105,110,103, 99, 0,104, 97,115,105,122,101, 0,102,108,
- 97,114,101,115,105,122,101, 0,115,117, 98,115,105,122,101, 0,102,108, 97,114,101, 98,111,111,115,116, 0,115,116,114, 97,110,
-100, 95,115,116, 97, 0,115,116,114, 97,110,100, 95,101,110,100, 0,115,116,114, 97,110,100, 95,101, 97,115,101, 0,115,116,114,
- 97,110,100, 95,115,117,114,102,110,111,114, 0,115,116,114, 97,110,100, 95,109,105,110, 0,115,116,114, 97,110,100, 95,119,105,
-100,116,104,102, 97,100,101, 0,115,116,114, 97,110,100, 95,117,118,110, 97,109,101, 91, 51, 50, 93, 0,115, 98,105, 97,115, 0,
-108, 98,105, 97,115, 0,115,104, 97,100, 95, 97,108,112,104, 97, 0,115,101,112,116,101,120, 0,114,103, 98,115,101,108, 0,112,
-114, 95,116,121,112,101, 0,112,114, 95, 98, 97, 99,107, 0,112,114, 95,108, 97,109,112, 0,109,108, 95,102,108, 97,103, 0,100,
-105,102,102, 95,115,104, 97,100,101,114, 0,115,112,101, 99, 95,115,104, 97,100,101,114, 0,114,111,117,103,104,110,101,115,115,
- 0,114,101,102,114, 97, 99, 0,112, 97,114, 97,109, 91, 52, 93, 0,114,109,115, 0,100, 97,114,107,110,101,115,115, 0, 42,114,
- 97,109,112, 95, 99,111,108, 0, 42,114, 97,109,112, 95,115,112,101, 99, 0,114, 97,109,112,105,110, 95, 99,111,108, 0,114, 97,
-109,112,105,110, 95,115,112,101, 99, 0,114, 97,109,112, 98,108,101,110,100, 95, 99,111,108, 0,114, 97,109,112, 98,108,101,110,
-100, 95,115,112,101, 99, 0,114, 97,109,112, 95,115,104,111,119, 0,112, 97,100, 51, 0,114, 97,109,112,102, 97, 99, 95, 99,111,
-108, 0,114, 97,109,112,102, 97, 99, 95,115,112,101, 99, 0, 42,103,114,111,117,112, 0,102,114,105, 99,116,105,111,110, 0,102,
-104, 0,114,101,102,108,101, 99,116, 0,102,104,100,105,115,116, 0,120,121,102,114,105, 99,116, 0,100,121,110, 97,109,111,100,
-101, 0,115,115,115, 95,114, 97,100,105,117,115, 91, 51, 93, 0,115,115,115, 95, 99,111,108, 91, 51, 93, 0,115,115,115, 95,101,
-114,114,111,114, 0,115,115,115, 95,115, 99, 97,108,101, 0,115,115,115, 95,105,111,114, 0,115,115,115, 95, 99,111,108,102, 97,
- 99, 0,115,115,115, 95,116,101,120,102, 97, 99, 0,115,115,115, 95,102,114,111,110,116, 0,115,115,115, 95, 98, 97, 99,107, 0,
-115,115,115, 95,102,108, 97,103, 0,115,115,115, 95,112,114,101,115,101,116, 0, 89, 70, 95, 97,114, 0, 89, 70, 95, 97,103, 0,
- 89, 70, 95, 97, 98, 0, 89, 70, 95,100,115, 99, 97,108,101, 0, 89, 70, 95,100,112,119,114, 0, 89, 70, 95,100,115,109,112, 0,
- 89, 70, 95,112,114,101,115,101,116, 0, 89, 70, 95,100,106,105,116, 0,103,112,117,109, 97,116,101,114,105, 97,108, 0,110, 97,
-109,101, 91, 50, 53, 54, 93, 0, 42, 98, 98, 0,105, 49, 0,106, 49, 0,107, 49, 0,105, 50, 0,106, 50, 0,107, 50, 0,115,101,
-108, 99,111,108, 49, 0,115,101,108, 99,111,108, 50, 0,113,117, 97,116, 91, 52, 93, 0,101,120,112,120, 0,101,120,112,121, 0,
-101,120,112,122, 0,114, 97,100, 0,114, 97,100, 50, 0,115, 0, 42,109, 97,116, 0, 42,105,109, 97,116, 0,101,108,101,109,115,
- 0,100,105,115,112, 0, 42,101,100,105,116,101,108,101,109,115, 0, 42, 42,109, 97,116, 0,116,111,116, 99,111,108, 0,119,105,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,
+114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,
+160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255,
+ 16, 64, 16,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,
+255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+154, 0, 0,255,189, 17, 17,255,247, 10, 10,255, 0, 0, 0, 0,247, 64, 24,255,246,105, 19,255,250,153, 0,255, 0, 0, 0, 0,
+ 30,145, 9,255, 89,183, 11,255,131,239, 29,255, 0, 0, 0, 0, 10, 54,148,255, 54,103,223,255, 94,193,239,255, 0, 0, 0, 0,
+169, 41, 78,255,193, 65,106,255,240, 93,145,255, 0, 0, 0, 0, 67, 12,120,255, 84, 58,163,255,135,100,213,255, 0, 0, 0, 0,
+ 36,120, 90,255, 60,149,121,255,111,182,171,255, 0, 0, 0, 0, 75,112,124,255,106,134,145,255,155,194,205,255, 0, 0, 0, 0,
+244,201, 12,255,238,194, 54,255,243,255, 0,255, 0, 0, 0, 0, 30, 32, 36,255, 72, 76, 86,255,255,255,255,255, 0, 0, 0, 0,
+111, 47,106,255,152, 69,190,255,211, 48,214,255, 0, 0, 0, 0,108,142, 34,255,127,176, 34,255,187,239, 91,255, 0, 0, 0, 0,
+141,141,141,255,176,176,176,255,222,222,222,255, 0, 0, 0, 0,131, 67, 38,255,139, 88, 17,255,189,106, 17,255, 0, 0, 0, 0,
+ 8, 49, 14,255, 28, 67, 11,255, 52, 98, 43,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,200, 21, 0, 0, 40,207, 13, 7,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168, 3, 10, 7, 82,111,117,110,
+100,101,100, 0, 0,101,119, 32, 85,115,101,114, 32, 84,104,101,109,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,
+153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,
+153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 1, 0, 25, 0,231,255, 0, 0, 25, 25, 25,255,
+153,153,153,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255, 1, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0,255,
+ 70, 70, 70,255, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0,255,
+ 70, 70, 70,255, 70, 70, 70,255,255,255,255,255, 0, 0, 0,255,255,255,255,255, 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,
+180,180,180,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255, 1, 0,236,255, 0, 0, 0, 0, 25, 25, 25,255,
+180,180,180,255,153,153,153,255,128,128,128,255, 0, 0, 0,255,255,255,255,255, 1, 0,236,255, 0, 0, 0, 0, 0, 0, 0,255,
+ 70, 70, 70,255, 70, 70, 70,255,255,255,255,255,255,255,255,255,204,204,204,255, 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0,255,
+ 63, 63, 63,255, 86,128,194,255,255,255,255,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255,
+ 25, 25, 25,230, 46,124,217,204,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255,
+ 0, 0, 0, 0, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,175,175,175, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,
+127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 51,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,
+217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,255,130, 0,255,
+ 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255,
+ 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,
+127,112,112,100,255,130, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,150,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,100,143,143,143,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,
+255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255,255,255,255,255,255,255,255,255,255,130, 0,255,
+ 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 82, 96,110,255,124,137,150,255,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,
+255,130, 0,255, 2, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,
+127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,158,158,158,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255,
+255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255,
+ 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,
+135,177,125,255,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,143,143,143,255,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,204,
+255,255,170,204, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,143,143,143,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,
+255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255,
+ 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,255,255,255,170,255, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,
+127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 81,105,135,255,109, 88,129,255, 78,152, 62,255, 46,143,143,255,169, 84,124,255,126,126, 80,255,
+162, 95,111,255,109,145,131,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,
+255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255,
+ 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,255,133, 0,255,
+ 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,195,195,195,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,
+127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,153,153,153,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,153,153,153,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 88, 88, 88,255, 0, 0, 0,255,
+255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255,
+ 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0,100, 0, 0,255, 0, 0,200,255,128, 0, 80,255, 95, 95, 0,255, 0,100, 50,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,
+127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,158,158,158,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,150,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255,
+255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255,
+ 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,
+127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255,127,127,127,255,
+142,138,145,255,120,145,120,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,100,100,255,
+ 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 51,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,
+217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,255,130, 0,255,
+ 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255,
+ 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255,
+ 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0,255,
+189, 17, 17,255,247, 10, 10,255, 0, 0, 0, 0,247, 64, 24,255,246,105, 19,255,250,153, 0,255, 0, 0, 0, 0, 30,145, 9,255,
+ 89,183, 11,255,131,239, 29,255, 0, 0, 0, 0, 10, 54,148,255, 54,103,223,255, 94,193,239,255, 0, 0, 0, 0,169, 41, 78,255,
+193, 65,106,255,240, 93,145,255, 0, 0, 0, 0, 67, 12,120,255, 84, 58,163,255,135,100,213,255, 0, 0, 0, 0, 36,120, 90,255,
+ 60,149,121,255,111,182,171,255, 0, 0, 0, 0, 75,112,124,255,106,134,145,255,155,194,205,255, 0, 0, 0, 0,244,201, 12,255,
+238,194, 54,255,243,255, 0,255, 0, 0, 0, 0, 30, 32, 36,255, 72, 76, 86,255,255,255,255,255, 0, 0, 0, 0,111, 47,106,255,
+152, 69,190,255,211, 48,214,255, 0, 0, 0, 0,108,142, 34,255,127,176, 34,255,187,239, 91,255, 0, 0, 0, 0,141,141,141,255,
+176,176,176,255,222,222,222,255, 0, 0, 0, 0,131, 67, 38,255,139, 88, 17,255,189,106, 17,255, 0, 0, 0, 0, 8, 49, 14,255,
+ 28, 67, 11,255, 52, 98, 43,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 78, 65, 49,
+ 28,222, 0, 0, 32, 80, 6, 7, 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, 78, 65, 77, 69,212, 10, 0, 0, 42,110,101,120,
+116, 0, 42,112,114,101,118, 0, 42,100, 97,116, 97, 0, 42,102,105,114,115,116, 0, 42,108, 97,115,116, 0,120, 0,121, 0,122,
+ 0,119, 0,120,109,105,110, 0,120,109, 97,120, 0,121,109,105,110, 0,121,109, 97,120, 0, 42,112,111,105,110,116,101,114, 0,
+103,114,111,117,112, 0,118, 97,108, 0,118, 97,108, 50, 0,116,121,112,101, 0,115,117, 98,116,121,112,101, 0,102,108, 97,103,
+ 0,110, 97,109,101, 91, 51, 50, 93, 0,115, 97,118,101,100, 0,100, 97,116, 97, 0,108,101,110, 0,116,111,116, 97,108,108,101,
+110, 0, 42,110,101,119,105,100, 0, 42,108,105, 98, 0,110, 97,109,101, 91, 50, 52, 93, 0,117,115, 0,105, 99,111,110, 95,105,
+100, 0, 42,112,114,111,112,101,114,116,105,101,115, 0,105,100, 0, 42,105,100, 98,108,111, 99,107, 0, 42,102,105,108,101,100,
+ 97,116, 97, 0,110, 97,109,101, 91, 50, 52, 48, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 52, 48, 93, 0,116,111,116, 0,
+112, 97,100, 0, 42,112, 97,114,101,110,116, 0,119, 91, 50, 93, 0,104, 91, 50, 93, 0, 99,104, 97,110,103,101,100, 91, 50, 93,
+ 0,112, 97,100, 48, 0,112, 97,100, 49, 0, 42,114,101, 99,116, 91, 50, 93, 0, 42,111, 98, 0, 98,108,111, 99,107,116,121,112,
+101, 0, 97,100,114, 99,111,100,101, 0,110, 97,109,101, 91, 49, 50, 56, 93, 0, 42, 98,112, 0, 42, 98,101,122,116, 0,109, 97,
+120,114, 99,116, 0,116,111,116,114, 99,116, 0,118, 97,114,116,121,112,101, 0,116,111,116,118,101,114,116, 0,105,112,111, 0,
+101,120,116,114, 97,112, 0,114,116, 0, 98,105,116,109, 97,115,107, 0,115,108,105,100,101, 95,109,105,110, 0,115,108,105,100,
+101, 95,109, 97,120, 0, 99,117,114,118, 97,108, 0, 42,100,114,105,118,101,114, 0, 99,117,114,118,101, 0, 99,117,114, 0,115,
+104,111,119,107,101,121, 0,109,117,116,101,105,112,111, 0,112,111,115, 0,114,101,108, 97,116,105,118,101, 0,116,111,116,101,
+108,101,109, 0,112, 97,100, 50, 0, 42,119,101,105,103,104,116,115, 0,118,103,114,111,117,112, 91, 51, 50, 93, 0,115,108,105,
+100,101,114,109,105,110, 0,115,108,105,100,101,114,109, 97,120, 0, 42, 97,100,116, 0, 42,114,101,102,107,101,121, 0,101,108,
+101,109,115,116,114, 91, 51, 50, 93, 0,101,108,101,109,115,105,122,101, 0, 98,108,111, 99,107, 0, 42,105,112,111, 0, 42,102,
+114,111,109, 0,116,111,116,107,101,121, 0,115,108,117,114,112,104, 0, 42,108,105,110,101, 0, 42,102,111,114,109, 97,116, 0,
+ 98,108,101,110, 0,108,105,110,101,110,111, 0,115,116, 97,114,116, 0,101,110,100, 0,102,108, 97,103,115, 0, 99,111,108,111,
+114, 91, 52, 93, 0,112, 97,100, 91, 52, 93, 0, 42,110, 97,109,101, 0,110,108,105,110,101,115, 0,108,105,110,101,115, 0, 42,
+ 99,117,114,108, 0, 42,115,101,108,108, 0, 99,117,114, 99, 0,115,101,108, 99, 0,109, 97,114,107,101,114,115, 0, 42,117,110,
+100,111, 95, 98,117,102, 0,117,110,100,111, 95,112,111,115, 0,117,110,100,111, 95,108,101,110, 0, 42, 99,111,109,112,105,108,
+101,100, 0,109,116,105,109,101, 0,115,105,122,101, 0,115,101,101,107, 0,112, 97,115,115,101,112, 97,114,116, 97,108,112,104,
+ 97, 0, 97,110,103,108,101, 0, 99,108,105,112,115,116, 97, 0, 99,108,105,112,101,110,100, 0,108,101,110,115, 0,111,114,116,
+104,111, 95,115, 99, 97,108,101, 0,100,114, 97,119,115,105,122,101, 0,115,104,105,102,116,120, 0,115,104,105,102,116,121, 0,
+ 89, 70, 95,100,111,102,100,105,115,116, 0, 89, 70, 95, 97,112,101,114,116,117,114,101, 0, 89, 70, 95, 98,107,104,116,121,112,
+101, 0, 89, 70, 95, 98,107,104, 98,105, 97,115, 0, 89, 70, 95, 98,107,104,114,111,116, 0, 42,100,111,102, 95,111, 98, 0,102,
+114, 97,109,101,110,114, 0,102,114, 97,109,101,115, 0,111,102,102,115,101,116, 0,115,102,114, 97, 0,102,105,101, 95,105,109,
+ 97, 0, 99,121, 99,108, 0,111,107, 0,109,117,108,116,105, 95,105,110,100,101,120, 0,108, 97,121,101,114, 0,112, 97,115,115,
+ 0,109,101,110,117,110,114, 0, 42,115, 99,101,110,101, 0,105, 98,117,102,115, 0, 42,103,112,117,116,101,120,116,117,114,101,
+ 0, 42, 97,110,105,109, 0, 42,114,114, 0,115,111,117,114, 99,101, 0,108, 97,115,116,102,114, 97,109,101, 0,116,112, 97,103,
+101,102,108, 97,103, 0,116,111,116, 98,105,110,100, 0,120,114,101,112, 0,121,114,101,112, 0,116,119,115,116, 97, 0,116,119,
+101,110,100, 0, 98,105,110,100, 99,111,100,101, 0, 42,114,101,112, 98,105,110,100, 0, 42,112, 97, 99,107,101,100,102,105,108,
+101, 0, 42,112,114,101,118,105,101,119, 0, 42,114,101,110,100,101,114, 95,116,101,120,116, 0,108, 97,115,116,117,112,100, 97,
+116,101, 0,108, 97,115,116,117,115,101,100, 0, 97,110,105,109,115,112,101,101,100, 0,103,101,110, 95,120, 0,103,101,110, 95,
+121, 0,103,101,110, 95,116,121,112,101, 0, 97,115,112,120, 0, 97,115,112,121, 0,116,101,120, 99,111, 0,109, 97,112,116,111,
+ 0,109, 97,112,116,111,110,101,103, 0, 98,108,101,110,100,116,121,112,101, 0, 42,111, 98,106,101, 99,116, 0, 42,116,101,120,
+ 0,117,118,110, 97,109,101, 91, 51, 50, 93, 0,112,114,111,106,120, 0,112,114,111,106,121, 0,112,114,111,106,122, 0,109, 97,
+112,112,105,110,103, 0,111,102,115, 91, 51, 93, 0,115,105,122,101, 91, 51, 93, 0,114,111,116, 0,116,101,120,102,108, 97,103,
+ 0, 99,111,108,111,114,109,111,100,101,108, 0,112,109, 97,112,116,111, 0,112,109, 97,112,116,111,110,101,103, 0,110,111,114,
+109, 97,112,115,112, 97, 99,101, 0,119,104,105, 99,104, 95,111,117,116,112,117,116, 0, 98,114,117,115,104, 95,109, 97,112, 95,
+109,111,100,101, 0,112, 97,100, 91, 55, 93, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114, 0, 99,111,108,102,
+ 97, 99, 0,110,111,114,102, 97, 99, 0,118, 97,114,102, 97, 99, 0,100,105,115,112,102, 97, 99, 0,119, 97,114,112,102, 97, 99,
+ 0,110, 97,109,101, 91, 49, 54, 48, 93, 0, 42,104, 97,110,100,108,101, 0, 42,112,110, 97,109,101, 0, 42,115,116,110, 97,109,
+101,115, 0,115,116,121,112,101,115, 0,118, 97,114,115, 0, 42,118, 97,114,115,116,114, 0, 42,114,101,115,117,108,116, 0, 42,
+ 99,102,114, 97, 0,100, 97,116, 97, 91, 51, 50, 93, 0, 40, 42,100,111,105,116, 41, 40, 41, 0, 40, 42,105,110,115,116, 97,110,
+ 99,101, 95,105,110,105,116, 41, 40, 41, 0, 40, 42, 99, 97,108,108, 98, 97, 99,107, 41, 40, 41, 0,118,101,114,115,105,111,110,
+ 0, 97, 0,105,112,111,116,121,112,101, 0, 42,105,109, 97, 0, 42, 99,117, 98,101, 91, 54, 93, 0,105,109, 97,116, 91, 52, 93,
+ 91, 52, 93, 0,111, 98,105,109, 97,116, 91, 51, 93, 91, 51, 93, 0,115,116,121,112,101, 0,118,105,101,119,115, 99, 97,108,101,
+ 0,110,111,116,108, 97,121, 0, 99,117, 98,101,114,101,115, 0,100,101,112,116,104, 0,114,101, 99, 97,108, 99, 0,108, 97,115,
+116,115,105,122,101, 0,102, 97,108,108,111,102,102, 95,116,121,112,101, 0,102, 97,108,108,111,102,102, 95,115,111,102,116,110,
+101,115,115, 0,114, 97,100,105,117,115, 0, 99,111,108,111,114, 95,115,111,117,114, 99,101, 0,116,111,116,112,111,105,110,116,
+115, 0,112,100,112, 97,100, 0, 42,112,115,121,115, 0,112,115,121,115, 95, 99, 97, 99,104,101, 95,115,112, 97, 99,101, 0,111,
+ 98, 95, 99, 97, 99,104,101, 95,115,112, 97, 99,101, 0,112,100,112, 97,100, 50, 91, 50, 93, 0, 42,112,111,105,110,116, 95,116,
+114,101,101, 0, 42,112,111,105,110,116, 95,100, 97,116, 97, 0,110,111,105,115,101, 95,115,105,122,101, 0,110,111,105,115,101,
+ 95,100,101,112,116,104, 0,110,111,105,115,101, 95,105,110,102,108,117,101,110, 99,101, 0,110,111,105,115,101, 95, 98, 97,115,
+105,115, 0,112,100,112, 97,100, 51, 91, 51, 93, 0,110,111,105,115,101, 95,102, 97, 99, 0,115,112,101,101,100, 95,115, 99, 97,
+108,101, 0, 42, 99,111, 98, 97, 0,114,101,115,111,108, 91, 51, 93, 0,105,110,116,101,114,112, 95,116,121,112,101, 0,102,105,
+108,101, 95,102,111,114,109, 97,116, 0,105,110,116, 95,109,117,108,116,105,112,108,105,101,114, 0,115,116,105,108,108, 95,102,
+114, 97,109,101, 0,115,111,117,114, 99,101, 95,112, 97,116,104, 91, 50, 52, 48, 93, 0, 42,100, 97,116, 97,115,101,116, 0,110,
+111,105,115,101,115,105,122,101, 0,116,117,114, 98,117,108, 0, 98,114,105,103,104,116, 0, 99,111,110,116,114, 97,115,116, 0,
+114,102, 97, 99, 0,103,102, 97, 99, 0, 98,102, 97, 99, 0,102,105,108,116,101,114,115,105,122,101, 0,109,103, 95, 72, 0,109,
+103, 95,108, 97, 99,117,110, 97,114,105,116,121, 0,109,103, 95,111, 99,116, 97,118,101,115, 0,109,103, 95,111,102,102,115,101,
+116, 0,109,103, 95,103, 97,105,110, 0,100,105,115,116, 95, 97,109,111,117,110,116, 0,110,115, 95,111,117,116,115, 99, 97,108,
+101, 0,118,110, 95,119, 49, 0,118,110, 95,119, 50, 0,118,110, 95,119, 51, 0,118,110, 95,119, 52, 0,118,110, 95,109,101,120,
+112, 0,118,110, 95,100,105,115,116,109, 0,118,110, 95, 99,111,108,116,121,112,101, 0,110,111,105,115,101,100,101,112,116,104,
+ 0,110,111,105,115,101,116,121,112,101, 0,110,111,105,115,101, 98, 97,115,105,115, 0,110,111,105,115,101, 98, 97,115,105,115,
+ 50, 0,105,109, 97,102,108, 97,103, 0, 99,114,111,112,120,109,105,110, 0, 99,114,111,112,121,109,105,110, 0, 99,114,111,112,
+120,109, 97,120, 0, 99,114,111,112,121,109, 97,120, 0,116,101,120,102,105,108,116,101,114, 0, 97,102,109, 97,120, 0,120,114,
+101,112,101, 97,116, 0,121,114,101,112,101, 97,116, 0,101,120,116,101,110,100, 0, 99,104,101, 99,107,101,114,100,105,115,116,
+ 0,110, 97, 98,108, 97, 0,105,117,115,101,114, 0, 42,110,111,100,101,116,114,101,101, 0, 42,112,108,117,103,105,110, 0, 42,
+101,110,118, 0, 42,112,100, 0, 42,118,100, 0,117,115,101, 95,110,111,100,101,115, 0,108,111, 99, 91, 51, 93, 0,114,111,116,
+ 91, 51, 93, 0,109, 97,116, 91, 52, 93, 91, 52, 93, 0,109,105,110, 91, 51, 93, 0,109, 97,120, 91, 51, 93, 0,109,111,100,101,
+ 0,116,111,116,101,120, 0,115,104,100,119,114, 0,115,104,100,119,103, 0,115,104,100,119, 98, 0,115,104,100,119,112, 97,100,
+ 0,101,110,101,114,103,121, 0,100,105,115,116, 0,115,112,111,116,115,105,122,101, 0,115,112,111,116, 98,108,101,110,100, 0,
+104, 97,105,110,116, 0, 97,116,116, 49, 0, 97,116,116, 50, 0, 42, 99,117,114,102, 97,108,108,111,102,102, 0,115,104, 97,100,
+115,112,111,116,115,105,122,101, 0, 98,105, 97,115, 0,115,111,102,116, 0, 98,117,102,115,105,122,101, 0,115, 97,109,112, 0,
+ 98,117,102,102,101,114,115, 0,102,105,108,116,101,114,116,121,112,101, 0, 98,117,102,102,108, 97,103, 0, 98,117,102,116,121,
+112,101, 0,114, 97,121, 95,115, 97,109,112, 0,114, 97,121, 95,115, 97,109,112,121, 0,114, 97,121, 95,115, 97,109,112,122, 0,
+114, 97,121, 95,115, 97,109,112, 95,116,121,112,101, 0, 97,114,101, 97, 95,115,104, 97,112,101, 0, 97,114,101, 97, 95,115,105,
+122,101, 0, 97,114,101, 97, 95,115,105,122,101,121, 0, 97,114,101, 97, 95,115,105,122,101,122, 0, 97,100, 97,112,116, 95,116,
+104,114,101,115,104, 0,114, 97,121, 95,115, 97,109,112, 95,109,101,116,104,111,100, 0,116,101,120, 97, 99,116, 0,115,104, 97,
+100,104, 97,108,111,115,116,101,112, 0,115,117,110, 95,101,102,102,101, 99,116, 95,116,121,112,101, 0,115,107,121, 98,108,101,
+110,100,116,121,112,101, 0,104,111,114,105,122,111,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,112,114,101, 97,100,
+ 0,115,117,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,117,110, 95,115,105,122,101, 0, 98, 97, 99,107,115, 99, 97,
+116,116,101,114,101,100, 95,108,105,103,104,116, 0,115,117,110, 95,105,110,116,101,110,115,105,116,121, 0, 97,116,109, 95,116,
+117,114, 98,105,100,105,116,121, 0, 97,116,109, 95,105,110,115, 99, 97,116,116,101,114,105,110,103, 95,102, 97, 99,116,111,114,
+ 0, 97,116,109, 95,101,120,116,105,110, 99,116,105,111,110, 95,102, 97, 99,116,111,114, 0, 97,116,109, 95,100,105,115,116, 97,
+110, 99,101, 95,102, 97, 99,116,111,114, 0,115,107,121, 98,108,101,110,100,102, 97, 99, 0,115,107,121, 95,101,120,112,111,115,
+117,114,101, 0,115,107,121, 95, 99,111,108,111,114,115,112, 97, 99,101, 0,112, 97,100, 52, 0, 89, 70, 95,110,117,109,112,104,
+111,116,111,110,115, 0, 89, 70, 95,110,117,109,115,101, 97,114, 99,104, 0, 89, 70, 95,112,104,100,101,112,116,104, 0, 89, 70,
+ 95,117,115,101,113,109, 99, 0, 89, 70, 95, 98,117,102,115,105,122,101, 0, 89, 70, 95,112, 97,100, 0, 89, 70, 95, 99, 97,117,
+115,116,105, 99, 98,108,117,114, 0, 89, 70, 95,108,116,114, 97,100,105,117,115, 0, 89, 70, 95,103,108,111,119,105,110,116, 0,
+ 89, 70, 95,103,108,111,119,111,102,115, 0, 89, 70, 95,103,108,111,119,116,121,112,101, 0, 89, 70, 95,112, 97,100, 50, 0, 42,
+109,116,101,120, 91, 49, 56, 93, 0,112,114, 95,116,101,120,116,117,114,101, 0,112, 97,100, 91, 51, 93, 0,100,101,110,115,105,
+116,121, 0,101,109,105,115,115,105,111,110, 0, 97, 98,115,111,114,112,116,105,111,110, 0,115, 99, 97,116,116,101,114,105,110,
+103, 0,101,109,105,115,115,105,111,110, 95, 99,111,108, 91, 51, 93, 0, 97, 98,115,111,114,112,116,105,111,110, 95, 99,111,108,
+ 91, 51, 93, 0,100,101,110,115,105,116,121, 95,115, 99, 97,108,101, 0,100,101,112,116,104, 95, 99,117,116,111,102,102, 0,112,
+104, 97,115,101,102,117,110, 99, 95,116,121,112,101, 0,118,112, 97,100, 91, 51, 93, 0,112,104, 97,115,101,102,117,110, 99, 95,
+103, 0,115,116,101,112,115,105,122,101, 0,115,104, 97,100,101, 95,115,116,101,112,115,105,122,101, 0,115,116,101,112,115,105,
+122,101, 95,116,121,112,101, 0,115,104, 97,100,101,102,108, 97,103, 0,115,104, 97,100,101, 95,116,121,112,101, 0,112,114,101,
+ 99, 97, 99,104,101, 95,114,101,115,111,108,117,116,105,111,110, 0,109,115, 95,100,105,102,102, 0,109,115, 95,105,110,116,101,
+110,115,105,116,121, 0,109,115, 95,115,116,101,112,115, 0,109, 97,116,101,114,105, 97,108, 95,116,121,112,101, 0,115,112,101,
+ 99,114, 0,115,112,101, 99,103, 0,115,112,101, 99, 98, 0,109,105,114,114, 0,109,105,114,103, 0,109,105,114, 98, 0, 97,109,
+ 98,114, 0, 97,109, 98, 98, 0, 97,109, 98,103, 0, 97,109, 98, 0,101,109,105,116, 0, 97,110,103, 0,115,112,101, 99,116,114,
+ 97, 0,114, 97,121, 95,109,105,114,114,111,114, 0, 97,108,112,104, 97, 0,114,101,102, 0,115,112,101, 99, 0,122,111,102,102,
+115, 0, 97,100,100, 0,116,114, 97,110,115,108,117, 99,101,110, 99,121, 0,118,111,108, 0,102,114,101,115,110,101,108, 95,109,
+105,114, 0,102,114,101,115,110,101,108, 95,109,105,114, 95,105, 0,102,114,101,115,110,101,108, 95,116,114, 97, 0,102,114,101,
+115,110,101,108, 95,116,114, 97, 95,105, 0,102,105,108,116,101,114, 0,116,120, 95,108,105,109,105,116, 0,116,120, 95,102, 97,
+108,108,111,102,102, 0,114, 97,121, 95,100,101,112,116,104, 0,114, 97,121, 95,100,101,112,116,104, 95,116,114, 97, 0,104, 97,
+114, 0,115,101,101,100, 49, 0,115,101,101,100, 50, 0,103,108,111,115,115, 95,109,105,114, 0,103,108,111,115,115, 95,116,114,
+ 97, 0,115, 97,109,112, 95,103,108,111,115,115, 95,109,105,114, 0,115, 97,109,112, 95,103,108,111,115,115, 95,116,114, 97, 0,
+ 97,100, 97,112,116, 95,116,104,114,101,115,104, 95,109,105,114, 0, 97,100, 97,112,116, 95,116,104,114,101,115,104, 95,116,114,
+ 97, 0, 97,110,105,115,111, 95,103,108,111,115,115, 95,109,105,114, 0,100,105,115,116, 95,109,105,114, 0,102, 97,100,101,116,
+111, 95,109,105,114, 0,115,104, 97,100,101, 95,102,108, 97,103, 0,109,111,100,101, 95,108, 0,102,108, 97,114,101, 99, 0,115,
+116, 97,114, 99, 0,108,105,110,101, 99, 0,114,105,110,103, 99, 0,104, 97,115,105,122,101, 0,102,108, 97,114,101,115,105,122,
+101, 0,115,117, 98,115,105,122,101, 0,102,108, 97,114,101, 98,111,111,115,116, 0,115,116,114, 97,110,100, 95,115,116, 97, 0,
+115,116,114, 97,110,100, 95,101,110,100, 0,115,116,114, 97,110,100, 95,101, 97,115,101, 0,115,116,114, 97,110,100, 95,115,117,
+114,102,110,111,114, 0,115,116,114, 97,110,100, 95,109,105,110, 0,115,116,114, 97,110,100, 95,119,105,100,116,104,102, 97,100,
+101, 0,115,116,114, 97,110,100, 95,117,118,110, 97,109,101, 91, 51, 50, 93, 0,115, 98,105, 97,115, 0,108, 98,105, 97,115, 0,
+115,104, 97,100, 95, 97,108,112,104, 97, 0,115,101,112,116,101,120, 0,114,103, 98,115,101,108, 0,112,114, 95,116,121,112,101,
+ 0,112,114, 95, 98, 97, 99,107, 0,112,114, 95,108, 97,109,112, 0,109,108, 95,102,108, 97,103, 0,100,105,102,102, 95,115,104,
+ 97,100,101,114, 0,115,112,101, 99, 95,115,104, 97,100,101,114, 0,114,111,117,103,104,110,101,115,115, 0,114,101,102,114, 97,
+ 99, 0,112, 97,114, 97,109, 91, 52, 93, 0,114,109,115, 0,100, 97,114,107,110,101,115,115, 0, 42,114, 97,109,112, 95, 99,111,
+108, 0, 42,114, 97,109,112, 95,115,112,101, 99, 0,114, 97,109,112,105,110, 95, 99,111,108, 0,114, 97,109,112,105,110, 95,115,
+112,101, 99, 0,114, 97,109,112, 98,108,101,110,100, 95, 99,111,108, 0,114, 97,109,112, 98,108,101,110,100, 95,115,112,101, 99,
+ 0,114, 97,109,112, 95,115,104,111,119, 0,112, 97,100, 51, 0,114, 97,109,112,102, 97, 99, 95, 99,111,108, 0,114, 97,109,112,
+102, 97, 99, 95,115,112,101, 99, 0, 42,103,114,111,117,112, 0,102,114,105, 99,116,105,111,110, 0,102,104, 0,114,101,102,108,
+101, 99,116, 0,102,104,100,105,115,116, 0,120,121,102,114,105, 99,116, 0,100,121,110, 97,109,111,100,101, 0,115,115,115, 95,
+114, 97,100,105,117,115, 91, 51, 93, 0,115,115,115, 95, 99,111,108, 91, 51, 93, 0,115,115,115, 95,101,114,114,111,114, 0,115,
+115,115, 95,115, 99, 97,108,101, 0,115,115,115, 95,105,111,114, 0,115,115,115, 95, 99,111,108,102, 97, 99, 0,115,115,115, 95,
+116,101,120,102, 97, 99, 0,115,115,115, 95,102,114,111,110,116, 0,115,115,115, 95, 98, 97, 99,107, 0,115,115,115, 95,102,108,
+ 97,103, 0,115,115,115, 95,112,114,101,115,101,116, 0, 89, 70, 95, 97,114, 0, 89, 70, 95, 97,103, 0, 89, 70, 95, 97, 98, 0,
+ 89, 70, 95,100,115, 99, 97,108,101, 0, 89, 70, 95,100,112,119,114, 0, 89, 70, 95,100,115,109,112, 0, 89, 70, 95,112,114,101,
+115,101,116, 0, 89, 70, 95,100,106,105,116, 0,103,112,117,109, 97,116,101,114,105, 97,108, 0,110, 97,109,101, 91, 50, 53, 54,
+ 93, 0, 42, 98, 98, 0,105, 49, 0,106, 49, 0,107, 49, 0,105, 50, 0,106, 50, 0,107, 50, 0,115,101,108, 99,111,108, 49, 0,
+115,101,108, 99,111,108, 50, 0,113,117, 97,116, 91, 52, 93, 0,101,120,112,120, 0,101,120,112,121, 0,101,120,112,122, 0,114,
+ 97,100, 0,114, 97,100, 50, 0,115, 0, 42,109, 97,116, 0, 42,105,109, 97,116, 0,101,108,101,109,115, 0,100,105,115,112, 0,
+ 42,101,100,105,116,101,108,101,109,115, 0, 42, 42,109, 97,116, 0,102,108, 97,103, 50, 0,116,111,116, 99,111,108, 0,119,105,
114,101,115,105,122,101, 0,114,101,110,100,101,114,115,105,122,101, 0,116,104,114,101,115,104, 0, 42,108, 97,115,116,101,108,
-101,109, 0,118,101, 99, 91, 51, 93, 91, 51, 93, 0, 97,108,102, 97, 0,119,101,105,103,104,116, 0,114, 97,100,105,117,115, 0,
-104, 49, 0,104, 50, 0,102, 49, 0,102, 50, 0,102, 51, 0,104,105,100,101, 0,118,101, 99, 91, 52, 93, 0,109, 97,116, 95,110,
-114, 0,112,110,116,115,117, 0,112,110,116,115,118, 0,114,101,115,111,108,117, 0,114,101,115,111,108,118, 0,111,114,100,101,
-114,117, 0,111,114,100,101,114,118, 0,102,108, 97,103,117, 0,102,108, 97,103,118, 0, 42,107,110,111,116,115,117, 0, 42,107,
-110,111,116,115,118, 0,116,105,108,116, 95,105,110,116,101,114,112, 0,114, 97,100,105,117,115, 95,105,110,116,101,114,112, 0,
- 99,104, 97,114,105,100,120, 0,107,101,114,110, 0,104, 0,110,117,114, 98, 0, 42,101,100,105,116,110,117,114, 98, 0, 42, 98,
-101,118,111, 98,106, 0, 42,116, 97,112,101,114,111, 98,106, 0, 42,116,101,120,116,111,110, 99,117,114,118,101, 0, 42,112, 97,
-116,104, 0, 42,107,101,121, 0, 98,101,118, 0,112, 97,116,104,108,101,110, 0, 98,101,118,114,101,115,111,108, 0,119,105,100,
-116,104, 0,101,120,116, 49, 0,101,120,116, 50, 0,114,101,115,111,108,117, 95,114,101,110, 0,114,101,115,111,108,118, 95,114,
-101,110, 0, 97, 99,116,110,117, 0, 42,108, 97,115,116,115,101,108, 98,112, 0,115,112, 97, 99,101,109,111,100,101, 0,115,112,
- 97, 99,105,110,103, 0,108,105,110,101,100,105,115,116, 0,115,104,101, 97,114, 0,102,115,105,122,101, 0,119,111,114,100,115,
-112, 97, 99,101, 0,117,108,112,111,115, 0,117,108,104,101,105,103,104,116, 0,120,111,102, 0,121,111,102, 0,108,105,110,101,
-119,105,100,116,104, 0, 42,115,116,114, 0, 42,115,101,108, 98,111,120,101,115, 0, 42,101,100,105,116,102,111,110,116, 0,102,
- 97,109,105,108,121, 91, 50, 52, 93, 0, 42,118,102,111,110,116, 0, 42,118,102,111,110,116, 98, 0, 42,118,102,111,110,116,105,
- 0, 42,118,102,111,110,116, 98,105, 0,115,101,112, 99,104, 97,114, 0, 99,116,105,109,101, 0,116,111,116, 98,111,120, 0, 97,
- 99,116, 98,111,120, 0, 42,116, 98, 0,115,101,108,115,116, 97,114,116, 0,115,101,108,101,110,100, 0, 42,115,116,114,105,110,
-102,111, 0, 99,117,114,105,110,102,111, 0,101,102,102,101, 99,116, 0, 42,109,102, 97, 99,101, 0, 42,109,116,102, 97, 99,101,
- 0, 42,116,102, 97, 99,101, 0, 42,109,118,101,114,116, 0, 42,109,101,100,103,101, 0, 42,100,118,101,114,116, 0, 42,109, 99,
-111,108, 0, 42,109,115,116,105, 99,107,121, 0, 42,116,101,120, 99,111,109,101,115,104, 0, 42,109,115,101,108,101, 99,116, 0,
- 42,101,100,105,116, 95,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,100, 97,116, 97, 0,116,111,116,
-101,100,103,101, 0,116,111,116,102, 97, 99,101, 0,116,111,116,115,101,108,101, 99,116, 0, 97, 99,116, 95,102, 97, 99,101, 0,
- 99,117, 98,101,109, 97,112,115,105,122,101, 0,100,114, 97,119,102,108, 97,103, 0,115,109,111,111,116,104,114,101,115,104, 0,
-115,117, 98,100,105,118, 0,115,117, 98,100,105,118,114, 0,115,117, 98,115,117,114,102,116,121,112,101, 0, 42,109,114, 0, 42,
-112,118, 0, 42,116,112, 97,103,101, 0,117,118, 91, 52, 93, 91, 50, 93, 0, 99,111,108, 91, 52, 93, 0,116,114, 97,110,115,112,
- 0,116,105,108,101, 0,117,110,119,114, 97,112, 0,118, 49, 0,118, 50, 0,118, 51, 0,118, 52, 0,101,100, 99,111,100,101, 0,
- 99,114,101, 97,115,101, 0, 98,119,101,105,103,104,116, 0,100,101,102, 95,110,114, 0, 42,100,119, 0,116,111,116,119,101,105,
-103,104,116, 0, 99,111, 91, 51, 93, 0,110,111, 91, 51, 93, 0,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,105,110,100,101,
-120, 0,102, 0,105, 0,115, 91, 50, 53, 54, 93, 0,116,111,116,100,105,115,112, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0,
-118, 91, 52, 93, 0,109,105,100, 0,118, 91, 50, 93, 0, 42,102, 97, 99,101,115, 0, 42, 99,111,108,102, 97, 99,101,115, 0, 42,
-101,100,103,101,115, 0, 42,118,101,114,116,115, 0,108,101,118,101,108,115, 0,108,101,118,101,108, 95, 99,111,117,110,116, 0,
- 99,117,114,114,101,110,116, 0,110,101,119,108,118,108, 0,101,100,103,101,108,118,108, 0,112,105,110,108,118,108, 0,114,101,
-110,100,101,114,108,118,108, 0,117,115,101, 95, 99,111,108, 0, 42,101,100,103,101, 95,102,108, 97,103,115, 0, 42,101,100,103,
-101, 95, 99,114,101, 97,115,101,115, 0, 42,118,101,114,116, 95,109, 97,112, 0, 42,101,100,103,101, 95,109, 97,112, 0, 42,111,
-108,100, 95,102, 97, 99,101,115, 0, 42,111,108,100, 95,101,100,103,101,115, 0, 42,101,114,114,111,114, 0,109,111,100,105,102,
-105,101,114, 0,115,117, 98,100,105,118, 84,121,112,101, 0,114,101,110,100,101,114, 76,101,118,101,108,115, 0, 42,101,109, 67,
- 97, 99,104,101, 0, 42,109, 67, 97, 99,104,101, 0,100,101,102, 97,120,105,115, 0,112, 97,100, 91, 54, 93, 0,108,101,110,103,
-116,104, 0,114, 97,110,100,111,109,105,122,101, 0,115,101,101,100, 0, 42,111, 98, 95, 97,114,109, 0, 42,115,116, 97,114,116,
- 95, 99, 97,112, 0, 42,101,110,100, 95, 99, 97,112, 0, 42, 99,117,114,118,101, 95,111, 98, 0, 42,111,102,102,115,101,116, 95,
-111, 98, 0,111,102,102,115,101,116, 91, 51, 93, 0,115, 99, 97,108,101, 91, 51, 93, 0,109,101,114,103,101, 95,100,105,115,116,
- 0,102,105,116, 95,116,121,112,101, 0,111,102,102,115,101,116, 95,116,121,112,101, 0, 99,111,117,110,116, 0, 97,120,105,115,
- 0,116,111,108,101,114, 97,110, 99,101, 0, 42,109,105,114,114,111,114, 95,111, 98, 0,115,112,108,105,116, 95, 97,110,103,108,
-101, 0,118, 97,108,117,101, 0,114,101,115, 0,118, 97,108, 95,102,108, 97,103,115, 0,108,105,109, 95,102,108, 97,103,115, 0,
-101, 95,102,108, 97,103,115, 0, 98,101,118,101,108, 95, 97,110,103,108,101, 0,100,101,102,103,114,112, 95,110, 97,109,101, 91,
- 51, 50, 93, 0, 42,116,101,120,116,117,114,101, 0,115,116,114,101,110,103,116,104, 0,100,105,114,101, 99,116,105,111,110, 0,
-109,105,100,108,101,118,101,108, 0,116,101,120,109, 97,112,112,105,110,103, 0, 42,109, 97,112, 95,111, 98,106,101, 99,116, 0,
-117,118,108, 97,121,101,114, 95,110, 97,109,101, 91, 51, 50, 93, 0,117,118,108, 97,121,101,114, 95,116,109,112, 0, 42,112,114,
-111,106,101, 99,116,111,114,115, 91, 49, 48, 93, 0, 42,105,109, 97,103,101, 0,110,117,109, 95,112,114,111,106,101, 99,116,111,
-114,115, 0, 97,115,112,101, 99,116,120, 0, 97,115,112,101, 99,116,121, 0,112,101,114, 99,101,110,116, 0,102, 97, 99,101, 67,
-111,117,110,116, 0,102, 97, 99, 0,114,101,112,101, 97,116, 0, 42,111, 98,106,101, 99,116, 99,101,110,116,101,114, 0,115,116,
- 97,114,116,120, 0,115,116, 97,114,116,121, 0,104,101,105,103,104,116, 0,110, 97,114,114,111,119, 0,115,112,101,101,100, 0,
-100, 97,109,112, 0,102, 97,108,108,111,102,102, 0,116,105,109,101,111,102,102,115, 0,108,105,102,101,116,105,109,101, 0,100,
-101,102,111,114,109,102,108, 97,103, 0,109,117,108,116,105, 0, 42,112,114,101,118, 67,111,115, 0,112, 97,114,101,110,116,105,
-110,118, 91, 52, 93, 91, 52, 93, 0, 99,101,110,116, 91, 51, 93, 0, 42,105,110,100,101,120, 97,114, 0,116,111,116,105,110,100,
-101,120, 0,102,111,114, 99,101, 0, 42, 99,108,111,116,104, 79, 98,106,101, 99,116, 0, 42,115,105,109, 95,112, 97,114,109,115,
- 0, 42, 99,111,108,108, 95,112, 97,114,109,115, 0, 42,112,111,105,110,116, 95, 99, 97, 99,104,101, 0, 42,120, 0, 42,120,110,
-101,119, 0, 42,120,111,108,100, 0, 42, 99,117,114,114,101,110,116, 95,120,110,101,119, 0, 42, 99,117,114,114,101,110,116, 95,
-120, 0, 42, 99,117,114,114,101,110,116, 95,118, 0, 42,109,102, 97, 99,101,115, 0,110,117,109,118,101,114,116,115, 0,110,117,
-109,102, 97, 99,101,115, 0, 97, 98,115,111,114,112,116,105,111,110, 0,116,105,109,101, 0, 42, 98,118,104,116,114,101,101, 0,
- 42,118, 0, 42,100,109, 0, 99,102,114, 97, 0,111,112,101,114, 97,116,105,111,110, 0,118,101,114,116,101,120, 0,116,111,116,
-105,110,102,108,117,101,110, 99,101, 0,103,114,105,100,115,105,122,101, 0,110,101,101,100, 98,105,110,100, 0, 42, 98,105,110,
-100,119,101,105,103,104,116,115, 0, 42, 98,105,110,100, 99,111,115, 0,116,111,116, 99, 97,103,101,118,101,114,116, 0, 42,100,
-121,110,103,114,105,100, 0, 42,100,121,110,105,110,102,108,117,101,110, 99,101,115, 0, 42,100,121,110,118,101,114,116,115, 0,
- 42,112, 97,100, 50, 0,100,121,110,103,114,105,100,115,105,122,101, 0,100,121,110, 99,101,108,108,109,105,110, 91, 51, 93, 0,
-100,121,110, 99,101,108,108,119,105,100,116,104, 0, 98,105,110,100,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 42,112,115,121,115,
- 0,116,111,116,100,109,118,101,114,116, 0,116,111,116,100,109,101,100,103,101, 0,116,111,116,100,109,102, 97, 99,101, 0,112,
-115,121,115, 0,112,111,115,105,116,105,111,110, 0,114, 97,110,100,111,109, 95,112,111,115,105,116,105,111,110, 0, 42,102, 97,
- 99,101,112, 97, 0,118,103,114,111,117,112, 0,112,114,111,116,101, 99,116, 0, 42,117,110,100,111, 95,118,101,114,116,115, 0,
-117,110,100,111, 95,118,101,114,116,115, 95,116,111,116, 0,117,110,100,111, 95,115,105,103,110, 97,108, 0,108,118,108, 0,116,
-111,116,108,118,108, 0,115,105,109,112,108,101, 0, 42,102,115,115, 0, 42,116, 97,114,103,101,116, 0, 42, 97,117,120, 84, 97,
-114,103,101,116, 0,118,103,114,111,117,112, 95,110, 97,109,101, 91, 51, 50, 93, 0,107,101,101,112, 68,105,115,116, 0,115,104,
-114,105,110,107, 84,121,112,101, 0,115,104,114,105,110,107, 79,112,116,115, 0,112,114,111,106, 65,120,105,115, 0,115,117, 98,
-115,117,114,102, 76,101,118,101,108,115, 0, 42,111,114,105,103,105,110, 0,102, 97, 99,116,111,114, 0,108,105,109,105,116, 91,
- 50, 93, 0,111,114,105,103,105,110, 79,112,116,115, 0,112,110,116,115,119, 0,111,112,110,116,115,117, 0,111,112,110,116,115,
-118, 0,111,112,110,116,115,119, 0,116,121,112,101,117, 0,116,121,112,101,118, 0,116,121,112,101,119, 0,102,117, 0,102,118,
- 0,102,119, 0,100,117, 0,100,118, 0,100,119, 0, 42,100,101,102, 0, 42,108, 97,116,116,105, 99,101,100, 97,116, 97, 0,108,
- 97,116,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 42,101,100,105,116,108, 97,116,116, 0,118,101, 99, 91, 56, 93, 91, 51, 93, 0,
-112, 97,114,116,121,112,101, 0,112, 97,114, 49, 0,112, 97,114, 50, 0,112, 97,114, 51, 0,112, 97,114,115,117, 98,115,116,114,
- 91, 51, 50, 93, 0, 42,116,114, 97, 99,107, 0, 42,112,114,111,120,121, 0, 42,112,114,111,120,121, 95,103,114,111,117,112, 0,
- 42,112,114,111,120,121, 95,102,114,111,109, 0, 42, 97, 99,116,105,111,110, 0, 42,112,111,115,101,108,105, 98, 0, 42,112,111,
-115,101, 0, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 0,100,101,102, 98, 97,115,101, 0,109,111,
-100,105,102,105,101,114,115, 0, 42,109, 97,116, 98,105,116,115, 0, 97, 99,116, 99,111,108, 0,100,108,111, 99, 91, 51, 93, 0,
-111,114,105,103, 91, 51, 93, 0,100,115,105,122,101, 91, 51, 93, 0,100,114,111,116, 91, 51, 93, 0,111, 98,109, 97,116, 91, 52,
- 93, 91, 52, 93, 0, 99,111,110,115,116,105,110,118, 91, 52, 93, 91, 52, 93, 0,108, 97,121, 0, 99,111,108, 98,105,116,115, 0,
-116,114, 97,110,115,102,108, 97,103, 0,112,114,111,116,101, 99,116,102,108, 97,103, 0,116,114, 97, 99,107,102,108, 97,103, 0,
-117,112,102,108, 97,103, 0,110,108, 97,102,108, 97,103, 0,105,112,111,102,108, 97,103, 0,105,112,111,119,105,110, 0,115, 99,
- 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0, 98,111,117,110,100,116,121,112,101, 0,100,117,112,111,110,
- 0,100,117,112,111,102,102, 0,100,117,112,115,116, 97, 0,100,117,112,101,110,100, 0,115,102, 0,109, 97,115,115, 0,100, 97,
-109,112,105,110,103, 0,105,110,101,114,116,105, 97, 0,102,111,114,109,102, 97, 99,116,111,114, 0,114,100, 97,109,112,105,110,
-103, 0,115,105,122,101,102, 97, 99, 0,109, 97,114,103,105,110, 0,109, 97,120, 95,118,101,108, 0,109,105,110, 95,118,101,108,
- 0,109, 95, 99,111,110,116, 97, 99,116, 80,114,111, 99,101,115,115,105,110,103, 84,104,114,101,115,104,111,108,100, 0,100,116,
- 0,100,116,120, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,112, 97,100, 49, 91, 53, 93, 0,101,109,112,116,
-121, 95,100,114, 97,119,115,105,122,101, 0,100,117,112,102, 97, 99,101,115, 99, 97, 0,112,114,111,112, 0,115,101,110,115,111,
-114,115, 0, 99,111,110,116,114,111,108,108,101,114,115, 0, 97, 99,116,117, 97,116,111,114,115, 0, 98, 98,115,105,122,101, 91,
- 51, 93, 0, 97, 99,116,100,101,102, 0,103, 97,109,101,102,108, 97,103, 0,103, 97,109,101,102,108, 97,103, 50, 0, 42, 98,115,
-111,102,116, 0,115,111,102,116,102,108, 97,103, 0, 97,110,105,115,111,116,114,111,112,105, 99, 70,114,105, 99,116,105,111,110,
- 91, 51, 93, 0, 99,111,110,115,116,114, 97,105,110,116,115, 0,110,108, 97,115,116,114,105,112,115, 0,104,111,111,107,115, 0,
-112, 97,114,116,105, 99,108,101,115,121,115,116,101,109, 0, 42,112,100, 0, 42,115,111,102,116, 0, 42,100,117,112, 95,103,114,
-111,117,112, 0,102,108,117,105,100,115,105,109, 70,108, 97,103, 0,114,101,115,116,114,105, 99,116,102,108, 97,103, 0,115,104,
- 97,112,101,110,114, 0,115,104, 97,112,101,102,108, 97,103, 0,114,101, 99, 97,108, 99,111, 0, 98,111,100,121, 95,116,121,112,
-101, 0, 42,102,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 42,100,101,114,105,118,101,100, 68,101,102,111,
-114,109, 0, 42,100,101,114,105,118,101,100, 70,105,110, 97,108, 0,108, 97,115,116, 68, 97,116, 97, 77, 97,115,107, 0,115,116,
- 97,116,101, 0,105,110,105,116, 95,115,116, 97,116,101, 0,103,112,117,108, 97,109,112, 0, 99,117,114,105,110,100,101,120, 0,
- 97, 99,116,105,118,101, 0,100,101,102,108,101, 99,116, 0,102,111,114, 99,101,102,105,101,108,100, 0,112,100,101,102, 95,100,
- 97,109,112, 0,112,100,101,102, 95,114,100, 97,109,112, 0,112,100,101,102, 95,112,101,114,109, 0,112,100,101,102, 95,102,114,
-105, 99,116, 0,112,100,101,102, 95,114,102,114,105, 99,116, 0,102, 95,115,116,114,101,110,103,116,104, 0,102, 95,112,111,119,
-101,114, 0,102, 95,100,105,115,116, 0,102, 95,100, 97,109,112, 0,109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116,
- 0,109, 97,120,114, 97,100, 0,109,105,110,114, 97,100, 0,102, 95,112,111,119,101,114, 95,114, 0,112,100,101,102, 95,115, 98,
-100, 97,109,112, 0,112,100,101,102, 95,115, 98,105,102,116, 0,112,100,101,102, 95,115, 98,111,102,116, 0, 99,108,117,109,112,
- 95,102, 97, 99, 0, 99,108,117,109,112, 95,112,111,119, 0,107,105,110,107, 95,102,114,101,113, 0,107,105,110,107, 95,115,104,
- 97,112,101, 0,107,105,110,107, 95, 97,109,112, 0,102,114,101,101, 95,101,110,100, 0,116,101,120, 95,110, 97, 98,108, 97, 0,
-116,101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110,107, 95, 97,120,105,115, 0,114,116, 50, 0, 42,114,110,103,
- 0,102, 95,110,111,105,115,101, 0,102,114, 97,109,101, 0,116,111,116,112,111,105,110,116, 0, 42,120,100, 97,116, 97, 0,115,
-116,101,112, 0,115,105,109,102,114, 97,109,101, 0,115,116, 97,114,116,102,114, 97,109,101, 0,101,110,100,102,114, 97,109,101,
- 0,101,100,105,116,102,114, 97,109,101, 0,108, 97,115,116, 95,101,120, 97, 99,116, 0,110, 97,109,101, 91, 54, 52, 93, 0,112,
-114,101,118, 95,110, 97,109,101, 91, 54, 52, 93, 0,105,110,102,111, 91, 54, 52, 93, 0,112, 97,116,104, 91, 50, 52, 48, 93, 0,
-109,101,109, 95, 99, 97, 99,104,101, 0,108,105,110, 83,116,105,102,102, 0, 97,110,103, 83,116,105,102,102, 0,118,111,108,117,
-109,101, 0,118,105,116,101,114, 97,116,105,111,110,115, 0,112,105,116,101,114, 97,116,105,111,110,115, 0,100,105,116,101,114,
- 97,116,105,111,110,115, 0, 99,105,116,101,114, 97,116,105,111,110,115, 0,107, 83, 82, 72, 82, 95, 67, 76, 0,107, 83, 75, 72,
- 82, 95, 67, 76, 0,107, 83, 83, 72, 82, 95, 67, 76, 0,107, 83, 82, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 83, 75, 95, 83, 80,
- 76, 84, 95, 67, 76, 0,107, 83, 83, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 86, 67, 70, 0,107, 68, 80, 0,107, 68, 71, 0,107,
- 76, 70, 0,107, 80, 82, 0,107, 86, 67, 0,107, 68, 70, 0,107, 77, 84, 0,107, 67, 72, 82, 0,107, 75, 72, 82, 0,107, 83, 72,
- 82, 0,107, 65, 72, 82, 0, 99,111,108,108,105,115,105,111,110,102,108, 97,103,115, 0,110,117,109, 99,108,117,115,116,101,114,
-105,116,101,114, 97,116,105,111,110,115, 0,119,101,108,100,105,110,103, 0, 42,112, 97,114,116,105, 99,108,101,115, 0,116,111,
-116,115,112,114,105,110,103, 0, 42, 98,112,111,105,110,116, 0, 42, 98,115,112,114,105,110,103, 0,109,115,103, 95,108,111, 99,
-107, 0,109,115,103, 95,118, 97,108,117,101, 0,110,111,100,101,109, 97,115,115, 0,110, 97,109,101,100, 86, 71, 95, 77, 97,115,
-115, 91, 51, 50, 93, 0,103,114, 97,118, 0,109,101,100,105, 97,102,114,105, 99,116, 0,114,107,108,105,109,105,116, 0,112,104,
-121,115,105, 99,115, 95,115,112,101,101,100, 0,103,111, 97,108,115,112,114,105,110,103, 0,103,111, 97,108,102,114,105, 99,116,
- 0,109,105,110,103,111, 97,108, 0,109, 97,120,103,111, 97,108, 0,100,101,102,103,111, 97,108, 0,118,101,114,116,103,114,111,
-117,112, 0,110, 97,109,101,100, 86, 71, 95, 83,111,102,116,103,111, 97,108, 91, 51, 50, 93, 0,102,117,122,122,121,110,101,115,
-115, 0,105,110,115,112,114,105,110,103, 0,105,110,102,114,105, 99,116, 0,110, 97,109,101,100, 86, 71, 95, 83,112,114,105,110,
-103, 95, 75, 91, 51, 50, 93, 0,101,102,114, 97, 0,105,110,116,101,114,118, 97,108, 0,108,111, 99, 97,108, 0,115,111,108,118,
-101,114,102,108, 97,103,115, 0, 42, 42,107,101,121,115, 0,116,111,116,112,111,105,110,116,107,101,121, 0,115,101, 99,111,110,
-100,115,112,114,105,110,103, 0, 99,111,108, 98, 97,108,108, 0, 98, 97,108,108,100, 97,109,112, 0, 98, 97,108,108,115,116,105,
-102,102, 0,115, 98, 99, 95,109,111,100,101, 0, 97,101,114,111,101,100,103,101, 0,109,105,110,108,111,111,112,115, 0,109, 97,
-120,108,111,111,112,115, 0, 99,104,111,107,101, 0,115,111,108,118,101,114, 95, 73, 68, 0,112,108, 97,115,116,105, 99, 0,115,
-112,114,105,110,103,112,114,101,108,111, 97,100, 0, 42,115, 99,114, 97,116, 99,104, 0,115,104,101, 97,114,115,116,105,102,102,
- 0,105,110,112,117,115,104, 0, 42,112,111,105,110,116, 99, 97, 99,104,101, 0,115,104,111,119, 95, 97,100,118, 97,110, 99,101,
-100,111,112,116,105,111,110,115, 0,114,101,115,111,108,117,116,105,111,110,120,121,122, 0,112,114,101,118,105,101,119,114,101,
-115,120,121,122, 0,114,101, 97,108,115,105,122,101, 0,103,117,105, 68,105,115,112,108, 97,121, 77,111,100,101, 0,114,101,110,
-100,101,114, 68,105,115,112,108, 97,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, 86, 97,108,117,101, 0,118,105,
-115, 99,111,115,105,116,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, 69,120,112,111,110,101,110,116, 0,103,114,
- 97,118,120, 0,103,114, 97,118,121, 0,103,114, 97,118,122, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69,110,
-100, 0,103,115,116, 97,114, 0,109, 97,120, 82,101,102,105,110,101, 0,105,110,105, 86,101,108,120, 0,105,110,105, 86,101,108,
-121, 0,105,110,105, 86,101,108,122, 0, 42,111,114,103, 77,101,115,104, 0, 42,109,101,115,104, 83,117,114,102, 97, 99,101, 0,
- 42,109,101,115,104, 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 50, 52, 48, 93, 0, 98, 98, 83,116, 97,114,
-116, 91, 51, 93, 0, 98, 98, 83,105,122,101, 91, 51, 93, 0,116,121,112,101, 70,108, 97,103,115, 0,100,111,109, 97,105,110, 78,
-111,118,101, 99,103,101,110, 0,118,111,108,117,109,101, 73,110,105,116, 84,121,112,101, 0,112, 97,114,116, 83,108,105,112, 86,
- 97,108,117,101, 0,103,101,110,101,114, 97,116,101, 84,114, 97, 99,101,114,115, 0,103,101,110,101,114, 97,116,101, 80, 97,114,
-116,105, 99,108,101,115, 0,115,117,114,102, 97, 99,101, 83,109,111,111,116,104,105,110,103, 0,115,117,114,102, 97, 99,101, 83,
-117, 98,100,105,118,115, 0,112, 97,114,116,105, 99,108,101, 73,110,102, 83,105,122,101, 0,112, 97,114,116,105, 99,108,101, 73,
-110,102, 65,108,112,104, 97, 0,102, 97,114, 70,105,101,108,100, 83,105,122,101, 0, 42,109,101,115,104, 83,117,114,102, 78,111,
-114,109, 97,108,115, 0, 99,112,115, 84,105,109,101, 83,116, 97,114,116, 0, 99,112,115, 84,105,109,101, 69,110,100, 0, 99,112,
-115, 81,117, 97,108,105,116,121, 0, 97,116,116,114, 97, 99,116,102,111,114, 99,101, 83,116,114,101,110,103,116,104, 0, 97,116,
-116,114, 97, 99,116,102,111,114, 99,101, 82, 97,100,105,117,115, 0,118,101,108,111, 99,105,116,121,102,111,114, 99,101, 83,116,
-114,101,110,103,116,104, 0,118,101,108,111, 99,105,116,121,102,111,114, 99,101, 82, 97,100,105,117,115, 0,108, 97,115,116,103,
-111,111,100,102,114, 97,109,101, 0,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,
-104,111,114,107, 0,122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,122,101,110,107, 0, 97,109, 98,107, 0,102, 97,
-115,116, 99,111,108, 0,101,120,112,111,115,117,114,101, 0,101,120,112, 0,114, 97,110,103,101, 0,108,105,110,102, 97, 99, 0,
-108,111,103,102, 97, 99, 0,103,114, 97,118,105,116,121, 0, 97, 99,116,105,118,105,116,121, 66,111,120, 82, 97,100,105,117,115,
- 0,115,107,121,116,121,112,101, 0,111, 99, 99,108,117,115,105,111,110, 82,101,115, 0,112,104,121,115,105, 99,115, 69,110,103,
-105,110,101, 0,116,105, 99,114, 97,116,101, 0,109, 97,120,108,111,103,105, 99,115,116,101,112, 0,112,104,121,115,117, 98,115,
-116,101,112, 0,109, 97,120,112,104,121,115,116,101,112, 0,109,105,115,105, 0,109,105,115,116,115,116, 97, 0,109,105,115,116,
-100,105,115,116, 0,109,105,115,116,104,105, 0,115,116, 97,114,114, 0,115,116, 97,114,103, 0,115,116, 97,114, 98, 0,115,116,
- 97,114,107, 0,115,116, 97,114,115,105,122,101, 0,115,116, 97,114,109,105,110,100,105,115,116, 0,115,116, 97,114,100,105,115,
-116, 0,115,116, 97,114, 99,111,108,110,111,105,115,101, 0,100,111,102,115,116, 97, 0,100,111,102,101,110,100, 0,100,111,102,
-109,105,110, 0,100,111,102,109, 97,120, 0, 97,111,100,105,115,116, 0, 97,111,100,105,115,116,102, 97, 99, 0, 97,111,101,110,
-101,114,103,121, 0, 97,111, 98,105, 97,115, 0, 97,111,109,111,100,101, 0, 97,111,115, 97,109,112, 0, 97,111,109,105,120, 0,
- 97,111, 99,111,108,111,114, 0, 97,111, 95, 97,100, 97,112,116, 95,116,104,114,101,115,104, 0, 97,111, 95, 97,100, 97,112,116,
- 95,115,112,101,101,100, 95,102, 97, 99, 0, 97,111, 95, 97,112,112,114,111,120, 95,101,114,114,111,114, 0, 97,111, 95, 97,112,
-112,114,111,120, 95, 99,111,114,114,101, 99,116,105,111,110, 0, 97,111, 95,115, 97,109,112, 95,109,101,116,104,111,100, 0, 97,
-111, 95,103, 97,116,104,101,114, 95,109,101,116,104,111,100, 0, 97,111, 95, 97,112,112,114,111,120, 95,112, 97,115,115,101,115,
- 0, 42, 97,111,115,112,104,101,114,101, 0, 42, 97,111,116, 97, 98,108,101,115, 0,115,101,108, 99,111,108, 0,115,120, 0,115,
-121, 0, 42,108,112, 70,111,114,109, 97,116, 0, 42,108,112, 80, 97,114,109,115, 0, 99, 98, 70,111,114,109, 97,116, 0, 99, 98,
- 80, 97,114,109,115, 0,102, 99, 99, 84,121,112,101, 0,102, 99, 99, 72, 97,110,100,108,101,114, 0,100,119, 75,101,121, 70,114,
- 97,109,101, 69,118,101,114,121, 0,100,119, 81,117, 97,108,105,116,121, 0,100,119, 66,121,116,101,115, 80,101,114, 83,101, 99,
-111,110,100, 0,100,119, 70,108, 97,103,115, 0,100,119, 73,110,116,101,114,108,101, 97,118,101, 69,118,101,114,121, 0, 97,118,
-105, 99,111,100,101, 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, 42, 99,100, 80, 97,114,109,115, 0, 42,112, 97,100, 0, 99,100,
- 83,105,122,101, 0,113,116, 99,111,100,101, 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, 99,111,100,101, 99, 0, 97,117,100,105,
-111, 95, 99,111,100,101, 99, 0,118,105,100,101,111, 95, 98,105,116,114, 97,116,101, 0, 97,117,100,105,111, 95, 98,105,116,114,
- 97,116,101, 0,103,111,112, 95,115,105,122,101, 0,114, 99, 95,109,105,110, 95,114, 97,116,101, 0,114, 99, 95,109, 97,120, 95,
-114, 97,116,101, 0,114, 99, 95, 98,117,102,102,101,114, 95,115,105,122,101, 0,109,117,120, 95,112, 97, 99,107,101,116, 95,115,
-105,122,101, 0,109,117,120, 95,114, 97,116,101, 0,109,105,120,114, 97,116,101, 0,109, 97,105,110, 0, 42,109, 97,116, 95,111,
-118,101,114,114,105,100,101, 0, 42,108,105,103,104,116, 95,111,118,101,114,114,105,100,101, 0,108, 97,121, 95,122,109, 97,115,
-107, 0,108, 97,121,102,108, 97,103, 0,112, 97,115,115,102,108, 97,103, 0,112, 97,115,115, 95,120,111,114, 0, 42, 97,118,105,
- 99,111,100,101, 99,100, 97,116, 97, 0, 42,113,116, 99,111,100,101, 99,100, 97,116, 97, 0,102,102, 99,111,100,101, 99,100, 97,
-116, 97, 0, 97,117,100,105,111, 0,112,115,102,114, 97, 0,112,101,102,114, 97, 0,105,109, 97,103,101,115, 0,102,114, 97,109,
- 97,112,116,111, 0,116,104,114,101, 97,100,115, 0,102,114, 97,109,101,108,101,110, 0, 98,108,117,114,102, 97, 99, 0,101,100,
-103,101, 82, 0,101,100,103,101, 71, 0,101,100,103,101, 66, 0,102,117,108,108,115, 99,114,101,101,110, 0,120,112,108, 97,121,
- 0,121,112,108, 97,121, 0,102,114,101,113,112,108, 97,121, 0, 97,116,116,114,105, 98, 0,114,116, 49, 0,115,116,101,114,101,
-111,109,111,100,101, 0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116, 0,109, 97,120,105,109,115,105,122,101,
- 0,120,115, 99,104, 0,121,115, 99,104, 0,120,112, 97,114,116,115, 0,121,112, 97,114,116,115, 0,119,105,110,112,111,115, 0,
-112,108, 97,110,101,115, 0,105,109,116,121,112,101, 0,115,117, 98,105,109,116,121,112,101, 0,113,117, 97,108,105,116,121, 0,
-100,105,115,112,108, 97,121,109,111,100,101, 0,114,112, 97,100, 49, 0,114,112, 97,100, 50, 0,115, 99,101,109,111,100,101, 0,
-114,101,110,100,101,114,101,114, 0,111, 99,114,101,115, 0, 97,108,112,104, 97,109,111,100,101, 0,111,115, 97, 0,102,114,115,
- 95,115,101, 99, 0,101,100,103,101,105,110,116, 0,115, 97,102,101,116,121, 0, 98,111,114,100,101,114, 0,100,105,115,112,114,
-101, 99,116, 0,108, 97,121,101,114,115, 0, 97, 99,116,108, 97,121, 0,120, 97,115,112, 0,121, 97,115,112, 0,102,114,115, 95,
-115,101, 99, 95, 98, 97,115,101, 0,103, 97,117,115,115, 0, 99,111,108,111,114, 95,109,103,116, 95,102,108, 97,103, 0,112,111,
-115,116,103, 97,109,109, 97, 0,112,111,115,116,104,117,101, 0,112,111,115,116,115, 97,116, 0,100,105,116,104,101,114, 95,105,
-110,116,101,110,115,105,116,121, 0, 98, 97,107,101, 95,111,115, 97, 0, 98, 97,107,101, 95,102,105,108,116,101,114, 0, 98, 97,
-107,101, 95,109,111,100,101, 0, 98, 97,107,101, 95,102,108, 97,103, 0, 98, 97,107,101, 95,110,111,114,109, 97,108, 95,115,112,
- 97, 99,101, 0, 98, 97,107,101, 95,113,117, 97,100, 95,115,112,108,105,116, 0, 98, 97,107,101, 95,109, 97,120,100,105,115,116,
- 0, 98, 97,107,101, 95, 98,105, 97,115,100,105,115,116, 0, 98, 97,107,101, 95,112, 97,100, 0, 71, 73,113,117, 97,108,105,116,
-121, 0, 71, 73, 99, 97, 99,104,101, 0, 71, 73,109,101,116,104,111,100, 0, 71, 73,112,104,111,116,111,110,115, 0, 71, 73,100,
-105,114,101, 99,116, 0, 89, 70, 95, 65, 65, 0, 89, 70,101,120,112,111,114,116,120,109,108, 0, 89, 70, 95,110,111, 98,117,109,
-112, 0, 89, 70, 95, 99,108, 97,109,112,114,103, 98, 0,121,102,112, 97,100, 49, 0, 71, 73,100,101,112,116,104, 0, 71, 73, 99,
- 97,117,115,100,101,112,116,104, 0, 71, 73,112,105,120,101,108,115,112,101,114,115, 97,109,112,108,101, 0, 71, 73,112,104,111,
-116,111,110, 99,111,117,110,116, 0, 71, 73,109,105,120,112,104,111,116,111,110,115, 0, 71, 73,112,104,111,116,111,110,114, 97,
-100,105,117,115, 0, 89, 70, 95,114, 97,121,100,101,112,116,104, 0, 89, 70, 95, 65, 65,112, 97,115,115,101,115, 0, 89, 70, 95,
- 65, 65,115, 97,109,112,108,101,115, 0,121,102,112, 97,100, 50, 0, 71, 73,115,104, 97,100,111,119,113,117, 97,108,105,116,121,
- 0, 71, 73,114,101,102,105,110,101,109,101,110,116, 0, 71, 73,112,111,119,101,114, 0, 71, 73,105,110,100,105,114,112,111,119,
-101,114, 0, 89, 70, 95,103, 97,109,109, 97, 0, 89, 70, 95,101,120,112,111,115,117,114,101, 0, 89, 70, 95,114, 97,121, 98,105,
- 97,115, 0, 89, 70, 95, 65, 65,112,105,120,101,108,115,105,122,101, 0, 89, 70, 95, 65, 65,116,104,114,101,115,104,111,108,100,
- 0, 98, 97, 99,107, 98,117,102, 91, 49, 54, 48, 93, 0,112,105, 99, 91, 49, 54, 48, 93, 0,115,116, 97,109,112, 0,115,116, 97,
-109,112, 95,102,111,110,116, 95,105,100, 0,115,116, 97,109,112, 95,117,100, 97,116, 97, 91, 49, 54, 48, 93, 0,102,103, 95,115,
-116, 97,109,112, 91, 52, 93, 0, 98,103, 95,115,116, 97,109,112, 91, 52, 93, 0,115,105,109,112,108,105,102,121, 95,115,117, 98,
-115,117,114,102, 0,115,105,109,112,108,105,102,121, 95,115,104, 97,100,111,119,115, 97,109,112,108,101,115, 0,115,105,109,112,
-108,105,102,121, 95,112, 97,114,116,105, 99,108,101,115, 0,115,105,109,112,108,105,102,121, 95, 97,111,115,115,115, 0, 99,105,
-110,101,111,110,119,104,105,116,101, 0, 99,105,110,101,111,110, 98,108, 97, 99,107, 0, 99,105,110,101,111,110,103, 97,109,109,
- 97, 0,106,112, 50, 95,112,114,101,115,101,116, 0,106,112, 50, 95,100,101,112,116,104, 0,114,112, 97,100, 51, 0,100,111,109,
-101,114,101,115, 0,100,111,109,101,109,111,100,101, 0,100,111,109,101, 97,110,103,108,101, 0,100,111,109,101,116,105,108,116,
- 0,100,111,109,101,114,101,115, 98,117,102, 0, 42,100,111,109,101,116,101,120,116, 0,101,110,103,105,110,101, 91, 51, 50, 93,
- 0,112, 97,114,116,105, 99,108,101, 95,112,101,114, 99, 0,115,117, 98,115,117,114,102, 95,109, 97,120, 0,115,104, 97,100, 98,
-117,102,115, 97,109,112,108,101, 95,109, 97,120, 0, 97,111, 95,101,114,114,111,114, 0,116,105,108,116, 0,114,101,115, 98,117,
-102, 0, 42,119, 97,114,112,116,101,120,116, 0, 99,111,108, 91, 51, 93, 0,112, 97,100, 49, 49, 0,102,114, 97,109,105,110,103,
- 0,100,111,109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0, 42, 98,114,117,115,104, 0,116,111,111,108, 0,115,101, 97,
-109, 95, 98,108,101,101,100, 0,110,111,114,109, 97,108, 95, 97,110,103,108,101, 0, 42,112, 97,105,110,116, 99,117,114,115,111,
-114, 0,105,110,118,101,114,116, 0,116,111,116,114,101,107,101,121, 0,116,111,116, 97,100,100,107,101,121, 0, 98,114,117,115,
-104,116,121,112,101, 0, 98,114,117,115,104, 91, 55, 93, 0,101,109,105,116,116,101,114,100,105,115,116, 0,100,114, 97,119, 95,
-116,105,109,101,100, 0,115,101,108,101, 99,116,109,111,100,101, 0,110, 97,109,101, 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93,
- 91, 51, 93, 0, 42,115,101,115,115,105,111,110, 0,112,105,118,111,116, 91, 51, 93, 0,116,101,120,115,101,112, 0,116, 97, 98,
-108,101,116, 95,115,105,122,101, 0,116, 97, 98,108,101,116, 95,115,116,114,101,110,103,116,104, 0,112, 97,100, 91, 53, 93, 0,
-103, 97,109,109, 97, 0,109,117,108, 0, 42,118,112, 97,105,110,116, 95,112,114,101,118, 0, 42,119,112, 97,105,110,116, 95,112,
-114,101,118, 0, 42,118,112, 97,105,110,116, 0, 42,119,112, 97,105,110,116, 0, 42,115, 99,117,108,112,116, 0,118,103,114,111,
-117,112, 95,119,101,105,103,104,116, 0, 99,111,114,110,101,114,116,121,112,101, 0,101,100,105,116, 98,117,116,102,108, 97,103,
- 0,106,111,105,110,116,114,105,108,105,109,105,116, 0,100,101,103,114, 0,116,117,114,110, 0,101,120,116,114, 95,111,102,102,
-115, 0,100,111,117, 98,108,105,109,105,116, 0,110,111,114,109, 97,108,115,105,122,101, 0, 97,117,116,111,109,101,114,103,101,
- 0,115,101,103,109,101,110,116,115, 0,114,105,110,103,115, 0,118,101,114,116,105, 99,101,115, 0,117,110,119,114, 97,112,112,
-101,114, 0,117,118, 99, 97,108, 99, 95,114, 97,100,105,117,115, 0,117,118, 99, 97,108, 99, 95, 99,117, 98,101,115,105,122,101,
- 0,117,118, 99, 97,108, 99, 95,109, 97,114,103,105,110, 0,117,118, 99, 97,108, 99, 95,109, 97,112,100,105,114, 0,117,118, 99,
- 97,108, 99, 95,109, 97,112, 97,108,105,103,110, 0,117,118, 99, 97,108, 99, 95,102,108, 97,103, 0,117,118, 95,102,108, 97,103,
- 0,117,118, 95,115,101,108,101, 99,116,109,111,100,101, 0,117,118, 95,112, 97,100, 91, 50, 93, 0, 97,117,116,111,105,107, 95,
- 99,104, 97,105,110,108,101,110, 0,105,109, 97,112, 97,105,110,116, 0,112, 97,114,116,105, 99,108,101, 0,112,114,111,112,111,
-114,116,105,111,110, 97,108, 95,115,105,122,101, 0,115,101,108,101, 99,116, 95,116,104,114,101,115,104, 0, 99,108,101, 97,110,
- 95,116,104,114,101,115,104, 0, 97,117,116,111,107,101,121, 95,109,111,100,101, 0,114,101,116,111,112,111, 95,109,111,100,101,
- 0,114,101,116,111,112,111, 95,112, 97,105,110,116, 95,116,111,111,108, 0,108,105,110,101, 95,100,105,118, 0,101,108,108,105,
-112,115,101, 95,100,105,118, 0,114,101,116,111,112,111, 95,104,111,116,115,112,111,116, 0,109,117,108,116,105,114,101,115, 95,
-115,117, 98,100,105,118, 95,116,121,112,101, 0,115,107,103,101,110, 95,114,101,115,111,108,117,116,105,111,110, 0,115,107,103,
-101,110, 95,116,104,114,101,115,104,111,108,100, 95,105,110,116,101,114,110, 97,108, 0,115,107,103,101,110, 95,116,104,114,101,
-115,104,111,108,100, 95,101,120,116,101,114,110, 97,108, 0,115,107,103,101,110, 95,108,101,110,103,116,104, 95,114, 97,116,105,
-111, 0,115,107,103,101,110, 95,108,101,110,103,116,104, 95,108,105,109,105,116, 0,115,107,103,101,110, 95, 97,110,103,108,101,
- 95,108,105,109,105,116, 0,115,107,103,101,110, 95, 99,111,114,114,101,108, 97,116,105,111,110, 95,108,105,109,105,116, 0,115,
-107,103,101,110, 95,115,121,109,109,101,116,114,121, 95,108,105,109,105,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,
-101,116, 95, 97,110,103,108,101, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,108,
-101,110,103,116,104, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,100,105,115,116,
- 97,110, 99,101, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,111,112,116,105,111,110,115, 0,115,107,103,101,110, 95,
-112,111,115,116,112,114,111, 0,115,107,103,101,110, 95,112,111,115,116,112,114,111, 95,112, 97,115,115,101,115, 0,115,107,103,
-101,110, 95,115,117, 98,100,105,118,105,115,105,111,110,115, 91, 51, 93, 0,115,107,103,101,110, 95,109,117,108,116,105, 95,108,
-101,118,101,108, 0, 42,115,107,103,101,110, 95,116,101,109,112,108, 97,116,101, 0, 98,111,110,101, 95,115,107,101,116, 99,104,
-105,110,103, 0, 98,111,110,101, 95,115,107,101,116, 99,104,105,110,103, 95, 99,111,110,118,101,114,116, 0,115,107,103,101,110,
- 95,115,117, 98,100,105,118,105,115,105,111,110, 95,110,117,109, 98,101,114, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,
-101,116, 95,111,112,116,105,111,110,115, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,114,111,108,108, 0,115,
-107,103,101,110, 95,115,105,100,101, 95,115,116,114,105,110,103, 91, 56, 93, 0,115,107,103,101,110, 95,110,117,109, 95,115,116,
-114,105,110,103, 91, 56, 93, 0,101,100,103,101, 95,109,111,100,101, 0,115,110, 97,112, 95,109,111,100,101, 0,115,110, 97,112,
- 95,102,108, 97,103, 0,115,110, 97,112, 95,116, 97,114,103,101,116, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 0,112,
-114,111,112, 95,109,111,100,101, 0,116,111,116,111, 98,106, 0,116,111,116,108, 97,109,112, 0,116,111,116,111, 98,106,115,101,
-108, 0,116,111,116, 99,117,114,118,101, 0,116,111,116,109,101,115,104, 0,116,111,116, 97,114,109, 97,116,117,114,101, 0, 42,
- 99, 97,109,101,114, 97, 0, 42,119,111,114,108,100, 0, 42,115,101,116, 0, 98, 97,115,101, 0, 42, 98, 97,115, 97, 99,116, 0,
- 42,111, 98,101,100,105,116, 0, 99,117,114,115,111,114, 91, 51, 93, 0,116,119, 99,101,110,116, 91, 51, 93, 0,116,119,109,105,
-110, 91, 51, 93, 0,116,119,109, 97,120, 91, 51, 93, 0, 42,101,100, 0, 42,116,111,111,108,115,101,116,116,105,110,103,115, 0,
- 42,115,116, 97,116,115, 0,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0, 42,116,104,101, 68, 97,103, 0,
-100, 97,103,105,115,118, 97,108,105,100, 0,100, 97,103,102,108, 97,103,115, 0,106,117,109,112,102,114, 97,109,101, 0,102,114,
- 97,109,101, 95,115,116,101,112, 0, 97, 99,116,105,118,101, 95,107,101,121,105,110,103,115,101,116, 0,107,101,121,105,110,103,
-115,101,116,115, 0,103,109, 0, 98,108,101,110,100, 0,119,105,110,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,109,
- 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,105,110,118, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,109, 97,116, 91, 52,
- 93, 91, 52, 93, 0,112,101,114,115,105,110,118, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,109, 97,116,111, 98, 91, 52, 93, 91,
- 52, 93, 0,112,101,114,115,109, 97,116,111, 98, 91, 52, 93, 91, 52, 93, 0,116,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,
-105,101,119,113,117, 97,116, 91, 52, 93, 0,122,102, 97, 99, 0, 99, 97,109,100,120, 0, 99, 97,109,100,121, 0,112,105,120,115,
-105,122,101, 0, 99, 97,109,122,111,111,109, 0,118,105,101,119, 98,117,116, 0,108, 97,115,116,109,111,100,101, 0,114,102,108,
- 97,103, 0,118,105,101,119,108,111, 99,107, 0,112,101,114,115,112, 0,118,105,101,119, 0, 99,108,105,112, 91, 54, 93, 91, 52,
- 93, 0, 42, 99,108,105,112, 98, 98, 0, 42,103,112,100, 0, 42,108,111, 99, 97,108,118,100, 0, 42,114,105, 0, 42,114,101,116,
-111,112,111, 95,118,105,101,119, 95,100, 97,116, 97, 0, 42,100,101,112,116,104,115, 0, 42,115,109,115, 0, 42,115,109,111,111,
-116,104, 95,116,105,109,101,114, 0,108,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,108,112,101,114,115,112, 0,108,118,105,
-101,119, 0,114,101,103,105,111,110, 98, 97,115,101, 0,115,112, 97, 99,101,116,121,112,101, 0, 98,108,111, 99,107,115, 99, 97,
-108,101, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 93, 0,108, 97,121, 95,117,115,101,100, 0, 42,111, 98, 95,
- 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 0,111, 98, 95, 99,101,110,116,114,101, 95, 98,111,110,101, 91, 51, 50, 93,
- 0,108, 97,121, 97, 99,116, 0,100,114, 97,119,116,121,112,101, 0,108,111, 99, 97,108,118,105,101,119, 0,115, 99,101,110,101,
-108,111, 99,107, 0, 97,114,111,117,110,100, 0,102,108, 97,103, 50, 0,112,105,118,111,116, 95,108, 97,115,116, 0,103,114,105,
-100, 0,103,114,105,100,118,105,101,119, 0,112, 97,100,102, 0,110,101, 97,114, 0,102, 97,114, 0,103,114,105,100,108,105,110,
-101,115, 0,103,114,105,100,102,108, 97,103, 0,103,114,105,100,115,117, 98,100,105,118, 0,109,111,100,101,115,101,108,101, 99,
-116, 0,107,101,121,102,108, 97,103,115, 0,116,119,116,121,112,101, 0,116,119,109,111,100,101, 0,116,119,102,108, 97,103, 0,
-116,119,100,114, 97,119,102,108, 97,103, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 0, 97,102,116,101,114,
-100,114, 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 0,110,100,111,102,109,111,100,101, 0,110,100,111,102,102,105,108,116,
-101,114, 0, 42,112,114,111,112,101,114,116,105,101,115, 95,115,116,111,114, 97,103,101, 0,118,101,114,116, 0,104,111,114, 0,
-109, 97,115,107, 0,109,105,110, 91, 50, 93, 0,109, 97,120, 91, 50, 93, 0,109,105,110,122,111,111,109, 0,109, 97,120,122,111,
-111,109, 0,115, 99,114,111,108,108, 0,115, 99,114,111,108,108, 95,117,105, 0,107,101,101,112,116,111,116, 0,107,101,101,112,
-122,111,111,109, 0,107,101,101,112,111,102,115, 0, 97,108,105,103,110, 0,119,105,110,120, 0,119,105,110,121, 0,111,108,100,
-119,105,110,120, 0,111,108,100,119,105,110,121, 0, 99,117,114,115,111,114, 91, 50, 93, 0, 42,116, 97, 98, 95,111,102,102,115,
-101,116, 0,116, 97, 98, 95,110,117,109, 0,116, 97, 98, 95, 99,117,114, 0, 42,115, 99,114,101,101,110, 0,118, 50,100, 0, 42,
- 97,100,115, 0,103,104,111,115,116, 67,117,114,118,101,115, 0, 97,117,116,111,115,110, 97,112, 0,112,105,110, 0,108,111, 99,
-107, 0,109, 97,105,110, 98, 0,109, 97,105,110, 98,111, 0,109, 97,105,110, 98,117,115,101,114, 0,114,101, 95, 97,108,105,103,
-110, 0,112,114,101,118,105,101,119, 0,112, 97,116,104,102,108, 97,103, 0,100, 97,116, 97,105, 99,111,110, 0, 42,112,105,110,
-105,100, 0,114,101,110,100,101,114, 95,115,105,122,101, 0, 99,104, 97,110,115,104,111,119,110, 0,122,101, 98,114, 97, 0,122,
-111,111,109, 0,116,105,116,108,101, 91, 50, 52, 93, 0,100,105,114, 91, 50, 52, 48, 93, 0,102,105,108,101, 91, 56, 48, 93, 0,
-115,111,114,116, 0,100,105,115,112,108, 97,121, 0, 97, 99,116,105,118,101, 95, 98,111,111,107,109, 97,114,107, 0, 97, 99,116,
-105,118,101, 95,102,105,108,101, 0,115,101,108,115,116, 97,116,101, 0,102, 95,102,112, 0,109,101,110,117, 0,102,112, 95,115,
-116,114, 91, 56, 93, 0, 42,112,117,112,109,101,110,117, 0, 42,112, 97,114, 97,109,115, 0, 42,102,105,108,101,115, 0, 42,102,
-111,108,100,101,114,115, 95,112,114,101,118, 0, 42,102,111,108,100,101,114,115, 95,110,101,120,116, 0, 42,111,112, 0, 42,108,
-111, 97,100,105,109, 97,103,101, 95,116,105,109,101,114, 0, 42,108, 97,121,111,117,116, 0,114,101, 99,101,110,116,110,114, 0,
- 98,111,111,107,109, 97,114,107,110,114, 0,115,121,115,116,101,109,110,114, 0,116,114,101,101, 0, 42,116,114,101,101,115,116,
-111,114,101, 0,115,101, 97,114, 99,104, 95,115,116,114,105,110,103, 91, 51, 50, 93, 0,115,101, 97,114, 99,104, 95,116,115,101,
- 0,115,101, 97,114, 99,104, 95,102,108, 97,103,115, 0,100,111, 95, 0,111,117,116,108,105,110,101,118,105,115, 0,115,116,111,
-114,101,102,108, 97,103, 0, 42, 99,117,109, 97,112, 0,105,109, 97,110,114, 0, 99,117,114,116,105,108,101, 0,105,109,116,121,
-112,101,110,114, 0,100,116, 95,117,118, 0,115,116,105, 99,107,121, 0,100,116, 95,117,118,115,116,114,101,116, 99,104, 0, 99,
-101,110,116,120, 0, 99,101,110,116,121, 0, 42,116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, 0,108,
-104,101,105,103,104,116, 0, 99,119,105,100,116,104, 0,108,105,110,101,110,114,115, 95,116,111,116, 0,108,101,102,116, 0,115,
-104,111,119,108,105,110,101,110,114,115, 0,116, 97, 98,110,117,109, 98,101,114, 0,115,104,111,119,115,121,110,116, 97,120, 0,
-111,118,101,114,119,114,105,116,101, 0,108,105,118,101, 95,101,100,105,116, 0,112,105,120, 95,112,101,114, 95,108,105,110,101,
- 0,116,120,116,115, 99,114,111,108,108, 0,116,120,116, 98, 97,114, 0,119,111,114,100,119,114, 97,112, 0,100,111,112,108,117,
-103,105,110,115, 0,102,105,110,100,115,116,114, 91, 50, 53, 54, 93, 0,114,101,112,108, 97, 99,101,115,116,114, 91, 50, 53, 54,
- 93, 0, 42,112,121, 95,100,114, 97,119, 0, 42,112,121, 95,101,118,101,110,116, 0, 42,112,121, 95, 98,117,116,116,111,110, 0,
- 42,112,121, 95, 98,114,111,119,115,101,114, 99, 97,108,108, 98, 97, 99,107, 0, 42,112,121, 95,103,108,111, 98, 97,108,100,105,
- 99,116, 0,108, 97,115,116,115,112, 97, 99,101, 0,115, 99,114,105,112,116,110, 97,109,101, 91, 50, 53, 54, 93, 0,115, 99,114,
-105,112,116, 97,114,103, 91, 50, 53, 54, 93, 0, 42,115, 99,114,105,112,116, 0, 42, 98,117,116, 95,114,101,102,115, 0,114,101,
-100,114, 97,119,115, 0, 42,105,100, 0, 97,115,112,101, 99,116, 0, 42, 99,117,114,102,111,110,116, 0,109,120, 0,109,121, 0,
- 42,101,100,105,116,116,114,101,101, 0,116,114,101,101,116,121,112,101, 0,116,101,120,102,114,111,109, 0,110,117,109,116,105,
-108,101,115,120, 0,110,117,109,116,105,108,101,115,121, 0,118,105,101,119,114,101, 99,116, 0, 98,111,111,107,109, 97,114,107,
-114,101, 99,116, 0,115, 99,114,111,108,108,112,111,115, 0,115, 99,114,111,108,108,104,101,105,103,104,116, 0,115, 99,114,111,
-108,108, 97,114,101, 97, 0,114,101,116,118, 97,108, 0,112,114,118, 95,119, 0,112,114,118, 95,104, 0, 40, 42,114,101,116,117,
-114,110,102,117,110, 99, 41, 40, 41, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99, 95,101,118,101,110,116, 41, 40, 41, 0,
- 40, 42,114,101,116,117,114,110,102,117,110, 99, 95, 97,114,103,115, 41, 40, 41, 0, 42, 97,114,103, 49, 0, 42, 97,114,103, 50,
- 0, 42,109,101,110,117,112, 0, 42,105,109,103, 0,108,101,110, 95, 97,108,108,111, 99, 0, 99,117,114,115,111,114, 0,114,112,
-116, 95,109, 97,115,107, 0,115, 99,114,111,108,108, 98, 97, 99,107, 0,104,105,115,116,111,114,121, 0,112,114,111,109,112,116,
- 91, 56, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 53, 54, 93, 0, 98,108,102, 95,105,100, 0,117,105,102,111,110,116, 95,
-105,100, 0,114, 95,116,111, 95,108, 0,112,111,105,110,116,115, 0,107,101,114,110,105,110,103, 0,105,116, 97,108,105, 99, 0,
- 98,111,108,100, 0,115,104, 97,100,111,119, 0,115,104, 97,100,120, 0,115,104, 97,100,121, 0,115,104, 97,100,111,119, 97,108,
-112,104, 97, 0,115,104, 97,100,111,119, 99,111,108,111,114, 0,112, 97,110,101,108,116,105,116,108,101, 0,103,114,111,117,112,
-108, 97, 98,101,108, 0,119,105,100,103,101,116,108, 97, 98,101,108, 0,119,105,100,103,101,116, 0,112, 97,110,101,108,122,111,
-111,109, 0,109,105,110,108, 97, 98,101,108, 99,104, 97,114,115, 0,109,105,110,119,105,100,103,101,116, 99,104, 97,114,115, 0,
- 99,111,108,117,109,110,115,112, 97, 99,101, 0,116,101,109,112,108, 97,116,101,115,112, 97, 99,101, 0, 98,111,120,115,112, 97,
- 99,101, 0, 98,117,116,116,111,110,115,112, 97, 99,101,120, 0, 98,117,116,116,111,110,115,112, 97, 99,101,121, 0,112, 97,110,
-101,108,115,112, 97, 99,101, 0,112, 97,110,101,108,111,117,116,101,114, 0,112, 97,100, 91, 49, 93, 0,111,117,116,108,105,110,
-101, 91, 52, 93, 0,105,110,110,101,114, 91, 52, 93, 0,105,110,110,101,114, 95,115,101,108, 91, 52, 93, 0,105,116,101,109, 91,
- 52, 93, 0,116,101,120,116, 91, 52, 93, 0,116,101,120,116, 95,115,101,108, 91, 52, 93, 0,115,104, 97,100,101,100, 0,115,104,
- 97,100,101,116,111,112, 0,115,104, 97,100,101,100,111,119,110, 0,105,110,110,101,114, 95, 97,110,105,109, 91, 52, 93, 0,105,
-110,110,101,114, 95, 97,110,105,109, 95,115,101,108, 91, 52, 93, 0,105,110,110,101,114, 95,107,101,121, 91, 52, 93, 0,105,110,
-110,101,114, 95,107,101,121, 95,115,101,108, 91, 52, 93, 0,105,110,110,101,114, 95,100,114,105,118,101,110, 91, 52, 93, 0,105,
-110,110,101,114, 95,100,114,105,118,101,110, 95,115,101,108, 91, 52, 93, 0,119, 99,111,108, 95,114,101,103,117,108, 97,114, 0,
-119, 99,111,108, 95,116,111,111,108, 0,119, 99,111,108, 95,116,101,120,116, 0,119, 99,111,108, 95,114, 97,100,105,111, 0,119,
- 99,111,108, 95,111,112,116,105,111,110, 0,119, 99,111,108, 95,116,111,103,103,108,101, 0,119, 99,111,108, 95,110,117,109, 0,
-119, 99,111,108, 95,110,117,109,115,108,105,100,101,114, 0,119, 99,111,108, 95,109,101,110,117, 0,119, 99,111,108, 95,112,117,
-108,108,100,111,119,110, 0,119, 99,111,108, 95,109,101,110,117, 95, 98, 97, 99,107, 0,119, 99,111,108, 95,109,101,110,117, 95,
-105,116,101,109, 0,119, 99,111,108, 95, 98,111,120, 0,119, 99,111,108, 95,115, 99,114,111,108,108, 0,119, 99,111,108, 95,108,
-105,115,116, 95,105,116,101,109, 0,119, 99,111,108, 95,115,116, 97,116,101, 0,105, 99,111,110,102,105,108,101, 91, 56, 48, 93,
- 0, 98, 97, 99,107, 91, 52, 93, 0,116,105,116,108,101, 91, 52, 93, 0,116,101,120,116, 95,104,105, 91, 52, 93, 0,104,101, 97,
-100,101,114, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,105,116,108,101, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,101,
-120,116, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0, 98,117,116,116,111,110, 91, 52,
- 93, 0, 98,117,116,116,111,110, 95,116,105,116,108,101, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101,120,116, 91, 52, 93,
- 0, 98,117,116,116,111,110, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,108,105,115,116, 91, 52, 93, 0,108,105,115,116, 95,
-116,105,116,108,101, 91, 52, 93, 0,108,105,115,116, 95,116,101,120,116, 91, 52, 93, 0,108,105,115,116, 95,116,101,120,116, 95,
-104,105, 91, 52, 93, 0,112, 97,110,101,108, 91, 52, 93, 0,112, 97,110,101,108, 95,116,105,116,108,101, 91, 52, 93, 0,112, 97,
-110,101,108, 95,116,101,120,116, 91, 52, 93, 0,112, 97,110,101,108, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,115,104, 97,
-100,101, 49, 91, 52, 93, 0,115,104, 97,100,101, 50, 91, 52, 93, 0,104,105,108,105,116,101, 91, 52, 93, 0,103,114,105,100, 91,
- 52, 93, 0,119,105,114,101, 91, 52, 93, 0,115,101,108,101, 99,116, 91, 52, 93, 0,108, 97,109,112, 91, 52, 93, 0, 97, 99,116,
-105,118,101, 91, 52, 93, 0,103,114,111,117,112, 91, 52, 93, 0,103,114,111,117,112, 95, 97, 99,116,105,118,101, 91, 52, 93, 0,
-116,114, 97,110,115,102,111,114,109, 91, 52, 93, 0,118,101,114,116,101,120, 91, 52, 93, 0,118,101,114,116,101,120, 95,115,101,
-108,101, 99,116, 91, 52, 93, 0,101,100,103,101, 91, 52, 93, 0,101,100,103,101, 95,115,101,108,101, 99,116, 91, 52, 93, 0,101,
-100,103,101, 95,115,101, 97,109, 91, 52, 93, 0,101,100,103,101, 95,115,104, 97,114,112, 91, 52, 93, 0,101,100,103,101, 95,102,
- 97, 99,101,115,101,108, 91, 52, 93, 0,102, 97, 99,101, 91, 52, 93, 0,102, 97, 99,101, 95,115,101,108,101, 99,116, 91, 52, 93,
- 0,102, 97, 99,101, 95,100,111,116, 91, 52, 93, 0,110,111,114,109, 97,108, 91, 52, 93, 0, 98,111,110,101, 95,115,111,108,105,
-100, 91, 52, 93, 0, 98,111,110,101, 95,112,111,115,101, 91, 52, 93, 0,115,116,114,105,112, 91, 52, 93, 0,115,116,114,105,112,
- 95,115,101,108,101, 99,116, 91, 52, 93, 0, 99,102,114, 97,109,101, 91, 52, 93, 0,100,115, 95, 99,104, 97,110,110,101,108, 91,
- 52, 93, 0,100,115, 95,115,117, 98, 99,104, 97,110,110,101,108, 91, 52, 93, 0,118,101,114,116,101,120, 95,115,105,122,101, 0,
-102, 97, 99,101,100,111,116, 95,115,105,122,101, 0, 98,112, 97,100, 91, 50, 93, 0,115,121,110,116, 97,120,108, 91, 52, 93, 0,
-115,121,110,116, 97,120,110, 91, 52, 93, 0,115,121,110,116, 97,120, 98, 91, 52, 93, 0,115,121,110,116, 97,120,118, 91, 52, 93,
- 0,115,121,110,116, 97,120, 99, 91, 52, 93, 0,109,111,118,105,101, 91, 52, 93, 0,105,109, 97,103,101, 91, 52, 93, 0,115, 99,
-101,110,101, 91, 52, 93, 0, 97,117,100,105,111, 91, 52, 93, 0,101,102,102,101, 99,116, 91, 52, 93, 0,112,108,117,103,105,110,
- 91, 52, 93, 0,116,114, 97,110,115,105,116,105,111,110, 91, 52, 93, 0,109,101,116, 97, 91, 52, 93, 0,101,100,105,116,109,101,
-115,104, 95, 97, 99,116,105,118,101, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 91, 52, 93, 0,104, 97,
-110,100,108,101, 95,118,101,114,116,101,120, 95,115,101,108,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,
-116,101,120, 95,115,105,122,101, 0,104,112, 97,100, 91, 51, 93, 0,115,111,108,105,100, 91, 52, 93, 0,116,117,105, 0,116, 98,
-117,116,115, 0,116,118, 51,100, 0,116,102,105,108,101, 0,116,105,112,111, 0,116,105,110,102,111, 0,116,115,110,100, 0,116,
- 97, 99,116, 0,116,110,108, 97, 0,116,115,101,113, 0,116,105,109, 97, 0,116,105,109, 97,115,101,108, 0,116,101,120,116, 0,
-116,111,111,112,115, 0,116,116,105,109,101, 0,116,110,111,100,101, 0,116,108,111,103,105, 99, 0,116, 97,114,109, 91, 50, 48,
- 93, 0,115,112,101, 99, 91, 52, 93, 0,100,117,112,102,108, 97,103, 0,115, 97,118,101,116,105,109,101, 0,116,101,109,112,100,
-105,114, 91, 49, 54, 48, 93, 0,102,111,110,116,100,105,114, 91, 49, 54, 48, 93, 0,114,101,110,100,101,114,100,105,114, 91, 49,
- 54, 48, 93, 0,116,101,120,116,117,100,105,114, 91, 49, 54, 48, 93, 0,112,108,117,103,116,101,120,100,105,114, 91, 49, 54, 48,
- 93, 0,112,108,117,103,115,101,113,100,105,114, 91, 49, 54, 48, 93, 0,112,121,116,104,111,110,100,105,114, 91, 49, 54, 48, 93,
- 0,115,111,117,110,100,100,105,114, 91, 49, 54, 48, 93, 0,121,102,101,120,112,111,114,116,100,105,114, 91, 49, 54, 48, 93, 0,
-118,101,114,115,105,111,110,115, 0,103, 97,109,101,102,108, 97,103,115, 0,119,104,101,101,108,108,105,110,101,115, 99,114,111,
-108,108, 0,117,105,102,108, 97,103, 0,108, 97,110,103,117, 97,103,101, 0,117,115,101,114,112,114,101,102, 0,118,105,101,119,
-122,111,111,109, 0,109,105,120, 98,117,102,115,105,122,101, 0,100,112,105, 0,101,110, 99,111,100,105,110,103, 0,116,114, 97,
-110,115,111,112,116,115, 0,109,101,110,117,116,104,114,101,115,104,111,108,100, 49, 0,109,101,110,117,116,104,114,101,115,104,
-111,108,100, 50, 0,116,104,101,109,101,115, 0,117,105,102,111,110,116,115, 0,117,105,115,116,121,108,101,115, 0,117,110,100,
-111,115,116,101,112,115, 0,117,110,100,111,109,101,109,111,114,121, 0,103,112, 95,109, 97,110,104, 97,116,116,101,110,100,105,
-115,116, 0,103,112, 95,101,117, 99,108,105,100,101, 97,110,100,105,115,116, 0,103,112, 95,101,114, 97,115,101,114, 0,103,112,
- 95,115,101,116,116,105,110,103,115, 0,116, 98, 95,108,101,102,116,109,111,117,115,101, 0,116, 98, 95,114,105,103,104,116,109,
-111,117,115,101, 0,108,105,103,104,116, 91, 51, 93, 0,116,119, 95,104,111,116,115,112,111,116, 0,116,119, 95,102,108, 97,103,
- 0,116,119, 95,104, 97,110,100,108,101,115,105,122,101, 0,116,119, 95,115,105,122,101, 0,116,101,120,116,105,109,101,111,117,
-116, 0,116,101,120, 99,111,108,108,101, 99,116,114, 97,116,101, 0,119,109,100,114, 97,119,109,101,116,104,111,100, 0,119,109,
-112, 97,100, 0,109,101,109, 99, 97, 99,104,101,108,105,109,105,116, 0,112,114,101,102,101,116, 99,104,102,114, 97,109,101,115,
- 0,102,114, 97,109,101,115,101,114,118,101,114,112,111,114,116, 0,112, 97,100, 95,114,111,116, 95, 97,110,103,108,101, 0,111,
- 98, 99,101,110,116,101,114, 95,100,105, 97, 0,114,118,105,115,105,122,101, 0,114,118,105, 98,114,105,103,104,116, 0,114,101,
- 99,101,110,116, 95,102,105,108,101,115, 0,115,109,111,111,116,104, 95,118,105,101,119,116,120, 0,103,108,114,101,115,108,105,
-109,105,116, 0,110,100,111,102, 95,112, 97,110, 0,110,100,111,102, 95,114,111,116, 97,116,101, 0, 99,117,114,115,115,105,122,
-101, 0,105,112,111, 95,110,101,119, 0,118,101,114,115,101,109, 97,115,116,101,114, 91, 49, 54, 48, 93, 0,118,101,114,115,101,
-117,115,101,114, 91, 49, 54, 48, 93, 0,103,108, 97,108,112,104, 97, 99,108,105,112, 0, 97,117,116,111,107,101,121, 95,102,108,
- 97,103, 0, 99,111, 98, 97, 95,119,101,105,103,104,116, 0,118,101,114,116, 98, 97,115,101, 0,101,100,103,101, 98, 97,115,101,
- 0, 97,114,101, 97, 98, 97,115,101, 0, 42,110,101,119,115, 99,101,110,101, 0,102,117,108,108, 0,119,105,110,105,100, 0,100,
-111, 95,100,114, 97,119, 0,100,111, 95,114,101,102,114,101,115,104, 0,100,111, 95,100,114, 97,119, 95,103,101,115,116,117,114,
-101, 0,100,111, 95,100,114, 97,119, 95,112, 97,105,110,116, 99,117,114,115,111,114, 0,115,119, 97,112, 0,109, 97,105,110,119,
-105,110, 0,115,117, 98,119,105,110, 97, 99,116,105,118,101, 0, 42, 97,110,105,109,116,105,109,101,114, 0, 42, 99,111,110,116,
-101,120,116, 0,104, 97,110,100,108,101,114, 91, 56, 93, 0, 42,110,101,119,118, 0,118,101, 99, 0, 42,118, 49, 0, 42,118, 50,
- 0, 42,116,121,112,101, 0,112, 97,110,101,108,110, 97,109,101, 91, 54, 52, 93, 0,116, 97, 98,110, 97,109,101, 91, 54, 52, 93,
- 0,100,114, 97,119,110, 97,109,101, 91, 54, 52, 93, 0,111,102,115,120, 0,111,102,115,121, 0,115,105,122,101,120, 0,115,105,
-122,101,121, 0,108, 97, 98,101,108,111,102,115, 0,114,117,110,116,105,109,101, 95,102,108, 97,103, 0, 99,111,110,116,114,111,
-108, 0,115,110, 97,112, 0,115,111,114,116,111,114,100,101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0, 42, 97, 99,116,105,
-118,101,100, 97,116, 97, 0,108,105,115,116, 95,115, 99,114,111,108,108, 0,108,105,115,116, 95,115,105,122,101, 0,108,105,115,
-116, 95,115,101, 97,114, 99,104, 91, 54, 52, 93, 0, 42,118, 51, 0, 42,118, 52, 0, 42,102,117,108,108, 0, 98,117,116,115,112,
- 97, 99,101,116,121,112,101, 0,104,101, 97,100,101,114,116,121,112,101, 0,115,112, 97, 99,101,100, 97,116, 97, 0,104, 97,110,
-100,108,101,114,115, 0, 97, 99,116,105,111,110,122,111,110,101,115, 0,119,105,110,114, 99,116, 0,100,114, 97,119,114, 99,116,
- 0,115,119,105,110,105,100, 0,114,101,103,105,111,110,116,121,112,101, 0, 97,108,105,103,110,109,101,110,116, 0,117,105, 98,
-108,111, 99,107,115, 0,112, 97,110,101,108,115, 0, 42,104,101, 97,100,101,114,115,116,114, 0, 42,114,101,103,105,111,110,100,
- 97,116, 97, 0,115,117, 98,118,115,116,114, 91, 52, 93, 0,115,117, 98,118,101,114,115,105,111,110, 0,112, 97,100,115, 0,109,
-105,110,118,101,114,115,105,111,110, 0,109,105,110,115,117, 98,118,101,114,115,105,111,110, 0, 42, 99,117,114,115, 99,114,101,
-101,110, 0, 42, 99,117,114,115, 99,101,110,101, 0,102,105,108,101,102,108, 97,103,115, 0,103,108,111, 98, 97,108,102, 0,110,
- 97,109,101, 91, 56, 48, 93, 0, 42,105, 98,117,102, 0, 42,105, 98,117,102, 95, 99,111,109,112, 0, 42,115,101, 49, 0, 42,115,
-101, 50, 0, 42,115,101, 51, 0,110,114, 0, 98,111,116,116,111,109, 0,114,105,103,104,116, 0,120,111,102,115, 0,121,111,102,
-115, 0,108,105,102,116, 91, 51, 93, 0,103, 97,109,109, 97, 91, 51, 93, 0,103, 97,105,110, 91, 51, 93, 0,115, 97,116,117,114,
- 97,116,105,111,110, 0,100,105,114, 91, 49, 54, 48, 93, 0,100,111,110,101, 0,115,116, 97,114,116,115,116,105,108,108, 0,101,
-110,100,115,116,105,108,108, 0, 42,115,116,114,105,112,100, 97,116, 97, 0,111,114,120, 0,111,114,121, 0, 42, 99,114,111,112,
- 0, 42,116,114, 97,110,115,102,111,114,109, 0, 42, 99,111,108,111,114, 95, 98, 97,108, 97,110, 99,101, 0, 42,116,115,116,114,
-105,112,100, 97,116, 97, 0, 42,116,115,116,114,105,112,100, 97,116, 97, 95,115,116, 97,114,116,115,116,105,108,108, 0, 42,116,
-115,116,114,105,112,100, 97,116, 97, 95,101,110,100,115,116,105,108,108, 0, 42,105, 98,117,102, 95,115,116, 97,114,116,115,116,
-105,108,108, 0, 42,105, 98,117,102, 95,101,110,100,115,116,105,108,108, 0, 42,105,110,115,116, 97,110, 99,101, 95,112,114,105,
-118, 97,116,101, 95,100, 97,116, 97, 0, 42, 42, 99,117,114,114,101,110,116, 95,112,114,105,118, 97,116,101, 95,100, 97,116, 97,
- 0, 42,116,109,112, 0,115,116, 97,114,116,111,102,115, 0,101,110,100,111,102,115, 0,109, 97, 99,104,105,110,101, 0,115,116,
- 97,114,116,100,105,115,112, 0,101,110,100,100,105,115,112, 0,104, 97,110,100,115,105,122,101, 0, 97,110,105,109, 95,112,114,
-101,115,101,101,107, 0, 42,115,116,114,105,112, 0,102, 97, 99,102, 48, 0,102, 97, 99,102, 49, 0, 42,115,101,113, 49, 0, 42,
-115,101,113, 50, 0, 42,115,101,113, 51, 0,115,101,113, 98, 97,115,101, 0, 42,115,111,117,110,100, 0, 42,104,100, 97,117,100,
-105,111, 0,108,101,118,101,108, 0,112, 97,110, 0,115, 99,101,110,101,110,114, 0,115,116,114,111, 98,101, 0, 42,101,102,102,
-101, 99,116,100, 97,116, 97, 0, 97,110,105,109, 95,115,116, 97,114,116,111,102,115, 0, 97,110,105,109, 95,101,110,100,111,102,
-115, 0, 98,108,101,110,100, 95,109,111,100,101, 0, 98,108,101,110,100, 95,111,112, 97, 99,105,116,121, 0, 42,111,108,100, 98,
- 97,115,101,112, 0, 42,112, 97,114,115,101,113, 0, 42,115,101,113, 98, 97,115,101,112, 0,109,101,116, 97,115,116, 97, 99,107,
- 0, 42, 97, 99,116, 95,115,101,113, 0, 97, 99,116, 95,105,109, 97,103,101,100,105,114, 91, 50, 53, 54, 93, 0, 97, 99,116, 95,
-115,111,117,110,100,100,105,114, 91, 50, 53, 54, 93, 0,101,100,103,101, 87,105,100,116,104, 0,102,111,114,119, 97,114,100, 0,
-119,105,112,101,116,121,112,101, 0,102, 77,105,110,105, 0,102, 67,108, 97,109,112, 0,102, 66,111,111,115,116, 0,100, 68,105,
-115,116, 0,100, 81,117, 97,108,105,116,121, 0, 98, 78,111, 67,111,109,112, 0, 83, 99, 97,108,101,120, 73,110,105, 0, 83, 99,
- 97,108,101,121, 73,110,105, 0, 83, 99, 97,108,101,120, 70,105,110, 0, 83, 99, 97,108,101,121, 70,105,110, 0,120, 73,110,105,
- 0,120, 70,105,110, 0,121, 73,110,105, 0,121, 70,105,110, 0,114,111,116, 73,110,105, 0,114,111,116, 70,105,110, 0,105,110,
-116,101,114,112,111,108, 97,116,105,111,110, 0, 42,102,114, 97,109,101, 77, 97,112, 0,103,108,111, 98, 97,108, 83,112,101,101,
-100, 0,108, 97,115,116, 86, 97,108,105,100, 70,114, 97,109,101, 0, 98,117,116,116,121,112,101, 0,117,115,101,114,106,105,116,
- 0,115,116, 97, 0,116,111,116,112, 97,114,116, 0,110,111,114,109,102, 97, 99, 0,111, 98,102, 97, 99, 0,114, 97,110,100,102,
- 97, 99, 0,116,101,120,102, 97, 99, 0,114, 97,110,100,108,105,102,101, 0,102,111,114, 99,101, 91, 51, 93, 0,118,101, 99,116,
-115,105,122,101, 0,109, 97,120,108,101,110, 0,100,101,102,118,101, 99, 91, 51, 93, 0,109,117,108,116, 91, 52, 93, 0,108,105,
-102,101, 91, 52, 93, 0, 99,104,105,108,100, 91, 52, 93, 0,109, 97,116, 91, 52, 93, 0,116,101,120,109, 97,112, 0, 99,117,114,
-109,117,108,116, 0,115,116, 97,116,105, 99,115,116,101,112, 0,111,109, 97,116, 0,116,105,109,101,116,101,120, 0,115,112,101,
-101,100,116,101,120, 0,102,108, 97,103, 50,110,101,103, 0,118,101,114,116,103,114,111,117,112, 95,118, 0,118,103,114,111,117,
-112,110, 97,109,101, 91, 51, 50, 93, 0,118,103,114,111,117,112,110, 97,109,101, 95,118, 91, 51, 50, 93, 0, 42,107,101,121,115,
- 0,109,105,110,102, 97, 99, 0,117,115,101,100, 0,117,115,101,100,101,108,101,109, 0, 42,112,111,105,110, 0,114,101,115,101,
-116,100,105,115,116, 0,108, 97,115,116,118, 97,108, 0, 42,109, 97, 0,107,101,121, 0,113,117, 97,108, 0,113,117, 97,108, 50,
- 0,116, 97,114,103,101,116, 78, 97,109,101, 91, 51, 50, 93, 0,116,111,103,103,108,101, 78, 97,109,101, 91, 51, 50, 93, 0,118,
- 97,108,117,101, 91, 51, 50, 93, 0,109, 97,120,118, 97,108,117,101, 91, 51, 50, 93, 0,100,101,108, 97,121, 0,100,117,114, 97,
-116,105,111,110, 0,109, 97,116,101,114,105, 97,108, 78, 97,109,101, 91, 51, 50, 93, 0,100, 97,109,112,116,105,109,101,114, 0,
-112,114,111,112,110, 97,109,101, 91, 51, 50, 93, 0,109, 97,116,110, 97,109,101, 91, 51, 50, 93, 0, 97,120,105,115,102,108, 97,
-103, 0, 42,102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 51, 50, 93, 0, 98,111,100,121, 91, 51,
- 50, 93, 0,111,116,121,112,101, 0,112,117,108,115,101, 0,102,114,101,113, 0,116,111,116,108,105,110,107,115, 0, 42, 42,108,
-105,110,107,115, 0,116, 97,112, 0,106,111,121,105,110,100,101,120, 0, 97,120,105,115, 95,115,105,110,103,108,101, 0, 97,120,
-105,115,102, 0, 98,117,116,116,111,110, 0,104, 97,116, 0,104, 97,116,102, 0,112,114,101, 99,105,115,105,111,110, 0,115,116,
-114, 91, 49, 50, 56, 93, 0,109,111,100,117,108,101, 91, 54, 52, 93, 0, 42,109,121,110,101,119, 0,105,110,112,117,116,115, 0,
-116,111,116,115,108,105,110,107,115, 0, 42, 42,115,108,105,110,107,115, 0,118, 97,108,111, 0,115,116, 97,116,101, 95,109, 97,
-115,107, 0, 42, 97, 99,116, 0,102,114, 97,109,101, 80,114,111,112, 91, 51, 50, 93, 0, 98,108,101,110,100,105,110, 0,112,114,
-105,111,114,105,116,121, 0,101,110,100, 95,114,101,115,101,116, 0,115,116,114,105,100,101, 97,120,105,115, 0,115,116,114,105,
-100,101,108,101,110,103,116,104, 0,115,110,100,110,114, 0,112, 97,100, 49, 91, 50, 93, 0,109, 97,107,101, 99,111,112,121, 0,
- 99,111,112,121,109, 97,100,101, 0,112, 97,100, 50, 91, 49, 93, 0,116,114, 97, 99,107, 0, 42,109,101, 0,108,105,110, 86,101,
-108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,103, 86,101,108,111, 99,105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108,
- 97,103, 0,100,121,110, 95,111,112,101,114, 97,116,105,111,110, 0,102,111,114, 99,101,108,111, 99, 91, 51, 93, 0,102,111,114,
- 99,101,114,111,116, 91, 51, 93, 0,108,105,110,101, 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,103,117,108,
- 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 42,114,101,102,101,114,101,110, 99,101, 0, 98,117,116,115,116, 97, 0,
- 98,117,116,101,110,100, 0,109,105,110, 0,109, 97,120, 0,118,105,115,105,102, 97, 99, 0,114,111,116,100, 97,109,112, 0,109,
-105,110,108,111, 99, 91, 51, 93, 0,109, 97,120,108,111, 99, 91, 51, 93, 0,109,105,110,114,111,116, 91, 51, 93, 0,109, 97,120,
-114,111,116, 91, 51, 93, 0,109, 97,116,112,114,111,112, 91, 51, 50, 93, 0,100,105,115,116,114,105, 98,117,116,105,111,110, 0,
-105,110,116, 95, 97,114,103, 95, 49, 0,105,110,116, 95, 97,114,103, 95, 50, 0,102,108,111, 97,116, 95, 97,114,103, 95, 49, 0,
-102,108,111, 97,116, 95, 97,114,103, 95, 50, 0,116,111, 80,114,111,112, 78, 97,109,101, 91, 51, 50, 93, 0, 42,116,111, 79, 98,
-106,101, 99,116, 0, 98,111,100,121, 84,121,112,101, 0,102,105,108,101,110, 97,109,101, 91, 54, 52, 93, 0,108,111, 97,100, 97,
-110,105,110, 97,109,101, 91, 54, 52, 93, 0,105,110,116, 95, 97,114,103, 0,102,108,111, 97,116, 95, 97,114,103, 0,103,111, 0,
- 97, 99, 99,101,108,108,101,114, 97,116,105,111,110, 0,109, 97,120,115,112,101,101,100, 0,109, 97,120,114,111,116,115,112,101,
-101,100, 0,109, 97,120,116,105,108,116,115,112,101,101,100, 0,116,105,108,116,100, 97,109,112, 0,115,112,101,101,100,100, 97,
-109,112, 0, 42,115, 97,109,112,108,101, 0, 42,115,116,114,101, 97,109, 0, 42,110,101,119,112, 97, 99,107,101,100,102,105,108,
-101, 0, 42,115,110,100, 95,115,111,117,110,100, 0,112, 97,110,110,105,110,103, 0, 97,116,116,101,110,117, 97,116,105,111,110,
- 0,112,105,116, 99,104, 0,109,105,110, 95,103, 97,105,110, 0,109, 97,120, 95,103, 97,105,110, 0,100,105,115,116, 97,110, 99,
-101, 0,115,116,114,101, 97,109,108,101,110, 0, 99,104, 97,110,110,101,108,115, 0,104,105,103,104,112,114,105,111, 0,112, 97,
-100, 91, 49, 48, 93, 0,103, 97,105,110, 0,100,111,112,112,108,101,114,102, 97, 99,116,111,114, 0,100,111,112,112,108,101,114,
-118,101,108,111, 99,105,116,121, 0,110,117,109,115,111,117,110,100,115, 98,108,101,110,100,101,114, 0,110,117,109,115,111,117,
-110,100,115,103, 97,109,101,101,110,103,105,110,101, 0, 42, 97,114,101, 97, 0, 42,108, 97,109,112,114,101,110, 0,103,111, 98,
+101,109, 0,118,101, 99, 91, 51, 93, 91, 51, 93, 0, 97,108,102, 97, 0,119,101,105,103,104,116, 0,104, 49, 0,104, 50, 0,102,
+ 49, 0,102, 50, 0,102, 51, 0,104,105,100,101, 0,118,101, 99, 91, 52, 93, 0,109, 97,116, 95,110,114, 0,112,110,116,115,117,
+ 0,112,110,116,115,118, 0,114,101,115,111,108,117, 0,114,101,115,111,108,118, 0,111,114,100,101,114,117, 0,111,114,100,101,
+114,118, 0,102,108, 97,103,117, 0,102,108, 97,103,118, 0, 42,107,110,111,116,115,117, 0, 42,107,110,111,116,115,118, 0,116,
+105,108,116, 95,105,110,116,101,114,112, 0,114, 97,100,105,117,115, 95,105,110,116,101,114,112, 0, 99,104, 97,114,105,100,120,
+ 0,107,101,114,110, 0,104, 0,110,117,114, 98, 0, 42,101,100,105,116,110,117,114, 98, 0, 42, 98,101,118,111, 98,106, 0, 42,
+116, 97,112,101,114,111, 98,106, 0, 42,116,101,120,116,111,110, 99,117,114,118,101, 0, 42,112, 97,116,104, 0, 42,107,101,121,
+ 0, 98,101,118, 0,100,114, 97,119,102,108, 97,103, 0,116,119,105,115,116, 95,109,111,100,101, 0,112, 97,100, 91, 50, 93, 0,
+116,119,105,115,116, 95,115,109,111,111,116,104, 0,112, 97,116,104,108,101,110, 0, 98,101,118,114,101,115,111,108, 0,119,105,
+100,116,104, 0,101,120,116, 49, 0,101,120,116, 50, 0,114,101,115,111,108,117, 95,114,101,110, 0,114,101,115,111,108,118, 95,
+114,101,110, 0, 97, 99,116,110,117, 0, 42,108, 97,115,116,115,101,108, 98,112, 0,115,112, 97, 99,101,109,111,100,101, 0,115,
+112, 97, 99,105,110,103, 0,108,105,110,101,100,105,115,116, 0,115,104,101, 97,114, 0,102,115,105,122,101, 0,119,111,114,100,
+115,112, 97, 99,101, 0,117,108,112,111,115, 0,117,108,104,101,105,103,104,116, 0,120,111,102, 0,121,111,102, 0,108,105,110,
+101,119,105,100,116,104, 0, 42,115,116,114, 0, 42,115,101,108, 98,111,120,101,115, 0, 42,101,100,105,116,102,111,110,116, 0,
+102, 97,109,105,108,121, 91, 50, 52, 93, 0, 42,118,102,111,110,116, 0, 42,118,102,111,110,116, 98, 0, 42,118,102,111,110,116,
+105, 0, 42,118,102,111,110,116, 98,105, 0,115,101,112, 99,104, 97,114, 0, 99,116,105,109,101, 0,116,111,116, 98,111,120, 0,
+ 97, 99,116, 98,111,120, 0, 42,116, 98, 0,115,101,108,115,116, 97,114,116, 0,115,101,108,101,110,100, 0, 42,115,116,114,105,
+110,102,111, 0, 99,117,114,105,110,102,111, 0,101,102,102,101, 99,116, 0, 42,109,102, 97, 99,101, 0, 42,109,116,102, 97, 99,
+101, 0, 42,116,102, 97, 99,101, 0, 42,109,118,101,114,116, 0, 42,109,101,100,103,101, 0, 42,100,118,101,114,116, 0, 42,109,
+ 99,111,108, 0, 42,109,115,116,105, 99,107,121, 0, 42,116,101,120, 99,111,109,101,115,104, 0, 42,109,115,101,108,101, 99,116,
+ 0, 42,101,100,105,116, 95,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,100, 97,116, 97, 0,116,111,
+116,101,100,103,101, 0,116,111,116,102, 97, 99,101, 0,116,111,116,115,101,108,101, 99,116, 0, 97, 99,116, 95,102, 97, 99,101,
+ 0, 99,117, 98,101,109, 97,112,115,105,122,101, 0,115,109,111,111,116,104,114,101,115,104, 0,115,117, 98,100,105,118, 0,115,
+117, 98,100,105,118,114, 0,115,117, 98,115,117,114,102,116,121,112,101, 0, 42,109,114, 0, 42,112,118, 0, 42,116,112, 97,103,
+101, 0,117,118, 91, 52, 93, 91, 50, 93, 0, 99,111,108, 91, 52, 93, 0,116,114, 97,110,115,112, 0,116,105,108,101, 0,117,110,
+119,114, 97,112, 0,118, 49, 0,118, 50, 0,118, 51, 0,118, 52, 0,101,100, 99,111,100,101, 0, 99,114,101, 97,115,101, 0, 98,
+119,101,105,103,104,116, 0,100,101,102, 95,110,114, 0, 42,100,119, 0,116,111,116,119,101,105,103,104,116, 0, 99,111, 91, 51,
+ 93, 0,110,111, 91, 51, 93, 0,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,105,110,100,101,120, 0,102, 0,105, 0,115, 91,
+ 50, 53, 54, 93, 0,116,111,116,100,105,115,112, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0,118, 91, 52, 93, 0,109,105,100,
+ 0,118, 91, 50, 93, 0, 42,102, 97, 99,101,115, 0, 42, 99,111,108,102, 97, 99,101,115, 0, 42,101,100,103,101,115, 0, 42,118,
+101,114,116,115, 0,108,101,118,101,108,115, 0,108,101,118,101,108, 95, 99,111,117,110,116, 0, 99,117,114,114,101,110,116, 0,
+110,101,119,108,118,108, 0,101,100,103,101,108,118,108, 0,112,105,110,108,118,108, 0,114,101,110,100,101,114,108,118,108, 0,
+117,115,101, 95, 99,111,108, 0, 42,101,100,103,101, 95,102,108, 97,103,115, 0, 42,101,100,103,101, 95, 99,114,101, 97,115,101,
+115, 0, 42,118,101,114,116, 95,109, 97,112, 0, 42,101,100,103,101, 95,109, 97,112, 0, 42,111,108,100, 95,102, 97, 99,101,115,
+ 0, 42,111,108,100, 95,101,100,103,101,115, 0, 42,101,114,114,111,114, 0,109,111,100,105,102,105,101,114, 0,115,117, 98,100,
+105,118, 84,121,112,101, 0,114,101,110,100,101,114, 76,101,118,101,108,115, 0, 42,101,109, 67, 97, 99,104,101, 0, 42,109, 67,
+ 97, 99,104,101, 0,100,101,102, 97,120,105,115, 0,112, 97,100, 91, 54, 93, 0,108,101,110,103,116,104, 0,114, 97,110,100,111,
+109,105,122,101, 0,115,101,101,100, 0, 42,111, 98, 95, 97,114,109, 0, 42,115,116, 97,114,116, 95, 99, 97,112, 0, 42,101,110,
+100, 95, 99, 97,112, 0, 42, 99,117,114,118,101, 95,111, 98, 0, 42,111,102,102,115,101,116, 95,111, 98, 0,111,102,102,115,101,
+116, 91, 51, 93, 0,115, 99, 97,108,101, 91, 51, 93, 0,109,101,114,103,101, 95,100,105,115,116, 0,102,105,116, 95,116,121,112,
+101, 0,111,102,102,115,101,116, 95,116,121,112,101, 0, 99,111,117,110,116, 0, 97,120,105,115, 0,116,111,108,101,114, 97,110,
+ 99,101, 0, 42,109,105,114,114,111,114, 95,111, 98, 0,115,112,108,105,116, 95, 97,110,103,108,101, 0,118, 97,108,117,101, 0,
+114,101,115, 0,118, 97,108, 95,102,108, 97,103,115, 0,108,105,109, 95,102,108, 97,103,115, 0,101, 95,102,108, 97,103,115, 0,
+ 98,101,118,101,108, 95, 97,110,103,108,101, 0,100,101,102,103,114,112, 95,110, 97,109,101, 91, 51, 50, 93, 0, 42,100,111,109,
+ 97,105,110, 0, 42,102,108,111,119, 0, 42, 99,111,108,108, 0,116,105,109,101, 0, 42,116,101,120,116,117,114,101, 0,115,116,
+114,101,110,103,116,104, 0,100,105,114,101, 99,116,105,111,110, 0,109,105,100,108,101,118,101,108, 0,116,101,120,109, 97,112,
+112,105,110,103, 0, 42,109, 97,112, 95,111, 98,106,101, 99,116, 0,117,118,108, 97,121,101,114, 95,110, 97,109,101, 91, 51, 50,
+ 93, 0,117,118,108, 97,121,101,114, 95,116,109,112, 0, 42,112,114,111,106,101, 99,116,111,114,115, 91, 49, 48, 93, 0, 42,105,
+109, 97,103,101, 0,110,117,109, 95,112,114,111,106,101, 99,116,111,114,115, 0, 97,115,112,101, 99,116,120, 0, 97,115,112,101,
+ 99,116,121, 0,112,101,114, 99,101,110,116, 0,102, 97, 99,101, 67,111,117,110,116, 0,102, 97, 99, 0,114,101,112,101, 97,116,
+ 0, 42,111, 98,106,101, 99,116, 99,101,110,116,101,114, 0,115,116, 97,114,116,120, 0,115,116, 97,114,116,121, 0,104,101,105,
+103,104,116, 0,110, 97,114,114,111,119, 0,115,112,101,101,100, 0,100, 97,109,112, 0,102, 97,108,108,111,102,102, 0,116,105,
+109,101,111,102,102,115, 0,108,105,102,101,116,105,109,101, 0,100,101,102,111,114,109,102,108, 97,103, 0,109,117,108,116,105,
+ 0, 42,112,114,101,118, 67,111,115, 0,115,117, 98,116, 97,114,103,101,116, 91, 51, 50, 93, 0,112, 97,114,101,110,116,105,110,
+118, 91, 52, 93, 91, 52, 93, 0, 99,101,110,116, 91, 51, 93, 0, 42,105,110,100,101,120, 97,114, 0,116,111,116,105,110,100,101,
+120, 0,102,111,114, 99,101, 0, 42, 99,108,111,116,104, 79, 98,106,101, 99,116, 0, 42,115,105,109, 95,112, 97,114,109,115, 0,
+ 42, 99,111,108,108, 95,112, 97,114,109,115, 0, 42,112,111,105,110,116, 95, 99, 97, 99,104,101, 0,112,116, 99, 97, 99,104,101,
+115, 0, 42,120, 0, 42,120,110,101,119, 0, 42,120,111,108,100, 0, 42, 99,117,114,114,101,110,116, 95,120,110,101,119, 0, 42,
+ 99,117,114,114,101,110,116, 95,120, 0, 42, 99,117,114,114,101,110,116, 95,118, 0, 42,109,102, 97, 99,101,115, 0,110,117,109,
+118,101,114,116,115, 0,110,117,109,102, 97, 99,101,115, 0, 42, 98,118,104,116,114,101,101, 0, 42,118, 0, 42,100,109, 0, 99,
+102,114, 97, 0,111,112,101,114, 97,116,105,111,110, 0,118,101,114,116,101,120, 0,116,111,116,105,110,102,108,117,101,110, 99,
+101, 0,103,114,105,100,115,105,122,101, 0,110,101,101,100, 98,105,110,100, 0, 42, 98,105,110,100,119,101,105,103,104,116,115,
+ 0, 42, 98,105,110,100, 99,111,115, 0,116,111,116, 99, 97,103,101,118,101,114,116, 0, 42,100,121,110,103,114,105,100, 0, 42,
+100,121,110,105,110,102,108,117,101,110, 99,101,115, 0, 42,100,121,110,118,101,114,116,115, 0, 42,112, 97,100, 50, 0,100,121,
+110,103,114,105,100,115,105,122,101, 0,100,121,110, 99,101,108,108,109,105,110, 91, 51, 93, 0,100,121,110, 99,101,108,108,119,
+105,100,116,104, 0, 98,105,110,100,109, 97,116, 91, 52, 93, 91, 52, 93, 0,116,111,116,100,109,118,101,114,116, 0,116,111,116,
+100,109,101,100,103,101, 0,116,111,116,100,109,102, 97, 99,101, 0,112,115,121,115, 0,112,111,115,105,116,105,111,110, 0,114,
+ 97,110,100,111,109, 95,112,111,115,105,116,105,111,110, 0, 42,102, 97, 99,101,112, 97, 0,118,103,114,111,117,112, 0,112,114,
+111,116,101, 99,116, 0, 42,117,110,100,111, 95,118,101,114,116,115, 0,117,110,100,111, 95,118,101,114,116,115, 95,116,111,116,
+ 0,117,110,100,111, 95,115,105,103,110, 97,108, 0,108,118,108, 0,116,111,116,108,118,108, 0,115,105,109,112,108,101, 0, 42,
+102,115,115, 0, 42,116, 97,114,103,101,116, 0, 42, 97,117,120, 84, 97,114,103,101,116, 0,118,103,114,111,117,112, 95,110, 97,
+109,101, 91, 51, 50, 93, 0,107,101,101,112, 68,105,115,116, 0,115,104,114,105,110,107, 84,121,112,101, 0,115,104,114,105,110,
+107, 79,112,116,115, 0,112,114,111,106, 65,120,105,115, 0,115,117, 98,115,117,114,102, 76,101,118,101,108,115, 0, 42,111,114,
+105,103,105,110, 0,102, 97, 99,116,111,114, 0,108,105,109,105,116, 91, 50, 93, 0,111,114,105,103,105,110, 79,112,116,115, 0,
+112,110,116,115,119, 0,111,112,110,116,115,117, 0,111,112,110,116,115,118, 0,111,112,110,116,115,119, 0,116,121,112,101,117,
+ 0,116,121,112,101,118, 0,116,121,112,101,119, 0,102,117, 0,102,118, 0,102,119, 0,100,117, 0,100,118, 0,100,119, 0, 42,
+100,101,102, 0, 42,108, 97,116,116,105, 99,101,100, 97,116, 97, 0,108, 97,116,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 42,101,
+100,105,116,108, 97,116,116, 0,118,101, 99, 91, 56, 93, 91, 51, 93, 0, 42,115, 99,117,108,112,116, 0,112, 97,114,116,121,112,
+101, 0,112, 97,114, 49, 0,112, 97,114, 50, 0,112, 97,114, 51, 0,112, 97,114,115,117, 98,115,116,114, 91, 51, 50, 93, 0, 42,
+116,114, 97, 99,107, 0, 42,112,114,111,120,121, 0, 42,112,114,111,120,121, 95,103,114,111,117,112, 0, 42,112,114,111,120,121,
+ 95,102,114,111,109, 0, 42, 97, 99,116,105,111,110, 0, 42,112,111,115,101,108,105, 98, 0, 42,112,111,115,101, 0, 42,103,112,
+100, 0, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 0,100,101,102, 98, 97,115,101, 0,109,111,100,
+105,102,105,101,114,115, 0,114,101,115,116,111,114,101, 95,109,111,100,101, 0, 42,109, 97,116, 98,105,116,115, 0, 97, 99,116,
+ 99,111,108, 0,100,108,111, 99, 91, 51, 93, 0,111,114,105,103, 91, 51, 93, 0,100,115,105,122,101, 91, 51, 93, 0,100,114,111,
+116, 91, 51, 93, 0,111, 98,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 99,111,110,115,116,105,110,118, 91, 52, 93, 91, 52, 93, 0,
+108, 97,121, 0, 99,111,108, 98,105,116,115, 0,116,114, 97,110,115,102,108, 97,103, 0,112,114,111,116,101, 99,116,102,108, 97,
+103, 0,116,114, 97, 99,107,102,108, 97,103, 0,117,112,102,108, 97,103, 0,110,108, 97,102,108, 97,103, 0,105,112,111,102,108,
+ 97,103, 0,105,112,111,119,105,110, 0,115, 99, 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0, 98,111,117,
+110,100,116,121,112,101, 0,100,117,112,111,110, 0,100,117,112,111,102,102, 0,100,117,112,115,116, 97, 0,100,117,112,101,110,
+100, 0,115,102, 0,109, 97,115,115, 0,100, 97,109,112,105,110,103, 0,105,110,101,114,116,105, 97, 0,102,111,114,109,102, 97,
+ 99,116,111,114, 0,114,100, 97,109,112,105,110,103, 0,115,105,122,101,102, 97, 99, 0,109, 97,114,103,105,110, 0,109, 97,120,
+ 95,118,101,108, 0,109,105,110, 95,118,101,108, 0,109, 95, 99,111,110,116, 97, 99,116, 80,114,111, 99,101,115,115,105,110,103,
+ 84,104,114,101,115,104,111,108,100, 0,100,116, 0,100,116,120, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,
+112, 97,100, 49, 91, 53, 93, 0,101,109,112,116,121, 95,100,114, 97,119,115,105,122,101, 0,100,117,112,102, 97, 99,101,115, 99,
+ 97, 0,112,114,111,112, 0,115,101,110,115,111,114,115, 0, 99,111,110,116,114,111,108,108,101,114,115, 0, 97, 99,116,117, 97,
+116,111,114,115, 0, 98, 98,115,105,122,101, 91, 51, 93, 0, 97, 99,116,100,101,102, 0,103, 97,109,101,102,108, 97,103, 0,103,
+ 97,109,101,102,108, 97,103, 50, 0, 42, 98,115,111,102,116, 0,115,111,102,116,102,108, 97,103, 0, 97,110,105,115,111,116,114,
+111,112,105, 99, 70,114,105, 99,116,105,111,110, 91, 51, 93, 0, 99,111,110,115,116,114, 97,105,110,116,115, 0,110,108, 97,115,
+116,114,105,112,115, 0,104,111,111,107,115, 0,112, 97,114,116,105, 99,108,101,115,121,115,116,101,109, 0, 42,115,111,102,116,
+ 0, 42,100,117,112, 95,103,114,111,117,112, 0,102,108,117,105,100,115,105,109, 70,108, 97,103, 0,114,101,115,116,114,105, 99,
+116,102,108, 97,103, 0,115,104, 97,112,101,110,114, 0,115,104, 97,112,101,102,108, 97,103, 0,114,101, 99, 97,108, 99,111, 0,
+ 98,111,100,121, 95,116,121,112,101, 0, 42,102,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 42,100,101,114,
+105,118,101,100, 68,101,102,111,114,109, 0, 42,100,101,114,105,118,101,100, 70,105,110, 97,108, 0,108, 97,115,116, 68, 97,116,
+ 97, 77, 97,115,107, 0,115,116, 97,116,101, 0,105,110,105,116, 95,115,116, 97,116,101, 0,103,112,117,108, 97,109,112, 0,112,
+ 99, 95,105,100,115, 0, 99,117,114,105,110,100,101,120, 0, 97, 99,116,105,118,101, 0,100,101,102,108,101, 99,116, 0,102,111,
+114, 99,101,102,105,101,108,100, 0,112,100,101,102, 95,100, 97,109,112, 0,112,100,101,102, 95,114,100, 97,109,112, 0,112,100,
+101,102, 95,112,101,114,109, 0,112,100,101,102, 95,102,114,105, 99,116, 0,112,100,101,102, 95,114,102,114,105, 99,116, 0,102,
+ 95,115,116,114,101,110,103,116,104, 0,102, 95,112,111,119,101,114, 0,102, 95,100,105,115,116, 0,102, 95,100, 97,109,112, 0,
+109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116, 0,109, 97,120,114, 97,100, 0,109,105,110,114, 97,100, 0,102, 95,
+112,111,119,101,114, 95,114, 0,112,100,101,102, 95,115, 98,100, 97,109,112, 0,112,100,101,102, 95,115, 98,105,102,116, 0,112,
+100,101,102, 95,115, 98,111,102,116, 0, 99,108,117,109,112, 95,102, 97, 99, 0, 99,108,117,109,112, 95,112,111,119, 0,107,105,
+110,107, 95,102,114,101,113, 0,107,105,110,107, 95,115,104, 97,112,101, 0,107,105,110,107, 95, 97,109,112, 0,102,114,101,101,
+ 95,101,110,100, 0,116,101,120, 95,110, 97, 98,108, 97, 0,116,101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110,
+107, 95, 97,120,105,115, 0,114,116, 50, 0, 42,114,110,103, 0,102, 95,110,111,105,115,101, 0,102,114, 97,109,101, 0,116,111,
+116,112,111,105,110,116, 0,100, 97,116, 97, 95,116,121,112,101,115, 0, 42,105,110,100,101,120, 95, 97,114,114, 97,121, 0, 42,
+100, 97,116, 97, 91, 56, 93, 0, 42, 99,117,114, 91, 56, 93, 0,115,116,101,112, 0,115,105,109,102,114, 97,109,101, 0,115,116,
+ 97,114,116,102,114, 97,109,101, 0,101,110,100,102,114, 97,109,101, 0,101,100,105,116,102,114, 97,109,101, 0,108, 97,115,116,
+ 95,101,120, 97, 99,116, 0,110, 97,109,101, 91, 54, 52, 93, 0,112,114,101,118, 95,110, 97,109,101, 91, 54, 52, 93, 0,105,110,
+102,111, 91, 54, 52, 93, 0,112, 97,116,104, 91, 50, 52, 48, 93, 0,109,101,109, 95, 99, 97, 99,104,101, 0, 42,101,100,105,116,
+ 0, 40, 42,102,114,101,101, 95,101,100,105,116, 41, 40, 41, 0,108,105,110, 83,116,105,102,102, 0, 97,110,103, 83,116,105,102,
+102, 0,118,111,108,117,109,101, 0,118,105,116,101,114, 97,116,105,111,110,115, 0,112,105,116,101,114, 97,116,105,111,110,115,
+ 0,100,105,116,101,114, 97,116,105,111,110,115, 0, 99,105,116,101,114, 97,116,105,111,110,115, 0,107, 83, 82, 72, 82, 95, 67,
+ 76, 0,107, 83, 75, 72, 82, 95, 67, 76, 0,107, 83, 83, 72, 82, 95, 67, 76, 0,107, 83, 82, 95, 83, 80, 76, 84, 95, 67, 76, 0,
+107, 83, 75, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 83, 83, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 86, 67, 70, 0,107, 68, 80,
+ 0,107, 68, 71, 0,107, 76, 70, 0,107, 80, 82, 0,107, 86, 67, 0,107, 68, 70, 0,107, 77, 84, 0,107, 67, 72, 82, 0,107, 75,
+ 72, 82, 0,107, 83, 72, 82, 0,107, 65, 72, 82, 0, 99,111,108,108,105,115,105,111,110,102,108, 97,103,115, 0,110,117,109, 99,
+108,117,115,116,101,114,105,116,101,114, 97,116,105,111,110,115, 0,119,101,108,100,105,110,103, 0,116,111,116,115,112,114,105,
+110,103, 0, 42, 98,112,111,105,110,116, 0, 42, 98,115,112,114,105,110,103, 0,109,115,103, 95,108,111, 99,107, 0,109,115,103,
+ 95,118, 97,108,117,101, 0,110,111,100,101,109, 97,115,115, 0,110, 97,109,101,100, 86, 71, 95, 77, 97,115,115, 91, 51, 50, 93,
+ 0,103,114, 97,118, 0,109,101,100,105, 97,102,114,105, 99,116, 0,114,107,108,105,109,105,116, 0,112,104,121,115,105, 99,115,
+ 95,115,112,101,101,100, 0,103,111, 97,108,115,112,114,105,110,103, 0,103,111, 97,108,102,114,105, 99,116, 0,109,105,110,103,
+111, 97,108, 0,109, 97,120,103,111, 97,108, 0,100,101,102,103,111, 97,108, 0,118,101,114,116,103,114,111,117,112, 0,110, 97,
+109,101,100, 86, 71, 95, 83,111,102,116,103,111, 97,108, 91, 51, 50, 93, 0,102,117,122,122,121,110,101,115,115, 0,105,110,115,
+112,114,105,110,103, 0,105,110,102,114,105, 99,116, 0,110, 97,109,101,100, 86, 71, 95, 83,112,114,105,110,103, 95, 75, 91, 51,
+ 50, 93, 0,101,102,114, 97, 0,105,110,116,101,114,118, 97,108, 0,108,111, 99, 97,108, 0,115,111,108,118,101,114,102,108, 97,
+103,115, 0, 42, 42,107,101,121,115, 0,116,111,116,112,111,105,110,116,107,101,121, 0,115,101, 99,111,110,100,115,112,114,105,
+110,103, 0, 99,111,108, 98, 97,108,108, 0, 98, 97,108,108,100, 97,109,112, 0, 98, 97,108,108,115,116,105,102,102, 0,115, 98,
+ 99, 95,109,111,100,101, 0, 97,101,114,111,101,100,103,101, 0,109,105,110,108,111,111,112,115, 0,109, 97,120,108,111,111,112,
+115, 0, 99,104,111,107,101, 0,115,111,108,118,101,114, 95, 73, 68, 0,112,108, 97,115,116,105, 99, 0,115,112,114,105,110,103,
+112,114,101,108,111, 97,100, 0, 42,115, 99,114, 97,116, 99,104, 0,115,104,101, 97,114,115,116,105,102,102, 0,105,110,112,117,
+115,104, 0, 42,112,111,105,110,116, 99, 97, 99,104,101, 0,115,104,111,119, 95, 97,100,118, 97,110, 99,101,100,111,112,116,105,
+111,110,115, 0,114,101,115,111,108,117,116,105,111,110,120,121,122, 0,112,114,101,118,105,101,119,114,101,115,120,121,122, 0,
+114,101, 97,108,115,105,122,101, 0,103,117,105, 68,105,115,112,108, 97,121, 77,111,100,101, 0,114,101,110,100,101,114, 68,105,
+115,112,108, 97,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, 86, 97,108,117,101, 0,118,105,115, 99,111,115,105,
+116,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, 69,120,112,111,110,101,110,116, 0,103,114, 97,118,120, 0,103,
+114, 97,118,121, 0,103,114, 97,118,122, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69,110,100, 0,103,115,116,
+ 97,114, 0,109, 97,120, 82,101,102,105,110,101, 0,105,110,105, 86,101,108,120, 0,105,110,105, 86,101,108,121, 0,105,110,105,
+ 86,101,108,122, 0, 42,111,114,103, 77,101,115,104, 0, 42,109,101,115,104, 83,117,114,102, 97, 99,101, 0, 42,109,101,115,104,
+ 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 50, 52, 48, 93, 0, 98, 98, 83,116, 97,114,116, 91, 51, 93, 0,
+ 98, 98, 83,105,122,101, 91, 51, 93, 0,116,121,112,101, 70,108, 97,103,115, 0,100,111,109, 97,105,110, 78,111,118,101, 99,103,
+101,110, 0,118,111,108,117,109,101, 73,110,105,116, 84,121,112,101, 0,112, 97,114,116, 83,108,105,112, 86, 97,108,117,101, 0,
+103,101,110,101,114, 97,116,101, 84,114, 97, 99,101,114,115, 0,103,101,110,101,114, 97,116,101, 80, 97,114,116,105, 99,108,101,
+115, 0,115,117,114,102, 97, 99,101, 83,109,111,111,116,104,105,110,103, 0,115,117,114,102, 97, 99,101, 83,117, 98,100,105,118,
+115, 0,112, 97,114,116,105, 99,108,101, 73,110,102, 83,105,122,101, 0,112, 97,114,116,105, 99,108,101, 73,110,102, 65,108,112,
+104, 97, 0,102, 97,114, 70,105,101,108,100, 83,105,122,101, 0, 42,109,101,115,104, 83,117,114,102, 78,111,114,109, 97,108,115,
+ 0, 99,112,115, 84,105,109,101, 83,116, 97,114,116, 0, 99,112,115, 84,105,109,101, 69,110,100, 0, 99,112,115, 81,117, 97,108,
+105,116,121, 0, 97,116,116,114, 97, 99,116,102,111,114, 99,101, 83,116,114,101,110,103,116,104, 0, 97,116,116,114, 97, 99,116,
+102,111,114, 99,101, 82, 97,100,105,117,115, 0,118,101,108,111, 99,105,116,121,102,111,114, 99,101, 83,116,114,101,110,103,116,
+104, 0,118,101,108,111, 99,105,116,121,102,111,114, 99,101, 82, 97,100,105,117,115, 0,108, 97,115,116,103,111,111,100,102,114,
+ 97,109,101, 0,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,104,111,114,107, 0,
+122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,122,101,110,107, 0, 97,109, 98,107, 0,102, 97,115,116, 99,111,108,
+ 0,101,120,112,111,115,117,114,101, 0,101,120,112, 0,114, 97,110,103,101, 0,108,105,110,102, 97, 99, 0,108,111,103,102, 97,
+ 99, 0,103,114, 97,118,105,116,121, 0, 97, 99,116,105,118,105,116,121, 66,111,120, 82, 97,100,105,117,115, 0,115,107,121,116,
+121,112,101, 0,111, 99, 99,108,117,115,105,111,110, 82,101,115, 0,112,104,121,115,105, 99,115, 69,110,103,105,110,101, 0,116,
+105, 99,114, 97,116,101, 0,109, 97,120,108,111,103,105, 99,115,116,101,112, 0,112,104,121,115,117, 98,115,116,101,112, 0,109,
+ 97,120,112,104,121,115,116,101,112, 0,109,105,115,105, 0,109,105,115,116,115,116, 97, 0,109,105,115,116,100,105,115,116, 0,
+109,105,115,116,104,105, 0,115,116, 97,114,114, 0,115,116, 97,114,103, 0,115,116, 97,114, 98, 0,115,116, 97,114,107, 0,115,
+116, 97,114,115,105,122,101, 0,115,116, 97,114,109,105,110,100,105,115,116, 0,115,116, 97,114,100,105,115,116, 0,115,116, 97,
+114, 99,111,108,110,111,105,115,101, 0,100,111,102,115,116, 97, 0,100,111,102,101,110,100, 0,100,111,102,109,105,110, 0,100,
+111,102,109, 97,120, 0, 97,111,100,105,115,116, 0, 97,111,100,105,115,116,102, 97, 99, 0, 97,111,101,110,101,114,103,121, 0,
+ 97,111, 98,105, 97,115, 0, 97,111,109,111,100,101, 0, 97,111,115, 97,109,112, 0, 97,111,109,105,120, 0, 97,111, 99,111,108,
+111,114, 0, 97,111, 95, 97,100, 97,112,116, 95,116,104,114,101,115,104, 0, 97,111, 95, 97,100, 97,112,116, 95,115,112,101,101,
+100, 95,102, 97, 99, 0, 97,111, 95, 97,112,112,114,111,120, 95,101,114,114,111,114, 0, 97,111, 95, 97,112,112,114,111,120, 95,
+ 99,111,114,114,101, 99,116,105,111,110, 0, 97,111, 95,115, 97,109,112, 95,109,101,116,104,111,100, 0, 97,111, 95,103, 97,116,
+104,101,114, 95,109,101,116,104,111,100, 0, 97,111, 95, 97,112,112,114,111,120, 95,112, 97,115,115,101,115, 0, 42, 97,111,115,
+112,104,101,114,101, 0, 42, 97,111,116, 97, 98,108,101,115, 0,115,101,108, 99,111,108, 0,115,120, 0,115,121, 0, 42,108,112,
+ 70,111,114,109, 97,116, 0, 42,108,112, 80, 97,114,109,115, 0, 99, 98, 70,111,114,109, 97,116, 0, 99, 98, 80, 97,114,109,115,
+ 0,102, 99, 99, 84,121,112,101, 0,102, 99, 99, 72, 97,110,100,108,101,114, 0,100,119, 75,101,121, 70,114, 97,109,101, 69,118,
+101,114,121, 0,100,119, 81,117, 97,108,105,116,121, 0,100,119, 66,121,116,101,115, 80,101,114, 83,101, 99,111,110,100, 0,100,
+119, 70,108, 97,103,115, 0,100,119, 73,110,116,101,114,108,101, 97,118,101, 69,118,101,114,121, 0, 97,118,105, 99,111,100,101,
+ 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, 42, 99,100, 80, 97,114,109,115, 0, 42,112, 97,100, 0, 99,100, 83,105,122,101, 0,
+113,116, 99,111,100,101, 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, 99,111,100,101, 99, 0, 97,117,100,105,111, 95, 99,111,100,
+101, 99, 0,118,105,100,101,111, 95, 98,105,116,114, 97,116,101, 0, 97,117,100,105,111, 95, 98,105,116,114, 97,116,101, 0,103,
+111,112, 95,115,105,122,101, 0,114, 99, 95,109,105,110, 95,114, 97,116,101, 0,114, 99, 95,109, 97,120, 95,114, 97,116,101, 0,
+114, 99, 95, 98,117,102,102,101,114, 95,115,105,122,101, 0,109,117,120, 95,112, 97, 99,107,101,116, 95,115,105,122,101, 0,109,
+117,120, 95,114, 97,116,101, 0,109,105,120,114, 97,116,101, 0,109, 97,105,110, 0, 42,109, 97,116, 95,111,118,101,114,114,105,
+100,101, 0, 42,108,105,103,104,116, 95,111,118,101,114,114,105,100,101, 0,108, 97,121, 95,122,109, 97,115,107, 0,108, 97,121,
+102,108, 97,103, 0,112, 97,115,115,102,108, 97,103, 0,112, 97,115,115, 95,120,111,114, 0, 42, 97,118,105, 99,111,100,101, 99,
+100, 97,116, 97, 0, 42,113,116, 99,111,100,101, 99,100, 97,116, 97, 0,102,102, 99,111,100,101, 99,100, 97,116, 97, 0, 97,117,
+100,105,111, 0,112,115,102,114, 97, 0,112,101,102,114, 97, 0,105,109, 97,103,101,115, 0,102,114, 97,109, 97,112,116,111, 0,
+116,104,114,101, 97,100,115, 0,102,114, 97,109,101,108,101,110, 0, 98,108,117,114,102, 97, 99, 0,101,100,103,101, 82, 0,101,
+100,103,101, 71, 0,101,100,103,101, 66, 0,102,117,108,108,115, 99,114,101,101,110, 0,120,112,108, 97,121, 0,121,112,108, 97,
+121, 0,102,114,101,113,112,108, 97,121, 0, 97,116,116,114,105, 98, 0,114,116, 49, 0,115,116,101,114,101,111,109,111,100,101,
+ 0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116, 0,109, 97,120,105,109,115,105,122,101, 0,120,115, 99,104,
+ 0,121,115, 99,104, 0,120,112, 97,114,116,115, 0,121,112, 97,114,116,115, 0,119,105,110,112,111,115, 0,112,108, 97,110,101,
+115, 0,105,109,116,121,112,101, 0,115,117, 98,105,109,116,121,112,101, 0,113,117, 97,108,105,116,121, 0,100,105,115,112,108,
+ 97,121,109,111,100,101, 0,114,112, 97,100, 49, 0,114,112, 97,100, 50, 0,115, 99,101,109,111,100,101, 0,114,101,110,100,101,
+114,101,114, 0,111, 99,114,101,115, 0, 97,108,112,104, 97,109,111,100,101, 0,111,115, 97, 0,102,114,115, 95,115,101, 99, 0,
+101,100,103,101,105,110,116, 0,115, 97,102,101,116,121, 0, 98,111,114,100,101,114, 0,100,105,115,112,114,101, 99,116, 0,108,
+ 97,121,101,114,115, 0, 97, 99,116,108, 97,121, 0,120, 97,115,112, 0,121, 97,115,112, 0,102,114,115, 95,115,101, 99, 95, 98,
+ 97,115,101, 0,103, 97,117,115,115, 0, 99,111,108,111,114, 95,109,103,116, 95,102,108, 97,103, 0,112,111,115,116,103, 97,109,
+109, 97, 0,112,111,115,116,104,117,101, 0,112,111,115,116,115, 97,116, 0,100,105,116,104,101,114, 95,105,110,116,101,110,115,
+105,116,121, 0, 98, 97,107,101, 95,111,115, 97, 0, 98, 97,107,101, 95,102,105,108,116,101,114, 0, 98, 97,107,101, 95,109,111,
+100,101, 0, 98, 97,107,101, 95,102,108, 97,103, 0, 98, 97,107,101, 95,110,111,114,109, 97,108, 95,115,112, 97, 99,101, 0, 98,
+ 97,107,101, 95,113,117, 97,100, 95,115,112,108,105,116, 0, 98, 97,107,101, 95,109, 97,120,100,105,115,116, 0, 98, 97,107,101,
+ 95, 98,105, 97,115,100,105,115,116, 0, 98, 97,107,101, 95,112, 97,100, 0, 71, 73,113,117, 97,108,105,116,121, 0, 71, 73, 99,
+ 97, 99,104,101, 0, 71, 73,109,101,116,104,111,100, 0, 71, 73,112,104,111,116,111,110,115, 0, 71, 73,100,105,114,101, 99,116,
+ 0, 89, 70, 95, 65, 65, 0, 89, 70,101,120,112,111,114,116,120,109,108, 0, 89, 70, 95,110,111, 98,117,109,112, 0, 89, 70, 95,
+ 99,108, 97,109,112,114,103, 98, 0,121,102,112, 97,100, 49, 0, 71, 73,100,101,112,116,104, 0, 71, 73, 99, 97,117,115,100,101,
+112,116,104, 0, 71, 73,112,105,120,101,108,115,112,101,114,115, 97,109,112,108,101, 0, 71, 73,112,104,111,116,111,110, 99,111,
+117,110,116, 0, 71, 73,109,105,120,112,104,111,116,111,110,115, 0, 71, 73,112,104,111,116,111,110,114, 97,100,105,117,115, 0,
+ 89, 70, 95,114, 97,121,100,101,112,116,104, 0, 89, 70, 95, 65, 65,112, 97,115,115,101,115, 0, 89, 70, 95, 65, 65,115, 97,109,
+112,108,101,115, 0,121,102,112, 97,100, 50, 0, 71, 73,115,104, 97,100,111,119,113,117, 97,108,105,116,121, 0, 71, 73,114,101,
+102,105,110,101,109,101,110,116, 0, 71, 73,112,111,119,101,114, 0, 71, 73,105,110,100,105,114,112,111,119,101,114, 0, 89, 70,
+ 95,103, 97,109,109, 97, 0, 89, 70, 95,101,120,112,111,115,117,114,101, 0, 89, 70, 95,114, 97,121, 98,105, 97,115, 0, 89, 70,
+ 95, 65, 65,112,105,120,101,108,115,105,122,101, 0, 89, 70, 95, 65, 65,116,104,114,101,115,104,111,108,100, 0, 98, 97, 99,107,
+ 98,117,102, 91, 49, 54, 48, 93, 0,112,105, 99, 91, 49, 54, 48, 93, 0,115,116, 97,109,112, 0,115,116, 97,109,112, 95,102,111,
+110,116, 95,105,100, 0,115,116, 97,109,112, 95,117,100, 97,116, 97, 91, 49, 54, 48, 93, 0,102,103, 95,115,116, 97,109,112, 91,
+ 52, 93, 0, 98,103, 95,115,116, 97,109,112, 91, 52, 93, 0,115,105,109,112,108,105,102,121, 95,115,117, 98,115,117,114,102, 0,
+115,105,109,112,108,105,102,121, 95,115,104, 97,100,111,119,115, 97,109,112,108,101,115, 0,115,105,109,112,108,105,102,121, 95,
+112, 97,114,116,105, 99,108,101,115, 0,115,105,109,112,108,105,102,121, 95, 97,111,115,115,115, 0, 99,105,110,101,111,110,119,
+104,105,116,101, 0, 99,105,110,101,111,110, 98,108, 97, 99,107, 0, 99,105,110,101,111,110,103, 97,109,109, 97, 0,106,112, 50,
+ 95,112,114,101,115,101,116, 0,106,112, 50, 95,100,101,112,116,104, 0,114,112, 97,100, 51, 0,100,111,109,101,114,101,115, 0,
+100,111,109,101,109,111,100,101, 0,100,111,109,101, 97,110,103,108,101, 0,100,111,109,101,116,105,108,116, 0,100,111,109,101,
+114,101,115, 98,117,102, 0, 42,100,111,109,101,116,101,120,116, 0,101,110,103,105,110,101, 91, 51, 50, 93, 0,112, 97,114,116,
+105, 99,108,101, 95,112,101,114, 99, 0,115,117, 98,115,117,114,102, 95,109, 97,120, 0,115,104, 97,100, 98,117,102,115, 97,109,
+112,108,101, 95,109, 97,120, 0, 97,111, 95,101,114,114,111,114, 0,116,105,108,116, 0,114,101,115, 98,117,102, 0, 42,119, 97,
+114,112,116,101,120,116, 0, 99,111,108, 91, 51, 93, 0,109, 97,116,109,111,100,101, 0,102,114, 97,109,105,110,103, 0,100,111,
+109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0, 42, 42, 98,114,117,115,104,101,115, 0, 97, 99,116,105,118,101, 95, 98,
+114,117,115,104, 95,105,110,100,101,120, 0, 98,114,117,115,104, 95, 99,111,117,110,116, 0, 42,112, 97,105,110,116, 95, 99,117,
+114,115,111,114, 0,112, 97,105,110,116, 95, 99,117,114,115,111,114, 95, 99,111,108, 91, 52, 93, 0,112, 97,105,110,116, 0,116,
+111,111,108, 0,115,101, 97,109, 95, 98,108,101,101,100, 0,110,111,114,109, 97,108, 95, 97,110,103,108,101, 0, 42,112, 97,105,
+110,116, 99,117,114,115,111,114, 0,105,110,118,101,114,116, 0,116,111,116,114,101,107,101,121, 0,116,111,116, 97,100,100,107,
+101,121, 0, 98,114,117,115,104,116,121,112,101, 0, 98,114,117,115,104, 91, 55, 93, 0,101,109,105,116,116,101,114,100,105,115,
+116, 0,115,101,108,101, 99,116,109,111,100,101, 0,101,100,105,116,116,121,112,101, 0,100,114, 97,119, 95,115,116,101,112, 0,
+102, 97,100,101, 95,102,114, 97,109,101,115, 0,110, 97,109,101, 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93, 91, 51, 93, 0,112,
+105,118,111,116, 91, 51, 93, 0,116, 97, 98,108,101,116, 95,115,105,122,101, 0,116, 97, 98,108,101,116, 95,115,116,114,101,110,
+103,116,104, 0,103, 97,109,109, 97, 0,109,117,108, 0, 42,118,112, 97,105,110,116, 95,112,114,101,118, 0, 42,119,112, 97,105,
+110,116, 95,112,114,101,118, 0, 42,118,112, 97,105,110,116, 0, 42,119,112, 97,105,110,116, 0,118,103,114,111,117,112, 95,119,
+101,105,103,104,116, 0, 99,111,114,110,101,114,116,121,112,101, 0,101,100,105,116, 98,117,116,102,108, 97,103, 0,106,111,105,
+110,116,114,105,108,105,109,105,116, 0,100,101,103,114, 0,116,117,114,110, 0,101,120,116,114, 95,111,102,102,115, 0,100,111,
+117, 98,108,105,109,105,116, 0,110,111,114,109, 97,108,115,105,122,101, 0, 97,117,116,111,109,101,114,103,101, 0,115,101,103,
+109,101,110,116,115, 0,114,105,110,103,115, 0,118,101,114,116,105, 99,101,115, 0,117,110,119,114, 97,112,112,101,114, 0,117,
+118, 99, 97,108, 99, 95,114, 97,100,105,117,115, 0,117,118, 99, 97,108, 99, 95, 99,117, 98,101,115,105,122,101, 0,117,118, 99,
+ 97,108, 99, 95,109, 97,114,103,105,110, 0,117,118, 99, 97,108, 99, 95,109, 97,112,100,105,114, 0,117,118, 99, 97,108, 99, 95,
+109, 97,112, 97,108,105,103,110, 0,117,118, 99, 97,108, 99, 95,102,108, 97,103, 0,117,118, 95,102,108, 97,103, 0,117,118, 95,
+115,101,108,101, 99,116,109,111,100,101, 0,117,118, 95,112, 97,100, 91, 50, 93, 0, 97,117,116,111,105,107, 95, 99,104, 97,105,
+110,108,101,110, 0,105,109, 97,112, 97,105,110,116, 0,112, 97,114,116,105, 99,108,101, 0,112,114,111,112,111,114,116,105,111,
+110, 97,108, 95,115,105,122,101, 0,115,101,108,101, 99,116, 95,116,104,114,101,115,104, 0, 99,108,101, 97,110, 95,116,104,114,
+101,115,104, 0, 97,117,116,111,107,101,121, 95,109,111,100,101, 0, 97,117,116,111,107,101,121, 95,102,108, 97,103, 0,114,101,
+116,111,112,111, 95,109,111,100,101, 0,114,101,116,111,112,111, 95,112, 97,105,110,116, 95,116,111,111,108, 0,108,105,110,101,
+ 95,100,105,118, 0,101,108,108,105,112,115,101, 95,100,105,118, 0,114,101,116,111,112,111, 95,104,111,116,115,112,111,116, 0,
+109,117,108,116,105,114,101,115, 95,115,117, 98,100,105,118, 95,116,121,112,101, 0,115,107,103,101,110, 95,114,101,115,111,108,
+117,116,105,111,110, 0,115,107,103,101,110, 95,116,104,114,101,115,104,111,108,100, 95,105,110,116,101,114,110, 97,108, 0,115,
+107,103,101,110, 95,116,104,114,101,115,104,111,108,100, 95,101,120,116,101,114,110, 97,108, 0,115,107,103,101,110, 95,108,101,
+110,103,116,104, 95,114, 97,116,105,111, 0,115,107,103,101,110, 95,108,101,110,103,116,104, 95,108,105,109,105,116, 0,115,107,
+103,101,110, 95, 97,110,103,108,101, 95,108,105,109,105,116, 0,115,107,103,101,110, 95, 99,111,114,114,101,108, 97,116,105,111,
+110, 95,108,105,109,105,116, 0,115,107,103,101,110, 95,115,121,109,109,101,116,114,121, 95,108,105,109,105,116, 0,115,107,103,
+101,110, 95,114,101,116, 97,114,103,101,116, 95, 97,110,103,108,101, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,114,
+101,116, 97,114,103,101,116, 95,108,101,110,103,116,104, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,114,101,116, 97,
+114,103,101,116, 95,100,105,115,116, 97,110, 99,101, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,111,112,116,105,111,
+110,115, 0,115,107,103,101,110, 95,112,111,115,116,112,114,111, 0,115,107,103,101,110, 95,112,111,115,116,112,114,111, 95,112,
+ 97,115,115,101,115, 0,115,107,103,101,110, 95,115,117, 98,100,105,118,105,115,105,111,110,115, 91, 51, 93, 0,115,107,103,101,
+110, 95,109,117,108,116,105, 95,108,101,118,101,108, 0, 42,115,107,103,101,110, 95,116,101,109,112,108, 97,116,101, 0, 98,111,
+110,101, 95,115,107,101,116, 99,104,105,110,103, 0, 98,111,110,101, 95,115,107,101,116, 99,104,105,110,103, 95, 99,111,110,118,
+101,114,116, 0,115,107,103,101,110, 95,115,117, 98,100,105,118,105,115,105,111,110, 95,110,117,109, 98,101,114, 0,115,107,103,
+101,110, 95,114,101,116, 97,114,103,101,116, 95,111,112,116,105,111,110,115, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,
+101,116, 95,114,111,108,108, 0,115,107,103,101,110, 95,115,105,100,101, 95,115,116,114,105,110,103, 91, 56, 93, 0,115,107,103,
+101,110, 95,110,117,109, 95,115,116,114,105,110,103, 91, 56, 93, 0,101,100,103,101, 95,109,111,100,101, 0,115,110, 97,112, 95,
+109,111,100,101, 0,115,110, 97,112, 95,102,108, 97,103, 0,115,110, 97,112, 95,116, 97,114,103,101,116, 0,112,114,111,112,111,
+114,116,105,111,110, 97,108, 0,112,114,111,112, 95,109,111,100,101, 0,116,111,116,111, 98,106, 0,116,111,116,108, 97,109,112,
+ 0,116,111,116,111, 98,106,115,101,108, 0,116,111,116, 99,117,114,118,101, 0,116,111,116,109,101,115,104, 0,116,111,116, 97,
+114,109, 97,116,117,114,101, 0,115, 99, 97,108,101, 95,108,101,110,103,116,104, 0,115,121,115,116,101,109, 0, 42, 99, 97,109,
+101,114, 97, 0, 42,119,111,114,108,100, 0, 42,115,101,116, 0, 98, 97,115,101, 0, 42, 98, 97,115, 97, 99,116, 0, 42,111, 98,
+101,100,105,116, 0, 99,117,114,115,111,114, 91, 51, 93, 0,116,119, 99,101,110,116, 91, 51, 93, 0,116,119,109,105,110, 91, 51,
+ 93, 0,116,119,109, 97,120, 91, 51, 93, 0, 42,101,100, 0, 42,116,111,111,108,115,101,116,116,105,110,103,115, 0, 42,115,116,
+ 97,116,115, 0,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0,115,111,117,110,100, 95,104, 97,110,100,108,
+101,115, 0, 42,116,104,101, 68, 97,103, 0,100, 97,103,105,115,118, 97,108,105,100, 0,100, 97,103,102,108, 97,103,115, 0,106,
+117,109,112,102,114, 97,109,101, 0,102,114, 97,109,101, 95,115,116,101,112, 0, 97, 99,116,105,118,101, 95,107,101,121,105,110,
+103,115,101,116, 0,107,101,121,105,110,103,115,101,116,115, 0,103,109, 0,117,110,105,116, 0, 98,108,101,110,100, 0,119,105,
+110,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,105,110,118,
+ 91, 52, 93, 91, 52, 93, 0,112,101,114,115,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,105,110,118, 91, 52, 93, 91,
+ 52, 93, 0,118,105,101,119,109, 97,116,111, 98, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,109, 97,116,111, 98, 91, 52, 93, 91,
+ 52, 93, 0,116,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,122,102, 97, 99, 0,
+ 99, 97,109,100,120, 0, 99, 97,109,100,121, 0,112,105,120,115,105,122,101, 0, 99, 97,109,122,111,111,109, 0,118,105,101,119,
+ 98,117,116, 0,108, 97,115,116,109,111,100,101, 0,114,102,108, 97,103, 0,118,105,101,119,108,111, 99,107, 0,112,101,114,115,
+112, 0,118,105,101,119, 0, 99,108,105,112, 91, 54, 93, 91, 52, 93, 0, 42, 99,108,105,112, 98, 98, 0, 42,108,111, 99, 97,108,
+118,100, 0, 42,114,105, 0, 42,114,101,116,111,112,111, 95,118,105,101,119, 95,100, 97,116, 97, 0, 42,100,101,112,116,104,115,
+ 0, 42,115,109,115, 0, 42,115,109,111,111,116,104, 95,116,105,109,101,114, 0,108,118,105,101,119,113,117, 97,116, 91, 52, 93,
+ 0,108,112,101,114,115,112, 0,108,118,105,101,119, 0,114,101,103,105,111,110, 98, 97,115,101, 0,115,112, 97, 99,101,116,121,
+112,101, 0, 98,108,111, 99,107,115, 99, 97,108,101, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 93, 0,108, 97,
+121, 95,117,115,101,100, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 0,111, 98, 95, 99,101,110,116,
+114,101, 95, 98,111,110,101, 91, 51, 50, 93, 0,108, 97,121, 97, 99,116, 0,100,114, 97,119,116,121,112,101, 0,108,111, 99, 97,
+108,118,105,101,119, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0,112,105,118,111,116, 95,108, 97,115,
+116, 0,103,114,105,100, 0,103,114,105,100,118,105,101,119, 0,112, 97,100,102, 0,110,101, 97,114, 0,102, 97,114, 0,103,114,
+105,100,108,105,110,101,115, 0,103,114,105,100,102,108, 97,103, 0,103,114,105,100,115,117, 98,100,105,118, 0,109,111,100,101,
+115,101,108,101, 99,116, 0,107,101,121,102,108, 97,103,115, 0,116,119,116,121,112,101, 0,116,119,109,111,100,101, 0,116,119,
+102,108, 97,103, 0,116,119,100,114, 97,119,102,108, 97,103, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 0,
+ 97,102,116,101,114,100,114, 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 0,110,100,111,102,109,111,100,101, 0,110,100,111,
+102,102,105,108,116,101,114, 0, 42,112,114,111,112,101,114,116,105,101,115, 95,115,116,111,114, 97,103,101, 0,118,101,114,116,
+ 0,104,111,114, 0,109, 97,115,107, 0,109,105,110, 91, 50, 93, 0,109, 97,120, 91, 50, 93, 0,109,105,110,122,111,111,109, 0,
+109, 97,120,122,111,111,109, 0,115, 99,114,111,108,108, 0,115, 99,114,111,108,108, 95,117,105, 0,107,101,101,112,116,111,116,
+ 0,107,101,101,112,122,111,111,109, 0,107,101,101,112,111,102,115, 0, 97,108,105,103,110, 0,119,105,110,120, 0,119,105,110,
+121, 0,111,108,100,119,105,110,120, 0,111,108,100,119,105,110,121, 0, 99,117,114,115,111,114, 91, 50, 93, 0, 42,116, 97, 98,
+ 95,111,102,102,115,101,116, 0,116, 97, 98, 95,110,117,109, 0,116, 97, 98, 95, 99,117,114, 0, 42,115, 99,114,101,101,110, 0,
+118, 50,100, 0, 42, 97,100,115, 0,103,104,111,115,116, 67,117,114,118,101,115, 0, 97,117,116,111,115,110, 97,112, 0,112,105,
+110, 0,108,111, 99,107, 0,109, 97,105,110, 98, 0,109, 97,105,110, 98,111, 0,109, 97,105,110, 98,117,115,101,114, 0,114,101,
+ 95, 97,108,105,103,110, 0,112,114,101,118,105,101,119, 0,112, 97,116,104,102,108, 97,103, 0,100, 97,116, 97,105, 99,111,110,
+ 0, 42,112,105,110,105,100, 0,114,101,110,100,101,114, 95,115,105,122,101, 0, 99,104, 97,110,115,104,111,119,110, 0,122,101,
+ 98,114, 97, 0,122,111,111,109, 0,116,105,116,108,101, 91, 50, 52, 93, 0,100,105,114, 91, 50, 52, 48, 93, 0,102,105,108,101,
+ 91, 56, 48, 93, 0,114,101,110, 97,109,101,102,105,108,101, 91, 56, 48, 93, 0,115,111,114,116, 0,100,105,115,112,108, 97,121,
+ 0, 97, 99,116,105,118,101, 95, 98,111,111,107,109, 97,114,107, 0, 97, 99,116,105,118,101, 95,102,105,108,101, 0,115,101,108,
+115,116, 97,116,101, 0,102, 95,102,112, 0,109,101,110,117, 0,102,112, 95,115,116,114, 91, 56, 93, 0, 42,112,117,112,109,101,
+110,117, 0, 42,112, 97,114, 97,109,115, 0, 42,102,105,108,101,115, 0, 42,102,111,108,100,101,114,115, 95,112,114,101,118, 0,
+ 42,102,111,108,100,101,114,115, 95,110,101,120,116, 0, 42,111,112, 0, 42,108,111, 97,100,105,109, 97,103,101, 95,116,105,109,
+101,114, 0, 42,108, 97,121,111,117,116, 0,114,101, 99,101,110,116,110,114, 0, 98,111,111,107,109, 97,114,107,110,114, 0,115,
+121,115,116,101,109,110,114, 0,116,114,101,101, 0, 42,116,114,101,101,115,116,111,114,101, 0,115,101, 97,114, 99,104, 95,115,
+116,114,105,110,103, 91, 51, 50, 93, 0,115,101, 97,114, 99,104, 95,116,115,101, 0,115,101, 97,114, 99,104, 95,102,108, 97,103,
+115, 0,100,111, 95, 0,111,117,116,108,105,110,101,118,105,115, 0,115,116,111,114,101,102,108, 97,103, 0, 42, 99,117,109, 97,
+112, 0,105,109, 97,110,114, 0, 99,117,114,116,105,108,101, 0,105,109,116,121,112,101,110,114, 0,100,116, 95,117,118, 0,115,
+116,105, 99,107,121, 0,100,116, 95,117,118,115,116,114,101,116, 99,104, 0, 99,101,110,116,120, 0, 99,101,110,116,121, 0, 42,
+116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, 0,108,104,101,105,103,104,116, 0, 99,119,105,100,116,
+104, 0,108,105,110,101,110,114,115, 95,116,111,116, 0,108,101,102,116, 0,115,104,111,119,108,105,110,101,110,114,115, 0,116,
+ 97, 98,110,117,109, 98,101,114, 0,115,104,111,119,115,121,110,116, 97,120, 0,111,118,101,114,119,114,105,116,101, 0,108,105,
+118,101, 95,101,100,105,116, 0,112,105,120, 95,112,101,114, 95,108,105,110,101, 0,116,120,116,115, 99,114,111,108,108, 0,116,
+120,116, 98, 97,114, 0,119,111,114,100,119,114, 97,112, 0,100,111,112,108,117,103,105,110,115, 0,102,105,110,100,115,116,114,
+ 91, 50, 53, 54, 93, 0,114,101,112,108, 97, 99,101,115,116,114, 91, 50, 53, 54, 93, 0, 42,112,121, 95,100,114, 97,119, 0, 42,
+112,121, 95,101,118,101,110,116, 0, 42,112,121, 95, 98,117,116,116,111,110, 0, 42,112,121, 95, 98,114,111,119,115,101,114, 99,
+ 97,108,108, 98, 97, 99,107, 0, 42,112,121, 95,103,108,111, 98, 97,108,100,105, 99,116, 0,108, 97,115,116,115,112, 97, 99,101,
+ 0,115, 99,114,105,112,116,110, 97,109,101, 91, 50, 53, 54, 93, 0,115, 99,114,105,112,116, 97,114,103, 91, 50, 53, 54, 93, 0,
+ 42,115, 99,114,105,112,116, 0, 42, 98,117,116, 95,114,101,102,115, 0,114,101,100,114, 97,119,115, 0, 42,105,100, 0, 97,115,
+112,101, 99,116, 0, 42, 99,117,114,102,111,110,116, 0,109,120, 0,109,121, 0, 42,101,100,105,116,116,114,101,101, 0,116,114,
+101,101,116,121,112,101, 0,116,101,120,102,114,111,109, 0,110,117,109,116,105,108,101,115,120, 0,110,117,109,116,105,108,101,
+115,121, 0,118,105,101,119,114,101, 99,116, 0, 98,111,111,107,109, 97,114,107,114,101, 99,116, 0,115, 99,114,111,108,108,112,
+111,115, 0,115, 99,114,111,108,108,104,101,105,103,104,116, 0,115, 99,114,111,108,108, 97,114,101, 97, 0,114,101,116,118, 97,
+108, 0,112,114,118, 95,119, 0,112,114,118, 95,104, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99, 41, 40, 41, 0, 40, 42,
+114,101,116,117,114,110,102,117,110, 99, 95,101,118,101,110,116, 41, 40, 41, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99,
+ 95, 97,114,103,115, 41, 40, 41, 0, 42, 97,114,103, 49, 0, 42, 97,114,103, 50, 0, 42,109,101,110,117,112, 0, 42,105,109,103,
+ 0,108,101,110, 95, 97,108,108,111, 99, 0, 99,117,114,115,111,114, 0,114,112,116, 95,109, 97,115,107, 0,115, 99,114,111,108,
+108, 98, 97, 99,107, 0,104,105,115,116,111,114,121, 0,112,114,111,109,112,116, 91, 56, 93, 0,102,105,108,101,110, 97,109,101,
+ 91, 50, 53, 54, 93, 0, 98,108,102, 95,105,100, 0,117,105,102,111,110,116, 95,105,100, 0,114, 95,116,111, 95,108, 0,112,111,
+105,110,116,115, 0,107,101,114,110,105,110,103, 0,105,116, 97,108,105, 99, 0, 98,111,108,100, 0,115,104, 97,100,111,119, 0,
+115,104, 97,100,120, 0,115,104, 97,100,121, 0,115,104, 97,100,111,119, 97,108,112,104, 97, 0,115,104, 97,100,111,119, 99,111,
+108,111,114, 0,112, 97,110,101,108,116,105,116,108,101, 0,103,114,111,117,112,108, 97, 98,101,108, 0,119,105,100,103,101,116,
+108, 97, 98,101,108, 0,119,105,100,103,101,116, 0,112, 97,110,101,108,122,111,111,109, 0,109,105,110,108, 97, 98,101,108, 99,
+104, 97,114,115, 0,109,105,110,119,105,100,103,101,116, 99,104, 97,114,115, 0, 99,111,108,117,109,110,115,112, 97, 99,101, 0,
+116,101,109,112,108, 97,116,101,115,112, 97, 99,101, 0, 98,111,120,115,112, 97, 99,101, 0, 98,117,116,116,111,110,115,112, 97,
+ 99,101,120, 0, 98,117,116,116,111,110,115,112, 97, 99,101,121, 0,112, 97,110,101,108,115,112, 97, 99,101, 0,112, 97,110,101,
+108,111,117,116,101,114, 0,112, 97,100, 91, 49, 93, 0,111,117,116,108,105,110,101, 91, 52, 93, 0,105,110,110,101,114, 91, 52,
+ 93, 0,105,110,110,101,114, 95,115,101,108, 91, 52, 93, 0,105,116,101,109, 91, 52, 93, 0,116,101,120,116, 91, 52, 93, 0,116,
+101,120,116, 95,115,101,108, 91, 52, 93, 0,115,104, 97,100,101,100, 0,115,104, 97,100,101,116,111,112, 0,115,104, 97,100,101,
+100,111,119,110, 0,105,110,110,101,114, 95, 97,110,105,109, 91, 52, 93, 0,105,110,110,101,114, 95, 97,110,105,109, 95,115,101,
+108, 91, 52, 93, 0,105,110,110,101,114, 95,107,101,121, 91, 52, 93, 0,105,110,110,101,114, 95,107,101,121, 95,115,101,108, 91,
+ 52, 93, 0,105,110,110,101,114, 95,100,114,105,118,101,110, 91, 52, 93, 0,105,110,110,101,114, 95,100,114,105,118,101,110, 95,
+115,101,108, 91, 52, 93, 0,119, 99,111,108, 95,114,101,103,117,108, 97,114, 0,119, 99,111,108, 95,116,111,111,108, 0,119, 99,
+111,108, 95,116,101,120,116, 0,119, 99,111,108, 95,114, 97,100,105,111, 0,119, 99,111,108, 95,111,112,116,105,111,110, 0,119,
+ 99,111,108, 95,116,111,103,103,108,101, 0,119, 99,111,108, 95,110,117,109, 0,119, 99,111,108, 95,110,117,109,115,108,105,100,
+101,114, 0,119, 99,111,108, 95,109,101,110,117, 0,119, 99,111,108, 95,112,117,108,108,100,111,119,110, 0,119, 99,111,108, 95,
+109,101,110,117, 95, 98, 97, 99,107, 0,119, 99,111,108, 95,109,101,110,117, 95,105,116,101,109, 0,119, 99,111,108, 95, 98,111,
+120, 0,119, 99,111,108, 95,115, 99,114,111,108,108, 0,119, 99,111,108, 95,108,105,115,116, 95,105,116,101,109, 0,119, 99,111,
+108, 95,115,116, 97,116,101, 0,105, 99,111,110,102,105,108,101, 91, 56, 48, 93, 0, 98, 97, 99,107, 91, 52, 93, 0,116,105,116,
+108,101, 91, 52, 93, 0,116,101,120,116, 95,104,105, 91, 52, 93, 0,104,101, 97,100,101,114, 91, 52, 93, 0,104,101, 97,100,101,
+114, 95,116,105,116,108,101, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,101,120,116, 91, 52, 93, 0,104,101, 97,100,101,114,
+ 95,116,101,120,116, 95,104,105, 91, 52, 93, 0, 98,117,116,116,111,110, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,105,116,
+108,101, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101,120,116, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101,120,116,
+ 95,104,105, 91, 52, 93, 0,108,105,115,116, 91, 52, 93, 0,108,105,115,116, 95,116,105,116,108,101, 91, 52, 93, 0,108,105,115,
+116, 95,116,101,120,116, 91, 52, 93, 0,108,105,115,116, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,112, 97,110,101,108, 91,
+ 52, 93, 0,112, 97,110,101,108, 95,116,105,116,108,101, 91, 52, 93, 0,112, 97,110,101,108, 95,116,101,120,116, 91, 52, 93, 0,
+112, 97,110,101,108, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,115,104, 97,100,101, 49, 91, 52, 93, 0,115,104, 97,100,101,
+ 50, 91, 52, 93, 0,104,105,108,105,116,101, 91, 52, 93, 0,103,114,105,100, 91, 52, 93, 0,119,105,114,101, 91, 52, 93, 0,115,
+101,108,101, 99,116, 91, 52, 93, 0,108, 97,109,112, 91, 52, 93, 0, 97, 99,116,105,118,101, 91, 52, 93, 0,103,114,111,117,112,
+ 91, 52, 93, 0,103,114,111,117,112, 95, 97, 99,116,105,118,101, 91, 52, 93, 0,116,114, 97,110,115,102,111,114,109, 91, 52, 93,
+ 0,118,101,114,116,101,120, 91, 52, 93, 0,118,101,114,116,101,120, 95,115,101,108,101, 99,116, 91, 52, 93, 0,101,100,103,101,
+ 91, 52, 93, 0,101,100,103,101, 95,115,101,108,101, 99,116, 91, 52, 93, 0,101,100,103,101, 95,115,101, 97,109, 91, 52, 93, 0,
+101,100,103,101, 95,115,104, 97,114,112, 91, 52, 93, 0,101,100,103,101, 95,102, 97, 99,101,115,101,108, 91, 52, 93, 0,102, 97,
+ 99,101, 91, 52, 93, 0,102, 97, 99,101, 95,115,101,108,101, 99,116, 91, 52, 93, 0,102, 97, 99,101, 95,100,111,116, 91, 52, 93,
+ 0,110,111,114,109, 97,108, 91, 52, 93, 0, 98,111,110,101, 95,115,111,108,105,100, 91, 52, 93, 0, 98,111,110,101, 95,112,111,
+115,101, 91, 52, 93, 0,115,116,114,105,112, 91, 52, 93, 0,115,116,114,105,112, 95,115,101,108,101, 99,116, 91, 52, 93, 0, 99,
+102,114, 97,109,101, 91, 52, 93, 0,100,115, 95, 99,104, 97,110,110,101,108, 91, 52, 93, 0,100,115, 95,115,117, 98, 99,104, 97,
+110,110,101,108, 91, 52, 93, 0,118,101,114,116,101,120, 95,115,105,122,101, 0,102, 97, 99,101,100,111,116, 95,115,105,122,101,
+ 0, 98,112, 97,100, 91, 50, 93, 0,115,121,110,116, 97,120,108, 91, 52, 93, 0,115,121,110,116, 97,120,110, 91, 52, 93, 0,115,
+121,110,116, 97,120, 98, 91, 52, 93, 0,115,121,110,116, 97,120,118, 91, 52, 93, 0,115,121,110,116, 97,120, 99, 91, 52, 93, 0,
+109,111,118,105,101, 91, 52, 93, 0,105,109, 97,103,101, 91, 52, 93, 0,115, 99,101,110,101, 91, 52, 93, 0, 97,117,100,105,111,
+ 91, 52, 93, 0,101,102,102,101, 99,116, 91, 52, 93, 0,112,108,117,103,105,110, 91, 52, 93, 0,116,114, 97,110,115,105,116,105,
+111,110, 91, 52, 93, 0,109,101,116, 97, 91, 52, 93, 0,101,100,105,116,109,101,115,104, 95, 97, 99,116,105,118,101, 91, 52, 93,
+ 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 95,
+115,101,108,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 95,115,105,122,101, 0,104,112, 97,
+100, 91, 51, 93, 0,115,111,108,105,100, 91, 52, 93, 0,116,117,105, 0,116, 98,117,116,115, 0,116,118, 51,100, 0,116,102,105,
+108,101, 0,116,105,112,111, 0,116,105,110,102,111, 0,116,115,110,100, 0,116, 97, 99,116, 0,116,110,108, 97, 0,116,115,101,
+113, 0,116,105,109, 97, 0,116,105,109, 97,115,101,108, 0,116,101,120,116, 0,116,111,111,112,115, 0,116,116,105,109,101, 0,
+116,110,111,100,101, 0,116,108,111,103,105, 99, 0,116,117,115,101,114,112,114,101,102, 0,116, 97,114,109, 91, 50, 48, 93, 0,
+115,112,101, 99, 91, 52, 93, 0,100,117,112,102,108, 97,103, 0,115, 97,118,101,116,105,109,101, 0,116,101,109,112,100,105,114,
+ 91, 49, 54, 48, 93, 0,102,111,110,116,100,105,114, 91, 49, 54, 48, 93, 0,114,101,110,100,101,114,100,105,114, 91, 49, 54, 48,
+ 93, 0,116,101,120,116,117,100,105,114, 91, 49, 54, 48, 93, 0,112,108,117,103,116,101,120,100,105,114, 91, 49, 54, 48, 93, 0,
+112,108,117,103,115,101,113,100,105,114, 91, 49, 54, 48, 93, 0,112,121,116,104,111,110,100,105,114, 91, 49, 54, 48, 93, 0,115,
+111,117,110,100,100,105,114, 91, 49, 54, 48, 93, 0,121,102,101,120,112,111,114,116,100,105,114, 91, 49, 54, 48, 93, 0,118,101,
+114,115,105,111,110,115, 0,103, 97,109,101,102,108, 97,103,115, 0,119,104,101,101,108,108,105,110,101,115, 99,114,111,108,108,
+ 0,117,105,102,108, 97,103, 0,108, 97,110,103,117, 97,103,101, 0,117,115,101,114,112,114,101,102, 0,118,105,101,119,122,111,
+111,109, 0,109,105,120, 98,117,102,115,105,122,101, 0, 97,117,100,105,111,100,101,118,105, 99,101, 0, 97,117,100,105,111,114,
+ 97,116,101, 0, 97,117,100,105,111,102,111,114,109, 97,116, 0, 97,117,100,105,111, 99,104, 97,110,110,101,108,115, 0,100,112,
+105, 0,101,110, 99,111,100,105,110,103, 0,116,114, 97,110,115,111,112,116,115, 0,109,101,110,117,116,104,114,101,115,104,111,
+108,100, 49, 0,109,101,110,117,116,104,114,101,115,104,111,108,100, 50, 0,116,104,101,109,101,115, 0,117,105,102,111,110,116,
+115, 0,117,105,115,116,121,108,101,115, 0,117,110,100,111,115,116,101,112,115, 0,117,110,100,111,109,101,109,111,114,121, 0,
+103,112, 95,109, 97,110,104, 97,116,116,101,110,100,105,115,116, 0,103,112, 95,101,117, 99,108,105,100,101, 97,110,100,105,115,
+116, 0,103,112, 95,101,114, 97,115,101,114, 0,103,112, 95,115,101,116,116,105,110,103,115, 0,116, 98, 95,108,101,102,116,109,
+111,117,115,101, 0,116, 98, 95,114,105,103,104,116,109,111,117,115,101, 0,108,105,103,104,116, 91, 51, 93, 0,116,119, 95,104,
+111,116,115,112,111,116, 0,116,119, 95,102,108, 97,103, 0,116,119, 95,104, 97,110,100,108,101,115,105,122,101, 0,116,119, 95,
+115,105,122,101, 0,116,101,120,116,105,109,101,111,117,116, 0,116,101,120, 99,111,108,108,101, 99,116,114, 97,116,101, 0,119,
+109,100,114, 97,119,109,101,116,104,111,100, 0,119,109,112, 97,100, 0,109,101,109, 99, 97, 99,104,101,108,105,109,105,116, 0,
+112,114,101,102,101,116, 99,104,102,114, 97,109,101,115, 0,102,114, 97,109,101,115,101,114,118,101,114,112,111,114,116, 0,112,
+ 97,100, 95,114,111,116, 95, 97,110,103,108,101, 0,111, 98, 99,101,110,116,101,114, 95,100,105, 97, 0,114,118,105,115,105,122,
+101, 0,114,118,105, 98,114,105,103,104,116, 0,114,101, 99,101,110,116, 95,102,105,108,101,115, 0,115,109,111,111,116,104, 95,
+118,105,101,119,116,120, 0,103,108,114,101,115,108,105,109,105,116, 0,110,100,111,102, 95,112, 97,110, 0,110,100,111,102, 95,
+114,111,116, 97,116,101, 0, 99,117,114,115,115,105,122,101, 0,105,112,111, 95,110,101,119, 0,118,101,114,115,101,109, 97,115,
+116,101,114, 91, 49, 54, 48, 93, 0,118,101,114,115,101,117,115,101,114, 91, 49, 54, 48, 93, 0,103,108, 97,108,112,104, 97, 99,
+108,105,112, 0, 99,111, 98, 97, 95,119,101,105,103,104,116, 0,118,101,114,116, 98, 97,115,101, 0,101,100,103,101, 98, 97,115,
+101, 0, 97,114,101, 97, 98, 97,115,101, 0, 42,110,101,119,115, 99,101,110,101, 0,102,117,108,108, 0,119,105,110,105,100, 0,
+100,111, 95,100,114, 97,119, 0,100,111, 95,114,101,102,114,101,115,104, 0,100,111, 95,100,114, 97,119, 95,103,101,115,116,117,
+114,101, 0,100,111, 95,100,114, 97,119, 95,112, 97,105,110,116, 99,117,114,115,111,114, 0,115,119, 97,112, 0,109, 97,105,110,
+119,105,110, 0,115,117, 98,119,105,110, 97, 99,116,105,118,101, 0, 42, 97,110,105,109,116,105,109,101,114, 0, 42, 99,111,110,
+116,101,120,116, 0,104, 97,110,100,108,101,114, 91, 56, 93, 0, 42,110,101,119,118, 0,118,101, 99, 0, 42,118, 49, 0, 42,118,
+ 50, 0, 42,116,121,112,101, 0,112, 97,110,101,108,110, 97,109,101, 91, 54, 52, 93, 0,116, 97, 98,110, 97,109,101, 91, 54, 52,
+ 93, 0,100,114, 97,119,110, 97,109,101, 91, 54, 52, 93, 0,111,102,115,120, 0,111,102,115,121, 0,115,105,122,101,120, 0,115,
+105,122,101,121, 0,108, 97, 98,101,108,111,102,115, 0,114,117,110,116,105,109,101, 95,102,108, 97,103, 0, 99,111,110,116,114,
+111,108, 0,115,110, 97,112, 0,115,111,114,116,111,114,100,101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0, 42, 97, 99,116,
+105,118,101,100, 97,116, 97, 0,108,105,115,116, 95,115, 99,114,111,108,108, 0,108,105,115,116, 95,115,105,122,101, 0,108,105,
+115,116, 95,115,101, 97,114, 99,104, 91, 54, 52, 93, 0, 42,118, 51, 0, 42,118, 52, 0, 42,102,117,108,108, 0, 98,117,116,115,
+112, 97, 99,101,116,121,112,101, 0,104,101, 97,100,101,114,116,121,112,101, 0,115,112, 97, 99,101,100, 97,116, 97, 0,104, 97,
+110,100,108,101,114,115, 0, 97, 99,116,105,111,110,122,111,110,101,115, 0,119,105,110,114, 99,116, 0,100,114, 97,119,114, 99,
+116, 0,115,119,105,110,105,100, 0,114,101,103,105,111,110,116,121,112,101, 0, 97,108,105,103,110,109,101,110,116, 0,117,105,
+ 98,108,111, 99,107,115, 0,112, 97,110,101,108,115, 0, 42,104,101, 97,100,101,114,115,116,114, 0, 42,114,101,103,105,111,110,
+100, 97,116, 97, 0,115,117, 98,118,115,116,114, 91, 52, 93, 0,115,117, 98,118,101,114,115,105,111,110, 0,112, 97,100,115, 0,
+109,105,110,118,101,114,115,105,111,110, 0,109,105,110,115,117, 98,118,101,114,115,105,111,110, 0, 42, 99,117,114,115, 99,114,
+101,101,110, 0, 42, 99,117,114,115, 99,101,110,101, 0,102,105,108,101,102,108, 97,103,115, 0,103,108,111, 98, 97,108,102, 0,
+110, 97,109,101, 91, 56, 48, 93, 0, 42,105, 98,117,102, 0, 42,105, 98,117,102, 95, 99,111,109,112, 0, 42,115,101, 49, 0, 42,
+115,101, 50, 0, 42,115,101, 51, 0,110,114, 0, 98,111,116,116,111,109, 0,114,105,103,104,116, 0,120,111,102,115, 0,121,111,
+102,115, 0,108,105,102,116, 91, 51, 93, 0,103, 97,109,109, 97, 91, 51, 93, 0,103, 97,105,110, 91, 51, 93, 0,115, 97,116,117,
+114, 97,116,105,111,110, 0,100,105,114, 91, 49, 54, 48, 93, 0,100,111,110,101, 0,115,116, 97,114,116,115,116,105,108,108, 0,
+101,110,100,115,116,105,108,108, 0, 42,115,116,114,105,112,100, 97,116, 97, 0,111,114,120, 0,111,114,121, 0, 42, 99,114,111,
+112, 0, 42,116,114, 97,110,115,102,111,114,109, 0, 42, 99,111,108,111,114, 95, 98, 97,108, 97,110, 99,101, 0, 42,116,115,116,
+114,105,112,100, 97,116, 97, 0, 42,116,115,116,114,105,112,100, 97,116, 97, 95,115,116, 97,114,116,115,116,105,108,108, 0, 42,
+116,115,116,114,105,112,100, 97,116, 97, 95,101,110,100,115,116,105,108,108, 0, 42,105, 98,117,102, 95,115,116, 97,114,116,115,
+116,105,108,108, 0, 42,105, 98,117,102, 95,101,110,100,115,116,105,108,108, 0, 42,105,110,115,116, 97,110, 99,101, 95,112,114,
+105,118, 97,116,101, 95,100, 97,116, 97, 0, 42, 42, 99,117,114,114,101,110,116, 95,112,114,105,118, 97,116,101, 95,100, 97,116,
+ 97, 0, 42,116,109,112, 0,115,116, 97,114,116,111,102,115, 0,101,110,100,111,102,115, 0,109, 97, 99,104,105,110,101, 0,115,
+116, 97,114,116,100,105,115,112, 0,101,110,100,100,105,115,112, 0,104, 97,110,100,115,105,122,101, 0, 97,110,105,109, 95,112,
+114,101,115,101,101,107, 0, 42,115,116,114,105,112, 0,102, 97, 99,102, 48, 0,102, 97, 99,102, 49, 0, 42,115,101,113, 49, 0,
+ 42,115,101,113, 50, 0, 42,115,101,113, 51, 0,115,101,113, 98, 97,115,101, 0, 42,115,111,117,110,100, 0, 42,115,111,117,110,
+100, 95,104, 97,110,100,108,101, 0,108,101,118,101,108, 0,112, 97,110, 0,115, 99,101,110,101,110,114, 0,115,116,114,111, 98,
+101, 0, 42,101,102,102,101, 99,116,100, 97,116, 97, 0, 97,110,105,109, 95,115,116, 97,114,116,111,102,115, 0, 97,110,105,109,
+ 95,101,110,100,111,102,115, 0, 98,108,101,110,100, 95,109,111,100,101, 0, 98,108,101,110,100, 95,111,112, 97, 99,105,116,121,
+ 0, 42,111,108,100, 98, 97,115,101,112, 0, 42,112, 97,114,115,101,113, 0, 42,115,101,113, 98, 97,115,101,112, 0,109,101,116,
+ 97,115,116, 97, 99,107, 0, 42, 97, 99,116, 95,115,101,113, 0, 97, 99,116, 95,105,109, 97,103,101,100,105,114, 91, 50, 53, 54,
+ 93, 0, 97, 99,116, 95,115,111,117,110,100,100,105,114, 91, 50, 53, 54, 93, 0,101,100,103,101, 87,105,100,116,104, 0,102,111,
+114,119, 97,114,100, 0,119,105,112,101,116,121,112,101, 0,102, 77,105,110,105, 0,102, 67,108, 97,109,112, 0,102, 66,111,111,
+115,116, 0,100, 68,105,115,116, 0,100, 81,117, 97,108,105,116,121, 0, 98, 78,111, 67,111,109,112, 0, 83, 99, 97,108,101,120,
+ 73,110,105, 0, 83, 99, 97,108,101,121, 73,110,105, 0, 83, 99, 97,108,101,120, 70,105,110, 0, 83, 99, 97,108,101,121, 70,105,
+110, 0,120, 73,110,105, 0,120, 70,105,110, 0,121, 73,110,105, 0,121, 70,105,110, 0,114,111,116, 73,110,105, 0,114,111,116,
+ 70,105,110, 0,105,110,116,101,114,112,111,108, 97,116,105,111,110, 0, 42,102,114, 97,109,101, 77, 97,112, 0,103,108,111, 98,
+ 97,108, 83,112,101,101,100, 0,108, 97,115,116, 86, 97,108,105,100, 70,114, 97,109,101, 0, 98,117,116,116,121,112,101, 0,117,
+115,101,114,106,105,116, 0,115,116, 97, 0,116,111,116,112, 97,114,116, 0,110,111,114,109,102, 97, 99, 0,111, 98,102, 97, 99,
+ 0,114, 97,110,100,102, 97, 99, 0,116,101,120,102, 97, 99, 0,114, 97,110,100,108,105,102,101, 0,102,111,114, 99,101, 91, 51,
+ 93, 0,118,101, 99,116,115,105,122,101, 0,109, 97,120,108,101,110, 0,100,101,102,118,101, 99, 91, 51, 93, 0,109,117,108,116,
+ 91, 52, 93, 0,108,105,102,101, 91, 52, 93, 0, 99,104,105,108,100, 91, 52, 93, 0,109, 97,116, 91, 52, 93, 0,116,101,120,109,
+ 97,112, 0, 99,117,114,109,117,108,116, 0,115,116, 97,116,105, 99,115,116,101,112, 0,111,109, 97,116, 0,116,105,109,101,116,
+101,120, 0,115,112,101,101,100,116,101,120, 0,102,108, 97,103, 50,110,101,103, 0,118,101,114,116,103,114,111,117,112, 95,118,
+ 0,118,103,114,111,117,112,110, 97,109,101, 91, 51, 50, 93, 0,118,103,114,111,117,112,110, 97,109,101, 95,118, 91, 51, 50, 93,
+ 0, 42,107,101,121,115, 0,109,105,110,102, 97, 99, 0,117,115,101,100, 0,117,115,101,100,101,108,101,109, 0, 42,112,111,105,
+110, 0,114,101,115,101,116,100,105,115,116, 0,108, 97,115,116,118, 97,108, 0, 42,109, 97, 0,107,101,121, 0,113,117, 97,108,
+ 0,113,117, 97,108, 50, 0,116, 97,114,103,101,116, 78, 97,109,101, 91, 51, 50, 93, 0,116,111,103,103,108,101, 78, 97,109,101,
+ 91, 51, 50, 93, 0,118, 97,108,117,101, 91, 51, 50, 93, 0,109, 97,120,118, 97,108,117,101, 91, 51, 50, 93, 0,100,101,108, 97,
+121, 0,100,117,114, 97,116,105,111,110, 0,109, 97,116,101,114,105, 97,108, 78, 97,109,101, 91, 51, 50, 93, 0,100, 97,109,112,
+116,105,109,101,114, 0,112,114,111,112,110, 97,109,101, 91, 51, 50, 93, 0,109, 97,116,110, 97,109,101, 91, 51, 50, 93, 0, 97,
+120,105,115,102,108, 97,103, 0, 42,102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 51, 50, 93, 0,
+ 98,111,100,121, 91, 51, 50, 93, 0,111,116,121,112,101, 0,112,117,108,115,101, 0,102,114,101,113, 0,116,111,116,108,105,110,
+107,115, 0, 42, 42,108,105,110,107,115, 0,116, 97,112, 0,106,111,121,105,110,100,101,120, 0, 97,120,105,115, 95,115,105,110,
+103,108,101, 0, 97,120,105,115,102, 0, 98,117,116,116,111,110, 0,104, 97,116, 0,104, 97,116,102, 0,112,114,101, 99,105,115,
+105,111,110, 0,115,116,114, 91, 49, 50, 56, 93, 0,109,111,100,117,108,101, 91, 54, 52, 93, 0, 42,109,121,110,101,119, 0,105,
+110,112,117,116,115, 0,116,111,116,115,108,105,110,107,115, 0, 42, 42,115,108,105,110,107,115, 0,118, 97,108,111, 0,115,116,
+ 97,116,101, 95,109, 97,115,107, 0, 42, 97, 99,116, 0,102,114, 97,109,101, 80,114,111,112, 91, 51, 50, 93, 0, 98,108,101,110,
+100,105,110, 0,112,114,105,111,114,105,116,121, 0,101,110,100, 95,114,101,115,101,116, 0,115,116,114,105,100,101, 97,120,105,
+115, 0,115,116,114,105,100,101,108,101,110,103,116,104, 0,115,110,100,110,114, 0,112, 97,100, 49, 91, 50, 93, 0,112,105,116,
+ 99,104, 0,115,111,117,110,100, 51, 68, 0,109, 97,107,101, 99,111,112,121, 0, 99,111,112,121,109, 97,100,101, 0,112, 97,100,
+ 50, 91, 49, 93, 0, 42,109,101, 0,108,105,110, 86,101,108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,103, 86,101,108,111, 99,
+105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 0,100,121,110, 95,111,112,101,114, 97,116,105,111,110, 0,102,
+111,114, 99,101,108,111, 99, 91, 51, 93, 0,102,111,114, 99,101,114,111,116, 91, 51, 93, 0,108,105,110,101, 97,114,118,101,108,
+111, 99,105,116,121, 91, 51, 93, 0, 97,110,103,117,108, 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 42,114,101,102,
+101,114,101,110, 99,101, 0, 98,117,116,115,116, 97, 0, 98,117,116,101,110,100, 0,109,105,110, 0,109, 97,120, 0,118,105,115,
+105,102, 97, 99, 0,114,111,116,100, 97,109,112, 0,109,105,110,108,111, 99, 91, 51, 93, 0,109, 97,120,108,111, 99, 91, 51, 93,
+ 0,109,105,110,114,111,116, 91, 51, 93, 0,109, 97,120,114,111,116, 91, 51, 93, 0,109, 97,116,112,114,111,112, 91, 51, 50, 93,
+ 0,100,105,115,116,114,105, 98,117,116,105,111,110, 0,105,110,116, 95, 97,114,103, 95, 49, 0,105,110,116, 95, 97,114,103, 95,
+ 50, 0,102,108,111, 97,116, 95, 97,114,103, 95, 49, 0,102,108,111, 97,116, 95, 97,114,103, 95, 50, 0,116,111, 80,114,111,112,
+ 78, 97,109,101, 91, 51, 50, 93, 0, 42,116,111, 79, 98,106,101, 99,116, 0, 98,111,100,121, 84,121,112,101, 0,102,105,108,101,
+110, 97,109,101, 91, 54, 52, 93, 0,108,111, 97,100, 97,110,105,110, 97,109,101, 91, 54, 52, 93, 0,105,110,116, 95, 97,114,103,
+ 0,102,108,111, 97,116, 95, 97,114,103, 0,103,111, 0, 97, 99, 99,101,108,108,101,114, 97,116,105,111,110, 0,109, 97,120,115,
+112,101,101,100, 0,109, 97,120,114,111,116,115,112,101,101,100, 0,109, 97,120,116,105,108,116,115,112,101,101,100, 0,116,105,
+108,116,100, 97,109,112, 0,115,112,101,101,100,100, 97,109,112, 0, 42,115,111,117,114, 99,101, 0,102,114, 97,109,101,115,107,
+105,112, 0,109,117,116,101, 0, 99,104, 97,110,103,101,100, 0,109,105,110, 95,103, 97,105,110, 0,109, 97,120, 95,103, 97,105,
+110, 0,114,101,102,101,114,101,110, 99,101, 95,100,105,115,116, 97,110, 99,101, 0,109, 97,120, 95,100,105,115,116, 97,110, 99,
+101, 0,114,111,108,108,111,102,102, 95,102, 97, 99,116,111,114, 0, 99,111,110,101, 95,105,110,110,101,114, 95, 97,110,103,108,
+101, 0, 99,111,110,101, 95,111,117,116,101,114, 95, 97,110,103,108,101, 0, 99,111,110,101, 95,111,117,116,101,114, 95,103, 97,
+105,110, 0, 42,110,101,119,112, 97, 99,107,101,100,102,105,108,101, 0, 97,116,116,101,110,117, 97,116,105,111,110, 0,100,105,
+115,116, 97,110, 99,101, 0, 42, 99, 97, 99,104,101, 0, 42, 97,114,101, 97, 0, 42,108, 97,109,112,114,101,110, 0,103,111, 98,
106,101, 99,116, 0,100,117,112,108,105, 95,111,102,115, 91, 51, 93, 0, 99,104,105,108,100, 98, 97,115,101, 0,114,111,108,108,
0,104,101, 97,100, 91, 51, 93, 0,116, 97,105,108, 91, 51, 93, 0, 98,111,110,101, 95,109, 97,116, 91, 51, 93, 91, 51, 93, 0,
97,114,109, 95,104,101, 97,100, 91, 51, 93, 0, 97,114,109, 95,116, 97,105,108, 91, 51, 93, 0, 97,114,109, 95,109, 97,116, 91,
@@ -1879,321 +2013,347 @@ char datatoc_B_blend[]= {
98, 97,115,101, 0, 42,101,100, 98,111, 0, 42,115,107,101,116, 99,104, 0,108, 97,121,101,114, 95,112,114,111,116,101, 99,116,
101,100, 0,103,104,111,115,116,101,112, 0,103,104,111,115,116,115,105,122,101, 0,103,104,111,115,116,116,121,112,101, 0,112,
97,116,104,115,105,122,101, 0,103,104,111,115,116,115,102, 0,103,104,111,115,116,101,102, 0,112, 97,116,104,115,102, 0,112,
- 97,116,104,101,102, 0,112, 97,116,104, 98, 99, 0,112, 97,116,104, 97, 99, 0, 42,112,114,111,112, 0, 99,111,110,115,116,102,
-108, 97,103, 0,105,107,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120,
- 0, 42, 98,111,110,101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0, 42, 98, 95, 98,111,110,101, 95,109, 97,116,
-115, 0, 42,100,117, 97,108, 95,113,117, 97,116, 0, 42, 98, 95, 98,111,110,101, 95,100,117, 97,108, 95,113,117, 97,116,115, 0,
-101,117,108, 91, 51, 93, 0,114,111,116,109,111,100,101, 0, 99,104, 97,110, 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,
-115,101, 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,101, 95,104,101, 97,100, 91, 51, 93, 0,112,111,115,101, 95,116,
- 97,105,108, 91, 51, 93, 0,108,105,109,105,116,109,105,110, 91, 51, 93, 0,108,105,109,105,116,109, 97,120, 91, 51, 93, 0,115,
-116,105,102,102,110,101,115,115, 91, 51, 93, 0,105,107,115,116,114,101,116, 99,104, 0, 42, 99,117,115,116,111,109, 0, 99,104,
- 97,110, 98, 97,115,101, 0,112,114,111,120,121, 95,108, 97,121,101,114, 0,115,116,114,105,100,101, 95,111,102,102,115,101,116,
- 91, 51, 93, 0, 99,121, 99,108,105, 99, 95,111,102,102,115,101,116, 91, 51, 93, 0, 97,103,114,111,117,112,115, 0, 97, 99,116,
-105,118,101, 95,103,114,111,117,112, 0, 99,117,115,116,111,109, 67,111,108, 0, 99,115, 0, 99,117,114,118,101,115, 0,103,114,
-111,117,112,115, 0, 97, 99,116,105,118,101, 95,109, 97,114,107,101,114, 0, 42,115,111,117,114, 99,101, 0,102,105,108,116,101,
-114,102,108, 97,103, 0, 97,100,115, 0, 97, 99,116,110,114, 0, 97, 99,116,119,105,100,116,104, 0,116,105,109,101,115,108,105,
-100,101, 0, 42,103,114,112, 0,116,101,109,112, 0,110, 97,109,101, 91, 51, 48, 93, 0,111,119,110,115,112, 97, 99,101, 0,116,
- 97,114,115,112, 97, 99,101, 0,101,110,102,111,114, 99,101, 0,104,101, 97,100,116, 97,105,108, 0, 42,116, 97,114, 0,115,117,
- 98,116, 97,114,103,101,116, 91, 51, 50, 93, 0,109, 97,116,114,105,120, 91, 52, 93, 91, 52, 93, 0,115,112, 97, 99,101, 0,116,
- 97,114,110,117,109, 0,116, 97,114,103,101,116,115, 0,105,116,101,114, 97,116,105,111,110,115, 0,114,111,111,116, 98,111,110,
-101, 0,109, 97,120, 95,114,111,111,116, 98,111,110,101, 0, 42,112,111,108,101,116, 97,114, 0,112,111,108,101,115,117, 98,116,
- 97,114,103,101,116, 91, 51, 50, 93, 0,112,111,108,101, 97,110,103,108,101, 0,111,114,105,101,110,116,119,101,105,103,104,116,
- 0,103,114, 97, 98,116, 97,114,103,101,116, 91, 51, 93, 0,114,101,115,101,114,118,101,100, 49, 0,114,101,115,101,114,118,101,
-100, 50, 0,109,105,110,109, 97,120,102,108, 97,103, 0,115,116,117, 99,107, 0, 99, 97, 99,104,101, 91, 51, 93, 0,108,111, 99,
-107,102,108, 97,103, 0,102,111,108,108,111,119,102,108, 97,103, 0,118,111,108,109,111,100,101, 0,112,108, 97,110,101, 0,111,
-114,103,108,101,110,103,116,104, 0, 98,117,108,103,101, 0,112,105,118, 88, 0,112,105,118, 89, 0,112,105,118, 90, 0, 97,120,
- 88, 0, 97,120, 89, 0, 97,120, 90, 0,109,105,110, 76,105,109,105,116, 91, 54, 93, 0,109, 97,120, 76,105,109,105,116, 91, 54,
- 93, 0,101,120,116,114, 97, 70,122, 0,105,110,118,109, 97,116, 91, 52, 93, 91, 52, 93, 0,102,114,111,109, 0,116,111, 0,109,
- 97,112, 91, 51, 93, 0,101,120,112,111, 0,102,114,111,109, 95,109,105,110, 91, 51, 93, 0,102,114,111,109, 95,109, 97,120, 91,
- 51, 93, 0,116,111, 95,109,105,110, 91, 51, 93, 0,116,111, 95,109, 97,120, 91, 51, 93, 0,122,109,105,110, 0,122,109, 97,120,
- 0,112, 97,100, 91, 57, 93, 0, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,110,111, 95,114,111,116, 95, 97,120,105,115, 0,
-115,116,114,105,100,101, 95, 97,120,105,115, 0, 99,117,114,109,111,100, 0, 97, 99,116,115,116, 97,114,116, 0, 97, 99,116,101,
-110,100, 0, 97, 99,116,111,102,102,115, 0,115,116,114,105,100,101,108,101,110, 0,115, 99, 97,108,101, 0, 98,108,101,110,100,
-111,117,116, 0,115,116,114,105,100,101, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,111,102,102,115, 95, 98,111,110,101, 91,
- 51, 50, 93, 0,104, 97,115,105,110,112,117,116, 0,104, 97,115,111,117,116,112,117,116, 0,100, 97,116, 97,116,121,112,101, 0,
-115,111, 99,107,101,116,116,121,112,101, 0, 42,110,101,119, 95,115,111, 99,107, 0,110,115, 0,108,105,109,105,116, 0,115,116,
- 97, 99,107, 95,105,110,100,101,120, 0,105,110,116,101,114,110, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 95,101,120,116,
- 0,108,111, 99,120, 0,108,111, 99,121, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, 95,105,110,100,101,120, 0, 42,116,
-111,115,111, 99,107, 0, 42,108,105,110,107, 0, 42,110,101,119, 95,110,111,100,101, 0,117,115,101,114,110, 97,109,101, 91, 51,
- 50, 93, 0,108, 97,115,116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97,103,101, 0,109,105,110,105,119,105,
-100,116,104, 0, 99,117,115,116,111,109, 49, 0, 99,117,115,116,111,109, 50, 0, 99,117,115,116,111,109, 51, 0, 99,117,115,116,
-111,109, 52, 0,110,101,101,100, 95,101,120,101, 99, 0,101,120,101, 99, 0, 42,116,104,114,101, 97,100,100, 97,116, 97, 0,116,
-111,116,114, 0, 98,117,116,114, 0,112,114,118,114, 0, 42,116,121,112,101,105,110,102,111, 0, 42,102,114,111,109,110,111,100,
-101, 0, 42,116,111,110,111,100,101, 0, 42,102,114,111,109,115,111, 99,107, 0,110,111,100,101,115, 0,108,105,110,107,115, 0,
- 42,115,116, 97, 99,107, 0, 42,116,104,114,101, 97,100,115,116, 97, 99,107, 0,105,110,105,116, 0,115,116, 97, 99,107,115,105,
-122,101, 0, 99,117,114, 95,105,110,100,101,120, 0, 97,108,108,116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0, 42,
-115,101,108,105,110, 0, 42,115,101,108,111,117,116, 0, 40, 42,116,105,109,101, 99,117,114,115,111,114, 41, 40, 41, 0, 40, 42,
-115,116, 97,116,115, 95,100,114, 97,119, 41, 40, 41, 0, 40, 42,116,101,115,116, 95, 98,114,101, 97,107, 41, 40, 41, 0, 42,116,
- 98,104, 0, 42,116, 99,104, 0, 42,115,100,104, 0, 99,121, 99,108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,
-115, 0,109,105,110,115,112,101,101,100, 0,112,101,114, 99,101,110,116,120, 0,112,101,114, 99,101,110,116,121, 0, 98,111,107,
-101,104, 0, 99,117,114,118,101,100, 0,105,109, 97,103,101, 95,105,110, 95,119,105,100,116,104, 0,105,109, 97,103,101, 95,105,
-110, 95,104,101,105,103,104,116, 0, 99,101,110,116,101,114, 95,120, 0, 99,101,110,116,101,114, 95,121, 0,115,112,105,110, 0,
-105,116,101,114, 0,119,114, 97,112, 0,115,105,103,109, 97, 95, 99,111,108,111,114, 0,115,105,103,109, 97, 95,115,112, 97, 99,
-101, 0,104,117,101, 0,115, 97,116, 0,116, 49, 0,116, 50, 0,116, 51, 0,102,115,116,114,101,110,103,116,104, 0,102, 97,108,
-112,104, 97, 0,107,101,121, 91, 52, 93, 0,120, 49, 0,120, 50, 0,121, 49, 0,121, 50, 0, 99,111,108,110, 97,109,101, 91, 51,
- 50, 93, 0, 98,107,116,121,112,101, 0,114,111,116, 97,116,105,111,110, 0,103, 97,109, 99,111, 0,110,111, 95,122, 98,117,102,
- 0,102,115,116,111,112, 0,109, 97,120, 98,108,117,114, 0, 98,116,104,114,101,115,104, 0, 42,100,105, 99,116, 0, 42,110,111,
-100,101, 0, 97,110,103,108,101, 95,111,102,115, 0, 99,111,108,109,111,100, 0,109,105,120, 0,116,104,114,101,115,104,111,108,
-100, 0,102, 97,100,101, 0,109, 0, 99, 0,106,105,116, 0,112,114,111,106, 0,102,105,116, 0,115,104,111,114,116,121, 0,109,
-105,110,116, 97, 98,108,101, 0,109, 97,120,116, 97, 98,108,101, 0,101,120,116, 95,105,110, 91, 50, 93, 0,101,120,116, 95,111,
-117,116, 91, 50, 93, 0, 42, 99,117,114,118,101, 0, 42,116, 97, 98,108,101, 0, 42,112,114,101,109,117,108,116, 97, 98,108,101,
- 0, 99,117,114,114, 0, 99,108,105,112,114, 0, 99,109, 91, 52, 93, 0, 98,108, 97, 99,107, 91, 51, 93, 0,119,104,105,116,101,
- 91, 51, 93, 0, 98,119,109,117,108, 91, 51, 93, 0,115, 97,109,112,108,101, 91, 51, 93, 0,111,102,102,115,101,116, 91, 50, 93,
- 0, 99,108,111,110,101, 0,105,110,110,101,114,114, 97,100,105,117,115, 0,114, 97,116,101, 0,114,103, 98, 91, 51, 93, 0,114,
-111,116, 0,115, 99,117,108,112,116, 95,116,111,111,108, 0, 97, 99,116,105,118,101, 95,114,110,100, 0, 97, 99,116,105,118,101,
+ 97,116,104,101,102, 0,112, 97,116,104, 98, 99, 0,112, 97,116,104, 97, 99, 0, 42,112,111,105,110,116,115, 0,115,116, 97,114,
+116, 95,102,114, 97,109,101, 0,101,110,100, 95,102,114, 97,109,101, 0, 42,112,114,111,112, 0, 99,111,110,115,116,102,108, 97,
+103, 0,105,107,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120, 0, 42,
+ 98,111,110,101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0, 42, 98, 95, 98,111,110,101, 95,109, 97,116,115, 0,
+ 42,100,117, 97,108, 95,113,117, 97,116, 0, 42, 98, 95, 98,111,110,101, 95,100,117, 97,108, 95,113,117, 97,116,115, 0,101,117,
+108, 91, 51, 93, 0,114,111,116,109,111,100,101, 0, 99,104, 97,110, 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,101,
+ 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,101, 95,104,101, 97,100, 91, 51, 93, 0,112,111,115,101, 95,116, 97,105,
+108, 91, 51, 93, 0,108,105,109,105,116,109,105,110, 91, 51, 93, 0,108,105,109,105,116,109, 97,120, 91, 51, 93, 0,115,116,105,
+102,102,110,101,115,115, 91, 51, 93, 0,105,107,115,116,114,101,116, 99,104, 0, 42, 99,117,115,116,111,109, 0, 99,104, 97,110,
+ 98, 97,115,101, 0,112,114,111,120,121, 95,108, 97,121,101,114, 0,115,116,114,105,100,101, 95,111,102,102,115,101,116, 91, 51,
+ 93, 0, 99,121, 99,108,105, 99, 95,111,102,102,115,101,116, 91, 51, 93, 0, 97,103,114,111,117,112,115, 0, 97, 99,116,105,118,
+101, 95,103,114,111,117,112, 0, 99,104, 97,110,110,101,108,115, 0, 99,117,115,116,111,109, 67,111,108, 0, 99,115, 0, 99,117,
+114,118,101,115, 0,103,114,111,117,112,115, 0, 97, 99,116,105,118,101, 95,109, 97,114,107,101,114, 0,102,105,108,116,101,114,
+102,108, 97,103, 0, 97,100,115, 0, 97, 99,116,110,114, 0, 97, 99,116,119,105,100,116,104, 0,116,105,109,101,115,108,105,100,
+101, 0, 42,103,114,112, 0,116,101,109,112, 0,110, 97,109,101, 91, 51, 48, 93, 0,111,119,110,115,112, 97, 99,101, 0,116, 97,
+114,115,112, 97, 99,101, 0,101,110,102,111,114, 99,101, 0,104,101, 97,100,116, 97,105,108, 0, 42,116, 97,114, 0,109, 97,116,
+114,105,120, 91, 52, 93, 91, 52, 93, 0,115,112, 97, 99,101, 0,114,111,116, 79,114,100,101,114, 0,116, 97,114,110,117,109, 0,
+116, 97,114,103,101,116,115, 0,105,116,101,114, 97,116,105,111,110,115, 0,114,111,111,116, 98,111,110,101, 0,109, 97,120, 95,
+114,111,111,116, 98,111,110,101, 0, 42,112,111,108,101,116, 97,114, 0,112,111,108,101,115,117, 98,116, 97,114,103,101,116, 91,
+ 51, 50, 93, 0,112,111,108,101, 97,110,103,108,101, 0,111,114,105,101,110,116,119,101,105,103,104,116, 0,103,114, 97, 98,116,
+ 97,114,103,101,116, 91, 51, 93, 0,114,101,115,101,114,118,101,100, 49, 0,114,101,115,101,114,118,101,100, 50, 0,109,105,110,
+109, 97,120,102,108, 97,103, 0,115,116,117, 99,107, 0, 99, 97, 99,104,101, 91, 51, 93, 0,108,111, 99,107,102,108, 97,103, 0,
+102,111,108,108,111,119,102,108, 97,103, 0,118,111,108,109,111,100,101, 0,112,108, 97,110,101, 0,111,114,103,108,101,110,103,
+116,104, 0, 98,117,108,103,101, 0,112,105,118, 88, 0,112,105,118, 89, 0,112,105,118, 90, 0, 97,120, 88, 0, 97,120, 89, 0,
+ 97,120, 90, 0,109,105,110, 76,105,109,105,116, 91, 54, 93, 0,109, 97,120, 76,105,109,105,116, 91, 54, 93, 0,101,120,116,114,
+ 97, 70,122, 0,105,110,118,109, 97,116, 91, 52, 93, 91, 52, 93, 0,102,114,111,109, 0,116,111, 0,109, 97,112, 91, 51, 93, 0,
+101,120,112,111, 0,102,114,111,109, 95,109,105,110, 91, 51, 93, 0,102,114,111,109, 95,109, 97,120, 91, 51, 93, 0,116,111, 95,
+109,105,110, 91, 51, 93, 0,116,111, 95,109, 97,120, 91, 51, 93, 0,122,109,105,110, 0,122,109, 97,120, 0,112, 97,100, 91, 57,
+ 93, 0, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,110,111, 95,114,111,116, 95, 97,120,105,115, 0,115,116,114,105,100,101,
+ 95, 97,120,105,115, 0, 99,117,114,109,111,100, 0, 97, 99,116,115,116, 97,114,116, 0, 97, 99,116,101,110,100, 0, 97, 99,116,
+111,102,102,115, 0,115,116,114,105,100,101,108,101,110, 0,115, 99, 97,108,101, 0, 98,108,101,110,100,111,117,116, 0,115,116,
+114,105,100,101, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,111,102,102,115, 95, 98,111,110,101, 91, 51, 50, 93, 0,104, 97,
+115,105,110,112,117,116, 0,104, 97,115,111,117,116,112,117,116, 0,100, 97,116, 97,116,121,112,101, 0,115,111, 99,107,101,116,
+116,121,112,101, 0, 42,110,101,119, 95,115,111, 99,107, 0,110,115, 0,108,105,109,105,116, 0,115,116, 97, 99,107, 95,105,110,
+100,101,120, 0,105,110,116,101,114,110, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 95,101,120,116, 0,108,111, 99,120, 0,
+108,111, 99,121, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, 95,105,110,100,101,120, 0, 42,116,111,115,111, 99,107, 0,
+ 42,108,105,110,107, 0, 42,110,101,119, 95,110,111,100,101, 0,117,115,101,114,110, 97,109,101, 91, 51, 50, 93, 0,108, 97,115,
+116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97,103,101, 0,109,105,110,105,119,105,100,116,104, 0, 99,117,
+115,116,111,109, 49, 0, 99,117,115,116,111,109, 50, 0, 99,117,115,116,111,109, 51, 0, 99,117,115,116,111,109, 52, 0,110,101,
+101,100, 95,101,120,101, 99, 0,101,120,101, 99, 0, 42,116,104,114,101, 97,100,100, 97,116, 97, 0,116,111,116,114, 0, 98,117,
+116,114, 0,112,114,118,114, 0, 42,116,121,112,101,105,110,102,111, 0, 42,102,114,111,109,110,111,100,101, 0, 42,116,111,110,
+111,100,101, 0, 42,102,114,111,109,115,111, 99,107, 0,110,111,100,101,115, 0,108,105,110,107,115, 0, 42,115,116, 97, 99,107,
+ 0, 42,116,104,114,101, 97,100,115,116, 97, 99,107, 0,105,110,105,116, 0,115,116, 97, 99,107,115,105,122,101, 0, 99,117,114,
+ 95,105,110,100,101,120, 0, 97,108,108,116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0, 42,115,101,108,105,110, 0,
+ 42,115,101,108,111,117,116, 0, 40, 42,116,105,109,101, 99,117,114,115,111,114, 41, 40, 41, 0, 40, 42,115,116, 97,116,115, 95,
+100,114, 97,119, 41, 40, 41, 0, 40, 42,116,101,115,116, 95, 98,114,101, 97,107, 41, 40, 41, 0, 42,116, 98,104, 0, 42,116, 99,
+104, 0, 42,115,100,104, 0, 99,121, 99,108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,115, 0,109,105,110,115,
+112,101,101,100, 0,112,101,114, 99,101,110,116,120, 0,112,101,114, 99,101,110,116,121, 0, 98,111,107,101,104, 0, 99,117,114,
+118,101,100, 0,105,109, 97,103,101, 95,105,110, 95,119,105,100,116,104, 0,105,109, 97,103,101, 95,105,110, 95,104,101,105,103,
+104,116, 0, 99,101,110,116,101,114, 95,120, 0, 99,101,110,116,101,114, 95,121, 0,115,112,105,110, 0,105,116,101,114, 0,119,
+114, 97,112, 0,115,105,103,109, 97, 95, 99,111,108,111,114, 0,115,105,103,109, 97, 95,115,112, 97, 99,101, 0,104,117,101, 0,
+115, 97,116, 0,116, 49, 0,116, 50, 0,116, 51, 0,102,115,116,114,101,110,103,116,104, 0,102, 97,108,112,104, 97, 0,107,101,
+121, 91, 52, 93, 0,120, 49, 0,120, 50, 0,121, 49, 0,121, 50, 0, 99,111,108,110, 97,109,101, 91, 51, 50, 93, 0, 98,107,116,
+121,112,101, 0,114,111,116, 97,116,105,111,110, 0,103, 97,109, 99,111, 0,110,111, 95,122, 98,117,102, 0,102,115,116,111,112,
+ 0,109, 97,120, 98,108,117,114, 0, 98,116,104,114,101,115,104, 0, 42,100,105, 99,116, 0, 42,110,111,100,101, 0, 97,110,103,
+108,101, 95,111,102,115, 0, 99,111,108,109,111,100, 0,109,105,120, 0,116,104,114,101,115,104,111,108,100, 0,102, 97,100,101,
+ 0,109, 0, 99, 0,106,105,116, 0,112,114,111,106, 0,102,105,116, 0,115,104,111,114,116,121, 0,109,105,110,116, 97, 98,108,
+101, 0,109, 97,120,116, 97, 98,108,101, 0,101,120,116, 95,105,110, 91, 50, 93, 0,101,120,116, 95,111,117,116, 91, 50, 93, 0,
+ 42, 99,117,114,118,101, 0, 42,116, 97, 98,108,101, 0, 42,112,114,101,109,117,108,116, 97, 98,108,101, 0, 99,117,114,114, 0,
+ 99,108,105,112,114, 0, 99,109, 91, 52, 93, 0, 98,108, 97, 99,107, 91, 51, 93, 0,119,104,105,116,101, 91, 51, 93, 0, 98,119,
+109,117,108, 91, 51, 93, 0,115, 97,109,112,108,101, 91, 51, 93, 0,111,102,102,115,101,116, 91, 50, 93, 0, 99,108,111,110,101,
+ 0,105,110,110,101,114,114, 97,100,105,117,115, 0,115,109,111,111,116,104, 95,115,116,114,111,107,101, 95,114, 97,100,105,117,
+115, 0,115,109,111,111,116,104, 95,115,116,114,111,107,101, 95,102, 97, 99,116,111,114, 0,114, 97,116,101, 0,114,103, 98, 91,
+ 51, 93, 0,115, 99,117,108,112,116, 95,116,111,111,108, 0, 97, 99,116,105,118,101, 95,114,110,100, 0, 97, 99,116,105,118,101,
95, 99,108,111,110,101, 0, 97, 99,116,105,118,101, 95,109, 97,115,107, 0, 42,108, 97,121,101,114,115, 0,116,111,116,108, 97,
121,101,114, 0,109, 97,120,108, 97,121,101,114, 0,116,111,116,115,105,122,101, 0, 42,112,111,111,108, 0,101,100,105,116,102,
-108, 97,103, 0,118,101,108, 91, 51, 93, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 0,110,117,109, 0,112, 97,114,
-101,110,116, 0,112, 97, 91, 52, 93, 0,119, 91, 52, 93, 0,102,117,118, 91, 52, 93, 0,102,111,102,102,115,101,116, 0,114, 97,
-110,100, 91, 51, 93, 0, 42,115,116,105, 99,107, 95,111, 98, 0,112,114,101,118, 95,115,116, 97,116,101, 0, 42,104, 97,105,114,
- 0, 42, 98,111,105,100, 0,114, 95,114,111,116, 91, 52, 93, 0,114, 95, 97,118,101, 91, 51, 93, 0,114, 95,118,101, 91, 51, 93,
- 0,100,105,101,116,105,109,101, 0,115,105,122,101,109,117,108, 0,110,117,109, 95,100,109, 99, 97, 99,104,101, 0, 98,112,105,
- 0, 97,108,105,118,101, 0,108,111,111,112, 0, 42, 98,111,105,100,115, 0,100,105,115,116,114, 0,112,104,121,115,116,121,112,
-101, 0, 97,118,101,109,111,100,101, 0,114,101, 97, 99,116,101,118,101,110,116, 0,100,114, 97,119, 0,100,114, 97,119, 95, 97,
-115, 0,100,114, 97,119, 95,115,105,122,101, 0, 99,104,105,108,100,116,121,112,101, 0,114,101,110, 95, 97,115, 0,100,114, 97,
-119, 95,115,116,101,112, 0,114,101,110, 95,115,116,101,112, 0,104, 97,105,114, 95,115,116,101,112, 0,107,101,121,115, 95,115,
-116,101,112, 0, 97,100, 97,112,116, 95, 97,110,103,108,101, 0, 97,100, 97,112,116, 95,112,105,120, 0,114,111,116,102,114,111,
-109, 0,105,110,116,101,103,114, 97,116,111,114, 0, 98, 98, 95, 97,108,105,103,110, 0, 98, 98, 95,117,118, 95,115,112,108,105,
-116, 0, 98, 98, 95, 97,110,105,109, 0, 98, 98, 95,115,112,108,105,116, 95,111,102,102,115,101,116, 0, 98, 98, 95,116,105,108,
-116, 0, 98, 98, 95,114, 97,110,100, 95,116,105,108,116, 0, 98, 98, 95,111,102,102,115,101,116, 91, 50, 93, 0,115,105,109,112,
-108,105,102,121, 95,102,108, 97,103, 0,115,105,109,112,108,105,102,121, 95,114,101,102,115,105,122,101, 0,115,105,109,112,108,
-105,102,121, 95,114, 97,116,101, 0,115,105,109,112,108,105,102,121, 95,116,114, 97,110,115,105,116,105,111,110, 0,115,105,109,
-112,108,105,102,121, 95,118,105,101,119,112,111,114,116, 0,116,105,109,101,116,119,101, 97,107, 0,106,105,116,102, 97, 99, 0,
-101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114,101,115, 0,112, 97,114,116,102, 97, 99, 0,116, 97,110,102, 97, 99,
- 0,116, 97,110,112,104, 97,115,101, 0,114,101, 97, 99,116,102, 97, 99, 0, 97,118,101,102, 97, 99, 0,112,104, 97,115,101,102,
- 97, 99, 0,114, 97,110,100,114,111,116,102, 97, 99, 0,114, 97,110,100,112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100,115,
-105,122,101, 0,114,101, 97, 99,116,115,104, 97,112,101, 0, 97, 99, 99, 91, 51, 93, 0,100,114, 97,103,102, 97, 99, 0, 98,114,
-111,119,110,102, 97, 99, 0,100, 97,109,112,102, 97, 99, 0,114, 97,110,100,108,101,110,103,116,104, 0, 99,104,105,108,100, 95,
-110, 98,114, 0,114,101,110, 95, 99,104,105,108,100, 95,110, 98,114, 0,112, 97,114,101,110,116,115, 0, 99,104,105,108,100,115,
-105,122,101, 0, 99,104,105,108,100,114, 97,110,100,115,105,122,101, 0, 99,104,105,108,100,114, 97,100, 0, 99,104,105,108,100,
-102,108, 97,116, 0, 99,108,117,109,112,102, 97, 99, 0, 99,108,117,109,112,112,111,119, 0,114,111,117,103,104, 49, 0,114,111,
-117,103,104, 49, 95,115,105,122,101, 0,114,111,117,103,104, 50, 0,114,111,117,103,104, 50, 95,115,105,122,101, 0,114,111,117,
-103,104, 50, 95,116,104,114,101,115, 0,114,111,117,103,104, 95,101,110,100, 0,114,111,117,103,104, 95,101,110,100, 95,115,104,
- 97,112,101, 0, 99,108,101,110,103,116,104, 0, 99,108,101,110,103,116,104, 95,116,104,114,101,115, 0, 98,114, 97,110, 99,104,
- 95,116,104,114,101,115, 0,100,114, 97,119, 95,108,105,110,101, 91, 50, 93, 0,112, 97,116,104, 95,115,116, 97,114,116, 0,112,
- 97,116,104, 95,101,110,100, 0,116,114, 97,105,108, 95, 99,111,117,110,116, 0,107,101,121,101,100, 95,108,111,111,112,115, 0,
-101,102,102,101, 99,116,111,114, 95,119,101,105,103,104,116, 91, 49, 48, 93, 0, 42,101,102,102, 95,103,114,111,117,112, 0, 42,
-100,117,112, 95,111, 98, 0, 42, 98, 98, 95,111, 98, 0, 42,112,100, 50, 0, 42,112, 97,114,116, 0, 42,101,100,105,116, 0, 40,
- 42,102,114,101,101, 95,101,100,105,116, 41, 40, 41, 0, 42, 42,112, 97,116,104, 99, 97, 99,104,101, 0, 42, 42, 99,104,105,108,
-100, 99, 97, 99,104,101, 0,112, 97,116,104, 99, 97, 99,104,101, 98,117,102,115, 0, 99,104,105,108,100, 99, 97, 99,104,101, 98,
-117,102,115, 0, 42,116, 97,114,103,101,116, 95,111, 98, 0, 42,108, 97,116,116,105, 99,101, 0,101,102,102,101, 99,116,111,114,
-115, 0,114,101, 97, 99,116,101,118,101,110,116,115, 0,116,114,101,101, 95,102,114, 97,109,101, 0,116,111,116, 99,104,105,108,
-100, 0,116,111,116, 99, 97, 99,104,101,100, 0,116,111,116, 99,104,105,108,100, 99, 97, 99,104,101, 0,116, 97,114,103,101,116,
- 95,112,115,121,115, 0,116,111,116,107,101,121,101,100, 0, 98, 97,107,101,115,112, 97, 99,101, 0, 98, 98, 95,117,118,110, 97,
-109,101, 91, 51, 93, 91, 51, 50, 93, 0,118,103,114,111,117,112, 91, 49, 50, 93, 0,118,103, 95,110,101,103, 0,114,116, 51, 0,
- 42,114,101,110,100,101,114,100, 97,116, 97, 0, 42,116,114,101,101, 0, 42, 99, 97, 99,104,101, 0, 67,100,105,115, 0, 67,118,
-105, 0, 91, 51, 93, 0,115,116,114,117, 99,116,117,114, 97,108, 0, 98,101,110,100,105,110,103, 0,109, 97,120, 95, 98,101,110,
-100, 0,109, 97,120, 95,115,116,114,117, 99,116, 0,109, 97,120, 95,115,104,101, 97,114, 0, 97,118,103, 95,115,112,114,105,110,
-103, 95,108,101,110, 0,116,105,109,101,115, 99, 97,108,101, 0,101,102,102, 95,102,111,114, 99,101, 95,115, 99, 97,108,101, 0,
-101,102,102, 95,119,105,110,100, 95,115, 99, 97,108,101, 0,115,105,109, 95,116,105,109,101, 95,111,108,100, 0,115,116,101,112,
-115, 80,101,114, 70,114, 97,109,101, 0,112,114,101,114,111,108,108, 0,109, 97,120,115,112,114,105,110,103,108,101,110, 0,115,
-111,108,118,101,114, 95,116,121,112,101, 0,118,103,114,111,117,112, 95, 98,101,110,100, 0,118,103,114,111,117,112, 95,109, 97,
-115,115, 0,118,103,114,111,117,112, 95,115,116,114,117, 99,116, 0,112,114,101,115,101,116,115, 0, 42, 99,111,108,108,105,115,
-105,111,110, 95,108,105,115,116, 0,101,112,115,105,108,111,110, 0,115,101,108,102, 95,102,114,105, 99,116,105,111,110, 0,115,
-101,108,102,101,112,115,105,108,111,110, 0,115,101,108,102, 95,108,111,111,112, 95, 99,111,117,110,116, 0,108,111,111,112, 95,
- 99,111,117,110,116, 0,112,114,101,115,115,117,114,101, 0, 42,112,111,105,110,116,115, 0,116,111,116,112,111,105,110,116,115,
- 0,116,104,105, 99,107,110,101,115,115, 0,115,116,114,111,107,101,115, 0,102,114, 97,109,101,110,117,109, 0, 42, 97, 99,116,
-102,114, 97,109,101, 0,103,115,116,101,112, 0,105,110,102,111, 91, 49, 50, 56, 93, 0,115, 98,117,102,102,101,114, 95,115,105,
-122,101, 0,115, 98,117,102,102,101,114, 95,115,102,108, 97,103, 0, 42,115, 98,117,102,102,101,114, 0, 42,116,121,112,101,115,
-116,114, 0, 42,109,101,115,115, 97,103,101, 0,108,105,115,116, 0,112,114,105,110,116,108,101,118,101,108, 0,115,116,111,114,
-101,108,101,118,101,108, 0, 42,119,105,110,100,114, 97,119, 97, 98,108,101, 0, 42,119,105,110, 97, 99,116,105,118,101, 0,119,
-105,110,100,111,119,115, 0,105,110,105,116,105, 97,108,105,122,101,100, 0,102,105,108,101, 95,115, 97,118,101,100, 0,111,112,
-101,114, 97,116,111,114,115, 0,113,117,101,117,101, 0,114,101,112,111,114,116,115, 0,106,111, 98,115, 0,112, 97,105,110,116,
- 99,117,114,115,111,114,115, 0,107,101,121,109, 97,112,115, 0, 42,103,104,111,115,116,119,105,110, 0, 42,110,101,119,115, 99,
-114,101,101,110, 0,115, 99,114,101,101,110,110, 97,109,101, 91, 51, 50, 93, 0,112,111,115,120, 0,112,111,115,121, 0,119,105,
-110,100,111,119,115,116, 97,116,101, 0,109,111,110,105,116,111,114, 0,108, 97,115,116, 99,117,114,115,111,114, 0, 97,100,100,
-109,111,117,115,101,109,111,118,101, 0, 42,101,118,101,110,116,115,116, 97,116,101, 0, 42, 99,117,114,115,119,105,110, 0, 42,
-116,119,101, 97,107, 0,100,114, 97,119,109,101,116,104,111,100, 0,100,114, 97,119,102, 97,105,108, 0, 42,100,114, 97,119,100,
- 97,116, 97, 0,116,105,109,101,114,115, 0,115,117, 98,119,105,110,100,111,119,115, 0,103,101,115,116,117,114,101, 0,105,100,
-110, 97,109,101, 91, 54, 52, 93, 0, 42,112,116,114, 0,115,104,105,102,116, 0, 99,116,114,108, 0, 97,108,116, 0,111,115,107,
-101,121, 0,107,101,121,109,111,100,105,102,105,101,114, 0,112,114,111,112,118, 97,108,117,101, 0,105,110, 97, 99,116,105,118,
-101, 0,109, 97,112,116,121,112,101, 0,107,101,121,109, 97,112, 0,110, 97,109,101,105,100, 91, 54, 52, 93, 0,115,112, 97, 99,
-101,105,100, 0,114,101,103,105,111,110,105,100, 0,105,115, 95,109,111,100, 97,108, 0, 42,105,116,101,109,115, 0, 42, 99,117,
-115,116,111,109,100, 97,116, 97, 0, 42,114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0,109,118, 97,
-108, 91, 50, 93, 0,112,114,101,118,120, 0,112,114,101,118,121, 0,117,110,105, 99,111,100,101, 0, 97,115, 99,105,105, 0, 42,
-107,101,121,109, 97,112, 95,105,100,110, 97,109,101, 0, 99,117,115,116,111,109, 0, 99,117,115,116,111,109,100, 97,116, 97,102,
-114,101,101, 0, 42,101,100, 97,116, 97, 0,105,110,102,108,117,101,110, 99,101, 0, 42, 99,111,101,102,102,105, 99,105,101,110,
-116,115, 0, 97,114,114, 97,121,115,105,122,101, 0,112,111,108,121, 95,111,114,100,101,114, 0, 97,109,112,108,105,116,117,100,
-101, 0,112,104, 97,115,101, 95,109,117,108,116,105,112,108,105,101,114, 0,112,104, 97,115,101, 95,111,102,102,115,101,116, 0,
-118, 97,108,117,101, 95,111,102,102,115,101,116, 0,109,105,100,118, 97,108, 0, 98,101,102,111,114,101, 95,109,111,100,101, 0,
- 97,102,116,101,114, 95,109,111,100,101, 0, 98,101,102,111,114,101, 95, 99,121, 99,108,101,115, 0, 97,102,116,101,114, 95, 99,
-121, 99,108,101,115, 0,114,101, 99,116, 0,112,104, 97,115,101, 0,109,111,100,105,102,105, 99, 97,116,105,111,110, 0, 42,114,
-110, 97, 95,112, 97,116,104, 0, 97,114,114, 97,121, 95,105,110,100,101,120, 0,101,120,112,114,101,115,115,105,111,110, 91, 50,
- 53, 54, 93, 0,118,101, 99, 91, 50, 93, 0, 42,102,112,116, 0, 99,111,108,111,114, 95,109,111,100,101, 0, 99,111,108,111,114,
- 91, 51, 93, 0,102,114,111,109, 91, 49, 50, 56, 93, 0,116,111, 91, 49, 50, 56, 93, 0,109, 97,112,112,105,110,103,115, 0,115,
-116,114,105,112,115, 0, 42,114,101,109, 97,112, 0,102, 99,117,114,118,101,115, 0,115,116,114,105,112, 95,116,105,109,101, 0,
- 98,108,101,110,100,109,111,100,101, 0,101,120,116,101,110,100,109,111,100,101, 0,103,114,111,117,112, 91, 54, 52, 93, 0,105,
-100,116,121,112,101, 0,116,101,109,112,108, 97,116,101,115, 0,103,114,111,117,112,109,111,100,101, 0,112, 97,116,104,115, 0,
-107,101,121,105,110,103,102,108, 97,103, 0, 42,116,109,112, 97, 99,116, 0,110,108, 97, 95,116,114, 97, 99,107,115, 0, 42, 97,
- 99,116,115,116,114,105,112, 0,100,114,105,118,101,114,115, 0,111,118,101,114,114,105,100,101,115, 0,114,117,108,101, 0,111,
-112,116,105,111,110,115, 0,102,101, 97,114, 95,102, 97, 99,116,111,114, 0,115,105,103,110, 97,108, 95,105,100, 0,108,111,111,
-107, 95, 97,104,101, 97,100, 0,111,108,111, 99, 91, 51, 93, 0,113,117,101,117,101, 95,115,105,122,101, 0,119, 97,110,100,101,
-114, 0,102,108,101,101, 95,100,105,115,116, 97,110, 99,101, 0,104,101, 97,108,116,104, 0,115,116, 97,116,101, 95,105,100, 0,
-114,117,108,101,115, 0, 99,111,110,100,105,116,105,111,110,115, 0, 97, 99,116,105,111,110,115, 0,114,117,108,101,115,101,116,
- 95,116,121,112,101, 0,114,117,108,101, 95,102,117,122,122,105,110,101,115,115, 0,108, 97,115,116, 95,115,116, 97,116,101, 95,
-105,100, 0,108, 97,110,100,105,110,103, 95,115,109,111,111,116,104,110,101,115,115, 0, 98, 97,110,107,105,110,103, 0, 97,103,
-103,114,101,115,115,105,111,110, 0, 97, 99, 99,117,114, 97, 99,121, 0, 97,105,114, 95,109,105,110, 95,115,112,101,101,100, 0,
- 97,105,114, 95,109, 97,120, 95,115,112,101,101,100, 0, 97,105,114, 95,109, 97,120, 95, 97, 99, 99, 0, 97,105,114, 95,109, 97,
-120, 95, 97,118,101, 0, 97,105,114, 95,112,101,114,115,111,110, 97,108, 95,115,112, 97, 99,101, 0,108, 97,110,100, 95,106,117,
-109,112, 95,115,112,101,101,100, 0,108, 97,110,100, 95,109, 97,120, 95,115,112,101,101,100, 0,108, 97,110,100, 95,109, 97,120,
- 95, 97, 99, 99, 0,108, 97,110,100, 95,109, 97,120, 95, 97,118,101, 0,108, 97,110,100, 95,112,101,114,115,111,110, 97,108, 95,
-115,112, 97, 99,101, 0,108, 97,110,100, 95,115,116,105, 99,107, 95,102,111,114, 99,101, 0,115,116, 97,116,101,115, 0, 0, 0,
- 84, 89, 80, 69,168, 1, 0, 0, 99,104, 97,114, 0,117, 99,104, 97,114, 0,115,104,111,114,116, 0,117,115,104,111,114,116, 0,
-105,110,116, 0,108,111,110,103, 0,117,108,111,110,103, 0,102,108,111, 97,116, 0,100,111,117, 98,108,101, 0,118,111,105,100,
- 0, 76,105,110,107, 0, 76,105,110,107, 68, 97,116, 97, 0, 76,105,115,116, 66, 97,115,101, 0,118,101, 99, 50,115, 0,118,101,
- 99, 50,105, 0,118,101, 99, 50,102, 0,118,101, 99, 50,100, 0,118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51,
-100, 0,118,101, 99, 52,105, 0,118,101, 99, 52,102, 0,118,101, 99, 52,100, 0,114, 99,116,105, 0,114, 99,116,102, 0, 73, 68,
- 80,114,111,112,101,114,116,121, 68, 97,116, 97, 0, 73, 68, 80,114,111,112,101,114,116,121, 0, 73, 68, 0, 76,105, 98,114, 97,
-114,121, 0, 70,105,108,101, 68, 97,116, 97, 0, 80,114,101,118,105,101,119, 73,109, 97,103,101, 0, 73,112,111, 68,114,105,118,
-101,114, 0, 79, 98,106,101, 99,116, 0, 73,112,111, 67,117,114,118,101, 0, 66, 80,111,105,110,116, 0, 66,101,122, 84,114,105,
-112,108,101, 0, 73,112,111, 0, 75,101,121, 66,108,111, 99,107, 0, 75,101,121, 0, 65,110,105,109, 68, 97,116, 97, 0, 84,101,
-120,116, 76,105,110,101, 0, 84,101,120,116, 77, 97,114,107,101,114, 0, 84,101,120,116, 0, 80, 97, 99,107,101,100, 70,105,108,
-101, 0, 67, 97,109,101,114, 97, 0, 73,109, 97,103,101, 85,115,101,114, 0, 83, 99,101,110,101, 0, 73,109, 97,103,101, 0, 71,
- 80, 85, 84,101,120,116,117,114,101, 0, 97,110,105,109, 0, 82,101,110,100,101,114, 82,101,115,117,108,116, 0, 77, 84,101,120,
- 0, 84,101,120, 0, 80,108,117,103,105,110, 84,101,120, 0, 67, 66, 68, 97,116, 97, 0, 67,111,108,111,114, 66, 97,110,100, 0,
- 69,110,118, 77, 97,112, 0, 73,109, 66,117,102, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97,112,112,105,110,
-103, 0, 76, 97,109,112, 0, 67,117,114,118,101, 77, 97,112,112,105,110,103, 0, 87, 97,118,101, 0, 77, 97,116,101,114,105, 97,
-108, 0, 71,114,111,117,112, 0, 86, 70,111,110,116, 0, 86, 70,111,110,116, 68, 97,116, 97, 0, 77,101,116, 97, 69,108,101,109,
- 0, 66,111,117,110,100, 66,111,120, 0, 77,101,116, 97, 66, 97,108,108, 0, 78,117,114, 98, 0, 67,104, 97,114, 73,110,102,111,
- 0, 84,101,120,116, 66,111,120, 0, 67,117,114,118,101, 0, 80, 97,116,104, 0, 83,101,108, 66,111,120, 0, 69,100,105,116, 70,
-111,110,116, 0, 77,101,115,104, 0, 77, 70, 97, 99,101, 0, 77, 84, 70, 97, 99,101, 0, 84, 70, 97, 99,101, 0, 77, 86,101,114,
-116, 0, 77, 69,100,103,101, 0, 77, 68,101,102,111,114,109, 86,101,114,116, 0, 77, 67,111,108, 0, 77, 83,116,105, 99,107,121,
- 0, 77, 83,101,108,101, 99,116, 0, 69,100,105,116, 77,101,115,104, 0, 67,117,115,116,111,109, 68, 97,116, 97, 0, 77,117,108,
-116,105,114,101,115, 0, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 0, 77, 68,101,102,111,114,109, 87,
-101,105,103,104,116, 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111,112, 67,111,108, 0,
- 77, 70,108,111, 97,116, 80,114,111,112,101,114,116,121, 0, 77, 73,110,116, 80,114,111,112,101,114,116,121, 0, 77, 83,116,114,
-105,110,103, 80,114,111,112,101,114,116,121, 0, 79,114,105,103, 83,112, 97, 99,101, 70, 97, 99,101, 0, 77, 68,105,115,112,115,
- 0, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 32, 40, 49, 60, 60, 49, 41, 32, 35,100,101,
-102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 32, 40, 49, 60, 60, 50, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70,
- 71, 79, 78, 32, 40, 49, 60, 60, 51, 41, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 82, 69, 78, 68, 69,
- 82, 32, 40, 49, 60, 60, 53, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, 71, 69, 32, 40, 49,
- 60, 60, 55, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 32, 40, 49, 60, 60, 56, 41,
- 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 32, 40, 49, 60, 60, 57, 41, 32, 32, 32, 35,100,101,102,105,
-110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 50,
- 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77,
- 69, 95, 70, 76, 73, 80, 86, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 89, 32, 49, 54, 32,
- 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 32, 51, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95,
- 80, 82, 79, 74, 89, 90, 32, 54, 52, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 32, 49, 32, 35,100,101,
-102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 49, 32, 52,
- 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 52,
- 86, 49, 32, 56, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 32, 49, 32, 35,100,101,102,105,110,
-101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 32, 50, 32, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 83, 69,
-108, 32, 48, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69,
- 95, 70, 83, 69, 76, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, 49, 32, 32, 35,100,
-101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69,
- 76, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84,
- 70, 95, 83, 69, 76, 51, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 32, 51, 50, 32, 35,100,101,
-102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 32, 54, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 89, 78,
- 65, 77, 73, 67, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, 32, 50, 32, 35,100,
-101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68,
- 86, 69, 82, 84, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 32, 49, 54, 32, 35,100,101,102,105,
-110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 73,
- 76, 69, 83, 32, 49, 50, 56, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 32, 50, 53,
- 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 32, 53, 49, 50, 32, 35,100,101,102,105,110,101,
- 32, 84, 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 32, 49, 48, 50, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66,
- 67, 79, 76, 32, 50, 48, 52, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 32, 52,
- 48, 57, 54, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 32, 56, 49, 57, 50, 32, 35,100,101,102,
-105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 32, 49, 54, 51, 56, 52, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95,
- 83, 79, 76, 73, 68, 32, 48, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 32, 49, 32, 35,100,101,102,105,110,101,
- 32, 84, 70, 95, 65, 76, 80, 72, 65, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80, 32, 52, 32, 32, 32,
- 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 32, 51, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80,
- 82, 69, 67, 65, 84, 69, 68, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68,
- 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 32, 52, 32, 35,100,101,
-102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70,
- 95, 80, 73, 78, 49, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 32, 51, 50, 32, 35,100,101,102,
-105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 52, 32, 49,
- 50, 56, 32, 35,101,110,100,105,102, 32, 32, 99,104, 97,114, 32,117,115,101, 95, 99,111,108, 44, 32,102,108, 97,103, 59, 10, 10,
- 9, 47, 42, 32, 83,112,101, 99,105, 97,108, 32,108,101,118,101,108, 32, 49, 32,100, 97,116, 97, 32,116,104, 97,116, 32, 99, 97,
-110,110,111,116, 32, 98,101, 32,109,111,100,105,102,105,101,100, 32,102,114,111,109, 32,111,116,104,101,114, 32,108,101,118,101,
-108,115, 32, 42, 47, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,118,100, 97,116, 97, 59, 10, 9, 67,117,115,116,111,109,
- 68, 97,116, 97, 32,102,100, 97,116, 97, 59, 10, 9,115,104,111,114,116, 32, 42,101,100,103,101, 95,102,108, 97,103,115, 59, 10,
- 9, 99,104, 97,114, 32, 42,101,100,103,101, 95, 99,114,101, 97,115,101,115, 59, 10,125, 32, 77,117,108,116,105,114,101,115, 59,
- 10, 10, 47, 42, 42, 32, 69,110,100, 32, 77,117,108,116,105,114,101,115, 32, 42, 42, 47, 10, 10,116,121,112,101,100,101,102, 32,
-115,116,114,117, 99,116, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 32,123, 10, 9,117,110,115,105,
-103,110,101,100, 32,105,110,116, 32, 42,118,101,114,116, 95,109, 97,112, 59, 32, 47, 42, 32,118,101,114,116, 95,109, 97,112, 91,
- 79,108,100, 32, 73,110,100,101,120, 93, 61, 32, 78,101,119, 32, 73,110,100,101,120, 32, 42, 47, 10, 9,105,110,116, 32, 42,101,
-100,103,101, 95,109, 97,112, 59, 32, 47, 42, 32,101,100,103,101, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61,
- 32, 78,101,119, 32, 73,110,100,101,120, 44, 32, 45, 49, 61, 32,104,105,100,100,101,110, 32, 42, 47, 10, 9, 77, 70, 97, 99,101,
- 32, 42,111,108,100, 95,102, 97, 99,101,115, 59, 10, 9, 77, 69,100,103,101, 32, 42,111,108,100, 95,101,100,103,101,115, 59, 10,
- 9,117,110,115,105,103,110,101,100, 32,105,110,116, 32,116,111,116,102, 97, 99,101, 44, 32,116,111,116,101,100,103,101, 44, 32,
-116,111,116,118,101,114,116, 44, 32,112, 97,100, 59, 10,125, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,
-121, 59, 10, 10, 47, 42, 32,109,118,101,114,116, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 32, 42, 47,
- 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 83, 84, 9, 50, 10, 35,100,101,102,105,110,101,
- 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 77, 80, 9, 52, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 72, 73, 68, 69,
- 9, 9, 9, 49, 54, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 69, 82, 84, 95, 77, 69, 82, 71, 69, 68, 9, 9, 40, 49,
- 60, 60, 54, 41, 10, 10, 47, 42, 32,109,101,100,103,101, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 42,
- 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 9, 9, 9, 40, 49, 60, 60, 49, 41, 10, 35,
-100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 9, 9, 9, 9, 40, 49, 60, 60, 50, 41, 10, 35,100,101,102,105,110,101,
- 32, 77, 69, 95, 70, 71, 79, 78, 9, 9, 9, 9, 40, 49, 60, 60, 51, 41, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,114,101,115,101,
-114,118,101, 32, 49, 54, 32,102,111,114, 32, 77, 69, 95, 72, 73, 68, 69, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 77, 69,
- 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 9, 9, 40, 49, 60, 60, 53, 41, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76,
- 79, 79, 83, 69, 69, 68, 71, 69, 9, 9, 40, 49, 60, 60, 55, 41, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77,
- 95, 76, 65, 83, 84, 9, 9, 40, 49, 60, 60, 56, 41, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 9, 9,
- 9, 40, 49, 60, 60, 57, 41, 10, 10, 47, 42, 32,112,117,110,111, 32, 61, 32,118,101,114,116,101,120,110,111,114,109, 97,108, 32,
- 40,109,102, 97, 99,101, 41, 32, 42, 47, 10, 47, 42, 32,114,101,110,100,101,114, 32, 97,115,115,117,109,101,115, 32,102,108,105,
-112,115, 32,116,111, 32, 98,101, 32,111,114,100,101,114,101,100, 32,108,105,107,101, 32,116,104,105,115, 32, 42, 47, 10, 35,100,
-101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 9, 9, 49, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76,
- 73, 80, 86, 50, 9, 9, 50, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 9, 9, 52, 10, 35,100,101,
-102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 9, 9, 56, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79,
- 74, 88, 89, 9, 9, 49, 54, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 9, 9, 51, 50, 10, 35,100,
-101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 89, 90, 9, 9, 54, 52, 10, 10, 47, 42, 32,101,100, 99,111,100,101, 32, 40,
-109,102, 97, 99,101, 41, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 9, 9, 9, 49, 10, 35,100,
-101,102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 9, 9, 9, 50, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86,
- 49, 9, 9, 9, 52, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 9, 9, 9, 52, 10, 35,100,101,102,105,110,
-101, 32, 77, 69, 95, 86, 52, 86, 49, 9, 9, 9, 56, 10, 10, 47, 42, 32,102,108, 97,103, 32, 40,109,102, 97, 99,101, 41, 32, 42,
- 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 9, 9, 9, 49, 10, 35,100,101,102,105,110,101, 32,
- 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 9, 9, 9, 50, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,102,108, 97,103, 32, 77, 69,
- 95, 72, 73, 68, 69, 61, 61, 49, 54, 32,105,115, 32,117,115,101,100, 32,104,101,114,101, 32,116,111,111, 32, 42, 47, 32, 10, 47,
- 42, 32,109,115,101,108,101, 99,116, 45, 62,116,121,112,101, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 83,
- 69,108, 9, 48, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 10, 35,100,101,102,105,110,101, 32, 77,
- 69, 95, 70, 83, 69, 76, 32, 50, 10, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,102,108, 97,103, 32, 42, 47, 10, 35,100,101,
-102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 9, 49, 32, 47, 42, 32,117,115,101, 32, 77, 70, 97, 99,101, 32,104,105,
-100,101, 32,102,108, 97,103, 32, 40, 97,102,116,101,114, 32, 50, 46, 52, 51, 41, 44, 32,115,104,111,117,108,100, 32, 98,101, 32,
- 97, 98,108,101, 32,116,111, 32,114,101,117,115,101, 32, 97,102,116,101,114, 32, 50, 46, 52, 52, 32, 42, 47, 10, 35,100,101,102,
-105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 9, 50, 32, 47, 42, 32,100,101,112,114,101, 99, 97,116,101,100, 33, 32, 42,
- 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 9, 9, 52, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95,
- 83, 69, 76, 50, 9, 9, 56, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 51, 9, 9, 49, 54, 10, 35,100,101,102,
-105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 9, 9, 51, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 9,
- 9, 54, 52, 32, 47, 42, 32,117,110,117,115,101,100, 44, 32,115, 97,109,101, 32, 97,115, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84,
- 32, 42, 47, 10, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,109,111,100,101, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32,
- 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 9, 9, 49, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79,
- 82, 84, 9, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 9, 9, 9, 52, 10, 35,100,101,102,105,110,101, 32,
- 84, 70, 95, 83, 72, 65, 82, 69, 68, 86, 69, 82, 84, 9, 56, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84,
- 9, 9, 49, 54, 10, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 9, 54, 52, 10, 35,100,
-101,102,105,110,101, 32, 84, 70, 95, 84, 73, 76, 69, 83, 9, 9, 49, 50, 56, 9, 9, 47, 42, 32,100,101,112,114,101, 99, 97,116,
-101,100, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 9, 50, 53, 54, 10, 35,
-100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 9, 9, 53, 49, 50, 10, 35,100,101,102,105,110,101, 32, 84,
- 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 9, 49, 48, 50, 52, 10, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, 67,
- 79, 76, 9, 9, 50, 48, 52, 56, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 9, 52,
- 48, 57, 54, 9, 47, 42, 32,119,105,116,104, 32, 90, 32, 97,120,105,115, 32, 99,111,110,115,116,114, 97,105,110,116, 32, 42, 47,
- 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 9, 9, 56, 49, 57, 50, 10, 35,100,101,102,105,110,101,
- 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 9, 9, 49, 54, 51, 56, 52, 10, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,116,114,
- 97,110,115,112, 44, 32,118, 97,108,117,101,115, 32, 49, 45, 52, 32, 97,114,101, 32,117,115,101,100, 32, 97,115, 32,102,108, 97,
-103,115, 32,105,110, 32,116,104,101, 32, 71, 76, 44, 32, 87, 65, 82, 78, 73, 78, 71, 44, 32, 84, 70, 95, 83, 85, 66, 32, 99, 97,
-110,116, 32,119,111,114,107, 32,119,105,116,104, 32,116,104,105,115, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95,
- 83, 79, 76, 73, 68, 9, 48, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 9, 9, 49, 10, 35,100,101,102,105,110,
-101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 9, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80, 9, 9, 52, 32,
- 47, 42, 32, 99,108,105,112,109, 97,112, 32, 97,108,112,104, 97, 47, 98,105,110, 97,114,121, 32, 97,108,112,104, 97, 32, 97,108,
-108, 32,111,114, 32,110,111,116,104,105,110,103, 33, 32, 42, 47, 10, 10, 47, 42, 32,115,117, 98, 32,105,115, 32,110,111,116, 32,
- 97,118, 97,105,108, 97, 98,108,101, 32,105,110, 32,116,104,101, 32,117,115,101,114, 32,105,110,116,101,114,102, 97, 99,101, 32,
- 97,110,121,109,111,114,101, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 9, 9, 51, 10, 10, 10, 47,
- 42, 32,109,116,102, 97, 99,101, 45, 62,117,110,119,114, 97,112, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68,
- 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 9, 49, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84,
- 69, 68, 50, 9, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 9, 52, 10, 35,
-100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 9, 56, 10, 35,100,101,102,105,110,101, 32,
- 84, 70, 95, 80, 73, 78, 49, 9, 9, 32, 32, 32, 32, 49, 54, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 9,
- 9, 32, 32, 32, 32, 51, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 9, 32, 32, 32, 9, 9, 54, 52, 10,
- 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 52, 9, 32, 32, 32, 32, 9, 49, 50, 56, 10, 10, 35,101,110,100,105,102,
- 10,105,110, 79, 67, 75, 33,116, 95,102, 97, 99,101, 59, 32, 32, 32, 32, 32,129, 71, 0, 77,117,108,116,105,114,101,115, 67,111,
-108, 0, 77,117,108,116,105,114,101,115, 67,111,108, 70, 97, 99,101, 0, 77,117,108,116,105,114,101,115, 70, 97, 99,101, 0, 77,
-117,108,116,105,114,101,115, 69,100,103,101, 0, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 0, 77,111,100,105,102,105,
-101,114, 68, 97,116, 97, 0, 83,117, 98,115,117,114,102, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 76, 97,116,116,105,
- 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,117,114,118,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97,
- 0, 66,117,105,108,100, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77, 97,115,107, 77,111,100,105,102,105,101,114, 68,
- 97,116, 97, 0, 65,114,114, 97,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,105,114,114,111,114, 77,111,100,105,
-102,105,101,114, 68, 97,116, 97, 0, 69,100,103,101, 83,112,108,105,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66,
-101,118,101,108, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66, 77,101,115,104, 77,111,100,105,102,105,101,114, 68, 97,
-116, 97, 0, 68,105,115,112,108, 97, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 85, 86, 80,114,111,106,101, 99,
+108, 97,103, 0,118,101,108, 91, 51, 93, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 0, 42,103,114,111,117,110,100,
+ 0,103,114, 97,118,105,116,121, 91, 51, 93, 0,119, 97,110,100,101,114, 91, 51, 93, 0,110,117,109, 0,112, 97,114,101,110,116,
+ 0,112, 97, 91, 52, 93, 0,119, 91, 52, 93, 0,102,117,118, 91, 52, 93, 0,102,111,102,102,115,101,116, 0,114, 97,110,100, 91,
+ 51, 93, 0,112,114,101,118, 95,115,116, 97,116,101, 0, 42,104, 97,105,114, 0, 42, 98,111,105,100, 0,100,105,101,116,105,109,
+101, 0,110,117,109, 95,100,109, 99, 97, 99,104,101, 0, 97,108,105,118,101, 0,108,111,111,112, 0,104, 97,105,114, 95,105,110,
+100,101,120, 0, 42, 98,111,105,100,115, 0,100,105,115,116,114, 0,112,104,121,115,116,121,112,101, 0, 97,118,101,109,111,100,
+101, 0,114,101, 97, 99,116,101,118,101,110,116, 0,100,114, 97,119, 0,100,114, 97,119, 95, 97,115, 0,100,114, 97,119, 95,115,
+105,122,101, 0, 99,104,105,108,100,116,121,112,101, 0,114,101,110, 95, 97,115, 0,114,101,110, 95,115,116,101,112, 0,104, 97,
+105,114, 95,115,116,101,112, 0,107,101,121,115, 95,115,116,101,112, 0, 97,100, 97,112,116, 95, 97,110,103,108,101, 0, 97,100,
+ 97,112,116, 95,112,105,120, 0,114,111,116,102,114,111,109, 0,105,110,116,101,103,114, 97,116,111,114, 0, 98, 98, 95, 97,108,
+105,103,110, 0, 98, 98, 95,117,118, 95,115,112,108,105,116, 0, 98, 98, 95, 97,110,105,109, 0, 98, 98, 95,115,112,108,105,116,
+ 95,111,102,102,115,101,116, 0, 98, 98, 95,116,105,108,116, 0, 98, 98, 95,114, 97,110,100, 95,116,105,108,116, 0, 98, 98, 95,
+111,102,102,115,101,116, 91, 50, 93, 0,115,105,109,112,108,105,102,121, 95,102,108, 97,103, 0,115,105,109,112,108,105,102,121,
+ 95,114,101,102,115,105,122,101, 0,115,105,109,112,108,105,102,121, 95,114, 97,116,101, 0,115,105,109,112,108,105,102,121, 95,
+116,114, 97,110,115,105,116,105,111,110, 0,115,105,109,112,108,105,102,121, 95,118,105,101,119,112,111,114,116, 0,116,105,109,
+101,116,119,101, 97,107, 0,106,105,116,102, 97, 99, 0,101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114,101,115, 0,
+112, 97,114,116,102, 97, 99, 0,116, 97,110,102, 97, 99, 0,116, 97,110,112,104, 97,115,101, 0,114,101, 97, 99,116,102, 97, 99,
+ 0, 97,118,101,102, 97, 99, 0,112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100,114,111,116,102, 97, 99, 0,114, 97,110,100,
+112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100,115,105,122,101, 0,114,101, 97, 99,116,115,104, 97,112,101, 0, 97, 99, 99,
+ 91, 51, 93, 0,100,114, 97,103,102, 97, 99, 0, 98,114,111,119,110,102, 97, 99, 0,100, 97,109,112,102, 97, 99, 0,114, 97,110,
+100,108,101,110,103,116,104, 0, 99,104,105,108,100, 95,110, 98,114, 0,114,101,110, 95, 99,104,105,108,100, 95,110, 98,114, 0,
+112, 97,114,101,110,116,115, 0, 99,104,105,108,100,115,105,122,101, 0, 99,104,105,108,100,114, 97,110,100,115,105,122,101, 0,
+ 99,104,105,108,100,114, 97,100, 0, 99,104,105,108,100,102,108, 97,116, 0, 99,108,117,109,112,102, 97, 99, 0, 99,108,117,109,
+112,112,111,119, 0,114,111,117,103,104, 49, 0,114,111,117,103,104, 49, 95,115,105,122,101, 0,114,111,117,103,104, 50, 0,114,
+111,117,103,104, 50, 95,115,105,122,101, 0,114,111,117,103,104, 50, 95,116,104,114,101,115, 0,114,111,117,103,104, 95,101,110,
+100, 0,114,111,117,103,104, 95,101,110,100, 95,115,104, 97,112,101, 0, 99,108,101,110,103,116,104, 0, 99,108,101,110,103,116,
+104, 95,116,104,114,101,115, 0, 98,114, 97,110, 99,104, 95,116,104,114,101,115, 0,100,114, 97,119, 95,108,105,110,101, 91, 50,
+ 93, 0,112, 97,116,104, 95,115,116, 97,114,116, 0,112, 97,116,104, 95,101,110,100, 0,116,114, 97,105,108, 95, 99,111,117,110,
+116, 0,107,101,121,101,100, 95,108,111,111,112,115, 0,101,102,102,101, 99,116,111,114, 95,119,101,105,103,104,116, 91, 49, 48,
+ 93, 0, 42,101,102,102, 95,103,114,111,117,112, 0, 42,100,117,112, 95,111, 98, 0, 42, 98, 98, 95,111, 98, 0, 42,112,100, 50,
+ 0, 42,112, 97,114,116, 0, 42,112, 97,114,116,105, 99,108,101,115, 0, 42, 42,112, 97,116,104, 99, 97, 99,104,101, 0, 42, 42,
+ 99,104,105,108,100, 99, 97, 99,104,101, 0,112, 97,116,104, 99, 97, 99,104,101, 98,117,102,115, 0, 99,104,105,108,100, 99, 97,
+ 99,104,101, 98,117,102,115, 0, 42, 99,108,109,100, 0, 42,104, 97,105,114, 95,105,110, 95,100,109, 0, 42,104, 97,105,114, 95,
+111,117,116, 95,100,109, 0, 42,116, 97,114,103,101,116, 95,111, 98, 0, 42,108, 97,116,116,105, 99,101, 0,101,102,102,101, 99,
+116,111,114,115, 0,114,101, 97, 99,116,101,118,101,110,116,115, 0,116,114,101,101, 95,102,114, 97,109,101, 0,116,111,116, 99,
+104,105,108,100, 0,116,111,116, 99, 97, 99,104,101,100, 0,116,111,116, 99,104,105,108,100, 99, 97, 99,104,101, 0,116, 97,114,
+103,101,116, 95,112,115,121,115, 0,116,111,116,107,101,121,101,100, 0, 98, 97,107,101,115,112, 97, 99,101, 0, 98, 98, 95,117,
+118,110, 97,109,101, 91, 51, 93, 91, 51, 50, 93, 0,118,103,114,111,117,112, 91, 49, 50, 93, 0,118,103, 95,110,101,103, 0,114,
+116, 51, 0, 42,114,101,110,100,101,114,100, 97,116, 97, 0, 42,116,114,101,101, 0, 67,100,105,115, 0, 67,118,105, 0, 91, 51,
+ 93, 0,115,116,114,117, 99,116,117,114, 97,108, 0, 98,101,110,100,105,110,103, 0,109, 97,120, 95, 98,101,110,100, 0,109, 97,
+120, 95,115,116,114,117, 99,116, 0,109, 97,120, 95,115,104,101, 97,114, 0, 97,118,103, 95,115,112,114,105,110,103, 95,108,101,
+110, 0,116,105,109,101,115, 99, 97,108,101, 0,101,102,102, 95,102,111,114, 99,101, 95,115, 99, 97,108,101, 0,101,102,102, 95,
+119,105,110,100, 95,115, 99, 97,108,101, 0,115,105,109, 95,116,105,109,101, 95,111,108,100, 0,118,101,108,111, 99,105,116,121,
+ 95,115,109,111,111,116,104, 0,115,116,101,112,115, 80,101,114, 70,114, 97,109,101, 0,112,114,101,114,111,108,108, 0,109, 97,
+120,115,112,114,105,110,103,108,101,110, 0,115,111,108,118,101,114, 95,116,121,112,101, 0,118,103,114,111,117,112, 95, 98,101,
+110,100, 0,118,103,114,111,117,112, 95,109, 97,115,115, 0,118,103,114,111,117,112, 95,115,116,114,117, 99,116, 0,112,114,101,
+115,101,116,115, 0, 42, 99,111,108,108,105,115,105,111,110, 95,108,105,115,116, 0,101,112,115,105,108,111,110, 0,115,101,108,
+102, 95,102,114,105, 99,116,105,111,110, 0,115,101,108,102,101,112,115,105,108,111,110, 0,115,101,108,102, 95,108,111,111,112,
+ 95, 99,111,117,110,116, 0,108,111,111,112, 95, 99,111,117,110,116, 0,112,114,101,115,115,117,114,101, 0,116,104,105, 99,107,
+110,101,115,115, 0,115,116,114,111,107,101,115, 0,102,114, 97,109,101,110,117,109, 0, 42, 97, 99,116,102,114, 97,109,101, 0,
+103,115,116,101,112, 0,105,110,102,111, 91, 49, 50, 56, 93, 0,115, 98,117,102,102,101,114, 95,115,105,122,101, 0,115, 98,117,
+102,102,101,114, 95,115,102,108, 97,103, 0, 42,115, 98,117,102,102,101,114, 0, 42,116,121,112,101,115,116,114, 0, 42,109,101,
+115,115, 97,103,101, 0,108,105,115,116, 0,112,114,105,110,116,108,101,118,101,108, 0,115,116,111,114,101,108,101,118,101,108,
+ 0, 42,119,105,110,100,114, 97,119, 97, 98,108,101, 0, 42,119,105,110, 97, 99,116,105,118,101, 0,119,105,110,100,111,119,115,
+ 0,105,110,105,116,105, 97,108,105,122,101,100, 0,102,105,108,101, 95,115, 97,118,101,100, 0,111,112,101,114, 97,116,111,114,
+115, 0,113,117,101,117,101, 0,114,101,112,111,114,116,115, 0,106,111, 98,115, 0,112, 97,105,110,116, 99,117,114,115,111,114,
+115, 0,107,101,121,109, 97,112,115, 0, 42,103,104,111,115,116,119,105,110, 0, 42,110,101,119,115, 99,114,101,101,110, 0,115,
+ 99,114,101,101,110,110, 97,109,101, 91, 51, 50, 93, 0,112,111,115,120, 0,112,111,115,121, 0,119,105,110,100,111,119,115,116,
+ 97,116,101, 0,109,111,110,105,116,111,114, 0,108, 97,115,116, 99,117,114,115,111,114, 0, 97,100,100,109,111,117,115,101,109,
+111,118,101, 0, 42,101,118,101,110,116,115,116, 97,116,101, 0, 42, 99,117,114,115,119,105,110, 0, 42,116,119,101, 97,107, 0,
+100,114, 97,119,109,101,116,104,111,100, 0,100,114, 97,119,102, 97,105,108, 0, 42,100,114, 97,119,100, 97,116, 97, 0,116,105,
+109,101,114,115, 0,115,117, 98,119,105,110,100,111,119,115, 0,103,101,115,116,117,114,101, 0,105,100,110, 97,109,101, 91, 54,
+ 52, 93, 0, 42,112,116,114, 0,115,104,105,102,116, 0, 99,116,114,108, 0, 97,108,116, 0,111,115,107,101,121, 0,107,101,121,
+109,111,100,105,102,105,101,114, 0,112,114,111,112,118, 97,108,117,101, 0,105,110, 97, 99,116,105,118,101, 0,109, 97,112,116,
+121,112,101, 0,107,101,121,109, 97,112, 0,110, 97,109,101,105,100, 91, 54, 52, 93, 0,115,112, 97, 99,101,105,100, 0,114,101,
+103,105,111,110,105,100, 0,105,115, 95,109,111,100, 97,108, 0, 42,105,116,101,109,115, 0, 42, 99,117,115,116,111,109,100, 97,
+116, 97, 0, 42,114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0,109,118, 97,108, 91, 50, 93, 0,112,
+114,101,118,120, 0,112,114,101,118,121, 0,117,110,105, 99,111,100,101, 0, 97,115, 99,105,105, 0, 42,107,101,121,109, 97,112,
+ 95,105,100,110, 97,109,101, 0, 99,117,115,116,111,109, 0, 99,117,115,116,111,109,100, 97,116, 97,102,114,101,101, 0, 42,101,
+100, 97,116, 97, 0,105,110,102,108,117,101,110, 99,101, 0, 42, 99,111,101,102,102,105, 99,105,101,110,116,115, 0, 97,114,114,
+ 97,121,115,105,122,101, 0,112,111,108,121, 95,111,114,100,101,114, 0, 97,109,112,108,105,116,117,100,101, 0,112,104, 97,115,
+101, 95,109,117,108,116,105,112,108,105,101,114, 0,112,104, 97,115,101, 95,111,102,102,115,101,116, 0,118, 97,108,117,101, 95,
+111,102,102,115,101,116, 0,109,105,100,118, 97,108, 0, 98,101,102,111,114,101, 95,109,111,100,101, 0, 97,102,116,101,114, 95,
+109,111,100,101, 0, 98,101,102,111,114,101, 95, 99,121, 99,108,101,115, 0, 97,102,116,101,114, 95, 99,121, 99,108,101,115, 0,
+114,101, 99,116, 0,112,104, 97,115,101, 0,109,111,100,105,102,105, 99, 97,116,105,111,110, 0, 42,114,110, 97, 95,112, 97,116,
+104, 0, 97,114,114, 97,121, 95,105,110,100,101,120, 0,101,120,112,114,101,115,115,105,111,110, 91, 50, 53, 54, 93, 0,118,101,
+ 99, 91, 50, 93, 0, 42,102,112,116, 0, 99,111,108,111,114, 95,109,111,100,101, 0, 99,111,108,111,114, 91, 51, 93, 0,102,114,
+111,109, 91, 49, 50, 56, 93, 0,116,111, 91, 49, 50, 56, 93, 0,109, 97,112,112,105,110,103,115, 0,115,116,114,105,112,115, 0,
+ 42,114,101,109, 97,112, 0,102, 99,117,114,118,101,115, 0,115,116,114,105,112, 95,116,105,109,101, 0, 98,108,101,110,100,109,
+111,100,101, 0,101,120,116,101,110,100,109,111,100,101, 0,103,114,111,117,112, 91, 54, 52, 93, 0,105,100,116,121,112,101, 0,
+116,101,109,112,108, 97,116,101,115, 0,103,114,111,117,112,109,111,100,101, 0,112, 97,116,104,115, 0,107,101,121,105,110,103,
+102,108, 97,103, 0, 42,116,109,112, 97, 99,116, 0,110,108, 97, 95,116,114, 97, 99,107,115, 0, 42, 97, 99,116,115,116,114,105,
+112, 0,100,114,105,118,101,114,115, 0,111,118,101,114,114,105,100,101,115, 0, 97, 99,116, 95, 98,108,101,110,100,109,111,100,
+101, 0, 97, 99,116, 95,101,120,116,101,110,100,109,111,100,101, 0, 97, 99,116, 95,105,110,102,108,117,101,110, 99,101, 0,114,
+117,108,101, 0,111,112,116,105,111,110,115, 0,102,101, 97,114, 95,102, 97, 99,116,111,114, 0,115,105,103,110, 97,108, 95,105,
+100, 0,108,111,111,107, 95, 97,104,101, 97,100, 0,111,108,111, 99, 91, 51, 93, 0,113,117,101,117,101, 95,115,105,122,101, 0,
+119, 97,110,100,101,114, 0,102,108,101,101, 95,100,105,115,116, 97,110, 99,101, 0,104,101, 97,108,116,104, 0,115,116, 97,116,
+101, 95,105,100, 0,114,117,108,101,115, 0, 99,111,110,100,105,116,105,111,110,115, 0, 97, 99,116,105,111,110,115, 0,114,117,
+108,101,115,101,116, 95,116,121,112,101, 0,114,117,108,101, 95,102,117,122,122,105,110,101,115,115, 0,108, 97,115,116, 95,115,
+116, 97,116,101, 95,105,100, 0,108, 97,110,100,105,110,103, 95,115,109,111,111,116,104,110,101,115,115, 0, 98, 97,110,107,105,
+110,103, 0, 97,103,103,114,101,115,115,105,111,110, 0, 97, 99, 99,117,114, 97, 99,121, 0, 97,105,114, 95,109,105,110, 95,115,
+112,101,101,100, 0, 97,105,114, 95,109, 97,120, 95,115,112,101,101,100, 0, 97,105,114, 95,109, 97,120, 95, 97, 99, 99, 0, 97,
+105,114, 95,109, 97,120, 95, 97,118,101, 0, 97,105,114, 95,112,101,114,115,111,110, 97,108, 95,115,112, 97, 99,101, 0,108, 97,
+110,100, 95,106,117,109,112, 95,115,112,101,101,100, 0,108, 97,110,100, 95,109, 97,120, 95,115,112,101,101,100, 0,108, 97,110,
+100, 95,109, 97,120, 95, 97, 99, 99, 0,108, 97,110,100, 95,109, 97,120, 95, 97,118,101, 0,108, 97,110,100, 95,112,101,114,115,
+111,110, 97,108, 95,115,112, 97, 99,101, 0,108, 97,110,100, 95,115,116,105, 99,107, 95,102,111,114, 99,101, 0,115,116, 97,116,
+101,115, 0, 42,115,109,100, 0, 42,102,108,117,105,100, 0, 42,102,108,117,105,100, 95,103,114,111,117,112, 0, 42, 99,111,108,
+108, 95,103,114,111,117,112, 0, 42,119,116, 0, 42,116,101,120, 95,119,116, 0, 42,116,101,120, 95,115,104, 97,100,111,119, 0,
+ 42,115,104, 97,100,111,119, 0,112, 48, 91, 51, 93, 0,112, 49, 91, 51, 93, 0,100,120, 0,111,109,101,103, 97, 0,116,101,109,
+112, 65,109, 98, 0, 98,101,116, 97, 0,114,101,115, 91, 51, 93, 0, 97,109,112,108,105,102,121, 0,109, 97,120,114,101,115, 0,
+118,105,101,119,115,101,116,116,105,110,103,115, 0,110,111,105,115,101, 0,100,105,115,115, 95,112,101,114, 99,101,110,116, 0,
+100,105,115,115, 95,115,112,101,101,100, 0,114,101,115, 95,119,116, 91, 51, 93, 0,100,120, 95,119,116, 0,118, 51,100,110,117,
+109, 0, 42,112,111,105,110,116, 95, 99, 97, 99,104,101, 91, 50, 93, 0,112,116, 99, 97, 99,104,101,115, 91, 50, 93, 0,118,101,
+108,111, 99,105,116,121, 91, 51, 93, 0,118,103,114,112, 95,104,101, 97,116, 95,115, 99, 97,108,101, 91, 50, 93, 0,118,103,114,
+111,117,112, 95,102,108,111,119, 0,118,103,114,111,117,112, 95,100,101,110,115,105,116,121, 0,118,103,114,111,117,112, 95,104,
+101, 97,116, 0, 42,112,111,105,110,116,115, 95,111,108,100, 0, 42,118,101,108, 0,109, 97,116, 95,111,108,100, 91, 52, 93, 91,
+ 52, 93, 0,110,117,109,112,111,105,110,116,115, 0, 0, 0, 0, 84, 89, 80, 69,182, 1, 0, 0, 99,104, 97,114, 0,117, 99,104,
+ 97,114, 0,115,104,111,114,116, 0,117,115,104,111,114,116, 0,105,110,116, 0,108,111,110,103, 0,117,108,111,110,103, 0,102,
+108,111, 97,116, 0,100,111,117, 98,108,101, 0,118,111,105,100, 0, 76,105,110,107, 0, 76,105,110,107, 68, 97,116, 97, 0, 76,
+105,115,116, 66, 97,115,101, 0,118,101, 99, 50,115, 0,118,101, 99, 50,105, 0,118,101, 99, 50,102, 0,118,101, 99, 50,100, 0,
+118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51,100, 0,118,101, 99, 52,105, 0,118,101, 99, 52,102, 0,118,101,
+ 99, 52,100, 0,114, 99,116,105, 0,114, 99,116,102, 0, 73, 68, 80,114,111,112,101,114,116,121, 68, 97,116, 97, 0, 73, 68, 80,
+114,111,112,101,114,116,121, 0, 73, 68, 0, 76,105, 98,114, 97,114,121, 0, 70,105,108,101, 68, 97,116, 97, 0, 80,114,101,118,
+105,101,119, 73,109, 97,103,101, 0, 73,112,111, 68,114,105,118,101,114, 0, 79, 98,106,101, 99,116, 0, 73,112,111, 67,117,114,
+118,101, 0, 66, 80,111,105,110,116, 0, 66,101,122, 84,114,105,112,108,101, 0, 73,112,111, 0, 75,101,121, 66,108,111, 99,107,
+ 0, 75,101,121, 0, 65,110,105,109, 68, 97,116, 97, 0, 84,101,120,116, 76,105,110,101, 0, 84,101,120,116, 77, 97,114,107,101,
+114, 0, 84,101,120,116, 0, 80, 97, 99,107,101,100, 70,105,108,101, 0, 67, 97,109,101,114, 97, 0, 73,109, 97,103,101, 85,115,
+101,114, 0, 83, 99,101,110,101, 0, 73,109, 97,103,101, 0, 71, 80, 85, 84,101,120,116,117,114,101, 0, 97,110,105,109, 0, 82,
+101,110,100,101,114, 82,101,115,117,108,116, 0, 77, 84,101,120, 0, 84,101,120, 0, 80,108,117,103,105,110, 84,101,120, 0, 67,
+ 66, 68, 97,116, 97, 0, 67,111,108,111,114, 66, 97,110,100, 0, 69,110,118, 77, 97,112, 0, 73,109, 66,117,102, 0, 80,111,105,
+110,116, 68,101,110,115,105,116,121, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, 86,111,120,101,108, 68, 97,
+116, 97, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97,112,112,105,110,103, 0, 76, 97,109,112, 0, 67,117,114,
+118,101, 77, 97,112,112,105,110,103, 0, 87, 97,118,101, 0, 86,111,108,117,109,101, 83,101,116,116,105,110,103,115, 0, 77, 97,
+116,101,114,105, 97,108, 0, 71,114,111,117,112, 0, 86, 70,111,110,116, 0, 86, 70,111,110,116, 68, 97,116, 97, 0, 77,101,116,
+ 97, 69,108,101,109, 0, 66,111,117,110,100, 66,111,120, 0, 77,101,116, 97, 66, 97,108,108, 0, 78,117,114, 98, 0, 67,104, 97,
+114, 73,110,102,111, 0, 84,101,120,116, 66,111,120, 0, 67,117,114,118,101, 0, 80, 97,116,104, 0, 83,101,108, 66,111,120, 0,
+ 69,100,105,116, 70,111,110,116, 0, 77,101,115,104, 0, 77, 70, 97, 99,101, 0, 77, 84, 70, 97, 99,101, 0, 84, 70, 97, 99,101,
+ 0, 77, 86,101,114,116, 0, 77, 69,100,103,101, 0, 77, 68,101,102,111,114,109, 86,101,114,116, 0, 77, 67,111,108, 0, 77, 83,
+116,105, 99,107,121, 0, 77, 83,101,108,101, 99,116, 0, 69,100,105,116, 77,101,115,104, 0, 67,117,115,116,111,109, 68, 97,116,
+ 97, 0, 77,117,108,116,105,114,101,115, 0, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 0, 77, 68,101,
+102,111,114,109, 87,101,105,103,104,116, 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111,
+112, 67,111,108, 0, 77, 70,108,111, 97,116, 80,114,111,112,101,114,116,121, 0, 77, 73,110,116, 80,114,111,112,101,114,116,121,
+ 0, 77, 83,116,114,105,110,103, 80,114,111,112,101,114,116,121, 0, 79,114,105,103, 83,112, 97, 99,101, 70, 97, 99,101, 0, 77,
+ 68,105,115,112,115, 0, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 32, 40, 49, 60, 60, 49,
+ 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 32, 40, 49, 60, 60, 50, 41, 32, 35,100,101,102,105,110,101,
+ 32, 77, 69, 95, 70, 71, 79, 78, 32, 40, 49, 60, 60, 51, 41, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69,
+ 82, 69, 78, 68, 69, 82, 32, 40, 49, 60, 60, 53, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68,
+ 71, 69, 32, 40, 49, 60, 60, 55, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 32, 40,
+ 49, 60, 60, 56, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 32, 40, 49, 60, 60, 57, 41, 32, 32, 32,
+ 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70,
+ 76, 73, 80, 86, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 32, 52, 32, 35,100,101,102,
+105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88,
+ 89, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 32, 51, 50, 32, 35,100,101,102,105,110,
+101, 32, 77, 69, 95, 80, 82, 79, 74, 89, 90, 32, 54, 52, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 32,
+ 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86,
+ 51, 86, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 32, 52, 32, 35,100,101,102,105,110,101, 32,
+ 77, 69, 95, 86, 52, 86, 49, 32, 56, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 32, 49, 32, 35,
+100,101,102,105,110,101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 32, 50, 32, 32, 32, 35,100,101,102,105,110,101, 32, 77,
+ 69, 95, 86, 83, 69,108, 32, 48, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 32, 35,100,101,102,105,
+110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32,
+ 49, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32,
+ 84, 70, 95, 83, 69, 76, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 32, 56, 32, 35,100,101,102,
+105,110,101, 32, 84, 70, 95, 83, 69, 76, 51, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 32, 51,
+ 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 32, 54, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84,
+ 70, 95, 68, 89, 78, 65, 77, 73, 67, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84,
+ 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83,
+ 72, 65, 82, 69, 68, 86, 69, 82, 84, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 32, 49, 54, 32,
+ 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32,
+ 84, 70, 95, 84, 73, 76, 69, 83, 32, 49, 50, 56, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65,
+ 82, 68, 32, 50, 53, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 32, 53, 49, 50, 32, 35,100,
+101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 32, 49, 48, 50, 52, 32, 35,100,101,102,105,110,101, 32,
+ 84, 70, 95, 79, 66, 67, 79, 76, 32, 50, 48, 52, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65,
+ 82, 68, 50, 32, 52, 48, 57, 54, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 32, 56, 49, 57, 50,
+ 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 32, 49, 54, 51, 56, 52, 32, 32, 35,100,101,102,105,110,
+101, 32, 84, 70, 95, 83, 79, 76, 73, 68, 32, 48, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 32, 49, 32, 35,100,
+101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80,
+ 32, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 32, 51, 32, 32, 35,100,101,102,105,110,101, 32, 84,
+ 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69,
+ 67, 65, 84, 69, 68, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 32,
+ 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 32, 56, 32, 35,100,101,102,105,
+110,101, 32, 84, 70, 95, 80, 73, 78, 49, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 32, 51, 50,
+ 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80,
+ 73, 78, 52, 32, 49, 50, 56, 32, 35,101,110,100,105,102, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 59, 13, 10, 13, 10,
+116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 77,117,108,116,105,114,101,115, 32,123, 13, 10, 9, 76,105,115,116,
+ 66, 97,115,101, 32,108,101,118,101,108,115, 59, 13, 10, 9, 77, 86,101,114,116, 32, 42,118,101,114,116,115, 59, 13, 10, 13, 10,
+ 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,108,101,118,101,108, 95, 99,111,117,110,116, 44, 32, 99,117,114,114,
+101,110,116, 44, 32,110,101,119,108,118,108, 44, 32,101,100,103,101,108,118,108, 44, 32,112,105,110,108,118,108, 44, 32,114,101,
+110,100,101,114,108,118,108, 59, 13, 10, 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,117,115,101, 95, 99,111,108,
+ 44, 32,102,108, 97,103, 59, 13, 10, 13, 10, 9, 47, 42, 32, 83,112,101, 99,105, 97,108, 32,108,101,118,101,108, 32, 49, 32,100,
+ 97,116, 97, 32,116,104, 97,116, 32, 99, 97,110,110,111,116, 32, 98,101, 32,109,111,100,105,102,105,101,100, 32,102,114,111,109,
+ 32,111,116,104,101,114, 32,108,101,118,101,108,115, 32, 42, 47, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,118,100,
+ 97,116, 97, 59, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,102,100, 97,116, 97, 59, 13, 10, 9,115,104,111,114,116,
+ 32, 42,101,100,103,101, 95,102,108, 97,103,115, 59, 13, 10, 9, 99,104, 97,114, 32, 42,101,100,103,101, 95, 99,114,101, 97,115,
+101,115, 59, 13, 10,125, 32, 77,117,108,116,105,114,101,115, 59, 13, 10, 13, 10, 47, 42, 42, 32, 69,110,100, 32, 77,117,108,116,
+105,114,101,115, 32, 42, 42, 47, 13, 10, 13, 10,116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 80, 97,114,116,105,
+ 97,108, 86,105,115,105, 98,105,108,105,116,121, 32,123, 13, 10, 9,117,110,115,105,103,110,101,100, 32,105,110,116, 32, 42,118,
+101,114,116, 95,109, 97,112, 59, 32, 47, 42, 32,118,101,114,116, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61,
+ 32, 78,101,119, 32, 73,110,100,101,120, 32, 42, 47, 13, 10, 9,105,110,116, 32, 42,101,100,103,101, 95,109, 97,112, 59, 32, 47,
+ 42, 32,101,100,103,101, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, 32, 78,101,119, 32, 73,110,100,101,120,
+ 44, 32, 45, 49, 61, 32,104,105,100,100,101,110, 32, 42, 47, 13, 10, 9, 77, 70, 97, 99,101, 32, 42,111,108,100, 95,102, 97, 99,
+101,115, 59, 13, 10, 9, 77, 69,100,103,101, 32, 42,111,108,100, 95,101,100,103,101,115, 59, 13, 10, 9,117,110,115,105,103,110,
+101,100, 32,105,110,116, 32,116,111,116,102, 97, 99,101, 44, 32,116,111,116,101,100,103,101, 44, 32,116,111,116,118,101,114,116,
+ 44, 32,112, 97,100, 59, 13, 10,125, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 59, 13, 10, 13, 10,
+ 47, 42, 32,109,118,101,114,116, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 32, 42, 47, 13, 10, 35,100,
+101,102,105,110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 83, 84, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77,
+ 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 77, 80, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 72, 73, 68, 69, 9,
+ 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 69, 82, 84, 95, 77, 69, 82, 71, 69, 68, 9, 9, 40, 49,
+ 60, 60, 54, 41, 13, 10, 13, 10, 47, 42, 32,109,101,100,103,101, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84,
+ 41, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 9, 9, 9, 40, 49, 60, 60, 49,
+ 41, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 9, 9, 9, 9, 40, 49, 60, 60, 50, 41, 13, 10, 35,100,
+101,102,105,110,101, 32, 77, 69, 95, 70, 71, 79, 78, 9, 9, 9, 9, 40, 49, 60, 60, 51, 41, 13, 10, 9, 9, 9, 9, 9, 9, 47,
+ 42, 32,114,101,115,101,114,118,101, 32, 49, 54, 32,102,111,114, 32, 77, 69, 95, 72, 73, 68, 69, 32, 42, 47, 13, 10, 35,100,101,
+102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 9, 9, 40, 49, 60, 60, 53, 41, 13, 10, 35,100,101,102,
+105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, 71, 69, 9, 9, 40, 49, 60, 60, 55, 41, 13, 10, 35,100,101,102,105,110,
+101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 9, 9, 40, 49, 60, 60, 56, 41, 13, 10, 35,100,101,102,105,110,101, 32,
+ 77, 69, 95, 83, 72, 65, 82, 80, 9, 9, 9, 40, 49, 60, 60, 57, 41, 13, 10, 13, 10, 47, 42, 32,112,117,110,111, 32, 61, 32,118,
+101,114,116,101,120,110,111,114,109, 97,108, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10, 47, 42, 32,114,101,110,100,101,
+114, 32, 97,115,115,117,109,101,115, 32,102,108,105,112,115, 32,116,111, 32, 98,101, 32,111,114,100,101,114,101,100, 32,108,105,
+107,101, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 9, 9, 49,
+ 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 50, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32,
+ 77, 69, 95, 70, 76, 73, 80, 86, 51, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 9,
+ 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 89, 9, 9, 49, 54, 13, 10, 35,100,101,102,105,
+110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 9, 9, 51, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79,
+ 74, 89, 90, 9, 9, 54, 52, 13, 10, 13, 10, 47, 42, 32,101,100, 99,111,100,101, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13,
+ 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69,
+ 95, 86, 50, 86, 51, 9, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 49, 9, 9, 9, 52, 13, 10,
+ 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95,
+ 86, 52, 86, 49, 9, 9, 9, 56, 13, 10, 13, 10, 47, 42, 32,102,108, 97,103, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10,
+ 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77,
+ 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 9, 9, 9, 50, 13, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,102,108, 97,103, 32, 77, 69,
+ 95, 72, 73, 68, 69, 61, 61, 49, 54, 32,105,115, 32,117,115,101,100, 32,104,101,114,101, 32,116,111,111, 32, 42, 47, 32, 13, 10,
+ 47, 42, 32,109,115,101,108,101, 99,116, 45, 62,116,121,112,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95,
+ 86, 83, 69,108, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 13, 10, 35,100,101,102,105,
+110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,102,108, 97,103, 32,
+ 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 9, 49, 32, 47, 42, 32,117,115,101, 32, 77,
+ 70, 97, 99,101, 32,104,105,100,101, 32,102,108, 97,103, 32, 40, 97,102,116,101,114, 32, 50, 46, 52, 51, 41, 44, 32,115,104,111,
+117,108,100, 32, 98,101, 32, 97, 98,108,101, 32,116,111, 32,114,101,117,115,101, 32, 97,102,116,101,114, 32, 50, 46, 52, 52, 32,
+ 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 9, 50, 32, 47, 42, 32,100,101,112,114,101,
+ 99, 97,116,101,100, 33, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 9, 9, 52, 13, 10, 35,
+100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 9, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69,
+ 76, 51, 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 9, 9, 51, 50, 13, 10, 35,100,101,
+102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 9, 9, 54, 52, 32, 47, 42, 32,117,110,117,115,101,100, 44, 32,115, 97,109,101,
+ 32, 97,115, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,109,
+111,100,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 9, 9, 49, 13, 10, 35,
+100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84,
+ 70, 95, 84, 69, 88, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 86, 69, 82, 84,
+ 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 9, 9, 49, 54, 13, 10, 13, 10, 35,100,101,102,
+105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95,
+ 84, 73, 76, 69, 83, 9, 9, 49, 50, 56, 9, 9, 47, 42, 32,100,101,112,114,101, 99, 97,116,101,100, 32, 42, 47, 13, 10, 35,100,
+101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 9, 50, 53, 54, 13, 10, 35,100,101,102,105,110,101, 32,
+ 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 9, 9, 53, 49, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73,
+ 83, 73, 66, 76, 69, 9, 49, 48, 50, 52, 13, 10, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, 67, 79, 76, 9, 9,
+ 50, 48, 52, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 9, 52, 48, 57, 54,
+ 9, 47, 42, 32,119,105,116,104, 32, 90, 32, 97,120,105,115, 32, 99,111,110,115,116,114, 97,105,110,116, 32, 42, 47, 13, 10, 35,
+100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 9, 9, 56, 49, 57, 50, 13, 10, 35,100,101,102,105,110,101, 32,
+ 84, 70, 95, 66, 77, 70, 79, 78, 84, 9, 9, 49, 54, 51, 56, 52, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,116,
+114, 97,110,115,112, 44, 32,118, 97,108,117,101,115, 32, 49, 45, 52, 32, 97,114,101, 32,117,115,101,100, 32, 97,115, 32,102,108,
+ 97,103,115, 32,105,110, 32,116,104,101, 32, 71, 76, 44, 32, 87, 65, 82, 78, 73, 78, 71, 44, 32, 84, 70, 95, 83, 85, 66, 32, 99,
+ 97,110,116, 32,119,111,114,107, 32,119,105,116,104, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84,
+ 70, 95, 83, 79, 76, 73, 68, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 9, 9, 49, 13, 10, 35,100,
+101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73,
+ 80, 9, 9, 52, 32, 47, 42, 32, 99,108,105,112,109, 97,112, 32, 97,108,112,104, 97, 47, 98,105,110, 97,114,121, 32, 97,108,112,
+104, 97, 32, 97,108,108, 32,111,114, 32,110,111,116,104,105,110,103, 33, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,115,117, 98, 32,
+105,115, 32,110,111,116, 32, 97,118, 97,105,108, 97, 98,108,101, 32,105,110, 32,116,104,101, 32,117,115,101,114, 32,105,110,116,
+101,114,102, 97, 99,101, 32, 97,110,121,109,111,114,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85,
+ 66, 9, 9, 51, 13, 10, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,117,110,119,114, 97,112, 32, 42, 47, 13, 10,
+ 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 9, 49, 13, 10, 35,100,101,102,105,110,
+101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 50, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68,
+ 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65,
+ 84, 69, 68, 52, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 49, 9, 9, 32, 32, 32, 32, 49, 54, 13,
+ 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 9, 9, 32, 32, 32, 32, 51, 50, 13, 10, 35,100,101,102,105,110,
+101, 32, 84, 70, 95, 80, 73, 78, 51, 9, 32, 32, 32, 9, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73,
+ 78, 52, 9, 32, 32, 32, 32, 9, 49, 50, 56, 13, 10, 13, 10, 35,101,110,100,105,102, 13, 10,104, 79, 67, 75, 33,109, 98,101,114,
+ 97, 2, 67, 3,191, 16, 8, 1,232, 80,100, 0, 77,117,108,116,105,114,101,115, 67,111,108, 0, 77,117,108,116,105,114,101,115,
+ 67,111,108, 70, 97, 99,101, 0, 77,117,108,116,105,114,101,115, 70, 97, 99,101, 0, 77,117,108,116,105,114,101,115, 69,100,103,
+101, 0, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 0, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,117, 98,
+115,117,114,102, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 76, 97,116,116,105, 99,101, 77,111,100,105,102,105,101,114,
+ 68, 97,116, 97, 0, 67,117,114,118,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66,117,105,108,100, 77,111,100,105,
+102,105,101,114, 68, 97,116, 97, 0, 77, 97,115,107, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 65,114,114, 97,121, 77,
+111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,105,114,114,111,114, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,
+100,103,101, 83,112,108,105,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66,101,118,101,108, 77,111,100,105,102,105,
+101,114, 68, 97,116, 97, 0, 66, 77,101,115,104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,109,111,107,101, 77,111,
+100,105,102,105,101,114, 68, 97,116, 97, 0, 83,109,111,107,101, 68,111,109, 97,105,110, 83,101,116,116,105,110,103,115, 0, 83,
+109,111,107,101, 70,108,111,119, 83,101,116,116,105,110,103,115, 0, 83,109,111,107,101, 67,111,108,108, 83,101,116,116,105,110,
+103,115, 0, 68,105,115,112,108, 97, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 85, 86, 80,114,111,106,101, 99,
116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,101, 99,105,109, 97,116,101, 77,111,100,105,102,105,101,114, 68, 97,
116, 97, 0, 83,109,111,111,116,104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67, 97,115,116, 77,111,100,105,102,105,
101,114, 68, 97,116, 97, 0, 87, 97,118,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 65,114,109, 97,116,117,114,101,
@@ -2206,749 +2366,778 @@ char datatoc_B_blend[]= {
111,109, 77,101,115,104, 0, 66,111,111,108,101, 97,110, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77, 68,101,102, 73,
110,102,108,117,101,110, 99,101, 0, 77, 68,101,102, 67,101,108,108, 0, 77,101,115,104, 68,101,102,111,114,109, 77,111,100,105,
102,105,101,114, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 77,111,100,105,102,105,101,114, 68,
- 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, 80, 97,114,116,105, 99,108,101, 73,110,115,116, 97,
-110, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,120,112,108,111,100,101, 77,111,100,105,102,105,101,114, 68,
- 97,116, 97, 0, 77,117,108,116,105,114,101,115, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 70,108,117,105,100,115,105,
-109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 70,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 83,
-104,114,105,110,107,119,114, 97,112, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,105,109,112,108,101, 68,101,102,111,
-114,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 76, 97,116,116,105, 99,101, 0, 98, 68,101,102,111,114,109, 71,114,
-111,117,112, 0, 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 0, 66,117,108,108,101,116, 83,111,102,116, 66,111,100,121,
- 0, 80, 97,114,116, 68,101,102,108,101, 99,116, 0, 83,111,102,116, 66,111,100,121, 0, 79, 98, 72,111,111,107, 0, 82, 78, 71,
- 0, 80, 84, 67, 97, 99,104,101, 77,101,109, 0, 83, 66, 86,101,114,116,101,120, 0, 66,111,100,121, 80,111,105,110,116, 0, 66,
-111,100,121, 83,112,114,105,110,103, 0, 83, 66, 83, 99,114, 97,116, 99,104, 0, 87,111,114,108,100, 0, 66, 97,115,101, 0, 65,
-118,105, 67,111,100,101, 99, 68, 97,116, 97, 0, 81,117,105, 99,107,116,105,109,101, 67,111,100,101, 99, 68, 97,116, 97, 0, 70,
- 70, 77,112,101,103, 67,111,100,101, 99, 68, 97,116, 97, 0, 65,117,100,105,111, 68, 97,116, 97, 0, 83, 99,101,110,101, 82,101,
-110,100,101,114, 76, 97,121,101,114, 0, 82,101,110,100,101,114, 68, 97,116, 97, 0, 82,101,110,100,101,114, 80,114,111,102,105,
-108,101, 0, 71, 97,109,101, 68,111,109,101, 0, 71, 97,109,101, 70,114, 97,109,105,110,103, 0, 71, 97,109,101, 68, 97,116, 97,
- 0, 84,105,109,101, 77, 97,114,107,101,114, 0, 73,109, 97,103,101, 80, 97,105,110,116, 83,101,116,116,105,110,103,115, 0, 66,
-114,117,115,104, 0, 80, 97,114,116,105, 99,108,101, 66,114,117,115,104, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 69,
-100,105,116, 83,101,116,116,105,110,103,115, 0, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110,
- 0, 83, 99,117,108,112,116, 0, 83, 99,117,108,112,116, 83,101,115,115,105,111,110, 0, 86, 80, 97,105,110,116, 0, 84,111,111,
-108, 83,101,116,116,105,110,103,115, 0, 98, 83,116, 97,116,115, 0, 69,100,105,116,105,110,103, 0, 83, 99,101,110,101, 83,116,
- 97,116,115, 0, 68, 97,103, 70,111,114,101,115,116, 0, 66, 71,112,105, 99, 0, 82,101,103,105,111,110, 86,105,101,119, 51, 68,
- 0, 98, 71, 80,100, 97,116, 97, 0, 82,101,110,100,101,114, 73,110,102,111, 0, 82,101,116,111,112,111, 86,105,101,119, 68, 97,
-116, 97, 0, 86,105,101,119, 68,101,112,116,104,115, 0, 83,109,111,111,116,104, 86,105,101,119, 83,116,111,114,101, 0,119,109,
- 84,105,109,101,114, 0, 86,105,101,119, 51, 68, 0, 83,112, 97, 99,101, 76,105,110,107, 0, 86,105,101,119, 50, 68, 0, 83,112,
- 97, 99,101, 73,110,102,111, 0, 98, 83, 99,114,101,101,110, 0, 83,112, 97, 99,101, 73,112,111, 0, 98, 68,111,112,101, 83,104,
-101,101,116, 0, 83,112, 97, 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0, 70,105,108,101, 83,101,108,101, 99,
-116, 80, 97,114, 97,109,115, 0, 83,112, 97, 99,101, 70,105,108,101, 0, 70,105,108,101, 76,105,115,116, 0,119,109, 79,112,101,
-114, 97,116,111,114, 0, 70,105,108,101, 76, 97,121,111,117,116, 0, 83,112, 97, 99,101, 79,111,112,115, 0, 84,114,101,101, 83,
-116,111,114,101, 0, 84,114,101,101, 83,116,111,114,101, 69,108,101,109, 0, 83,112, 97, 99,101, 73,109, 97,103,101, 0, 83,112,
- 97, 99,101, 78,108, 97, 0, 83,112, 97, 99,101, 84,101,120,116, 0, 83, 99,114,105,112,116, 0, 83,112, 97, 99,101, 83, 99,114,
-105,112,116, 0, 83,112, 97, 99,101, 84,105,109,101, 0, 83,112, 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,
-105, 99, 0, 83,112, 97, 99,101, 73,109, 97, 83,101,108, 0, 67,111,110,115,111,108,101, 76,105,110,101, 0, 83,112, 97, 99,101,
- 67,111,110,115,111,108,101, 0,117,105, 70,111,110,116, 0,117,105, 70,111,110,116, 83,116,121,108,101, 0,117,105, 83,116,121,
-108,101, 0,117,105, 87,105,100,103,101,116, 67,111,108,111,114,115, 0,117,105, 87,105,100,103,101,116, 83,116, 97,116,101, 67,
-111,108,111,114,115, 0, 84,104,101,109,101, 85, 73, 0, 84,104,101,109,101, 83,112, 97, 99,101, 0, 84,104,101,109,101, 87,105,
-114,101, 67,111,108,111,114, 0, 98, 84,104,101,109,101, 0, 83,111,108,105,100, 76,105,103,104,116, 0, 85,115,101,114, 68,101,
-102, 0, 83, 99,114, 86,101,114,116, 0, 83, 99,114, 69,100,103,101, 0, 80, 97,110,101,108, 0, 80, 97,110,101,108, 84,121,112,
-101, 0,117,105, 76, 97,121,111,117,116, 0, 83, 99,114, 65,114,101, 97, 0, 83,112, 97, 99,101, 84,121,112,101, 0, 65, 82,101,
-103,105,111,110, 0, 65, 82,101,103,105,111,110, 84,121,112,101, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114,105,
-112, 69,108,101,109, 0, 84, 83,116,114,105,112, 69,108,101,109, 0, 83,116,114,105,112, 67,114,111,112, 0, 83,116,114,105,112,
- 84,114, 97,110,115,102,111,114,109, 0, 83,116,114,105,112, 67,111,108,111,114, 66, 97,108, 97,110, 99,101, 0, 83,116,114,105,
-112, 80,114,111,120,121, 0, 83,116,114,105,112, 0, 80,108,117,103,105,110, 83,101,113, 0, 83,101,113,117,101,110, 99,101, 0,
- 98, 83,111,117,110,100, 0,104,100, 97,117,100,105,111, 0, 77,101,116, 97, 83,116, 97, 99,107, 0, 87,105,112,101, 86, 97,114,
-115, 0, 71,108,111,119, 86, 97,114,115, 0, 84,114, 97,110,115,102,111,114,109, 86, 97,114,115, 0, 83,111,108,105,100, 67,111,
-108,111,114, 86, 97,114,115, 0, 83,112,101,101,100, 67,111,110,116,114,111,108, 86, 97,114,115, 0, 69,102,102,101, 99,116, 0,
- 66,117,105,108,100, 69,102,102, 0, 80, 97,114,116, 69,102,102, 0, 80, 97,114,116,105, 99,108,101, 0, 87, 97,118,101, 69,102,
-102, 0, 98, 80,114,111,112,101,114,116,121, 0, 98, 78,101, 97,114, 83,101,110,115,111,114, 0, 98, 77,111,117,115,101, 83,101,
-110,115,111,114, 0, 98, 84,111,117, 99,104, 83,101,110,115,111,114, 0, 98, 75,101,121, 98,111, 97,114,100, 83,101,110,115,111,
-114, 0, 98, 80,114,111,112,101,114,116,121, 83,101,110,115,111,114, 0, 98, 65, 99,116,117, 97,116,111,114, 83,101,110,115,111,
-114, 0, 98, 68,101,108, 97,121, 83,101,110,115,111,114, 0, 98, 67,111,108,108,105,115,105,111,110, 83,101,110,115,111,114, 0,
- 98, 82, 97,100, 97,114, 83,101,110,115,111,114, 0, 98, 82, 97,110,100,111,109, 83,101,110,115,111,114, 0, 98, 82, 97,121, 83,
-101,110,115,111,114, 0, 98, 77,101,115,115, 97,103,101, 83,101,110,115,111,114, 0, 98, 83,101,110,115,111,114, 0, 98, 67,111,
-110,116,114,111,108,108,101,114, 0, 98, 74,111,121,115,116,105, 99,107, 83,101,110,115,111,114, 0, 98, 69,120,112,114,101,115,
-115,105,111,110, 67,111,110,116, 0, 98, 80,121,116,104,111,110, 67,111,110,116, 0, 98, 65, 99,116,117, 97,116,111,114, 0, 98,
- 65,100,100, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 65, 99,116,105,111,110, 65, 99,116,117, 97,116,111,
-114, 0, 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 98, 67, 68, 65, 99,116,117, 97,116,111,114, 0, 98, 69,100,
-105,116, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83, 99,101,110,101, 65, 99,116,117, 97,116,111,114, 0,
- 98, 80,114,111,112,101,114,116,121, 65, 99,116,117, 97,116,111,114, 0, 98, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,
-114, 0, 98, 73,112,111, 65, 99,116,117, 97,116,111,114, 0, 98, 67, 97,109,101,114, 97, 65, 99,116,117, 97,116,111,114, 0, 98,
- 67,111,110,115,116,114, 97,105,110,116, 65, 99,116,117, 97,116,111,114, 0, 98, 71,114,111,117,112, 65, 99,116,117, 97,116,111,
-114, 0, 98, 82, 97,110,100,111,109, 65, 99,116,117, 97,116,111,114, 0, 98, 77,101,115,115, 97,103,101, 65, 99,116,117, 97,116,
-111,114, 0, 98, 71, 97,109,101, 65, 99,116,117, 97,116,111,114, 0, 98, 86,105,115,105, 98,105,108,105,116,121, 65, 99,116,117,
- 97,116,111,114, 0, 98, 84,119,111, 68, 70,105,108,116,101,114, 65, 99,116,117, 97,116,111,114, 0, 98, 80, 97,114,101,110,116,
- 65, 99,116,117, 97,116,111,114, 0, 98, 83,116, 97,116,101, 65, 99,116,117, 97,116,111,114, 0, 70,114,101,101, 67, 97,109,101,
-114, 97, 0, 98, 83, 97,109,112,108,101, 0, 98, 83,111,117,110,100, 76,105,115,116,101,110,101,114, 0, 83,112, 97, 99,101, 83,
-111,117,110,100, 0, 71,114,111,117,112, 79, 98,106,101, 99,116, 0, 66,111,110,101, 0, 98, 65,114,109, 97,116,117,114,101, 0,
- 98, 80,111,115,101, 67,104, 97,110,110,101,108, 0, 98, 65, 99,116,105,111,110, 71,114,111,117,112, 0, 83,112, 97, 99,101, 65,
- 99,116,105,111,110, 0, 98, 65, 99,116,105,111,110, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115,116,114, 97,105,110,116,
- 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 84,
- 97,114,103,101,116, 0, 98, 80,121,116,104,111,110, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 75,105,110,101,109, 97,116,
-105, 99, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 84,114, 97, 99,107, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0,
- 98, 82,111,116, 97,116,101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99, 97,116,101, 76,105,107,
-101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 77,105,110, 77, 97,120, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,
-105,122,101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 67,111,110,115,116,114, 97,
-105,110,116, 0, 98, 76,111, 99,107, 84,114, 97, 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 70,111,108,108,111,119,
- 80, 97,116,104, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,116,114,101,116, 99,104, 84,111, 67,111,110,115,116,114, 97,
-105,110,116, 0, 98, 82,105,103,105,100, 66,111,100,121, 74,111,105,110,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,
-108, 97,109,112, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,104,105,108,100, 79,102, 67,111,110,115,116,114, 97,
-105,110,116, 0, 98, 84,114, 97,110,115,102,111,114,109, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99, 76,105,109,
-105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116,
- 0, 98, 83,105,122,101, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 68,105,115,116, 76,105,109,105,116,
- 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,104,114,105,110,107,119,114, 97,112, 67,111,110,115,116,114, 97,105,110,116,
- 0, 98, 65, 99,116,105,111,110, 77,111,100,105,102,105,101,114, 0, 98, 65, 99,116,105,111,110, 83,116,114,105,112, 0, 98, 78,
-111,100,101, 83,116, 97, 99,107, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 0, 98, 78,111,100,101, 76,105,110,107, 0, 98,
- 78,111,100,101, 0, 98, 78,111,100,101, 80,114,101,118,105,101,119, 0, 98, 78,111,100,101, 84,121,112,101, 0, 78,111,100,101,
- 73,109, 97,103,101, 65,110,105,109, 0, 78,111,100,101, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 68, 66,108,117,114,
- 68, 97,116, 97, 0, 78,111,100,101, 66,105,108, 97,116,101,114, 97,108, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 72,
-117,101, 83, 97,116, 0, 78,111,100,101, 73,109, 97,103,101, 70,105,108,101, 0, 78,111,100,101, 67,104,114,111,109, 97, 0, 78,
-111,100,101, 84,119,111, 88, 89,115, 0, 78,111,100,101, 84,119,111, 70,108,111, 97,116,115, 0, 78,111,100,101, 71,101,111,109,
-101,116,114,121, 0, 78,111,100,101, 86,101,114,116,101,120, 67,111,108, 0, 78,111,100,101, 68,101,102,111, 99,117,115, 0, 78,
-111,100,101, 83, 99,114,105,112,116, 68,105, 99,116, 0, 78,111,100,101, 71,108, 97,114,101, 0, 78,111,100,101, 84,111,110,101,
-109, 97,112, 0, 78,111,100,101, 76,101,110,115, 68,105,115,116, 0, 84,101,120, 78,111,100,101, 79,117,116,112,117,116, 0, 67,
-117,114,118,101, 77, 97,112, 80,111,105,110,116, 0, 67,117,114,118,101, 77, 97,112, 0, 66,114,117,115,104, 67,108,111,110,101,
- 0, 67,117,115,116,111,109, 68, 97,116, 97, 76, 97,121,101,114, 0, 72, 97,105,114, 75,101,121, 0, 80, 97,114,116,105, 99,108,
-101, 75,101,121, 0, 67,104,105,108,100, 80, 97,114,116,105, 99,108,101, 0, 80, 97,114,116,105, 99,108,101, 84, 97,114,103,101,
-116, 0, 80, 97,114,116,105, 99,108,101, 68, 97,116, 97, 0, 66,111,105,100, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101,
- 83,101,116,116,105,110,103,115, 0, 66,111,105,100, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, 99,108,101, 69,100,
-105,116, 0, 80, 97,114,116,105, 99,108,101, 67, 97, 99,104,101, 75,101,121, 0, 75, 68, 84,114,101,101, 0, 76,105,110,107, 78,
-111,100,101, 0, 98, 71, 80, 68,115,112,111,105,110,116, 0, 98, 71, 80, 68,115,116,114,111,107,101, 0, 98, 71, 80, 68,102,114,
- 97,109,101, 0, 98, 71, 80, 68,108, 97,121,101,114, 0, 82,101,112,111,114,116, 0, 82,101,112,111,114,116, 76,105,115,116, 0,
-119,109, 87,105,110,100,111,119, 77, 97,110, 97,103,101,114, 0,119,109, 87,105,110,100,111,119, 0,119,109, 69,118,101,110,116,
- 0,119,109, 83,117, 98, 87,105,110,100,111,119, 0,119,109, 71,101,115,116,117,114,101, 0,119,109, 75,101,121,109, 97,112, 73,
-116,101,109, 0, 80,111,105,110,116,101,114, 82, 78, 65, 0,119,109, 75,101,121, 77, 97,112, 0,119,109, 79,112,101,114, 97,116,
-111,114, 84,121,112,101, 0, 70, 77,111,100,105,102,105,101,114, 0, 70, 77,111,100, 95, 71,101,110,101,114, 97,116,111,114, 0,
- 70, 77,111,100, 95, 70,117,110, 99,116,105,111,110, 71,101,110,101,114, 97,116,111,114, 0, 70, 67, 77, 95, 69,110,118,101,108,
-111,112,101, 68, 97,116, 97, 0, 70, 77,111,100, 95, 69,110,118,101,108,111,112,101, 0, 70, 77,111,100, 95, 67,121, 99,108,101,
-115, 0, 70, 77,111,100, 95, 80,121,116,104,111,110, 0, 70, 77,111,100, 95, 76,105,109,105,116,115, 0, 70, 77,111,100, 95, 78,
-111,105,115,101, 0, 68,114,105,118,101,114, 84, 97,114,103,101,116, 0, 67,104, 97,110,110,101,108, 68,114,105,118,101,114, 0,
- 70, 80,111,105,110,116, 0, 70, 67,117,114,118,101, 0, 65,110,105,109, 77, 97,112, 80, 97,105,114, 0, 65,110,105,109, 77, 97,
-112,112,101,114, 0, 78,108, 97, 83,116,114,105,112, 0, 78,108, 97, 84,114, 97, 99,107, 0, 75, 83, 95, 80, 97,116,104, 0, 75,
-101,121,105,110,103, 83,101,116, 0, 65,110,105,109, 79,118,101,114,114,105,100,101, 0, 73,100, 65,100,116, 84,101,109,112,108,
- 97,116,101, 0, 66,111,105,100, 82,117,108,101, 0, 66,111,105,100, 82,117,108,101, 71,111, 97,108, 65,118,111,105,100, 0, 66,
-111,105,100, 82,117,108,101, 65,118,111,105,100, 67,111,108,108,105,115,105,111,110, 0, 66,111,105,100, 82,117,108,101, 70,111,
-108,108,111,119, 76,101, 97,100,101,114, 0, 66,111,105,100, 82,117,108,101, 65,118,101,114, 97,103,101, 83,112,101,101,100, 0,
- 66,111,105,100, 82,117,108,101, 70,105,103,104,116, 0, 66,111,105,100, 83,116, 97,116,101, 0, 84, 76, 69, 78, 1, 0, 1, 0,
- 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 16, 0, 24, 0, 16, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0,
- 12, 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 32, 0, 96, 0, 72, 0, 72, 2, 0, 0, 40, 0,144, 0, 40, 4,112, 0,
- 36, 0, 56, 0,112, 0,128, 0,168, 0, 88, 0, 40, 0, 48, 0,176, 0, 16, 0,152, 0, 40, 0,192, 5,184, 1, 0, 0, 0, 0,
- 0, 0,144, 0, 88, 1,120, 1, 24, 0, 8, 3,200, 0, 0, 0,232, 0,136, 0,232, 1, 56, 1, 80, 0,224, 2,104, 0, 88, 1,
- 0, 0,128, 0,104, 0,200, 0, 80, 0, 8, 0, 16, 0,200, 1, 0, 0, 0, 0, 0, 0,144, 1, 20, 0, 48, 0, 64, 0, 24, 0,
- 12, 0, 16, 0, 4, 0, 8, 0, 8, 0, 0, 0, 32, 0,112, 0, 48, 0, 8, 0, 16, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1,
- 32, 0, 16, 0, 0, 0, 16, 0, 64, 0, 24, 0, 12, 0, 64, 0, 72, 0, 96, 0,112, 0,120, 0, 88, 0,120, 0,152, 0, 88, 0,
- 80, 0,128, 0, 80, 0,176, 0,216, 0, 80, 0,112, 0,128, 0,216, 0,128, 0,208, 0, 72, 0,112, 0, 0, 0,136, 0, 32, 0,
-232, 1,152, 0, 0, 0,112, 0, 0, 0, 0, 0, 88, 0, 8, 0, 8, 0, 8, 1,104, 0,216, 1, 96, 0, 88, 0, 88, 0, 88, 0,
-184, 1,136, 0,128, 0,232, 0, 48, 0,144, 0, 72, 0,120, 0,136, 0, 16, 1,224, 0, 0, 0, 40, 0, 16, 0, 0, 0, 0, 0,
- 0, 0,216, 1, 40, 0,184, 0,152, 0, 56, 0, 16, 0, 88, 0, 24, 4, 64, 0, 24, 0, 16, 0, 88, 0, 88, 0, 24, 0, 40, 1,
- 8, 0, 88, 0, 88, 0, 40, 0, 0, 0, 48, 0, 64, 1, 32, 0, 48, 2, 0, 0, 0, 0, 64, 0,248, 2,104, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 32, 1, 56, 0,152, 0, 72, 0,208, 0,240, 0, 32, 0, 0, 1,240, 0,128, 1,104, 0, 0, 0,144, 0,
- 0, 0, 40, 1, 16, 0, 16, 0,168, 0,224, 0,144, 2,120, 2, 64, 0,200, 0, 32, 1, 72, 0,208, 2, 40, 0,112, 0, 24, 1,
- 32, 0,232, 0, 32, 0, 32, 0, 80, 2, 16, 1, 16, 0,192, 20, 56, 0, 64, 11, 32, 0, 40, 0, 80, 1, 0, 0, 0, 0,160, 0,
- 0, 0, 40, 1, 0, 0, 40, 0, 80, 0, 48, 0, 16, 0, 8, 0, 52, 0, 0, 1, 32, 1,200, 1, 8, 1, 72, 1, 0, 0, 32, 0,
- 12, 0, 24, 0, 48, 0, 16, 0, 24, 0, 24, 0, 32, 0, 72, 1, 0, 0, 64, 0, 64, 0, 48, 0, 8, 0, 48, 0, 72, 0,104, 0,
- 40, 0, 8, 0, 72, 0, 44, 0, 40, 0,108, 0, 72, 0, 96, 0,104, 0, 60, 0,128, 0, 80, 0, 80, 0, 16, 0, 96, 0, 32, 0,
- 20, 0, 88, 0, 24, 0, 80, 0,112, 0, 84, 0, 32, 0, 96, 0, 64, 0, 56, 0,112, 0,140, 0, 4, 0, 24, 0, 16, 0, 8, 0,
- 40, 0, 0, 0, 88, 0,224, 0, 40, 0, 24, 1,168, 0,232, 1,120, 0, 8, 1, 88, 0, 56, 0, 80, 0,128, 0, 80, 0,112, 0,
- 56, 0, 48, 0, 48, 0, 72, 0, 48, 0, 72, 0, 48, 0, 24, 0, 56, 0,104, 0, 16, 0,112, 0, 96, 0, 28, 0, 28, 0, 28, 0,
- 56, 0, 24, 0, 72, 0,168, 0, 40, 0,144, 0, 56, 0, 0, 1, 0, 0, 0, 0, 16, 0, 40, 0, 28, 0, 12, 0, 12, 0, 16, 1,
- 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 16, 0, 24, 0, 32, 0, 8, 0, 32, 0, 12, 0, 56, 0, 24, 0, 72, 0, 24, 0,
- 56, 0, 72, 0, 40, 0,248, 0, 20, 0, 8, 2,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 40, 0,192, 0, 40, 0,
- 32, 0,224, 0,224, 0, 72, 0, 0, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,104, 0, 24, 0, 24, 0, 16, 0, 24, 0, 8, 0,
- 16, 0, 24, 0, 20, 0,104, 0, 32, 1, 16, 0,104, 0, 0, 1, 40, 0,200, 0,104, 0,112, 0,104, 0, 32, 0, 80, 0, 56, 0,
- 80, 0, 64, 0,104, 0, 72, 0, 64, 0,128, 0, 83, 84, 82, 67,112, 1, 0, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1, 0,
- 11, 0, 3, 0, 11, 0, 0, 0, 11, 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0, 9, 0, 4, 0, 13, 0, 2, 0,
- 2, 0, 5, 0, 2, 0, 6, 0, 14, 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,
- 16, 0, 2, 0, 8, 0, 5, 0, 8, 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 18, 0, 3, 0,
- 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 20, 0, 4, 0,
- 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0,
- 7, 0, 8, 0, 22, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0, 23, 0, 4, 0, 4, 0, 9, 0,
- 4, 0, 10, 0, 4, 0, 11, 0, 4, 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0,
- 25, 0, 4, 0, 9, 0, 13, 0, 12, 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0, 26, 0, 0, 0, 26, 0, 1, 0,
- 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19, 0, 0, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0, 4, 0, 23, 0, 4, 0, 24, 0,
- 27, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0, 2, 0, 28, 0, 2, 0, 19, 0,
- 4, 0, 29, 0, 26, 0, 30, 0, 28, 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0,
- 4, 0, 36, 0, 4, 0, 37, 0, 28, 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0,
- 2, 0, 43, 0, 4, 0, 44, 0, 31, 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 17, 0, 2, 0, 19, 0,
- 0, 0, 48, 0, 33, 0, 21, 0, 33, 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0, 24, 0, 51, 0, 24, 0, 52, 0,
- 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0, 2, 0, 19, 0, 2, 0, 57, 0,
- 7, 0, 11, 0, 7, 0, 12, 0, 4, 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0, 31, 0, 62, 0, 36, 0, 7, 0,
- 27, 0, 31, 0, 12, 0, 63, 0, 24, 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0, 2, 0, 37, 0, 37, 0, 16, 0,
- 37, 0, 0, 0, 37, 0, 1, 0, 7, 0, 67, 0, 7, 0, 61, 0, 2, 0, 17, 0, 2, 0, 47, 0, 2, 0, 68, 0, 2, 0, 19, 0,
- 4, 0, 69, 0, 4, 0, 70, 0, 9, 0, 2, 0, 7, 0, 71, 0, 0, 0, 20, 0, 0, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0,
- 38, 0, 13, 0, 27, 0, 31, 0, 39, 0, 75, 0, 37, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0, 7, 0, 61, 0, 12, 0, 79, 0,
- 36, 0, 80, 0, 27, 0, 81, 0, 2, 0, 17, 0, 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 19, 0, 40, 0, 6, 0, 40, 0, 0, 0,
- 40, 0, 1, 0, 0, 0, 84, 0, 0, 0, 85, 0, 4, 0, 23, 0, 4, 0, 86, 0, 41, 0, 10, 0, 41, 0, 0, 0, 41, 0, 1, 0,
- 4, 0, 87, 0, 4, 0, 88, 0, 4, 0, 89, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, 0, 90, 0, 0, 0, 91, 0, 0, 0, 92, 0,
- 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 93, 0, 4, 0, 90, 0, 4, 0, 94, 0, 12, 0, 95, 0, 40, 0, 96, 0, 40, 0, 97, 0,
- 4, 0, 98, 0, 4, 0, 99, 0, 12, 0,100, 0, 0, 0,101, 0, 4, 0,102, 0, 4, 0,103, 0, 9, 0,104, 0, 8, 0,105, 0,
- 43, 0, 3, 0, 4, 0,106, 0, 4, 0,107, 0, 9, 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0,
- 2, 0, 19, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,112, 0, 7, 0,113, 0, 7, 0,114, 0,
- 7, 0,115, 0, 7, 0,116, 0, 7, 0,117, 0, 7, 0,118, 0, 2, 0,119, 0, 2, 0,120, 0, 7, 0,121, 0, 36, 0, 80, 0,
- 32, 0,122, 0, 45, 0, 13, 0, 4, 0,123, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 2, 0,127, 0, 2, 0,128, 0,
- 2, 0, 19, 0, 2, 0,129, 0, 2, 0,130, 0, 2, 0,131, 0, 2, 0,132, 0, 2, 0,133, 0, 46, 0,134, 0, 47, 0, 32, 0,
- 27, 0, 31, 0, 0, 0, 34, 0, 12, 0,135, 0, 48, 0,136, 0, 49, 0,137, 0, 50, 0,138, 0, 2, 0,129, 0, 2, 0, 19, 0,
- 2, 0,139, 0, 2, 0, 17, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, 0,140, 0, 2, 0,141, 0, 2, 0,142, 0, 2, 0,143, 0,
- 2, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 4, 0,147, 0, 4, 0,148, 0, 43, 0,149, 0, 30, 0,150, 0, 0, 0,151, 0,
- 7, 0,152, 0, 4, 0,153, 0, 2, 0,154, 0, 2, 0,155, 0, 2, 0,156, 0, 2, 0,157, 0, 7, 0,158, 0, 7, 0,159, 0,
- 51, 0, 31, 0, 2, 0,160, 0, 2, 0,161, 0, 2, 0,162, 0, 2, 0,163, 0, 32, 0,164, 0, 52, 0,165, 0, 0, 0,166, 0,
- 0, 0,167, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 7, 0,171, 0, 7, 0,172, 0, 2, 0,173, 0, 2, 0,174, 0,
- 2, 0,175, 0, 2, 0,176, 0, 2, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 7, 0,180, 0, 7, 0,181, 0, 7, 0,182, 0,
- 7, 0,183, 0, 7, 0,184, 0, 7, 0, 57, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,188, 0, 7, 0,189, 0,
- 53, 0, 15, 0, 0, 0,190, 0, 9, 0,191, 0, 0, 0,192, 0, 0, 0,193, 0, 4, 0,194, 0, 4, 0,195, 0, 9, 0,196, 0,
- 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, 4, 0,200, 0, 9, 0,201, 0, 9, 0,202, 0, 4, 0,203, 0, 4, 0, 37, 0,
- 54, 0, 6, 0, 7, 0,180, 0, 7, 0,181, 0, 7, 0,182, 0, 7, 0,204, 0, 7, 0, 67, 0, 4, 0, 64, 0, 55, 0, 5, 0,
- 2, 0, 19, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0,205, 0, 54, 0,199, 0, 56, 0, 17, 0, 32, 0,164, 0, 47, 0,206, 0,
- 57, 0,207, 0, 7, 0,208, 0, 7, 0,209, 0, 2, 0, 17, 0, 2, 0,210, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,211, 0,
- 4, 0,212, 0, 2, 0,213, 0, 2, 0,214, 0, 4, 0,129, 0, 4, 0,140, 0, 2, 0,215, 0, 2, 0,216, 0, 52, 0, 59, 0,
- 27, 0, 31, 0, 39, 0, 75, 0, 7, 0,217, 0, 7, 0,218, 0, 7, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0, 7, 0,222, 0,
- 7, 0,223, 0, 7, 0,224, 0, 7, 0,225, 0, 7, 0,226, 0, 7, 0,227, 0, 7, 0,228, 0, 7, 0,229, 0, 7, 0,230, 0,
- 7, 0,231, 0, 7, 0,232, 0, 7, 0,233, 0, 7, 0,234, 0, 7, 0,235, 0, 7, 0,236, 0, 2, 0,237, 0, 2, 0,238, 0,
- 2, 0,239, 0, 2, 0,240, 0, 2, 0,241, 0, 2, 0,242, 0, 2, 0,243, 0, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,210, 0,
- 7, 0,244, 0, 7, 0,245, 0, 7, 0,246, 0, 7, 0,247, 0, 4, 0,248, 0, 4, 0,249, 0, 2, 0,250, 0, 2, 0,251, 0,
- 2, 0,252, 0, 2, 0,127, 0, 4, 0, 23, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 7, 0,253, 0, 7, 0,254, 0,
- 7, 0,186, 0, 45, 0,255, 0, 58, 0, 0, 1, 36, 0, 80, 0, 47, 0,206, 0, 53, 0, 1, 1, 55, 0, 2, 1, 56, 0, 3, 1,
- 30, 0,150, 0, 0, 0, 4, 1, 0, 0, 5, 1, 59, 0, 8, 0, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0,172, 0, 4, 0, 19, 0,
- 7, 0, 8, 1, 7, 0, 9, 1, 7, 0, 10, 1, 32, 0, 45, 0, 60, 0, 82, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0,
- 2, 0, 19, 0, 4, 0, 11, 1, 2, 0,174, 0, 2, 0, 12, 1, 7, 0,180, 0, 7, 0,181, 0, 7, 0,182, 0, 7, 0,183, 0,
- 7, 0, 13, 1, 7, 0, 14, 1, 7, 0, 15, 1, 7, 0, 16, 1, 7, 0, 17, 1, 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1,
- 7, 0, 21, 1, 7, 0, 22, 1, 7, 0, 23, 1, 61, 0, 24, 1, 2, 0, 25, 1, 2, 0, 70, 0, 7, 0,110, 0, 7, 0,111, 0,
- 7, 0, 26, 1, 7, 0, 27, 1, 7, 0, 28, 1, 2, 0, 29, 1, 2, 0, 30, 1, 2, 0, 31, 1, 2, 0, 32, 1, 0, 0, 33, 1,
- 0, 0, 34, 1, 2, 0, 35, 1, 2, 0, 36, 1, 2, 0, 37, 1, 2, 0, 38, 1, 2, 0, 39, 1, 7, 0, 40, 1, 7, 0, 41, 1,
- 7, 0, 42, 1, 7, 0, 43, 1, 2, 0, 44, 1, 2, 0, 43, 0, 2, 0, 45, 1, 2, 0, 46, 1, 2, 0, 47, 1, 2, 0, 48, 1,
- 7, 0, 49, 1, 7, 0, 50, 1, 7, 0, 51, 1, 7, 0, 52, 1, 7, 0, 53, 1, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1,
- 7, 0, 57, 1, 7, 0, 58, 1, 7, 0, 59, 1, 7, 0, 60, 1, 2, 0, 61, 1, 2, 0, 62, 1, 4, 0, 63, 1, 4, 0, 64, 1,
- 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 67, 1, 2, 0, 68, 1, 7, 0, 69, 1, 7, 0, 70, 1, 7, 0, 71, 1, 7, 0, 72, 1,
- 2, 0, 73, 1, 2, 0, 74, 1, 36, 0, 80, 0, 51, 0, 75, 1, 2, 0, 76, 1, 2, 0, 77, 1, 30, 0,150, 0, 62, 0, 2, 0,
- 27, 0, 31, 0, 36, 0, 80, 0, 63, 0,129, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 78, 1, 2, 0, 19, 0, 7, 0,180, 0,
- 7, 0,181, 0, 7, 0,182, 0, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1, 7, 0, 84, 1,
- 7, 0, 85, 1, 7, 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 7, 0, 89, 1, 7, 0, 90, 1, 7, 0, 91, 1, 7, 0, 92, 1,
- 7, 0, 93, 1, 7, 0, 94, 1, 7, 0, 95, 1, 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, 7, 0,100, 1,
- 7, 0,101, 1, 7, 0,102, 1, 7, 0,103, 1, 7, 0,104, 1, 7, 0,105, 1, 2, 0,106, 1, 2, 0,107, 1, 2, 0,108, 1,
- 0, 0,109, 1, 0, 0,110, 1, 7, 0,111, 1, 7, 0,112, 1, 2, 0,113, 1, 2, 0,114, 1, 7, 0,115, 1, 7, 0,116, 1,
- 7, 0,117, 1, 7, 0,118, 1, 2, 0,119, 1, 2, 0,120, 1, 4, 0, 11, 1, 4, 0,121, 1, 2, 0,122, 1, 2, 0,123, 1,
- 2, 0,124, 1, 2, 0,125, 1, 7, 0,126, 1, 7, 0,127, 1, 7, 0,128, 1, 7, 0,129, 1, 7, 0,130, 1, 7, 0,131, 1,
- 7, 0,132, 1, 7, 0,133, 1, 7, 0,134, 1, 7, 0,135, 1, 0, 0,136, 1, 7, 0,137, 1, 7, 0,138, 1, 7, 0,139, 1,
- 4, 0,140, 1, 0, 0,141, 1, 0, 0, 45, 1, 0, 0,142, 1, 0, 0, 4, 1, 2, 0,143, 1, 2, 0,144, 1, 2, 0, 76, 1,
- 2, 0,145, 1, 2, 0,146, 1, 2, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, 7, 0,150, 1, 7, 0,151, 1, 7, 0,152, 1,
- 2, 0,160, 0, 2, 0,161, 0, 55, 0,153, 1, 55, 0,154, 1, 0, 0,155, 1, 0, 0,156, 1, 0, 0,157, 1, 0, 0,158, 1,
- 2, 0,159, 1, 2, 0,160, 1, 7, 0,161, 1, 7, 0,162, 1, 51, 0, 75, 1, 58, 0, 0, 1, 36, 0, 80, 0, 64, 0,163, 1,
- 30, 0,150, 0, 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1, 7, 0,167, 1, 7, 0,168, 1, 2, 0,169, 1, 2, 0, 70, 0,
- 7, 0,170, 1, 7, 0,171, 1, 7, 0,172, 1, 7, 0,173, 1, 7, 0,174, 1, 7, 0,175, 1, 7, 0,176, 1, 7, 0,177, 1,
- 7, 0,178, 1, 2, 0,179, 1, 2, 0,180, 1, 7, 0,181, 1, 7, 0,182, 1, 7, 0,183, 1, 7, 0,184, 1, 7, 0,185, 1,
- 4, 0,186, 1, 4, 0,187, 1, 4, 0,188, 1, 12, 0,189, 1, 65, 0, 4, 0, 27, 0, 31, 0, 0, 0,190, 1, 66, 0, 2, 0,
- 43, 0,149, 0, 67, 0, 26, 0, 67, 0, 0, 0, 67, 0, 1, 0, 68, 0,191, 1, 4, 0,192, 1, 4, 0,193, 1, 4, 0,194, 1,
- 4, 0,195, 1, 4, 0,196, 1, 4, 0,197, 1, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,198, 1, 2, 0,199, 1, 7, 0, 5, 0,
- 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,200, 1, 7, 0,201, 1, 7, 0,202, 1, 7, 0,203, 1, 7, 0,204, 1, 7, 0,205, 1,
- 7, 0,206, 1, 7, 0, 23, 0, 7, 0,207, 1, 7, 0,208, 1, 69, 0, 17, 0, 27, 0, 31, 0, 68, 0,191, 1, 12, 0,209, 1,
- 12, 0,210, 1, 12, 0,211, 1, 36, 0, 80, 0, 63, 0,212, 1, 2, 0, 19, 0, 2, 0,213, 1, 4, 0,173, 0, 7, 0, 6, 1,
- 7, 0,172, 0, 7, 0, 7, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 67, 0,217, 1, 35, 0, 11, 0, 7, 0,218, 1,
- 7, 0,219, 1, 7, 0,220, 1, 7, 0,221, 1, 2, 0, 55, 0, 0, 0,222, 1, 0, 0,223, 1, 0, 0,224, 1, 0, 0,225, 1,
- 0, 0,226, 1, 0, 0,227, 1, 34, 0, 7, 0, 7, 0,228, 1, 7, 0,219, 1, 7, 0,220, 1, 2, 0,224, 1, 2, 0,227, 1,
- 7, 0,221, 1, 7, 0, 37, 0, 70, 0, 21, 0, 70, 0, 0, 0, 70, 0, 1, 0, 2, 0, 17, 0, 2, 0,229, 1, 2, 0,227, 1,
- 2, 0, 19, 0, 2, 0,230, 1, 2, 0,231, 1, 2, 0,232, 1, 2, 0,233, 1, 2, 0,234, 1, 2, 0,235, 1, 2, 0,236, 1,
- 2, 0,237, 1, 7, 0,238, 1, 7, 0,239, 1, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0,240, 1, 2, 0,241, 1, 4, 0,242, 1,
- 71, 0, 5, 0, 2, 0,243, 1, 2, 0,229, 1, 0, 0, 19, 0, 0, 0, 37, 0, 2, 0, 70, 0, 72, 0, 4, 0, 7, 0, 5, 0,
- 7, 0, 6, 0, 7, 0, 8, 0, 7, 0,244, 1, 73, 0, 62, 0, 27, 0, 31, 0, 39, 0, 75, 0, 68, 0,191, 1, 12, 0,245, 1,
- 12, 0,210, 1, 12, 0,246, 1, 32, 0,247, 1, 32, 0,248, 1, 32, 0,249, 1, 36, 0, 80, 0, 74, 0,250, 1, 38, 0,251, 1,
- 63, 0,212, 1, 12, 0,252, 1, 7, 0, 6, 1, 7, 0,172, 0, 7, 0, 7, 1, 4, 0,173, 0, 2, 0,253, 1, 2, 0,213, 1,
- 2, 0, 19, 0, 2, 0,254, 1, 7, 0,255, 1, 7, 0, 0, 2, 7, 0, 1, 2, 2, 0,232, 1, 2, 0,233, 1, 2, 0, 2, 2,
- 2, 0, 3, 2, 4, 0, 4, 2, 34, 0, 5, 2, 2, 0, 23, 0, 2, 0, 95, 0, 2, 0, 67, 0, 2, 0, 6, 2, 7, 0, 7, 2,
- 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 7, 0, 11, 2, 7, 0, 12, 2, 7, 0, 13, 2, 7, 0, 14, 2, 7, 0, 15, 2,
- 7, 0, 16, 2, 0, 0, 17, 2, 75, 0, 18, 2, 76, 0, 19, 2, 0, 0, 20, 2, 65, 0, 21, 2, 65, 0, 22, 2, 65, 0, 23, 2,
- 65, 0, 24, 2, 4, 0, 25, 2, 7, 0, 26, 2, 4, 0, 27, 2, 4, 0, 28, 2, 72, 0, 29, 2, 4, 0, 30, 2, 4, 0, 31, 2,
- 71, 0, 32, 2, 71, 0, 33, 2, 77, 0, 39, 0, 27, 0, 31, 0, 68, 0,191, 1, 12, 0, 34, 2, 36, 0, 80, 0, 38, 0,251, 1,
- 63, 0,212, 1, 78, 0, 35, 2, 79, 0, 36, 2, 80, 0, 37, 2, 81, 0, 38, 2, 82, 0, 39, 2, 83, 0, 40, 2, 84, 0, 41, 2,
- 85, 0, 42, 2, 77, 0, 43, 2, 86, 0, 44, 2, 87, 0, 45, 2, 88, 0, 46, 2, 88, 0, 47, 2, 88, 0, 48, 2, 4, 0, 54, 0,
- 4, 0, 49, 2, 4, 0, 50, 2, 4, 0, 51, 2, 4, 0, 52, 2, 4, 0,173, 0, 7, 0, 6, 1, 7, 0,172, 0, 7, 0, 7, 1,
- 7, 0, 53, 2, 4, 0, 54, 2, 2, 0, 55, 2, 2, 0, 19, 0, 2, 0, 56, 2, 2, 0, 57, 2, 2, 0,213, 1, 2, 0, 58, 2,
- 89, 0, 59, 2, 90, 0, 60, 2, 80, 0, 8, 0, 9, 0, 61, 2, 7, 0, 62, 2, 4, 0, 63, 2, 0, 0, 19, 0, 0, 0, 64, 2,
- 2, 0, 11, 1, 2, 0, 65, 2, 2, 0, 66, 2, 78, 0, 7, 0, 4, 0, 67, 2, 4, 0, 68, 2, 4, 0, 69, 2, 4, 0, 70, 2,
- 2, 0,229, 1, 0, 0, 71, 2, 0, 0, 19, 0, 82, 0, 5, 0, 4, 0, 67, 2, 4, 0, 68, 2, 0, 0, 72, 2, 0, 0, 73, 2,
- 2, 0, 19, 0, 91, 0, 2, 0, 4, 0, 74, 2, 7, 0,220, 1, 83, 0, 3, 0, 91, 0, 75, 2, 4, 0, 76, 2, 4, 0, 19, 0,
- 81, 0, 6, 0, 7, 0, 77, 2, 2, 0, 78, 2, 2, 0,229, 1, 0, 0, 19, 0, 0, 0, 73, 2, 0, 0,179, 0, 84, 0, 4, 0,
- 0, 0,204, 0, 0, 0,180, 0, 0, 0,181, 0, 0, 0,182, 0, 92, 0, 6, 0, 47, 0, 61, 2, 0, 0, 19, 0, 0, 0, 64, 2,
- 2, 0, 11, 1, 2, 0, 65, 2, 2, 0, 66, 2, 93, 0, 1, 0, 7, 0, 79, 2, 94, 0, 5, 0, 0, 0,204, 0, 0, 0,180, 0,
- 0, 0,181, 0, 0, 0,182, 0, 4, 0, 37, 0, 85, 0, 1, 0, 7, 0, 80, 2, 86, 0, 2, 0, 4, 0, 81, 2, 4, 0, 17, 0,
- 79, 0, 7, 0, 7, 0, 62, 2, 47, 0, 61, 2, 0, 0, 19, 0, 0, 0, 64, 2, 2, 0, 11, 1, 2, 0, 65, 2, 2, 0, 66, 2,
- 95, 0, 1, 0, 7, 0, 82, 2, 96, 0, 1, 0, 4, 0, 83, 2, 97, 0, 1, 0, 0, 0, 84, 2, 98, 0, 1, 0, 7, 0, 62, 2,
- 99, 0, 3, 0, 4, 0, 85, 2, 0, 0, 92, 0, 7, 0, 86, 2,101, 0, 4, 0, 7, 0,204, 0, 7, 0,180, 0, 7, 0,181, 0,
- 7, 0,182, 0,102, 0, 1, 0,101, 0, 63, 2,103, 0, 5, 0, 4, 0, 87, 2, 4, 0, 88, 2, 0, 0, 19, 0, 0, 0,229, 1,
- 0, 0,179, 0,104, 0, 2, 0, 4, 0, 89, 2, 4, 0, 88, 2,105, 0, 10, 0,105, 0, 0, 0,105, 0, 1, 0,103, 0, 90, 2,
-102, 0, 91, 2,104, 0, 92, 2, 4, 0, 54, 0, 4, 0, 50, 2, 4, 0, 49, 2, 4, 0, 37, 0, 81, 0, 93, 2, 89, 0, 14, 0,
- 12, 0, 94, 2, 81, 0, 93, 2, 0, 0, 95, 2, 0, 0, 96, 2, 0, 0, 97, 2, 0, 0, 98, 2, 0, 0, 99, 2, 0, 0,100, 2,
- 0, 0,101, 2, 0, 0, 19, 0, 88, 0, 46, 2, 88, 0, 48, 2, 2, 0,102, 2, 0, 0,103, 2, 90, 0, 8, 0, 4, 0,104, 2,
- 4, 0,105, 2, 78, 0,106, 2, 82, 0,107, 2, 4, 0, 50, 2, 4, 0, 49, 2, 4, 0, 54, 0, 4, 0, 37, 0,106, 0, 7, 0,
-106, 0, 0, 0,106, 0, 1, 0, 4, 0, 17, 0, 4, 0, 11, 1, 0, 0, 20, 0, 46, 0,134, 0, 0, 0,108, 2,107, 0, 7, 0,
-106, 0,109, 2, 2, 0,110, 2, 2, 0, 94, 2, 2, 0,111, 2, 2, 0, 90, 0, 9, 0,112, 2, 9, 0,113, 2,108, 0, 3, 0,
-106, 0,109, 2, 32, 0,164, 0, 0, 0, 20, 0,109, 0, 5, 0,106, 0,109, 2, 32, 0,164, 0, 0, 0, 20, 0, 2, 0,114, 2,
- 0, 0,115, 2,110, 0, 5, 0,106, 0,109, 2, 7, 0, 88, 0, 7, 0,116, 2, 4, 0,117, 2, 4, 0,118, 2,111, 0, 5, 0,
-106, 0,109, 2, 32, 0,119, 2, 0, 0, 72, 0, 4, 0, 11, 1, 4, 0, 19, 0,112, 0, 13, 0,106, 0,109, 2, 32, 0,120, 2,
- 32, 0,121, 2, 32, 0,122, 2, 32, 0,123, 2, 7, 0,124, 2, 7, 0,125, 2, 7, 0,116, 2, 7, 0,126, 2, 4, 0,127, 2,
- 4, 0,128, 2, 4, 0, 90, 0, 4, 0,129, 2,113, 0, 5, 0,106, 0,109, 2, 2, 0,130, 2, 2, 0, 19, 0, 7, 0,131, 2,
- 32, 0,132, 2,114, 0, 3, 0,106, 0,109, 2, 7, 0,133, 2, 4, 0, 90, 0,115, 0, 10, 0,106, 0,109, 2, 7, 0,134, 2,
- 4, 0,135, 2, 4, 0, 37, 0, 2, 0, 90, 0, 2, 0,136, 2, 2, 0,137, 2, 2, 0,138, 2, 7, 0,139, 2, 0, 0,140, 2,
-116, 0, 3, 0,106, 0,109, 2, 7, 0, 37, 0, 4, 0, 17, 0,117, 0, 11, 0,106, 0,109, 2, 52, 0,141, 2, 7, 0,142, 2,
- 4, 0,143, 2, 0, 0,140, 2, 7, 0,144, 2, 4, 0,145, 2, 32, 0,146, 2, 0, 0,147, 2, 4, 0,148, 2, 4, 0, 37, 0,
-118, 0, 10, 0,106, 0,109, 2, 32, 0,149, 2, 47, 0,150, 2, 4, 0, 90, 0, 4, 0,151, 2, 7, 0,152, 2, 7, 0,153, 2,
- 0, 0,147, 2, 4, 0,148, 2, 4, 0, 37, 0,119, 0, 3, 0,106, 0,109, 2, 7, 0,154, 2, 4, 0,155, 2,120, 0, 5, 0,
-106, 0,109, 2, 7, 0,156, 2, 0, 0,140, 2, 2, 0, 19, 0, 2, 0,157, 2,121, 0, 8, 0,106, 0,109, 2, 32, 0,164, 0,
- 7, 0,156, 2, 7, 0,221, 1, 7, 0,106, 0, 0, 0,140, 2, 2, 0, 19, 0, 2, 0, 17, 0,122, 0, 21, 0,106, 0,109, 2,
- 32, 0,158, 2, 0, 0,140, 2, 52, 0,141, 2, 32, 0,146, 2, 2, 0, 19, 0, 2, 0, 37, 0, 7, 0,159, 2, 7, 0,160, 2,
- 7, 0,161, 2, 7, 0,255, 1, 7, 0,162, 2, 7, 0,163, 2, 7, 0,164, 2, 7, 0,165, 2, 4, 0,145, 2, 4, 0,148, 2,
- 0, 0,147, 2, 7, 0,166, 2, 7, 0,167, 2, 7, 0, 43, 0,123, 0, 7, 0,106, 0,109, 2, 2, 0,168, 2, 2, 0,169, 2,
- 4, 0, 70, 0, 32, 0,164, 0, 7, 0,170, 2, 0, 0,140, 2,124, 0, 9, 0,106, 0,109, 2, 32, 0,164, 0, 7, 0,171, 2,
- 7, 0,172, 2, 7, 0,165, 2, 4, 0,173, 2, 4, 0,174, 2, 7, 0,175, 2, 0, 0, 20, 0,125, 0, 1, 0,106, 0,109, 2,
-126, 0, 6, 0,106, 0,109, 2, 46, 0,134, 0,127, 0,176, 2,128, 0,177, 2,129, 0,178, 2,130, 0,179, 2,131, 0, 14, 0,
-106, 0,109, 2, 81, 0,180, 2, 81, 0,181, 2, 81, 0,182, 2, 81, 0,183, 2, 81, 0,184, 2, 81, 0,185, 2, 78, 0,186, 2,
- 4, 0,187, 2, 4, 0,188, 2, 2, 0,189, 2, 2, 0, 37, 0, 7, 0,190, 2,132, 0,191, 2,133, 0, 7, 0,106, 0,109, 2,
- 81, 0,180, 2, 81, 0,192, 2,134, 0,193, 2,135, 0,191, 2, 4, 0,194, 2, 4, 0,187, 2,136, 0, 4, 0,106, 0,109, 2,
- 32, 0,164, 0, 4, 0,195, 2, 4, 0, 37, 0,137, 0, 2, 0, 4, 0,196, 2, 7, 0,220, 1,138, 0, 2, 0, 4, 0,125, 0,
- 4, 0,197, 2,139, 0, 20, 0,106, 0,109, 2, 32, 0,164, 0, 0, 0,140, 2, 2, 0,198, 2, 2, 0,199, 2, 2, 0, 19, 0,
- 2, 0, 37, 0, 7, 0,200, 2, 7, 0,201, 2, 4, 0, 54, 0, 4, 0,202, 2,138, 0,203, 2,137, 0,204, 2, 4, 0,205, 2,
- 4, 0,206, 2, 4, 0,207, 2, 4, 0,197, 2, 7, 0,208, 2, 7, 0,209, 2, 7, 0,210, 2,140, 0, 8, 0,106, 0,109, 2,
-141, 0,211, 2,134, 0,193, 2, 4, 0,212, 2, 4, 0,213, 2, 4, 0,214, 2, 2, 0, 19, 0, 2, 0, 57, 0,142, 0, 8, 0,
-106, 0,109, 2, 32, 0, 45, 0, 2, 0,215, 2, 2, 0, 19, 0, 2, 0,130, 2, 2, 0, 57, 0, 7, 0,216, 2, 7, 0,217, 2,
-143, 0, 5, 0,106, 0,109, 2, 4, 0,218, 2, 2, 0, 19, 0, 2, 0,219, 2, 7, 0,220, 2,144, 0, 7, 0,106, 0,109, 2,
- 81, 0,221, 2, 4, 0,222, 2, 0, 0,223, 2, 0, 0,224, 2, 0, 0,225, 2, 0, 0,226, 2,145, 0, 3, 0,106, 0,109, 2,
-146, 0,227, 2,130, 0,179, 2,147, 0, 10, 0,106, 0,109, 2, 32, 0,228, 2, 32, 0,229, 2, 0, 0,230, 2, 7, 0,231, 2,
- 2, 0,232, 2, 2, 0,233, 2, 0, 0,234, 2, 0, 0,235, 2, 0, 0,115, 2,148, 0, 9, 0,106, 0,109, 2, 32, 0,236, 2,
- 0, 0,230, 2, 7, 0,237, 2, 7, 0,238, 2, 0, 0, 11, 1, 0, 0,130, 2, 0, 0,239, 2, 0, 0, 37, 0,149, 0, 27, 0,
- 27, 0, 31, 0, 2, 0,230, 1, 2, 0,231, 1, 2, 0,240, 2, 2, 0, 19, 0, 2, 0,241, 2, 2, 0,242, 2, 2, 0,243, 2,
- 2, 0, 70, 0, 0, 0,244, 2, 0, 0,245, 2, 0, 0,246, 2, 0, 0, 17, 0, 4, 0, 37, 0, 7, 0,247, 2, 7, 0,248, 2,
- 7, 0,249, 2, 7, 0,250, 2, 7, 0,251, 2, 7, 0,252, 2, 34, 0,253, 2, 36, 0, 80, 0, 38, 0,251, 1, 83, 0, 40, 2,
- 7, 0,254, 2, 7, 0,255, 2,149, 0, 0, 3,150, 0, 3, 0,150, 0, 0, 0,150, 0, 1, 0, 0, 0, 20, 0, 68, 0, 3, 0,
- 7, 0, 1, 3, 4, 0, 19, 0, 4, 0, 37, 0, 32, 0,111, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 2, 3,
- 4, 0, 3, 3, 4, 0, 4, 3, 4, 0, 5, 3, 0, 0, 6, 3, 32, 0, 38, 0, 32, 0, 7, 3, 32, 0, 8, 3, 32, 0, 9, 3,
- 32, 0, 10, 3, 36, 0, 80, 0, 74, 0,250, 1, 68, 0,191, 1,151, 0, 11, 3,151, 0, 12, 3,152, 0, 13, 3, 9, 0, 2, 0,
- 12, 0, 14, 3, 12, 0, 34, 2, 12, 0,210, 1, 12, 0, 15, 3, 12, 0, 16, 3, 63, 0,212, 1, 0, 0, 17, 3, 4, 0,213, 1,
- 4, 0, 18, 3, 7, 0, 6, 1, 7, 0, 19, 3, 7, 0, 20, 3, 7, 0,172, 0, 7, 0, 21, 3, 7, 0, 7, 1, 7, 0, 22, 3,
- 7, 0, 23, 3, 7, 0,171, 2, 7, 0, 24, 3, 7, 0,208, 0, 4, 0, 25, 3, 2, 0, 19, 0, 2, 0, 26, 3, 2, 0, 27, 3,
- 2, 0, 28, 3, 2, 0, 29, 3, 2, 0, 30, 3, 2, 0, 31, 3, 2, 0, 32, 3, 2, 0, 33, 3, 2, 0, 34, 3, 2, 0, 35, 3,
- 2, 0, 36, 3, 4, 0, 37, 3, 4, 0, 38, 3, 4, 0, 39, 3, 4, 0, 40, 3, 7, 0, 41, 3, 7, 0, 26, 2, 7, 0, 42, 3,
- 7, 0, 43, 3, 7, 0, 44, 3, 7, 0, 45, 3, 7, 0, 46, 3, 7, 0, 47, 3, 7, 0, 48, 3, 7, 0, 49, 3, 7, 0, 50, 3,
- 7, 0, 51, 3, 0, 0, 52, 3, 0, 0, 53, 3, 0, 0, 54, 3, 0, 0, 55, 3, 7, 0, 56, 3, 7, 0, 57, 3, 12, 0, 58, 3,
- 12, 0, 59, 3, 12, 0, 60, 3, 12, 0, 61, 3, 7, 0, 62, 3, 2, 0, 81, 2, 2, 0, 63, 3, 7, 0, 63, 2, 4, 0, 64, 3,
- 4, 0, 65, 3,153, 0, 66, 3, 2, 0, 67, 3, 2, 0,215, 0, 7, 0, 68, 3, 12, 0, 69, 3, 12, 0, 70, 3, 12, 0, 71, 3,
- 12, 0, 72, 3,154, 0, 73, 3,155, 0, 74, 3, 64, 0, 75, 3, 2, 0, 76, 3, 2, 0, 77, 3, 2, 0, 78, 3, 2, 0, 79, 3,
- 7, 0, 55, 2, 2, 0, 80, 3, 2, 0, 81, 3,146, 0, 82, 3,134, 0, 83, 3,134, 0, 84, 3, 4, 0, 85, 3, 4, 0, 86, 3,
- 4, 0, 87, 3, 4, 0, 70, 0, 12, 0, 88, 3,156, 0, 14, 0,156, 0, 0, 0,156, 0, 1, 0, 32, 0, 38, 0, 7, 0,171, 2,
- 7, 0, 8, 1, 7, 0,172, 2, 7, 0,165, 2, 0, 0, 20, 0, 4, 0,173, 2, 4, 0,174, 2, 4, 0, 89, 3, 2, 0, 17, 0,
- 2, 0, 90, 3, 7, 0,175, 2,154, 0, 36, 0, 2, 0, 91, 3, 2, 0, 92, 3, 2, 0, 19, 0, 2, 0,165, 2, 7, 0, 93, 3,
- 7, 0, 94, 3, 7, 0, 95, 3, 7, 0, 96, 3, 7, 0, 97, 3, 7, 0, 98, 3, 7, 0, 99, 3, 7, 0,100, 3, 7, 0,101, 3,
- 7, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 7, 0,105, 3, 7, 0,106, 3, 7, 0,107, 3, 7, 0,108, 3, 7, 0,109, 3,
- 7, 0,110, 3, 7, 0,111, 3, 7, 0,112, 3, 7, 0,113, 3, 7, 0,114, 3, 7, 0,115, 3, 7, 0,116, 3, 2, 0,117, 3,
- 2, 0,118, 3, 2, 0,119, 3, 2, 0,120, 3, 52, 0,165, 0,157, 0,121, 3, 7, 0,122, 3, 4, 0,118, 2,158, 0, 6, 0,
-158, 0, 0, 0,158, 0, 1, 0, 4, 0,123, 3, 4, 0,124, 3, 7, 0, 2, 0, 9, 0,125, 3,130, 0, 15, 0, 4, 0, 19, 0,
- 4, 0,126, 3, 4, 0,127, 3, 4, 0,128, 3, 4, 0,129, 3, 4, 0,130, 3, 4, 0,131, 3, 4, 0,124, 3, 4, 0, 81, 2,
- 4, 0, 57, 0, 0, 0,132, 3, 0, 0,133, 3, 0, 0,134, 3, 0, 0,135, 3, 12, 0,136, 3,159, 0, 1, 0, 7, 0,228, 1,
-153, 0, 30, 0, 4, 0, 19, 0, 7, 0,137, 3, 7, 0,138, 3, 7, 0,139, 3, 4, 0,140, 3, 4, 0,141, 3, 4, 0,142, 3,
- 4, 0,143, 3, 7, 0,144, 3, 7, 0,145, 3, 7, 0,146, 3, 7, 0,147, 3, 7, 0,148, 3, 7, 0,149, 3, 7, 0,150, 3,
- 7, 0,151, 3, 7, 0,152, 3, 7, 0,153, 3, 7, 0,154, 3, 7, 0,155, 3, 7, 0,156, 3, 7, 0,157, 3, 7, 0,158, 3,
- 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, 4, 0,162, 3, 4, 0,163, 3, 7, 0,164, 3, 7, 0, 48, 3,155, 0, 49, 0,
-141, 0,165, 3, 4, 0,124, 3, 4, 0,166, 3,160, 0,167, 3,161, 0,168, 3, 0, 0, 37, 0, 0, 0,169, 3, 2, 0,170, 3,
- 7, 0,171, 3, 0, 0,172, 3, 7, 0,173, 3, 7, 0,174, 3, 7, 0,175, 3, 7, 0,176, 3, 7, 0,177, 3, 7, 0,178, 3,
- 7, 0,179, 3, 7, 0,180, 3, 7, 0,181, 3, 2, 0,182, 3, 0, 0,183, 3, 2, 0,184, 3, 7, 0,185, 3, 7, 0,186, 3,
- 0, 0,187, 3, 4, 0,126, 0, 4, 0,188, 3, 4, 0,189, 3, 2, 0,190, 3, 2, 0,191, 3,159, 0,192, 3, 4, 0,193, 3,
- 4, 0, 82, 0, 7, 0,194, 3, 7, 0,195, 3, 7, 0,196, 3, 7, 0,197, 3, 2, 0,198, 3, 2, 0,199, 3, 2, 0,200, 3,
- 2, 0,201, 3, 2, 0,202, 3, 2, 0,203, 3, 2, 0,204, 3, 2, 0,205, 3,162, 0,206, 3, 7, 0,207, 3, 7, 0,208, 3,
-130, 0,209, 3,146, 0, 48, 0, 2, 0, 17, 0, 2, 0,210, 3, 2, 0,211, 3, 2, 0,212, 3, 7, 0,213, 3, 2, 0,214, 3,
- 2, 0,215, 3, 7, 0,216, 3, 2, 0,217, 3, 2, 0,218, 3, 7, 0,219, 3, 7, 0,220, 3, 7, 0,221, 3, 7, 0,222, 3,
- 7, 0,223, 3, 7, 0,224, 3, 4, 0,225, 3, 7, 0,226, 3, 7, 0,227, 3, 7, 0,228, 3, 77, 0,229, 3, 77, 0,230, 3,
- 77, 0,231, 3, 0, 0,232, 3, 7, 0,233, 3, 7, 0,234, 3, 36, 0, 80, 0, 2, 0,235, 3, 0, 0,236, 3, 0, 0,237, 3,
- 7, 0,238, 3, 4, 0,239, 3, 7, 0,240, 3, 7, 0,241, 3, 4, 0,242, 3, 4, 0, 19, 0, 7, 0,243, 3, 7, 0,244, 3,
- 7, 0,245, 3, 81, 0,246, 3, 7, 0,247, 3, 7, 0,248, 3, 7, 0,249, 3, 7, 0,250, 3, 7, 0,251, 3, 7, 0,252, 3,
- 7, 0,253, 3, 4, 0,254, 3,163, 0, 73, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,174, 0, 2, 0, 12, 1, 2, 0, 45, 1,
- 2, 0,255, 3, 7, 0, 0, 4, 7, 0, 1, 4, 7, 0, 2, 4, 7, 0, 3, 4, 7, 0, 4, 4, 7, 0, 5, 4, 7, 0, 6, 4,
- 7, 0, 7, 4, 7, 0, 85, 1, 7, 0, 87, 1, 7, 0, 86, 1, 7, 0, 8, 4, 4, 0, 9, 4, 7, 0, 10, 4, 7, 0, 11, 4,
- 7, 0, 12, 4, 7, 0, 13, 4, 7, 0, 14, 4, 7, 0, 15, 4, 7, 0, 16, 4, 2, 0, 17, 4, 2, 0, 11, 1, 2, 0, 18, 4,
- 2, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 2, 0, 22, 4, 2, 0, 23, 4, 7, 0, 24, 4, 7, 0, 25, 4, 7, 0, 26, 4,
- 7, 0, 27, 4, 7, 0, 28, 4, 7, 0, 29, 4, 7, 0, 30, 4, 7, 0, 31, 4, 7, 0, 32, 4, 7, 0, 33, 4, 7, 0, 34, 4,
- 7, 0, 35, 4, 2, 0, 36, 4, 2, 0, 37, 4, 2, 0, 38, 4, 2, 0, 39, 4, 7, 0, 40, 4, 7, 0, 41, 4, 7, 0, 42, 4,
- 7, 0, 43, 4, 2, 0, 44, 4, 2, 0, 45, 4, 2, 0, 46, 4, 2, 0, 47, 4, 7, 0, 48, 4, 7, 0, 49, 4, 7, 0, 50, 4,
- 7, 0, 51, 4, 2, 0, 52, 4, 2, 0, 53, 4, 2, 0, 54, 4, 2, 0, 19, 0, 7, 0, 55, 4, 7, 0, 56, 4, 36, 0, 80, 0,
- 51, 0, 75, 1, 2, 0, 76, 1, 2, 0, 77, 1, 30, 0,150, 0,164, 0, 8, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0, 25, 3,
- 4, 0, 57, 4, 4, 0, 19, 0, 2, 0, 58, 4, 2, 0, 59, 4, 32, 0,164, 0,165, 0, 13, 0, 9, 0, 60, 4, 9, 0, 61, 4,
- 4, 0, 62, 4, 4, 0, 63, 4, 4, 0, 64, 4, 4, 0, 65, 4, 4, 0, 66, 4, 4, 0, 67, 4, 4, 0, 68, 4, 4, 0, 69, 4,
- 4, 0, 70, 4, 4, 0, 37, 0, 0, 0, 71, 4,166, 0, 5, 0, 9, 0, 72, 4, 9, 0, 73, 4, 4, 0, 74, 4, 4, 0, 70, 0,
- 0, 0, 75, 4,167, 0, 13, 0, 4, 0, 17, 0, 4, 0, 76, 4, 4, 0, 77, 4, 4, 0, 78, 4, 4, 0, 79, 4, 4, 0, 80, 4,
- 4, 0, 90, 0, 4, 0, 81, 4, 4, 0, 82, 4, 4, 0, 83, 4, 4, 0, 84, 4, 4, 0, 85, 4, 26, 0, 30, 0,168, 0, 4, 0,
- 4, 0, 86, 4, 7, 0, 87, 4, 2, 0, 19, 0, 2, 0, 77, 1,169, 0, 11, 0,169, 0, 0, 0,169, 0, 1, 0, 0, 0, 20, 0,
- 63, 0, 88, 4, 64, 0, 89, 4, 4, 0, 25, 3, 4, 0, 90, 4, 4, 0, 91, 4, 4, 0, 37, 0, 4, 0, 92, 4, 4, 0, 93, 4,
-170, 0,132, 0,165, 0, 94, 4,166, 0, 95, 4,167, 0, 96, 4,168, 0, 97, 4, 4, 0,194, 2, 4, 0,126, 0, 4, 0,188, 3,
- 4, 0, 98, 4, 4, 0, 99, 4, 4, 0,100, 4, 4, 0,101, 4, 2, 0, 19, 0, 2, 0,102, 4, 7, 0, 26, 2, 7, 0,103, 4,
- 7, 0,104, 4, 7, 0,105, 4, 7, 0,106, 4, 7, 0,107, 4, 2, 0,108, 4, 2, 0,109, 4, 2, 0,110, 4, 2, 0,111, 4,
- 2, 0,214, 0, 2, 0,112, 4, 2, 0,113, 4, 2, 0,120, 3, 2, 0,114, 4, 2, 0,115, 4, 2, 0, 32, 1, 2, 0,106, 0,
- 2, 0,116, 4, 2, 0,117, 4, 2, 0,118, 4, 2, 0,119, 4, 2, 0,120, 4, 2, 0,121, 4, 2, 0,122, 4, 2, 0,123, 4,
- 2, 0,124, 4, 2, 0, 33, 1, 2, 0,125, 4, 2, 0,126, 4, 2, 0,127, 4, 2, 0,128, 4, 4, 0,129, 4, 4, 0, 11, 1,
- 2, 0,130, 4, 2, 0,131, 4, 2, 0,132, 4, 2, 0,133, 4, 2, 0,134, 4, 2, 0,135, 4, 24, 0,136, 4, 24, 0,137, 4,
- 23, 0,138, 4, 12, 0,139, 4, 2, 0,140, 4, 2, 0, 37, 0, 7, 0,141, 4, 7, 0,142, 4, 7, 0,143, 4, 7, 0,144, 4,
- 4, 0,145, 4, 7, 0,146, 4, 7, 0,147, 4, 7, 0,148, 4, 7, 0,149, 4, 2, 0,150, 4, 2, 0,151, 4, 2, 0,152, 4,
- 2, 0,153, 4, 2, 0,154, 4, 2, 0,155, 4, 7, 0,156, 4, 7, 0,157, 4, 7, 0,158, 4, 2, 0,159, 4, 2, 0,160, 4,
- 2, 0,161, 4, 2, 0,162, 4, 2, 0,163, 4, 2, 0,164, 4, 2, 0,165, 4, 2, 0,166, 4, 2, 0,167, 4, 2, 0,168, 4,
- 4, 0,169, 4, 4, 0,170, 4, 4, 0,171, 4, 4, 0,172, 4, 4, 0,173, 4, 7, 0,174, 4, 4, 0,175, 4, 4, 0,176, 4,
- 4, 0,177, 4, 4, 0,178, 4, 7, 0,179, 4, 7, 0,180, 4, 7, 0,181, 4, 7, 0,182, 4, 7, 0,183, 4, 7, 0,184, 4,
- 7, 0,185, 4, 7, 0,186, 4, 7, 0,187, 4, 0, 0,188, 4, 0, 0,189, 4, 4, 0,190, 4, 2, 0,191, 4, 2, 0,160, 1,
- 0, 0,192, 4, 7, 0,193, 4, 7, 0,194, 4, 4, 0,195, 4, 4, 0,196, 4, 7, 0,197, 4, 7, 0,198, 4, 2, 0,199, 4,
- 2, 0,200, 4, 7, 0,201, 4, 2, 0,202, 4, 2, 0,203, 4, 4, 0,204, 4, 2, 0,205, 4, 2, 0,206, 4, 2, 0,207, 4,
- 2, 0,208, 4, 7, 0,209, 4, 7, 0, 70, 0, 42, 0,210, 4, 0, 0,211, 4,171, 0, 9, 0,171, 0, 0, 0,171, 0, 1, 0,
- 0, 0, 20, 0, 2, 0,212, 4, 2, 0,213, 4, 2, 0,214, 4, 2, 0, 43, 0, 7, 0,215, 4, 7, 0, 70, 0,172, 0, 7, 0,
- 2, 0,135, 2, 2, 0, 11, 1, 2, 0,109, 0, 2, 0,216, 4, 7, 0,217, 4, 7, 0, 70, 0, 42, 0,218, 4,173, 0, 5, 0,
- 7, 0,219, 4, 0, 0, 17, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0,160, 1,174, 0, 24, 0, 7, 0, 15, 4, 7, 0, 16, 4,
- 2, 0, 11, 1, 2, 0,220, 4, 2, 0, 18, 4, 2, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 2, 0, 22, 4, 2, 0, 23, 4,
-173, 0,221, 4, 2, 0,108, 4, 2, 0,109, 4, 2, 0,110, 4, 2, 0,111, 4, 2, 0,214, 0, 2, 0,112, 4, 2, 0,113, 4,
- 2, 0,120, 3,172, 0,222, 4, 2, 0,223, 4, 2, 0,114, 4, 2, 0,117, 4, 2, 0,118, 4,175, 0, 5, 0,175, 0, 0, 0,
-175, 0, 1, 0, 4, 0,123, 3, 0, 0,132, 3, 4, 0, 19, 0,176, 0, 6, 0,177, 0,224, 4, 2, 0, 19, 0, 2, 0,225, 4,
- 2, 0,226, 4, 2, 0,227, 4, 9, 0,228, 4,178, 0, 4, 0, 2, 0,106, 0, 2, 0,142, 2, 2, 0,126, 3, 2, 0,229, 4,
-179, 0, 10, 0, 2, 0, 19, 0, 2, 0,230, 4, 2, 0,231, 4, 2, 0,232, 4,178, 0,233, 4, 9, 0,228, 4, 7, 0,234, 4,
- 4, 0,235, 4, 4, 0,236, 4, 4, 0, 37, 0,180, 0, 4, 0,180, 0, 0, 0,180, 0, 1, 0, 0, 0,237, 4, 7, 0,238, 4,
-181, 0, 8, 0,182, 0,239, 4,177, 0,224, 4, 7, 0,240, 4, 4, 0, 90, 0, 0, 0,241, 4, 0, 0,242, 4, 0, 0,243, 4,
- 0, 0,244, 4,183, 0, 9, 0,177, 0,224, 4, 7, 0,245, 4, 7, 0,246, 4, 2, 0, 11, 1, 2, 0, 19, 0, 4, 0, 36, 0,
- 4, 0,247, 4, 83, 0,248, 4, 9, 0,228, 4,184, 0, 72, 0,183, 0,249, 4,183, 0,250, 4,181, 0,251, 4, 7, 0,252, 4,
- 2, 0,253, 4, 2, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 2, 0,126, 3, 2, 0, 1, 5, 7, 0, 2, 5, 7, 0, 3, 5,
- 7, 0, 4, 5, 2, 0, 5, 5, 2, 0,236, 4, 2, 0, 6, 5, 2, 0, 7, 5, 2, 0, 8, 5, 2, 0, 9, 5, 7, 0, 10, 5,
- 7, 0, 11, 5, 7, 0, 12, 5, 2, 0, 13, 5, 2, 0, 14, 5, 2, 0, 15, 5, 2, 0, 16, 5, 2, 0, 17, 5, 2, 0, 18, 5,
- 2, 0, 19, 5,176, 0, 20, 5,179, 0, 21, 5, 7, 0, 22, 5, 7, 0, 23, 5, 7, 0, 24, 5, 2, 0, 25, 5, 2, 0, 70, 0,
- 0, 0, 26, 5, 0, 0, 27, 5, 0, 0, 28, 5, 0, 0, 29, 5, 0, 0, 30, 5, 0, 0, 31, 5, 2, 0, 32, 5, 7, 0, 33, 5,
- 7, 0, 34, 5, 7, 0, 35, 5, 7, 0, 36, 5, 7, 0, 37, 5, 7, 0, 38, 5, 7, 0, 39, 5, 7, 0, 40, 5, 7, 0, 41, 5,
- 7, 0, 42, 5, 2, 0, 43, 5, 0, 0, 44, 5, 0, 0, 45, 5, 0, 0, 46, 5, 0, 0, 47, 5, 32, 0, 48, 5, 0, 0, 49, 5,
- 0, 0, 50, 5, 0, 0, 51, 5, 0, 0, 52, 5, 0, 0, 53, 5, 0, 0, 54, 5, 0, 0, 55, 5, 0, 0, 56, 5, 2, 0, 57, 5,
- 2, 0, 58, 5, 2, 0, 59, 5, 2, 0, 60, 5, 2, 0, 61, 5,185, 0, 8, 0, 4, 0, 62, 5, 4, 0, 63, 5, 4, 0, 64, 5,
- 4, 0, 65, 5, 4, 0, 66, 5, 4, 0, 67, 5, 4, 0, 54, 0, 4, 0, 50, 2, 46, 0, 34, 0, 27, 0, 31, 0, 39, 0, 75, 0,
- 32, 0, 68, 5,163, 0, 69, 5, 46, 0, 70, 5, 47, 0,206, 0, 12, 0, 71, 5,164, 0, 72, 5, 32, 0, 73, 5, 7, 0, 74, 5,
- 7, 0, 75, 5, 7, 0, 76, 5, 7, 0, 77, 5, 4, 0, 25, 3, 2, 0, 19, 0, 2, 0, 4, 1, 58, 0, 0, 1,186, 0, 78, 5,
-184, 0, 79, 5,187, 0, 80, 5,170, 0,180, 0,168, 0, 97, 4, 12, 0,100, 0, 12, 0, 81, 5,188, 0, 82, 5, 2, 0, 83, 5,
- 2, 0, 84, 5, 2, 0,215, 0, 2, 0, 85, 5, 4, 0, 86, 5, 4, 0, 87, 5, 12, 0, 88, 5,173, 0,221, 4,174, 0, 89, 5,
-189, 0, 6, 0, 47, 0,206, 0, 45, 0,255, 0, 7, 0, 14, 2, 7, 0, 15, 2, 7, 0,106, 0, 7, 0, 90, 5,190, 0, 35, 0,
- 7, 0, 91, 5, 7, 0, 92, 5, 7, 0, 93, 5, 7, 0, 94, 5, 7, 0, 95, 5, 7, 0, 96, 5, 7, 0, 97, 5, 7, 0, 98, 5,
- 7, 0, 99, 5, 7, 0, 18, 1, 7, 0,100, 5, 7, 0,101, 5, 7, 0,102, 5, 7, 0,103, 5, 7, 0,171, 0, 2, 0,104, 5,
- 2, 0,105, 5, 4, 0,106, 5, 2, 0,107, 5, 2, 0,108, 5, 2, 0,109, 5, 2, 0,110, 5, 7, 0,111, 5, 68, 0,112, 5,
-191, 0,113, 5,190, 0,114, 5,192, 0,115, 5,193, 0,116, 5,194, 0,117, 5,195, 0,118, 5,196, 0,119, 5, 7, 0,120, 5,
- 2, 0,121, 5, 2, 0,122, 5, 4, 0,160, 1,197, 0, 54, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5,
- 7, 0,125, 5, 2, 0,126, 5, 7, 0, 99, 5, 7, 0, 18, 1, 7, 0, 43, 0, 4, 0,127, 5, 2, 0,109, 5, 2, 0,110, 5,
- 32, 0, 68, 5, 32, 0,128, 5,189, 0,129, 5,197, 0,114, 5, 0, 0,130, 5, 4, 0, 25, 3, 4, 0,131, 5, 2, 0,132, 5,
- 2, 0,133, 5, 2, 0,134, 5, 2, 0,135, 5, 2, 0,160, 1, 2, 0, 19, 0, 2, 0,136, 5, 2, 0,137, 5, 7, 0,112, 0,
- 7, 0,138, 5, 7, 0,139, 5, 7, 0,140, 5, 7, 0,141, 5, 7, 0,142, 5, 7, 0,171, 0, 7, 0, 74, 5, 2, 0,143, 5,
- 2, 0, 62, 1, 2, 0,144, 5, 2, 0,145, 5, 2, 0,146, 5, 2, 0,147, 5, 2, 0,148, 5, 2, 0,149, 5, 2, 0,150, 5,
- 2, 0,151, 5, 4, 0,152, 5, 12, 0,153, 5, 2, 0,154, 5, 2, 0, 64, 2, 2, 0,155, 5, 0, 0,156, 5, 0, 0,157, 5,
- 9, 0,158, 5,191, 0,113, 5,199, 0, 25, 0, 24, 0, 36, 0, 24, 0, 64, 0, 23, 0,159, 5, 23, 0,160, 5, 23, 0,161, 5,
- 7, 0,162, 5, 7, 0,163, 5, 7, 0,164, 5, 7, 0,165, 5, 2, 0,166, 5, 2, 0,167, 5, 2, 0,168, 5, 2, 0,169, 5,
- 2, 0,170, 5, 2, 0, 19, 0, 2, 0,171, 5, 2, 0,172, 5, 2, 0,173, 5, 2, 0,174, 5, 2, 0,175, 5, 2, 0,135, 5,
- 7, 0,176, 5, 7, 0,177, 5, 4, 0,178, 5, 4, 0,179, 5,198, 0, 6, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5,
- 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,200, 0, 8, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5,
- 7, 0,125, 5, 2, 0,126, 5,201, 0,180, 5, 46, 0,134, 0,202, 0, 14, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5,
- 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,203, 0,182, 5, 12, 0,183, 5, 2, 0, 11, 1, 2, 0, 19, 0,
- 2, 0,184, 5, 0, 0,185, 5, 0, 0,186, 5,204, 0, 20, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5,
- 7, 0,125, 5, 2, 0,126, 5,192, 0,115, 5,199, 0,181, 5, 2, 0,187, 5, 2, 0,188, 5, 2, 0,189, 5, 2, 0,190, 5,
- 2, 0,171, 5, 2, 0,191, 5, 0, 0, 19, 0, 0, 0, 77, 1, 9, 0,250, 1, 4, 0,192, 5, 4, 0,193, 5, 27, 0,194, 5,
-205, 0, 16, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,
- 7, 0, 14, 2, 7, 0, 15, 2, 2, 0,187, 5, 2, 0,195, 5, 2, 0,196, 5, 2, 0,197, 5, 4, 0, 19, 0, 7, 0,198, 5,
-191, 0,113, 5,206, 0, 15, 0, 0, 0,199, 5, 0, 0,200, 5, 0, 0,201, 5, 2, 0, 19, 0, 2, 0,202, 5, 2, 0,203, 5,
- 2, 0,103, 1, 2, 0,204, 5, 2, 0, 37, 0, 4, 0,205, 5, 4, 0,206, 5, 2, 0,207, 5, 2, 0,208, 5, 0, 0,209, 5,
- 0, 0,210, 5,207, 0, 16, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 4, 0, 37, 0,206, 0,211, 5,
-208, 0,212, 5, 12, 0,213, 5, 12, 0,214, 5,209, 0,215, 5,196, 0,216, 5,210, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5,
- 2, 0,220, 5, 2, 0, 70, 0,211, 0, 17, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,
- 2, 0,126, 5,199, 0,181, 5, 12, 0,221, 5,212, 0,222, 5, 0, 0,223, 5,213, 0,224, 5, 4, 0,225, 5, 4, 0,226, 5,
- 2, 0, 19, 0, 2, 0,227, 5, 2, 0,228, 5, 2, 0, 37, 0,214, 0, 29, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5,
- 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, 47, 0,150, 2, 45, 0,255, 0, 61, 0,229, 5, 2, 0,133, 0, 2, 0,230, 5,
- 2, 0, 70, 0, 2, 0,231, 5, 4, 0, 19, 0, 2, 0,232, 5, 2, 0,186, 5, 2, 0,185, 5, 2, 0,160, 1, 0, 0,233, 5,
- 0, 0,234, 5, 0, 0,235, 5, 0, 0,135, 5, 7, 0, 14, 2, 7, 0, 15, 2, 7, 0,198, 5, 7, 0, 62, 1, 7, 0,236, 5,
- 7, 0,237, 5,191, 0,113, 5,215, 0, 11, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,
- 2, 0,126, 5, 2, 0,184, 5, 2, 0, 19, 0, 4, 0, 37, 0,203, 0,182, 5,199, 0,181, 5,216, 0, 27, 0,198, 0, 0, 0,
-198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, 42, 0,238, 5, 4, 0,239, 5, 4, 0,240, 5,
- 2, 0, 90, 0, 2, 0,133, 0, 2, 0,241, 5, 0, 0,242, 5, 0, 0,243, 5, 4, 0,244, 5, 4, 0,245, 5, 4, 0,246, 5,
- 4, 0,247, 5, 2, 0,248, 5, 2, 0,249, 5, 7, 0,250, 5, 23, 0,251, 5, 23, 0,252, 5, 4, 0,253, 5, 4, 0,254, 5,
- 0, 0,255, 5, 0, 0, 0, 6,217, 0, 10, 0, 27, 0, 31, 0, 9, 0, 1, 6, 9, 0, 2, 6, 9, 0, 3, 6, 9, 0, 4, 6,
- 9, 0, 5, 6, 4, 0, 90, 0, 4, 0, 6, 6, 0, 0, 7, 6, 0, 0, 8, 6,218, 0, 10, 0,198, 0, 0, 0,198, 0, 1, 0,
- 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,217, 0, 9, 6, 2, 0, 90, 0, 2, 0,133, 0, 4, 0, 43, 0, 9, 0, 10, 6,
-219, 0, 8, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,199, 0,181, 5, 4, 0, 19, 0,
- 4, 0, 11, 6,220, 0, 23, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,
-199, 0,181, 5, 27, 0, 12, 6, 27, 0, 81, 0, 2, 0, 19, 0, 2, 0,133, 0, 7, 0, 13, 6, 9, 0, 14, 6, 7, 0, 14, 2,
- 7, 0, 15, 2, 7, 0, 15, 6, 7, 0, 16, 6, 58, 0, 0, 1, 58, 0, 17, 6, 4, 0, 18, 6, 2, 0, 19, 6, 2, 0, 37, 0,
-191, 0,113, 5,221, 0, 10, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,
- 2, 0, 19, 0, 2, 0, 34, 3, 4, 0, 37, 0,191, 0,113, 5,222, 0, 42, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5,
- 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,208, 0,212, 5, 0, 0,199, 5, 0, 0,200, 5, 0, 0,201, 5,
- 2, 0, 17, 0, 2, 0,208, 5, 2, 0, 19, 0, 2, 0,202, 5, 9, 0, 14, 6, 4, 0,205, 5, 4, 0, 20, 6, 4, 0, 21, 6,
- 4, 0,206, 5, 23, 0, 22, 6, 23, 0, 23, 6, 7, 0, 24, 6, 7, 0, 25, 6, 7, 0, 26, 6, 7, 0, 13, 6, 2, 0, 27, 6,
- 2, 0,205, 0, 2, 0,103, 1, 2, 0,204, 5, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 28, 6, 2, 0, 29, 6, 9, 0, 30, 6,
- 9, 0, 31, 6, 9, 0, 32, 6, 9, 0, 33, 6, 9, 0, 34, 6, 2, 0, 35, 6, 0, 0,210, 5, 57, 0, 36, 6,223, 0, 7, 0,
-223, 0, 0, 0,223, 0, 1, 0, 4, 0, 37, 6, 4, 0, 23, 0, 0, 0, 84, 0, 4, 0, 38, 6, 4, 0, 17, 0,224, 0, 13, 0,
-198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, 4, 0, 17, 0, 4, 0, 39, 6,
- 4, 0, 19, 0, 4, 0,241, 5, 12, 0, 40, 6, 12, 0, 41, 6, 0, 0, 42, 6,225, 0, 7, 0,225, 0, 0, 0,225, 0, 1, 0,
- 0, 0, 43, 6, 2, 0, 44, 6, 2, 0, 45, 6, 2, 0, 46, 6, 2, 0, 37, 0,226, 0, 12, 0, 2, 0, 45, 6, 2, 0, 47, 6,
- 2, 0, 48, 6, 0, 0,115, 2, 2, 0, 49, 6, 2, 0, 50, 6, 2, 0, 51, 6, 2, 0, 52, 6, 2, 0, 53, 6, 2, 0,171, 5,
- 7, 0, 54, 6, 7, 0, 55, 6,227, 0, 18, 0,227, 0, 0, 0,227, 0, 1, 0, 0, 0,132, 3,226, 0, 56, 6,226, 0, 57, 6,
-226, 0, 58, 6,226, 0, 59, 6, 7, 0, 60, 6, 2, 0, 61, 6, 2, 0, 62, 6, 2, 0, 63, 6, 2, 0, 64, 6, 2, 0, 65, 6,
- 2, 0, 66, 6, 2, 0, 67, 6, 2, 0, 68, 6, 2, 0, 69, 6, 2, 0, 70, 6,228, 0, 10, 0, 0, 0, 71, 6, 0, 0, 72, 6,
- 0, 0, 73, 6, 0, 0, 74, 6, 0, 0, 75, 6, 0, 0, 76, 6, 2, 0, 77, 6, 2, 0, 78, 6, 2, 0, 79, 6, 2, 0, 37, 0,
-229, 0, 8, 0, 0, 0, 80, 6, 0, 0, 81, 6, 0, 0, 82, 6, 0, 0, 83, 6, 0, 0, 84, 6, 0, 0, 85, 6, 7, 0, 90, 5,
- 7, 0, 37, 0,230, 0, 17, 0,228, 0, 86, 6,228, 0, 87, 6,228, 0, 88, 6,228, 0, 89, 6,228, 0, 90, 6,228, 0, 91, 6,
-228, 0, 92, 6,228, 0, 93, 6,228, 0, 94, 6,228, 0, 95, 6,228, 0, 96, 6,228, 0, 97, 6,228, 0, 98, 6,228, 0, 99, 6,
-228, 0,100, 6,229, 0,101, 6, 0, 0,102, 6,231, 0, 71, 0, 0, 0,103, 6, 0, 0,104, 6, 0, 0, 75, 6, 0, 0,105, 6,
- 0, 0,106, 6, 0, 0,107, 6, 0, 0,108, 6, 0, 0,109, 6, 0, 0,110, 6, 0, 0,111, 6, 0, 0,112, 6, 0, 0,113, 6,
- 0, 0,114, 6, 0, 0,115, 6, 0, 0,116, 6, 0, 0,117, 6, 0, 0,118, 6, 0, 0,119, 6, 0, 0,120, 6, 0, 0,121, 6,
- 0, 0,122, 6, 0, 0,123, 6, 0, 0,124, 6, 0, 0,125, 6, 0, 0,126, 6, 0, 0,127, 6, 0, 0,128, 6, 0, 0,129, 6,
- 0, 0,130, 6, 0, 0,131, 6, 0, 0,132, 6, 0, 0,133, 6, 0, 0,134, 6, 0, 0,135, 6, 0, 0,136, 6, 0, 0,137, 6,
- 0, 0,138, 6, 0, 0,139, 6, 0, 0,140, 6, 0, 0,141, 6, 0, 0,142, 6, 0, 0,143, 6, 0, 0,144, 6, 0, 0,145, 6,
- 0, 0,146, 6, 0, 0,147, 6, 0, 0,148, 6, 0, 0,149, 6, 0, 0,150, 6, 0, 0,151, 6, 0, 0,152, 6, 0, 0,153, 6,
- 0, 0,154, 6, 0, 0,155, 6, 0, 0,156, 6, 0, 0,157, 6, 0, 0,158, 6, 0, 0,159, 6, 0, 0,160, 6, 0, 0,161, 6,
- 0, 0,162, 6, 0, 0,163, 6, 0, 0,164, 6, 0, 0,165, 6, 0, 0,166, 6, 0, 0,167, 6, 0, 0,168, 6, 0, 0,169, 6,
- 0, 0,170, 6, 0, 0,171, 6, 0, 0, 92, 0,232, 0, 5, 0, 0, 0,172, 6, 0, 0,127, 6, 0, 0,129, 6, 2, 0, 19, 0,
- 2, 0, 37, 0,233, 0, 21, 0,233, 0, 0, 0,233, 0, 1, 0, 0, 0, 20, 0,230, 0,173, 6,231, 0,174, 6,231, 0,175, 6,
-231, 0,176, 6,231, 0,177, 6,231, 0,178, 6,231, 0,179, 6,231, 0,180, 6,231, 0,181, 6,231, 0,182, 6,231, 0,183, 6,
-231, 0,184, 6,231, 0,185, 6,231, 0,186, 6,231, 0,187, 6,231, 0,188, 6,231, 0,189, 6,232, 0,190, 6,234, 0, 5, 0,
- 4, 0, 19, 0, 4, 0, 37, 0, 7, 0, 63, 2, 7, 0,191, 6, 7, 0,228, 1,235, 0, 67, 0, 4, 0, 19, 0, 4, 0,192, 6,
- 4, 0,193, 6, 0, 0,194, 6, 0, 0,195, 6, 0, 0,196, 6, 0, 0,197, 6, 0, 0,198, 6, 0, 0,199, 6, 0, 0,200, 6,
- 0, 0,201, 6, 0, 0,202, 6, 2, 0,203, 6, 2, 0, 37, 0, 4, 0,204, 6, 4, 0,205, 6, 4, 0,206, 6, 4, 0,207, 6,
- 2, 0,208, 6, 2, 0,209, 6, 4, 0,210, 6, 4, 0, 40, 6, 4, 0,211, 6, 2, 0,212, 6, 2, 0,213, 6, 2, 0,214, 6,
- 2, 0,215, 6, 12, 0,216, 6, 12, 0,217, 6, 12, 0,218, 6, 2, 0,219, 6, 2, 0,220, 6, 2, 0,221, 6, 2, 0,222, 6,
- 2, 0,223, 6, 2, 0,224, 6, 2, 0,225, 6, 2, 0,226, 6,234, 0,227, 6, 2, 0,228, 6, 2, 0,229, 6, 2, 0,230, 6,
- 2, 0,231, 6, 2, 0,232, 6, 2, 0,233, 6, 2, 0,234, 6, 2, 0,235, 6, 4, 0,236, 6, 4, 0,237, 6, 2, 0,238, 6,
- 2, 0,239, 6, 2, 0,240, 6, 2, 0,241, 6, 2, 0,242, 6, 2, 0,243, 6, 2, 0,244, 6, 2, 0,245, 6, 2, 0,246, 6,
- 2, 0,247, 6, 2, 0,248, 6, 2, 0,249, 6, 0, 0,250, 6, 0, 0,251, 6, 7, 0,252, 6, 2, 0, 25, 5, 2, 0,253, 6,
- 55, 0,254, 6,201, 0, 21, 0, 27, 0, 31, 0, 12, 0,255, 6, 12, 0, 0, 7, 12, 0, 1, 7, 12, 0,123, 5, 46, 0,134, 0,
- 46, 0, 2, 7, 2, 0, 3, 7, 2, 0, 4, 7, 2, 0, 5, 7, 2, 0, 6, 7, 2, 0, 7, 7, 2, 0, 8, 7, 2, 0, 9, 7,
- 2, 0, 37, 0, 2, 0, 10, 7, 2, 0, 11, 7, 4, 0, 70, 0,196, 0, 12, 7, 9, 0, 13, 7, 2, 0, 14, 7,236, 0, 5, 0,
-236, 0, 0, 0,236, 0, 1, 0,236, 0, 15, 7, 13, 0, 16, 7, 4, 0, 19, 0,237, 0, 7, 0,237, 0, 0, 0,237, 0, 1, 0,
-236, 0, 17, 7,236, 0, 18, 7, 2, 0,137, 4, 2, 0, 19, 0, 4, 0, 37, 0,238, 0, 23, 0,238, 0, 0, 0,238, 0, 1, 0,
-239, 0, 19, 7,240, 0,217, 5, 0, 0, 20, 7, 0, 0, 21, 7, 0, 0, 22, 7, 2, 0, 23, 7, 2, 0, 24, 7, 2, 0, 25, 7,
- 2, 0, 26, 7, 2, 0, 27, 7, 2, 0, 37, 0, 2, 0, 19, 0, 2, 0, 28, 7, 2, 0, 29, 7, 2, 0, 30, 7, 4, 0, 31, 7,
-238, 0, 32, 7, 9, 0, 33, 7, 4, 0, 34, 7, 4, 0, 35, 7, 0, 0, 36, 7,241, 0, 22, 0,241, 0, 0, 0,241, 0, 1, 0,
-236, 0, 17, 7,236, 0, 18, 7,236, 0, 37, 7,236, 0, 38, 7,201, 0, 39, 7, 23, 0, 52, 0, 0, 0,124, 5, 0, 0, 40, 7,
- 2, 0,172, 5, 2, 0,173, 5, 2, 0, 41, 7, 2, 0, 37, 0, 2, 0, 6, 7, 2, 0, 38, 6, 2, 0, 19, 0,242, 0, 19, 7,
- 12, 0, 42, 7, 12, 0,123, 5, 12, 0, 43, 7, 12, 0, 44, 7,243, 0, 21, 0,243, 0, 0, 0,243, 0, 1, 0,199, 0,181, 5,
- 23, 0, 45, 7, 23, 0, 46, 7, 2, 0,172, 5, 2, 0,173, 5, 2, 0, 47, 7, 2, 0, 48, 7, 2, 0, 49, 7, 2, 0, 19, 0,
- 7, 0, 10, 2, 2, 0, 5, 7, 2, 0, 9, 7, 4, 0, 43, 0,244, 0, 19, 7, 12, 0, 50, 7, 12, 0, 51, 7, 12, 0, 43, 7,
- 0, 0, 52, 7, 9, 0, 53, 7,245, 0, 11, 0, 0, 0, 54, 7, 2, 0, 55, 7, 2, 0, 56, 7, 2, 0, 57, 7, 2, 0, 58, 7,
- 2, 0,126, 4, 2, 0,121, 4,201, 0, 59, 7, 46, 0, 60, 7, 4, 0, 61, 7, 4, 0, 62, 7,246, 0, 1, 0, 0, 0, 63, 7,
-247, 0, 8, 0, 57, 0, 64, 7, 57, 0, 65, 7,247, 0, 66, 7,247, 0, 67, 7,247, 0, 68, 7, 2, 0,129, 0, 2, 0, 19, 0,
- 4, 0, 69, 7,248, 0, 4, 0, 4, 0,239, 5, 4, 0, 70, 7, 4, 0,244, 5, 4, 0, 71, 7,249, 0, 2, 0, 4, 0, 72, 7,
- 4, 0, 73, 7,250, 0, 7, 0, 7, 0, 74, 7, 7, 0, 75, 7, 7, 0, 76, 7, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0, 10, 4,
- 7, 0, 77, 7,251, 0, 6, 0, 0, 0, 78, 7, 0, 0,201, 5, 49, 0,137, 0, 2, 0,106, 0, 2, 0,125, 4, 4, 0, 37, 0,
-252, 0, 21, 0,252, 0, 0, 0,252, 0, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0, 79, 7, 4, 0, 80, 7,
- 4, 0, 81, 7,246, 0, 82, 7, 0, 0, 78, 7, 4, 0, 83, 7, 4, 0, 84, 7,251, 0, 8, 3,248, 0, 85, 7,249, 0, 86, 7,
-250, 0, 87, 7,247, 0, 88, 7,247, 0, 89, 7,247, 0, 90, 7, 57, 0, 91, 7, 57, 0, 92, 7,253, 0, 12, 0, 0, 0,190, 1,
- 9, 0,191, 0, 0, 0,192, 0, 4, 0,195, 0, 4, 0,203, 0, 9, 0,196, 0, 7, 0,198, 0, 7, 0,199, 0, 9, 0, 93, 7,
- 9, 0, 94, 7, 9, 0,200, 0, 9, 0,202, 0,254, 0, 43, 0,254, 0, 0, 0,254, 0, 1, 0, 9, 0, 95, 7, 9, 0, 26, 0,
- 0, 0, 27, 0, 4, 0, 19, 0, 4, 0, 17, 0, 4, 0, 23, 0, 4, 0, 88, 0, 4, 0, 96, 7, 4, 0, 97, 7, 4, 0, 80, 7,
- 4, 0, 81, 7, 4, 0, 98, 7, 4, 0,214, 0, 4, 0, 99, 7, 4, 0,100, 7, 7, 0,246, 4, 7, 0,101, 7, 4, 0,126, 0,
- 4, 0,102, 7,252, 0,103, 7, 36, 0, 80, 0, 46, 0,134, 0, 49, 0,137, 0, 7, 0,104, 7, 7, 0,105, 7,253, 0, 1, 1,
-254, 0,106, 7,254, 0,107, 7,254, 0,108, 7, 12, 0,109, 7,255, 0,110, 7, 0, 1,111, 7, 7, 0,112, 7, 7, 0,113, 7,
- 4, 0,114, 7, 7, 0,115, 7, 9, 0,116, 7, 4, 0,117, 7, 4, 0,118, 7, 4, 0,119, 7, 7, 0,120, 7, 1, 1, 4, 0,
- 1, 1, 0, 0, 1, 1, 1, 0, 12, 0,121, 7,254, 0,122, 7,186, 0, 6, 0, 12, 0,123, 7, 12, 0,109, 7, 12, 0,124, 7,
-254, 0,125, 7, 0, 0,126, 7, 0, 0,127, 7, 2, 1, 4, 0, 7, 0,128, 7, 7, 0,109, 0, 2, 0,129, 7, 2, 0,130, 7,
- 3, 1, 6, 0, 7, 0,131, 7, 7, 0,132, 7, 7, 0,133, 7, 7, 0,134, 7, 4, 0,135, 7, 4, 0,136, 7, 4, 1, 12, 0,
- 7, 0,137, 7, 7, 0,138, 7, 7, 0,139, 7, 7, 0,140, 7, 7, 0,141, 7, 7, 0,142, 7, 7, 0,143, 7, 7, 0,144, 7,
- 7, 0,145, 7, 7, 0,146, 7, 4, 0,154, 2, 4, 0,147, 7, 5, 1, 2, 0, 7, 0,219, 4, 7, 0, 37, 0, 6, 1, 5, 0,
- 7, 0,148, 7, 7, 0,149, 7, 4, 0, 90, 0, 4, 0,116, 2, 4, 0,150, 7, 7, 1, 6, 0, 7, 1, 0, 0, 7, 1, 1, 0,
- 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,151, 7, 2, 0, 57, 0, 8, 1, 8, 0, 8, 1, 0, 0, 8, 1, 1, 0, 2, 0, 17, 0,
- 2, 0, 19, 0, 2, 0,151, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0,126, 0, 9, 1, 45, 0, 9, 1, 0, 0, 9, 1, 1, 0,
- 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,151, 7, 2, 0,210, 0, 2, 0,182, 3, 2, 0,152, 7, 7, 0,153, 7, 7, 0, 89, 0,
- 7, 0,167, 2, 4, 0,154, 7, 4, 0, 82, 0, 4, 0,118, 2, 7, 0,155, 7, 7, 0,156, 7, 7, 0,157, 7, 7, 0,158, 7,
- 7, 0,159, 7, 7, 0,160, 7, 7, 0,164, 2, 7, 0,254, 0, 7, 0,161, 7, 7, 0,162, 7, 7, 0, 37, 0, 7, 0,163, 7,
- 7, 0,164, 7, 7, 0,165, 7, 2, 0,166, 7, 2, 0,167, 7, 2, 0,168, 7, 2, 0,169, 7, 2, 0,170, 7, 2, 0,171, 7,
- 2, 0,172, 7, 2, 0,173, 7, 2, 0,136, 5, 2, 0,174, 7, 2, 0,210, 1, 2, 0,175, 7, 0, 0,176, 7, 0, 0,177, 7,
- 7, 0,208, 0, 10, 1,178, 7, 64, 0,163, 1, 11, 1, 16, 0, 11, 1, 0, 0, 11, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0,
- 2, 0,151, 7, 2, 0,210, 0, 7, 0,159, 2, 7, 0,160, 2, 7, 0,161, 2, 7, 0,255, 1, 7, 0,162, 2, 7, 0,163, 2,
- 7, 0,179, 7, 7, 0,164, 2, 7, 0,166, 2, 7, 0,167, 2,213, 0, 5, 0, 2, 0, 17, 0, 2, 0, 69, 7, 2, 0, 19, 0,
- 2, 0,180, 7, 27, 0, 12, 6,212, 0, 3, 0, 4, 0, 69, 0, 4, 0,181, 7,213, 0, 2, 0, 12, 1, 7, 0, 12, 1, 0, 0,
- 12, 1, 1, 0, 0, 0, 20, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 22, 0, 9, 0,182, 7, 13, 1, 5, 0, 0, 0, 20, 0,
- 7, 0, 18, 1, 7, 0,183, 7, 4, 0,184, 7, 4, 0, 37, 0, 14, 1, 4, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 43, 0,
- 2, 0, 70, 0, 15, 1, 4, 0, 0, 0, 20, 0, 63, 0,185, 7, 7, 0, 18, 1, 7, 0, 37, 0, 16, 1, 6, 0, 2, 0,186, 7,
- 2, 0,187, 7, 2, 0, 17, 0, 2, 0,188, 7, 0, 0,189, 7, 0, 0,190, 7, 17, 1, 5, 0, 4, 0, 17, 0, 4, 0, 37, 0,
- 0, 0, 20, 0, 0, 0,191, 7, 0, 0,192, 7, 18, 1, 3, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0, 19, 1, 4, 0,
- 2, 0,193, 7, 2, 0,194, 7, 2, 0, 19, 0, 2, 0, 37, 0, 20, 1, 6, 0, 0, 0, 20, 0, 0, 0,195, 7, 2, 0,196, 7,
- 2, 0,164, 2, 2, 0, 11, 1, 2, 0, 70, 0, 21, 1, 5, 0, 0, 0, 20, 0, 7, 0,109, 0, 7, 0, 12, 4, 2, 0, 19, 0,
- 2, 0,130, 2, 22, 1, 3, 0, 0, 0, 20, 0, 4, 0,118, 2, 4, 0,193, 7, 23, 1, 7, 0, 0, 0, 20, 0, 7, 0, 12, 4,
- 0, 0,197, 7, 0, 0,198, 7, 2, 0, 11, 1, 2, 0, 43, 0, 4, 0,199, 7, 24, 1, 3, 0, 32, 0,200, 7, 0, 0,201, 7,
- 0, 0,202, 7, 25, 1, 18, 0, 25, 1, 0, 0, 25, 1, 1, 0, 2, 0, 17, 0, 2, 0,203, 7, 2, 0, 19, 0, 2, 0,204, 7,
- 2, 0,205, 7, 2, 0,206, 7, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 20, 0, 9, 0, 2, 0, 26, 1,207, 7, 32, 0, 45, 0,
- 2, 0,229, 4, 2, 0,112, 7, 2, 0,208, 7, 2, 0, 37, 0, 27, 1, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0, 0, 0,209, 7,
- 2, 0, 19, 0, 2, 0,130, 2, 2, 0,210, 7, 4, 0,211, 7, 4, 0,212, 7, 4, 0,213, 7, 4, 0,214, 7, 4, 0,215, 7,
- 28, 1, 1, 0, 0, 0,216, 7, 29, 1, 4, 0, 42, 0,238, 5, 0, 0,217, 7, 4, 0, 11, 1, 4, 0, 19, 0, 26, 1, 18, 0,
- 26, 1, 0, 0, 26, 1, 1, 0, 26, 1,218, 7, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,219, 7, 2, 0,206, 7, 2, 0,203, 7,
- 2, 0,220, 7, 2, 0, 70, 0, 2, 0,160, 1, 0, 0, 20, 0, 9, 0, 2, 0, 30, 1,207, 7, 25, 1,221, 7, 2, 0, 15, 0,
- 2, 0,222, 7, 4, 0,223, 7, 31, 1, 3, 0, 4, 0,190, 2, 4, 0, 37, 0, 32, 0, 45, 0, 32, 1, 12, 0,151, 0,224, 7,
- 2, 0, 17, 0, 2, 0, 19, 0, 4, 0,153, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0,225, 7, 2, 0,226, 7, 2, 0,227, 7,
- 2, 0,228, 7, 2, 0,229, 7, 7, 0,230, 7, 33, 1, 10, 0, 2, 0, 19, 0, 2, 0,231, 7, 4, 0,153, 7, 4, 0, 89, 0,
- 2, 0,232, 7,255, 0,110, 7, 2, 0, 17, 0, 2, 0,233, 7, 2, 0,234, 7, 2, 0,235, 7, 34, 1, 7, 0, 2, 0, 19, 0,
- 2, 0,231, 7, 4, 0,153, 7, 4, 0, 89, 0, 2, 0, 17, 0, 2, 0,236, 7, 7, 0,139, 3, 35, 1, 11, 0, 4, 0,190, 2,
- 2, 0, 17, 0, 2, 0, 19, 0, 32, 0, 45, 0, 77, 0,237, 7, 0, 0, 20, 0, 7, 0,238, 7, 7, 0,239, 7, 7, 0, 42, 3,
- 2, 0,240, 7, 2, 0,241, 7, 36, 1, 5, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 37, 0, 46, 0,134, 0, 32, 0, 68, 5,
- 37, 1, 5, 0, 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 20, 0, 0, 0,191, 7, 32, 0, 45, 0, 38, 1, 13, 0, 2, 0, 19, 0,
- 2, 0, 17, 0, 2, 0,203, 7, 2, 0, 43, 3, 7, 0,242, 7, 7, 0,243, 7, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0, 19, 3,
- 7, 0, 22, 3, 7, 0,244, 7, 7, 0,245, 7, 32, 0,246, 7, 39, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,153, 7,
- 4, 0, 89, 0, 0, 0, 20, 0, 0, 0,225, 7, 2, 0, 43, 0, 2, 0, 64, 0, 2, 0,247, 7, 2, 0,248, 7, 40, 1, 8, 0,
- 32, 0, 45, 0, 7, 0,161, 2, 7, 0,249, 7, 7, 0,250, 7, 7, 0,156, 2, 2, 0, 19, 0, 2, 0,130, 2, 7, 0,251, 7,
- 41, 1, 12, 0, 2, 0, 17, 0, 2, 0, 11, 1, 2, 0, 19, 0, 2, 0,164, 2, 2, 0,190, 2, 2, 0,252, 7, 4, 0, 37, 0,
- 7, 0,253, 7, 7, 0,254, 7, 7, 0,255, 7, 7, 0, 0, 8, 0, 0, 1, 8, 42, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0,
- 4, 0,153, 7, 4, 0, 89, 0, 0, 0, 20, 0, 2, 0, 77, 1, 2, 0, 64, 0, 2, 0,247, 7, 2, 0,248, 7, 64, 0,163, 1,
- 43, 1, 7, 0, 4, 0,118, 2, 4, 0, 2, 8, 4, 0, 3, 8, 4, 0, 4, 8, 7, 0, 5, 8, 7, 0, 6, 8, 0, 0,197, 7,
- 44, 1, 7, 0, 0, 0, 7, 8, 32, 0, 8, 8, 0, 0,201, 7, 2, 0, 9, 8, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0,202, 7,
- 45, 1, 6, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,153, 7, 4, 0, 89, 0, 0, 0, 10, 8, 0, 0, 11, 8, 46, 1, 1, 0,
- 4, 0, 19, 0, 47, 1, 6, 0, 0, 0, 92, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 12, 8, 7, 0, 13, 8, 42, 0,238, 5,
- 48, 1, 4, 0, 0, 0,179, 0, 2, 0, 19, 0, 4, 0, 17, 0, 32, 0, 45, 0, 49, 1, 2, 0, 4, 0, 17, 0, 4, 0,161, 5,
- 30, 1, 10, 0, 30, 1, 0, 0, 30, 1, 1, 0, 30, 1,218, 7, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,203, 7, 2, 0, 14, 8,
- 0, 0, 20, 0, 9, 0, 2, 0, 32, 0, 45, 0, 50, 1, 10, 0, 7, 0, 42, 3, 7, 0, 15, 8, 7, 0, 16, 8, 7, 0, 17, 8,
- 7, 0, 18, 8, 4, 0, 19, 0, 7, 0,252, 7, 7, 0, 19, 8, 7, 0, 20, 8, 7, 0, 37, 0,255, 0, 20, 0, 27, 0, 31, 0,
- 0, 0,190, 0, 51, 1, 21, 8, 9, 0, 22, 8, 43, 0,149, 0, 43, 0, 23, 8, 9, 0, 24, 8, 36, 0, 80, 0, 7, 0,139, 3,
- 7, 0, 25, 8, 7, 0, 26, 8, 7, 0, 27, 8, 7, 0, 28, 8, 7, 0, 29, 8, 7, 0, 30, 8, 4, 0, 90, 0, 4, 0, 31, 8,
- 0, 0, 32, 8, 0, 0, 33, 8, 0, 0, 34, 8, 52, 1, 6, 0, 27, 0, 31, 0, 7, 0, 35, 8, 7, 0, 36, 8, 7, 0, 37, 8,
- 2, 0, 38, 8, 2, 0, 39, 8, 53, 1, 15, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,
-241, 0, 40, 8,199, 0,181, 5,255, 0,110, 7, 2, 0, 11, 1, 2, 0,231, 7, 2, 0, 14, 2, 2, 0, 15, 2, 2, 0, 19, 0,
- 2, 0,186, 5, 4, 0, 70, 0, 54, 1, 6, 0, 54, 1, 0, 0, 54, 1, 1, 0, 32, 0, 45, 0, 9, 0, 41, 8, 4, 0,215, 0,
- 4, 0, 37, 0, 64, 0, 4, 0, 27, 0, 31, 0, 12, 0, 42, 8, 4, 0,131, 0, 7, 0, 43, 8, 55, 1, 25, 0, 55, 1, 0, 0,
- 55, 1, 1, 0, 55, 1, 38, 0, 12, 0, 44, 8, 0, 0, 20, 0, 7, 0, 45, 8, 7, 0, 46, 8, 7, 0, 47, 8, 7, 0, 48, 8,
- 4, 0, 19, 0, 7, 0, 49, 8, 7, 0, 50, 8, 7, 0, 51, 8, 7, 0, 18, 1, 7, 0,220, 1, 7, 0, 52, 8, 7, 0,116, 2,
- 7, 0, 53, 8, 7, 0, 54, 8, 7, 0, 55, 8, 7, 0, 56, 8, 7, 0, 57, 8, 7, 0,172, 0, 2, 0,131, 0, 2, 0, 6, 5,
- 56, 1, 21, 0, 27, 0, 31, 0, 12, 0, 58, 8, 12, 0, 59, 8, 12, 0, 60, 8, 9, 0, 61, 8, 4, 0, 19, 0, 4, 0,132, 5,
- 2, 0,168, 2, 2, 0,192, 5, 2, 0,131, 0, 2, 0, 62, 8, 2, 0, 63, 8, 2, 0, 64, 8, 2, 0, 65, 8, 2, 0, 66, 8,
- 4, 0, 67, 8, 4, 0, 68, 8, 4, 0, 69, 8, 4, 0, 70, 8, 4, 0, 71, 8, 4, 0, 72, 8, 57, 1, 38, 0, 57, 1, 0, 0,
- 57, 1, 1, 0, 26, 0, 73, 8, 12, 0, 69, 3, 0, 0, 20, 0, 2, 0, 19, 0, 2, 0, 74, 8, 2, 0, 75, 8, 2, 0, 76, 8,
- 2, 0, 28, 3, 2, 0, 77, 8, 4, 0,253, 1, 4, 0, 69, 8, 4, 0, 70, 8, 55, 1, 78, 8, 57, 1, 38, 0, 57, 1, 79, 8,
- 12, 0, 80, 8, 9, 0, 81, 8, 9, 0, 82, 8, 9, 0, 83, 8, 7, 0, 6, 1, 7, 0,172, 0, 7, 0, 84, 8, 7, 0,200, 1,
- 2, 0, 85, 8, 2, 0, 37, 0, 7, 0, 86, 8, 7, 0, 87, 8, 7, 0, 24, 3, 7, 0, 88, 8, 7, 0, 89, 8, 7, 0, 90, 8,
- 7, 0, 91, 8, 7, 0, 92, 8, 7, 0, 93, 8, 7, 0,250, 1, 32, 0, 94, 8,152, 0, 9, 0, 12, 0, 95, 8, 2, 0, 19, 0,
- 2, 0, 96, 8, 7, 0, 26, 2, 7, 0, 97, 8, 7, 0, 98, 8, 12, 0, 99, 8, 4, 0,100, 8, 4, 0, 37, 0, 58, 1, 7, 0,
- 58, 1, 0, 0, 58, 1, 1, 0, 12, 0, 32, 8, 4, 0, 19, 0, 4, 0,101, 8, 0, 0,132, 3,232, 0,102, 8,151, 0, 7, 0,
- 27, 0, 31, 0, 12, 0,103, 8, 12, 0, 95, 8, 12, 0,104, 8, 12, 0,100, 0, 4, 0, 19, 0, 4, 0,105, 8,203, 0, 4, 0,
- 27, 0,106, 8, 12, 0, 95, 8, 4, 0,107, 8, 4, 0, 19, 0, 59, 1, 17, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5,
- 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,151, 0, 11, 3,203, 0,108, 8, 0, 0, 11, 1, 0, 0,184, 5,
- 2, 0, 19, 0, 2, 0,109, 8, 2, 0,185, 5, 2, 0,186, 5, 2, 0,110, 8, 7, 0,111, 8, 60, 1, 8, 0, 60, 1, 0, 0,
- 60, 1, 1, 0, 58, 1,112, 8, 36, 0, 80, 0, 12, 0, 14, 3, 4, 0, 19, 0, 0, 0, 20, 0, 4, 0,113, 8, 61, 1, 5, 0,
- 61, 1, 0, 0, 61, 1, 1, 0, 36, 0, 80, 0, 2, 0, 19, 0, 0, 0,114, 8, 62, 1, 12, 0, 62, 1, 0, 0, 62, 1, 1, 0,
- 9, 0, 2, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0,115, 8, 0, 0,116, 8, 0, 0,114, 8, 7, 0,117, 8, 7, 0,118, 8,
- 4, 0, 37, 0, 36, 0, 80, 0, 63, 1, 9, 0, 63, 1, 0, 0, 63, 1, 1, 0, 32, 0,119, 8, 0, 0,120, 8, 7, 0,121, 8,
- 2, 0,122, 8, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0, 37, 0, 64, 1, 7, 0, 42, 0,238, 5, 26, 0, 73, 8, 4, 0, 19, 0,
- 4, 0,123, 8, 12, 0,124, 8, 32, 0,119, 8, 0, 0,120, 8, 65, 1, 12, 0, 32, 0,119, 8, 2, 0,125, 8, 2, 0, 19, 0,
- 2, 0,126, 8, 2, 0,127, 8, 0, 0,120, 8, 32, 0,128, 8, 0, 0,129, 8, 7, 0,130, 8, 7, 0,220, 1, 7, 0,131, 8,
- 7, 0,132, 8, 66, 1, 6, 0, 32, 0,119, 8, 4, 0,133, 8, 4, 0,134, 8, 4, 0, 90, 0, 4, 0, 37, 0, 0, 0,120, 8,
- 67, 1, 4, 0, 32, 0,119, 8, 4, 0, 19, 0, 4, 0,133, 8, 0, 0,120, 8, 68, 1, 4, 0, 32, 0,119, 8, 4, 0, 19, 0,
- 4, 0,133, 8, 0, 0,120, 8, 69, 1, 10, 0, 32, 0,119, 8, 4, 0,135, 8, 7, 0,125, 0, 4, 0, 19, 0, 2, 0,234, 5,
- 2, 0,136, 8, 2, 0, 43, 0, 2, 0, 70, 0, 7, 0,137, 8, 0, 0,120, 8, 70, 1, 4, 0, 32, 0,119, 8, 4, 0, 19, 0,
- 4, 0,133, 8, 0, 0,120, 8, 71, 1, 10, 0, 32, 0,119, 8, 2, 0, 17, 0, 2, 0,190, 3, 4, 0, 88, 0, 4, 0, 89, 0,
- 7, 0,249, 7, 7, 0,250, 7, 4, 0, 37, 0,151, 0,224, 7, 0, 0,120, 8, 72, 1, 4, 0, 32, 0,119, 8, 4, 0, 29, 3,
- 4, 0,138, 8, 0, 0,120, 8, 73, 1, 5, 0, 32, 0,119, 8, 7, 0,125, 0, 4, 0,139, 8, 4, 0, 29, 3, 4, 0, 30, 3,
- 74, 1, 6, 0, 32, 0,119, 8, 4, 0,140, 8, 4, 0,141, 8, 7, 0,142, 8, 7, 0,143, 8, 0, 0,120, 8, 75, 1, 16, 0,
- 32, 0,119, 8, 32, 0, 79, 8, 4, 0, 17, 0, 7, 0,144, 8, 7, 0,145, 8, 7, 0,146, 8, 7, 0,147, 8, 7, 0,148, 8,
- 7, 0,149, 8, 7, 0,150, 8, 7, 0,151, 8, 7, 0,152, 8, 2, 0, 19, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0,
- 76, 1, 3, 0, 32, 0,119, 8, 4, 0, 19, 0, 4, 0,136, 5, 77, 1, 5, 0, 32, 0,119, 8, 4, 0, 19, 0, 4, 0, 37, 0,
- 7, 0,153, 8, 0, 0,120, 8, 78, 1, 10, 0, 32, 0,119, 8, 0, 0,120, 8, 2, 0,154, 8, 2, 0,155, 8, 0, 0,156, 8,
- 0, 0,157, 8, 7, 0,158, 8, 7, 0,159, 8, 7, 0,160, 8, 7, 0,161, 8, 79, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0,
- 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,162, 8, 7, 0,163, 8, 2, 0, 19, 0, 2, 0,136, 5, 80, 1, 8, 0, 7, 0, 9, 0,
- 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,162, 8, 7, 0,163, 8, 2, 0, 19, 0, 2, 0,136, 5, 81, 1, 8, 0,
- 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,162, 8, 7, 0,163, 8, 2, 0, 19, 0, 2, 0,136, 5,
- 82, 1, 7, 0, 32, 0,119, 8, 0, 0,120, 8, 7, 0, 18, 1, 7, 0, 28, 1, 2, 0, 19, 0, 2, 0, 11, 1, 4, 0, 37, 0,
- 83, 1, 5, 0, 32, 0,228, 2, 7, 0, 18, 1, 2, 0,232, 2, 0, 0,234, 2, 0, 0,164, 8, 84, 1, 10, 0, 84, 1, 0, 0,
- 84, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0,165, 8, 7, 0,217, 0, 7, 0,218, 0, 2, 0, 32, 8, 2, 0,166, 8,
- 32, 0, 45, 0, 85, 1, 22, 0, 85, 1, 0, 0, 85, 1, 1, 0, 2, 0, 19, 0, 2, 0, 11, 1, 2, 0,167, 8, 2, 0,168, 8,
- 36, 0, 80, 0,151, 0,224, 7, 32, 0,164, 0, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,169, 8, 7, 0,170, 8, 7, 0,171, 8,
- 7, 0,172, 8, 7, 0,157, 2, 7, 0,173, 8, 7, 0,226, 7, 7, 0,174, 8, 0, 0,175, 8, 0, 0,176, 8, 12, 0, 16, 3,
- 86, 1, 8, 0, 7, 0,228, 1, 7, 0,249, 7, 7, 0,250, 7, 9, 0, 2, 0, 2, 0,177, 8, 2, 0,178, 8, 2, 0,179, 8,
- 2, 0,180, 8, 87, 1, 18, 0, 87, 1, 0, 0, 87, 1, 1, 0, 87, 1,181, 8, 0, 0, 20, 0, 86, 1,182, 8, 2, 0, 17, 0,
- 2, 0, 19, 0, 2, 0,183, 8, 2, 0,184, 8, 2, 0,185, 8, 2, 0,186, 8, 4, 0, 43, 0, 7, 0,187, 8, 7, 0,188, 8,
- 4, 0,189, 8, 4, 0,190, 8, 87, 1,191, 8, 88, 1,192, 8, 89, 1, 33, 0, 89, 1, 0, 0, 89, 1, 1, 0, 89, 1,193, 8,
- 0, 0, 20, 0, 0, 0,194, 8, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 79, 7, 2, 0,112, 7, 2, 0,195, 8, 2, 0,133, 0,
- 2, 0,184, 8, 2, 0, 69, 7, 12, 0,219, 7, 12, 0,196, 8, 27, 0, 12, 6, 9, 0,197, 8, 7, 0,187, 8, 7, 0,188, 8,
- 7, 0,255, 1, 7, 0,198, 8, 2, 0,199, 8, 2, 0,200, 8, 7, 0,201, 8, 7, 0,202, 8, 2, 0,203, 8, 2, 0,204, 8,
- 9, 0,205, 8, 24, 0,206, 8, 24, 0,207, 8, 24, 0,208, 8, 90, 1,150, 0, 91, 1,209, 8, 88, 1, 8, 0, 88, 1, 0, 0,
- 88, 1, 1, 0, 89, 1,210, 8, 89, 1,211, 8, 87, 1,212, 8, 87, 1,191, 8, 4, 0, 19, 0, 4, 0, 37, 0, 58, 0, 20, 0,
- 27, 0, 31, 0, 39, 0, 75, 0, 12, 0,213, 8, 12, 0,214, 8, 86, 1,215, 8, 12, 0,216, 8, 4, 0, 17, 0, 4, 0,217, 8,
- 4, 0,218, 8, 4, 0,219, 8, 12, 0,220, 8, 91, 1,221, 8, 87, 1,222, 8, 87, 1,223, 8, 9, 0,224, 8, 9, 0,225, 8,
- 4, 0,226, 8, 9, 0,227, 8, 9, 0,228, 8, 9, 0,229, 8, 92, 1, 6, 0, 4, 0,124, 0, 4, 0,126, 0, 4, 0, 69, 7,
- 0, 0,230, 8, 0, 0,231, 8, 2, 0, 37, 0, 93, 1, 16, 0, 2, 0, 25, 7, 2, 0, 26, 7, 2, 0,232, 8, 2, 0, 16, 8,
- 2, 0,233, 8, 2, 0, 68, 0, 7, 0,156, 2, 7, 0,234, 8, 7, 0,235, 8, 2, 0, 32, 1, 0, 0,236, 8, 0, 0,245, 4,
- 2, 0,237, 8, 2, 0, 37, 0, 4, 0,238, 8, 4, 0,239, 8, 94, 1, 9, 0, 7, 0,240, 8, 7, 0,241, 8, 7, 0, 30, 8,
- 7, 0,109, 0, 7, 0,242, 8, 7, 0,198, 5, 2, 0,243, 8, 0, 0,244, 8, 0, 0, 37, 0, 95, 1, 4, 0, 7, 0,245, 8,
- 7, 0,246, 8, 2, 0,243, 8, 2, 0, 37, 0, 96, 1, 3, 0, 7, 0,247, 8, 7, 0,248, 8, 7, 0, 15, 0, 97, 1, 7, 0,
- 0, 0,190, 1, 2, 0,123, 4, 2, 0,124, 4, 2, 0,125, 4, 2, 0, 76, 4, 4, 0,126, 0, 4, 0,188, 3, 98, 1, 7, 0,
- 7, 0,249, 8, 7, 0,250, 8, 7, 0,251, 8, 7, 0, 10, 2, 7, 0,252, 8, 7, 0,253, 8, 7, 0,254, 8, 99, 1, 4, 0,
- 2, 0,255, 8, 2, 0, 0, 9, 2, 0, 1, 9, 2, 0, 2, 9,100, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,101, 1, 2, 0,
- 0, 0,166, 0, 0, 0, 3, 9,102, 1, 1, 0, 0, 0, 20, 0,103, 1, 10, 0, 0, 0, 4, 9, 0, 0, 5, 9, 0, 0,191, 5,
- 0, 0, 6, 9, 2, 0,232, 8, 2, 0, 7, 9, 7, 0, 8, 9, 7, 0, 9, 9, 7, 0, 10, 9, 7, 0,173, 8,104, 1, 2, 0,
- 9, 0, 11, 9, 9, 0, 12, 9,105, 1, 11, 0, 0, 0,125, 4, 0, 0, 17, 0, 0, 0,243, 8, 0, 0,109, 0, 0, 0, 13, 9,
- 0, 0,106, 0, 0, 0,179, 0, 7, 0, 14, 9, 7, 0, 15, 9, 7, 0, 16, 9, 7, 0, 17, 9,106, 1, 8, 0, 7, 0,186, 7,
- 7, 0,125, 0, 7, 0,245, 4, 7, 0, 82, 2, 7, 0, 18, 9, 7, 0,204, 0, 7, 0, 19, 9, 4, 0, 17, 0,107, 1, 4, 0,
- 2, 0, 20, 9, 2, 0, 21, 9, 2, 0, 22, 9, 2, 0, 37, 0,108, 1, 1, 0, 0, 0, 20, 0,109, 1, 4, 0, 7, 0, 5, 0,
- 7, 0, 6, 0, 2, 0, 19, 0, 2, 0, 23, 9,110, 1, 10, 0, 2, 0,124, 3, 2, 0, 19, 0, 7, 0, 12, 4, 7, 0, 24, 9,
- 7, 0, 25, 9, 7, 0, 26, 9, 7, 0, 27, 9,109, 1, 28, 9,109, 1, 29, 9,109, 1, 30, 9, 61, 0, 9, 0, 4, 0, 19, 0,
- 4, 0, 64, 0, 24, 0, 31, 9, 24, 0, 32, 9,110, 1, 33, 9, 7, 0, 34, 9, 7, 0, 35, 9, 7, 0, 36, 9, 7, 0, 37, 9,
-111, 1, 4, 0, 47, 0,150, 2, 7, 0, 38, 9, 7, 0, 93, 1, 7, 0, 37, 0,177, 0, 17, 0, 27, 0, 31, 0,111, 1, 39, 9,
- 61, 0, 28, 9, 51, 0, 75, 1, 2, 0, 19, 0, 2, 0, 90, 5, 4, 0,106, 0, 7, 0, 40, 9, 7, 0, 7, 2, 7, 0, 41, 9,
- 7, 0, 42, 9, 7, 0, 93, 1, 7, 0, 43, 9, 2, 0, 45, 1, 0, 0, 44, 9, 0, 0,117, 3, 0, 0, 92, 0,112, 1, 10, 0,
- 4, 0, 17, 0, 4, 0,125, 0, 4, 0, 19, 0, 4, 0, 90, 3, 4, 0, 45, 9, 4, 0, 46, 9, 4, 0, 47, 9, 0, 0, 92, 0,
- 0, 0, 20, 0, 9, 0, 2, 0, 88, 0, 6, 0,112, 1, 48, 9, 4, 0, 49, 9, 4, 0, 50, 9, 4, 0, 51, 9, 4, 0, 37, 0,
- 9, 0, 52, 9,113, 1, 5, 0, 7, 0, 77, 2, 7, 0,190, 2, 7, 0,220, 1, 2, 0, 53, 9, 2, 0, 37, 0,114, 1, 5, 0,
- 7, 0, 77, 2, 7, 0, 54, 9, 7, 0, 55, 9, 7, 0, 56, 9, 7, 0,190, 2,115, 1, 7, 0, 4, 0, 57, 9, 4, 0, 58, 9,
- 4, 0, 59, 9, 7, 0, 60, 9, 7, 0, 61, 9, 7, 0, 62, 9, 7, 0, 63, 9,116, 1, 8, 0,116, 1, 0, 0,116, 1, 1, 0,
- 32, 0, 45, 0, 4, 0,215, 2, 2, 0, 19, 0, 2, 0, 11, 1, 7, 0,190, 2, 7, 0,194, 7,117, 1, 24, 0, 32, 0, 64, 9,
-114, 1, 86, 3,114, 1, 65, 9,113, 1, 66, 9,114, 1,178, 7,118, 1, 67, 9, 7, 0, 68, 9, 7, 0, 69, 9, 7, 0, 70, 9,
- 7, 0, 61, 9, 7, 0, 62, 9, 7, 0,190, 2, 7, 0,167, 2, 7, 0, 71, 9, 7, 0,106, 0, 7, 0, 72, 9, 4, 0, 57, 9,
- 4, 0, 73, 9, 4, 0, 82, 0, 4, 0, 74, 9, 2, 0, 19, 0, 2, 0, 75, 9, 2, 0, 76, 9, 2, 0,120, 3,119, 1,107, 0,
- 27, 0, 31, 0, 39, 0, 75, 0,120, 1, 77, 9, 4, 0, 19, 0, 2, 0, 17, 0, 2, 0,154, 8, 2, 0, 78, 9, 2, 0, 79, 9,
- 2, 0, 85, 8, 2, 0, 80, 9, 2, 0, 81, 9, 2, 0, 82, 9, 2, 0, 83, 9, 2, 0, 84, 9, 2, 0, 85, 9, 2, 0, 86, 9,
- 2, 0,120, 3, 2, 0, 87, 9, 2, 0, 88, 9, 2, 0, 89, 9, 2, 0, 90, 9, 2, 0, 91, 9, 2, 0, 92, 9, 2, 0,210, 1,
- 2, 0,171, 7, 2, 0,147, 7, 2, 0, 93, 9, 2, 0, 94, 9, 2, 0,118, 3, 2, 0,119, 3, 2, 0, 95, 9, 2, 0, 96, 9,
- 2, 0, 97, 9, 2, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9, 7, 0,101, 9, 2, 0,102, 9, 2, 0,103, 9, 7, 0,104, 9,
- 7, 0,105, 9, 7, 0,106, 9, 7, 0,153, 7, 7, 0, 89, 0, 7, 0,167, 2, 7, 0,159, 7, 7, 0,107, 9, 7, 0,108, 9,
- 7, 0,109, 9, 4, 0,154, 7, 4, 0,152, 7, 4, 0,110, 9, 7, 0,155, 7, 7, 0,156, 7, 7, 0,157, 7, 7, 0,111, 9,
- 7, 0,112, 9, 7, 0,113, 9, 7, 0,114, 9, 7, 0,115, 9, 7, 0,116, 9, 7, 0,117, 9, 7, 0,118, 9, 7, 0, 42, 3,
- 7, 0,106, 0, 7, 0,119, 9, 7, 0,120, 9, 7, 0,121, 9, 7, 0,122, 9, 7, 0,123, 9, 7, 0,124, 9, 7, 0,125, 9,
- 4, 0,126, 9, 4, 0,127, 9, 7, 0,128, 9, 7, 0,129, 9, 7, 0,130, 9, 7, 0,131, 9, 7, 0,132, 9, 7, 0,133, 9,
- 7, 0,134, 9, 7, 0,114, 3, 7, 0,112, 3, 7, 0,113, 3, 7, 0,135, 9, 7, 0,136, 9, 7, 0,137, 9, 7, 0,138, 9,
- 7, 0,139, 9, 7, 0,140, 9, 7, 0,141, 9, 7, 0,142, 9, 7, 0,143, 9, 7, 0,144, 9, 7, 0,145, 9, 7, 0,146, 9,
- 7, 0,147, 9, 4, 0,148, 9, 4, 0,149, 9, 7, 0,150, 9, 64, 0, 75, 3, 64, 0,151, 9, 32, 0,152, 9, 32, 0,153, 9,
- 36, 0, 80, 0,154, 0, 73, 3,154, 0,154, 9,141, 0, 41, 0,141, 0, 0, 0,141, 0, 1, 0,119, 1,155, 9,117, 1,165, 3,
-115, 1, 79, 8,121, 1,156, 9, 9, 0,157, 9,122, 1,158, 9,122, 1,159, 9, 12, 0,160, 9, 12, 0,161, 9,155, 0, 74, 3,
- 32, 0,162, 9, 32, 0,163, 9, 32, 0, 38, 0, 12, 0,164, 9, 12, 0,165, 9, 12, 0,124, 8, 0, 0, 20, 0, 7, 0,208, 0,
- 7, 0,194, 2, 7, 0,166, 9, 4, 0,118, 2, 4, 0, 19, 0, 4, 0,154, 7, 4, 0,167, 9, 4, 0,168, 9, 4, 0,169, 9,
- 2, 0,215, 0, 2, 0,170, 9, 2, 0,171, 9, 2, 0, 67, 3, 2, 0,172, 9, 2, 0,120, 3, 0, 0,173, 9, 2, 0,174, 9,
- 2, 0,175, 9, 2, 0,176, 9, 9, 0,177, 9,130, 0,209, 3,123, 1,178, 9,128, 0, 34, 0,124, 1,179, 9, 7, 0,179, 3,
- 7, 0,180, 9, 7, 0,181, 9, 7, 0, 15, 4, 7, 0,182, 9, 7, 0, 52, 3, 7, 0, 42, 3, 7, 0,183, 9, 7, 0, 9, 2,
- 7, 0,184, 9, 7, 0,185, 9, 7, 0,186, 9, 7, 0,187, 9, 7, 0,188, 9, 7, 0,189, 9, 7, 0,180, 3, 7, 0,190, 9,
- 7, 0,191, 9, 7, 0,192, 9, 7, 0,181, 3, 7, 0,177, 3, 7, 0,178, 3, 4, 0,193, 9, 4, 0, 90, 0, 4, 0,194, 9,
- 4, 0,195, 9, 2, 0,196, 9, 2, 0,197, 9, 2, 0,198, 9, 2, 0,199, 9, 2, 0,200, 9, 2, 0, 37, 0, 4, 0, 70, 0,
-129, 0, 8, 0,124, 1,201, 9, 7, 0,202, 9, 7, 0,203, 9, 7, 0,164, 1, 7, 0,204, 9, 4, 0, 90, 0, 2, 0,205, 9,
- 2, 0,206, 9,125, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,207, 9,126, 1, 6, 0,126, 1, 0, 0,
-126, 1, 1, 0,125, 1,208, 9, 4, 0,209, 9, 2, 0,210, 9, 2, 0, 19, 0,127, 1, 5, 0,127, 1, 0, 0,127, 1, 1, 0,
- 12, 0,211, 9, 4, 0,212, 9, 4, 0, 19, 0,128, 1, 9, 0,128, 1, 0, 0,128, 1, 1, 0, 12, 0,124, 0,127, 1,213, 9,
- 4, 0, 19, 0, 2, 0,210, 9, 2, 0,214, 9, 7, 0, 91, 0, 0, 0,215, 9,191, 0, 6, 0, 27, 0, 31, 0, 12, 0,139, 4,
- 4, 0, 19, 0, 2, 0,216, 9, 2, 0,217, 9, 9, 0,218, 9,129, 1, 7, 0,129, 1, 0, 0,129, 1, 1, 0, 2, 0, 17, 0,
- 2, 0, 19, 0, 4, 0, 23, 0, 0, 0,219, 9, 0, 0,220, 9,130, 1, 5, 0, 12, 0,221, 9, 4, 0,222, 9, 4, 0,223, 9,
- 4, 0, 19, 0, 4, 0, 37, 0,131, 1, 13, 0, 27, 0, 31, 0,132, 1,224, 9,132, 1,225, 9, 12, 0,226, 9, 4, 0,227, 9,
- 2, 0,228, 9, 2, 0, 37, 0, 12, 0,229, 9, 12, 0,230, 9,130, 1,231, 9, 12, 0,232, 9, 12, 0,233, 9, 12, 0,234, 9,
-132, 1, 30, 0,132, 1, 0, 0,132, 1, 1, 0, 9, 0,235, 9, 4, 0, 4, 7, 4, 0, 37, 0,201, 0,180, 5,201, 0,236, 9,
- 0, 0,237, 9, 2, 0,238, 9, 2, 0,239, 9, 2, 0, 25, 7, 2, 0, 26, 7, 2, 0,240, 9, 2, 0,241, 9, 2, 0, 90, 3,
- 2, 0, 38, 6, 2, 0,242, 9, 2, 0,243, 9, 4, 0,160, 1,133, 1,244, 9,134, 1,245, 9,135, 1,246, 9, 4, 0,247, 9,
- 4, 0,248, 9, 9, 0,249, 9, 12, 0,250, 9, 12, 0,230, 9, 12, 0, 43, 7, 12, 0,251, 9, 12, 0,252, 9,136, 1, 16, 0,
-136, 1, 0, 0,136, 1, 1, 0, 0, 0,253, 9,137, 1,254, 9, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0,255, 9, 2, 0, 0, 10,
- 2, 0, 1, 10, 2, 0, 2, 10, 2, 0, 3, 10, 2, 0, 4, 10, 2, 0, 5, 10, 2, 0, 6, 10, 2, 0, 70, 0, 2, 0,160, 1,
-138, 1, 9, 0,138, 1, 0, 0,138, 1, 1, 0, 12, 0, 7, 10, 0, 0, 8, 10, 2, 0, 9, 10, 2, 0, 10, 10, 2, 0, 11, 10,
- 2, 0, 37, 0, 9, 0, 12, 10,209, 0, 10, 0,209, 0, 0, 0,209, 0, 1, 0, 0, 0,253, 9, 26, 0, 30, 0,139, 1, 19, 7,
- 9, 0, 13, 10,137, 1,254, 9,130, 1, 14, 10, 12, 0, 15, 10,209, 0, 16, 10,133, 1, 23, 0,133, 1, 0, 0,133, 1, 1, 0,
- 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 5, 0, 2, 0, 6, 0, 2, 0, 17, 10, 2, 0, 18, 10, 2, 0, 19, 10, 2, 0, 20, 10,
- 0, 0, 21, 10, 0, 0, 37, 0, 2, 0,255, 9, 2, 0, 0, 10, 2, 0, 1, 10, 2, 0, 2, 10, 2, 0, 3, 10, 2, 0, 43, 0,
- 0, 0, 22, 10, 2, 0, 23, 10, 2, 0, 24, 10, 4, 0, 70, 0, 9, 0, 13, 10,140, 1, 8, 0,140, 1, 0, 0,140, 1, 1, 0,
- 9, 0, 2, 0, 9, 0, 25, 10, 0, 0,132, 3, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0, 26, 10,141, 1, 5, 0, 7, 0, 27, 10,
- 4, 0, 28, 10, 4, 0, 29, 10, 4, 0, 11, 1, 4, 0, 19, 0,142, 1, 6, 0, 7, 0, 30, 10, 7, 0, 31, 10, 7, 0, 32, 10,
- 7, 0, 33, 10, 4, 0, 17, 0, 4, 0, 19, 0,143, 1, 5, 0, 7, 0,249, 7, 7, 0,250, 7, 7, 0,190, 2, 2, 0,224, 1,
- 2, 0,225, 1,144, 1, 5, 0,143, 1, 2, 0, 4, 0, 54, 0, 7, 0, 34, 10, 7, 0,249, 7, 7, 0,250, 7,145, 1, 4, 0,
- 2, 0, 35, 10, 2, 0, 36, 10, 2, 0, 37, 10, 2, 0, 38, 10,146, 1, 2, 0, 42, 0, 9, 6, 26, 0, 73, 8,147, 1, 3, 0,
- 24, 0, 39, 10, 4, 0, 19, 0, 4, 0, 37, 0,148, 1, 6, 0, 7, 0,106, 0, 7, 0,142, 2, 7, 0, 40, 10, 7, 0, 37, 0,
- 2, 0,214, 0, 2, 0, 41, 10,149, 1, 7, 0,149, 1, 0, 0,149, 1, 1, 0, 27, 0, 12, 6, 0, 0, 42, 10, 4, 0, 43, 10,
- 4, 0, 90, 0, 0, 0,132, 3,150, 1, 6, 0, 12, 0,124, 8, 0, 0, 44, 10, 7, 0, 61, 0, 7, 0, 26, 10, 4, 0, 17, 0,
- 4, 0, 19, 0,151, 1, 3, 0, 7, 0, 45, 10, 4, 0, 19, 0, 4, 0, 37, 0,152, 1, 15, 0,152, 1, 0, 0,152, 1, 1, 0,
- 58, 1,112, 8,150, 1, 62, 0, 12, 0, 16, 3, 35, 0, 50, 0,151, 1, 46, 10, 4, 0, 54, 0, 7, 0, 61, 0, 2, 0, 19, 0,
- 2, 0,252, 0, 4, 0, 43, 10, 0, 0, 42, 10, 4, 0, 47, 10, 7, 0, 48, 10,153, 1, 2, 0, 0, 0, 49, 10, 0, 0, 50, 10,
-154, 1, 4, 0,154, 1, 0, 0,154, 1, 1, 0,151, 0,228, 2, 12, 0, 51, 10,155, 1, 24, 0,155, 1, 0, 0,155, 1, 1, 0,
- 12, 0, 52, 10,151, 0,224, 7,154, 1, 53, 10, 12, 0, 54, 10, 12, 0, 16, 3, 0, 0,132, 3, 7, 0, 26, 10, 7, 0, 55, 10,
- 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,169, 8, 7, 0,170, 8, 7, 0,157, 2, 7, 0,173, 8, 7, 0,226, 7, 7, 0,174, 8,
- 2, 0, 56, 10, 2, 0, 57, 10, 2, 0, 43, 0, 2, 0, 17, 0, 4, 0, 19, 0, 4, 0, 70, 0,156, 1, 6, 0,156, 1, 0, 0,
-156, 1, 1, 0, 12, 0, 52, 10, 4, 0, 19, 0, 4, 0, 81, 2, 0, 0,132, 3,157, 1, 10, 0,157, 1, 0, 0,157, 1, 1, 0,
- 27, 0, 12, 6, 0, 0, 58, 10, 4, 0, 59, 10, 4, 0, 60, 10, 0, 0, 42, 10, 4, 0, 43, 10, 2, 0, 19, 0, 2, 0, 61, 10,
-158, 1, 6, 0,158, 1, 0, 0,158, 1, 1, 0, 12, 0, 62, 10, 0, 0,132, 3, 4, 0, 19, 0, 4, 0, 63, 10,159, 1, 5, 0,
-159, 1, 0, 0,159, 1, 1, 0, 0, 0, 42, 10, 4, 0, 43, 10, 7, 0,134, 2, 39, 0, 9, 0,151, 0, 11, 3,151, 0, 64, 10,
-154, 1, 53, 10, 12, 0, 65, 10,155, 1, 66, 10, 12, 0, 67, 10, 12, 0, 68, 10, 4, 0, 19, 0, 4, 0,215, 0,160, 1, 2, 0,
- 27, 0, 31, 0, 39, 0, 75, 0,161, 1, 5, 0,161, 1, 0, 0,161, 1, 1, 0, 4, 0, 17, 0, 4, 0, 19, 0, 0, 0, 20, 0,
-162, 1, 6, 0,161, 1, 69, 10, 32, 0, 45, 0, 4, 0, 70, 10, 7, 0, 71, 10, 4, 0, 72, 10, 4, 0, 32, 8,163, 1, 3, 0,
-161, 1, 69, 10, 4, 0, 70, 10, 7, 0, 73, 10,164, 1, 8, 0,161, 1, 69, 10, 32, 0, 45, 0, 7, 0, 6, 1, 7, 0, 74, 10,
- 7, 0,194, 2, 7, 0, 30, 8, 4, 0, 70, 10, 4, 0, 75, 10,165, 1, 5, 0,161, 1, 69, 10, 7, 0, 76, 10, 7, 0,112, 7,
- 7, 0,163, 2, 7, 0, 57, 0,166, 1, 3, 0,161, 1, 69, 10, 7, 0, 30, 8, 7, 0, 77, 10,118, 1, 4, 0, 7, 0, 78, 10,
- 7, 0,121, 9, 2, 0, 79, 10, 2, 0, 11, 1,167, 1, 14, 0,167, 1, 0, 0,167, 1, 1, 0, 12, 0, 80, 10, 12, 0, 81, 10,
- 12, 0, 82, 10, 0, 0, 20, 0, 4, 0, 31, 0, 4, 0, 19, 0, 4, 0, 83, 10, 7, 0, 84, 10, 4, 0, 72, 10, 4, 0, 32, 8,
- 7, 0,139, 3, 7, 0,165, 2,120, 1, 23, 0, 4, 0, 70, 10, 4, 0, 85, 10, 7, 0, 86, 10, 7, 0, 57, 0, 7, 0, 87, 10,
- 7, 0,161, 2, 7, 0, 78, 10, 7, 0, 88, 10, 7, 0,142, 2, 7, 0, 89, 10, 7, 0, 12, 4, 7, 0, 90, 10, 7, 0, 91, 10,
- 7, 0, 92, 10, 7, 0, 93, 10, 7, 0, 94, 10, 7, 0, 95, 10, 7, 0, 96, 10, 7, 0, 97, 10, 7, 0, 98, 10, 7, 0, 99, 10,
- 7, 0,100, 10, 12, 0,101, 10, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 73,110,115,116, 97,110, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97,
+ 0, 69,120,112,108,111,100,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,117,108,116,105,114,101,115, 77,111,100,
+105,102,105,101,114, 68, 97,116, 97, 0, 70,108,117,105,100,115,105,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 70,
+108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 83,104,114,105,110,107,119,114, 97,112, 77,111,100,105,102,105,
+101,114, 68, 97,116, 97, 0, 83,105,109,112,108,101, 68,101,102,111,114,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0,
+ 76, 97,116,116,105, 99,101, 0, 98, 68,101,102,111,114,109, 71,114,111,117,112, 0, 83, 99,117,108,112,116, 83,101,115,115,105,
+111,110, 0, 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 0, 98, 71, 80,100, 97,116, 97, 0, 66,117,108,108,101,116, 83,
+111,102,116, 66,111,100,121, 0, 80, 97,114,116, 68,101,102,108,101, 99,116, 0, 83,111,102,116, 66,111,100,121, 0, 79, 98, 72,
+111,111,107, 0, 82, 78, 71, 0, 80, 84, 67, 97, 99,104,101, 77,101,109, 0, 80, 84, 67, 97, 99,104,101, 69,100,105,116, 0, 83,
+ 66, 86,101,114,116,101,120, 0, 66,111,100,121, 80,111,105,110,116, 0, 66,111,100,121, 83,112,114,105,110,103, 0, 83, 66, 83,
+ 99,114, 97,116, 99,104, 0, 87,111,114,108,100, 0, 66, 97,115,101, 0, 65,118,105, 67,111,100,101, 99, 68, 97,116, 97, 0, 81,
+117,105, 99,107,116,105,109,101, 67,111,100,101, 99, 68, 97,116, 97, 0, 70, 70, 77,112,101,103, 67,111,100,101, 99, 68, 97,116,
+ 97, 0, 65,117,100,105,111, 68, 97,116, 97, 0, 83, 99,101,110,101, 82,101,110,100,101,114, 76, 97,121,101,114, 0, 82,101,110,
+100,101,114, 68, 97,116, 97, 0, 82,101,110,100,101,114, 80,114,111,102,105,108,101, 0, 71, 97,109,101, 68,111,109,101, 0, 71,
+ 97,109,101, 70,114, 97,109,105,110,103, 0, 71, 97,109,101, 68, 97,116, 97, 0, 84,105,109,101, 77, 97,114,107,101,114, 0, 80,
+ 97,105,110,116, 0, 66,114,117,115,104, 0, 73,109, 97,103,101, 80, 97,105,110,116, 83,101,116,116,105,110,103,115, 0, 80, 97,
+114,116,105, 99,108,101, 66,114,117,115,104, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 69,100,105,116, 83,101,116,116,
+105,110,103,115, 0, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110, 0, 83, 99,117,108,112,116,
+ 0, 86, 80, 97,105,110,116, 0, 84,111,111,108, 83,101,116,116,105,110,103,115, 0, 98, 83,116, 97,116,115, 0, 85,110,105,116,
+ 83,101,116,116,105,110,103,115, 0, 69,100,105,116,105,110,103, 0, 83, 99,101,110,101, 83,116, 97,116,115, 0, 68, 97,103, 70,
+111,114,101,115,116, 0, 66, 71,112,105, 99, 0, 82,101,103,105,111,110, 86,105,101,119, 51, 68, 0, 82,101,110,100,101,114, 73,
+110,102,111, 0, 82,101,116,111,112,111, 86,105,101,119, 68, 97,116, 97, 0, 86,105,101,119, 68,101,112,116,104,115, 0, 83,109,
+111,111,116,104, 86,105,101,119, 83,116,111,114,101, 0,119,109, 84,105,109,101,114, 0, 86,105,101,119, 51, 68, 0, 83,112, 97,
+ 99,101, 76,105,110,107, 0, 86,105,101,119, 50, 68, 0, 83,112, 97, 99,101, 73,110,102,111, 0, 98, 83, 99,114,101,101,110, 0,
+ 83,112, 97, 99,101, 73,112,111, 0, 98, 68,111,112,101, 83,104,101,101,116, 0, 83,112, 97, 99,101, 66,117,116,115, 0, 83,112,
+ 97, 99,101, 83,101,113, 0, 70,105,108,101, 83,101,108,101, 99,116, 80, 97,114, 97,109,115, 0, 83,112, 97, 99,101, 70,105,108,
+101, 0, 70,105,108,101, 76,105,115,116, 0,119,109, 79,112,101,114, 97,116,111,114, 0, 70,105,108,101, 76, 97,121,111,117,116,
+ 0, 83,112, 97, 99,101, 79,111,112,115, 0, 84,114,101,101, 83,116,111,114,101, 0, 84,114,101,101, 83,116,111,114,101, 69,108,
+101,109, 0, 83,112, 97, 99,101, 73,109, 97,103,101, 0, 83,112, 97, 99,101, 78,108, 97, 0, 83,112, 97, 99,101, 84,101,120,116,
+ 0, 83, 99,114,105,112,116, 0, 83,112, 97, 99,101, 83, 99,114,105,112,116, 0, 83,112, 97, 99,101, 84,105,109,101, 0, 83,112,
+ 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,105, 99, 0, 83,112, 97, 99,101, 73,109, 97, 83,101,108, 0, 67,
+111,110,115,111,108,101, 76,105,110,101, 0, 83,112, 97, 99,101, 67,111,110,115,111,108,101, 0, 83,112, 97, 99,101, 85,115,101,
+114, 80,114,101,102, 0,117,105, 70,111,110,116, 0,117,105, 70,111,110,116, 83,116,121,108,101, 0,117,105, 83,116,121,108,101,
+ 0,117,105, 87,105,100,103,101,116, 67,111,108,111,114,115, 0,117,105, 87,105,100,103,101,116, 83,116, 97,116,101, 67,111,108,
+111,114,115, 0, 84,104,101,109,101, 85, 73, 0, 84,104,101,109,101, 83,112, 97, 99,101, 0, 84,104,101,109,101, 87,105,114,101,
+ 67,111,108,111,114, 0, 98, 84,104,101,109,101, 0, 83,111,108,105,100, 76,105,103,104,116, 0, 85,115,101,114, 68,101,102, 0,
+ 83, 99,114, 86,101,114,116, 0, 83, 99,114, 69,100,103,101, 0, 80, 97,110,101,108, 0, 80, 97,110,101,108, 84,121,112,101, 0,
+117,105, 76, 97,121,111,117,116, 0, 83, 99,114, 65,114,101, 97, 0, 83,112, 97, 99,101, 84,121,112,101, 0, 65, 82,101,103,105,
+111,110, 0, 65, 82,101,103,105,111,110, 84,121,112,101, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114,105,112, 69,
+108,101,109, 0, 84, 83,116,114,105,112, 69,108,101,109, 0, 83,116,114,105,112, 67,114,111,112, 0, 83,116,114,105,112, 84,114,
+ 97,110,115,102,111,114,109, 0, 83,116,114,105,112, 67,111,108,111,114, 66, 97,108, 97,110, 99,101, 0, 83,116,114,105,112, 80,
+114,111,120,121, 0, 83,116,114,105,112, 0, 80,108,117,103,105,110, 83,101,113, 0, 83,101,113,117,101,110, 99,101, 0, 98, 83,
+111,117,110,100, 0, 83,111,117,110,100, 72, 97,110,100,108,101, 0, 77,101,116, 97, 83,116, 97, 99,107, 0, 87,105,112,101, 86,
+ 97,114,115, 0, 71,108,111,119, 86, 97,114,115, 0, 84,114, 97,110,115,102,111,114,109, 86, 97,114,115, 0, 83,111,108,105,100,
+ 67,111,108,111,114, 86, 97,114,115, 0, 83,112,101,101,100, 67,111,110,116,114,111,108, 86, 97,114,115, 0, 69,102,102,101, 99,
+116, 0, 66,117,105,108,100, 69,102,102, 0, 80, 97,114,116, 69,102,102, 0, 80, 97,114,116,105, 99,108,101, 0, 87, 97,118,101,
+ 69,102,102, 0, 98, 80,114,111,112,101,114,116,121, 0, 98, 78,101, 97,114, 83,101,110,115,111,114, 0, 98, 77,111,117,115,101,
+ 83,101,110,115,111,114, 0, 98, 84,111,117, 99,104, 83,101,110,115,111,114, 0, 98, 75,101,121, 98,111, 97,114,100, 83,101,110,
+115,111,114, 0, 98, 80,114,111,112,101,114,116,121, 83,101,110,115,111,114, 0, 98, 65, 99,116,117, 97,116,111,114, 83,101,110,
+115,111,114, 0, 98, 68,101,108, 97,121, 83,101,110,115,111,114, 0, 98, 67,111,108,108,105,115,105,111,110, 83,101,110,115,111,
+114, 0, 98, 82, 97,100, 97,114, 83,101,110,115,111,114, 0, 98, 82, 97,110,100,111,109, 83,101,110,115,111,114, 0, 98, 82, 97,
+121, 83,101,110,115,111,114, 0, 98, 77,101,115,115, 97,103,101, 83,101,110,115,111,114, 0, 98, 83,101,110,115,111,114, 0, 98,
+ 67,111,110,116,114,111,108,108,101,114, 0, 98, 74,111,121,115,116,105, 99,107, 83,101,110,115,111,114, 0, 98, 69,120,112,114,
+101,115,115,105,111,110, 67,111,110,116, 0, 98, 80,121,116,104,111,110, 67,111,110,116, 0, 98, 65, 99,116,117, 97,116,111,114,
+ 0, 98, 65,100,100, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 65, 99,116,105,111,110, 65, 99,116,117, 97,
+116,111,114, 0, 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 83,111,117,110,100, 51, 68, 0, 98, 69,100,105,116,
+ 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83, 99,101,110,101, 65, 99,116,117, 97,116,111,114, 0, 98, 80,
+114,111,112,101,114,116,121, 65, 99,116,117, 97,116,111,114, 0, 98, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0,
+ 98, 73,112,111, 65, 99,116,117, 97,116,111,114, 0, 98, 67, 97,109,101,114, 97, 65, 99,116,117, 97,116,111,114, 0, 98, 67,111,
+110,115,116,114, 97,105,110,116, 65, 99,116,117, 97,116,111,114, 0, 98, 71,114,111,117,112, 65, 99,116,117, 97,116,111,114, 0,
+ 98, 82, 97,110,100,111,109, 65, 99,116,117, 97,116,111,114, 0, 98, 77,101,115,115, 97,103,101, 65, 99,116,117, 97,116,111,114,
+ 0, 98, 71, 97,109,101, 65, 99,116,117, 97,116,111,114, 0, 98, 86,105,115,105, 98,105,108,105,116,121, 65, 99,116,117, 97,116,
+111,114, 0, 98, 84,119,111, 68, 70,105,108,116,101,114, 65, 99,116,117, 97,116,111,114, 0, 98, 80, 97,114,101,110,116, 65, 99,
+116,117, 97,116,111,114, 0, 98, 83,116, 97,116,101, 65, 99,116,117, 97,116,111,114, 0, 70,114,101,101, 67, 97,109,101,114, 97,
+ 0, 83,112, 97, 99,101, 83,111,117,110,100, 0, 71,114,111,117,112, 79, 98,106,101, 99,116, 0, 66,111,110,101, 0, 98, 65,114,
+109, 97,116,117,114,101, 0, 98, 77,111,116,105,111,110, 80, 97,116,104, 86,101,114,116, 0, 98, 77,111,116,105,111,110, 80, 97,
+116,104, 0, 98, 65,110,105,109, 86,105,122, 83,101,116,116,105,110,103,115, 0, 98, 80,111,115,101, 67,104, 97,110,110,101,108,
+ 0, 98, 65, 99,116,105,111,110, 71,114,111,117,112, 0, 83,112, 97, 99,101, 65, 99,116,105,111,110, 0, 98, 65, 99,116,105,111,
+110, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,
+115,116,114, 97,105,110,116, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 84, 97,114,103,101,116, 0, 98, 80,121,116,104,111,
+110, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 75,105,110,101,109, 97,116,105, 99, 67,111,110,115,116,114, 97,105,110,116,
+ 0, 98, 84,114, 97, 99,107, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 97,116,101, 76,105,107,101, 67,
+111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99, 97,116,101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, 0,
+ 98, 77,105,110, 77, 97,120, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,105,122,101, 76,105,107,101, 67,111,110,115,116,
+114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99,107, 84,114, 97,
+ 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 70,111,108,108,111,119, 80, 97,116,104, 67,111,110,115,116,114, 97,105,
+110,116, 0, 98, 83,116,114,101,116, 99,104, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,105,103,105,100, 66,111,
+100,121, 74,111,105,110,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,108, 97,109,112, 84,111, 67,111,110,115,116,114,
+ 97,105,110,116, 0, 98, 67,104,105,108,100, 79,102, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 84,114, 97,110,115,102,111,
+114,109, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116,
+ 0, 98, 82,111,116, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,105,122,101, 76,105,109,105,116, 67,
+111,110,115,116,114, 97,105,110,116, 0, 98, 68,105,115,116, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98,
+ 83,104,114,105,110,107,119,114, 97,112, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 77,111,100,105,
+102,105,101,114, 0, 98, 65, 99,116,105,111,110, 83,116,114,105,112, 0, 98, 78,111,100,101, 83,116, 97, 99,107, 0, 98, 78,111,
+100,101, 83,111, 99,107,101,116, 0, 98, 78,111,100,101, 76,105,110,107, 0, 98, 78,111,100,101, 0, 98, 78,111,100,101, 80,114,
+101,118,105,101,119, 0, 98, 78,111,100,101, 84,121,112,101, 0, 78,111,100,101, 73,109, 97,103,101, 65,110,105,109, 0, 78,111,
+100,101, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 68, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 66,105,108,
+ 97,116,101,114, 97,108, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 72,117,101, 83, 97,116, 0, 78,111,100,101, 73,109,
+ 97,103,101, 70,105,108,101, 0, 78,111,100,101, 67,104,114,111,109, 97, 0, 78,111,100,101, 84,119,111, 88, 89,115, 0, 78,111,
+100,101, 84,119,111, 70,108,111, 97,116,115, 0, 78,111,100,101, 71,101,111,109,101,116,114,121, 0, 78,111,100,101, 86,101,114,
+116,101,120, 67,111,108, 0, 78,111,100,101, 68,101,102,111, 99,117,115, 0, 78,111,100,101, 83, 99,114,105,112,116, 68,105, 99,
+116, 0, 78,111,100,101, 71,108, 97,114,101, 0, 78,111,100,101, 84,111,110,101,109, 97,112, 0, 78,111,100,101, 76,101,110,115,
+ 68,105,115,116, 0, 84,101,120, 78,111,100,101, 79,117,116,112,117,116, 0, 67,117,114,118,101, 77, 97,112, 80,111,105,110,116,
+ 0, 67,117,114,118,101, 77, 97,112, 0, 66,114,117,115,104, 67,108,111,110,101, 0, 67,117,115,116,111,109, 68, 97,116, 97, 76,
+ 97,121,101,114, 0, 72, 97,105,114, 75,101,121, 0, 80, 97,114,116,105, 99,108,101, 75,101,121, 0, 66,111,105,100, 80, 97,114,
+116,105, 99,108,101, 0, 66,111,105,100, 68, 97,116, 97, 0, 67,104,105,108,100, 80, 97,114,116,105, 99,108,101, 0, 80, 97,114,
+116,105, 99,108,101, 84, 97,114,103,101,116, 0, 80, 97,114,116,105, 99,108,101, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,
+101, 83,101,116,116,105,110,103,115, 0, 66,111,105,100, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, 99,108,101, 67,
+ 97, 99,104,101, 75,101,121, 0, 75, 68, 84,114,101,101, 0, 76,105,110,107, 78,111,100,101, 0, 98, 71, 80, 68,115,112,111,105,
+110,116, 0, 98, 71, 80, 68,115,116,114,111,107,101, 0, 98, 71, 80, 68,102,114, 97,109,101, 0, 98, 71, 80, 68,108, 97,121,101,
+114, 0, 82,101,112,111,114,116, 0, 82,101,112,111,114,116, 76,105,115,116, 0,119,109, 87,105,110,100,111,119, 77, 97,110, 97,
+103,101,114, 0,119,109, 87,105,110,100,111,119, 0,119,109, 69,118,101,110,116, 0,119,109, 83,117, 98, 87,105,110,100,111,119,
+ 0,119,109, 71,101,115,116,117,114,101, 0,119,109, 75,101,121,109, 97,112, 73,116,101,109, 0, 80,111,105,110,116,101,114, 82,
+ 78, 65, 0,119,109, 75,101,121, 77, 97,112, 0,119,109, 79,112,101,114, 97,116,111,114, 84,121,112,101, 0, 70, 77,111,100,105,
+102,105,101,114, 0, 70, 77,111,100, 95, 71,101,110,101,114, 97,116,111,114, 0, 70, 77,111,100, 95, 70,117,110, 99,116,105,111,
+110, 71,101,110,101,114, 97,116,111,114, 0, 70, 67, 77, 95, 69,110,118,101,108,111,112,101, 68, 97,116, 97, 0, 70, 77,111,100,
+ 95, 69,110,118,101,108,111,112,101, 0, 70, 77,111,100, 95, 67,121, 99,108,101,115, 0, 70, 77,111,100, 95, 80,121,116,104,111,
+110, 0, 70, 77,111,100, 95, 76,105,109,105,116,115, 0, 70, 77,111,100, 95, 78,111,105,115,101, 0, 68,114,105,118,101,114, 84,
+ 97,114,103,101,116, 0, 67,104, 97,110,110,101,108, 68,114,105,118,101,114, 0, 70, 80,111,105,110,116, 0, 70, 67,117,114,118,
+101, 0, 65,110,105,109, 77, 97,112, 80, 97,105,114, 0, 65,110,105,109, 77, 97,112,112,101,114, 0, 78,108, 97, 83,116,114,105,
+112, 0, 78,108, 97, 84,114, 97, 99,107, 0, 75, 83, 95, 80, 97,116,104, 0, 75,101,121,105,110,103, 83,101,116, 0, 65,110,105,
+109, 79,118,101,114,114,105,100,101, 0, 73,100, 65,100,116, 84,101,109,112,108, 97,116,101, 0, 66,111,105,100, 82,117,108,101,
+ 0, 66,111,105,100, 82,117,108,101, 71,111, 97,108, 65,118,111,105,100, 0, 66,111,105,100, 82,117,108,101, 65,118,111,105,100,
+ 67,111,108,108,105,115,105,111,110, 0, 66,111,105,100, 82,117,108,101, 70,111,108,108,111,119, 76,101, 97,100,101,114, 0, 66,
+111,105,100, 82,117,108,101, 65,118,101,114, 97,103,101, 83,112,101,101,100, 0, 66,111,105,100, 82,117,108,101, 70,105,103,104,
+116, 0, 66,111,105,100, 83,116, 97,116,101, 0, 70, 76, 85, 73, 68, 95, 51, 68, 0, 87, 84, 85, 82, 66, 85, 76, 69, 78, 67, 69,
+ 0, 0, 0, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 0, 12, 0,
+ 8, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, 12, 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 20, 0, 76, 0, 52, 0,
+ 40, 2, 0, 0, 32, 0,140, 0,100, 3, 92, 0, 36, 0, 56, 0, 84, 0,112, 0,124, 0, 56, 0, 24, 0, 40, 0,120, 0, 12, 0,
+120, 0, 36, 0, 92, 5,128, 1, 0, 0, 0, 0, 0, 0,144, 0, 40, 1, 84, 1, 24, 0, 8, 3,168, 0, 0, 0, 76, 0,128, 1,
+ 24, 1,140, 0,132, 0,124, 1, 8, 1, 56, 0, 88, 0,184, 2, 76, 0, 60, 1, 0, 0,108, 0,104, 0,148, 0, 56, 0, 8, 0,
+ 16, 0, 92, 1, 0, 0, 0, 0, 0, 0, 24, 1, 20, 0, 44, 0, 60, 0, 24, 0, 12, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0,
+ 24, 0, 76, 0, 32, 0, 8, 0, 12, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 12, 0, 0, 0, 16, 0, 64, 0, 24, 0,
+ 12, 0, 40, 0, 56, 0, 72, 0, 92, 0,100, 0, 72, 0,100, 0,120, 0, 68, 0, 64, 0,112, 0, 64, 0, 76, 0,176, 0, 48, 0,
+168, 0,152, 0,156, 0, 64, 0, 96, 0,108, 0,188, 0,104, 0,216, 0, 56, 0, 84, 0, 0, 0,132, 0, 28, 0,240, 1,104, 0,
+ 0, 0, 80, 0, 0, 0, 0, 0, 68, 0, 8, 0, 8, 0,220, 0, 80, 0, 76, 0, 68, 0, 68, 0, 64, 0,164, 1,112, 0,108, 0,
+188, 0, 40, 0, 0, 0, 92, 0, 56, 0, 72, 0,120, 0,128, 0,252, 0,208, 0, 0, 0, 92, 0, 0, 0, 16, 0, 0, 0, 0, 0,
+ 0, 0,104, 1, 28, 0,176, 0,144, 0, 52, 0, 16, 0, 72, 0, 0, 4, 56, 0, 20, 0, 16, 0, 92, 0, 80, 0, 24, 0,196, 0,
+ 36, 0, 8, 0,100, 0, 80, 0, 48, 0, 52, 0, 72, 1, 32, 0, 8, 0, 24, 2, 0, 0, 0, 0, 56, 0,216, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,240, 0, 40, 0,148, 0, 48, 0,140, 0,208, 0, 20, 0,224, 0,216, 0,204, 1, 60, 0, 0, 0,112, 0,
+ 0, 0, 4, 1, 12, 0, 12, 0,136, 0,200, 0,124, 2, 80, 2, 40, 0,180, 0,244, 0, 52, 0,148, 2, 28, 0, 80, 0, 24, 0,
+ 16, 1, 32, 0,224, 0, 32, 0, 32, 0, 80, 2, 16, 1, 16, 0,200, 21, 56, 0, 56, 11, 20, 0, 24, 0, 56, 1, 0, 0, 0, 0,
+ 96, 0, 0, 0,248, 0, 0, 0, 32, 0, 80, 0, 28, 0, 16, 0, 8, 0, 52, 0,252, 0,240, 0,168, 1,196, 0, 8, 1, 48, 0,
+ 16, 0, 12, 0, 24, 0, 48, 0, 16, 0, 20, 0, 16, 0, 24, 0, 56, 1, 0, 0, 56, 0, 52, 0, 48, 0, 8, 0, 44, 0, 72, 0,
+104, 0, 40, 0, 8, 0, 72, 0, 44, 0, 40, 0,108, 0, 68, 0, 76, 0, 80, 0, 60, 0,128, 0, 76, 0, 60, 0, 12, 0, 92, 0,
+ 68, 0, 32, 0, 80, 0, 16, 0, 76, 0,108, 0, 84, 0, 28, 0, 96, 0, 60, 0, 56, 0,108, 0,140, 0, 4, 0, 20, 0, 12, 0,
+ 8, 0, 40, 0,196, 0, 24, 0, 4, 1,124, 0, 16, 0, 20, 0, 24, 0,172, 1,104, 0,228, 0, 64, 0, 44, 0, 64, 0,116, 0,
+ 60, 0,104, 0, 52, 0, 44, 0, 44, 0, 68, 0, 44, 0, 64, 0, 44, 0, 20, 0, 52, 0, 96, 0, 12, 0,108, 0, 92, 0, 28, 0,
+ 28, 0, 28, 0, 52, 0, 20, 0, 60, 0,140, 0, 36, 0,120, 0, 32, 0,208, 0, 0, 0, 0, 0, 16, 0, 40, 0, 28, 0, 12, 0,
+ 12, 0, 16, 1, 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 8, 0, 24, 0, 32, 0, 8, 0, 32, 0, 12, 0, 44, 0, 20, 0,
+ 68, 0, 24, 0, 56, 0, 52, 0, 20, 0, 72, 0, 28, 0,180, 0,208, 1, 96, 0, 0, 0, 0, 0, 0, 0, 16, 0, 20, 0, 24, 0,
+172, 0, 24, 0, 24, 0,140, 0,148, 0, 56, 0, 0, 0, 0, 0,100, 0, 0, 0, 92, 0, 0, 0, 88, 0, 20, 0, 24, 0, 16, 0,
+ 20, 0, 8, 0, 8, 0, 24, 0, 20, 0, 88, 0, 24, 1, 16, 0, 68, 0, 0, 1, 20, 0,160, 0, 88, 0, 96, 0, 88, 0, 20, 0,
+ 56, 0, 48, 0, 68, 0, 56, 0, 92, 0, 64, 0, 56, 0, 96, 0, 0, 0, 0, 0, 83, 84, 82, 67,126, 1, 0, 0, 10, 0, 2, 0,
+ 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 3, 0, 11, 0, 0, 0, 11, 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0,
+ 9, 0, 4, 0, 13, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, 14, 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0,
+ 7, 0, 5, 0, 7, 0, 6, 0, 16, 0, 2, 0, 8, 0, 5, 0, 8, 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0,
+ 4, 0, 7, 0, 18, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0,
+ 8, 0, 7, 0, 20, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0,
+ 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 8, 0, 22, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0,
+ 23, 0, 4, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 4, 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0,
+ 7, 0, 11, 0, 7, 0, 12, 0, 25, 0, 4, 0, 9, 0, 13, 0, 12, 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0,
+ 26, 0, 0, 0, 26, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19, 0, 0, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0,
+ 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0,
+ 2, 0, 28, 0, 2, 0, 19, 0, 4, 0, 29, 0, 26, 0, 30, 0, 28, 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0,
+ 0, 0, 34, 0, 0, 0, 35, 0, 4, 0, 36, 0, 4, 0, 37, 0, 28, 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0,
+ 2, 0, 41, 0, 2, 0, 42, 0, 2, 0, 43, 0, 4, 0, 44, 0, 31, 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0,
+ 2, 0, 17, 0, 2, 0, 19, 0, 0, 0, 48, 0, 33, 0, 21, 0, 33, 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0,
+ 24, 0, 51, 0, 24, 0, 52, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0,
+ 2, 0, 19, 0, 2, 0, 57, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0,
+ 31, 0, 62, 0, 36, 0, 7, 0, 27, 0, 31, 0, 12, 0, 63, 0, 24, 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0,
+ 2, 0, 37, 0, 37, 0, 16, 0, 37, 0, 0, 0, 37, 0, 1, 0, 7, 0, 67, 0, 7, 0, 61, 0, 2, 0, 17, 0, 2, 0, 47, 0,
+ 2, 0, 68, 0, 2, 0, 19, 0, 4, 0, 69, 0, 4, 0, 70, 0, 9, 0, 2, 0, 7, 0, 71, 0, 0, 0, 20, 0, 0, 0, 72, 0,
+ 7, 0, 73, 0, 7, 0, 74, 0, 38, 0, 13, 0, 27, 0, 31, 0, 39, 0, 75, 0, 37, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0,
+ 7, 0, 61, 0, 12, 0, 79, 0, 36, 0, 80, 0, 27, 0, 81, 0, 2, 0, 17, 0, 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 19, 0,
+ 40, 0, 6, 0, 40, 0, 0, 0, 40, 0, 1, 0, 0, 0, 84, 0, 0, 0, 85, 0, 4, 0, 23, 0, 4, 0, 86, 0, 41, 0, 10, 0,
+ 41, 0, 0, 0, 41, 0, 1, 0, 4, 0, 87, 0, 4, 0, 88, 0, 4, 0, 89, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, 0, 90, 0,
+ 0, 0, 91, 0, 0, 0, 92, 0, 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 93, 0, 4, 0, 90, 0, 4, 0, 94, 0, 12, 0, 95, 0,
+ 40, 0, 96, 0, 40, 0, 97, 0, 4, 0, 98, 0, 4, 0, 99, 0, 12, 0,100, 0, 0, 0,101, 0, 4, 0,102, 0, 4, 0,103, 0,
+ 9, 0,104, 0, 8, 0,105, 0, 43, 0, 3, 0, 4, 0,106, 0, 4, 0,107, 0, 9, 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0,
+ 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,112, 0,
+ 7, 0,113, 0, 7, 0,114, 0, 7, 0,115, 0, 7, 0,116, 0, 7, 0,117, 0, 7, 0,118, 0, 2, 0,119, 0, 2, 0,120, 0,
+ 7, 0,121, 0, 36, 0, 80, 0, 32, 0,122, 0, 45, 0, 13, 0, 4, 0,123, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0,
+ 2, 0,127, 0, 2, 0,128, 0, 2, 0, 19, 0, 2, 0,129, 0, 2, 0,130, 0, 2, 0,131, 0, 2, 0,132, 0, 2, 0,133, 0,
+ 46, 0,134, 0, 47, 0, 32, 0, 27, 0, 31, 0, 0, 0, 34, 0, 12, 0,135, 0, 48, 0,136, 0, 49, 0,137, 0, 50, 0,138, 0,
+ 2, 0,129, 0, 2, 0, 19, 0, 2, 0,139, 0, 2, 0, 17, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, 0,140, 0, 2, 0,141, 0,
+ 2, 0,142, 0, 2, 0,143, 0, 2, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 4, 0,147, 0, 4, 0,148, 0, 43, 0,149, 0,
+ 30, 0,150, 0, 0, 0,151, 0, 7, 0,152, 0, 4, 0,153, 0, 2, 0,154, 0, 2, 0,155, 0, 2, 0,156, 0, 2, 0,157, 0,
+ 7, 0,158, 0, 7, 0,159, 0, 51, 0, 33, 0, 2, 0,160, 0, 2, 0,161, 0, 2, 0,162, 0, 2, 0,163, 0, 32, 0,164, 0,
+ 52, 0,165, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 7, 0,171, 0, 7, 0,172, 0,
+ 7, 0,173, 0, 2, 0,174, 0, 2, 0,175, 0, 2, 0,176, 0, 2, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 0, 0,180, 0,
+ 0, 0,181, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0, 57, 0, 7, 0,187, 0,
+ 7, 0,188, 0, 7, 0,189, 0, 7, 0,190, 0, 7, 0,191, 0, 53, 0, 15, 0, 0, 0,192, 0, 9, 0,193, 0, 0, 0,194, 0,
+ 0, 0,195, 0, 4, 0,196, 0, 4, 0,197, 0, 9, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 7, 0,201, 0, 4, 0,202, 0,
+ 9, 0,203, 0, 9, 0,204, 0, 4, 0,205, 0, 4, 0, 37, 0, 54, 0, 6, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0,
+ 7, 0,206, 0, 7, 0, 67, 0, 4, 0, 64, 0, 55, 0, 5, 0, 2, 0, 19, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0,207, 0,
+ 54, 0,201, 0, 56, 0, 17, 0, 32, 0,164, 0, 47, 0,208, 0, 57, 0,209, 0, 7, 0,210, 0, 7, 0,211, 0, 2, 0, 17, 0,
+ 2, 0,212, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,213, 0, 4, 0,214, 0, 2, 0,215, 0, 2, 0,216, 0, 4, 0,129, 0,
+ 4, 0,140, 0, 2, 0,217, 0, 2, 0,218, 0, 58, 0, 23, 0, 2, 0, 19, 0, 2, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0,
+ 2, 0,139, 0, 2, 0,222, 0, 4, 0,223, 0, 4, 0,224, 0, 32, 0,164, 0, 59, 0,225, 0, 2, 0,226, 0, 2, 0,227, 0,
+ 2, 0,228, 0, 9, 0,229, 0, 7, 0,230, 0, 7, 0,231, 0, 2, 0,232, 0, 2, 0,233, 0, 2, 0,234, 0, 2, 0,235, 0,
+ 7, 0,236, 0, 7, 0,237, 0, 55, 0,238, 0, 60, 0, 10, 0, 4, 0,239, 0, 4, 0,240, 0, 2, 0,241, 0, 2, 0, 19, 0,
+ 4, 0, 37, 0, 32, 0,164, 0, 7, 0,242, 0, 4, 0,243, 0, 0, 0,244, 0, 7, 0,245, 0, 52, 0, 61, 0, 27, 0, 31, 0,
+ 39, 0, 75, 0, 7, 0,246, 0, 7, 0,247, 0, 7, 0,248, 0, 7, 0,249, 0, 7, 0,250, 0, 7, 0,251, 0, 7, 0,252, 0,
+ 7, 0,253, 0, 7, 0,254, 0, 7, 0,255, 0, 7, 0, 0, 1, 7, 0, 1, 1, 7, 0, 2, 1, 7, 0, 3, 1, 7, 0, 4, 1,
+ 7, 0, 5, 1, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0, 8, 1, 7, 0, 9, 1, 2, 0, 10, 1, 2, 0, 11, 1, 2, 0, 12, 1,
+ 2, 0, 13, 1, 2, 0, 14, 1, 2, 0, 15, 1, 2, 0, 16, 1, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,212, 0, 7, 0, 17, 1,
+ 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1, 4, 0, 21, 1, 4, 0, 22, 1, 2, 0, 23, 1, 2, 0, 24, 1, 2, 0, 25, 1,
+ 2, 0,127, 0, 4, 0, 23, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 7, 0, 26, 1, 7, 0, 27, 1, 7, 0,188, 0,
+ 45, 0, 28, 1, 61, 0, 29, 1, 36, 0, 80, 0, 47, 0,208, 0, 53, 0, 30, 1, 55, 0,238, 0, 56, 0, 31, 1, 30, 0,150, 0,
+ 58, 0, 32, 1, 60, 0, 33, 1, 0, 0, 34, 1, 0, 0,181, 0, 62, 0, 8, 0, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0,172, 0,
+ 4, 0, 19, 0, 7, 0, 37, 1, 7, 0, 38, 1, 7, 0, 39, 1, 32, 0, 45, 0, 63, 0, 82, 0, 27, 0, 31, 0, 39, 0, 75, 0,
+ 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 40, 1, 2, 0,175, 0, 2, 0, 41, 1, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0,
+ 7, 0,185, 0, 7, 0, 42, 1, 7, 0, 43, 1, 7, 0, 44, 1, 7, 0, 45, 1, 7, 0, 46, 1, 7, 0, 47, 1, 7, 0, 48, 1,
+ 7, 0, 49, 1, 7, 0, 50, 1, 7, 0, 51, 1, 7, 0, 52, 1, 64, 0, 53, 1, 2, 0,219, 0, 2, 0, 70, 0, 7, 0,110, 0,
+ 7, 0,111, 0, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, 2, 0, 57, 1, 2, 0, 58, 1, 2, 0, 59, 1, 2, 0, 60, 1,
+ 0, 0, 61, 1, 0, 0, 62, 1, 2, 0, 63, 1, 2, 0, 64, 1, 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 67, 1, 7, 0, 68, 1,
+ 7, 0, 69, 1, 7, 0, 70, 1, 7, 0, 71, 1, 2, 0, 72, 1, 2, 0, 43, 0, 2, 0, 73, 1, 2, 0, 74, 1, 2, 0, 75, 1,
+ 2, 0, 76, 1, 7, 0, 77, 1, 7, 0, 78, 1, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1,
+ 7, 0, 84, 1, 7, 0, 85, 1, 7, 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 2, 0, 89, 1, 2, 0, 90, 1, 4, 0, 91, 1,
+ 4, 0, 92, 1, 2, 0, 93, 1, 2, 0, 94, 1, 2, 0, 95, 1, 2, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1,
+ 7, 0,100, 1, 2, 0,101, 1, 2, 0,102, 1, 36, 0, 80, 0, 51, 0,103, 1, 2, 0,104, 1, 2, 0,105, 1, 30, 0,150, 0,
+ 65, 0, 2, 0, 27, 0, 31, 0, 36, 0, 80, 0, 66, 0, 20, 0, 7, 0,106, 1, 7, 0,107, 1, 7, 0,108, 1, 7, 0,109, 1,
+ 7, 0,110, 1, 7, 0,111, 1, 7, 0,112, 1, 7, 0,113, 1, 2, 0,114, 1, 2, 0,115, 1, 7, 0,116, 1, 7, 0,117, 1,
+ 7, 0,118, 1, 2, 0,119, 1, 2, 0,120, 1, 2, 0,121, 1, 2, 0,122, 1, 7, 0,123, 1, 7, 0,124, 1, 4, 0,125, 1,
+ 67, 0,130, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,126, 1, 2, 0, 19, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0,
+ 7, 0,127, 1, 7, 0,128, 1, 7, 0,129, 1, 7, 0,130, 1, 7, 0,131, 1, 7, 0,132, 1, 7, 0,133, 1, 7, 0,134, 1,
+ 7, 0,135, 1, 7, 0,136, 1, 7, 0,137, 1, 7, 0,138, 1, 7, 0,139, 1, 7, 0,140, 1, 7, 0,141, 1, 7, 0,142, 1,
+ 7, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 7, 0,146, 1, 66, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, 7, 0,150, 1,
+ 7, 0,151, 1, 7, 0,152, 1, 7, 0,153, 1, 7, 0,154, 1, 2, 0,155, 1, 2, 0,156, 1, 2, 0,157, 1, 0, 0,158, 1,
+ 0, 0,159, 1, 7, 0,160, 1, 7, 0,161, 1, 2, 0,162, 1, 2, 0,163, 1, 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1,
+ 7, 0,167, 1, 2, 0,168, 1, 2, 0,169, 1, 4, 0, 40, 1, 4, 0,170, 1, 2, 0,171, 1, 2, 0,172, 1, 2, 0,173, 1,
+ 2, 0,174, 1, 7, 0,175, 1, 7, 0,176, 1, 7, 0,177, 1, 7, 0,178, 1, 7, 0,179, 1, 7, 0,180, 1, 7, 0,181, 1,
+ 7, 0,182, 1, 7, 0,183, 1, 7, 0,184, 1, 0, 0,185, 1, 7, 0,186, 1, 7, 0,187, 1, 7, 0,188, 1, 4, 0,189, 1,
+ 0, 0,190, 1, 0, 0, 73, 1, 0, 0,191, 1, 0, 0, 34, 1, 2, 0,192, 1, 2, 0,193, 1, 2, 0,104, 1, 2, 0,194, 1,
+ 2, 0,195, 1, 2, 0,196, 1, 7, 0,197, 1, 7, 0,198, 1, 7, 0,199, 1, 7, 0,200, 1, 7, 0,201, 1, 2, 0,160, 0,
+ 2, 0,161, 0, 55, 0,202, 1, 55, 0,203, 1, 0, 0,204, 1, 0, 0,205, 1, 0, 0,206, 1, 0, 0,207, 1, 2, 0,208, 1,
+ 2, 0,209, 1, 7, 0,210, 1, 7, 0,211, 1, 51, 0,103, 1, 61, 0, 29, 1, 36, 0, 80, 0, 68, 0,212, 1, 30, 0,150, 0,
+ 7, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 7, 0,217, 1, 2, 0,218, 1, 2, 0, 70, 0, 7, 0,219, 1,
+ 7, 0,220, 1, 7, 0,221, 1, 7, 0,222, 1, 7, 0,223, 1, 7, 0,224, 1, 7, 0,225, 1, 7, 0,226, 1, 7, 0,227, 1,
+ 2, 0,228, 1, 2, 0,229, 1, 7, 0,230, 1, 7, 0,231, 1, 7, 0,232, 1, 7, 0,233, 1, 7, 0,234, 1, 4, 0,235, 1,
+ 4, 0,236, 1, 4, 0,237, 1, 12, 0,238, 1, 69, 0, 4, 0, 27, 0, 31, 0, 0, 0,239, 1, 70, 0, 2, 0, 43, 0,149, 0,
+ 71, 0, 26, 0, 71, 0, 0, 0, 71, 0, 1, 0, 72, 0,240, 1, 4, 0,241, 1, 4, 0,242, 1, 4, 0,243, 1, 4, 0,244, 1,
+ 4, 0,245, 1, 4, 0,246, 1, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,247, 1, 2, 0,248, 1, 7, 0, 5, 0, 7, 0, 6, 0,
+ 7, 0, 7, 0, 7, 0,249, 1, 7, 0,250, 1, 7, 0,251, 1, 7, 0,252, 1, 7, 0,253, 1, 7, 0,254, 1, 7, 0,255, 1,
+ 7, 0, 23, 0, 7, 0, 0, 2, 7, 0, 1, 2, 73, 0, 19, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0,240, 1, 12, 0, 2, 2,
+ 12, 0, 3, 2, 12, 0, 4, 2, 36, 0, 80, 0, 67, 0, 5, 2, 0, 0, 19, 0, 0, 0, 6, 2, 2, 0, 7, 2, 4, 0,174, 0,
+ 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 71, 0, 11, 2, 35, 0, 11, 0,
+ 7, 0, 12, 2, 7, 0, 13, 2, 7, 0, 14, 2, 7, 0,221, 0, 2, 0, 55, 0, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 17, 2,
+ 0, 0, 18, 2, 0, 0, 19, 2, 0, 0, 20, 2, 34, 0, 7, 0, 7, 0, 21, 2, 7, 0, 13, 2, 7, 0, 14, 2, 2, 0, 17, 2,
+ 2, 0, 20, 2, 7, 0,221, 0, 7, 0, 37, 0, 74, 0, 21, 0, 74, 0, 0, 0, 74, 0, 1, 0, 2, 0, 17, 0, 2, 0, 22, 2,
+ 2, 0, 20, 2, 2, 0, 19, 0, 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 27, 2, 2, 0, 28, 2,
+ 2, 0, 29, 2, 2, 0, 30, 2, 7, 0, 31, 2, 7, 0, 32, 2, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0, 33, 2, 2, 0, 34, 2,
+ 4, 0, 35, 2, 75, 0, 5, 0, 2, 0, 36, 2, 2, 0, 22, 2, 0, 0, 19, 0, 0, 0, 37, 0, 2, 0, 70, 0, 76, 0, 4, 0,
+ 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 8, 0, 7, 0, 37, 2, 77, 0, 67, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0,240, 1,
+ 12, 0, 38, 2, 12, 0, 3, 2, 12, 0, 39, 2, 32, 0, 40, 2, 32, 0, 41, 2, 32, 0, 42, 2, 36, 0, 80, 0, 78, 0, 43, 2,
+ 38, 0, 44, 2, 67, 0, 5, 2, 12, 0, 45, 2, 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 4, 0,174, 0, 2, 0, 46, 2,
+ 2, 0, 47, 2, 2, 0, 48, 2, 7, 0, 49, 2, 7, 0, 70, 0, 2, 0, 50, 2, 2, 0, 7, 2, 2, 0, 19, 0, 2, 0, 51, 2,
+ 7, 0, 52, 2, 7, 0, 53, 2, 7, 0, 54, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 55, 2, 2, 0, 56, 2, 4, 0, 57, 2,
+ 34, 0, 58, 2, 2, 0, 23, 0, 2, 0, 95, 0, 2, 0, 67, 0, 2, 0, 59, 2, 7, 0, 60, 2, 7, 0, 61, 2, 7, 0, 62, 2,
+ 7, 0, 63, 2, 7, 0, 64, 2, 7, 0, 65, 2, 7, 0, 66, 2, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 69, 2, 0, 0, 70, 2,
+ 79, 0, 71, 2, 80, 0, 72, 2, 0, 0, 73, 2, 69, 0, 74, 2, 69, 0, 75, 2, 69, 0, 76, 2, 69, 0, 77, 2, 4, 0, 78, 2,
+ 7, 0, 79, 2, 4, 0, 80, 2, 4, 0, 81, 2, 76, 0, 82, 2, 4, 0, 83, 2, 4, 0, 84, 2, 75, 0, 85, 2, 75, 0, 86, 2,
+ 81, 0, 39, 0, 27, 0, 31, 0, 72, 0,240, 1, 12, 0, 87, 2, 36, 0, 80, 0, 38, 0, 44, 2, 67, 0, 5, 2, 82, 0, 88, 2,
+ 83, 0, 89, 2, 84, 0, 90, 2, 85, 0, 91, 2, 86, 0, 92, 2, 87, 0, 93, 2, 88, 0, 94, 2, 89, 0, 95, 2, 81, 0, 96, 2,
+ 90, 0, 97, 2, 91, 0, 98, 2, 92, 0, 99, 2, 92, 0,100, 2, 92, 0,101, 2, 4, 0, 54, 0, 4, 0,102, 2, 4, 0,103, 2,
+ 4, 0,104, 2, 4, 0,105, 2, 4, 0,174, 0, 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 7, 0,106, 2, 4, 0, 46, 2,
+ 2, 0,107, 2, 2, 0, 19, 0, 2, 0,108, 2, 2, 0,109, 2, 2, 0, 7, 2, 2, 0,110, 2, 93, 0,111, 2, 94, 0,112, 2,
+ 84, 0, 8, 0, 9, 0,113, 2, 7, 0,114, 2, 4, 0,115, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2,
+ 2, 0,118, 2, 82, 0, 7, 0, 4, 0,119, 2, 4, 0,120, 2, 4, 0,121, 2, 4, 0,122, 2, 2, 0, 22, 2, 0, 0,123, 2,
+ 0, 0, 19, 0, 86, 0, 5, 0, 4, 0,119, 2, 4, 0,120, 2, 0, 0,124, 2, 0, 0,125, 2, 2, 0, 19, 0, 95, 0, 2, 0,
+ 4, 0,126, 2, 7, 0, 14, 2, 87, 0, 3, 0, 95, 0,127, 2, 4, 0,128, 2, 4, 0, 19, 0, 85, 0, 6, 0, 7, 0,129, 2,
+ 2, 0,130, 2, 2, 0, 22, 2, 0, 0, 19, 0, 0, 0,125, 2, 0, 0, 48, 2, 88, 0, 4, 0, 0, 0,206, 0, 0, 0,182, 0,
+ 0, 0,183, 0, 0, 0,184, 0, 96, 0, 6, 0, 47, 0,113, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2,
+ 2, 0,118, 2, 97, 0, 1, 0, 7, 0,131, 2, 98, 0, 5, 0, 0, 0,206, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0,184, 0,
+ 4, 0, 37, 0, 89, 0, 1, 0, 7, 0,132, 2, 90, 0, 2, 0, 4, 0,133, 2, 4, 0, 17, 0, 83, 0, 7, 0, 7, 0,114, 2,
+ 47, 0,113, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, 2, 0,118, 2, 99, 0, 1, 0, 7, 0,134, 2,
+100, 0, 1, 0, 4, 0,135, 2,101, 0, 1, 0, 0, 0,136, 2,102, 0, 1, 0, 7, 0,114, 2,103, 0, 3, 0, 4, 0,137, 2,
+ 0, 0, 92, 0, 7, 0,138, 2,105, 0, 4, 0, 7, 0,206, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0,106, 0, 1, 0,
+105, 0,115, 2,107, 0, 5, 0, 4, 0,139, 2, 4, 0,140, 2, 0, 0, 19, 0, 0, 0, 22, 2, 0, 0, 48, 2,108, 0, 2, 0,
+ 4, 0,141, 2, 4, 0,140, 2,109, 0, 10, 0,109, 0, 0, 0,109, 0, 1, 0,107, 0,142, 2,106, 0,143, 2,108, 0,144, 2,
+ 4, 0, 54, 0, 4, 0,103, 2, 4, 0,102, 2, 4, 0, 37, 0, 85, 0,145, 2, 93, 0, 14, 0, 12, 0,146, 2, 85, 0,145, 2,
+ 0, 0,147, 2, 0, 0,148, 2, 0, 0,149, 2, 0, 0,150, 2, 0, 0,151, 2, 0, 0,152, 2, 0, 0,153, 2, 0, 0, 19, 0,
+ 92, 0, 99, 2, 92, 0,101, 2, 2, 0,154, 2, 0, 0,155, 2, 94, 0, 8, 0, 4, 0,156, 2, 4, 0,157, 2, 82, 0,158, 2,
+ 86, 0,159, 2, 4, 0,103, 2, 4, 0,102, 2, 4, 0, 54, 0, 4, 0, 37, 0,110, 0, 7, 0,110, 0, 0, 0,110, 0, 1, 0,
+ 4, 0, 17, 0, 4, 0, 40, 1, 0, 0, 20, 0, 46, 0,134, 0, 0, 0,160, 2,111, 0, 7, 0,110, 0,161, 2, 2, 0,162, 2,
+ 2, 0,146, 2, 2, 0,163, 2, 2, 0, 90, 0, 9, 0,164, 2, 9, 0,165, 2,112, 0, 3, 0,110, 0,161, 2, 32, 0,164, 0,
+ 0, 0, 20, 0,113, 0, 5, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0, 20, 0, 2, 0,166, 2, 0, 0,167, 2,114, 0, 5, 0,
+110, 0,161, 2, 7, 0, 88, 0, 7, 0,168, 2, 4, 0,169, 2, 4, 0,170, 2,115, 0, 5, 0,110, 0,161, 2, 32, 0,171, 2,
+ 0, 0, 72, 0, 4, 0, 40, 1, 4, 0, 19, 0,116, 0, 13, 0,110, 0,161, 2, 32, 0,172, 2, 32, 0,173, 2, 32, 0,174, 2,
+ 32, 0,175, 2, 7, 0,176, 2, 7, 0,177, 2, 7, 0,168, 2, 7, 0,178, 2, 4, 0,179, 2, 4, 0,180, 2, 4, 0, 90, 0,
+ 4, 0,181, 2,117, 0, 5, 0,110, 0,161, 2, 2, 0,182, 2, 2, 0, 19, 0, 7, 0,183, 2, 32, 0,184, 2,118, 0, 3, 0,
+110, 0,161, 2, 7, 0,185, 2, 4, 0, 90, 0,119, 0, 10, 0,110, 0,161, 2, 7, 0,186, 2, 4, 0,187, 2, 4, 0, 37, 0,
+ 2, 0, 90, 0, 2, 0,188, 2, 2, 0,189, 2, 2, 0,190, 2, 7, 0,191, 2, 0, 0,192, 2,120, 0, 3, 0,110, 0,161, 2,
+ 7, 0, 37, 0, 4, 0, 17, 0,121, 0, 6, 0,110, 0,161, 2,122, 0,193, 2,123, 0,194, 2,124, 0,195, 2, 7, 0,196, 2,
+ 4, 0, 17, 0,125, 0, 11, 0,110, 0,161, 2, 52, 0,197, 2, 7, 0,198, 2, 4, 0,199, 2, 0, 0,192, 2, 7, 0,200, 2,
+ 4, 0,201, 2, 32, 0,202, 2, 0, 0,203, 2, 4, 0,204, 2, 4, 0, 37, 0,126, 0, 10, 0,110, 0,161, 2, 32, 0,205, 2,
+ 47, 0,206, 2, 4, 0, 90, 0, 4, 0,207, 2, 7, 0,208, 2, 7, 0,209, 2, 0, 0,203, 2, 4, 0,204, 2, 4, 0, 37, 0,
+127, 0, 3, 0,110, 0,161, 2, 7, 0,210, 2, 4, 0,211, 2,128, 0, 5, 0,110, 0,161, 2, 7, 0,212, 2, 0, 0,192, 2,
+ 2, 0, 19, 0, 2, 0,213, 2,129, 0, 8, 0,110, 0,161, 2, 32, 0,164, 0, 7, 0,212, 2, 7, 0,221, 0, 7, 0,106, 0,
+ 0, 0,192, 2, 2, 0, 19, 0, 2, 0, 17, 0,130, 0, 21, 0,110, 0,161, 2, 32, 0,214, 2, 0, 0,192, 2, 52, 0,197, 2,
+ 32, 0,202, 2, 2, 0, 19, 0, 2, 0, 37, 0, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 7, 0, 52, 2, 7, 0,218, 2,
+ 7, 0,219, 2, 7, 0,220, 2, 7, 0,221, 2, 4, 0,201, 2, 4, 0,204, 2, 0, 0,203, 2, 7, 0,222, 2, 7, 0,223, 2,
+ 7, 0, 43, 0,131, 0, 7, 0,110, 0,161, 2, 2, 0,224, 2, 2, 0,225, 2, 4, 0, 70, 0, 32, 0,164, 0, 7, 0,226, 2,
+ 0, 0,192, 2,132, 0, 10, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0,227, 2, 7, 0,228, 2, 7, 0,229, 2, 7, 0,221, 2,
+ 4, 0,230, 2, 4, 0,231, 2, 7, 0,232, 2, 0, 0, 20, 0,133, 0, 1, 0,110, 0,161, 2,134, 0, 7, 0,110, 0,161, 2,
+ 46, 0,134, 0,135, 0,233, 2,136, 0,234, 2,137, 0,235, 2,138, 0,236, 2, 12, 0,237, 2,139, 0, 14, 0,110, 0,161, 2,
+ 85, 0,238, 2, 85, 0,239, 2, 85, 0,240, 2, 85, 0,241, 2, 85, 0,242, 2, 85, 0,243, 2, 82, 0,244, 2, 4, 0,245, 2,
+ 4, 0,246, 2, 2, 0,108, 1, 2, 0, 37, 0, 7, 0,196, 2,140, 0,247, 2,141, 0, 7, 0,110, 0,161, 2, 85, 0,238, 2,
+ 85, 0,248, 2,142, 0,249, 2,143, 0,247, 2, 4, 0,250, 2, 4, 0,245, 2,144, 0, 4, 0,110, 0,161, 2, 32, 0,164, 0,
+ 4, 0,251, 2, 4, 0, 37, 0,145, 0, 2, 0, 4, 0,252, 2, 7, 0, 14, 2,146, 0, 2, 0, 4, 0,125, 0, 4, 0,253, 2,
+147, 0, 20, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0,192, 2, 2, 0,254, 2, 2, 0,255, 2, 2, 0, 19, 0, 2, 0, 37, 0,
+ 7, 0, 0, 3, 7, 0, 1, 3, 4, 0, 54, 0, 4, 0, 2, 3,146, 0, 3, 3,145, 0, 4, 3, 4, 0, 5, 3, 4, 0, 6, 3,
+ 4, 0, 7, 3, 4, 0,253, 2, 7, 0, 8, 3, 7, 0, 9, 3, 7, 0, 10, 3,148, 0, 8, 0,110, 0,161, 2, 59, 0,225, 0,
+142, 0,249, 2, 4, 0, 11, 3, 4, 0, 12, 3, 4, 0, 13, 3, 2, 0, 19, 0, 2, 0, 57, 0,149, 0, 8, 0,110, 0,161, 2,
+ 32, 0, 45, 0, 2, 0, 14, 3, 2, 0, 19, 0, 2, 0,182, 2, 2, 0, 57, 0, 7, 0, 15, 3, 7, 0, 16, 3,150, 0, 5, 0,
+110, 0,161, 2, 4, 0, 17, 3, 2, 0, 19, 0, 2, 0, 18, 3, 7, 0, 19, 3,151, 0, 7, 0,110, 0,161, 2, 85, 0, 20, 3,
+ 4, 0, 21, 3, 0, 0, 22, 3, 0, 0, 23, 3, 0, 0, 24, 3, 0, 0, 25, 3,152, 0, 3, 0,110, 0,161, 2,153, 0, 26, 3,
+138, 0,236, 2,154, 0, 10, 0,110, 0,161, 2, 32, 0, 27, 3, 32, 0, 28, 3, 0, 0, 29, 3, 7, 0, 30, 3, 2, 0, 31, 3,
+ 2, 0, 32, 3, 0, 0, 33, 3, 0, 0, 34, 3, 0, 0,167, 2,155, 0, 9, 0,110, 0,161, 2, 32, 0, 35, 3, 0, 0, 29, 3,
+ 7, 0, 36, 3, 7, 0, 37, 3, 0, 0, 40, 1, 0, 0,182, 2, 0, 0, 38, 3, 0, 0, 37, 0,156, 0, 27, 0, 27, 0, 31, 0,
+ 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 39, 3, 2, 0, 19, 0, 2, 0, 40, 3, 2, 0, 41, 3, 2, 0, 42, 3, 2, 0, 70, 0,
+ 0, 0, 43, 3, 0, 0, 44, 3, 0, 0, 45, 3, 0, 0, 17, 0, 4, 0, 37, 0, 7, 0, 46, 3, 7, 0, 47, 3, 7, 0, 48, 3,
+ 7, 0, 49, 3, 7, 0, 50, 3, 7, 0, 51, 3, 34, 0, 52, 3, 36, 0, 80, 0, 38, 0, 44, 2, 87, 0, 93, 2, 7, 0, 53, 3,
+ 7, 0, 54, 3,156, 0, 55, 3,157, 0, 3, 0,157, 0, 0, 0,157, 0, 1, 0, 0, 0, 20, 0, 72, 0, 3, 0, 7, 0, 56, 3,
+ 4, 0, 19, 0, 4, 0, 37, 0, 32, 0,116, 0, 27, 0, 31, 0, 39, 0, 75, 0,158, 0, 57, 3, 2, 0, 17, 0, 2, 0, 58, 3,
+ 4, 0, 59, 3, 4, 0, 60, 3, 4, 0, 61, 3, 0, 0, 62, 3, 32, 0, 38, 0, 32, 0, 63, 3, 32, 0, 64, 3, 32, 0, 65, 3,
+ 32, 0, 66, 3, 36, 0, 80, 0, 78, 0, 43, 2, 72, 0,240, 1,159, 0, 67, 3,159, 0, 68, 3,160, 0, 69, 3, 9, 0, 2, 0,
+161, 0, 70, 3, 12, 0, 71, 3, 12, 0, 87, 2, 12, 0, 3, 2, 12, 0, 72, 3, 12, 0, 73, 3, 4, 0, 40, 1, 4, 0, 74, 3,
+ 67, 0, 5, 2, 0, 0, 75, 3, 4, 0, 7, 2, 4, 0, 76, 3, 7, 0, 35, 1, 7, 0, 77, 3, 7, 0, 78, 3, 7, 0,172, 0,
+ 7, 0, 79, 3, 7, 0, 36, 1, 7, 0, 80, 3, 7, 0, 81, 3, 7, 0,228, 2, 7, 0, 82, 3, 7, 0,210, 0, 4, 0, 83, 3,
+ 2, 0, 19, 0, 2, 0, 84, 3, 2, 0, 85, 3, 2, 0, 86, 3, 2, 0, 87, 3, 2, 0, 88, 3, 2, 0, 89, 3, 2, 0, 90, 3,
+ 2, 0, 91, 3, 2, 0, 92, 3, 2, 0, 93, 3, 2, 0, 94, 3, 4, 0, 95, 3, 4, 0, 96, 3, 4, 0, 97, 3, 4, 0, 98, 3,
+ 7, 0, 99, 3, 7, 0, 79, 2, 7, 0,100, 3, 7, 0,101, 3, 7, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 7, 0,105, 3,
+ 7, 0,106, 3, 7, 0,107, 3, 7, 0,108, 3, 7, 0,109, 3, 0, 0,110, 3, 0, 0,111, 3, 0, 0,112, 3, 0, 0,113, 3,
+ 7, 0,114, 3, 7, 0,115, 3, 12, 0,116, 3, 12, 0,117, 3, 12, 0,118, 3, 12, 0,119, 3, 7, 0,120, 3, 2, 0,133, 2,
+ 2, 0,121, 3, 7, 0,115, 2, 4, 0,122, 3, 4, 0,123, 3,162, 0,124, 3, 2, 0,125, 3, 2, 0,217, 0, 7, 0,126, 3,
+ 12, 0,127, 3, 12, 0,128, 3, 12, 0,129, 3, 12, 0,130, 3,163, 0, 32, 1,164, 0,131, 3, 68, 0,132, 3, 2, 0,133, 3,
+ 2, 0,134, 3, 2, 0,135, 3, 2, 0,136, 3, 7, 0,107, 2, 2, 0,137, 3, 2, 0,138, 3,153, 0,139, 3,142, 0,140, 3,
+142, 0,141, 3, 4, 0,142, 3, 4, 0,143, 3, 4, 0,144, 3, 4, 0, 70, 0, 12, 0,145, 3, 12, 0,146, 3,165, 0, 14, 0,
+165, 0, 0, 0,165, 0, 1, 0, 32, 0, 38, 0, 7, 0,228, 2, 7, 0, 37, 1, 7, 0,229, 2, 7, 0,221, 2, 0, 0, 20, 0,
+ 4, 0,230, 2, 4, 0,231, 2, 4, 0,147, 3, 2, 0, 17, 0, 2, 0,148, 3, 7, 0,232, 2,163, 0, 36, 0, 2, 0,149, 3,
+ 2, 0,150, 3, 2, 0, 19, 0, 2, 0,221, 2, 7, 0,151, 3, 7, 0,152, 3, 7, 0,153, 3, 7, 0,154, 3, 7, 0,155, 3,
+ 7, 0,156, 3, 7, 0,157, 3, 7, 0,158, 3, 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, 7, 0,162, 3, 7, 0,163, 3,
+ 7, 0,164, 3, 7, 0,165, 3, 7, 0,166, 3, 7, 0,167, 3, 7, 0,168, 3, 7, 0,169, 3, 7, 0,170, 3, 7, 0,171, 3,
+ 7, 0,172, 3, 7, 0,173, 3, 7, 0,174, 3, 2, 0,175, 3, 2, 0,176, 3, 2, 0,177, 3, 2, 0,178, 3, 52, 0,165, 0,
+166, 0,179, 3, 7, 0,180, 3, 4, 0,170, 2,167, 0, 9, 0,167, 0, 0, 0,167, 0, 1, 0, 4, 0,181, 3, 4, 0,182, 3,
+ 4, 0,183, 3, 4, 0, 19, 0, 4, 0,184, 3, 9, 0,185, 3, 9, 0,186, 3,138, 0, 19, 0,138, 0, 0, 0,138, 0, 1, 0,
+ 4, 0, 19, 0, 4, 0,187, 3, 4, 0,188, 3, 4, 0,189, 3, 4, 0,190, 3, 4, 0,191, 3, 4, 0,192, 3, 4, 0,182, 3,
+ 4, 0,133, 2, 4, 0, 57, 0, 0, 0,193, 3, 0, 0,194, 3, 0, 0,195, 3, 0, 0,196, 3, 12, 0,197, 3,168, 0,198, 3,
+ 9, 0,199, 3,169, 0, 1, 0, 7, 0, 21, 2,162, 0, 30, 0, 4, 0, 19, 0, 7, 0,200, 3, 7, 0,201, 3, 7, 0,202, 3,
+ 4, 0,203, 3, 4, 0,204, 3, 4, 0,205, 3, 4, 0,206, 3, 7, 0,207, 3, 7, 0,208, 3, 7, 0,209, 3, 7, 0,210, 3,
+ 7, 0,211, 3, 7, 0,212, 3, 7, 0,213, 3, 7, 0,214, 3, 7, 0,215, 3, 7, 0,216, 3, 7, 0,217, 3, 7, 0,218, 3,
+ 7, 0,219, 3, 7, 0,220, 3, 7, 0,221, 3, 7, 0,222, 3, 7, 0,223, 3, 7, 0,224, 3, 4, 0,225, 3, 4, 0,226, 3,
+ 7, 0,227, 3, 7, 0,106, 3,164, 0, 49, 0, 4, 0,182, 3, 4, 0,228, 3,170, 0,229, 3,171, 0,230, 3, 0, 0, 37, 0,
+ 0, 0,231, 3, 2, 0,232, 3, 7, 0,233, 3, 0, 0,234, 3, 7, 0,235, 3, 7, 0,236, 3, 7, 0,237, 3, 7, 0,238, 3,
+ 7, 0,239, 3, 7, 0,240, 3, 7, 0,241, 3, 7, 0,242, 3, 7, 0,243, 3, 2, 0,244, 3, 0, 0,245, 3, 2, 0,246, 3,
+ 7, 0,247, 3, 7, 0,248, 3, 0, 0,249, 3, 4, 0,126, 0, 4, 0,250, 3, 4, 0,251, 3, 2, 0,252, 3, 2, 0,253, 3,
+169, 0,254, 3, 4, 0,255, 3, 4, 0, 82, 0, 7, 0, 0, 4, 7, 0, 1, 4, 7, 0, 2, 4, 7, 0, 3, 4, 2, 0, 4, 4,
+ 2, 0, 5, 4, 2, 0, 6, 4, 2, 0, 7, 4, 2, 0, 8, 4, 2, 0, 9, 4, 2, 0, 10, 4, 2, 0, 11, 4,172, 0, 12, 4,
+ 7, 0, 13, 4, 7, 0, 14, 4,138, 0, 15, 4, 12, 0,237, 2,153, 0, 48, 0, 2, 0, 17, 0, 2, 0, 16, 4, 2, 0, 17, 4,
+ 2, 0, 18, 4, 7, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 7, 0, 22, 4, 2, 0, 23, 4, 2, 0, 24, 4, 7, 0, 25, 4,
+ 7, 0, 26, 4, 7, 0, 27, 4, 7, 0, 28, 4, 7, 0, 29, 4, 7, 0, 30, 4, 4, 0, 31, 4, 7, 0, 32, 4, 7, 0, 33, 4,
+ 7, 0, 34, 4, 81, 0, 35, 4, 81, 0, 36, 4, 81, 0, 37, 4, 0, 0, 38, 4, 7, 0, 39, 4, 7, 0, 40, 4, 36, 0, 80, 0,
+ 2, 0, 41, 4, 0, 0, 42, 4, 0, 0, 43, 4, 7, 0, 44, 4, 4, 0, 45, 4, 7, 0, 46, 4, 7, 0, 47, 4, 4, 0, 48, 4,
+ 4, 0, 19, 0, 7, 0, 49, 4, 7, 0, 50, 4, 7, 0, 51, 4, 85, 0, 52, 4, 7, 0, 53, 4, 7, 0, 54, 4, 7, 0, 55, 4,
+ 7, 0, 56, 4, 7, 0, 57, 4, 7, 0, 58, 4, 7, 0, 59, 4, 4, 0, 60, 4,173, 0, 73, 0, 27, 0, 31, 0, 39, 0, 75, 0,
+ 2, 0,175, 0, 2, 0, 41, 1, 2, 0, 73, 1, 2, 0, 61, 4, 7, 0, 62, 4, 7, 0, 63, 4, 7, 0, 64, 4, 7, 0, 65, 4,
+ 7, 0, 66, 4, 7, 0, 67, 4, 7, 0, 68, 4, 7, 0, 69, 4, 7, 0,133, 1, 7, 0,135, 1, 7, 0,134, 1, 7, 0, 70, 4,
+ 4, 0, 71, 4, 7, 0, 72, 4, 7, 0, 73, 4, 7, 0, 74, 4, 7, 0, 75, 4, 7, 0, 76, 4, 7, 0, 77, 4, 7, 0, 78, 4,
+ 2, 0, 79, 4, 2, 0, 40, 1, 2, 0, 80, 4, 2, 0, 81, 4, 2, 0, 82, 4, 2, 0, 83, 4, 2, 0, 84, 4, 2, 0, 85, 4,
+ 7, 0, 86, 4, 7, 0, 87, 4, 7, 0, 88, 4, 7, 0, 89, 4, 7, 0, 90, 4, 7, 0, 91, 4, 7, 0, 92, 4, 7, 0, 93, 4,
+ 7, 0, 94, 4, 7, 0, 95, 4, 7, 0, 96, 4, 7, 0, 97, 4, 2, 0, 98, 4, 2, 0, 99, 4, 2, 0,100, 4, 2, 0,101, 4,
+ 7, 0,102, 4, 7, 0,103, 4, 7, 0,104, 4, 7, 0,105, 4, 2, 0,106, 4, 2, 0,107, 4, 2, 0,108, 4, 2, 0,109, 4,
+ 7, 0,110, 4, 7, 0,111, 4, 7, 0,112, 4, 7, 0,113, 4, 2, 0,114, 4, 2, 0,115, 4, 2, 0,116, 4, 2, 0, 19, 0,
+ 7, 0,117, 4, 7, 0,118, 4, 36, 0, 80, 0, 51, 0,103, 1, 2, 0,104, 1, 2, 0,105, 1, 30, 0,150, 0,174, 0, 8, 0,
+174, 0, 0, 0,174, 0, 1, 0, 4, 0, 83, 3, 4, 0,119, 4, 4, 0, 19, 0, 2, 0,120, 4, 2, 0,121, 4, 32, 0,164, 0,
+175, 0, 13, 0, 9, 0,122, 4, 9, 0,123, 4, 4, 0,124, 4, 4, 0,125, 4, 4, 0,126, 4, 4, 0,127, 4, 4, 0,128, 4,
+ 4, 0,129, 4, 4, 0,130, 4, 4, 0,131, 4, 4, 0,132, 4, 4, 0, 37, 0, 0, 0,133, 4,176, 0, 5, 0, 9, 0,134, 4,
+ 9, 0,135, 4, 4, 0,136, 4, 4, 0, 70, 0, 0, 0,137, 4,177, 0, 13, 0, 4, 0, 17, 0, 4, 0,138, 4, 4, 0,139, 4,
+ 4, 0,140, 4, 4, 0,141, 4, 4, 0,142, 4, 4, 0, 90, 0, 4, 0,143, 4, 4, 0,144, 4, 4, 0,145, 4, 4, 0,146, 4,
+ 4, 0,147, 4, 26, 0, 30, 0,178, 0, 4, 0, 4, 0,148, 4, 7, 0,149, 4, 2, 0, 19, 0, 2, 0,105, 1,179, 0, 11, 0,
+179, 0, 0, 0,179, 0, 1, 0, 0, 0, 20, 0, 67, 0,150, 4, 68, 0,151, 4, 4, 0, 83, 3, 4, 0,152, 4, 4, 0,153, 4,
+ 4, 0, 37, 0, 4, 0,154, 4, 4, 0,155, 4,180, 0,132, 0,175, 0,156, 4,176, 0,157, 4,177, 0,158, 4,178, 0,159, 4,
+ 4, 0,250, 2, 4, 0,126, 0, 4, 0,250, 3, 4, 0,160, 4, 4, 0,161, 4, 4, 0,162, 4, 4, 0,163, 4, 2, 0, 19, 0,
+ 2, 0,164, 4, 7, 0, 79, 2, 7, 0,165, 4, 7, 0,166, 4, 7, 0,167, 4, 7, 0,168, 4, 7, 0,169, 4, 2, 0,170, 4,
+ 2, 0,171, 4, 2, 0,172, 4, 2, 0,173, 4, 2, 0,216, 0, 2, 0,174, 4, 2, 0,175, 4, 2, 0,178, 3, 2, 0,176, 4,
+ 2, 0,177, 4, 2, 0, 60, 1, 2, 0,106, 0, 2, 0,178, 4, 2, 0,179, 4, 2, 0,180, 4, 2, 0,181, 4, 2, 0,182, 4,
+ 2, 0,183, 4, 2, 0,184, 4, 2, 0,185, 4, 2, 0,186, 4, 2, 0, 61, 1, 2, 0,187, 4, 2, 0,188, 4, 2, 0,189, 4,
+ 2, 0,190, 4, 4, 0,191, 4, 4, 0, 40, 1, 2, 0,192, 4, 2, 0,193, 4, 2, 0,194, 4, 2, 0,195, 4, 2, 0,196, 4,
+ 2, 0,197, 4, 24, 0,198, 4, 24, 0,199, 4, 23, 0,200, 4, 12, 0,201, 4, 2, 0,202, 4, 2, 0, 37, 0, 7, 0,203, 4,
+ 7, 0,204, 4, 7, 0,205, 4, 7, 0,206, 4, 4, 0,207, 4, 7, 0,208, 4, 7, 0,209, 4, 7, 0,210, 4, 7, 0,211, 4,
+ 2, 0,212, 4, 2, 0,213, 4, 2, 0,214, 4, 2, 0,215, 4, 2, 0,216, 4, 2, 0,217, 4, 7, 0,218, 4, 7, 0,219, 4,
+ 7, 0,220, 4, 2, 0,221, 4, 2, 0,222, 4, 2, 0,223, 4, 2, 0,224, 4, 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4,
+ 2, 0,228, 4, 2, 0,229, 4, 2, 0,230, 4, 4, 0,231, 4, 4, 0,232, 4, 4, 0,233, 4, 4, 0,234, 4, 4, 0,235, 4,
+ 7, 0,236, 4, 4, 0,237, 4, 4, 0,238, 4, 4, 0,239, 4, 4, 0,240, 4, 7, 0,241, 4, 7, 0,242, 4, 7, 0,243, 4,
+ 7, 0,244, 4, 7, 0,245, 4, 7, 0,246, 4, 7, 0,247, 4, 7, 0,248, 4, 7, 0,249, 4, 0, 0,250, 4, 0, 0,251, 4,
+ 4, 0,252, 4, 2, 0,253, 4, 2, 0,209, 1, 0, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 4, 0, 1, 5, 4, 0, 2, 5,
+ 7, 0, 3, 5, 7, 0, 4, 5, 2, 0, 5, 5, 2, 0, 6, 5, 7, 0, 7, 5, 2, 0, 8, 5, 2, 0, 9, 5, 4, 0, 10, 5,
+ 2, 0, 11, 5, 2, 0, 12, 5, 2, 0, 13, 5, 2, 0, 14, 5, 7, 0, 15, 5, 7, 0, 70, 0, 42, 0, 16, 5, 0, 0, 17, 5,
+181, 0, 9, 0,181, 0, 0, 0,181, 0, 1, 0, 0, 0, 20, 0, 2, 0, 18, 5, 2, 0, 19, 5, 2, 0, 20, 5, 2, 0, 43, 0,
+ 7, 0, 21, 5, 7, 0, 70, 0,182, 0, 7, 0, 2, 0,187, 2, 2, 0, 40, 1, 2, 0,109, 0, 2, 0, 22, 5, 7, 0, 23, 5,
+ 7, 0, 70, 0, 42, 0, 24, 5,183, 0, 5, 0, 7, 0, 25, 5, 0, 0, 17, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0,209, 1,
+184, 0, 26, 0, 7, 0, 77, 4, 7, 0, 78, 4, 2, 0, 40, 1, 2, 0, 19, 0, 2, 0, 26, 5, 2, 0,105, 1, 2, 0, 80, 4,
+ 2, 0, 81, 4, 2, 0, 82, 4, 2, 0, 83, 4, 2, 0, 84, 4, 2, 0, 85, 4,183, 0, 27, 5, 2, 0,170, 4, 2, 0,171, 4,
+ 2, 0,172, 4, 2, 0,173, 4, 2, 0,216, 0, 2, 0,174, 4, 2, 0,175, 4, 2, 0,178, 3,182, 0, 28, 5, 2, 0, 29, 5,
+ 2, 0,176, 4, 2, 0,179, 4, 2, 0,180, 4,185, 0, 5, 0,185, 0, 0, 0,185, 0, 1, 0, 4, 0,181, 3, 0, 0,193, 3,
+ 4, 0, 19, 0,186, 0, 6, 0,187, 0, 30, 5, 4, 0, 31, 5, 4, 0, 32, 5, 9, 0, 33, 5, 0, 0, 34, 5, 4, 0, 37, 0,
+188, 0, 6, 0,186, 0, 35, 5, 2, 0, 19, 0, 2, 0, 36, 5, 2, 0, 37, 5, 2, 0, 38, 5, 9, 0, 39, 5,189, 0, 4, 0,
+ 2, 0,106, 0, 2, 0,198, 2, 2, 0,187, 3, 2, 0, 40, 5,190, 0, 14, 0, 2, 0, 19, 0, 2, 0, 41, 5, 2, 0, 42, 5,
+ 2, 0, 43, 5,189, 0, 44, 5, 9, 0, 39, 5, 7, 0, 45, 5, 7, 0, 57, 0, 4, 0, 46, 5, 4, 0, 47, 5, 4, 0, 48, 5,
+ 4, 0, 49, 5, 46, 0,134, 0, 32, 0,164, 0,191, 0, 4, 0,191, 0, 0, 0,191, 0, 1, 0, 0, 0, 50, 5, 7, 0, 51, 5,
+192, 0, 6, 0,186, 0, 35, 5, 7, 0, 52, 5, 4, 0, 90, 0, 0, 0, 53, 5, 0, 0, 54, 5, 0, 0,167, 2,193, 0, 9, 0,
+186, 0, 35, 5, 7, 0, 55, 5, 7, 0, 56, 5, 2, 0, 40, 1, 2, 0, 19, 0, 4, 0, 36, 0, 4, 0, 57, 5, 87, 0, 58, 5,
+ 9, 0, 39, 5,194, 0, 72, 0,193, 0, 59, 5,193, 0, 60, 5,192, 0, 57, 3, 7, 0, 61, 5, 2, 0, 62, 5, 2, 0, 63, 5,
+ 7, 0, 64, 5, 7, 0, 65, 5, 2, 0,187, 3, 2, 0, 66, 5, 7, 0, 67, 5, 7, 0, 68, 5, 7, 0, 69, 5, 2, 0, 70, 5,
+ 2, 0, 46, 5, 2, 0, 71, 5, 2, 0, 72, 5, 2, 0, 73, 5, 2, 0, 74, 5, 7, 0, 75, 5, 7, 0, 76, 5, 7, 0, 77, 5,
+ 2, 0, 78, 5, 2, 0, 79, 5, 2, 0, 80, 5, 2, 0, 81, 5, 2, 0, 82, 5, 2, 0, 83, 5, 2, 0, 84, 5,188, 0, 85, 5,
+190, 0, 86, 5, 7, 0, 87, 5, 7, 0, 88, 5, 7, 0, 89, 5, 2, 0, 90, 5, 2, 0, 91, 5, 0, 0, 92, 5, 0, 0, 93, 5,
+ 0, 0, 94, 5, 0, 0, 95, 5, 0, 0, 96, 5, 0, 0, 97, 5, 2, 0, 98, 5, 7, 0, 99, 5, 7, 0,100, 5, 7, 0,101, 5,
+ 7, 0,102, 5, 7, 0,103, 5, 7, 0,104, 5, 7, 0,105, 5, 7, 0,106, 5, 7, 0,107, 5, 7, 0,108, 5, 2, 0,109, 5,
+ 0, 0,110, 5, 0, 0,111, 5, 0, 0,112, 5, 0, 0,113, 5, 32, 0,114, 5, 0, 0,115, 5, 0, 0,116, 5, 0, 0,117, 5,
+ 0, 0,118, 5, 0, 0,119, 5, 0, 0,120, 5, 0, 0,121, 5, 0, 0,122, 5, 2, 0,123, 5, 2, 0,124, 5, 2, 0,125, 5,
+ 2, 0,126, 5, 2, 0,127, 5,195, 0, 8, 0, 4, 0,128, 5, 4, 0,129, 5, 4, 0,130, 5, 4, 0,131, 5, 4, 0,132, 5,
+ 4, 0,133, 5, 4, 0, 54, 0, 4, 0,103, 2,196, 0, 3, 0, 7, 0,134, 5, 2, 0,135, 5, 2, 0, 19, 0, 46, 0, 37, 0,
+ 27, 0, 31, 0, 39, 0, 75, 0, 32, 0,136, 5,173, 0,137, 5, 46, 0,138, 5, 47, 0,208, 0, 12, 0,139, 5,174, 0,140, 5,
+ 32, 0,141, 5, 7, 0,142, 5, 7, 0,143, 5, 7, 0,144, 5, 7, 0,145, 5, 4, 0, 83, 3, 2, 0, 19, 0, 2, 0, 34, 1,
+ 61, 0, 29, 1,197, 0,146, 5,194, 0,147, 5,198, 0,148, 5,180, 0,182, 0,178, 0,159, 4, 12, 0,100, 0, 12, 0,149, 5,
+ 12, 0,150, 5,199, 0,151, 5, 2, 0,152, 5, 2, 0,153, 5, 2, 0,217, 0, 2, 0,154, 5, 4, 0,155, 5, 4, 0,156, 5,
+ 12, 0,157, 5,183, 0, 27, 5,184, 0,158, 5,196, 0,159, 5,161, 0, 70, 3,200, 0, 6, 0, 47, 0,208, 0, 45, 0, 28, 1,
+ 7, 0, 67, 2, 7, 0, 68, 2, 7, 0,106, 0, 7, 0,160, 5,201, 0, 35, 0, 7, 0,161, 5, 7, 0,162, 5, 7, 0,163, 5,
+ 7, 0,164, 5, 7, 0,165, 5, 7, 0,166, 5, 7, 0,167, 5, 7, 0,168, 5, 7, 0,169, 5, 7, 0, 47, 1, 7, 0,170, 5,
+ 7, 0,171, 5, 7, 0,172, 5, 7, 0,173, 5, 7, 0,171, 0, 2, 0,174, 5, 2, 0,175, 5, 4, 0,176, 5, 2, 0,177, 5,
+ 2, 0,178, 5, 2, 0,179, 5, 2, 0,180, 5, 7, 0,181, 5, 72, 0,182, 5,161, 0, 70, 3,201, 0,183, 5,202, 0,184, 5,
+203, 0,185, 5,204, 0,186, 5,205, 0,187, 5,206, 0,188, 5, 7, 0,189, 5, 2, 0,190, 5, 2, 0,191, 5, 4, 0,209, 1,
+207, 0, 54, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 7, 0,169, 5,
+ 7, 0, 47, 1, 7, 0, 43, 0, 4, 0,196, 5, 2, 0,179, 5, 2, 0,180, 5, 32, 0,136, 5, 32, 0,197, 5,200, 0,198, 5,
+207, 0,183, 5, 0, 0,199, 5, 4, 0, 83, 3, 4, 0,200, 5, 2, 0,201, 5, 2, 0,202, 5, 2, 0,203, 5, 2, 0,204, 5,
+ 2, 0,209, 1, 2, 0, 19, 0, 2, 0, 6, 2, 2, 0,205, 5, 7, 0,112, 0, 7, 0,206, 5, 7, 0,207, 5, 7, 0,208, 5,
+ 7, 0,209, 5, 7, 0,210, 5, 7, 0,171, 0, 7, 0,142, 5, 2, 0,211, 5, 2, 0, 90, 1, 2, 0,212, 5, 2, 0,213, 5,
+ 2, 0,214, 5, 2, 0,215, 5, 2, 0,216, 5, 2, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5, 4, 0,220, 5, 12, 0,221, 5,
+ 2, 0,222, 5, 2, 0,116, 2, 2, 0,223, 5, 0, 0,224, 5, 0, 0,225, 5, 9, 0,226, 5,161, 0, 70, 3,209, 0, 25, 0,
+ 24, 0, 36, 0, 24, 0, 64, 0, 23, 0,227, 5, 23, 0,228, 5, 23, 0,229, 5, 7, 0,230, 5, 7, 0,231, 5, 7, 0,232, 5,
+ 7, 0,233, 5, 2, 0,234, 5, 2, 0,235, 5, 2, 0,236, 5, 2, 0,237, 5, 2, 0,238, 5, 2, 0, 19, 0, 2, 0,239, 5,
+ 2, 0,240, 5, 2, 0,241, 5, 2, 0,242, 5, 2, 0,243, 5, 2, 0,204, 5, 7, 0,244, 5, 7, 0,245, 5, 4, 0,246, 5,
+ 4, 0,247, 5,208, 0, 6, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,
+210, 0, 8, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,211, 0,248, 5,
+ 46, 0,134, 0,212, 0, 14, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,
+209, 0,249, 5,213, 0,250, 5, 12, 0,251, 5, 2, 0, 40, 1, 2, 0, 19, 0, 2, 0,252, 5, 0, 0,253, 5, 0, 0,254, 5,
+214, 0, 20, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,202, 0,184, 5,
+209, 0,249, 5, 2, 0,255, 5, 2, 0, 0, 6, 2, 0, 1, 6, 2, 0, 2, 6, 2, 0,239, 5, 2, 0, 3, 6, 0, 0, 19, 0,
+ 0, 0,105, 1, 9, 0, 43, 2, 4, 0, 4, 6, 4, 0, 5, 6, 27, 0, 6, 6,215, 0, 16, 0,208, 0, 0, 0,208, 0, 1, 0,
+ 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, 7, 0, 67, 2, 7, 0, 68, 2, 2, 0,255, 5,
+ 2, 0, 7, 6, 2, 0, 8, 6, 2, 0, 9, 6, 4, 0, 19, 0, 7, 0, 10, 6,161, 0, 70, 3,216, 0, 16, 0, 0, 0, 11, 6,
+ 0, 0, 12, 6, 0, 0, 13, 6, 0, 0, 14, 6, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 15, 6, 2, 0, 16, 6, 2, 0,152, 1,
+ 2, 0, 17, 6, 4, 0, 18, 6, 4, 0, 19, 6, 2, 0, 20, 6, 2, 0, 21, 6, 0, 0, 22, 6, 0, 0, 23, 6,217, 0, 16, 0,
+208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 4, 0, 37, 0,216, 0, 24, 6,218, 0, 25, 6, 12, 0, 26, 6,
+ 12, 0, 27, 6,219, 0, 28, 6,206, 0, 29, 6,220, 0, 30, 6, 2, 0, 31, 6, 2, 0, 32, 6, 2, 0, 33, 6, 2, 0, 70, 0,
+221, 0, 17, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5,
+ 12, 0, 34, 6,222, 0, 35, 6, 0, 0, 36, 6,223, 0, 37, 6, 4, 0, 38, 6, 4, 0, 39, 6, 2, 0, 19, 0, 2, 0, 40, 6,
+ 2, 0, 41, 6, 2, 0, 37, 0,224, 0, 29, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,
+ 2, 0,195, 5, 47, 0,206, 2, 45, 0, 28, 1, 64, 0, 42, 6, 2, 0,133, 0, 2, 0, 43, 6, 2, 0, 70, 0, 2, 0, 44, 6,
+ 4, 0, 19, 0, 2, 0, 45, 6, 2, 0,254, 5, 2, 0,253, 5, 2, 0,209, 1, 0, 0, 46, 6, 0, 0, 47, 6, 0, 0, 48, 6,
+ 0, 0,204, 5, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 10, 6, 7, 0, 90, 1, 7, 0, 49, 6, 7, 0, 50, 6,161, 0, 70, 3,
+225, 0, 11, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 2, 0,252, 5,
+ 2, 0, 19, 0, 4, 0, 37, 0,213, 0,250, 5,209, 0,249, 5,226, 0, 27, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5,
+ 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 42, 0, 51, 6, 4, 0, 52, 6, 4, 0, 53, 6, 2, 0, 90, 0, 2, 0,133, 0,
+ 2, 0, 54, 6, 0, 0, 55, 6, 0, 0, 56, 6, 4, 0, 57, 6, 4, 0, 58, 6, 4, 0, 59, 6, 4, 0, 60, 6, 2, 0, 61, 6,
+ 2, 0, 62, 6, 7, 0, 63, 6, 23, 0, 64, 6, 23, 0, 65, 6, 4, 0, 66, 6, 4, 0, 67, 6, 0, 0, 68, 6, 0, 0, 69, 6,
+227, 0, 10, 0, 27, 0, 31, 0, 9, 0, 70, 6, 9, 0, 71, 6, 9, 0, 72, 6, 9, 0, 73, 6, 9, 0, 74, 6, 4, 0, 90, 0,
+ 4, 0, 75, 6, 0, 0, 76, 6, 0, 0, 77, 6,228, 0, 10, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5,
+ 7, 0,194, 5,227, 0, 78, 6, 2, 0, 90, 0, 2, 0,133, 0, 4, 0, 43, 0, 9, 0, 79, 6,229, 0, 8, 0,208, 0, 0, 0,
+208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,209, 0,249, 5, 4, 0, 19, 0, 4, 0, 80, 6,230, 0, 23, 0,
+208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, 27, 0, 81, 6,
+ 27, 0, 81, 0, 2, 0, 19, 0, 2, 0,133, 0, 7, 0, 82, 6, 9, 0, 83, 6, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 84, 6,
+ 7, 0, 85, 6, 61, 0, 29, 1, 61, 0, 86, 6, 4, 0, 87, 6, 2, 0, 88, 6, 2, 0, 37, 0,161, 0, 70, 3,231, 0, 10, 0,
+208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 2, 0, 19, 0, 2, 0, 92, 3,
+ 4, 0, 37, 0,161, 0, 70, 3,232, 0, 42, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,
+ 2, 0,195, 5,209, 0,249, 5,218, 0, 25, 6, 0, 0, 11, 6, 0, 0, 12, 6, 0, 0, 13, 6, 2, 0, 17, 0, 2, 0, 21, 6,
+ 2, 0, 19, 0, 2, 0, 15, 6, 9, 0, 83, 6, 4, 0, 18, 6, 4, 0, 89, 6, 4, 0, 90, 6, 4, 0, 19, 6, 23, 0, 91, 6,
+ 23, 0, 92, 6, 7, 0, 93, 6, 7, 0, 94, 6, 7, 0, 95, 6, 7, 0, 82, 6, 2, 0, 96, 6, 2, 0,207, 0, 2, 0,152, 1,
+ 2, 0, 17, 6, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 97, 6, 2, 0, 98, 6, 9, 0, 99, 6, 9, 0,100, 6, 9, 0,101, 6,
+ 9, 0,102, 6, 9, 0,103, 6, 2, 0,104, 6, 0, 0, 23, 6, 57, 0,105, 6,233, 0, 7, 0,233, 0, 0, 0,233, 0, 1, 0,
+ 4, 0,106, 6, 4, 0, 23, 0, 0, 0, 84, 0, 4, 0,107, 6, 4, 0, 17, 0,234, 0, 13, 0,208, 0, 0, 0,208, 0, 1, 0,
+ 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 4, 0, 17, 0, 4, 0,108, 6, 4, 0, 19, 0, 4, 0, 54, 6,
+ 12, 0,109, 6, 12, 0,110, 6, 0, 0,111, 6,235, 0, 5, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5,
+ 4, 0, 37, 0,236, 0, 7, 0,236, 0, 0, 0,236, 0, 1, 0, 0, 0,112, 6, 2, 0,113, 6, 2, 0,114, 6, 2, 0,115, 6,
+ 2, 0, 37, 0,237, 0, 12, 0, 2, 0,114, 6, 2, 0,116, 6, 2, 0,117, 6, 0, 0,167, 2, 2, 0,118, 6, 2, 0,119, 6,
+ 2, 0,120, 6, 2, 0,121, 6, 2, 0,122, 6, 2, 0,239, 5, 7, 0,123, 6, 7, 0,124, 6,238, 0, 18, 0,238, 0, 0, 0,
+238, 0, 1, 0, 0, 0,193, 3,237, 0,125, 6,237, 0,126, 6,237, 0,127, 6,237, 0,128, 6, 7, 0,129, 6, 2, 0,130, 6,
+ 2, 0,131, 6, 2, 0,132, 6, 2, 0,133, 6, 2, 0,134, 6, 2, 0,135, 6, 2, 0,136, 6, 2, 0,137, 6, 2, 0,138, 6,
+ 2, 0,139, 6,239, 0, 10, 0, 0, 0,140, 6, 0, 0,141, 6, 0, 0,142, 6, 0, 0,143, 6, 0, 0,144, 6, 0, 0,145, 6,
+ 2, 0,146, 6, 2, 0,147, 6, 2, 0,148, 6, 2, 0, 37, 0,240, 0, 8, 0, 0, 0,149, 6, 0, 0,150, 6, 0, 0,151, 6,
+ 0, 0,152, 6, 0, 0,153, 6, 0, 0,154, 6, 7, 0,160, 5, 7, 0, 37, 0,241, 0, 17, 0,239, 0,155, 6,239, 0,156, 6,
+239, 0,157, 6,239, 0,158, 6,239, 0,159, 6,239, 0,160, 6,239, 0,161, 6,239, 0,162, 6,239, 0,163, 6,239, 0,164, 6,
+239, 0,165, 6,239, 0,166, 6,239, 0,167, 6,239, 0,168, 6,239, 0,169, 6,240, 0,170, 6, 0, 0,171, 6,242, 0, 71, 0,
+ 0, 0,172, 6, 0, 0,173, 6, 0, 0,144, 6, 0, 0,174, 6, 0, 0,175, 6, 0, 0,176, 6, 0, 0,177, 6, 0, 0,178, 6,
+ 0, 0,179, 6, 0, 0,180, 6, 0, 0,181, 6, 0, 0,182, 6, 0, 0,183, 6, 0, 0,184, 6, 0, 0,185, 6, 0, 0,186, 6,
+ 0, 0,187, 6, 0, 0,188, 6, 0, 0,189, 6, 0, 0,190, 6, 0, 0,191, 6, 0, 0,192, 6, 0, 0,193, 6, 0, 0,194, 6,
+ 0, 0,195, 6, 0, 0,196, 6, 0, 0,197, 6, 0, 0,198, 6, 0, 0,199, 6, 0, 0,200, 6, 0, 0,201, 6, 0, 0,202, 6,
+ 0, 0,203, 6, 0, 0,204, 6, 0, 0,205, 6, 0, 0,206, 6, 0, 0,207, 6, 0, 0,208, 6, 0, 0,209, 6, 0, 0,210, 6,
+ 0, 0,211, 6, 0, 0,212, 6, 0, 0,213, 6, 0, 0,214, 6, 0, 0,215, 6, 0, 0,216, 6, 0, 0,217, 6, 0, 0,218, 6,
+ 0, 0,219, 6, 0, 0,220, 6, 0, 0,221, 6, 0, 0,222, 6, 0, 0,223, 6, 0, 0,224, 6, 0, 0,225, 6, 0, 0,226, 6,
+ 0, 0,227, 6, 0, 0,228, 6, 0, 0,229, 6, 0, 0,230, 6, 0, 0,231, 6, 0, 0,232, 6, 0, 0,233, 6, 0, 0,234, 6,
+ 0, 0,235, 6, 0, 0,236, 6, 0, 0,237, 6, 0, 0,238, 6, 0, 0,239, 6, 0, 0,240, 6, 0, 0, 92, 0,243, 0, 5, 0,
+ 0, 0,241, 6, 0, 0,196, 6, 0, 0,198, 6, 2, 0, 19, 0, 2, 0, 37, 0,244, 0, 22, 0,244, 0, 0, 0,244, 0, 1, 0,
+ 0, 0, 20, 0,241, 0,242, 6,242, 0,243, 6,242, 0,244, 6,242, 0,245, 6,242, 0,246, 6,242, 0,247, 6,242, 0,248, 6,
+242, 0,249, 6,242, 0,250, 6,242, 0,251, 6,242, 0,252, 6,242, 0,253, 6,242, 0,254, 6,242, 0,255, 6,242, 0, 0, 7,
+242, 0, 1, 7,242, 0, 2, 7,242, 0, 3, 7,243, 0, 4, 7,245, 0, 5, 0, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,115, 2,
+ 7, 0, 5, 7, 7, 0, 21, 2,246, 0, 71, 0, 4, 0, 19, 0, 4, 0, 6, 7, 4, 0, 7, 7, 0, 0, 8, 7, 0, 0, 9, 7,
+ 0, 0, 10, 7, 0, 0, 11, 7, 0, 0, 12, 7, 0, 0, 13, 7, 0, 0, 14, 7, 0, 0, 15, 7, 0, 0, 16, 7, 2, 0, 17, 7,
+ 2, 0, 37, 0, 4, 0, 18, 7, 4, 0, 19, 7, 4, 0, 20, 7, 4, 0, 21, 7, 2, 0, 22, 7, 2, 0, 23, 7, 4, 0, 24, 7,
+ 4, 0, 25, 7, 4, 0, 26, 7, 4, 0, 27, 7, 4, 0, 28, 7, 4, 0,109, 6, 4, 0, 29, 7, 2, 0, 30, 7, 2, 0, 31, 7,
+ 2, 0, 32, 7, 2, 0, 33, 7, 12, 0, 34, 7, 12, 0, 35, 7, 12, 0, 36, 7, 2, 0, 37, 7, 2, 0, 38, 7, 2, 0, 39, 7,
+ 2, 0, 40, 7, 2, 0, 41, 7, 2, 0, 42, 7, 2, 0, 43, 7, 2, 0, 44, 7,245, 0, 45, 7, 2, 0, 46, 7, 2, 0, 47, 7,
+ 2, 0, 48, 7, 2, 0, 49, 7, 2, 0, 50, 7, 2, 0, 51, 7, 2, 0, 52, 7, 2, 0, 53, 7, 4, 0, 54, 7, 4, 0, 55, 7,
+ 2, 0, 56, 7, 2, 0, 57, 7, 2, 0, 58, 7, 2, 0, 59, 7, 2, 0, 60, 7, 2, 0, 61, 7, 2, 0, 62, 7, 2, 0, 63, 7,
+ 2, 0, 64, 7, 2, 0, 65, 7, 2, 0, 66, 7, 2, 0, 67, 7, 0, 0, 68, 7, 0, 0, 69, 7, 7, 0, 70, 7, 2, 0, 90, 5,
+ 2, 0, 91, 5, 55, 0, 71, 7,211, 0, 21, 0, 27, 0, 31, 0, 12, 0, 72, 7, 12, 0, 73, 7, 12, 0, 74, 7, 12, 0,192, 5,
+ 46, 0,134, 0, 46, 0, 75, 7, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 79, 7, 2, 0, 80, 7, 2, 0, 81, 7,
+ 2, 0, 82, 7, 2, 0, 37, 0, 2, 0, 83, 7, 2, 0, 84, 7, 4, 0, 70, 0,206, 0, 85, 7, 9, 0, 86, 7, 2, 0, 87, 7,
+247, 0, 5, 0,247, 0, 0, 0,247, 0, 1, 0,247, 0, 88, 7, 13, 0, 89, 7, 4, 0, 19, 0,248, 0, 7, 0,248, 0, 0, 0,
+248, 0, 1, 0,247, 0, 90, 7,247, 0, 91, 7, 2, 0,199, 4, 2, 0, 19, 0, 4, 0, 37, 0,249, 0, 23, 0,249, 0, 0, 0,
+249, 0, 1, 0,250, 0, 92, 7,251, 0, 30, 6, 0, 0, 93, 7, 0, 0, 94, 7, 0, 0, 95, 7, 2, 0, 96, 7, 2, 0, 97, 7,
+ 2, 0, 98, 7, 2, 0, 99, 7, 2, 0,100, 7, 2, 0, 37, 0, 2, 0, 19, 0, 2, 0,101, 7, 2, 0,102, 7, 2, 0,103, 7,
+ 4, 0,104, 7,249, 0,105, 7, 9, 0,106, 7, 4, 0,107, 7, 4, 0,108, 7, 0, 0,109, 7,252, 0, 22, 0,252, 0, 0, 0,
+252, 0, 1, 0,247, 0, 90, 7,247, 0, 91, 7,247, 0,110, 7,247, 0,111, 7,211, 0,112, 7, 23, 0, 52, 0, 0, 0,193, 5,
+ 0, 0,113, 7, 2, 0,240, 5, 2, 0,241, 5, 2, 0,114, 7, 2, 0, 37, 0, 2, 0, 79, 7, 2, 0,107, 6, 2, 0, 19, 0,
+253, 0, 92, 7, 12, 0,115, 7, 12, 0,192, 5, 12, 0,116, 7, 12, 0,117, 7,254, 0, 21, 0,254, 0, 0, 0,254, 0, 1, 0,
+209, 0,249, 5, 23, 0,118, 7, 23, 0,119, 7, 2, 0,240, 5, 2, 0,241, 5, 2, 0,120, 7, 2, 0,121, 7, 2, 0,122, 7,
+ 2, 0, 19, 0, 7, 0, 63, 2, 2, 0, 78, 7, 2, 0, 82, 7, 4, 0, 43, 0,255, 0, 92, 7, 12, 0,123, 7, 12, 0,124, 7,
+ 12, 0,116, 7, 0, 0,125, 7, 9, 0,126, 7, 0, 1, 11, 0, 0, 0,127, 7, 2, 0,128, 7, 2, 0,129, 7, 2, 0,130, 7,
+ 2, 0,131, 7, 2, 0,188, 4, 2, 0,183, 4,211, 0,132, 7, 46, 0,133, 7, 4, 0,134, 7, 4, 0,135, 7, 1, 1, 1, 0,
+ 0, 0,136, 7, 2, 1, 8, 0, 57, 0,137, 7, 57, 0,138, 7, 2, 1,139, 7, 2, 1,140, 7, 2, 1,141, 7, 2, 0,129, 0,
+ 2, 0, 19, 0, 4, 0,142, 7, 3, 1, 4, 0, 4, 0, 52, 6, 4, 0,143, 7, 4, 0, 57, 6, 4, 0,144, 7, 4, 1, 2, 0,
+ 4, 0,145, 7, 4, 0,146, 7, 5, 1, 7, 0, 7, 0,147, 7, 7, 0,148, 7, 7, 0,149, 7, 4, 0, 19, 0, 4, 0, 37, 0,
+ 7, 0, 72, 4, 7, 0,150, 7, 6, 1, 6, 0, 0, 0,151, 7, 0, 0, 13, 6, 49, 0,137, 0, 2, 0,106, 0, 2, 0,187, 4,
+ 4, 0, 37, 0, 7, 1, 21, 0, 7, 1, 0, 0, 7, 1, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0,152, 7,
+ 4, 0,153, 7, 4, 0,154, 7, 1, 1,155, 7, 0, 0,151, 7, 4, 0,156, 7, 4, 0,157, 7, 6, 1, 64, 3, 3, 1,158, 7,
+ 4, 1,159, 7, 5, 1,160, 7, 2, 1,161, 7, 2, 1,162, 7, 2, 1,163, 7, 57, 0,164, 7, 57, 0,165, 7, 8, 1, 12, 0,
+ 0, 0,239, 1, 9, 0,193, 0, 0, 0,194, 0, 4, 0,197, 0, 4, 0,205, 0, 9, 0,198, 0, 7, 0,200, 0, 7, 0,201, 0,
+ 9, 0,166, 7, 9, 0,167, 7, 9, 0,202, 0, 9, 0,204, 0, 9, 1, 43, 0, 9, 1, 0, 0, 9, 1, 1, 0, 9, 0,168, 7,
+ 9, 0, 26, 0, 0, 0, 27, 0, 4, 0, 19, 0, 4, 0, 17, 0, 4, 0, 23, 0, 4, 0, 88, 0, 4, 0,169, 7, 4, 0,170, 7,
+ 4, 0,153, 7, 4, 0,154, 7, 4, 0,171, 7, 4, 0,216, 0, 4, 0,172, 7, 4, 0,173, 7, 7, 0, 56, 5, 7, 0,174, 7,
+ 4, 0,126, 0, 4, 0,175, 7, 7, 1,176, 7, 36, 0, 80, 0, 46, 0,134, 0, 49, 0,137, 0, 7, 0,177, 7, 7, 0,178, 7,
+ 8, 1, 30, 1, 9, 1,179, 7, 9, 1,180, 7, 9, 1,181, 7, 12, 0,182, 7, 10, 1,183, 7, 11, 1,184, 7, 7, 0,185, 7,
+ 7, 0,186, 7, 4, 0,187, 7, 7, 0,188, 7, 9, 0,189, 7, 4, 0,190, 7, 4, 0,191, 7, 4, 0,192, 7, 7, 0,193, 7,
+ 12, 1, 4, 0, 12, 1, 0, 0, 12, 1, 1, 0, 12, 0,194, 7, 9, 1,195, 7,197, 0, 6, 0, 12, 0,196, 7, 12, 0,182, 7,
+ 12, 0,197, 7, 9, 1,198, 7, 0, 0,199, 7, 0, 0,200, 7, 13, 1, 4, 0, 7, 0,201, 7, 7, 0,109, 0, 2, 0,202, 7,
+ 2, 0,203, 7, 14, 1, 6, 0, 7, 0,204, 7, 7, 0,205, 7, 7, 0,206, 7, 7, 0,207, 7, 4, 0,208, 7, 4, 0,209, 7,
+ 15, 1, 12, 0, 7, 0,210, 7, 7, 0,211, 7, 7, 0,212, 7, 7, 0,213, 7, 7, 0,214, 7, 7, 0,215, 7, 7, 0,216, 7,
+ 7, 0,217, 7, 7, 0,218, 7, 7, 0,219, 7, 4, 0,210, 2, 4, 0,220, 7, 16, 1, 2, 0, 7, 0, 25, 5, 7, 0, 37, 0,
+ 17, 1, 5, 0, 7, 0,221, 7, 7, 0,222, 7, 4, 0, 90, 0, 4, 0,168, 2, 4, 0,223, 7, 18, 1, 6, 0, 18, 1, 0, 0,
+ 18, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0, 57, 0, 19, 1, 8, 0, 19, 1, 0, 0, 19, 1, 1, 0,
+ 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0,126, 0, 20, 1, 45, 0, 20, 1, 0, 0,
+ 20, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0,212, 0, 2, 0,244, 3, 2, 0,225, 7, 7, 0,226, 7,
+ 7, 0, 89, 0, 7, 0,223, 2, 4, 0,227, 7, 4, 0, 82, 0, 4, 0,170, 2, 7, 0,228, 7, 7, 0,229, 7, 7, 0,230, 7,
+ 7, 0,231, 7, 7, 0,232, 7, 7, 0,233, 7, 7, 0,220, 2, 7, 0, 27, 1, 7, 0,234, 7, 7, 0,235, 7, 7, 0, 37, 0,
+ 7, 0,236, 7, 7, 0,237, 7, 7, 0,238, 7, 2, 0,239, 7, 2, 0,240, 7, 2, 0,241, 7, 2, 0,242, 7, 2, 0,243, 7,
+ 2, 0,244, 7, 2, 0,245, 7, 2, 0,246, 7, 2, 0, 6, 2, 2, 0,247, 7, 2, 0, 3, 2, 2, 0,248, 7, 0, 0,249, 7,
+ 0, 0,250, 7, 7, 0,210, 0, 21, 1,251, 7, 68, 0,212, 1, 22, 1, 16, 0, 22, 1, 0, 0, 22, 1, 1, 0, 2, 0, 17, 0,
+ 2, 0, 19, 0, 2, 0,224, 7, 2, 0,212, 0, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 7, 0, 52, 2, 7, 0,218, 2,
+ 7, 0,219, 2, 7, 0,252, 7, 7, 0,220, 2, 7, 0,222, 2, 7, 0,223, 2,223, 0, 5, 0, 2, 0, 17, 0, 2, 0,142, 7,
+ 2, 0, 19, 0, 2, 0,253, 7, 27, 0, 81, 6,222, 0, 3, 0, 4, 0, 69, 0, 4, 0,254, 7,223, 0, 2, 0, 23, 1, 7, 0,
+ 23, 1, 0, 0, 23, 1, 1, 0, 0, 0, 20, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 22, 0, 9, 0,255, 7, 24, 1, 5, 0,
+ 0, 0, 20, 0, 7, 0, 47, 1, 7, 0, 0, 8, 4, 0, 1, 8, 4, 0, 37, 0, 25, 1, 4, 0, 2, 0, 17, 0, 2, 0, 19, 0,
+ 2, 0, 43, 0, 2, 0, 70, 0, 26, 1, 4, 0, 0, 0, 20, 0, 67, 0, 2, 8, 7, 0, 47, 1, 7, 0, 37, 0, 27, 1, 6, 0,
+ 2, 0, 3, 8, 2, 0, 4, 8, 2, 0, 17, 0, 2, 0, 5, 8, 0, 0, 6, 8, 0, 0, 7, 8, 28, 1, 5, 0, 4, 0, 17, 0,
+ 4, 0, 37, 0, 0, 0, 20, 0, 0, 0, 8, 8, 0, 0, 9, 8, 29, 1, 3, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0,
+ 30, 1, 4, 0, 2, 0, 10, 8, 2, 0, 11, 8, 2, 0, 19, 0, 2, 0, 37, 0, 31, 1, 6, 0, 0, 0, 20, 0, 0, 0, 12, 8,
+ 2, 0, 13, 8, 2, 0,220, 2, 2, 0, 40, 1, 2, 0, 70, 0, 32, 1, 5, 0, 0, 0, 20, 0, 7, 0,109, 0, 7, 0, 74, 4,
+ 2, 0, 19, 0, 2, 0,182, 2, 33, 1, 3, 0, 0, 0, 20, 0, 4, 0,170, 2, 4, 0, 10, 8, 34, 1, 7, 0, 0, 0, 20, 0,
+ 7, 0, 74, 4, 0, 0, 14, 8, 0, 0, 15, 8, 2, 0, 40, 1, 2, 0, 43, 0, 4, 0, 16, 8, 35, 1, 3, 0, 32, 0, 17, 8,
+ 0, 0, 18, 8, 0, 0, 19, 8, 36, 1, 18, 0, 36, 1, 0, 0, 36, 1, 1, 0, 2, 0, 17, 0, 2, 0, 20, 8, 2, 0, 19, 0,
+ 2, 0, 21, 8, 2, 0, 22, 8, 2, 0, 23, 8, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 20, 0, 9, 0, 2, 0, 37, 1, 24, 8,
+ 32, 0, 45, 0, 2, 0, 40, 5, 2, 0,185, 7, 2, 0, 25, 8, 2, 0, 37, 0, 38, 1, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0,
+ 0, 0, 26, 8, 2, 0, 19, 0, 2, 0,182, 2, 2, 0, 27, 8, 4, 0, 28, 8, 4, 0, 29, 8, 4, 0, 30, 8, 4, 0, 31, 8,
+ 4, 0, 32, 8, 39, 1, 1, 0, 0, 0, 33, 8, 40, 1, 4, 0, 42, 0, 51, 6, 0, 0, 34, 8, 4, 0, 40, 1, 4, 0, 19, 0,
+ 37, 1, 18, 0, 37, 1, 0, 0, 37, 1, 1, 0, 37, 1, 35, 8, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 36, 8, 2, 0, 23, 8,
+ 2, 0, 20, 8, 2, 0, 37, 8, 2, 0, 70, 0, 2, 0,209, 1, 0, 0, 20, 0, 9, 0, 2, 0, 41, 1, 24, 8, 36, 1, 38, 8,
+ 2, 0, 15, 0, 2, 0, 39, 8, 4, 0, 40, 8, 42, 1, 3, 0, 4, 0,196, 2, 4, 0, 37, 0, 32, 0, 45, 0, 43, 1, 12, 0,
+159, 0, 41, 8, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0, 42, 8, 2, 0, 43, 8,
+ 2, 0, 44, 8, 2, 0, 45, 8, 2, 0, 46, 8, 7, 0, 47, 8, 44, 1, 13, 0, 2, 0, 19, 0, 2, 0, 48, 8, 4, 0,226, 7,
+ 4, 0, 89, 0, 2, 0, 49, 8, 7, 0,202, 3, 7, 0, 50, 8, 10, 1,183, 7, 45, 1, 51, 8, 2, 0, 17, 0, 2, 0, 52, 8,
+ 2, 0, 53, 8, 2, 0, 54, 8, 46, 1, 11, 0, 4, 0,196, 2, 2, 0, 17, 0, 2, 0, 19, 0, 32, 0, 45, 0, 81, 0, 55, 8,
+ 0, 0, 20, 0, 7, 0, 56, 8, 7, 0, 57, 8, 7, 0,100, 3, 2, 0, 58, 8, 2, 0, 59, 8, 47, 1, 5, 0, 2, 0, 17, 0,
+ 2, 0, 19, 0, 4, 0, 37, 0, 46, 0,134, 0, 32, 0,136, 5, 48, 1, 5, 0, 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 20, 0,
+ 0, 0, 8, 8, 32, 0, 45, 0, 49, 1, 13, 0, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0, 20, 8, 2, 0,101, 3, 7, 0, 60, 8,
+ 7, 0, 61, 8, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0, 77, 3, 7, 0, 80, 3, 7, 0, 62, 8, 7, 0, 63, 8, 32, 0, 64, 8,
+ 50, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0, 42, 8, 2, 0, 43, 0,
+ 2, 0, 64, 0, 2, 0, 65, 8, 2, 0, 66, 8, 51, 1, 8, 0, 32, 0, 45, 0, 7, 0,217, 2, 7, 0, 67, 8, 7, 0, 68, 8,
+ 7, 0,212, 2, 2, 0, 19, 0, 2, 0,182, 2, 7, 0, 69, 8, 52, 1, 12, 0, 2, 0, 17, 0, 2, 0, 40, 1, 2, 0, 19, 0,
+ 2, 0,220, 2, 2, 0,196, 2, 2, 0, 70, 8, 4, 0, 37, 0, 7, 0, 71, 8, 7, 0, 72, 8, 7, 0, 73, 8, 7, 0, 74, 8,
+ 0, 0, 75, 8, 53, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 2, 0,105, 1,
+ 2, 0, 64, 0, 2, 0, 65, 8, 2, 0, 66, 8, 68, 0,212, 1, 54, 1, 7, 0, 4, 0,170, 2, 4, 0, 76, 8, 4, 0, 77, 8,
+ 4, 0, 78, 8, 7, 0, 79, 8, 7, 0, 80, 8, 0, 0, 14, 8, 55, 1, 7, 0, 0, 0, 81, 8, 32, 0, 82, 8, 0, 0, 18, 8,
+ 2, 0, 83, 8, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0, 19, 8, 56, 1, 6, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7,
+ 4, 0, 89, 0, 0, 0, 84, 8, 0, 0, 85, 8, 57, 1, 1, 0, 4, 0, 19, 0, 58, 1, 6, 0, 0, 0, 92, 0, 2, 0, 17, 0,
+ 2, 0, 19, 0, 4, 0, 86, 8, 7, 0, 87, 8, 42, 0, 51, 6, 59, 1, 4, 0, 0, 0, 48, 2, 2, 0, 19, 0, 4, 0, 17, 0,
+ 32, 0, 45, 0, 60, 1, 2, 0, 4, 0, 17, 0, 4, 0,229, 5, 41, 1, 10, 0, 41, 1, 0, 0, 41, 1, 1, 0, 41, 1, 35, 8,
+ 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 20, 8, 2, 0, 88, 8, 0, 0, 20, 0, 9, 0, 2, 0, 32, 0, 45, 0, 61, 1, 10, 0,
+ 7, 0,100, 3, 7, 0, 89, 8, 7, 0, 90, 8, 7, 0, 91, 8, 7, 0, 92, 8, 4, 0, 19, 0, 7, 0, 70, 8, 7, 0, 93, 8,
+ 7, 0, 94, 8, 7, 0, 37, 0, 11, 1, 12, 0, 11, 1, 0, 0, 11, 1, 1, 0, 10, 1, 95, 8, 9, 0,193, 0, 4, 0,143, 3,
+ 4, 0,189, 3, 4, 0,190, 3, 4, 0, 96, 8, 4, 0, 97, 8, 4, 0, 98, 8, 7, 0,202, 3, 7, 0, 37, 0, 45, 1, 8, 0,
+ 7, 0, 99, 8, 7, 0,100, 8, 7, 0,101, 8, 7, 0,102, 8, 7, 0,103, 8, 7, 0,104, 8, 7, 0,105, 8, 7, 0,106, 8,
+ 10, 1, 15, 0, 27, 0, 31, 0, 0, 0,192, 0, 43, 0,149, 0, 9, 0,193, 0, 43, 0,107, 8, 36, 0, 80, 0, 7, 0,202, 3,
+ 7, 0,108, 8, 7, 0, 50, 8, 7, 0, 99, 8, 7, 0,100, 8, 7, 0,109, 8, 4, 0, 90, 0, 4, 0, 98, 8, 9, 0,110, 8,
+ 62, 1, 15, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,252, 0,111, 8,209, 0,249, 5,
+ 10, 1,183, 7, 2, 0, 40, 1, 2, 0, 48, 8, 2, 0, 67, 2, 2, 0, 68, 2, 2, 0, 19, 0, 2, 0,254, 5, 4, 0, 70, 0,
+ 63, 1, 6, 0, 63, 1, 0, 0, 63, 1, 1, 0, 32, 0, 45, 0, 9, 0,112, 8, 4, 0,217, 0, 4, 0, 37, 0, 68, 0, 4, 0,
+ 27, 0, 31, 0, 12, 0,113, 8, 4, 0,131, 0, 7, 0,114, 8, 64, 1, 25, 0, 64, 1, 0, 0, 64, 1, 1, 0, 64, 1, 38, 0,
+ 12, 0,115, 8, 0, 0, 20, 0, 7, 0,116, 8, 7, 0,117, 8, 7, 0,118, 8, 7, 0,119, 8, 4, 0, 19, 0, 7, 0,120, 8,
+ 7, 0,121, 8, 7, 0,122, 8, 7, 0, 47, 1, 7, 0, 14, 2, 7, 0,123, 8, 7, 0,168, 2, 7, 0,124, 8, 7, 0,125, 8,
+ 7, 0,126, 8, 7, 0,127, 8, 7, 0,128, 8, 7, 0,172, 0, 2, 0,131, 0, 2, 0, 71, 5, 65, 1, 21, 0, 27, 0, 31, 0,
+ 12, 0,129, 8, 12, 0,130, 8, 12, 0,131, 8, 9, 0,132, 8, 4, 0, 19, 0, 4, 0,201, 5, 2, 0,224, 2, 2, 0, 4, 6,
+ 2, 0,131, 0, 2, 0,133, 8, 2, 0,134, 8, 2, 0,135, 8, 2, 0,136, 8, 2, 0,137, 8, 4, 0,138, 8, 4, 0,139, 8,
+ 4, 0,140, 8, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 66, 1, 2, 0, 7, 0,129, 2, 4, 0, 19, 0, 67, 1, 5, 0,
+ 66, 1,144, 8, 4, 0,168, 2, 4, 0,145, 8, 4, 0,146, 8, 4, 0, 19, 0, 68, 1, 6, 0, 4, 0, 37, 0, 4, 0, 4, 6,
+ 4, 0,140, 8, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 69, 1, 38, 0, 69, 1, 0, 0, 69, 1, 1, 0, 26, 0,147, 8,
+ 12, 0,127, 3, 0, 0, 20, 0, 2, 0, 19, 0, 2, 0,148, 8, 2, 0,149, 8, 2, 0,150, 8, 2, 0, 86, 3, 2, 0,151, 8,
+ 4, 0, 50, 2, 4, 0,140, 8, 4, 0,141, 8, 64, 1,152, 8, 69, 1, 38, 0, 69, 1,153, 8, 12, 0,154, 8, 9, 0,155, 8,
+ 9, 0,156, 8, 9, 0,157, 8, 7, 0, 35, 1, 7, 0,172, 0, 7, 0,158, 8, 7, 0,249, 1, 2, 0,159, 8, 2, 0, 37, 0,
+ 7, 0,160, 8, 7, 0,161, 8, 7, 0, 82, 3, 7, 0,162, 8, 7, 0,163, 8, 7, 0,164, 8, 7, 0,165, 8, 7, 0,166, 8,
+ 7, 0,167, 8, 7, 0, 43, 2, 32, 0,168, 8,160, 0, 9, 0, 12, 0,169, 8, 2, 0, 19, 0, 2, 0,170, 8, 7, 0, 79, 2,
+ 7, 0,171, 8, 7, 0,172, 8, 12, 0,173, 8, 4, 0,174, 8, 4, 0, 37, 0, 70, 1, 7, 0, 70, 1, 0, 0, 70, 1, 1, 0,
+ 12, 0,175, 8, 4, 0, 19, 0, 4, 0,176, 8, 0, 0,193, 3,243, 0,177, 8,159, 0, 7, 0, 27, 0, 31, 0, 12, 0,178, 8,
+ 12, 0,169, 8, 12, 0,179, 8, 12, 0,100, 0, 4, 0, 19, 0, 4, 0,180, 8,213, 0, 4, 0, 27, 0, 95, 8, 12, 0,169, 8,
+ 4, 0,181, 8, 4, 0, 19, 0, 71, 1, 17, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,
+ 2, 0,195, 5,209, 0,249, 5,159, 0, 67, 3,213, 0,182, 8, 0, 0, 40, 1, 0, 0,252, 5, 2, 0, 19, 0, 2, 0,183, 8,
+ 2, 0,253, 5, 2, 0,254, 5, 2, 0,184, 8, 7, 0,185, 8, 72, 1, 8, 0, 72, 1, 0, 0, 72, 1, 1, 0, 70, 1,186, 8,
+ 36, 0, 80, 0, 12, 0, 71, 3, 4, 0, 19, 0, 0, 0, 20, 0, 4, 0,187, 8, 73, 1, 5, 0, 73, 1, 0, 0, 73, 1, 1, 0,
+ 36, 0, 80, 0, 2, 0, 19, 0, 0, 0,188, 8, 74, 1, 12, 0, 74, 1, 0, 0, 74, 1, 1, 0, 9, 0, 2, 0, 2, 0, 17, 0,
+ 2, 0, 19, 0, 0, 0,189, 8, 0, 0,190, 8, 0, 0,188, 8, 7, 0,191, 8, 7, 0,192, 8, 4, 0, 37, 0, 36, 0, 80, 0,
+ 75, 1, 9, 0, 75, 1, 0, 0, 75, 1, 1, 0, 32, 0,193, 8, 0, 0,227, 2, 7, 0,194, 8, 2, 0,195, 8, 2, 0, 19, 0,
+ 2, 0, 17, 0, 2, 0,196, 8, 76, 1, 7, 0, 42, 0, 51, 6, 26, 0,147, 8, 4, 0, 19, 0, 4, 0,197, 8, 12, 0,198, 8,
+ 32, 0,193, 8, 0, 0,227, 2, 77, 1, 12, 0, 32, 0,193, 8, 2, 0,199, 8, 2, 0, 19, 0, 2, 0,200, 8, 2, 0,201, 8,
+ 0, 0,227, 2, 32, 0,202, 8, 0, 0,203, 8, 7, 0,204, 8, 7, 0, 14, 2, 7, 0,205, 8, 7, 0,206, 8, 78, 1, 6, 0,
+ 32, 0,193, 8, 4, 0,207, 8, 4, 0,208, 8, 4, 0, 90, 0, 4, 0, 37, 0, 0, 0,227, 2, 79, 1, 4, 0, 32, 0,193, 8,
+ 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, 80, 1, 4, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2,
+ 81, 1, 10, 0, 32, 0,193, 8, 4, 0,209, 8, 7, 0,125, 0, 4, 0, 19, 0, 2, 0, 47, 6, 2, 0,210, 8, 2, 0, 43, 0,
+ 2, 0, 70, 0, 7, 0,211, 8, 0, 0,227, 2, 82, 1, 4, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2,
+ 83, 1, 10, 0, 32, 0,193, 8, 2, 0, 17, 0, 2, 0,252, 3, 4, 0, 88, 0, 4, 0, 89, 0, 7, 0, 67, 8, 7, 0, 68, 8,
+ 4, 0, 37, 0,159, 0, 41, 8, 0, 0,227, 2, 84, 1, 4, 0, 32, 0,193, 8, 4, 0, 87, 3, 4, 0,212, 8, 0, 0,227, 2,
+ 85, 1, 5, 0, 32, 0,193, 8, 7, 0,125, 0, 4, 0,213, 8, 4, 0, 87, 3, 4, 0, 88, 3, 86, 1, 6, 0, 32, 0,193, 8,
+ 4, 0,214, 8, 4, 0,215, 8, 7, 0,216, 8, 7, 0,217, 8, 0, 0,227, 2, 87, 1, 16, 0, 32, 0,193, 8, 32, 0,153, 8,
+ 4, 0, 17, 0, 7, 0,218, 8, 7, 0,219, 8, 7, 0,220, 8, 7, 0,221, 8, 7, 0,222, 8, 7, 0,223, 8, 7, 0,224, 8,
+ 7, 0,225, 8, 7, 0,226, 8, 2, 0, 19, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, 88, 1, 3, 0, 32, 0,193, 8,
+ 4, 0, 19, 0, 4, 0, 6, 2, 89, 1, 5, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,227, 8, 0, 0,227, 2,
+ 90, 1, 10, 0, 32, 0,193, 8, 0, 0,227, 2, 2, 0,228, 8, 2, 0,229, 8, 0, 0,230, 8, 0, 0,231, 8, 7, 0,232, 8,
+ 7, 0,233, 8, 7, 0,234, 8, 7, 0,235, 8, 91, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0,
+ 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 92, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0,
+ 7, 0, 12, 0, 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 93, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0,
+ 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 94, 1, 7, 0, 32, 0,193, 8,
+ 0, 0,227, 2, 7, 0, 47, 1, 7, 0, 56, 1, 2, 0, 19, 0, 2, 0, 40, 1, 4, 0, 37, 0, 95, 1, 5, 0, 32, 0, 27, 3,
+ 7, 0, 47, 1, 2, 0, 31, 3, 0, 0, 33, 3, 0, 0,238, 8, 96, 1, 10, 0, 96, 1, 0, 0, 96, 1, 1, 0, 2, 0, 17, 0,
+ 2, 0, 19, 0, 0, 0,239, 8, 7, 0,246, 0, 7, 0,247, 0, 2, 0,175, 8, 2, 0,240, 8, 32, 0, 45, 0, 97, 1, 22, 0,
+ 97, 1, 0, 0, 97, 1, 1, 0, 2, 0, 19, 0, 2, 0, 40, 1, 2, 0,241, 8, 2, 0,242, 8, 36, 0, 80, 0,159, 0, 41, 8,
+ 32, 0,164, 0, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,243, 8, 7, 0,244, 8, 7, 0,245, 8, 7, 0,246, 8, 7, 0,213, 2,
+ 7, 0,247, 8, 7, 0, 43, 8, 7, 0,248, 8, 0, 0,249, 8, 0, 0,250, 8, 12, 0, 73, 3, 98, 1, 8, 0, 7, 0, 21, 2,
+ 7, 0, 67, 8, 7, 0, 68, 8, 9, 0, 2, 0, 2, 0,251, 8, 2, 0,252, 8, 2, 0,253, 8, 2, 0,254, 8, 99, 1, 18, 0,
+ 99, 1, 0, 0, 99, 1, 1, 0, 99, 1,255, 8, 0, 0, 20, 0, 98, 1, 0, 9, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 1, 9,
+ 2, 0, 2, 9, 2, 0, 3, 9, 2, 0, 4, 9, 4, 0, 43, 0, 7, 0, 5, 9, 7, 0, 6, 9, 4, 0, 7, 9, 4, 0, 8, 9,
+ 99, 1, 9, 9,100, 1, 10, 9,101, 1, 33, 0,101, 1, 0, 0,101, 1, 1, 0,101, 1, 11, 9, 0, 0, 20, 0, 0, 0, 12, 9,
+ 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,152, 7, 2, 0,185, 7, 2, 0, 13, 9, 2, 0,133, 0, 2, 0, 2, 9, 2, 0,142, 7,
+ 12, 0, 36, 8, 12, 0, 14, 9, 27, 0, 81, 6, 9, 0, 15, 9, 7, 0, 5, 9, 7, 0, 6, 9, 7, 0, 52, 2, 7, 0, 16, 9,
+ 2, 0, 17, 9, 2, 0, 18, 9, 7, 0, 19, 9, 7, 0, 20, 9, 2, 0, 21, 9, 2, 0, 22, 9, 9, 0, 23, 9, 24, 0, 24, 9,
+ 24, 0, 25, 9, 24, 0, 26, 9,102, 1,150, 0,103, 1, 27, 9,100, 1, 8, 0,100, 1, 0, 0,100, 1, 1, 0,101, 1, 28, 9,
+101, 1, 29, 9, 99, 1, 30, 9, 99, 1, 9, 9, 4, 0, 19, 0, 4, 0, 37, 0, 61, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0,
+ 12, 0, 31, 9, 12, 0, 32, 9, 98, 1, 33, 9, 12, 0, 34, 9, 4, 0, 17, 0, 4, 0, 35, 9, 4, 0, 36, 9, 4, 0, 37, 9,
+ 12, 0, 38, 9,103, 1, 39, 9, 99, 1, 40, 9, 99, 1, 41, 9, 9, 0, 42, 9, 9, 0, 43, 9, 4, 0, 44, 9, 9, 0, 45, 9,
+ 9, 0, 46, 9, 9, 0, 47, 9,104, 1, 6, 0, 4, 0,124, 0, 4, 0,126, 0, 4, 0,142, 7, 0, 0, 48, 9, 0, 0, 49, 9,
+ 2, 0, 37, 0,105, 1, 16, 0, 2, 0, 98, 7, 2, 0, 99, 7, 2, 0, 50, 9, 2, 0, 90, 8, 2, 0, 51, 9, 2, 0, 68, 0,
+ 7, 0,212, 2, 7, 0, 52, 9, 7, 0, 53, 9, 2, 0, 60, 1, 0, 0, 54, 9, 0, 0, 55, 5, 2, 0, 55, 9, 2, 0, 37, 0,
+ 4, 0, 56, 9, 4, 0, 57, 9,106, 1, 9, 0, 7, 0, 58, 9, 7, 0, 59, 9, 7, 0,109, 8, 7, 0,109, 0, 7, 0, 60, 9,
+ 7, 0, 10, 6, 2, 0, 61, 9, 0, 0, 62, 9, 0, 0, 37, 0,107, 1, 4, 0, 7, 0, 63, 9, 7, 0, 64, 9, 2, 0, 61, 9,
+ 2, 0, 37, 0,108, 1, 3, 0, 7, 0, 65, 9, 7, 0, 66, 9, 7, 0, 15, 0,109, 1, 7, 0, 0, 0,239, 1, 2, 0,185, 4,
+ 2, 0,186, 4, 2, 0,187, 4, 2, 0,138, 4, 4, 0,126, 0, 4, 0,250, 3,110, 1, 7, 0, 7, 0, 67, 9, 7, 0, 68, 9,
+ 7, 0, 69, 9, 7, 0, 63, 2, 7, 0, 70, 9, 7, 0, 71, 9, 7, 0, 72, 9,111, 1, 4, 0, 2, 0, 73, 9, 2, 0, 74, 9,
+ 2, 0, 75, 9, 2, 0, 76, 9,112, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,113, 1, 2, 0, 0, 0,166, 0, 0, 0, 77, 9,
+114, 1, 1, 0, 0, 0, 20, 0,115, 1, 10, 0, 0, 0, 78, 9, 0, 0, 79, 9, 0, 0, 3, 6, 0, 0, 80, 9, 2, 0, 50, 9,
+ 2, 0, 81, 9, 7, 0, 82, 9, 7, 0, 83, 9, 7, 0, 84, 9, 7, 0,247, 8,116, 1, 2, 0, 9, 0, 85, 9, 9, 0, 86, 9,
+117, 1, 11, 0, 0, 0,187, 4, 0, 0, 17, 0, 0, 0, 61, 9, 0, 0,109, 0, 0, 0, 87, 9, 0, 0,106, 0, 0, 0, 48, 2,
+ 7, 0, 88, 9, 7, 0, 89, 9, 7, 0, 90, 9, 7, 0, 91, 9,118, 1, 8, 0, 7, 0, 3, 8, 7, 0,125, 0, 7, 0, 55, 5,
+ 7, 0,134, 2, 7, 0, 92, 9, 7, 0,206, 0, 7, 0, 93, 9, 4, 0, 17, 0,119, 1, 4, 0, 2, 0, 94, 9, 2, 0, 95, 9,
+ 2, 0, 96, 9, 2, 0, 37, 0,120, 1, 1, 0, 0, 0, 20, 0,121, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 19, 0,
+ 2, 0, 97, 9,122, 1, 10, 0, 2, 0,182, 3, 2, 0, 19, 0, 7, 0, 74, 4, 7, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9,
+ 7, 0,101, 9,121, 1,102, 9,121, 1,103, 9,121, 1,104, 9, 64, 0, 9, 0, 4, 0, 19, 0, 4, 0, 64, 0, 24, 0,105, 9,
+ 24, 0,106, 9,122, 1,107, 9, 7, 0,108, 9, 7, 0,109, 9, 7, 0,110, 9, 7, 0,111, 9,123, 1, 4, 0, 47, 0,206, 2,
+ 7, 0,112, 9, 7, 0,141, 1, 7, 0, 37, 0,187, 0, 17, 0, 27, 0, 31, 0,123, 1,113, 9, 64, 0,102, 9, 51, 0,103, 1,
+ 2, 0, 19, 0, 2, 0,160, 5, 4, 0,106, 0, 7, 0,114, 9, 7, 0, 60, 2, 4, 0,115, 9, 7, 0,116, 9, 7, 0,117, 9,
+ 7, 0,118, 9, 7, 0,141, 1, 2, 0, 73, 1, 0, 0,119, 9, 0, 0,139, 6,124, 1, 10, 0, 4, 0, 17, 0, 4, 0,125, 0,
+ 4, 0, 19, 0, 4, 0,148, 3, 4, 0,120, 9, 4, 0,121, 9, 4, 0,122, 9, 0, 0, 92, 0, 0, 0, 20, 0, 9, 0, 2, 0,
+ 92, 0, 6, 0,124, 1,123, 9, 4, 0,124, 9, 4, 0,125, 9, 4, 0,126, 9, 4, 0, 37, 0, 9, 0,127, 9,125, 1, 5, 0,
+ 7, 0,129, 2, 7, 0,196, 2, 7, 0, 14, 2, 2, 0,128, 9, 2, 0, 37, 0,126, 1, 5, 0, 7, 0,129, 2, 7, 0,129, 9,
+ 7, 0,130, 9, 7, 0,131, 9, 7, 0,196, 2,127, 1, 5, 0, 32, 0,132, 9,128, 1, 22, 0, 7, 0,133, 9, 7, 0,134, 9,
+ 7, 0, 57, 0,129, 1, 7, 0, 4, 0,135, 9, 4, 0,136, 9, 4, 0,137, 9, 7, 0,138, 9, 7, 0,139, 9, 7, 0,140, 9,
+ 7, 0,141, 9,130, 1, 8, 0,130, 1, 0, 0,130, 1, 1, 0, 32, 0, 45, 0, 4, 0, 14, 3, 2, 0, 19, 0, 2, 0, 40, 1,
+ 7, 0,196, 2, 7, 0, 11, 8,131, 1, 18, 0,126, 1,143, 3,126, 1,142, 9,125, 1,143, 9,126, 1,251, 7,127, 1,144, 9,
+ 4, 0, 82, 0, 7, 0,196, 2, 7, 0,223, 2, 7, 0,145, 9, 4, 0,135, 9, 4, 0,146, 9, 7, 0,139, 9, 7, 0,140, 9,
+ 7, 0,106, 0, 2, 0, 19, 0, 2, 0,147, 9, 2, 0,148, 9, 2, 0,149, 9,132, 1,107, 0, 27, 0, 31, 0, 39, 0, 75, 0,
+133, 1,150, 9, 4, 0, 19, 0, 2, 0, 17, 0, 2, 0,228, 8, 2, 0,151, 9, 2, 0,152, 9, 2, 0,159, 8, 2, 0,153, 9,
+ 2, 0,154, 9, 2, 0,155, 9, 2, 0,156, 9, 2, 0,157, 9, 2, 0,158, 9, 2, 0,159, 9, 2, 0,178, 3, 2, 0, 48, 5,
+ 2, 0,160, 9, 2, 0,161, 9, 2, 0,162, 9, 2, 0,163, 9, 2, 0,164, 9, 2, 0, 3, 2, 2, 0,244, 7, 2, 0,220, 7,
+ 2, 0,165, 9, 2, 0,166, 9, 2, 0,176, 3, 2, 0,177, 3, 2, 0,167, 9, 2, 0,168, 9, 2, 0,169, 9, 2, 0,170, 9,
+ 7, 0,171, 9, 7, 0,172, 9, 7, 0,173, 9, 2, 0,174, 9, 2, 0,175, 9, 7, 0,176, 9, 7, 0,177, 9, 7, 0,178, 9,
+ 7, 0,226, 7, 7, 0, 89, 0, 7, 0,223, 2, 7, 0,232, 7, 7, 0,179, 9, 7, 0,180, 9, 7, 0,181, 9, 4, 0,227, 7,
+ 4, 0,225, 7, 4, 0,182, 9, 7, 0,228, 7, 7, 0,229, 7, 7, 0,230, 7, 7, 0,183, 9, 7, 0,184, 9, 7, 0,185, 9,
+ 7, 0,186, 9, 7, 0,187, 9, 7, 0,188, 9, 7, 0,189, 9, 7, 0,190, 9, 7, 0,100, 3, 7, 0,106, 0, 7, 0,191, 9,
+ 7, 0,192, 9, 7, 0,193, 9, 7, 0,194, 9, 7, 0,195, 9, 7, 0,196, 9, 7, 0,197, 9, 4, 0,198, 9, 4, 0,199, 9,
+ 7, 0,200, 9, 7, 0,201, 9, 7, 0,202, 9, 7, 0,203, 9, 7, 0,204, 9, 7, 0,205, 9, 7, 0,206, 9, 7, 0,172, 3,
+ 7, 0,170, 3, 7, 0,171, 3, 7, 0,207, 9, 7, 0,208, 9, 7, 0,209, 9, 7, 0,210, 9, 7, 0,211, 9, 7, 0,212, 9,
+ 7, 0,213, 9, 7, 0,214, 9, 7, 0,215, 9, 7, 0,216, 9, 7, 0,217, 9, 7, 0,218, 9, 7, 0,219, 9, 4, 0,220, 9,
+ 4, 0,221, 9, 7, 0,222, 9, 68, 0,132, 3, 68, 0,223, 9, 32, 0,224, 9, 32, 0,225, 9, 36, 0, 80, 0,163, 0, 32, 1,
+163, 0,226, 9, 59, 0, 43, 0, 59, 0, 0, 0, 59, 0, 1, 0,132, 1,227, 9,131, 1,228, 9,129, 1,153, 8,168, 0,198, 3,
+ 9, 0,199, 3,134, 1,229, 9,134, 1,230, 9, 12, 0,231, 9, 12, 0,232, 9,134, 0,233, 9,142, 0,234, 9,142, 0,235, 9,
+ 32, 0,236, 9, 32, 0,237, 9, 32, 0, 38, 0, 12, 0,238, 9, 12, 0,239, 9, 12, 0,198, 8, 0, 0, 20, 0, 7, 0,210, 0,
+ 7, 0,250, 2, 7, 0,240, 9, 4, 0,170, 2, 4, 0, 57, 0, 4, 0, 19, 0, 4, 0,227, 7, 4, 0,241, 9, 4, 0,242, 9,
+ 4, 0,243, 9, 2, 0,217, 0, 2, 0,244, 9, 2, 0,245, 9, 2, 0,246, 9, 0, 0,247, 9, 2, 0,248, 9, 2, 0,249, 9,
+ 2, 0,250, 9, 9, 0,251, 9,138, 0, 15, 4, 12, 0,237, 2,135, 1,252, 9,136, 0, 34, 0,136, 1,110, 8, 7, 0,241, 3,
+ 7, 0,253, 9, 7, 0,254, 9, 7, 0, 77, 4, 7, 0,255, 9, 7, 0,110, 3, 7, 0,100, 3, 7, 0, 0, 10, 7, 0, 62, 2,
+ 7, 0, 1, 10, 7, 0, 2, 10, 7, 0, 3, 10, 7, 0, 4, 10, 7, 0, 5, 10, 7, 0, 6, 10, 7, 0,242, 3, 7, 0, 7, 10,
+ 7, 0, 8, 10, 7, 0, 9, 10, 7, 0,243, 3, 7, 0,239, 3, 7, 0,240, 3, 7, 0, 10, 10, 4, 0, 11, 10, 4, 0, 90, 0,
+ 4, 0, 12, 10, 4, 0, 13, 10, 2, 0, 14, 10, 2, 0, 15, 10, 2, 0, 16, 10, 2, 0, 17, 10, 2, 0, 18, 10, 2, 0, 37, 0,
+137, 0, 8, 0,136, 1, 19, 10, 7, 0, 20, 10, 7, 0, 21, 10, 7, 0,213, 1, 7, 0, 22, 10, 4, 0, 90, 0, 2, 0, 23, 10,
+ 2, 0, 24, 10,137, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 25, 10,138, 1, 6, 0,138, 1, 0, 0,
+138, 1, 1, 0,137, 1,144, 8, 4, 0,223, 0, 2, 0, 26, 10, 2, 0, 19, 0,139, 1, 5, 0,139, 1, 0, 0,139, 1, 1, 0,
+ 12, 0, 27, 10, 4, 0, 28, 10, 4, 0, 19, 0,140, 1, 9, 0,140, 1, 0, 0,140, 1, 1, 0, 12, 0,124, 0,139, 1, 29, 10,
+ 4, 0, 19, 0, 2, 0, 26, 10, 2, 0, 30, 10, 7, 0, 91, 0, 0, 0, 31, 10,161, 0, 6, 0, 27, 0, 31, 0, 12, 0,201, 4,
+ 4, 0, 19, 0, 2, 0, 32, 10, 2, 0, 33, 10, 9, 0, 34, 10,141, 1, 7, 0,141, 1, 0, 0,141, 1, 1, 0, 2, 0, 17, 0,
+ 2, 0, 19, 0, 4, 0, 23, 0, 0, 0, 35, 10, 0, 0, 36, 10,142, 1, 5, 0, 12, 0, 37, 10, 4, 0, 38, 10, 4, 0, 39, 10,
+ 4, 0, 19, 0, 4, 0, 37, 0,143, 1, 13, 0, 27, 0, 31, 0,144, 1, 40, 10,144, 1, 41, 10, 12, 0, 42, 10, 4, 0, 43, 10,
+ 2, 0, 44, 10, 2, 0, 37, 0, 12, 0, 45, 10, 12, 0, 46, 10,142, 1, 47, 10, 12, 0, 48, 10, 12, 0, 49, 10, 12, 0, 50, 10,
+144, 1, 30, 0,144, 1, 0, 0,144, 1, 1, 0, 9, 0, 51, 10, 4, 0, 77, 7, 4, 0, 37, 0,211, 0,248, 5,211, 0, 52, 10,
+ 0, 0, 53, 10, 2, 0, 54, 10, 2, 0, 55, 10, 2, 0, 98, 7, 2, 0, 99, 7, 2, 0, 56, 10, 2, 0, 57, 10, 2, 0,148, 3,
+ 2, 0,107, 6, 2, 0, 58, 10, 2, 0, 59, 10, 4, 0,209, 1,145, 1, 60, 10,146, 1, 61, 10,147, 1, 62, 10, 4, 0, 63, 10,
+ 4, 0, 64, 10, 9, 0, 65, 10, 12, 0, 66, 10, 12, 0, 46, 10, 12, 0,116, 7, 12, 0, 67, 10, 12, 0, 68, 10,148, 1, 16, 0,
+148, 1, 0, 0,148, 1, 1, 0, 0, 0, 69, 10,149, 1, 70, 10, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 71, 10, 2, 0, 72, 10,
+ 2, 0, 73, 10, 2, 0, 74, 10, 2, 0, 75, 10, 2, 0, 76, 10, 2, 0, 77, 10, 2, 0, 78, 10, 2, 0, 70, 0, 2, 0,209, 1,
+150, 1, 9, 0,150, 1, 0, 0,150, 1, 1, 0, 12, 0, 79, 10, 0, 0, 80, 10, 2, 0, 81, 10, 2, 0, 82, 10, 2, 0, 83, 10,
+ 2, 0, 37, 0, 9, 0, 84, 10,219, 0, 12, 0,219, 0, 0, 0,219, 0, 1, 0, 0, 0, 69, 10, 26, 0, 30, 0,151, 1, 92, 7,
+ 9, 0, 85, 10,149, 1, 70, 10,142, 1, 86, 10, 12, 0, 87, 10,219, 0, 88, 10, 2, 0, 19, 0, 2, 0,105, 1,145, 1, 23, 0,
+145, 1, 0, 0,145, 1, 1, 0, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 5, 0, 2, 0, 6, 0, 2, 0, 89, 10, 2, 0, 90, 10,
+ 2, 0, 91, 10, 2, 0, 92, 10, 0, 0, 93, 10, 0, 0, 37, 0, 2, 0, 71, 10, 2, 0, 72, 10, 2, 0, 73, 10, 2, 0, 74, 10,
+ 2, 0, 75, 10, 2, 0, 43, 0, 0, 0, 94, 10, 2, 0, 95, 10, 2, 0, 96, 10, 4, 0, 70, 0, 9, 0, 85, 10,152, 1, 8, 0,
+152, 1, 0, 0,152, 1, 1, 0, 9, 0, 2, 0, 9, 0, 97, 10, 0, 0,193, 3, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0, 98, 10,
+153, 1, 5, 0, 7, 0, 99, 10, 4, 0,100, 10, 4, 0,101, 10, 4, 0, 40, 1, 4, 0, 19, 0,154, 1, 6, 0, 7, 0,102, 10,
+ 7, 0,103, 10, 7, 0,104, 10, 7, 0,105, 10, 4, 0, 17, 0, 4, 0, 19, 0,155, 1, 5, 0, 7, 0, 67, 8, 7, 0, 68, 8,
+ 7, 0,196, 2, 2, 0, 17, 2, 2, 0, 18, 2,156, 1, 5, 0,155, 1, 2, 0, 4, 0, 54, 0, 7, 0,106, 10, 7, 0, 67, 8,
+ 7, 0, 68, 8,157, 1, 4, 0, 2, 0,107, 10, 2, 0,108, 10, 2, 0,109, 10, 2, 0,110, 10,158, 1, 2, 0, 42, 0, 78, 6,
+ 26, 0,147, 8,159, 1, 3, 0, 24, 0,111, 10, 4, 0, 19, 0, 4, 0, 37, 0,160, 1, 6, 0, 7, 0,106, 0, 7, 0,198, 2,
+ 7, 0,112, 10, 7, 0, 37, 0, 2, 0,216, 0, 2, 0,113, 10,161, 1, 7, 0,161, 1, 0, 0,161, 1, 1, 0, 27, 0, 81, 6,
+ 0, 0,114, 10, 4, 0,115, 10, 4, 0, 90, 0, 0, 0,193, 3,162, 1, 6, 0, 12, 0,198, 8, 0, 0,116, 10, 7, 0, 61, 0,
+ 7, 0, 98, 10, 4, 0, 17, 0, 4, 0, 19, 0,163, 1, 3, 0, 7, 0,117, 10, 4, 0, 19, 0, 4, 0, 37, 0,164, 1, 15, 0,
+164, 1, 0, 0,164, 1, 1, 0, 70, 1,186, 8,162, 1, 62, 0, 12, 0, 73, 3, 35, 0, 50, 0,163, 1,118, 10, 4, 0, 54, 0,
+ 7, 0, 61, 0, 2, 0, 19, 0, 2, 0, 25, 1, 4, 0,115, 10, 0, 0,114, 10, 4, 0,119, 10, 7, 0,120, 10,165, 1, 2, 0,
+ 0, 0,121, 10, 0, 0,122, 10,166, 1, 4, 0,166, 1, 0, 0,166, 1, 1, 0,159, 0, 27, 3, 12, 0,123, 10,167, 1, 24, 0,
+167, 1, 0, 0,167, 1, 1, 0, 12, 0,124, 10,159, 0, 41, 8,166, 1,125, 10, 12, 0,126, 10, 12, 0, 73, 3, 0, 0,193, 3,
+ 7, 0, 98, 10, 7, 0,127, 10, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,243, 8, 7, 0,244, 8, 7, 0,213, 2, 7, 0,247, 8,
+ 7, 0, 43, 8, 7, 0,248, 8, 2, 0,128, 10, 2, 0,129, 10, 2, 0, 43, 0, 2, 0, 17, 0, 4, 0, 19, 0, 4, 0, 70, 0,
+168, 1, 6, 0,168, 1, 0, 0,168, 1, 1, 0, 12, 0,124, 10, 4, 0, 19, 0, 4, 0,133, 2, 0, 0,193, 3,169, 1, 10, 0,
+169, 1, 0, 0,169, 1, 1, 0, 27, 0, 81, 6, 0, 0,130, 10, 4, 0,131, 10, 4, 0,132, 10, 0, 0,114, 10, 4, 0,115, 10,
+ 2, 0, 19, 0, 2, 0,133, 10,170, 1, 6, 0,170, 1, 0, 0,170, 1, 1, 0, 12, 0,134, 10, 0, 0,193, 3, 4, 0, 19, 0,
+ 4, 0,135, 10,171, 1, 5, 0,171, 1, 0, 0,171, 1, 1, 0, 0, 0,114, 10, 4, 0,115, 10, 7, 0,186, 2, 39, 0, 12, 0,
+159, 0, 67, 3,159, 0,136, 10,166, 1,125, 10, 12, 0,137, 10,167, 1,138, 10, 12, 0,139, 10, 12, 0,140, 10, 4, 0, 19, 0,
+ 4, 0,217, 0, 2, 0,141, 10, 2, 0,142, 10, 7, 0,143, 10,172, 1, 2, 0, 27, 0, 31, 0, 39, 0, 75, 0,173, 1, 5, 0,
+173, 1, 0, 0,173, 1, 1, 0, 4, 0, 17, 0, 4, 0, 19, 0, 0, 0, 20, 0,174, 1, 6, 0,173, 1,144, 10, 32, 0, 45, 0,
+ 4, 0,145, 10, 7, 0,146, 10, 4, 0,147, 10, 4, 0,175, 8,175, 1, 3, 0,173, 1,144, 10, 4, 0,145, 10, 7, 0,148, 10,
+176, 1, 8, 0,173, 1,144, 10, 32, 0, 45, 0, 7, 0, 35, 1, 7, 0,149, 10, 7, 0,250, 2, 7, 0,109, 8, 4, 0,145, 10,
+ 4, 0,150, 10,177, 1, 5, 0,173, 1,144, 10, 7, 0,151, 10, 7, 0,185, 7, 7, 0,219, 2, 7, 0, 57, 0,178, 1, 3, 0,
+173, 1,144, 10, 7, 0,109, 8, 7, 0,152, 10,128, 1, 4, 0, 7, 0,153, 10, 7, 0,193, 9, 2, 0,154, 10, 2, 0, 40, 1,
+179, 1, 14, 0,179, 1, 0, 0,179, 1, 1, 0, 12, 0,155, 10, 12, 0,156, 10, 12, 0,157, 10, 0, 0, 20, 0, 4, 0, 31, 0,
+ 4, 0, 19, 0, 4, 0,158, 10, 7, 0,159, 10, 4, 0,147, 10, 4, 0,175, 8, 7, 0,202, 3, 7, 0,221, 2,133, 1, 23, 0,
+ 4, 0,145, 10, 4, 0,160, 10, 7, 0,161, 10, 7, 0, 57, 0, 7, 0,162, 10, 7, 0,217, 2, 7, 0,153, 10, 7, 0,163, 10,
+ 7, 0,198, 2, 7, 0,164, 10, 7, 0, 74, 4, 7, 0,165, 10, 7, 0,166, 10, 7, 0,167, 10, 7, 0,168, 10, 7, 0,169, 10,
+ 7, 0,170, 10, 7, 0,171, 10, 7, 0,172, 10, 7, 0,173, 10, 7, 0,174, 10, 7, 0,175, 10, 12, 0,176, 10,122, 0, 33, 0,
+121, 0,177, 10,180, 1,178, 10, 68, 0,179, 10, 68, 0,223, 9, 68, 0,180, 10,181, 1,181, 10, 48, 0,165, 0, 48, 0,182, 10,
+ 48, 0,183, 10, 7, 0,184, 10, 7, 0,185, 10, 7, 0,186, 10, 7, 0,187, 10, 7, 0,188, 10, 7, 0,187, 8, 7, 0,189, 10,
+ 7, 0,141, 1, 7, 0,190, 10, 4, 0,191, 10, 4, 0,192, 10, 4, 0,193, 10, 4, 0, 90, 0, 4, 0, 37, 0, 4, 0,194, 10,
+ 2, 0,195, 10, 2, 0,196, 10, 4, 0,197, 10, 7, 0,198, 2, 4, 0,198, 10, 7, 0,199, 10, 4, 0,200, 10,138, 0,201, 10,
+ 12, 0,202, 10,123, 0, 11, 0,121, 0,177, 10, 59, 0,225, 0, 7, 0,106, 1, 7, 0,187, 8, 7, 0,203, 10, 7, 0,204, 10,
+ 2, 0,205, 10, 2, 0,206, 10, 2, 0,207, 10, 2, 0, 17, 0, 4, 0, 37, 0,124, 0, 13, 0,121, 0,177, 10,140, 0,247, 2,
+142, 0,249, 2, 7, 0,144, 8, 7, 0,208, 10, 7, 0,209, 10, 7, 0, 37, 1, 7, 0,210, 10, 4, 0,211, 10, 4, 0,245, 2,
+ 2, 0, 17, 0, 2, 0, 37, 0, 4, 0, 70, 0, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0};
diff --git a/source/blender/editors/datafiles/splash.jpg.c b/source/blender/editors/datafiles/splash.png.c
index c1ca8b575e6..bbce480ecba 100644
--- a/source/blender/editors/datafiles/splash.jpg.c
+++ b/source/blender/editors/datafiles/splash.png.c
@@ -1,7 +1,7 @@
-/* DataToC output of file <splash_jpg> */
+/* DataToC output of file <splash_png> */
-int datatoc_splash_jpg_size= 79258;
-char datatoc_splash_jpg[]= {
+int datatoc_splash_png_size= 79258;
+char datatoc_splash_png[]= {
255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 1, 0, 72, 0, 72, 0, 0,255,225, 0, 22, 69,120,
105,102, 0, 0, 77, 77, 0, 42, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,255,219, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2,
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index d33ad16dfb1..d311b39b9a3 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -47,7 +47,7 @@
void ED_keymap_gpencil(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Grease Pencil", 0, 0);
wmKeymapItem *kmi;
/* Draw */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 99b85d62026..92ae2400666 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1341,7 +1341,7 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event)
}
/* add a modal handler for this operator, so that we can then draw continuous strokes */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 799829a6e87..d9439956569 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -42,11 +42,14 @@ struct View2D;
struct Scene;
struct Object;
+struct bDopeSheet;
+
struct bActionGroup;
struct FCurve;
struct FModifier;
struct uiBlock;
+struct uiLayout;
/* ************************************************ */
/* ANIMATION CHANNEL FILTERING */
@@ -137,6 +140,7 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_DSWOR,
ANIMTYPE_DSPART,
ANIMTYPE_DSMBALL,
+ ANIMTYPE_DSARM,
ANIMTYPE_SHAPEKEY, // XXX probably can become depreceated???
@@ -206,6 +210,7 @@ typedef enum eAnimFilter_Flags {
#define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND))
#define FILTER_PART_OBJD(part) ((part->flag & PART_DS_EXPAND))
#define FILTER_MBALL_OBJD(mb) ((mb->flag2 & MB_DS_EXPAND))
+#define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND))
/* 'Sub-object/Action' channels (flags stored in Action) */
#define SEL_ACTC(actc) ((actc->flag & ACT_SELECTED))
#define EXPANDED_ACTC(actc) ((actc->flag & ACT_COLLAPSED)==0)
@@ -392,11 +397,14 @@ void ANIM_draw_cfra(const struct bContext *C, struct View2D *v2d, short flag);
/* main call to draw preview range curtains */
void ANIM_draw_previewrange(const struct bContext *C, struct View2D *v2d);
+/* ------------- Preview Range Drawing -------------- */
+
+/* standard header buttons for Animation Editors */
+short ANIM_headerUI_standard_buttons(const struct bContext *C, struct bDopeSheet *ads, struct uiBlock *block, short xco, short yco);
+
/* ************************************************* */
/* F-MODIFIER TOOLS */
-struct uiLayout;
-
/* draw a given F-Modifier for some layout/UI-Block */
void ANIM_uiTemplate_fmodifier_draw(struct uiLayout *layout, struct ID *id, ListBase *modifiers, struct FModifier *fcm);
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index 5d24b93418b..993cbceae18 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -40,8 +40,8 @@ extern char datatoc_blenderbuttons[];
extern int datatoc_prvicons_size;
extern char datatoc_prvicons[];
-extern int datatoc_splash_jpg_size;
-extern char datatoc_splash_jpg[];
+extern int datatoc_splash_png_size;
+extern char datatoc_splash_png[];
extern int datatoc_Bfont_size;
extern char datatoc_Bfont[];
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 57ab6a5f8f6..221b377dd25 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -51,21 +51,21 @@ typedef enum FileListColumns {
typedef struct FileLayout
{
/* view settings - XXX - move into own struct */
- short prv_w;
- short prv_h;
- short tile_w;
- short tile_h;
- short tile_border_x;
- short tile_border_y;
- short prv_border_x;
- short prv_border_y;
- short rows;
- short columns;
- short width;
- short height;
- short flag;
- short dirty;
- short textheight;
+ int prv_w;
+ int prv_h;
+ int tile_w;
+ int tile_h;
+ int tile_border_x;
+ int tile_border_y;
+ int prv_border_x;
+ int prv_border_y;
+ int rows;
+ int columns;
+ int width;
+ int height;
+ int flag;
+ int dirty;
+ int textheight;
float column_widths[MAX_FILE_COLUMN];
} FileLayout;
@@ -84,7 +84,7 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar
int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar);
int ED_fileselect_layout_offset(FileLayout* layout, int x, int y);
-void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y);
+void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, int *x, int *y);
#endif /* ED_FILES_H */
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 566105109b2..41a83a34ee4 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -38,7 +38,10 @@ struct uiBlock;
struct Image *ED_space_image(struct SpaceImage *sima);
void ED_space_image_set(struct bContext *C, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima);
-struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima);
+struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r);
+void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock);
+int ED_space_image_has_buffer(struct SpaceImage *sima);
+
void ED_space_image_size(struct SpaceImage *sima, int *width, int *height);
void ED_space_image_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
void ED_space_image_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy);
@@ -53,9 +56,6 @@ int ED_space_image_show_paint(struct SpaceImage *sima);
int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit);
int ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit);
-void ED_image_uiblock_panel(const struct bContext *C, struct uiBlock *block, struct Image **ima_pp,
- struct ImageUser *iuser, short redraw, short imagechanged);
-
/* image_render.c, export for screen_ops.c, render operator */
void ED_space_image_output(struct bContext *C);
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 0969398f1e2..51d7c664fba 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -119,5 +119,9 @@ void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree
void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
+/* Keyframe Finding */
+ActKeyColumn *cfra_find_actkeycolumn(ActKeyColumn *ak, float cframe);
+ActKeyColumn *cfra_find_nearest_next_ak(ActKeyColumn *ak, float cframe, short next);
+
#endif /* ED_KEYFRAMES_DRAW_H */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index b2bf05ea5ea..57a6c5fc773 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -73,6 +73,7 @@ typedef enum eEditKeyframes_Snap {
SNAP_KEYS_NEARSEC,
SNAP_KEYS_NEARMARKER,
SNAP_KEYS_HORIZONTAL,
+ SNAP_KEYS_VALUE,
} eEditKeyframes_Snap;
/* mirroring tools */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 20c2301d2ac..d30fccfe4de 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -163,6 +163,9 @@ void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot);
/* ************ Drivers ********************** */
+/* Returns whether there is a driver in the copy/paste buffer to paste */
+short ANIM_driver_can_paste(void);
+
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block
*/
@@ -171,11 +174,24 @@ short ANIM_add_driver (struct ID *id, const char rna_path[], int array_index, sh
/* Main Driver Management API calls:
* Remove the driver for the specified property on the given ID block (if available)
*/
-short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index, short flag);
+short ANIM_remove_driver(struct ID *id, const char rna_path[], int array_index, short flag);
+
+/* Main Driver Management API calls:
+ * Make a copy of the driver for the specified property on the given ID block
+ */
+short ANIM_copy_driver(struct ID *id, const char rna_path[], int array_index, short flag);
+
+/* Main Driver Management API calls:
+ * Add a new driver for the specified property on the given ID block or replace an existing one
+ * with the driver + driver-curve data from the buffer
+ */
+short ANIM_paste_driver(struct ID *id, const char rna_path[], int array_index, short flag);
/* Driver management operators for UI buttons */
void ANIM_OT_add_driver_button(struct wmOperatorType *ot);
void ANIM_OT_remove_driver_button(struct wmOperatorType *ot);
+void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
+void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
/* ************ Auto-Keyframing ********************** */
/* Notes:
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index a2dba89ec20..fd88f9889ae 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -38,6 +38,7 @@ struct EditFace;
struct bContext;
struct wmOperator;
struct wmWindowManager;
+struct ReportList;
struct EditSelection;
struct ViewContext;
struct bDeformGroup;
@@ -49,6 +50,8 @@ struct MCol;
struct UvVertMap;
struct UvMapVert;
struct CustomData;
+struct Material;
+struct Object;
#define EM_FGON_DRAW 1 // face flag
#define EM_FGON 2 // edge and face flag both
@@ -89,9 +92,9 @@ void ED_keymap_mesh(struct wmWindowManager *wm);
void ED_spacetypes_init(void);
void ED_keymap_mesh(struct wmWindowManager *wm);
-void make_editMesh(struct Scene *scene, Object *ob);
-void load_editMesh(struct Scene *scene, Object *ob);
-void remake_editMesh(struct Scene *scene, Object *ob);
+void make_editMesh(struct Scene *scene, struct Object *ob);
+void load_editMesh(struct Scene *scene, struct Object *ob);
+void remake_editMesh(struct Scene *scene, struct Object *ob);
void free_editMesh(struct EditMesh *em);
void recalc_editnormals(struct EditMesh *em);
@@ -118,6 +121,7 @@ void EM_select_face(struct EditFace *efa, int sel);
void EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val);
void EM_select_swap(struct EditMesh *em);
void EM_toggle_select_all(struct EditMesh *em);
+void EM_select_all(struct EditMesh *em);
void EM_selectmode_flush(struct EditMesh *em);
void EM_deselect_flush(struct EditMesh *em);
void EM_selectmode_set(struct EditMesh *em);
@@ -175,5 +179,26 @@ float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int ver
struct MDeformWeight *ED_vgroup_weight_verify(struct MDeformVert *dv, int defgroup);
struct MDeformWeight *ED_vgroup_weight_get(struct MDeformVert *dv, int defgroup);
+/*needed by edge slide*/
+struct EditVert *editedge_getOtherVert(struct EditEdge *eed, struct EditVert *eve);
+struct EditVert *editedge_getSharedVert(struct EditEdge *eed, struct EditEdge *eed2);
+int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve);
+int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
+int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
+short sharesFace(struct EditMesh *em, struct EditEdge *e1, struct EditEdge *e2);
+
+/* mesh_data.c */
+
+void ED_mesh_geometry_add(struct Mesh *mesh, struct ReportList *reports, int verts, int edges, int faces);
+void ED_mesh_transform(struct Mesh *me, float *mat);
+void ED_mesh_calc_normals(struct Mesh *me);
+void ED_mesh_material_add(struct Mesh *me, struct Material *ma);
+void ED_mesh_update(struct Mesh *mesh, struct bContext *C);
+
+int ED_mesh_uv_texture_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me);
+int ED_mesh_uv_texture_remove(struct bContext *C, struct Object *ob, struct Mesh *me);
+int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me);
+int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me);
+
#endif /* ED_MESH_H */
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index bf4632dc3da..305b2a64ffe 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -31,10 +31,15 @@
struct Material;
struct Scene;
struct Tex;
+struct bContext;
+struct bNode;
/* drawnode.c */
void ED_init_node_butfuncs(void);
+/* node_draw.c */
+void ED_node_changed_update(struct bContext *C, struct bNode *node);
+
/* node_edit.c */
void ED_node_shader_default(struct Material *ma);
void ED_node_composit_default(struct Scene *sce);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 67dc6dada5f..363795afeab 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -88,6 +88,8 @@ void object_test_constraints(struct Object *ob);
void ED_object_constraint_rename(struct Object *ob, struct bConstraint *con, char *oldname);
void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con);
+void ED_object_constraint_update(struct Object *ob);
+void ED_object_constraint_dependency_update(struct Scene *scene, struct Object *ob);
/* object_lattice.c */
void mouse_lattice(struct bContext *C, short mval[2], int extend);
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 28807caa255..a052142102d 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -38,6 +38,7 @@ struct RadialControl;
struct rcti;
struct wmWindowManager;
struct PTCacheEdit;
+struct Scene;
/* particle edit mode */
void PE_free_ptcache_edit(struct PTCacheEdit *edit);
@@ -46,7 +47,7 @@ int PE_start_edit(struct PTCacheEdit *edit);
/* access */
struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob);
int PE_minmax(struct Scene *scene, float *min, float *max);
-struct ParticleEditSettings *PE_settings(Scene *scene);
+struct ParticleEditSettings *PE_settings(struct Scene *scene);
/* update calls */
void PE_hide_keys_time(struct Scene *scene, struct PTCacheEdit *edit, float cfra);
@@ -59,15 +60,11 @@ int PE_circle_select(struct bContext *C, int selecting, short *mval, float rad);
int PE_lasso_select(struct bContext *C, short mcords[][2], short moves, short select);
/* undo */
-void PE_undo_push(Scene *scene, char *str);
-void PE_undo_step(Scene *scene, int step);
-void PE_undo(Scene *scene);
-void PE_redo(Scene *scene);
-void PE_undo_menu(Scene *scene, Object *ob);
-
-/* operators */
-void ED_operatortypes_particle(void);
-void ED_keymap_particle(struct wmWindowManager *wm);
+void PE_undo_push(struct Scene *scene, char *str);
+void PE_undo_step(struct Scene *scene, int step);
+void PE_undo(struct Scene *scene);
+void PE_redo(struct Scene *scene);
+void PE_undo_menu(struct Scene *scene, struct Object *ob);
#endif /* ED_PARTICLE_H */
diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h
index 6ab804230d0..ee340c54e7d 100644
--- a/source/blender/editors/include/ED_physics.h
+++ b/source/blender/editors/include/ED_physics.h
@@ -31,11 +31,8 @@
#define ED_PHYSICS_H
/* operators */
-
-void ED_operatortypes_boids(void);
-void ED_operatortypes_pointcache(void);
-void ED_operatortypes_fluid(void);
-//void ED_keymap_pointcache(struct wmWindowManager *wm);
+void ED_operatortypes_physics(void);
+void ED_keymap_physics(struct wmWindowManager *wm);
#endif /* ED_PHYSICS_H */
diff --git a/source/blender/editors/include/ED_previewrender.h b/source/blender/editors/include/ED_render.h
index 7e0d71db7e1..be93bf92e5e 100644
--- a/source/blender/editors/include/ED_previewrender.h
+++ b/source/blender/editors/include/ED_render.h
@@ -21,22 +21,29 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef ED_PREVIEWRENDER_H
-#define ED_PREVIEWRENDER_H
+#ifndef ED_RENDER_H
+#define ED_RENDER_H
#include "DNA_vec_types.h"
-struct View3D;
-struct SpaceButs;
-struct RenderInfo;
-struct Scene;
-struct Image;
-struct Render;
struct bContext;
struct ID;
+struct Main;
struct MTex;
+struct Render;
+struct RenderInfo;
+
+/* render_ops.c */
+
+void ED_operatortypes_render(void);
+
+/* render_shading.c */
+
+void ED_render_id_flush_update(struct Main *bmain, struct ID *id);
+
+/* render_preview.c */
-#define PREVIEW_RENDERSIZE 140
+#define _RENDERSIZE 140
/* stores rendered preview - is also used for icons */
typedef struct RenderInfo {
@@ -72,7 +79,7 @@ void ED_preview_init_dbase(void);
void ED_preview_free_dbase(void);
void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey);
-void ED_preview_iconrender(struct Scene *scene, struct ID *id, unsigned int *rect, int sizex, int sizey);
+void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey);
void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 0153b3c9bdb..63b6a067389 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -58,6 +58,7 @@ void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, char *context, int contextnr);
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);
/* spaces */
@@ -104,7 +105,6 @@ void ED_screen_new_window(struct bContext *C, struct rcti *position, int type);
/* anim */
void ED_update_for_newframe(const struct bContext *C, int mute);
-unsigned int ED_screen_view3d_layers(struct bScreen *screen);
void ED_operatortypes_screen(void);
void ED_keymap_screen(struct wmWindowManager *wm);
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 72afe7704b4..dcdc9e417e4 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -59,7 +59,7 @@ typedef struct AZone {
/* internal */
short do_draw;
/* for draw */
- short x1, y1, x2, y2, x3, y3;
+ short x1, y1, x2, y2;
/* for clip */
rcti rect;
} AZone;
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index c6a8881a0c6..a08f0576f42 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -33,10 +33,10 @@ struct wmWindowManager;
/* sculpt.c */
void ED_operatortypes_sculpt(void);
-void ED_keymap_sculpt(struct wmWindowManager *wm);
/* paint_ops.c */
void ED_operatortypes_paint(void);
+void ED_keymap_paint(struct wmWindowManager *wm);
/* paint_image.c */
void undo_imagepaint_step(int step);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 984def760ae..7f08e95aceb 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -41,8 +41,9 @@ struct Object;
struct uiLayout;
struct EnumPropertyItem;
struct wmOperatorType;
+struct wmKeyMap;
-void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid);
+void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid);
void transform_operatortypes(void);
/* ******************** Macros & Prototypes *********************** */
@@ -74,7 +75,8 @@ enum {
TFM_BAKE_TIME,
TFM_BEVEL,
TFM_BWEIGHT,
- TFM_ALIGN
+ TFM_ALIGN,
+ TFM_EDGE_SLIDE
} TfmMode;
/* TRANSFORM CONTEXTS */
@@ -109,10 +111,12 @@ int BIF_snappingSupported(struct Object *obedit);
struct TransformOrientation;
struct bContext;
+struct ReportList;
void BIF_clearTransformOrientation(struct bContext *C);
void BIF_removeTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
-void BIF_manageTransformOrientation(struct bContext *C, int confirm, int set);
+void BIF_removeTransformOrientationIndex(struct bContext *C, int index);
+void BIF_createTransformOrientation(struct bContext *C, struct ReportList *reports, char *name, int use, int overwrite);
int BIF_menuselectTransformOrientation(void);
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index b45ab2d4997..e1762991676 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -146,6 +146,7 @@ typedef struct uiLayout uiLayout;
#define UI_BUT_DRIVEN (1<<22)
#define UI_BUT_INACTIVE (1<<23)
#define UI_BUT_LAST_ACTIVE (1<<24)
+#define UI_BUT_UNDO (1<<25)
#define UI_PANEL_WIDTH 340
#define UI_COMPACT_PANEL_WIDTH 160
@@ -417,11 +418,13 @@ typedef void (*uiIDPoinFunc)(struct bContext *C, struct ID *id, int event);
uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
short x1, short y1, short x2, short y2, void *idpp, char *tip);
-int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID *id, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events);
+
+int uiIconFromID(struct ID *id);
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip);
+uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *func_arg1, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, char *str, short x1, short y1, short x2, short y2, char *tip);
@@ -429,7 +432,7 @@ uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, char *
uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip);
-void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip);
+uiBut *uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip);
uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *keypoin, short *modkeypoin, char *tip);
uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip);
@@ -484,6 +487,7 @@ int uiSearchBoxhHeight(void);
void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg);
void uiBlockSetButmFunc (uiBlock *block, uiMenuHandleFunc func, void *arg);
void uiBlockSetFunc (uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2);
+void uiBlockSetNFunc (uiBlock *block, uiButHandleFunc func, void *argN, void *arg2);
void uiButSetRenameFunc (uiBut *but, uiButHandleRenameFunc func, void *arg1);
void uiButSetFunc (uiBut *but, uiButHandleFunc func, void *arg1, void *arg2);
@@ -527,29 +531,6 @@ void UI_add_region_handlers(struct ListBase *handlers);
void UI_add_area_handlers(struct ListBase *handlers);
void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *menu);
-/* Legacy code
- * Callbacks and utils to get 2.48 work */
-
-void test_idbutton_cb(struct bContext *C, void *namev, void *arg2);
-void test_scriptpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_actionpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_obpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_meshobpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_meshpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_matpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_scenepoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_grouppoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_texpoin_but(struct bContext *C, char *name, struct ID **idpp);
-void test_imapoin_but(struct bContext *C, char *name, struct ID **idpp);
-void autocomplete_bone(struct bContext *C, char *str, void *arg_v);
-void autocomplete_vgroup(struct bContext *C, char *str, void *arg_v);
-
-struct rctf;
-void curvemap_buttons(uiBlock *block, struct CurveMapping *cumap, char labeltype, short event, short redraw, struct rctf *rect);
-void curvemap_layout(uiLayout *layout, struct CurveMapping *cumap, char labeltype, short event, short redraw, struct rctf *rect);
-void colorband_buttons(uiBlock *block, struct ColorBand *coba, struct rctf *rect, int small);
-
-
/* Module
*
* init and exit should be called before using this module. init_userdef must
@@ -593,7 +574,7 @@ void UI_exit(void);
uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style);
void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout);
-void uiBlockLayoutResolve(const struct bContext *C, uiBlock *block, int *x, int *y);
+void uiBlockLayoutResolve(uiBlock *block, int *x, int *y);
uiBlock *uiLayoutGetBlock(uiLayout *layout);
@@ -638,10 +619,11 @@ void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr,
uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot);
-void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
-void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type, int compact);
+void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
+void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels);
void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname);
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);
+void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *userptr, int compact);
void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C);
void uiTemplateOperatorSearch(uiLayout *layout);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index bf160b4ad68..afe6a2b9dcb 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -57,9 +57,9 @@ int UI_icon_get_height(int icon_id);
void UI_icon_draw(float x, float y, int icon_id);
void UI_icon_draw_preview(float x, float y, int icon_id, int nocreate);
-void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect);
-void UI_icon_draw_aspect_blended(float x, float y, int icon_id, float aspect, int shade);
-void UI_icon_draw_size_blended(float x, float y, int size, int icon_id, int shade);
+void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect, float alpha);
+void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, float *rgb);
+void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha);
void UI_icons_free();
void UI_icons_free_drawinfo(void *drawinfo);
diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript
index e44de5410f1..bca0350d4fc 100644
--- a/source/blender/editors/interface/SConscript
+++ b/source/blender/editors/interface/SConscript
@@ -16,4 +16,7 @@ defs = []
if env['WITH_BF_INTERNATIONAL']:
defs.append('INTERNATIONAL')
-env.BlenderLib ( 'bf_editors_interface', sources, Split(incs), Split(defs), libtype=['core'], priority=[110] )
+if not env['WITH_BF_PYTHON']:
+ defs.append('DISABLE_PYTHON')
+
+env.BlenderLib ( 'bf_editors_interface', sources, Split(incs), defs, libtype=['core'], priority=[110] )
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 3c6e12905d6..3e5cc0e6d67 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -597,7 +597,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
if(but->context)
CTX_store_set((bContext*)C, but->context);
- if(ot==NULL || (ot->poll && ot->poll((bContext *)C)==0)) {
+ if(ot == NULL || WM_operator_poll((bContext*)C, ot)==0) {
but->flag |= UI_BUT_DISABLED;
but->lock = 1;
}
@@ -622,7 +622,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
}
/* handle pending stuff */
- if(block->layouts.first) uiBlockLayoutResolve(C, block, NULL, NULL);
+ if(block->layouts.first) uiBlockLayoutResolve(block, NULL, NULL);
ui_block_do_align(block);
if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block);
@@ -1684,6 +1684,9 @@ void uiFreeBlock(const bContext *C, uiBlock *block)
ui_free_but(C, but);
}
+ if(block->func_argN)
+ MEM_freeN(block->func_argN);
+
CTX_store_free_list(&block->contexts);
BLI_freelistN(&block->saferct);
@@ -2232,6 +2235,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
but->func= block->func;
but->func_arg1= block->func_arg1;
but->func_arg2= block->func_arg2;
+
+ but->funcN= block->funcN;
+ if(block->func_argN)
+ but->func_argN= MEM_dupallocN(block->func_argN);
but->pos= -1; /* cursor invisible */
@@ -2264,6 +2271,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
}
}
+ if(ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, SEARCH_MENU, BUTM));
+ else if(ELEM5(but->type, SCROLL, SEPR, LINK, INLINK, FTPREVIEW));
+ else but->flag |= UI_BUT_UNDO;
+
BLI_addtail(&block->buttons, but);
if(block->curlayout)
@@ -2942,6 +2953,16 @@ void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2
block->func_arg2= arg2;
}
+void uiBlockSetNFunc(uiBlock *block, uiButHandleFunc func, void *argN, void *arg2)
+{
+ if(block->func_argN)
+ MEM_freeN(block->func_argN);
+
+ block->funcN= func;
+ block->func_argN= argN;
+ block->func_arg2= arg2;
+}
+
void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1)
{
but->rename_func= func;
@@ -2964,6 +2985,9 @@ void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
{
+ if(but->func_argN)
+ MEM_freeN(but->func_argN);
+
but->funcN= funcN;
but->func_argN= argN;
but->func_arg2= arg2;
@@ -3000,6 +3024,8 @@ uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, char *
{
uiBut *but= ui_def_but(block, BLOCK, 0, str, x1, y1, x2, y2, NULL, 0.0, 0.0, 0.0, 0.0, tip);
but->block_create_func= func;
+ if(but->func_argN)
+ MEM_freeN(but->func_argN);
but->func_argN= argN;
ui_check_but(but);
return but;
@@ -3038,6 +3064,20 @@ uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, in
return but;
}
+uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, short x1, short y1, short x2, short y2, char *tip)
+{
+ uiBut *but= ui_def_but(block, PULLDOWN, 0, "", x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip);
+
+ but->icon= (BIFIconID) icon;
+ but->flag |= UI_HAS_ICON;
+ but->flag &=~ UI_ICON_LEFT;
+
+ but->menu_create_func= func;
+ ui_check_but(but);
+
+ return but;
+}
+
/* Block button containing both string label and icon */
uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip)
{
@@ -3073,10 +3113,11 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int
return but;
}
-void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip)
+uiBut *uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip)
{
uiBut *but= ui_def_but(block, KEYEVT|SHO, retval, str, x1, y1, x2, y2, spoin, 0.0, 0.0, 0.0, 0.0, tip);
ui_check_but(but);
+ return but;
}
/* short pointers hardcoded */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 8c41726b81b..8037a609a2f 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -209,6 +209,18 @@ void ui_but_anim_remove_driver(bContext *C)
WM_operator_name_call(C, "ANIM_OT_remove_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
}
+void ui_but_anim_copy_driver(bContext *C)
+{
+ /* this operator calls uiAnimContextProperty above */
+ WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+void ui_but_anim_paste_driver(bContext *C)
+{
+ /* this operator calls uiAnimContextProperty above */
+ WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
+}
+
void ui_but_anim_add_keyingset(bContext *C)
{
/* this operator calls uiAnimContextProperty above */
@@ -264,6 +276,10 @@ void ui_but_anim_menu(bContext *C, uiBut *but)
}
else
uiItemBooleanO(layout, "Delete Driver", 0, "ANIM_OT_remove_driver_button", "all", 0);
+
+ uiItemO(layout, "Copy Driver", 0, "ANIM_OT_copy_driver_button");
+ if (ANIM_driver_can_paste())
+ uiItemO(layout, "Paste Driver", 0, "ANIM_OT_paste_driver_button");
}
else if(but->flag & UI_BUT_ANIMATED_KEY);
else if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
@@ -275,6 +291,9 @@ void ui_but_anim_menu(bContext *C, uiBut *but)
}
else
uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0);
+
+ if (ANIM_driver_can_paste())
+ uiItemO(layout, "Paste Driver", 0, "ANIM_OT_paste_driver_button");
}
if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 259ccba6b89..c60c94a9c4d 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -246,7 +246,13 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
if(but->func || but->funcN || block->handle_func || but->rename_func || (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) {
after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
- after->func= but->func;
+ if(but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
+ /* exception, this will crash due to removed button otherwise */
+ but->func(C, but->func_arg1, but->func_arg2);
+ }
+ else
+ after->func= but->func;
+
after->func_arg1= but->func_arg1;
after->func_arg2= but->func_arg2;
after->func_arg3= but->func_arg3;
@@ -292,8 +298,7 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but)
uiAfterFunc *after;
char *str= NULL;
- if ELEM6(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX);
- else {
+ if(but->flag & UI_BUT_UNDO) {
/* define which string to use for undo */
if ELEM(but->type, LINK, INLINK) str= "Add button link";
else if ELEM(but->type, MENU, ICONTEXTROW) str= but->drawstr;
@@ -850,6 +855,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
ui_apply_but_CHARTAB(C, but, data);
break;
#endif
+ case KEYEVT:
case HOTKEYEVT:
ui_apply_but_BUT(C, but, data);
break;
@@ -1440,16 +1446,20 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
for(but= actbut->next; but; but= but->next) {
if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
- data->postbut= but;
- data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
- return;
+ if(!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
}
}
for(but= block->buttons.first; but!=actbut; but= but->next) {
if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
- data->postbut= but;
- data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
- return;
+ if(!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
}
}
}
@@ -1464,16 +1474,20 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
for(but= actbut->prev; but; but= but->prev) {
if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
- data->postbut= but;
- data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
- return;
+ if(!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
}
}
for(but= block->buttons.last; but!=actbut; but= but->prev) {
if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
- data->postbut= but;
- data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
- return;
+ if(!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut= but;
+ data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
}
}
}
@@ -1646,7 +1660,7 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
break;
}
case LEFTMOUSE:
- if(event->val == 0)
+ if(event->val == KM_RELEASE)
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval= WM_UI_HANDLER_BREAK;
break;
@@ -2109,7 +2123,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
wmTabletData *wmtab= event->customdata;
/* de-sensitise based on tablet pressure */
- if (ELEM(wmtab->Active, DEV_STYLUS, DEV_ERASER))
+ if (wmtab->Active != EVT_TABLET_NONE)
fac *= wmtab->Pressure;
}
@@ -3257,7 +3271,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
retval= WM_UI_HANDLER_CONTINUE;
if(but->flag & UI_BUT_DISABLED)
- return WM_UI_HANDLER_BREAK;
+ return WM_UI_HANDLER_CONTINUE;
if(data->state == BUTTON_STATE_HIGHLIGHT) {
/* handle copy-paste */
@@ -3647,11 +3661,11 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
if(!(but->block->handle && but->block->handle->popup)) {
if(button_modal_state(state)) {
if(!button_modal_state(data->state))
- WM_event_add_ui_handler(C, &data->window->handlers, ui_handler_region_menu, NULL, data);
+ WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data);
}
else {
if(button_modal_state(data->state))
- WM_event_remove_ui_handler(&data->window->handlers, ui_handler_region_menu, NULL, data);
+ WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data);
}
}
@@ -4587,7 +4601,7 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
uiPopupBlockHandle temp= *menu;
ui_popup_block_free(C, menu);
- WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
+ WM_event_remove_ui_handler(&CTX_wm_window(C)->modalhandlers, ui_handler_popup, ui_handler_remove_popup, menu);
if(temp.menuretval == UI_RETURN_OK) {
if(temp.popup_func)
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 6c4110c8c37..1153c475339 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -47,6 +47,7 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_icons.h"
#include "BKE_utildefines.h"
@@ -58,7 +59,7 @@
#include "BIF_glutil.h"
#include "ED_datafiles.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
@@ -85,23 +86,45 @@ typedef struct IconImage {
typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
+#define ICON_TYPE_PREVIEW 0
+#define ICON_TYPE_TEXTURE 1
+#define ICON_TYPE_BUFFER 2
+#define ICON_TYPE_VECTOR 3
+
typedef struct DrawInfo {
+ int type;
+
+ union {
+ /* type specific data */
+ struct {
+ VectorDrawFunc func;
+ } vector;
+ struct {
+ IconImage* image;
+ } buffer;
+ struct {
+ int x, y, w, h;
+ } texture;
+ } data;
+} DrawInfo;
+
+typedef struct IconTexture {
+ GLuint id;
int w;
int h;
- float aspect;
- VectorDrawFunc drawFunc; /* If drawFunc is defined then it is a vector icon, otherwise use rect */
- IconImage* icon;
-} DrawInfo;
+ float invw;
+ float invh;
+} IconTexture;
/* ******************* STATIC LOCAL VARS ******************* */
/* static here to cache results of icon directory scan, so it's not
* scanning the filesystem each time the menu is drawn */
static struct ListBase iconfilelist = {0, 0};
-
+static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
/* **************************************************** */
-static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size)
+static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type)
{
Icon *new_icon = NULL;
IconImage *iimg = NULL;
@@ -115,23 +138,28 @@ static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int
new_icon->type = 0;
di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
- di->drawFunc = 0;
- di->w = size;
- di->h = size;
- di->aspect = 1.0f;
-
- iimg = MEM_mallocN(sizeof(IconImage), "icon_img");
- iimg->rect = MEM_mallocN(size*size*sizeof(unsigned int), "icon_rect");
- iimg->w = size;
- iimg->h = size;
-
- /* Here we store the rect in the icon - same as before */
- imgsize = bbuf->x;
- for (y=0; y<size; y++) {
- memcpy(&iimg->rect[y*size], &bbuf->rect[(y+yofs)*imgsize+xofs], size*sizeof(int));
- }
+ di->type= type;
+
+ if(type == ICON_TYPE_TEXTURE) {
+ di->data.texture.x= xofs;
+ di->data.texture.y= yofs;
+ di->data.texture.w= size;
+ di->data.texture.h= size;
+ }
+ else if(type == ICON_TYPE_BUFFER) {
+ iimg = MEM_mallocN(sizeof(IconImage), "icon_img");
+ iimg->rect = MEM_mallocN(size*size*sizeof(unsigned int), "icon_rect");
+ iimg->w = size;
+ iimg->h = size;
+
+ /* Here we store the rect in the icon - same as before */
+ imgsize = bbuf->x;
+ for (y=0; y<size; y++) {
+ memcpy(&iimg->rect[y*size], &bbuf->rect[(y+yofs)*imgsize+xofs], size*sizeof(int));
+ }
- di->icon = iimg;
+ di->data.buffer.image = iimg;
+ }
new_icon->drawinfo_free = UI_icons_free_drawinfo;
new_icon->drawinfo = di;
@@ -150,11 +178,8 @@ static void def_internal_vicon( int icon_id, VectorDrawFunc drawFunc)
new_icon->type = 0;
di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
- di->drawFunc =drawFunc;
- di->w = ICON_DEFAULT_HEIGHT;
- di->h = ICON_DEFAULT_HEIGHT;
- di->aspect = 1.0f;
- di->icon = NULL;
+ di->type= ICON_TYPE_VECTOR;
+ di->data.vector.func =drawFunc;
new_icon->drawinfo_free = 0;
new_icon->drawinfo = di;
@@ -430,7 +455,7 @@ static void init_internal_icons()
{
bTheme *btheme= U.themes.first;
ImBuf *bbuf= NULL;
- int x, y;
+ int x, y, icontype;
char iconfilestr[FILE_MAXDIR+FILE_MAXFILE];
char filenamestr[FILE_MAXFILE+16]; // 16 == strlen(".blender/icons/")+1
@@ -450,17 +475,54 @@ static void init_internal_icons()
printf("\n***WARNING***\nIcons file %s too small.\nUsing built-in Icons instead\n", iconfilestr);
IMB_freeImBuf(bbuf);
bbuf= NULL;
+ }
}
}
- }
if(bbuf==NULL)
bbuf = IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect);
+ if(bbuf) {
+ /* free existing texture if any */
+ if(icongltex.id) {
+ glDeleteTextures(1, &icongltex.id);
+ icongltex.id= 0;
+ }
+
+ /* we only use a texture for cards with non-power of two */
+ if(GLEW_ARB_texture_non_power_of_two) {
+ 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;
+
+ 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);
+ 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;
+ }
+ }
+ }
+ }
+
+ if(icongltex.id)
+ icontype= ICON_TYPE_TEXTURE;
+ else
+ icontype= ICON_TYPE_BUFFER;
+
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,
x*(ICON_GRID_W+ICON_GRID_MARGIN)+ICON_GRID_MARGIN,
- y*(ICON_GRID_H+ICON_GRID_MARGIN)+ICON_GRID_MARGIN, ICON_GRID_W);
+ y*(ICON_GRID_H+ICON_GRID_MARGIN)+ICON_GRID_MARGIN, ICON_GRID_W,
+ icontype);
}
}
@@ -587,6 +649,11 @@ ListBase *UI_iconfile_list(void)
void UI_icons_free()
{
+ if(icongltex.id) {
+ glDeleteTextures(1, &icongltex.id);
+ icongltex.id= 0;
+ }
+
free_iconfile_list(&iconfilelist);
BKE_icons_free();
}
@@ -595,12 +662,14 @@ void UI_icons_free_drawinfo(void *drawinfo)
{
DrawInfo *di = drawinfo;
- if (di)
- {
- if (di->icon) {
- MEM_freeN(di->icon->rect);
- MEM_freeN(di->icon);
+ if(di) {
+ if(di->type == ICON_TYPE_BUFFER) {
+ if(di->data.buffer.image) {
+ MEM_freeN(di->data.buffer.image->rect);
+ MEM_freeN(di->data.buffer.image);
+ }
}
+
MEM_freeN(di);
}
}
@@ -610,12 +679,7 @@ static DrawInfo *icon_create_drawinfo()
DrawInfo *di = NULL;
di = MEM_callocN(sizeof(DrawInfo), "di_icon");
-
- di->drawFunc = 0;
- di->w = ICON_DEFAULT_HEIGHT;
- di->h = ICON_DEFAULT_HEIGHT;
- di->icon = NULL;
- di->aspect = 1.0f;
+ di->type= ICON_TYPE_PREVIEW;
return di;
}
@@ -639,7 +703,7 @@ int UI_icon_get_width(int icon_id)
}
if (di)
- return di->w;
+ return ICON_DEFAULT_HEIGHT;
return 0;
}
@@ -664,7 +728,7 @@ int UI_icon_get_height(int icon_id)
}
if (di)
- return di->h;
+ return ICON_DEFAULT_HEIGHT;
return 0;
}
@@ -676,56 +740,6 @@ void UI_icons_init(int first_dyn_id)
init_internal_icons();
}
-static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
-{
- struct ImBuf *ima;
- unsigned int *drect, *srect;
- float scaledx, scaledy;
- short ex, ey, dx, dy;
-
- /* paranoia test */
- if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
- return;
-
- /* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
- ima = IMB_dupImBuf(ibuf);
-
- if (!ima)
- return;
-
- if (ima->x > ima->y) {
- scaledx = (float)w;
- scaledy = ( (float)ima->y/(float)ima->x )*(float)w;
- }
- else {
- scaledx = ( (float)ima->x/(float)ima->y )*(float)h;
- scaledy = (float)h;
- }
-
- ex = (short)scaledx;
- ey = (short)scaledy;
-
- dx = (w - ex) / 2;
- dy = (h - ey) / 2;
-
- IMB_scalefastImBuf(ima, ex, ey);
-
- /* if needed, convert to 32 bits */
- if(ima->rect==NULL)
- IMB_rect_from_float(ima);
-
- srect = ima->rect;
- drect = rect;
-
- drect+= dy*w+dx;
- for (;ey > 0; ey--){
- memcpy(drect,srect, ex * sizeof(int));
- drect += w;
- srect += ima->x;
- }
- IMB_freeImBuf(ima);
-}
-
/* Render size for preview images at level miplevel */
static int preview_render_size(int miplevel)
{
@@ -751,113 +765,39 @@ static void icon_create_mipmap(struct PreviewImage* prv_img, int miplevel)
}
}
-/* create single icon from jpg, png etc. */
-static void icon_from_image(Scene *scene, Image *img, int miplevel)
-{
- ImBuf *ibuf= NULL;
- ImageUser iuser;
- PreviewImage *pi;
- unsigned int pr_size;
- short image_loaded = 0;
-
- /* img->ok is zero when Image cannot load */
- if (img==NULL || img->ok==0)
- return;
-
- /* setup dummy image user */
- memset(&iuser, 0, sizeof(ImageUser));
- iuser.ok= iuser.framenr= 1;
- iuser.scene= scene;
-
- /* elubie: this needs to be changed: here image is always loaded if not
- already there. Very expensive for large images. Need to find a way to
- only get existing ibuf */
-
- ibuf = BKE_image_get_ibuf(img, &iuser);
- if(ibuf==NULL || ibuf->rect==NULL) {
- return;
- }
-
- pi = BKE_previewimg_get((ID*)img);
-
- if(!pi) {
- printf("preview image could'nt be allocated");
- return;
- }
- /* we can only create the preview rect here, since loading possibly deallocated
- old preview */
- icon_create_mipmap(pi, miplevel);
-
- pr_size = img->preview->w[miplevel]*img->preview->h[miplevel]*sizeof(unsigned int);
-
- image_loaded = 1;
- icon_copy_rect(ibuf, img->preview->w[miplevel], img->preview->h[miplevel], img->preview->rect[miplevel]);
-}
-
-static void set_alpha(char* cp, int sizex, int sizey, char alpha)
-{
- int x,y;
- for(y=0; y<sizey; y++) {
- for(x=0; x<sizex; x++, cp+=4) {
- cp[3]= alpha;
- }
- }
-}
-
/* only called when icon has changed */
/* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(Scene *scene, ID *id, PreviewImage* prv_img, int miplevel)
+static void icon_set_image(bContext *C, ID *id, PreviewImage* prv_img, int miplevel)
{
- RenderInfo ri;
- unsigned int pr_size = 0;
-
if (!prv_img) {
printf("No preview image for this ID: %s\n", id->name);
return;
}
- /* no drawing (see last parameter doDraw, just calculate preview image
- - hopefully small enough to be fast */
- if (GS(id->name) == ID_IM)
- icon_from_image(scene, (struct Image*)id, miplevel);
- else {
- /* create the preview rect */
- icon_create_mipmap(prv_img, miplevel);
-
- ri.curtile= 0;
- ri.tottile= 0;
- ri.pr_rectx = prv_img->w[miplevel];
- ri.pr_recty = prv_img->h[miplevel];
- pr_size = ri.pr_rectx*ri.pr_recty*sizeof(unsigned int);
- ri.rect = MEM_callocN(pr_size, "pr icon rect");
-
- ED_preview_iconrender(scene, id, ri.rect, ri.pr_rectx, ri.pr_recty);
-
- /* world is rendered with alpha=0, so it wasn't displayed
- this could be render option for sky to, for later */
- if (GS(id->name) == ID_WO) {
- set_alpha( (char*) ri.rect, ri.pr_rectx, ri.pr_recty, 255);
- }
- else if (GS(id->name) == ID_MA) {
- Material* mat = (Material*)id;
- if (mat->material_type == MA_TYPE_HALO) {
- set_alpha( (char*) ri.rect, ri.pr_rectx, ri.pr_recty, 255);
- }
- }
+ /* create the preview rect */
+ icon_create_mipmap(prv_img, miplevel);
- memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
-
- /* and clean up */
- MEM_freeN(ri.rect);
- }
+ ED_preview_icon_job(C, prv_img, id, prv_img->rect[miplevel],
+ prv_img->w[miplevel], prv_img->h[miplevel]);
}
-static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect)
+static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect, float alpha, float *rgb)
{
-
+ /* modulate color */
+ if(alpha != 1.0f)
+ glPixelTransferf(GL_ALPHA_SCALE, alpha);
+
+ if(rgb) {
+ glPixelTransferf(GL_RED_SCALE, rgb[0]);
+ glPixelTransferf(GL_GREEN_SCALE, rgb[1]);
+ glPixelTransferf(GL_BLUE_SCALE, rgb[2]);
+ }
+
+ /* position */
glRasterPos2f(x, y);
// XXX ui_rasterpos_safe(x, y, aspect);
+ /* draw */
if((w<1 || h<1)) {
// XXX - TODO 2.5 verify whether this case can happen
// and only print in debug
@@ -865,23 +805,68 @@ static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw,
}
/* rect contains image in 'rendersize', we only scale if needed */
else if(rw!=w && rh!=h) {
- ImBuf *ima;
if(w>2000 || h>2000) { /* something has gone wrong! */
printf("insane icon size w=%d h=%d\n",w,h);
- return;
}
- /* first allocate imbuf for scaling and copy preview into it */
- ima = IMB_allocImBuf(rw, rh, 32, IB_rect, 0);
- memcpy(ima->rect, rect, rw*rh*sizeof(unsigned int));
-
- /* scale it */
- IMB_scaleImBuf(ima, w, h);
- glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, ima->rect);
-
- IMB_freeImBuf(ima);
+ else {
+ ImBuf *ima;
+
+ /* first allocate imbuf for scaling and copy preview into it */
+ ima = IMB_allocImBuf(rw, rh, 32, IB_rect, 0);
+ memcpy(ima->rect, rect, rw*rh*sizeof(unsigned int));
+
+ /* scale it */
+ IMB_scaleImBuf(ima, w, h);
+ glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, ima->rect);
+
+ IMB_freeImBuf(ima);
+ }
}
else
glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+
+ /* restore color */
+ if(alpha != 0.0f)
+ glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+
+ if(rgb) {
+ glPixelTransferf(GL_RED_SCALE, 1.0f);
+ glPixelTransferf(GL_GREEN_SCALE, 1.0f);
+ glPixelTransferf(GL_BLUE_SCALE, 1.0f);
+ }
+}
+
+static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy, int iw, int ih, float alpha, float *rgb)
+{
+ float x1, x2, y1, y2;
+
+ if(rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha);
+ else glColor4f(1.0f, 1.0f, 1.0f, alpha);
+
+ x1= ix*icongltex.invw;
+ x2= (ix + ih)*icongltex.invw;
+ y1= iy*icongltex.invh;
+ y2= (iy + ih)*icongltex.invh;
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, icongltex.id);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(x1, y1);
+ glVertex2f(x, y);
+
+ glTexCoord2f(x2, y1);
+ glVertex2f(x+w, y);
+
+ glTexCoord2f(x2, y2);
+ glVertex2f(x+w, y+h);
+
+ glTexCoord2f(x1, y2);
+ glVertex2f(x, y+h);
+ glEnd();
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
}
/* Drawing size for preview images at level miplevel */
@@ -894,10 +879,12 @@ static int preview_size(int miplevel)
return 0;
}
-static void icon_draw_size(float x, float y, int icon_id, float aspect, int miplevel, int draw_size, int nocreate)
+static void icon_draw_size(float x, float y, int icon_id, float aspect, float alpha, float *rgb, int miplevel, int draw_size, int nocreate)
{
Icon *icon = NULL;
DrawInfo *di = NULL;
+ IconImage *iimg;
+ int w, h;
icon = BKE_icon_get(icon_id);
@@ -905,7 +892,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
printf("icon_draw_mipmap: Internal error, no icon for icon ID: %d\n", icon_id);
return;
}
-
+
di = (DrawInfo*)icon->drawinfo;
if (!di) {
@@ -915,36 +902,43 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
icon->drawinfo_free = UI_icons_free_drawinfo;
}
- di->aspect = aspect;
/* scale width and height according to aspect */
- di->w = (int)(draw_size/di->aspect + 0.5f);
- di->h = (int)(draw_size/di->aspect + 0.5f);
+ w = (int)(draw_size/aspect + 0.5f);
+ h = (int)(draw_size/aspect + 0.5f);
- if (di->drawFunc) {
+ if(di->type == ICON_TYPE_VECTOR) {
/* vector icons use the uiBlock transformation, they are not drawn
with untransformed coordinates like the other icons */
- di->drawFunc(x, y, ICON_DEFAULT_HEIGHT, ICON_DEFAULT_HEIGHT, 1.0f);
+ di->data.vector.func(x, y, ICON_DEFAULT_HEIGHT, ICON_DEFAULT_HEIGHT, 1.0f);
}
- else if (di->icon) {
+ else if(di->type == ICON_TYPE_TEXTURE) {
+ icon_draw_texture(x, y, w, h, di->data.texture.x, di->data.texture.y,
+ di->data.texture.w, di->data.texture.h, alpha, rgb);
+ }
+ else if(di->type == ICON_TYPE_BUFFER) {
/* it is a builtin icon */
- if (!di->icon->rect) return; /* something has gone wrong! */
+ iimg= di->data.buffer.image;
+
+ if(!iimg->rect) return; /* something has gone wrong! */
- icon_draw_rect(x,y,di->w, di->h, di->aspect, di->icon->w, di->icon->h, di->icon->rect);
+ icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb);
}
- else {
+ else if(di->type == ICON_TYPE_PREVIEW) {
PreviewImage* pi = BKE_previewimg_get((ID*)icon->obj);
- if (pi) {
+ if(pi) {
/* no create icon on this level in code */
+ if(!pi->rect[miplevel]) return; /* something has gone wrong! */
- if (!pi->rect[miplevel]) return; /* something has gone wrong! */
-
- icon_draw_rect(x,y,di->w, di->h, di->aspect, pi->w[miplevel], pi->h[miplevel], pi->rect[miplevel]);
+ /* preview images use premul alpha ... */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ icon_draw_rect(x, y, w, h, aspect, pi->w[miplevel], pi->h[miplevel], pi->rect[miplevel], 1.0f, NULL);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
}
-void ui_id_icon_render(Scene *scene, ID *id)
+void ui_id_icon_render(bContext *C, ID *id)
{
PreviewImage *pi = BKE_previewimg_get(id);
@@ -952,13 +946,13 @@ void ui_id_icon_render(Scene *scene, ID *id)
if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
{
/* create the preview rect if necessary */
- icon_set_image(scene, id, pi, 0);
+ icon_set_image(C, id, pi, 0);
pi->changed[0] = 0;
}
}
}
-int ui_id_icon_get(Scene *scene, ID *id)
+int ui_id_icon_get(bContext *C, ID *id)
{
int iconid= 0;
@@ -972,7 +966,7 @@ int ui_id_icon_get(Scene *scene, ID *id)
case ID_LA: /* fall through */
iconid= BKE_icon_getid(id);
/* checks if not exists, or changed */
- ui_id_icon_render(scene, id);
+ ui_id_icon_render(C, id);
break;
default:
break;
@@ -981,50 +975,35 @@ int ui_id_icon_get(Scene *scene, ID *id)
return iconid;
}
-static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate)
+static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, float alpha, int miplevel, int nocreate)
{
int draw_size = preview_size(miplevel);
- icon_draw_size(x,y,icon_id, aspect, miplevel, draw_size, nocreate);
+ icon_draw_size(x, y, icon_id, aspect, alpha, NULL, miplevel, draw_size, nocreate);
}
+void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect, float alpha)
+{
+ icon_draw_mipmap(x, y, icon_id, aspect, alpha, PREVIEW_MIPMAP_ZERO, 0);
+}
-void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect)
+void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, float *rgb)
{
- icon_draw_mipmap(x,y,icon_id, aspect, PREVIEW_MIPMAP_ZERO, 0);
+ int draw_size = preview_size(PREVIEW_MIPMAP_ZERO);
+ icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, PREVIEW_MIPMAP_ZERO, draw_size, 0);
}
void UI_icon_draw(float x, float y, int icon_id)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f);
+ UI_icon_draw_aspect(x, y, icon_id, 1.0f, 1.0f);
}
-void UI_icon_draw_size_blended(float x, float y, int size, int icon_id, int shade)
+void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
{
- if(shade < 0) {
- float r= (128+shade)/128.0f;
- glPixelTransferf(GL_ALPHA_SCALE, r);
- }
-
- icon_draw_size(x,y,icon_id, 1.0f, 0, size, 1);
-
- if(shade < 0)
- glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+ icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, 0, size, 1);
}
void UI_icon_draw_preview(float x, float y, int icon_id, int nocreate)
{
- icon_draw_mipmap(x,y,icon_id, 1.0f, PREVIEW_MIPMAP_LARGE, nocreate);
+ icon_draw_mipmap(x, y, icon_id, 1.0f, 1.0f, PREVIEW_MIPMAP_LARGE, nocreate);
}
-void UI_icon_draw_aspect_blended(float x, float y, int icon_id, float aspect, int shade)
-{
- if(shade < 0) {
- float r= (128+shade)/128.0f;
- glPixelTransferf(GL_ALPHA_SCALE, r);
- }
-
- UI_icon_draw_aspect(x, y, icon_id, aspect);
-
- if(shade < 0)
- glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
-}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 2e623114fe9..97bbee0a1c3 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -72,6 +72,7 @@ typedef enum {
/* menus */
UI_WTYPE_MENU_RADIO,
+ UI_WTYPE_MENU_ICON_RADIO,
UI_WTYPE_MENU_POINTER_LINK,
UI_WTYPE_PULLDOWN,
@@ -263,6 +264,9 @@ struct uiBlock {
void *func_arg1;
void *func_arg2;
+ uiButHandleNFunc funcN;
+ void *func_argN;
+
uiMenuHandleFunc butm_func;
void *butm_func_arg;
@@ -447,8 +451,8 @@ void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int i
void uiStyleInit(void);
/* interface_icons.c */
-void ui_id_icon_render(struct Scene *scene, struct ID *id);
-int ui_id_icon_get(struct Scene *scene, struct ID *id);
+void ui_id_icon_render(struct bContext *C, struct ID *id);
+int ui_id_icon_get(struct bContext *C, struct ID *id);
/* resources.c */
void init_userdef_do_versions(void);
@@ -467,6 +471,8 @@ void ui_but_anim_insert_keyframe(struct bContext *C);
void ui_but_anim_delete_keyframe(struct bContext *C);
void ui_but_anim_add_driver(struct bContext *C);
void ui_but_anim_remove_driver(struct bContext *C);
+void ui_but_anim_copy_driver(struct bContext *C);
+void ui_but_anim_paste_driver(struct bContext *C);
void ui_but_anim_add_keyingset(struct bContext *C);
void ui_but_anim_remove_keyingset(struct bContext *C);
void ui_but_anim_menu(struct bContext *C, uiBut *but);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index bf449dba597..e9160e0e416 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -480,7 +480,8 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr,
static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h, int icon_only)
{
uiLayout *sub;
- uiBut *but;
+ uiBut *but=NULL;
+ PropertyType type;
PropertySubType subtype;
int labelw;
@@ -496,6 +497,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i
w= w-labelw;
}
+ type= RNA_property_type(prop);
subtype= RNA_property_subtype(prop);
if(subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
@@ -505,8 +507,10 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i
/* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */
but= uiDefIconButO(block, BUT, "BUTTONS_OT_file_browse", WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, "Browse for file or directory.");
}
+ else if(subtype == PROP_DIRECTION)
+ uiDefButR(block, BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL);
else
- but= uiDefAutoButR(block, ptr, prop, index, (icon_only)? "": NULL, icon, x, y, w, h);
+ but= uiDefAutoButR(block, ptr, prop, index, (type == PROP_ENUM && !icon_only)? NULL: "", icon, x, y, w, h);
uiBlockSetCurLayout(block, layout);
return but;
@@ -529,7 +533,7 @@ void uiFileBrowseContextProperty(const bContext *C, PointerRNA *ptr, PropertyRNA
prevbut= but->prev;
/* find the button before the active one */
- if((but->flag & UI_BUT_LAST_ACTIVE) && prevbut && prevbut->rnapoin.id.data) {
+ if((but->flag & UI_BUT_LAST_ACTIVE) && prevbut && prevbut->rnapoin.data) {
if(RNA_property_type(prevbut->rnaprop) == PROP_STRING) {
*ptr= prevbut->rnapoin;
*prop= prevbut->rnaprop;
@@ -718,7 +722,7 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch
/* enum lookup */
if((prop= RNA_struct_find_property(&ptr, propname))) {
RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
- if(RNA_enum_value_from_id(item, value_str, &value)==0) {
+ if(item==NULL || RNA_enum_value_from_id(item, value_str, &value)==0) {
if(free) MEM_freeN(item);
printf("uiItemEnumO_string: %s.%s, enum %s not found.\n", RNA_struct_identifier(ptr.type), propname, value_str);
return;
@@ -840,9 +844,6 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
char namestr[UI_MAX_NAME_STR];
int len, w, h, slider, toggle, expand, icon_only;
- if(!ptr->data || !prop)
- return;
-
uiBlockSetCurLayout(block, layout);
/* retrieve info */
@@ -913,12 +914,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int flag)
{
- PropertyRNA *prop;
-
- if(!ptr->data || !propname)
- return;
-
- prop= RNA_struct_find_property(ptr, propname);
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
if(!prop) {
ui_item_disabled(layout, propname);
@@ -931,12 +927,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop
void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value)
{
- PropertyRNA *prop;
-
- if(!ptr->data || !propname)
- return;
-
- prop= RNA_struct_find_property(ptr, propname);
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
if(!prop || RNA_property_type(prop) != PROP_ENUM) {
ui_item_disabled(layout, propname);
@@ -949,15 +940,10 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr,
void uiItemEnumR_string(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value)
{
- PropertyRNA *prop;
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
EnumPropertyItem *item;
int ivalue, a, free;
- if(!ptr->data || !propname)
- return;
-
- prop= RNA_struct_find_property(ptr, propname);
-
if(!prop || RNA_property_type(prop) != PROP_ENUM) {
ui_item_disabled(layout, propname);
printf("uiItemEnumR: enum property not found: %s\n", propname);
@@ -1035,7 +1021,6 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, uiSearchItems *items)
{
- Scene *scene= CTX_data_scene(C);
uiBut *but= arg_but;
char *name;
int i, iconid;
@@ -1044,7 +1029,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, ui
RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
iconid= 0;
if(RNA_struct_is_ID(itemptr.type))
- iconid= ui_id_icon_get(scene, itemptr.data);
+ iconid= ui_id_icon_get((bContext*)C, itemptr.data);
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
@@ -1107,7 +1092,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
but->hardmax= MAX2(but->hardmax, 256);
but->rnasearchpoin= *searchptr;
but->rnasearchprop= searchprop;
- but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT;
+ but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT|UI_BUT_UNDO;
uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL);
}
@@ -1123,9 +1108,6 @@ void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *p
int w, h;
/* validate arguments */
- if(!ptr->data || !searchptr->data)
- return;
-
prop= RNA_struct_find_property(ptr, propname);
if(!prop) {
@@ -1200,8 +1182,10 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun
if(layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */
w -= 10;
- if(icon)
+ if(name[0] && icon)
but= uiDefIconTextMenuBut(block, func, arg, icon, (char*)name, 0, 0, w, h, "");
+ else if(icon)
+ but= uiDefIconMenuBut(block, func, arg, icon, 0, 0, w, h, "");
else
but= uiDefMenuBut(block, func, arg, (char*)name, 0, 0, w, h, "");
@@ -2227,18 +2211,13 @@ static void ui_item_layout(uiItem *item)
}
}
-static void ui_layout_items(const bContext *C, uiBlock *block, uiLayout *layout)
-{
- ui_item_estimate(&layout->item);
- ui_item_layout(&layout->item);
-}
-
-static void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
+static void ui_layout_end(uiBlock *block, uiLayout *layout, int *x, int *y)
{
if(layout->root->handlefunc)
uiBlockSetButmFunc(block, layout->root->handlefunc, layout->root->argv);
- ui_layout_items(C, block, layout);
+ ui_item_estimate(&layout->item);
+ ui_item_layout(&layout->item);
if(x) *x= layout->x;
if(y) *y= layout->y;
@@ -2346,7 +2325,7 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
layout->root->argv= argv;
}
-void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y)
+void uiBlockLayoutResolve(uiBlock *block, int *x, int *y)
{
uiLayoutRoot *root;
@@ -2357,7 +2336,7 @@ void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y)
for(root=block->layouts.first; root; root=root->next) {
/* NULL in advance so we don't interfere when adding button */
- ui_layout_end(C, block, root->layout, x, y);
+ ui_layout_end(block, root->layout, x, y);
ui_layout_free(root->layout);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 05001109b53..fa24aa72b9f 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -963,6 +963,7 @@ static void check_panel_overlap(ARegion *ar, Panel *panel)
}
}
+#if 0 // XXX panel docking/tabbing code that's no longer used
static void test_add_new_tabs(ARegion *ar)
{
Panel *pa, *pasel=NULL, *palap=NULL;
@@ -990,6 +991,7 @@ static void test_add_new_tabs(ARegion *ar)
}
if(pasel==NULL || palap==NULL) return;
+ if(palap->type && palap->type->flag & PNL_NO_HEADER) return;
/* the overlapped panel becomes a tab */
palap->paneltab= pasel;
@@ -1015,6 +1017,7 @@ static void test_add_new_tabs(ARegion *ar)
pa= pa->next;
}
}
+#endif
/************************ panel dragging ****************************/
@@ -1381,7 +1384,12 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
if(state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
if(data && data->state != PANEL_STATE_ANIMATION) {
- test_add_new_tabs(ar); // also copies locations of tabs in dragged panel
+ /* XXX:
+ * - the panel tabbing function call below (test_add_new_tabs()) has been commented out
+ * "It is too easy to do by accident when reordering panels, is very hard to control and use, and has no real benefit." - BillRey
+ * Aligorith, 2009Sep
+ */
+ //test_add_new_tabs(ar); // also copies locations of tabs in dragged panel
check_panel_overlap(ar, NULL); // clears
}
@@ -1399,14 +1407,14 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
MEM_freeN(data);
pa->activedata= NULL;
- WM_event_remove_ui_handler(&win->handlers, ui_handler_panel, ui_handler_remove_panel, pa);
+ WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa);
}
else {
if(!data) {
data= MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData");
pa->activedata= data;
- WM_event_add_ui_handler(C, &win->handlers, ui_handler_panel, ui_handler_remove_panel, pa);
+ WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa);
}
if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG))
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 1d911fef418..0f04333c6c5 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -758,7 +758,7 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
data->active= a+1;
if(cpoin) cpoin[0]= '|';
}
- if(data->items.totitem==1)
+ if(data->items.totitem==1 && but->editstr[0])
data->active= 1;
}
@@ -2192,7 +2192,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
block->direction= direction;
- uiBlockLayoutResolve(C, block, NULL, NULL);
+ uiBlockLayoutResolve(block, NULL, NULL);
if(pup->popup) {
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1);
@@ -2226,7 +2226,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
}
block->minbounds= minwidth;
- uiTextBoundsBlock(block, 40);
+ uiTextBoundsBlock(block, 50);
}
/* if menu slides out of other menu, override direction */
@@ -2275,7 +2275,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
if(!but) {
handle->popup= 1;
- UI_add_popup_handlers(C, &window->handlers, handle);
+ UI_add_popup_handlers(C, &window->modalhandlers, handle);
WM_event_add_mousemove(C);
}
@@ -2332,7 +2332,7 @@ void uiPupMenuEnd(bContext *C, uiPopupMenu *pup)
menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup);
menu->popup= 1;
- UI_add_popup_handlers(C, &window->handlers, menu);
+ UI_add_popup_handlers(C, &window->modalhandlers, menu);
WM_event_add_mousemove(C);
MEM_freeN(pup);
@@ -2493,7 +2493,7 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, i
handle->optype= (opname)? WM_operatortype_find(opname, 0): NULL;
handle->opcontext= opcontext;
- UI_add_popup_handlers(C, &window->handlers, handle);
+ UI_add_popup_handlers(C, &window->modalhandlers, handle);
WM_event_add_mousemove(C);
}
@@ -2516,7 +2516,7 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int
handle->cancel_func= confirm_cancel_operator;
handle->opcontext= opcontext;
- UI_add_popup_handlers(C, &window->handlers, handle);
+ UI_add_popup_handlers(C, &window->modalhandlers, handle);
WM_event_add_mousemove(C);
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 2b7d6f383bf..57dc484f975 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -36,10 +36,11 @@
#include "BKE_icons.h"
#include "BKE_global.h"
#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_utildefines.h"
#include "ED_screen.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "RNA_access.h"
@@ -75,7 +76,7 @@ typedef struct TemplateID {
} TemplateID;
/* Search browse menu, assign */
-static void id_search_call_cb(struct bContext *C, void *arg_template, void *item)
+static void id_search_call_cb(bContext *C, void *arg_template, void *item)
{
TemplateID *template= (TemplateID*)arg_template;
@@ -90,10 +91,9 @@ static void id_search_call_cb(struct bContext *C, void *arg_template, void *item
}
/* ID Search browse menu, do the search */
-static void id_search_cb(const struct bContext *C, void *arg_template, char *str, uiSearchItems *items)
+static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSearchItems *items)
{
TemplateID *template= (TemplateID*)arg_template;
- Scene *scene= CTX_data_scene(C);
ListBase *lb= template->idlb;
ID *id;
int iconid;
@@ -101,7 +101,7 @@ static void id_search_cb(const struct bContext *C, void *arg_template, char *str
/* ID listbase */
for(id= lb->first; id; id= id->next) {
if(BLI_strcasestr(id->name+2, str)) {
- iconid= ui_id_icon_get(scene, id);
+ iconid= ui_id_icon_get((bContext*)C, id);
if(!uiSearchItemAdd(items, id->name+2, id, iconid))
break;
@@ -291,7 +291,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6;
if(newop) {
- but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL);
+ but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, (id)? "": "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 {
@@ -344,9 +344,6 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
StructRNA *type;
int flag;
- if(!ptr->data)
- return;
-
prop= RNA_struct_find_property(ptr, propname);
if(!prop || RNA_property_type(prop) != PROP_POINTER) {
@@ -407,10 +404,12 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
{
Object *ob = ob_v;
- ModifierData *md;
-
+ ModifierData *md= md_v;
int i, cageIndex = modifiers_getCageIndex(ob, NULL );
+ /* undo button operation */
+ md->mode ^= eModifierMode_OnCage;
+
for(i = 0, md=ob->modifiers.first; md; ++i, md=md->next) {
if(md == md_v) {
if(i >= cageIndex)
@@ -519,9 +518,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
/* XXX uiBlockSetEmboss(block, UI_EMBOSSR); */
if(ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
-
/* XXX uiBlockSetCol(block, color); */
- but = uiDefIconBut(block, BUT, 0, ICON_MESH_DATA, 0, 0, 16, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
+ but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0, 16, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
+ if(index < cageIndex)
+ uiButSetFlag(but, UI_BUT_DISABLED);
uiButSetFunc(but, modifiers_setOnCage, ob, md);
uiBlockEndAlign(block);
/* XXX uiBlockSetCol(block, TH_AUTO); */
@@ -675,6 +675,8 @@ void do_constraint_panels(bContext *C, void *arg, int event)
if(ob->type==OB_ARMATURE) DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB);
else DAG_id_flush_update(&ob->id, OB_RECALC_OB);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
// XXX allqueue(REDRAWVIEW3D, 0);
// XXX allqueue(REDRAWBUTSOBJECT, 0);
@@ -686,19 +688,15 @@ static void constraint_active_func(bContext *C, void *ob_v, void *con_v)
ED_object_constraint_set_active(ob_v, con_v);
}
-static void verify_constraint_name_func (bContext *C, void *con_v, void *name_v)
+static void verify_constraint_name_func (bContext *C, void *con_v, void *dummy)
{
Object *ob= CTX_data_active_object(C);
bConstraint *con= con_v;
- char oldname[32];
if (!con)
return;
- /* put on the stack */
- BLI_strncpy(oldname, (char *)name_v, 32);
-
- ED_object_constraint_rename(ob, con, oldname);
+ ED_object_constraint_rename(ob, con, NULL);
ED_object_constraint_set_active(ob, con);
// XXX allqueue(REDRAWACTION, 0);
}
@@ -764,6 +762,22 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
}
}
+static void test_obpoin_but(bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ id= CTX_data_main(C)->object.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ id_lib_extern(id); /* checks lib data, sets correct flag for saving then */
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
/* draw panel showing settings for a constraint */
static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
{
@@ -887,10 +901,11 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_down", WM_OP_INVOKE_DEFAULT, VICON_MOVE_DOWN, xco+width-50+18, yco, 16, 18, "Move constraint down in constraint stack");
uiBlockEndAlign(block);
}
-
-
+
/* Close 'button' - emboss calls here disable drawing of 'button' behind X */
uiBlockSetEmboss(block, UI_EMBOSSN);
+ uiDefIconButBitS(block, ICONTOGN, CONSTRAINT_OFF, B_CONSTRAINT_TEST, ICON_CHECKBOX_DEHLT, xco+243, yco, 19, 19, &con->flag, 0.0, 0.0, 0.0, 0.0, "enable/disable constraint");
+
uiDefIconButO(block, BUT, "CONSTRAINT_OT_delete", WM_OP_INVOKE_DEFAULT, ICON_X, xco+262, yco, 19, 19, "Delete constraint");
uiBlockSetEmboss(block, UI_EMBOSS);
}
@@ -958,11 +973,11 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* subtarget */
if (is_armature_target(ct->tar)) {
but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", xco+120, yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)ct->tar);
+ //uiButSetCompleteFunc(but, autocomplete_bone, (void *)ct->tar);
}
else if (is_geom_target(ct->tar)) {
but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", xco+120, yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
- uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ct->tar);
+ //uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ct->tar);
}
else {
strcpy(ct->subtarget, "");
@@ -1241,54 +1256,501 @@ void uiTemplatePreview(uiLayout *layout, ID *id, ID *parent, MTex *slot)
/********************** ColorRamp Template **************************/
-void uiTemplateColorRamp(uiLayout *layout, ColorBand *coba, int expand)
+#include "BKE_texture.h"
+
+typedef struct RNAUpdateCb {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+} RNAUpdateCb;
+
+static void rna_update_cb(bContext *C, void *arg_cb, void *arg_unused)
+{
+ RNAUpdateCb *cb= (RNAUpdateCb*)arg_cb;
+
+ /* we call update here on the pointer property, this way the
+ owner of the curve mapping can still define it's own update
+ and notifier, even if the CurveMapping struct is shared. */
+ RNA_property_update(C, &cb->ptr, cb->prop);
+}
+
+#define B_BANDCOL 1
+
+static int vergcband(const void *a1, const void *a2)
+{
+ const CBData *x1=a1, *x2=a2;
+
+ if( x1->pos > x2->pos ) return 1;
+ else if( x1->pos < x2->pos) return -1;
+ return 0;
+}
+
+static void colorband_pos_cb(bContext *C, void *cb_v, void *coba_v)
+{
+ ColorBand *coba= coba_v;
+ int a;
+
+ if(coba->tot<2) return;
+
+ for(a=0; a<coba->tot; a++) coba->data[a].cur= a;
+ qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
+ for(a=0; a<coba->tot; a++) {
+ if(coba->data[a].cur==coba->cur) {
+ coba->cur= a;
+ break;
+ }
+ }
+
+ rna_update_cb(C, cb_v, NULL);
+}
+
+static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
+{
+ ColorBand *coba= coba_v;
+
+ if(coba->tot < MAXCOLORBAND-1) coba->tot++;
+ coba->cur= coba->tot-1;
+
+ colorband_pos_cb(C, cb_v, coba_v);
+
+ ED_undo_push(C, "Add colorband");
+}
+
+static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
+{
+ ColorBand *coba= coba_v;
+ int a;
+
+ if(coba->tot<2) return;
+
+ for(a=coba->cur; a<coba->tot; a++) {
+ coba->data[a]= coba->data[a+1];
+ }
+ if(coba->cur) coba->cur--;
+ coba->tot--;
+
+ ED_undo_push(C, "Delete colorband");
+
+ rna_update_cb(C, cb_v, NULL);
+}
+
+
+/* offset aligns from bottom, standard width 300, height 115 */
+static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb)
+{
+
+ uiBut *bt;
+
+ if(coba==NULL) return;
+
+ bt= uiDefBut(block, BUT, 0, "Add", 0+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Add a new color stop to the colorband");
+ uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
+
+ bt= uiDefBut(block, BUT, 0, "Delete", 60+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Delete the active position");
+ uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
+
+ uiDefButS(block, NUM, 0, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(MAX2(0, coba->tot-1)), 0, 0, "Choose active color stop");
+
+ bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
+ 210+xoffs, 100+yoffs, 90, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ uiBlockEndAlign(block);
+
+ bt= uiDefBut(block, BUT_COLORBAND, 0, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, "");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ if(coba->tot) {
+ CBData *cbd= coba->data + coba->cur;
+
+ bt= uiDefButF(block, NUM, 0, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop");
+ uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba);
+ bt= uiDefButF(block, COL, 0, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ bt= uiDefButF(block, NUMSLI, 0, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ }
+
+}
+
+static void colorband_buttons_small(uiBlock *block, ColorBand *coba, rctf *butr, RNAUpdateCb *cb)
+{
+ uiBut *bt;
+ float unit= (butr->xmax-butr->xmin)/14.0f;
+ float xs= butr->xmin;
+
+
+ bt= uiDefBut(block, BUT, 0, "Add", xs,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband");
+ uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
+ bt= uiDefBut(block, BUT, 0, "Delete", xs+2.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Delete the active position");
+ uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
+
+ if(coba->tot) {
+ CBData *cbd= coba->data + coba->cur;
+ bt= uiDefButF(block, COL, 0, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ bt= uiDefButF(block, NUMSLI, 0, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ }
+
+ bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
+ xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ bt= uiDefBut(block, BUT_COLORBAND, 0, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, "");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ uiBlockEndAlign(block);
+}
+
+static void colorband_buttons_layout(uiBlock *block, ColorBand *coba, rctf *butr, int small, RNAUpdateCb *cb)
{
+ if(small)
+ colorband_buttons_small(block, coba, butr, cb);
+ else
+ colorband_buttons_large(block, coba, 0, 0, cb);
+}
+
+void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, char *propname, int expand)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ RNAUpdateCb *cb;
uiBlock *block;
rctf rect;
- if(coba) {
- rect.xmin= 0; rect.xmax= 200;
- rect.ymin= 0; rect.ymax= 190;
-
- block= uiLayoutFreeBlock(layout);
- colorband_buttons(block, coba, &rect, !expand);
- }
+ if(!prop || RNA_property_type(prop) != PROP_POINTER)
+ return;
+
+ cptr= RNA_property_pointer_get(ptr, prop);
+ if(!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp))
+ return;
+
+ cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr= *ptr;
+ cb->prop= prop;
+
+ rect.xmin= 0; rect.xmax= 200;
+ rect.ymin= 0; rect.ymax= 190;
+
+ block= uiLayoutFreeBlock(layout);
+ colorband_buttons_layout(block, cptr.data, &rect, !expand, cb);
+
+ MEM_freeN(cb);
}
/********************* CurveMapping Template ************************/
#include "DNA_color_types.h"
+#include "BKE_colortools.h"
-void uiTemplateCurveMapping(uiLayout *layout, CurveMapping *cumap, int type, int compact)
+static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *unused)
{
- rctf rect;
+ CurveMapping *cumap = cumap_v;
+ float d;
+
+ /* we allow 20 times zoom */
+ if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
+ d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin);
+ cumap->curr.xmin+= d;
+ cumap->curr.xmax-= d;
+ d= 0.1154f*(cumap->curr.ymax - cumap->curr.ymin);
+ cumap->curr.ymin+= d;
+ cumap->curr.ymax-= d;
+ }
- if(cumap) {
- if(compact) {
- rect.xmin= 0; rect.xmax= 150;
- rect.ymin= 0; rect.ymax= 140;
+ ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *unused)
+{
+ CurveMapping *cumap = cumap_v;
+ float d, d1;
+
+ /* we allow 20 times zoom, but dont view outside clip */
+ if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
+ d= d1= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
+
+ if(cumap->flag & CUMA_DO_CLIP)
+ if(cumap->curr.xmin-d < cumap->clipr.xmin)
+ d1= cumap->curr.xmin - cumap->clipr.xmin;
+ cumap->curr.xmin-= d1;
+
+ d1= d;
+ if(cumap->flag & CUMA_DO_CLIP)
+ if(cumap->curr.xmax+d > cumap->clipr.xmax)
+ d1= -cumap->curr.xmax + cumap->clipr.xmax;
+ cumap->curr.xmax+= d1;
+
+ d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin);
+
+ if(cumap->flag & CUMA_DO_CLIP)
+ if(cumap->curr.ymin-d < cumap->clipr.ymin)
+ d1= cumap->curr.ymin - cumap->clipr.ymin;
+ cumap->curr.ymin-= d1;
+
+ d1= d;
+ if(cumap->flag & CUMA_DO_CLIP)
+ if(cumap->curr.ymax+d > cumap->clipr.ymax)
+ d1= -cumap->curr.ymax + cumap->clipr.ymax;
+ cumap->curr.ymax+= d1;
+ }
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+static void curvemap_buttons_setclip(bContext *C, void *cumap_v, void *unused)
+{
+ CurveMapping *cumap = cumap_v;
+
+ curvemapping_changed(cumap, 0);
+}
+
+static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
+{
+ CurveMapping *cumap = cumap_v;
+
+ curvemap_remove(cumap->cm+cumap->cur, SELECT);
+ curvemapping_changed(cumap, 0);
+
+ rna_update_cb(C, cb_v, NULL);
+}
+
+/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
+static uiBlock *curvemap_clipping_func(bContext *C, struct ARegion *ar, void *cumap_v)
+{
+ CurveMapping *cumap = cumap_v;
+ uiBlock *block;
+ uiBut *bt;
+
+ block= uiBeginBlock(C, ar, "curvemap_clipping_func", UI_EMBOSS);
+
+ /* use this for a fake extra empy space around the buttons */
+ uiDefBut(block, LABEL, 0, "", -4, 16, 128, 106, NULL, 0, 0, 0, 0, "");
+
+ bt= uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, "Use Clipping",
+ 0,100,120,18, &cumap->flag, 0.0, 0.0, 10, 0, "");
+ uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, 0, "Min X ", 0,74,120,18, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, "");
+ uiDefButF(block, NUM, 0, "Min Y ", 0,56,120,18, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, "");
+ uiDefButF(block, NUM, 0, "Max X ", 0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "Max Y ", 0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+
+ uiEndBlock(C, block);
+ return block;
+}
+
+static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
+{
+ CurveMapping *cumap = cumap_v;
+ CurveMap *cuma= cumap->cm+cumap->cur;
+
+ switch(event) {
+ case 0:
+ curvemap_reset(cuma, &cumap->clipr);
+ curvemapping_changed(cumap, 0);
+ break;
+ case 1:
+ cumap->curr= cumap->clipr;
+ break;
+ case 2: /* set vector */
+ curvemap_sethandle(cuma, 1);
+ curvemapping_changed(cumap, 0);
+ break;
+ case 3: /* set auto */
+ curvemap_sethandle(cuma, 0);
+ curvemapping_changed(cumap, 0);
+ break;
+ case 4: /* extend horiz */
+ cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ curvemapping_changed(cumap, 0);
+ break;
+ case 5: /* extend extrapolate */
+ cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
+ curvemapping_changed(cumap, 0);
+ break;
+ }
+ ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+static uiBlock *curvemap_tools_func(bContext *C, struct ARegion *ar, void *cumap_v)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS);
+ uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset View", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Horizontal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Extrapolated", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Curve", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 50);
+
+ uiEndBlock(C, block);
+ return block;
+}
+
+static void curvemap_buttons_redraw(bContext *C, void *arg1, void *arg2)
+{
+ ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
+{
+ CurveMapping *cumap = cumap_v;
+ int a;
+
+ for(a=0; a<CM_TOT; a++)
+ curvemap_reset(cumap->cm+a, &cumap->clipr);
+
+ cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f;
+ cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f;
+ curvemapping_set_black_white(cumap, NULL, NULL);
+
+ curvemapping_changed(cumap, 0);
+
+ rna_update_cb(C, cb_v, NULL);
+}
+
+/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
+static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels, RNAUpdateCb *cb)
+{
+ CurveMapping *cumap= ptr->data;
+ uiLayout *row, *sub, *split;
+ uiBlock *block;
+ uiBut *bt;
+ float dx= UI_UNIT_X;
+ int icon, size;
+
+ block= uiLayoutGetBlock(layout);
+
+ /* curve chooser */
+ row= uiLayoutRow(layout, 0);
+
+ if(labeltype=='v') {
+ /* vector */
+ sub= uiLayoutRow(row, 1);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ if(cumap->cm[0].curve) {
+ bt= uiDefButI(block, ROW, 0, "X", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
}
- else {
- rect.xmin= 0; rect.xmax= 200;
- rect.ymin= 0; rect.ymax= 190;
+ if(cumap->cm[1].curve) {
+ bt= uiDefButI(block, ROW, 0, "Y", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if(cumap->cm[2].curve) {
+ bt= uiDefButI(block, ROW, 0, "Z", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ }
+ else if(labeltype=='c') {
+ /* color */
+ sub= uiLayoutRow(row, 1);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ if(cumap->cm[3].curve) {
+ bt= uiDefButI(block, ROW, 0, "C", 0, 0, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if(cumap->cm[0].curve) {
+ bt= uiDefButI(block, ROW, 0, "R", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if(cumap->cm[1].curve) {
+ bt= uiDefButI(block, ROW, 0, "G", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if(cumap->cm[2].curve) {
+ bt= uiDefButI(block, ROW, 0, "B", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
}
-
- curvemap_layout(layout, cumap, type, 0, 0, &rect);
}
+ else
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
+
+ /* operation buttons */
+ sub= uiLayoutRow(row, 1);
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ bt= uiDefIconBut(block, BUT, 0, ICON_ZOOMIN, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in");
+ uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL);
+
+ bt= uiDefIconBut(block, BUT, 0, ICON_ZOOMOUT, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out");
+ uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
+
+ bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, 18, "Tools");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT;
+ bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, 18, "Clipping Options");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ bt= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points");
+ uiButSetNFunc(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+ uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ /* curve itself */
+ size= uiLayoutGetWidth(layout);
+ row= uiLayoutRow(layout, 0);
+ uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 200), cumap, 0.0f, 1.0f, 0, 0, "");
+
+ /* black/white levels */
+ if(levels) {
+ split= uiLayoutSplit(layout, 0);
+ uiItemR(uiLayoutColumn(split, 0), NULL, 0, ptr, "black_level", UI_ITEM_R_EXPAND);
+ uiItemR(uiLayoutColumn(split, 0), NULL, 0, ptr, "white_level", UI_ITEM_R_EXPAND);
+
+ uiLayoutRow(layout, 0);
+ bt=uiDefBut(block, BUT, 0, "Reset", 0, 0, UI_UNIT_X*10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves");
+ uiButSetNFunc(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
+ }
+
+ uiBlockSetNFunc(block, NULL, NULL, NULL);
+}
+
+void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, int type, int levels)
+{
+ RNAUpdateCb *cb;
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+
+ if(!prop || RNA_property_type(prop) != PROP_POINTER)
+ return;
+
+ cptr= RNA_property_pointer_get(ptr, prop);
+ if(!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping))
+ return;
+
+ cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr= *ptr;
+ cb->prop= prop;
+
+ curvemap_buttons_layout(layout, &cptr, type, levels, cb);
+
+ MEM_freeN(cb);
}
/********************* TriColor (ThemeWireColorSet) Template ************************/
void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname)
{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
uiLayout *row;
- PropertyRNA *prop;
PointerRNA csPtr;
-
- if (!ptr->data)
- return;
-
- prop= RNA_struct_find_property(ptr, propname);
+
if (!prop) {
printf("uiTemplateTriColorSet: property not found: %s\n", propname);
return;
@@ -1319,9 +1781,6 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
int groups, cols, layers;
int group, col, layer, row;
- if (!ptr->data)
- return;
-
prop= RNA_struct_find_property(ptr, propname);
if (!prop) {
printf("uiTemplateLayer: layers property not found: %s\n", propname);
@@ -1382,6 +1841,36 @@ static void list_item_add(ListBase *lb, ListBase *itemlb, uiLayout *layout, Poin
}
#endif
+static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
+{
+ 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;
+ }
+
+ /* get icon from ID */
+ if(id) {
+ icon= ui_id_icon_get(C, id);
+
+ if(icon)
+ return icon;
+ }
+
+ return rnaicon;
+}
+
ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
{
//Scene *scene= CTX_data_scene(C);
@@ -1394,7 +1883,7 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
Panel *pa;
ListBase lb, *itemlb;
char *name, str[32];
- int icon=0, i= 0, activei= 0, len= 0, items, found, min, max;
+ int rnaicon=0, icon=0, i= 0, activei= 0, len= 0, items, found, min, max;
lb.first= lb.last= NULL;
@@ -1441,7 +1930,7 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
/* get icon */
if(ptr->data && prop) {
ptype= RNA_property_pointer_type(ptr, prop);
- icon= RNA_struct_ui_icon(ptype);
+ rnaicon= RNA_struct_ui_icon(ptype);
}
/* get active data */
@@ -1461,15 +1950,7 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
if(i == 9)
row= uiLayoutRow(col, 0);
- if(RNA_struct_is_a(itemptr.type, &RNA_TextureSlot)) {
-#if 0
- MTex *mtex= itemptr.data;
-
- if(mtex && mtex->tex)
- icon= ui_id_icon_get(scene, &mtex->tex->id);
-#endif
- }
-
+ icon= list_item_icon_get(C, &itemptr, rnaicon);
uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
@@ -1493,6 +1974,7 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
if(found) {
/* create button */
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+ icon= list_item_icon_get(C, &itemptr, rnaicon);
uiItemL(row, (name)? name: "", icon);
if(name)
@@ -1546,6 +2028,8 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
subrow= uiLayoutRow(col, 0);
+
+ icon= list_item_icon_get(C, &itemptr, rnaicon);
/* create button */
if(!icon || icon == ICON_DOT)
@@ -1593,7 +2077,7 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
/************************* Operator Search Template **************************/
-static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
+static void operator_call_cb(bContext *C, void *arg1, void *arg2)
{
wmOperatorType *ot= arg2;
@@ -1601,14 +2085,14 @@ static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
}
-static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+static void operator_search_cb(const bContext *C, void *arg, char *str, uiSearchItems *items)
{
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
if(BLI_strcasestr(ot->name, str)) {
- if(ot->poll==NULL || ot->poll((bContext *)C)) {
+ if(WM_operator_poll((bContext*)C, ot)) {
char name[256];
int len= strlen(ot->name);
@@ -1682,17 +2166,4 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
}
-/************************* Image Template **************************/
-
-#include "ED_image.h"
-
-void uiTemplateTextureImage(uiLayout *layout, bContext *C, Tex *tex)
-{
- uiBlock *block;
-
- if(tex) {
- block= uiLayoutFreeBlock(layout);
- ED_image_uiblock_panel(C, block, &tex->ima, &tex->iuser, 0, 0);
- }
-}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 63f81c9e46c..1d56ed4fb6a 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -23,30 +23,13 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <math.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-
-#include "DNA_action_types.h"
-#include "DNA_color_types.h"
-#include "DNA_listBase.h"
-#include "DNA_material_types.h"
#include "DNA_object_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "BLI_blenlib.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_idprop.h"
-#include "BKE_icons.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -54,18 +37,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "ED_screen.h"
-#include "ED_util.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "interface_intern.h"
-
-#define DEF_BUT_WIDTH 150
-#define DEF_ICON_BUT_WIDTH 20
-#define DEF_BUT_HEIGHT 20
-
/*************************** RNA Utilities ******************************/
uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2)
@@ -102,7 +73,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
if(RNA_property_subtype(prop) == PROP_COLOR)
but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
}
- else if(RNA_property_subtype(prop) == PROP_PERCENTAGE)
+ else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR)
but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
else
but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
@@ -176,989 +147,38 @@ void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int
else
col= NULL;
- /* temp hack to show normal button for spin/screw */
- if(strcmp(name, "Axis")==0) {
- uiDefButR(uiLayoutGetBlock(col), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
- }
- else uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0);
+ uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0);
}
RNA_STRUCT_END;
}
/***************************** ID Utilities *******************************/
-/* note, C code version, will be replaced with version in interface_templates.c */
-
-typedef struct uiIDPoinParams {
- uiIDPoinFunc func;
- ListBase *lb;
- ID *id;
- short id_code;
- short browsenr;
-} uiIDPoinParams;
-
-static void idpoin_cb(bContext *C, void *arg_params, void *arg_event)
-{
- uiIDPoinParams *params= (uiIDPoinParams*)arg_params;
- ListBase *lb= params->lb;
- uiIDPoinFunc func= params->func;
- ID *id= params->id, *idtest;
- int nr, event= GET_INT_FROM_POINTER(arg_event);
-
- if(event == UI_ID_BROWSE && params->browsenr == 32767)
- event= UI_ID_ADD_NEW;
- else if(event == UI_ID_BROWSE && params->browsenr == 32766)
- event= UI_ID_OPEN;
-
- switch(event) {
- case UI_ID_RENAME:
- if(id) test_idbutton(id->name+2);
- else return;
- break;
- case UI_ID_BROWSE: {
- /* ID can be NULL, if nothing was assigned yet */
- if(lb->first==NULL) return;
-
- if(params->browsenr== -2) {
- /* XXX implement or find a replacement (ID can be NULL!)
- * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &params->browsenr, do_global_buttons); */
- return;
- }
- if(params->browsenr < 0)
- return;
-
- for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
- if(nr==params->browsenr) {
- if(id == idtest)
- return;
-
- id= idtest;
-
- break;
- }
- }
- break;
- }
- case UI_ID_DELETE:
- id= NULL;
- break;
- case UI_ID_FAKE_USER:
- if(id) {
- if(id->flag & LIB_FAKEUSER) id->us++;
- else id->us--;
- }
- else return;
- break;
- case UI_ID_PIN:
- break;
- case UI_ID_ADD_NEW:
- break;
- case UI_ID_OPEN:
- break;
- case UI_ID_ALONE:
- if(!id || id->us < 1)
- return;
- break;
- case UI_ID_LOCAL:
- if(!id || id->us < 1)
- return;
- break;
- case UI_ID_AUTO_NAME:
- break;
- }
-
- if(func)
- func(C, id, event);
-}
-
-/* ***************************** ID Search browse menu ********************** */
-
-static void id_search_call_cb(struct bContext *C, void *arg_params, void *item)
-{
- uiIDPoinParams *params= (uiIDPoinParams*)arg_params;
-
- if(item && params->func)
- params->func(C, item, UI_ID_BROWSE);
-
-}
-
-static void id_search_cb(const struct bContext *C, void *arg_params, char *str, uiSearchItems *items)
-{
- uiIDPoinParams *params= (uiIDPoinParams*)arg_params;
- ID *id;
-
- for(id= params->lb->first; id; id= id->next) {
- int iconid= 0;
-
-
- /* icon */
- switch(GS(id->name))
- {
- case ID_MA: /* fall through */
- case ID_TE: /* fall through */
- case ID_IM: /* fall through */
- case ID_WO: /* fall through */
- case ID_LA: /* fall through */
- iconid= BKE_icon_getid(id);
- break;
- default:
- break;
- }
-
- if(BLI_strcasestr(id->name+2, str)) {
- if(0==uiSearchItemAdd(items, id->name+2, id, iconid))
- break;
- }
- }
-}
-
-static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_params)
-{
- static char search[256];
- static uiIDPoinParams params;
- wmEvent event;
- wmWindow *win= CTX_wm_window(C);
- uiBlock *block;
- uiBut *but;
-
- /* clear initial search string, then all items show */
- search[0]= 0;
- /* params is malloced, can be freed by parent button */
- params= *((uiIDPoinParams*)arg_params);
-
- block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
-
- /* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
-
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
- uiButSetSearchFunc(but, id_search_cb, &params, id_search_call_cb, NULL);
-
- uiBoundsBlock(block, 6);
- uiBlockSetDirection(block, UI_DOWN);
- uiEndBlock(C, block);
-
- event= *(win->eventstate); /* XXX huh huh? make api call */
- event.type= EVT_BUT_OPEN;
- event.val= KM_PRESS;
- event.customdata= but;
- event.customdatafree= FALSE;
- wm_event_add(win, &event);
-
- return block;
-}
-
-/* ****************** */
-
-int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID *id, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events)
-{
- uiBut *but;
- uiIDPoinParams *params, *dup_params;
- char str1[10];
- int len, add_addbutton=0;
-
- /* setup struct that we will pass on with the buttons */
- params= MEM_callocN(sizeof(uiIDPoinParams), "uiIDPoinParams");
- params->lb= wich_libbase(bmain, id_code);
- params->id= id;
- params->id_code= id_code;
- params->func= func;
-
- /* create buttons */
- uiBlockBeginAlign(block);
-
- /* XXX solve?
- if(id && id->us>1)
- uiBlockSetCol(block, TH_BUT_SETTING1);
-
- if((events & UI_ID_PIN) && *pin_p)
- uiBlockSetCol(block, TH_BUT_SETTING2);
- */
-
- /* pin button */
- if(id && (events & UI_ID_PIN)) {
- but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), ICON_KEY_DEHLT, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_PIN));
- x+= DEF_ICON_BUT_WIDTH;
- }
-
- /* browse menu */
- if(events & UI_ID_BROWSE) {
- uiDefBlockButN(block, id_search_menu, MEM_dupallocN(params), "", x, y, DEF_ICON_BUT_WIDTH, DEF_BUT_HEIGHT, "Browse ID data");
- x+= DEF_ICON_BUT_WIDTH;
- }
-
-
-
- /* text button with name */
- if(id) {
- /* XXX solve?
- if(id->us > 1)
- uiBlockSetCol(block, TH_BUT_SETTING1);
- */
- /* pinned data?
- if((events & UI_ID_PIN) && *pin_p)
- uiBlockSetCol(block, TH_BUT_SETTING2);
- */
- /* redalert overrides pin color
- if(id->us<=0)
- uiBlockSetCol(block, TH_REDALERT);
- */
- uiBlockSetButLock(block, id->lib!=0, "Can't edit external libdata");
-
- /* name button */
- text_idbutton(id, str1);
-
- if(GS(id->name)==ID_IP) len= 110;
- else if((y) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib)
- else if(y) len= 140; // comes from button panel
- else len= 120;
-
- but= uiDefBut(block, TEX, 0, str1,x, y, (short)len, DEF_BUT_HEIGHT, id->name+2, 0.0, 21.0, 0, 0, "Displays current Datablock name. Click to change.");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_RENAME));
-
- x+= len;
-
- uiBlockClearButLock(block);
-
- /* lib make local button */
- if(id->lib) {
- if(id->flag & LIB_INDIRECT) uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_DATALIB */,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Indirect Library Datablock. Cannot change.");
- else {
- but= uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_PARLIB */, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0,
- (events & UI_ID_LOCAL)? "Direct linked Library Datablock. Click to make local.": "Direct linked Library Datablock, cannot make local.");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
- }
-
- x+= DEF_ICON_BUT_WIDTH;
- }
-
- /* number of users / make local button */
- if((events & UI_ID_ALONE) && id->us>1) {
- int butwidth;
-
- uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't make pinned data single-user");
-
- sprintf(str1, "%d", id->us);
- butwidth= (id->us<10)? DEF_ICON_BUT_WIDTH: DEF_ICON_BUT_WIDTH+10;
-
- but= uiDefBut(block, BUT, 0, str1, x, y, butwidth, DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
- x+= butwidth;
-
- uiBlockClearButLock(block);
- }
-
- /* add button */
- if(events & UI_ID_ADD_NEW) {
- uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data");
- if(parid && parid->lib);
- else {
- dup_params= MEM_dupallocN(params);
- but= uiDefIconBut(block, BUT, 0, ICON_ZOOMIN, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
- x+= DEF_ICON_BUT_WIDTH;
- }
-
- uiBlockClearButLock(block);
- }
-
- /* delete button */
- if(events & UI_ID_DELETE) {
- uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data");
- if(parid && parid->lib);
- else {
- but= uiDefIconBut(block, BUT, 0, ICON_X, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Deletes link to this Datablock");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_DELETE));
- x+= DEF_ICON_BUT_WIDTH;
- }
-
- uiBlockClearButLock(block);
- }
-
- /* auto name button */
- if(events & UI_ID_AUTO_NAME) {
- if(parid && parid->lib);
- else {
- but= uiDefIconBut(block, BUT, 0, ICON_AUTO,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Generates an automatic name");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_AUTO_NAME));
- x+= DEF_ICON_BUT_WIDTH;
- }
- }
-
- /* fake user button */
- if(events & UI_ID_FAKE_USER) {
- but= uiDefButBitS(block, TOG, LIB_FAKEUSER, 0, "F", x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &id->flag, 0, 0, 0, 0, "Saves this datablock even if it has no users");
- uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_FAKE_USER));
- x+= DEF_ICON_BUT_WIDTH;
- }
- }
- /* add new button */
- else if(add_addbutton) {
- if(parid) uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
- dup_params= MEM_dupallocN(params);
- but= uiDefButS(block, TOG, 0, "Add New", x, y, 110, DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block");
- uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_ADD_NEW));
- x+= 110;
- }
-
- uiBlockEndAlign(block);
-
- MEM_freeN(params);
-
- return x;
-}
-
-/* ****************************** default button callbacks ******************* */
-/* ************ LEGACY WARNING, only to get things work with 2.48 code! ****** */
-
-void test_idbutton_cb(struct bContext *C, void *namev, void *arg2)
-{
- char *name= namev;
-
- test_idbutton(name+2);
-}
-
-
-void test_scriptpoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- id= CTX_data_main(C)->text.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-void test_actionpoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- id= CTX_data_main(C)->action.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- id_us_plus(id);
- *idpp= id;
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-
-void test_obpoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
-// XXX if(idpp == (ID **)&(emptytex.object)) {
-// error("You must add a texture first");
-// *idpp= 0;
-// return;
-// }
-
- id= CTX_data_main(C)->object.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_lib_extern(id); /* checks lib data, sets correct flag for saving then */
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-/* tests for an object of type OB_MESH */
-void test_meshobpoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- id = CTX_data_main(C)->object.first;
- while(id) {
- Object *ob = (Object *)id;
- if(ob->type == OB_MESH && strcmp(name, id->name + 2) == 0) {
- *idpp = id;
- /* checks lib data, sets correct flag for saving then */
- id_lib_extern(id);
- return;
- }
- id = id->next;
- }
- *idpp = NULL;
-}
-
-void test_meshpoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- if( *idpp ) (*idpp)->us--;
-
- id= CTX_data_main(C)->mesh.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_us_plus(id);
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-void test_matpoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- if( *idpp ) (*idpp)->us--;
-
- id= CTX_data_main(C)->mat.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_us_plus(id);
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-void test_scenepoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- if( *idpp ) (*idpp)->us--;
-
- id= CTX_data_main(C)->scene.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_us_plus(id);
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-void test_grouppoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- if( *idpp ) (*idpp)->us--;
-
- id= CTX_data_main(C)->group.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_us_plus(id);
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-void test_texpoin_but(struct bContext *C, char *name, ID **idpp)
+int uiIconFromID(ID *id)
{
- ID *id;
-
- if( *idpp ) (*idpp)->us--;
-
- id= CTX_data_main(C)->tex.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_us_plus(id);
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-void test_imapoin_but(struct bContext *C, char *name, ID **idpp)
-{
- ID *id;
-
- if( *idpp ) (*idpp)->us--;
-
- id= CTX_data_main(C)->image.first;
- while(id) {
- if( strcmp(name, id->name+2)==0 ) {
- *idpp= id;
- id_us_plus(id);
- return;
- }
- id= id->next;
- }
- *idpp= NULL;
-}
-
-/* autocomplete callback for buttons */
-void autocomplete_bone(struct bContext *C, char *str, void *arg_v)
-{
- Object *ob= (Object *)arg_v;
-
- if(ob==NULL || ob->pose==NULL) return;
-
- /* search if str matches the beginning of name */
- if(str[0]) {
- AutoComplete *autocpl= autocomplete_begin(str, 32);
- bPoseChannel *pchan;
-
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
- autocomplete_do_name(autocpl, pchan->name);
-
- autocomplete_end(autocpl, str);
- }
-}
-
-/* autocomplete callback for buttons */
-void autocomplete_vgroup(struct bContext *C, char *str, void *arg_v)
-{
- Object *ob= (Object *)arg_v;
-
- if(ob==NULL) return;
-
- /* search if str matches the beginning of a name */
- if(str[0]) {
- AutoComplete *autocpl= autocomplete_begin(str, 32);
- bDeformGroup *dg;
-
- for(dg= ob->defbase.first; dg; dg= dg->next)
- if(dg->name!=str)
- autocomplete_do_name(autocpl, dg->name);
-
- autocomplete_end(autocpl, str);
- }
-}
-
-
-/* ----------- custom button group ---------------------- */
-
-static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *unused)
-{
- CurveMapping *cumap = cumap_v;
- float d;
-
- /* we allow 20 times zoom */
- if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
- d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin);
- cumap->curr.xmin+= d;
- cumap->curr.xmax-= d;
- d= 0.1154f*(cumap->curr.ymax - cumap->curr.ymin);
- cumap->curr.ymin+= d;
- cumap->curr.ymax-= d;
- }
-}
-
-static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *unused)
-{
- CurveMapping *cumap = cumap_v;
- float d, d1;
-
- /* we allow 20 times zoom, but dont view outside clip */
- if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
- d= d1= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
-
- if(cumap->flag & CUMA_DO_CLIP)
- if(cumap->curr.xmin-d < cumap->clipr.xmin)
- d1= cumap->curr.xmin - cumap->clipr.xmin;
- cumap->curr.xmin-= d1;
-
- d1= d;
- if(cumap->flag & CUMA_DO_CLIP)
- if(cumap->curr.xmax+d > cumap->clipr.xmax)
- d1= -cumap->curr.xmax + cumap->clipr.xmax;
- cumap->curr.xmax+= d1;
-
- d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin);
-
- if(cumap->flag & CUMA_DO_CLIP)
- if(cumap->curr.ymin-d < cumap->clipr.ymin)
- d1= cumap->curr.ymin - cumap->clipr.ymin;
- cumap->curr.ymin-= d1;
-
- d1= d;
- if(cumap->flag & CUMA_DO_CLIP)
- if(cumap->curr.ymax+d > cumap->clipr.ymax)
- d1= -cumap->curr.ymax + cumap->clipr.ymax;
- cumap->curr.ymax+= d1;
- }
-}
-
-static void curvemap_buttons_setclip(bContext *C, void *cumap_v, void *unused)
-{
- CurveMapping *cumap = cumap_v;
-
- curvemapping_changed(cumap, 0);
-}
-
-static void curvemap_buttons_delete(bContext *C, void *cumap_v, void *unused)
-{
- CurveMapping *cumap = cumap_v;
-
- curvemap_remove(cumap->cm+cumap->cur, SELECT);
- curvemapping_changed(cumap, 0);
-}
-
-/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
-static uiBlock *curvemap_clipping_func(struct bContext *C, struct ARegion *ar, void *cumap_v)
-{
- CurveMapping *cumap = cumap_v;
- uiBlock *block;
- uiBut *bt;
-
- block= uiBeginBlock(C, ar, "curvemap_clipping_func", UI_EMBOSS);
-
- /* use this for a fake extra empy space around the buttons */
- uiDefBut(block, LABEL, 0, "", -4, 16, 128, 106, NULL, 0, 0, 0, 0, "");
-
- bt= uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, "Use Clipping",
- 0,100,120,18, &cumap->flag, 0.0, 0.0, 10, 0, "");
- uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, 0, "Min X ", 0,74,120,18, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, "");
- uiDefButF(block, NUM, 0, "Min Y ", 0,56,120,18, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, "");
- uiDefButF(block, NUM, 0, "Max X ", 0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "Max Y ", 0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, "");
-
- uiBlockSetDirection(block, UI_RIGHT);
-
- uiEndBlock(C, block);
- return block;
-}
-
-
-static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
-{
- CurveMapping *cumap = cumap_v;
- CurveMap *cuma= cumap->cm+cumap->cur;
-
- switch(event) {
- case 0:
- curvemap_reset(cuma, &cumap->clipr);
- curvemapping_changed(cumap, 0);
- break;
- case 1:
- cumap->curr= cumap->clipr;
- break;
- case 2: /* set vector */
- curvemap_sethandle(cuma, 1);
- curvemapping_changed(cumap, 0);
- break;
- case 3: /* set auto */
- curvemap_sethandle(cuma, 0);
- curvemapping_changed(cumap, 0);
- break;
- case 4: /* extend horiz */
- cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
- curvemapping_changed(cumap, 0);
- break;
- case 5: /* extend extrapolate */
- cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
- curvemapping_changed(cumap, 0);
- break;
- }
- ED_region_tag_redraw(CTX_wm_region(C));
-}
-
-static uiBlock *curvemap_tools_func(struct bContext *C, struct ARegion *ar, void *cumap_v)
-{
- uiBlock *block;
- short yco= 0, menuwidth=120;
-
- block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS);
- uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset View", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Horizontal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Extrapolated", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Curve", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
-
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 50);
-
- uiEndBlock(C, block);
- return block;
-}
-
-/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
-void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short event, short redraw, rctf *rect)
-{
- uiBut *bt;
- float dx, fy= rect->ymax-18.0f;
- int icon;
- short xco, yco;
-
- yco= (short)(rect->ymax-18.0f);
-
- /* curve choice options + tools/settings, 8 icons + spacer */
- dx= (rect->xmax-rect->xmin)/(9.0f);
-
- uiBlockBeginAlign(block);
- if(labeltype=='v') { /* vector */
- xco= (short)rect->xmin;
- if(cumap->cm[0].curve)
- uiDefButI(block, ROW, redraw, "X", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- xco= (short)(rect->xmin+1.0f*dx);
- if(cumap->cm[1].curve)
- uiDefButI(block, ROW, redraw, "Y", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- xco= (short)(rect->xmin+2.0f*dx);
- if(cumap->cm[2].curve)
- uiDefButI(block, ROW, redraw, "Z", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- }
- else if(labeltype=='c') { /* color */
- xco= (short)rect->xmin;
- if(cumap->cm[3].curve)
- uiDefButI(block, ROW, redraw, "C", xco, yco+2, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
- xco= (short)(rect->xmin+1.0f*dx);
- if(cumap->cm[0].curve)
- uiDefButI(block, ROW, redraw, "R", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- xco= (short)(rect->xmin+2.0f*dx);
- if(cumap->cm[1].curve)
- uiDefButI(block, ROW, redraw, "G", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- xco= (short)(rect->xmin+3.0f*dx);
- if(cumap->cm[2].curve)
- uiDefButI(block, ROW, redraw, "B", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- }
- /* else no channels ! */
- uiBlockEndAlign(block);
-
- xco= (short)(rect->xmin+4.5f*dx);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMIN, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in");
- uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL);
-
- xco= (short)(rect->xmin+5.25f*dx);
- bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMOUT, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out");
- uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
-
- xco= (short)(rect->xmin+6.0f*dx);
- bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, xco, yco, dx, 18, "Tools");
-
- xco= (short)(rect->xmin+7.0f*dx);
- if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT;
- bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, event, icon, xco, yco, dx, 18, "Clipping Options");
-
- xco= (short)(rect->xmin+8.0f*dx);
- bt= uiDefIconBut(block, BUT, event, ICON_X, xco, yco, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points");
- uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- uiDefBut(block, BUT_CURVE, event, "",
- rect->xmin, rect->ymin, rect->xmax-rect->xmin, fy-rect->ymin,
- cumap, 0.0f, 1.0f, 0, 0, "");
-}
-
-/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
-void curvemap_layout(uiLayout *layout, CurveMapping *cumap, char labeltype, short event, short redraw, rctf *rect)
-{
- uiLayout *row;
- uiBlock *block;
- uiBut *bt;
- float dx, fy= rect->ymax-18.0f;
- int icon;
-
- block= uiLayoutGetBlock(layout);
-
- /* curve choice options + tools/settings, 8 icons + spacer */
- dx= UI_UNIT_X;
-
- row= uiLayoutRow(layout, 0);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
-
- if(labeltype=='v') { /* vector */
- row= uiLayoutRow(layout, 1);
-
- if(cumap->cm[0].curve)
- uiDefButI(block, ROW, redraw, "X", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- if(cumap->cm[1].curve)
- uiDefButI(block, ROW, redraw, "Y", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- if(cumap->cm[2].curve)
- uiDefButI(block, ROW, redraw, "Z", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- }
- else if(labeltype=='c') { /* color */
- row= uiLayoutRow(layout, 1);
-
- if(cumap->cm[3].curve)
- uiDefButI(block, ROW, redraw, "C", 0, 0, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
- if(cumap->cm[0].curve)
- uiDefButI(block, ROW, redraw, "R", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- if(cumap->cm[1].curve)
- uiDefButI(block, ROW, redraw, "G", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- if(cumap->cm[2].curve)
- uiDefButI(block, ROW, redraw, "B", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- }
-
- row= uiLayoutRow(row, 1);
+ Object *ob;
+ PointerRNA ptr;
+ short idcode;
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMIN, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in");
- uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL);
-
- bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMOUT, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out");
- uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
-
- bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, 0, 0, dx, 18, "Tools");
-
- if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT;
- bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, event, icon, 0, 0, dx, 18, "Clipping Options");
+ if(id==NULL)
+ return 0;
- bt= uiDefIconBut(block, BUT, event, ICON_X, 0, 0, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points");
- uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- row= uiLayoutRow(layout, 0);
- uiDefBut(block, BUT_CURVE, event, "",
- rect->xmin, rect->ymin, rect->xmax-rect->xmin, fy-rect->ymin,
- cumap, 0.0f, 1.0f, 0, 0, "");
-}
-
-
-#define B_BANDCOL 1
-
-static int vergcband(const void *a1, const void *a2)
-{
- const CBData *x1=a1, *x2=a2;
-
- if( x1->pos > x2->pos ) return 1;
- else if( x1->pos < x2->pos) return -1;
- return 0;
-}
-
-static void colorband_pos_cb(bContext *C, void *coba_v, void *unused_v)
-{
- ColorBand *coba= coba_v;
- int a;
-
- if(coba->tot<2) return;
-
- for(a=0; a<coba->tot; a++) coba->data[a].cur= a;
- qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
- for(a=0; a<coba->tot; a++) {
- if(coba->data[a].cur==coba->cur) {
- // XXX if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */
- coba->cur= a;
- break;
- }
- }
+ idcode= GS(id->name);
- WM_event_add_notifier(C, NC_TEXTURE, NULL);
-}
-
-static void colorband_cb(bContext *C, void *coba_v, void *unused_v)
-{
- WM_event_add_notifier(C, NC_TEXTURE, NULL);
-}
+ /* exception for objects */
+ if(idcode == ID_OB) {
+ ob= (Object*)id;
-static void colorband_add_cb(bContext *C, void *coba_v, void *unused_v)
-{
- ColorBand *coba= coba_v;
-
- if(coba->tot < MAXCOLORBAND-1) coba->tot++;
- coba->cur= coba->tot-1;
-
- colorband_pos_cb(C, coba, NULL);
- ED_undo_push(C, "Add colorband");
- WM_event_add_notifier(C, NC_TEXTURE, NULL);
-}
-
-static void colorband_del_cb(bContext *C, void *coba_v, void *unused_v)
-{
- ColorBand *coba= coba_v;
- int a;
-
- if(coba->tot<2) return;
-
- for(a=coba->cur; a<coba->tot; a++) {
- coba->data[a]= coba->data[a+1];
+ if(ob->type == OB_EMPTY)
+ return ICON_EMPTY_DATA;
+ else
+ return uiIconFromID(ob->data);
}
- if(coba->cur) coba->cur--;
- coba->tot--;
-
- ED_undo_push(C, "Delete colorband");
- // XXX BIF_preview_changed(ID_TE);
- WM_event_add_notifier(C, NC_TEXTURE, NULL);
-}
-
-
-/* offset aligns from bottom, standard width 300, height 115 */
-static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw)
-{
- CBData *cbd;
- uiBut *bt;
-
- if(coba==NULL) return;
-
- bt= uiDefBut(block, BUT, redraw, "Add", 0+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Add a new color stop to the colorband");
- uiButSetFunc(bt, colorband_add_cb, coba, NULL);
- bt= uiDefBut(block, BUT, redraw, "Delete", 60+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Delete the active position");
- uiDefButS(block, NUM, redraw, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Choose active color stop");
-
- uiButSetFunc(bt, colorband_del_cb, coba, NULL);
-
- bt= uiDefButS(block, MENU, redraw, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
- 210+xoffs, 100+yoffs, 90, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
- uiButSetFunc(bt, colorband_cb, coba, NULL);
- uiBlockEndAlign(block);
- bt= uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, "");
- uiButSetFunc(bt, colorband_cb, coba, NULL);
-
- cbd= coba->data + coba->cur;
-
- bt= uiDefButF(block, NUM, redraw, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop");
- uiButSetFunc(bt, colorband_pos_cb, coba, NULL);
- bt= uiDefButF(block, COL, redraw, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
- uiButSetFunc(bt, colorband_cb, coba, NULL);
- bt= uiDefButF(block, NUMSLI, redraw, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop");
- uiButSetFunc(bt, colorband_cb, coba, NULL);
+ /* otherwise get it through RNA, creating the pointer
+ will set the right type, also with subclassing */
+ RNA_id_pointer_create(id, &ptr);
-}
-
-static void colorband_buttons_small(uiBlock *block, ColorBand *coba, rctf *butr, int event)
-{
- CBData *cbd;
- uiBut *bt;
- float unit= (butr->xmax-butr->xmin)/14.0f;
- float xs= butr->xmin;
-
- cbd= coba->data + coba->cur;
-
-
- bt= uiDefBut(block, BUT, event, "Add", xs,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband");
- uiButSetFunc(bt, colorband_add_cb, coba, NULL);
- bt= uiDefBut(block, BUT, event, "Delete", xs+2.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Delete the active position");
- uiButSetFunc(bt, colorband_del_cb, coba, NULL);
-
- uiDefButF(block, COL, event, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
- uiDefButF(block, NUMSLI, event, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop");
-
- uiDefButS(block, MENU, event, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
- xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
-
- uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, "");
- uiBlockEndAlign(block);
-}
-
-void colorband_buttons(uiBlock *block, ColorBand *coba, rctf *butr, int small)
-{
- if(small)
- colorband_buttons_small(block, coba, butr, 0);
- else
- colorband_buttons_large(block, coba, 0, 0, 0);
+ return (ptr.type)? RNA_struct_ui_icon(ptr.type): 0;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 2385b5ad15c..007a57fb67a 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -129,17 +129,21 @@ static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820},
{0.219306 , -0.238501}, {-0.393286 , -0.110949}, {-0.024699 , 0.013908},
{0.343805 , 0.147431}, {-0.272855 , 0.269918}, {0.095909 , 0.388710}};
-static float num_tria_vert[19][2]= {
+static float num_tria_vert[3][2]= {
+{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353}};
+
+static int num_tria_face[1][3]= {
+{0, 1, 2}};
+
+static float scroll_circle_vert[16][2]= {
{0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107},
{-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107},
{-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107},
-{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107},
-{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.729843, -0.008353}};
+{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}};
-static int num_tria_face[19][3]= {
-{13, 14, 18}, {17, 5, 6}, {12, 13, 18}, {17, 6, 7}, {15, 18, 14}, {16, 4, 5}, {16, 5, 17}, {18, 11, 12},
-{18, 17, 10}, {18, 10, 11}, {17, 9, 10}, {15, 0, 18}, {18, 0, 16}, {3, 4, 16}, {8, 9, 17}, {8, 17, 7},
-{2, 3, 16}, {1, 2, 16}, {16, 0, 1}};
+static int scroll_circle_face[14][3]= {
+{0, 1, 2}, {2, 0, 3}, {3, 0, 15}, {3, 15, 4}, {4, 15, 14}, {4, 14, 5}, {5, 14, 13}, {5, 13, 6},
+{6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9}};
static float menu_tria_vert[6][2]= {
{-0.41, 0.16}, {0.41, 0.16}, {0, 0.82},
@@ -451,15 +455,50 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha
i2=0; i1= 1;
}
- for(a=0; a<19; a++) {
+ for(a=0; a<3; a++) {
tria->vec[a][0]= sizex*num_tria_vert[a][i1] + centx;
tria->vec[a][1]= sizey*num_tria_vert[a][i2] + centy;
}
- tria->tot= 19;
+ tria->tot= 1;
tria->index= num_tria_face;
}
+static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+{
+ float centx, centy, sizex, sizey, minsize;
+ int a, i1=0, i2=1;
+
+ minsize= MIN2(rect->xmax-rect->xmin, rect->ymax-rect->ymin);
+
+ /* center position and size */
+ centx= (float)rect->xmin + 0.5f*minsize;
+ centy= (float)rect->ymin + 0.5f*minsize;
+ sizex= sizey= -0.5f*triasize*minsize;
+
+ if(where=='r') {
+ centx= (float)rect->xmax - 0.5f*minsize;
+ sizex= -sizex;
+ }
+ else if(where=='t') {
+ centy= (float)rect->ymax - 0.5f*minsize;
+ sizey= -sizey;
+ i2=0; i1= 1;
+ }
+ else if(where=='b') {
+ sizex= -sizex;
+ i2=0; i1= 1;
+ }
+
+ for(a=0; a<16; a++) {
+ tria->vec[a][0]= sizex*scroll_circle_vert[a][i1] + centx;
+ tria->vec[a][1]= sizey*scroll_circle_vert[a][i2] + centy;
+ }
+
+ tria->tot= 14;
+ tria->index= scroll_circle_face;
+}
+
static void widget_trias_draw(uiWidgetTrias *tria)
{
int a;
@@ -658,7 +697,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
/* icons have been standardized... and this call draws in untransformed coordinates */
#define ICON_HEIGHT 16.0f
-static void widget_draw_icon(uiBut *but, BIFIconID icon, int blend, rcti *rect)
+static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect)
{
int xs=0, ys=0;
float aspect, height;
@@ -685,7 +724,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, int blend, rcti *rect)
if ELEM4(but->type, TOG, ROW, TOGN, LISTROW) {
if(but->flag & UI_SELECT);
else if(but->flag & UI_ACTIVE);
- else blend= -60;
+ else alpha= 0.5f;
}
glEnable(GL_BLEND);
@@ -718,14 +757,14 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, int blend, rcti *rect)
ys= (rect->ymin+rect->ymax- height)/2;
}
- UI_icon_draw_aspect_blended(xs, ys, icon, aspect, blend);
+ UI_icon_draw_aspect(xs, ys, icon, aspect, alpha);
}
if(but->flag & UI_ICON_SUBMENU) {
xs= rect->xmax-17;
ys= (rect->ymin+rect->ymax- height)/2;
- UI_icon_draw_aspect_blended(xs, ys, ICON_RIGHTARROW_THIN, aspect, blend);
+ UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha);
}
glDisable(GL_BLEND);
@@ -734,7 +773,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, int blend, rcti *rect)
/* sets but->ofs to make sure text is correctly visible */
static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
{
- int okwidth= rect->xmax-rect->xmin;
+ int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10;
+ int okwidth= rect->xmax-rect->xmin - border;
/* need to set this first */
uiStyleFontSet(fstyle);
@@ -803,11 +843,8 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
but->drawstr[selend_tmp]= ch;
- /* if at pos 0, leave a bit more to the left */
- t= (pos == 0)? 0: 1;
-
glColor3ubv((unsigned char*)wcol->item);
- glRects(rect->xmin+selsta_draw+1, rect->ymin+2, rect->xmin+selwidth_draw+1, rect->ymax-2);
+ glRects(rect->xmin+selsta_draw, rect->ymin+2, rect->xmin+selwidth_draw, rect->ymax-2);
}
} else {
/* text cursor */
@@ -822,9 +859,6 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
but->drawstr[pos]= ch;
}
- /* if at pos 0, leave a bit more to the left */
- t += (pos == 0)? 0: 1;
-
glColor3ub(255,0,0);
glRects(rect->xmin+t, rect->ymin+2, rect->xmin+t+2, rect->ymax-2);
}
@@ -868,7 +902,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
/* check for button text label */
if (but->type == ICONTEXTROW) {
- widget_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0, rect);
+ widget_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 1.0f, rect);
}
else {
@@ -879,14 +913,14 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if(but->pointype==INT)
dualset= BTST( *(((int *)but->poin)+1), but->bitnr);
- widget_draw_icon(but, ICON_DOT, dualset?0:-100, rect);
+ widget_draw_icon(but, ICON_DOT, dualset?1.0f:0.25f, rect);
}
/* If there's an icon too (made with uiDefIconTextBut) then draw the icon
and offset the text label to accomodate it */
if (but->flag & UI_HAS_ICON) {
- widget_draw_icon(but, but->icon+but->iconadd, 0, rect);
+ widget_draw_icon(but, but->icon+but->iconadd, 1.0f, rect);
rect->xmin += UI_icon_get_width(but->icon+but->iconadd);
@@ -1736,12 +1770,12 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat
wcol->item[3]= 255;
if(horizontal) {
- widget_num_tria(&wtb.tria1, slider, 0.6f, 'l');
- widget_num_tria(&wtb.tria2, slider, 0.6f, 'r');
+ widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'l');
+ widget_scroll_circle(&wtb.tria2, slider, 0.6f, 'r');
}
else {
- widget_num_tria(&wtb.tria1, slider, 0.6f, 'b');
- widget_num_tria(&wtb.tria2, slider, 0.6f, 't');
+ widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'b');
+ widget_scroll_circle(&wtb.tria2, slider, 0.6f, 't');
}
}
widgetbase_draw(&wtb, wcol);
@@ -1939,7 +1973,19 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int state, int roun
/* text space */
rect->xmax -= (rect->ymax-rect->ymin);
+}
+
+static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+ uiWidgetBase wtb;
+ widget_init(&wtb);
+
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+
+ /* decoration */
+ widgetbase_draw(&wtb, wcol);
}
static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
@@ -2175,13 +2221,17 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
wt.wcol_theme= &btheme->tui.wcol_menu;
wt.draw= widget_menubut;
break;
+
+ case UI_WTYPE_MENU_ICON_RADIO:
+ wt.wcol_theme= &btheme->tui.wcol_menu;
+ wt.draw= widget_menuiconbut;
+ break;
case UI_WTYPE_MENU_POINTER_LINK:
wt.wcol_theme= &btheme->tui.wcol_menu;
wt.draw= widget_menubut;
break;
-
case UI_WTYPE_PULLDOWN:
wt.wcol_theme= &btheme->tui.wcol_pulldown;
wt.draw= widget_pulldownbut;
@@ -2371,7 +2421,10 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case MENU:
case BLOCK:
case ICONTEXTROW:
- wt= widget_type(UI_WTYPE_MENU_RADIO);
+ if(!but->str[0] && but->icon)
+ wt= widget_type(UI_WTYPE_MENU_ICON_RADIO);
+ else
+ wt= widget_type(UI_WTYPE_MENU_RADIO);
break;
case PULLDOWN:
@@ -2528,7 +2581,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid,
int xs= rect->xmin+4;
int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2;
glEnable(GL_BLEND);
- UI_icon_draw_aspect_blended(xs, ys, iconid, 1.2f, 0); /* XXX scale weak get from fstyle? */
+ UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* 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 c54e09b2b40..87026bd1a5d 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -517,10 +517,12 @@ void ui_theme_init_userdef(void)
/* space file */
/* to have something initialized */
btheme->tfile= btheme->tv3d;
- SETCOL(btheme->tfile.back, 90, 90, 90, 255);
+ SETCOLF(btheme->tfile.back, 0.3, 0.3, 0.3, 1);
+ SETCOLF(btheme->tfile.panel, 0.3, 0.3, 0.3, 1);
+ SETCOLF(btheme->tfile.list, 0.4, 0.4, 0.4, 1);
SETCOL(btheme->tfile.text, 250, 250, 250, 255);
SETCOL(btheme->tfile.text_hi, 15, 15, 15, 255);
- SETCOL(btheme->tfile.panel, 180, 180, 180, 255); // bookmark/ui regions
+ SETCOL(btheme->tfile.panel, 145, 145, 145, 255); // bookmark/ui regions
SETCOL(btheme->tfile.active, 130, 130, 130, 255); // selected files
SETCOL(btheme->tfile.hilite, 255, 140, 25, 255); // selected files
@@ -604,11 +606,11 @@ void ui_theme_init_userdef(void)
/* space node, re-uses syntax color storage */
btheme->tnode= btheme->tv3d;
SETCOL(btheme->tnode.edge_select, 255, 255, 255, 255);
- SETCOL(btheme->tnode.syntaxl, 150, 150, 150, 255); /* TH_NODE, backdrop */
- SETCOL(btheme->tnode.syntaxn, 129, 131, 144, 255); /* in/output */
- SETCOL(btheme->tnode.syntaxb, 127,127,127, 255); /* operator */
- SETCOL(btheme->tnode.syntaxv, 142, 138, 145, 255); /* generator */
- SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255); /* group */
+ SETCOL(btheme->tnode.syntaxl, 155, 155, 155, 160); /* TH_NODE, backdrop */
+ SETCOL(btheme->tnode.syntaxn, 100, 100, 100, 255); /* in/output */
+ SETCOL(btheme->tnode.syntaxb, 108, 105, 111, 255); /* operator */
+ SETCOL(btheme->tnode.syntaxv, 104, 106, 117, 255); /* generator */
+ SETCOL(btheme->tnode.syntaxc, 105, 117, 110, 255); /* group */
/* space logic */
btheme->tlogic= btheme->tv3d;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f9fb7a9306f..f7546e94f86 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -831,6 +831,7 @@ void UI_view2d_totRect_set_resize (View2D *v2d, int width, int height, int resiz
height= abs(height);
/* 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)
@@ -973,8 +974,8 @@ void UI_view2d_view_ortho(const bContext *C, View2D *v2d)
/* XXX brecht: instead of zero at least use a tiny offset, otherwise
* pixel rounding is effectively random due to float inaccuracy */
- xofs= 0.001f;
- yofs= 0.001f;
+ xofs= 0.001f*(v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
+ yofs= 0.001f*(v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
/* apply mask-based adjustments to cur rect (due to scrollers), to eliminate scaling artifacts */
view2d_map_cur_using_mask(v2d, &curmasked);
@@ -1351,7 +1352,7 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
vert= v2d->vert;
hor= v2d->hor;
- /* slider rects smaller than region */
+ /* slider rects need to be smaller than region */
hor.xmin+=4;
hor.xmax-=4;
if (scroll & V2D_SCROLL_BOTTOM)
@@ -1393,13 +1394,24 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
else
scrollers->hor_max= (int)(hor.xmin + (fac2 * scrollsize));
+ /* prevent inverted sliders */
if (scrollers->hor_min > scrollers->hor_max)
scrollers->hor_min= scrollers->hor_max;
+ /* prevent sliders from being too small, and disappearing */
+ if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE) {
+ scrollers->hor_max= scrollers->hor_min + V2D_SCROLLER_HANDLE_SIZE;
+
+ if(scrollers->hor_max > hor.xmax) {
+ scrollers->hor_max= hor.xmax;
+ scrollers->hor_min= MAX2(scrollers->hor_max - V2D_SCROLLER_HANDLE_SIZE, hor.xmin);
+ }
+ }
/* check whether sliders can disappear */
- if(v2d->keeptot)
+ if(v2d->keeptot) {
if(fac1 <= 0.0f && fac2 >= 1.0f)
scrollers->horfull= 1;
+ }
}
/* vertical scrollers */
@@ -1420,13 +1432,24 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
else
scrollers->vert_max= (int)(vert.ymin + (fac2 * scrollsize));
+ /* prevent inverted sliders */
if (scrollers->vert_min > scrollers->vert_max)
scrollers->vert_min= scrollers->vert_max;
+ /* prevent sliders from being too small, and disappearing */
+ if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE) {
+ scrollers->vert_max= scrollers->vert_min + V2D_SCROLLER_HANDLE_SIZE;
+
+ if(scrollers->vert_max > vert.ymax) {
+ scrollers->vert_max= vert.ymax;
+ scrollers->vert_min= MAX2(scrollers->vert_max - V2D_SCROLLER_HANDLE_SIZE, vert.ymin);
+ }
+ }
/* check whether sliders can disappear */
- if(v2d->keeptot)
+ if(v2d->keeptot) {
if(fac1 <= 0.0f && fac2 >= 1.0f)
scrollers->vertfull= 1;
+ }
}
/* grid markings on scrollbars */
@@ -1550,14 +1573,6 @@ static void scroll_printstr(View2DScrollers *scrollers, Scene *scene, float x, f
BLF_draw_default(x, y, 0.0f, str);
}
-/* local defines for scrollers drawing */
- /* radius of scroller 'button' caps */
-#define V2D_SCROLLCAP_RAD 5
- /* shading factor for scroller 'bar' */
-#define V2D_SCROLLBAR_SHADE 0.1f
- /* shading factor for scroller 'button' caps */
-#define V2D_SCROLLCAP_SHADE 0.2f
-
/* Draw scrollbars in the given 2d-region */
void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs)
{
@@ -1571,7 +1586,7 @@ 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= U.themes.first;
uiWidgetColors wcol= btheme->tui.wcol_scroll;
@@ -1584,13 +1599,15 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
slider.ymax= hor.ymax;
state= (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE)?UI_SCROLL_PRESSED:0;
+
+ // TODO: disable this for button regions...
if (!(v2d->keepzoom & V2D_LOCKZOOM_X))
state |= UI_SCROLL_ARROWS;
+
uiWidgetScrollDraw(&wcol, &hor, &slider, state);
}
/* scale indicators */
- // XXX will need to update the font drawing when the new stuff comes in
if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) {
View2DGrid *grid= vs->grid;
float fac, dfac, fac2, val;
@@ -1667,7 +1684,7 @@ 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= U.themes.first;
uiWidgetColors wcol= btheme->tui.wcol_scroll;
@@ -1680,14 +1697,16 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
slider.ymax= vs->vert_max;
state= (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE)?UI_SCROLL_PRESSED:0;
- if (!(v2d->keepzoom & V2D_LOCKZOOM_Y))
+
+ // TODO: disable this for button regions...
+ if (!(v2d->keepzoom & V2D_LOCKZOOM_Y))
state |= UI_SCROLL_ARROWS;
+
uiWidgetScrollDraw(&wcol, &vert, &slider, state);
}
/* scale indiators */
- // XXX will need to update the font drawing when the new stuff comes in
if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) {
View2DGrid *grid= vs->grid;
float fac, dfac, val;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 3e009884dee..0af5a5cac97 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -210,7 +210,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
WM_cursor_modal(window, BC_NSEW_SCROLLCURSOR);
/* add temp handler */
- WM_event_add_modal_handler(C, &window->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -237,7 +237,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case MIDDLEMOUSE:
- if (event->val==0) {
+ if (event->val==KM_RELEASE) {
/* calculate overall delta mouse-movement for redo */
RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
@@ -764,7 +764,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
WM_cursor_modal(window, BC_NSEW_SCROLLCURSOR);
/* add temp handler */
- WM_event_add_modal_handler(C, &window->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -836,7 +836,7 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case MIDDLEMOUSE:
- if (event->val==0) {
+ if (event->val==KM_RELEASE) {
/* for redo, store the overall deltas - need to respect zoom-locks here... */
if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0)
RNA_float_set(op->ptr, "deltax", vzd->dx);
@@ -1244,7 +1244,7 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case LEFTMOUSE:
- if (event->val==0) {
+ if (event->val==KM_RELEASE) {
scroller_activate_exit(C, op);
return OPERATOR_FINISHED;
}
@@ -1292,7 +1292,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
v2d->scroll_ui |= V2D_SCROLL_V_ACTIVE;
/* still ok, so can add */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
else {
@@ -1409,7 +1409,7 @@ void ui_view2d_operatortypes(void)
void UI_view2d_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "View2D", 0, 0);
/* pan/scroll */
WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
@@ -1445,7 +1445,7 @@ void UI_view2d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0);
/* Alternative keymap for buttons listview */
- keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0);
+ keymap= WM_keymap_find(wm, "View2D Buttons List", 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript
index df1f297698d..00391b3474a 100644
--- a/source/blender/editors/mesh/SConscript
+++ b/source/blender/editors/mesh/SConscript
@@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' #/intern/guardedalloc ../../gpu'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), [], libtype=['core'], priority=[45] )
diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c
index 4c3e76f2285..28103828dd4 100644
--- a/source/blender/editors/mesh/editmesh_loop.c
+++ b/source/blender/editors/mesh/editmesh_loop.c
@@ -60,6 +60,7 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
#include "BKE_library.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
+#include "BKE_report.h"
#include "BKE_utildefines.h"
#include "PIL_time.h"
@@ -199,6 +200,7 @@ static void edgering_sel(EditMesh *em, EditEdge *startedge, int select, int prev
}
}
}
+
void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts)
{
ViewContext vc; // XXX
@@ -636,6 +638,10 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
int len=0;
short numcuts=1, mode= RNA_int_get(op->ptr, "type");
+ /* edit-object needed for matrix, and ar->regiondata for projections to work */
+ if (ELEM3(NULL, obedit, ar, ar->regiondata))
+ return OPERATOR_CANCELLED;
+
if (EM_nvertices_selected(em) < 2) {
error("No edges are selected to operate on");
BKE_mesh_end_editmesh(obedit->data, em);
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index 7301901aff5..325a1aeec99 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -761,7 +761,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
float angle;
for(efa= em->faces.first; efa; efa= efa->next) {
if (!(efa->f & SELECT) && !efa->h) {
- angle= VecAngle2(base_efa->n, efa->n);
+ angle= RAD2DEG(VecAngle2(base_efa->n, efa->n));
if (angle/180.0<=thresh) {
EM_select_face(efa, 1);
selcount++;
@@ -776,7 +776,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
base_dot= Inpf(base_efa->cent, base_efa->n);
for(efa= em->faces.first; efa; efa= efa->next) {
if (!(efa->f & SELECT) && !efa->h) {
- angle= VecAngle2(base_efa->n, efa->n);
+ angle= RAD2DEG(VecAngle2(base_efa->n, efa->n));
if (angle/180.0<=thresh) {
dot=Inpf(efa->cent, base_efa->n);
if (fabs(base_dot-dot) <= thresh) {
@@ -916,7 +916,7 @@ static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mod
else if (eed->f2==0) /* first access, assign the face */
eed->tmp.f= efa;
else if (eed->f2==1) /* second, we assign the angle*/
- eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
+ eed->tmp.fp= RAD2DEG(VecAngle2(eed->tmp.f->n, efa->n))/180;
eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
}
j++;
@@ -946,7 +946,7 @@ static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mod
for(eed= em->edges.first; eed; eed= eed->next) {
if (!(eed->f & SELECT) && !eed->h) {
VecSubf(dir, eed->v1->co, eed->v2->co);
- angle= VecAngle2(base_dir, dir);
+ angle= RAD2DEG(VecAngle2(base_dir, dir));
if (angle>90) /* use the smallest angle between the edges */
angle= fabs(angle-180.0f);
@@ -1137,7 +1137,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
float angle;
for(eve= em->verts.first; eve; eve= eve->next) {
if (!(eve->f & SELECT) && !eve->h) {
- angle= VecAngle2(base_eve->no, eve->no);
+ angle= RAD2DEG(VecAngle2(base_eve->no, eve->no));
if (angle/180.0<=thresh) {
eve->f |= SELECT;
selcount++;
@@ -2033,6 +2033,9 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring
vc.mval[0]= mval[0];
vc.mval[1]= mval[1];
em= vc.em;
+
+ /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+ view3d_validate_backbuf(&vc);
eed= findnearestedge(&vc, &dist);
if(eed) {
@@ -2110,6 +2113,9 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2])
vc.mval[1]= mval[1];
em= vc.em;
+ /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+ view3d_validate_backbuf(&vc);
+
eed= findnearestedge(&vc, &dist);
if(eed) {
Mesh *me= vc.obedit->data;
@@ -3287,6 +3293,11 @@ void EM_toggle_select_all(EditMesh *em) /* exported for UV */
EM_set_flag_all(em, SELECT);
}
+void EM_select_all(EditMesh *em)
+{
+ EM_set_flag_all(em, SELECT);
+}
+
static int toggle_select_all_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
@@ -3547,7 +3558,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* props */
- RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
+ RNA_def_float_percentage(ot->srna, "percent", 50.0f, 0.0f, 100.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
}
void EM_select_by_material(EditMesh *em, int index)
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 5a4397256de..510f6ab464b 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -98,8 +98,6 @@ static void waitcursor(int val) {}
static int pupmenu() {return 0;}
static int qtest() {return 0;}
#define add_numbut(a, b, c, d, e, f, g) {}
-static int snap_sel_to_curs() {return 0;}
-static int snap_to_center() {return 0;}
/* XXX */
@@ -142,7 +140,7 @@ static int vergface(const void *v1, const void *v2)
/* *********************************** */
-void convert_to_triface(EditMesh *em, int direction)
+static void convert_to_triface(EditMesh *em, int direction)
{
EditFace *efa, *efan, *next;
float fac;
@@ -484,17 +482,16 @@ int removedoublesflag(EditMesh *em, short flag, short automerge, float limit) /
static int removedoublesflag_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- ToolSettings *ts= CTX_data_tool_settings(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
- char msg[100];
-
- int cnt = removedoublesflag(em,1,0,ts->doublimit);
+ /*char msg[100];*/
+ int cnt = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
+ /*XXX this messes up last operator panel
if(cnt)
{
sprintf(msg, "Removed %d vertices", cnt);
BKE_report(op->reports, RPT_INFO, msg);
- }
+ }*/
DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
@@ -516,6 +513,8 @@ void MESH_OT_remove_doubles(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_float(ot->srna, "limit", 0.0001f, 0.000001f, 50.0f, "Merge Threshold", "Minimum distance between merged verts", 0.00001f, 2.0f);
}
// XXX is this needed?
@@ -3121,13 +3120,13 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
CalcNormFloat(v1->co, v3->co, v4->co, noA2);
if(noA1[0] == noA2[0] && noA1[1] == noA2[1] && noA1[2] == noA2[2]) normalADiff = 0.0;
- else normalADiff = VecAngle2(noA1, noA2);
+ else normalADiff = RAD2DEG(VecAngle2(noA1, noA2));
//if(!normalADiff) normalADiff = 179;
CalcNormFloat(v2->co, v3->co, v4->co, noB1);
CalcNormFloat(v4->co, v1->co, v2->co, noB2);
if(noB1[0] == noB2[0] && noB1[1] == noB2[1] && noB1[2] == noB2[2]) normalBDiff = 0.0;
- else normalBDiff = VecAngle2(noB1, noB2);
+ else normalBDiff = RAD2DEG(VecAngle2(noB1, noB2));
//if(!normalBDiff) normalBDiff = 179;
measure += (normalADiff/360) + (normalBDiff/360);
@@ -3142,10 +3141,10 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
diff = 0.0;
diff = (
- fabs(VecAngle2(edgeVec1, edgeVec2) - 90) +
- fabs(VecAngle2(edgeVec2, edgeVec3) - 90) +
- fabs(VecAngle2(edgeVec3, edgeVec4) - 90) +
- fabs(VecAngle2(edgeVec4, edgeVec1) - 90)) / 360;
+ fabs(RAD2DEG(VecAngle2(edgeVec1, edgeVec2)) - 90) +
+ fabs(RAD2DEG(VecAngle2(edgeVec2, edgeVec3)) - 90) +
+ fabs(RAD2DEG(VecAngle2(edgeVec3, edgeVec4)) - 90) +
+ fabs(RAD2DEG(VecAngle2(edgeVec4, edgeVec1)) - 90)) / 360;
if(!diff) return 0.0;
measure += diff;
@@ -3868,11 +3867,11 @@ typedef struct SlideVert {
EditVert origvert;
} SlideVert;
+#if 0
int EdgeSlide(EditMesh *em, wmOperator *op, short immediate, float imperc)
{
return 0;
/* XXX REFACTOR - #if 0'd for now, otherwise can't make 64bit windows builds on 64bit machine */
-#if 0
useless:
goto useless // because it doesn't do anything right now
@@ -4654,11 +4653,12 @@ useless:
}
return 1;
-#endif // END OF XXX
}
+#endif // END OF XXX
int EdgeLoopDelete(EditMesh *em, wmOperator *op)
{
+#if 0 //XXX won't work with new edgeslide
/* temporal flag setting so we keep UVs when deleting edge loops,
* this is a bit of a hack but it works how you would want in almost all cases */
@@ -4677,6 +4677,8 @@ int EdgeLoopDelete(EditMesh *em, wmOperator *op)
EM_select_flush(em);
// DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
return 1;
+#endif
+ return 0;
}
@@ -5635,7 +5637,7 @@ static void collapseuvs(EditMesh *em, EditVert *mergevert)
}
}
-int collapseEdges(EditMesh *em)
+static int collapseEdges(EditMesh *em)
{
EditVert *eve;
EditEdge *eed;
@@ -5701,7 +5703,7 @@ int collapseEdges(EditMesh *em)
return mergecount;
}
-int merge_firstlast(EditMesh *em, int first, int uvmerge)
+static int merge_firstlast(EditMesh *em, int first, int uvmerge)
{
EditVert *eve,*mergevert;
EditSelection *ese;
@@ -5735,13 +5737,59 @@ int merge_firstlast(EditMesh *em, int first, int uvmerge)
return removedoublesflag(em, 1, 0, MERGELIMIT);
}
-int merge_target(EditMesh *em, int target, int uvmerge)
+static void em_snap_to_center(EditMesh *em)
+{
+ EditVert *eve;
+ float cent[3] = {0.0f, 0.0f, 0.0f};
+ int i=0;
+
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (eve->f & SELECT) {
+ VecAddf(cent, cent, eve->co);
+ i++;
+ }
+ }
+
+ if (!i)
+ return;
+
+ VecMulf(cent, 1.0f / (float)i);
+
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (eve->f & SELECT) {
+ VECCOPY(eve->co, cent);
+ }
+ }
+}
+
+static void em_snap_to_cursor(EditMesh *em, bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob= CTX_data_edit_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ EditVert *eve;
+ float co[3], *vco, invmat[4][4];
+
+ Mat4Invert(invmat, ob->obmat);
+
+ vco = give_cursor(scene, v3d);
+ VECCOPY(co, vco);
+ Mat4MulVecfl(invmat, co);
+
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (eve->f & SELECT) {
+ VECCOPY(eve->co, co);
+ }
+ }
+}
+
+static int merge_target(bContext *C, EditMesh *em, int target, int uvmerge)
{
EditVert *eve;
// XXX not working
- if(target) snap_sel_to_curs();
- else snap_to_center();
+ if(target) em_snap_to_cursor(em, C);
+ else em_snap_to_center(em);
if(uvmerge && CustomData_has_layer(&em->fdata, CD_MTFACE)){
for(eve=em->verts.first; eve; eve=eve->next) eve->f1 = 0;
@@ -5763,10 +5811,10 @@ static int merge_exec(bContext *C, wmOperator *op)
switch(RNA_enum_get(op->ptr, "type")) {
case 3:
- count = merge_target(em, 0, uvs);
+ count = merge_target(C, em, 0, uvs);
break;
case 4:
- count = merge_target(em, 1, uvs);
+ count = merge_target(C, em, 1, uvs);
break;
case 1:
count = merge_firstlast(em, 0, uvs);
@@ -5774,7 +5822,7 @@ static int merge_exec(bContext *C, wmOperator *op)
case 6:
count = merge_firstlast(em, 1, uvs);
break;
- case 2:
+ case 5:
count = collapseEdges(em);
break;
}
@@ -5878,7 +5926,7 @@ typedef struct PathEdge {
#define PATH_SELECT_EDGE_LENGTH 0
#define PATH_SELECT_TOPOLOGICAL 1
-int select_vertex_path_exec(bContext *C, wmOperator *op)
+static int select_vertex_path_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -7091,7 +7139,7 @@ void MESH_OT_edge_flip(wmOperatorType *ot)
/********************** Smooth/Solid Operators *************************/
-void mesh_set_smooth_faces(EditMesh *em, short smooth)
+static void mesh_set_smooth_faces(EditMesh *em, short smooth)
{
EditFace *efa;
diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c
new file mode 100644
index 00000000000..e58025ac6ce
--- /dev/null
+++ b/source/blender/editors/mesh/loopcut.c
@@ -0,0 +1,474 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Joseph Eagar, Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <float.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "DNA_ID.h"
+#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+#include "DNA_object_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "PIL_time.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_dynstr.h" /*for WM_operator_pystring */
+#include "BLI_editVert.h"
+
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h"
+#include "BKE_mesh.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h" /* for paint cursor */
+
+#include "IMB_imbuf_types.h"
+
+#include "ED_screen.h"
+#include "ED_util.h"
+#include "ED_space_api.h"
+#include "ED_view3d.h"
+#include "ED_mesh.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "mesh_intern.h"
+
+/* ringsel operator */
+
+/* struct for properties used while drawing */
+typedef struct tringselOpData {
+ ARegion *ar; /* region that ringsel was activated in */
+ void *draw_handle; /* for drawing preview loop */
+
+ float (*edges)[2][3];
+ int totedge;
+
+ ViewContext vc;
+
+ Object *ob;
+ EditMesh *em;
+ EditEdge *eed;
+
+ int extend;
+ int do_cut;
+} tringselOpData;
+
+/* modal loop selection drawing callback */
+static void ringsel_draw(const bContext *C, ARegion *ar, void *arg)
+{
+ int i;
+ tringselOpData *lcd = arg;
+
+ glDisable(GL_DEPTH_TEST);
+
+ glPushMatrix();
+ glMultMatrixf(lcd->ob->obmat);
+
+ glColor3ub(255, 0, 255);
+ glBegin(GL_LINES);
+ for (i=0; i<lcd->totedge; i++) {
+ glVertex3fv(lcd->edges[i][0]);
+ glVertex3fv(lcd->edges[i][1]);
+ }
+ glEnd();
+
+ glPopMatrix();
+ glEnable(GL_DEPTH_TEST);
+}
+
+static void edgering_sel(tringselOpData *lcd, int previewlines, int select)
+{
+ EditMesh *em = lcd->em;
+ EditEdge *startedge = lcd->eed;
+ EditEdge *eed;
+ EditFace *efa;
+ EditVert *v[2][2];
+ float (*edges)[2][3] = NULL;
+ V_DYNDECLARE(edges);
+ float co[2][3];
+ int looking=1, i, tot=0;
+
+ if (!startedge)
+ return;
+
+ if (lcd->edges) {
+ MEM_freeN(lcd->edges);
+ lcd->edges = NULL;
+ lcd->totedge = 0;
+ }
+
+ if (!lcd->extend) {
+ EM_clear_flag_all(lcd->em, SELECT);
+ }
+
+ /* in eed->f1 we put the valence (amount of faces in edge) */
+ /* in eed->f2 we put tagged flag as correct loop */
+ /* in efa->f1 we put tagged flag as correct to select */
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ eed->f1= 0;
+ eed->f2= 0;
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ efa->f1= 0;
+ if(efa->h==0) {
+ efa->e1->f1++;
+ efa->e2->f1++;
+ efa->e3->f1++;
+ if(efa->e4) efa->e4->f1++;
+ }
+ }
+
+ // tag startedge OK
+ startedge->f2= 1;
+
+ while(looking) {
+ looking= 0;
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->e4 && efa->f1==0 && efa->h == 0) { // not done quad
+ if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
+
+ // if edge tagged, select opposing edge and mark face ok
+ if(efa->e1->f2) {
+ efa->e3->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ else if(efa->e2->f2) {
+ efa->e4->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ if(efa->e3->f2) {
+ efa->e1->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ if(efa->e4->f2) {
+ efa->e2->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ }
+ }
+ }
+ }
+
+ if(previewlines > 0 && !select){
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->v4 == NULL) { continue; }
+ if(efa->h == 0){
+ if(efa->e1->f2 == 1){
+ if(efa->e1->h == 1 || efa->e3->h == 1 )
+ continue;
+
+ v[0][0] = efa->v1;
+ v[0][1] = efa->v2;
+ v[1][0] = efa->v4;
+ v[1][1] = efa->v3;
+ } else if(efa->e2->f2 == 1){
+ if(efa->e2->h == 1 || efa->e4->h == 1)
+ continue;
+ v[0][0] = efa->v2;
+ v[0][1] = efa->v3;
+ v[1][0] = efa->v1;
+ v[1][1] = efa->v4;
+ } else { continue; }
+
+ 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];
+
+ V_GROW(edges);
+ VECCOPY(edges[tot][0], co[0]);
+ VECCOPY(edges[tot][1], co[1]);
+ tot++;
+ }
+ }
+ }
+ } else {
+ select = (startedge->f & SELECT) == 0;
+
+ /* select the edges */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f2) EM_select_edge(eed, select);
+ }
+ }
+
+ lcd->edges = edges;
+ lcd->totedge = tot;
+}
+
+static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *ar, int cuts)
+{
+ if (lcd->eed)
+ edgering_sel(lcd, cuts, 0);
+}
+
+static void ringsel_finish(bContext *C, wmOperator *op)
+{
+ tringselOpData *lcd= op->customdata;
+ int cuts= RNA_int_get(op->ptr,"number_cuts");
+
+ if (lcd->eed) {
+ edgering_sel(lcd, cuts, 1);
+ if (lcd->do_cut) {
+ EditMesh *em = BKE_mesh_get_editmesh(lcd->ob->data);
+ esubdivideflag(lcd->ob, em, SELECT, 0.0f, 0.0f, 0, cuts, SUBDIV_SELECT_LOOPCUT);
+
+ DAG_id_flush_update(lcd->ob->data, OB_RECALC_DATA);
+ }
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, lcd->ob->data);
+ }
+}
+
+/* called when modal loop selection is done... */
+static void ringsel_exit (bContext *C, wmOperator *op)
+{
+ tringselOpData *lcd= op->customdata;
+
+ /* deactivate the extra drawing stuff in 3D-View */
+ ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle);
+
+ if (lcd->edges)
+ MEM_freeN(lcd->edges);
+
+ ED_region_tag_redraw(lcd->ar);
+
+ /* free the custom data */
+ MEM_freeN(lcd);
+ op->customdata= NULL;
+}
+
+/* called when modal loop selection gets set up... */
+static int ringsel_init (bContext *C, wmOperator *op, int do_cut)
+{
+ tringselOpData *lcd;
+
+ /* alloc new customdata */
+ lcd= op->customdata= MEM_callocN(sizeof(tringselOpData), "ringsel Modal Op Data");
+
+ /* assign the drawing handle for drawing preview line... */
+ lcd->ar= CTX_wm_region(C);
+ lcd->draw_handle= ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST);
+ lcd->ob = CTX_data_edit_object(C);
+ lcd->em= BKE_mesh_get_editmesh((Mesh *)lcd->ob->data);
+ lcd->extend = do_cut ? 0 : RNA_boolean_get(op->ptr, "extend");
+ lcd->do_cut = do_cut;
+ em_setup_viewcontext(C, &lcd->vc);
+
+ ED_region_tag_redraw(lcd->ar);
+
+ return 1;
+}
+
+static int ringsel_cancel (bContext *C, wmOperator *op)
+{
+ /* this is just a wrapper around exit() */
+ ringsel_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tringselOpData *lcd;
+ EditEdge *edge;
+ int dist = 75;
+
+ view3d_operator_needs_opengl(C);
+
+ if (!ringsel_init(C, op, 0))
+ return OPERATOR_CANCELLED;
+
+ /* add a modal handler for this operator - handles loop selection */
+ WM_event_add_modal_handler(C, op);
+
+ lcd = op->customdata;
+ lcd->vc.mval[0] = evt->mval[0];
+ lcd->vc.mval[1] = evt->mval[1];
+
+ edge = findnearestedge(&lcd->vc, &dist);
+ if (edge != lcd->eed) {
+ lcd->eed = edge;
+ ringsel_find_edge(lcd, C, lcd->ar, 1);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tringselOpData *lcd;
+ EditEdge *edge;
+ int dist = 75;
+
+ view3d_operator_needs_opengl(C);
+
+ if (!ringsel_init(C, op, 1))
+ return OPERATOR_CANCELLED;
+
+ /* add a modal handler for this operator - handles loop selection */
+ WM_event_add_modal_handler(C, op);
+
+ lcd = op->customdata;
+ lcd->vc.mval[0] = evt->mval[0];
+ lcd->vc.mval[1] = evt->mval[1];
+
+ edge = findnearestedge(&lcd->vc, &dist);
+ if (edge != lcd->eed) {
+ lcd->eed = edge;
+ ringsel_find_edge(lcd, C, lcd->ar, 1);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event)
+{
+ int cuts= RNA_int_get(op->ptr,"number_cuts");
+ tringselOpData *lcd= op->customdata;
+
+ view3d_operator_needs_opengl(C);
+
+
+ switch (event->type) {
+ case RIGHTMOUSE:
+ case LEFTMOUSE: /* confirm */ // XXX hardcoded
+ if (event->val == KM_RELEASE) {
+ /* finish */
+ ED_region_tag_redraw(lcd->ar);
+
+ ringsel_finish(C, op);
+ ringsel_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+
+ ED_region_tag_redraw(lcd->ar);
+ break;
+ case WHEELUPMOUSE: /* change number of cuts */
+ cuts++;
+ RNA_int_set(op->ptr,"number_cuts",cuts);
+ ringsel_find_edge(lcd, C, lcd->ar, cuts);
+
+ ED_region_tag_redraw(lcd->ar);
+ break;
+ case WHEELDOWNMOUSE: /* change number of cuts */
+ cuts=MAX2(cuts-1,1);
+ RNA_int_set(op->ptr,"number_cuts",cuts);
+ ringsel_find_edge(lcd, C, lcd->ar,cuts);
+
+ ED_region_tag_redraw(lcd->ar);
+ break;
+ case MOUSEMOVE: { /* mouse moved somewhere to select another loop */
+ int dist = 75;
+ EditEdge *edge;
+
+ lcd->vc.mval[0] = event->mval[0];
+ lcd->vc.mval[1] = event->mval[1];
+ edge = findnearestedge(&lcd->vc, &dist);
+
+ if (edge != lcd->eed) {
+ lcd->eed = edge;
+ ringsel_find_edge(lcd, C, lcd->ar, cuts);
+ }
+
+ ED_region_tag_redraw(lcd->ar);
+ break;
+ }
+ }
+
+ /* keep going until the user confirms */
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void MESH_OT_edgering_select (wmOperatorType *ot)
+{
+ /* description */
+ ot->name= "Edge Ring Select";
+ ot->idname= "MESH_OT_edgering_select";
+ ot->description= "Select an edge ring";
+
+ /* callbacks */
+ ot->invoke= ringsel_invoke;
+ ot->modal= ringsel_modal;
+ ot->cancel= ringsel_cancel;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
+}
+
+void MESH_OT_loopcut (wmOperatorType *ot)
+{
+ /* description */
+ ot->name= "Loop Cut";
+ ot->idname= "MESH_OT_loopcut";
+ ot->description= "Add a new loop between existing loops.";
+
+ /* callbacks */
+ ot->invoke= ringcut_invoke;
+ ot->modal= ringsel_modal;
+ ot->cancel= ringsel_cancel;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* properties */
+ RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX);
+}
diff --git a/source/blender/editors/mesh/mesh_layers.c b/source/blender/editors/mesh/mesh_data.c
index a36c7a56b7c..43e1dd417a6 100644
--- a/source/blender/editors/mesh/mesh_layers.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -26,12 +26,14 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <stdlib.h>
#include <math.h>
+#include <stdlib.h>
+#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_customdata_types.h"
+#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -43,9 +45,13 @@
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_report.h"
+#include "BLI_arithb.h"
#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -150,19 +156,8 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
}
}
-/*********************** UV texture operators ************************/
-
-static int layers_poll(bContext *C)
+int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- ID *data= (ob)? ob->data: NULL;
- return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
-}
-
-static int uv_texture_add_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- Mesh *me= ob->data;
EditMesh *em;
int layernum;
@@ -193,28 +188,11 @@ static int uv_texture_add_exec(bContext *C, wmOperator *op)
DAG_id_flush_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
- return OPERATOR_FINISHED;
+ return 1;
}
-void MESH_OT_uv_texture_add(wmOperatorType *ot)
+int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
{
- /* identifiers */
- ot->name= "Add UV Texture";
- ot->description= "Add UV texture layer.";
- ot->idname= "MESH_OT_uv_texture_add";
-
- /* api callbacks */
- ot->poll= layers_poll;
- ot->exec= uv_texture_add_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int uv_texture_remove_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- Mesh *me= ob->data;
CustomDataLayer *cdl;
int index;
@@ -222,38 +200,17 @@ static int uv_texture_remove_exec(bContext *C, wmOperator *op)
cdl= (index == -1)? NULL: &me->fdata.layers[index];
if(!cdl)
- return OPERATOR_CANCELLED;
+ return 0;
delete_customdata_layer(C, ob, cdl);
-
DAG_id_flush_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
- return OPERATOR_FINISHED;
-}
-
-void MESH_OT_uv_texture_remove(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Remove UV Texture";
- ot->description= "Remove UV texture layer.";
- ot->idname= "MESH_OT_uv_texture_remove";
-
- /* api callbacks */
- ot->poll= layers_poll;
- ot->exec= uv_texture_remove_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ return 1;
}
-/*********************** vertex color operators ************************/
-
-static int vertex_color_add_exec(bContext *C, wmOperator *op)
+int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me)
{
- Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- Mesh *me= ob->data;
EditMesh *em;
MCol *mcol;
int layernum;
@@ -263,7 +220,7 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op)
layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
if(layernum >= MAX_MCOL)
- return OPERATOR_CANCELLED;
+ return 0;
EM_add_data_layer(em, &em->fdata, CD_MCOL);
CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
@@ -271,7 +228,7 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op)
else {
layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
if(layernum >= MAX_MCOL)
- return OPERATOR_CANCELLED;
+ return 0;
mcol= me->mcol;
@@ -290,6 +247,100 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op)
DAG_id_flush_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
+ return 1;
+}
+
+int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
+{
+ CustomDataLayer *cdl;
+ int index;
+
+ index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
+ cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+ if(!cdl)
+ return 0;
+
+ delete_customdata_layer(C, ob, cdl);
+ DAG_id_flush_update(&me->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
+
+ return 1;
+}
+
+/*********************** UV texture operators ************************/
+
+static int layers_poll(bContext *C)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ID *data= (ob)? ob->data: NULL;
+ return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
+}
+
+static int uv_texture_add_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Mesh *me= ob->data;
+
+ if(!ED_mesh_uv_texture_add(C, scene, ob, me))
+ return OPERATOR_CANCELLED;
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_uv_texture_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add UV Texture";
+ ot->description= "Add UV texture layer.";
+ ot->idname= "MESH_OT_uv_texture_add";
+
+ /* api callbacks */
+ ot->poll= layers_poll;
+ ot->exec= uv_texture_add_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int uv_texture_remove_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Mesh *me= ob->data;
+
+ if(!ED_mesh_uv_texture_remove(C, ob, me))
+ return OPERATOR_CANCELLED;
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_uv_texture_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove UV Texture";
+ ot->description= "Remove UV texture layer.";
+ ot->idname= "MESH_OT_uv_texture_remove";
+
+ /* api callbacks */
+ ot->poll= layers_poll;
+ ot->exec= uv_texture_remove_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/*********************** vertex color operators ************************/
+
+static int vertex_color_add_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Mesh *me= ob->data;
+
+ if(!ED_mesh_color_add(C, scene, ob, me))
+ return OPERATOR_CANCELLED;
+
return OPERATOR_FINISHED;
}
@@ -312,20 +363,10 @@ static int vertex_color_remove_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
Mesh *me= ob->data;
- CustomDataLayer *cdl;
- int index;
-
- index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
- cdl= (index == -1)? NULL: &me->fdata.layers[index];
- if(!cdl)
+ if(!ED_mesh_color_remove(C, ob, me))
return OPERATOR_CANCELLED;
- delete_customdata_layer(C, ob, cdl);
-
- DAG_id_flush_update(&me->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
-
return OPERATOR_FINISHED;
}
@@ -409,3 +450,212 @@ void MESH_OT_sticky_remove(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/************************** Add Geometry Layers *************************/
+
+static void mesh_calc_edges(Mesh *mesh)
+{
+ CustomData edata;
+ EdgeHashIterator *ehi;
+ MFace *mf = mesh->mface;
+ MEdge *med;
+ EdgeHash *eh = BLI_edgehash_new();
+ int i, *index, totedge, totface = mesh->totface;
+
+ for (i = 0; i < totface; i++, mf++) {
+ if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
+ BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
+ if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
+ BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
+
+ if (mf->v4) {
+ if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
+ BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
+ if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
+ BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
+ } else {
+ if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
+ BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+ }
+ }
+
+ totedge = BLI_edgehash_size(eh);
+
+ /* write new edges into a temporary CustomData */
+ memset(&edata, 0, sizeof(edata));
+ CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+
+ ehi = BLI_edgehashIterator_new(eh);
+ med = CustomData_get_layer(&edata, CD_MEDGE);
+ for(i = 0; !BLI_edgehashIterator_isDone(ehi);
+ BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
+ BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
+
+ med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+ }
+ BLI_edgehashIterator_free(ehi);
+
+ /* free old CustomData and assign new one */
+ CustomData_free(&mesh->edata, mesh->totedge);
+ mesh->edata = edata;
+ mesh->totedge = totedge;
+
+ mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
+
+ BLI_edgehash_free(eh, NULL);
+}
+
+void ED_mesh_update(Mesh *mesh, bContext *C)
+{
+ if(mesh->totface && mesh->totedge == 0)
+ mesh_calc_edges(mesh);
+
+ mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
+
+ DAG_id_flush_update(&mesh->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
+}
+
+static void mesh_add_verts(Mesh *mesh, int len)
+{
+ CustomData vdata;
+ MVert *mvert;
+ int i, totvert;
+
+ if(len == 0)
+ return;
+
+ totvert= mesh->totvert + len;
+ CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
+ CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
+
+ if(!CustomData_has_layer(&vdata, CD_MVERT))
+ CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
+
+ CustomData_free(&mesh->vdata, mesh->totvert);
+ mesh->vdata= vdata;
+ mesh_update_customdata_pointers(mesh);
+
+ /* scan the input list and insert the new vertices */
+
+ mvert= &mesh->mvert[mesh->totvert];
+ for(i=0; i<len; i++, mvert++)
+ mvert->flag |= SELECT;
+
+ /* set final vertex list size */
+ mesh->totvert= totvert;
+}
+
+void ED_mesh_transform(Mesh *me, float *mat)
+{
+ int i;
+ MVert *mvert= me->mvert;
+
+ for(i= 0; i < me->totvert; i++, mvert++)
+ Mat4MulVecfl((float (*)[4])mat, mvert->co);
+
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+}
+
+static void mesh_add_edges(Mesh *mesh, int len)
+{
+ CustomData edata;
+ MEdge *medge;
+ int i, totedge;
+
+ if(len == 0)
+ return;
+
+ totedge= mesh->totedge+len;
+
+ /* update customdata */
+ CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
+ CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
+
+ if(!CustomData_has_layer(&edata, CD_MEDGE))
+ CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+
+ CustomData_free(&mesh->edata, mesh->totedge);
+ mesh->edata= edata;
+ mesh_update_customdata_pointers(mesh);
+
+ /* set default flags */
+ medge= &mesh->medge[mesh->totedge];
+ for(i=0; i<len; i++, medge++)
+ medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
+
+ mesh->totedge= totedge;
+}
+
+static void mesh_add_faces(Mesh *mesh, int len)
+{
+ CustomData fdata;
+ MFace *mface;
+ int i, totface;
+
+ if(len == 0)
+ return;
+
+ totface= mesh->totface + len; /* new face count */
+
+ /* update customdata */
+ CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
+ CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
+
+ if(!CustomData_has_layer(&fdata, CD_MFACE))
+ CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
+
+ CustomData_free(&mesh->fdata, mesh->totface);
+ mesh->fdata= fdata;
+ mesh_update_customdata_pointers(mesh);
+
+ /* set default flags */
+ mface= &mesh->mface[mesh->totface];
+ for(i=0; i<len; i++, mface++)
+ mface->flag= SELECT;
+
+ mesh->totface= totface;
+}
+
+void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
+{
+ if(mesh->edit_mesh) {
+ BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode.");
+ return;
+ }
+
+ if(verts)
+ mesh_add_verts(mesh, verts);
+ if(edges)
+ mesh_add_edges(mesh, edges);
+ if(faces)
+ mesh_add_faces(mesh, faces);
+}
+
+void ED_mesh_calc_normals(Mesh *me)
+{
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+}
+
+void ED_mesh_material_add(Mesh *me, Material *ma)
+{
+ int i;
+ int totcol = me->totcol + 1;
+ Material **mat;
+
+ /* don't add if mesh already has it */
+ for(i = 0; i < me->totcol; i++)
+ if(me->mat[i] == ma)
+ return;
+
+ mat= MEM_callocN(sizeof(void*)*totcol, "newmatar");
+
+ if(me->totcol) memcpy(mat, me->mat, sizeof(void*) * me->totcol);
+ if(me->mat) MEM_freeN(me->mat);
+
+ me->mat = mat;
+ me->mat[me->totcol++] = ma;
+ ma->id.us++;
+
+ test_object_materials((ID*)me);
+}
+
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 905a51a1bb0..37a6d0f384f 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -61,12 +61,6 @@ extern struct EditEdge *addedgelist(EditMesh *em, struct EditVert *v1, struct Ed
extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges);
extern struct EditEdge *findedgelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2);
-EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve);
-EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2);
-int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve);
-int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
-int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
-
void em_setup_viewcontext(struct bContext *C, ViewContext *vc);
void MESH_OT_separate(struct wmOperatorType *ot);
@@ -242,5 +236,8 @@ void MESH_OT_vertex_color_remove(struct wmOperatorType *ot);
void MESH_OT_sticky_add(struct wmOperatorType *ot);
void MESH_OT_sticky_remove(struct wmOperatorType *ot);
+void MESH_OT_edgering_select(struct wmOperatorType *ot);
+void MESH_OT_loopcut(struct wmOperatorType *ot);
+
#endif // MESH_INTERN_H
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index c545f7d70d6..13d73faeb98 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -113,6 +113,7 @@ static int edge_specials_invoke(bContext *C, wmOperator *op, wmEvent *event)
uiItemEnumO(layout, "Rotate Edge CCW", 0, "MESH_OT_edge_rotate", "direction", 2);
//uiItemO(layout, "Loopcut", 0, "MESH_OT_loop_cut"); // CutEdgeloop(em, 1);
//uiItemO(layout, "Edge Slide", 0, "MESH_OT_edge_slide"); // EdgeSlide(em, 0,0.0);
+ uiItemO(layout, "Edge Slide", 0, "TFM_OT_edge_slide");
uiItemO(layout, "Edge Loop", 0, "MESH_OT_loop_multi_select");
uiItemBooleanO(layout, "Edge Ring", 0, "MESH_OT_loop_multi_select", "ring", 1);
uiItemO(layout, NULL, 0, "MESH_OT_loop_to_region");
@@ -320,7 +321,18 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_face_specials);
WM_operatortype_append(MESH_OT_specials);
+ WM_operatortype_append(MESH_OT_edgering_select);
+ WM_operatortype_append(MESH_OT_loopcut);
+
/* macros */
+
+ /*combining operators with invoke and exec portions doesn't work yet.
+
+ ot= WM_operatortype_append_macro("MESH_OT_loopcut", "Loopcut", OPTYPE_UNDO|OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "MESH_OT_edgering_select");
+ WM_operatortype_macro_define(ot, "MESH_OT_subdivide");
+ */
+
ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
WM_operatortype_macro_define(ot, "TFM_OT_translate");
@@ -332,28 +344,32 @@ void ED_operatortypes_mesh(void)
ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_extrude");
WM_operatortype_macro_define(ot, "TFM_OT_translate");
-
+
}
/* note mesh keymap also for other space? */
void ED_keymap_mesh(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0);
+ wmKeyMap *keymap;
wmKeymapItem *kmi;
+ keymap= WM_keymap_find(wm, "EditMesh", 0, 0);
+ keymap->poll= ED_operator_editmesh;
+
+ WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0);
+
/* selecting */
/* standard mouse selection goes via space_view3d */
WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
- kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "ring", 1);
- kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0);
+
+ kmi= WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ kmi= WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
- RNA_boolean_set(kmi->ptr, "ring", 1);
WM_keymap_add_item(keymap, "MESH_OT_select_shortest_path", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "MESH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
@@ -413,16 +429,17 @@ void ED_keymap_mesh(wmWindowManager *wm)
WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0);
/* use KM_RELEASE because same key is used for tweaks */
WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_fgon_make", FKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_fgon_clear", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, 0, KKEY);
/* menus */
WM_keymap_add_item(keymap, "MESH_OT_vertex_specials", VKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 4aa99820a6e..00893f10165 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -632,7 +632,7 @@ void sort_faces(Scene *scene, View3D *v3d)
if (event == 1)
Mat4MulMat4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */
else if (event == 2) { /* sort from cursor */
- if( v3d && v3d->localview ) {
+ if( v3d && v3d->localvd ) {
VECCOPY(cur, v3d->cursor);
} else {
VECCOPY(cur, scene->cursor);
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index 38593af372f..dd8a18f385c 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -34,6 +34,8 @@
#include "DNA_listBase.h"
#include "DNA_windowmanager_types.h"
+#include "ED_screen.h"
+
#include "mball_intern.h"
void ED_operatortypes_metaball(void)
@@ -51,7 +53,10 @@ void ED_operatortypes_metaball(void)
void ED_keymap_metaball(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Metaball", 0, 0);
+ wmKeyMap *keymap;
+
+ keymap= WM_keymap_find(wm, "Metaball", 0, 0);
+ keymap->poll= ED_operator_editmball;
WM_keymap_add_item(keymap, "OBJECT_OT_metaball_add", AKEY, KM_PRESS, KM_SHIFT, 0);
@@ -60,6 +65,7 @@ void ED_keymap_metaball(wmWindowManager *wm)
RNA_enum_set(WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MBALL_OT_duplicate_metaelems", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MBALL_OT_select_deselect_all_metaelems", AKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/object/Makefile b/source/blender/editors/object/Makefile
index 70ada46c80f..fd2af305d87 100644
--- a/source/blender/editors/object/Makefile
+++ b/source/blender/editors/object/Makefile
@@ -47,6 +47,7 @@ CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../python
CPPFLAGS += -I../../imbuf
+CPPFLAGS += -I../../ikplugin
# own include
diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript
index 3371e172a82..6ecc80f2d81 100644
--- a/source/blender/editors/object/SConscript
+++ b/source/blender/editors/object/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc'
incs += ' #/intern/guardedalloc'
-incs += ' ../../makesrna ../../python'
+incs += ' ../../makesrna ../../python ../../ikplugin'
defs = []
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index f4c8c63c480..7188368a95f 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -32,11 +32,13 @@
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_fluidsim.h"
#include "DNA_object_types.h"
+#include "DNA_object_force.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
@@ -55,6 +57,7 @@
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
+#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_lattice.h"
@@ -109,7 +112,7 @@ void ED_object_base_init_from_view(bContext *C, Base *base)
VECCOPY(ob->loc, scene->cursor);
}
else {
- if (v3d->localview) {
+ if (v3d->localvd) {
base->lay= ob->lay= v3d->layact | v3d->lay;
VECCOPY(ob->loc, v3d->cursor);
}
@@ -165,7 +168,7 @@ static Object *object_add_type(bContext *C, int type)
/* for object add operator */
static int object_add_exec(bContext *C, wmOperator *op)
{
- object_add_type(C, RNA_int_get(op->ptr, "type"));
+ object_add_type(C, RNA_enum_get(op->ptr, "type"));
return OPERATOR_FINISHED;
}
@@ -189,6 +192,90 @@ void OBJECT_OT_add(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", "");
}
+/********************* Add Effector Operator ********************/
+/* copy from rna_object_force.c*/
+static EnumPropertyItem field_type_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {PFIELD_FORCE, "FORCE", 0, "Force", ""},
+ {PFIELD_WIND, "WIND", 0, "Wind", ""},
+ {PFIELD_VORTEX, "VORTEX", 0, "Vortex", ""},
+ {PFIELD_MAGNET, "MAGNET", 0, "Magnetic", ""},
+ {PFIELD_HARMONIC, "HARMONIC", 0, "Harmonic", ""},
+ {PFIELD_CHARGE, "CHARGE", 0, "Charge", ""},
+ {PFIELD_LENNARDJ, "LENNARDJ", 0, "Lennard-Jones", ""},
+ {PFIELD_TEXTURE, "TEXTURE", 0, "Texture", ""},
+ {PFIELD_GUIDE, "GUIDE", 0, "Curve Guide", ""},
+ {PFIELD_BOID, "BOID", 0, "Boid", ""},
+ {PFIELD_TURBULENCE, "TURBULENCE", 0, "Turbulence", ""},
+ {PFIELD_DRAG, "DRAG", 0, "Drag", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+void add_effector_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menus, only non-editmode stuff */
+{
+ /* keep here to get things compile, remove later */
+}
+
+/* for effector add primitive operators */
+static Object *effector_add_type(bContext *C, int type)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob;
+
+ /* for as long scene has editmode... */
+ if (CTX_data_edit_object(C))
+ ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
+
+ /* deselects all, sets scene->basact */
+ if(type==PFIELD_GUIDE) {
+ ob = add_object(scene, OB_CURVE);
+ ((Curve*)ob->data)->flag |= CU_PATH|CU_3D;
+ ED_object_enter_editmode(C, 0);
+ BLI_addtail(curve_get_editcurve(ob), add_nurbs_primitive(C, CU_NURBS|CU_PRIM_PATH, 1));
+ ED_object_exit_editmode(C, EM_FREEDATA);
+ }
+ else
+ ob= add_object(scene, OB_EMPTY);
+
+ ob->pd= object_add_collision_fields(type);
+
+ /* editor level activate, notifiers */
+ ED_base_object_activate(C, BASACT);
+
+ /* more editor stuff */
+ ED_object_base_init_from_view(C, BASACT);
+
+ DAG_scene_sort(scene);
+
+ return ob;
+}
+
+/* for object add operator */
+static int effector_add_exec(bContext *C, wmOperator *op)
+{
+ effector_add_type(C, RNA_int_get(op->ptr, "type"));
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_effector_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Effector";
+ ot->description = "Add an empty object with a physics effector to the scene.";
+ ot->idname= "OBJECT_OT_effector_add";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= effector_add_exec;
+
+ ot->poll= ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", "");
+}
+
/* ***************** add primitives *************** */
/* ****** work both in and outside editmode ****** */
@@ -307,7 +394,6 @@ static int object_add_curve_exec(bContext *C, wmOperator *op)
/* userdef */
if (newob && (U.flag & USER_ADD_EDITMODE)==0) {
- ED_object_enter_editmode(C, 0);
ED_object_exit_editmode(C, EM_FREEDATA);
}
@@ -468,7 +554,7 @@ static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *even
void OBJECT_OT_metaball_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Metaball";
+ ot->name= "Add Metaball";
ot->description= "Add an metaball object to the scene.";
ot->idname= "OBJECT_OT_metaball_add";
@@ -560,6 +646,45 @@ void OBJECT_OT_armature_add(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+static int object_lamp_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob;
+ int type= RNA_enum_get(op->ptr, "type");
+
+ ob= object_add_type(C, OB_LAMP);
+ if(ob && ob->data)
+ ((Lamp*)ob->data)->type= type;
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_lamp_add(wmOperatorType *ot)
+{
+ static EnumPropertyItem lamp_type_items[] = {
+ {LA_LOCAL, "POINT", ICON_LAMP_POINT, "Point", "Omnidirectional point light source."},
+ {LA_SUN, "SUN", ICON_LAMP_SUN, "Sun", "Constant direction parallel ray light source."},
+ {LA_SPOT, "SPOT", ICON_LAMP_SPOT, "Spot", "Directional cone light source."},
+ {LA_HEMI, "HEMI", ICON_LAMP_HEMI, "Hemi", "180 degree constant light source."},
+ {LA_AREA, "AREA", ICON_LAMP_AREA, "Area", "Directional area light source."},
+ {0, NULL, 0, NULL, NULL}};
+
+ /* identifiers */
+ ot->name= "Add Lamp";
+ ot->description = "Add a lamp object to the scene.";
+ ot->idname= "OBJECT_OT_lamp_add";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= object_lamp_add_exec;
+ ot->poll= ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", "");
+}
+
static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0);
@@ -568,7 +693,7 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve
uiItemMenuEnumO(layout, "Mesh", ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type");
uiItemMenuEnumO(layout, "Curve", ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type");
uiItemMenuEnumO(layout, "Surface", ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type");
- uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type");
+ uiItemMenuEnumO(layout, "Metaball", ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type");
uiItemO(layout, "Text", ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add");
uiItemS(layout);
uiItemO(layout, "Armature", ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add");
@@ -576,7 +701,9 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve
uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_add", "type", OB_EMPTY);
uiItemS(layout);
uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_add", "type", OB_CAMERA);
- uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LAMP, "OBJECT_OT_add", "type", OB_LAMP);
+ uiItemMenuEnumO(layout, "Lamp", ICON_OUTLINER_OB_LAMP, "OBJECT_OT_lamp_add", "type");
+ uiItemS(layout);
+ uiItemMenuEnumO(layout, "Force Field", ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_effector_add", "type");
uiPupMenuEnd(C, pup);
@@ -886,7 +1013,7 @@ static int convert_poll(bContext *C)
static int convert_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Base *basen=NULL, *basact, *basedel=NULL;
+ Base *basen=NULL, *basact=NULL, *basedel=NULL;
Object *ob, *ob1, *obact= CTX_data_active_object(C);
DerivedMesh *dm;
Curve *cu;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 9b073ed5878..8c0da354938 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -56,6 +56,7 @@
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_utildefines.h"
+#include "BIK_api.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -334,6 +335,7 @@ static void test_constraints (Object *owner, const char substring[])
* optional... otherwise poletarget must exist too or else
* the constraint is deemed invalid
*/
+ /* default IK check ... */
if (exist_object(data->tar) == 0) {
data->tar = NULL;
curcon->flag |= CONSTRAINT_DISABLE;
@@ -355,7 +357,8 @@ static void test_constraints (Object *owner, const char substring[])
}
}
}
-
+ /* ... can be overwritten here */
+ BIK_test_constraint(owner, curcon);
/* targets have already been checked for this */
continue;
}
@@ -702,6 +705,25 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con)
}
}
+void ED_object_constraint_update(Object *ob)
+{
+
+ if(ob->pose) update_pose_constraint_flags(ob->pose);
+
+ object_test_constraints(ob);
+
+ if(ob->type==OB_ARMATURE) DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB);
+ else DAG_id_flush_update(&ob->id, OB_RECALC_OB);
+}
+
+void ED_object_constraint_dependency_update(Scene *scene, Object *ob)
+{
+ ED_object_constraint_update(ob);
+
+ if(ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
+ DAG_scene_sort(scene);
+}
+
static int constraint_poll(bContext *C)
{
PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
@@ -717,6 +739,10 @@ static int constraint_delete_exec (bContext *C, wmOperator *op)
/* remove constraint itself */
lb= get_active_constraints(ob);
+ if (BLI_findindex(lb, con) == -1)
+ /* abnormal situation which happens on bone constraint when the armature is not in pose mode */
+ return OPERATOR_CANCELLED;
+
free_constraint_data(con);
BLI_freelinkN(lb, con);
@@ -823,17 +849,22 @@ void CONSTRAINT_OT_move_up (wmOperatorType *ot)
static int pose_constraints_clear_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_active_object(C);
+ Scene *scene= CTX_data_scene(C);
/* free constraints for all selected bones */
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
{
free_constraints(&pchan->constraints);
+ pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_CONST);
}
CTX_DATA_END;
+ /* force depsgraph to get recalculated since relationships removed */
+ DAG_scene_sort(scene); /* sort order of objects */
+
/* do updates */
- DAG_id_flush_update(&ob->id, OB_RECALC_OB);
- WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
return OPERATOR_FINISHED;
}
@@ -854,14 +885,18 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
static int object_constraints_clear_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_active_object(C);
+ Scene *scene= CTX_data_scene(C);
/* do freeing */
// TODO: we should free constraints for all selected objects instead (to be more consistent with bones)
free_constraints(&ob->constraints);
+ /* force depsgraph to get recalculated since relationships removed */
+ DAG_scene_sort(scene); /* sort order of objects */
+
/* do updates */
DAG_id_flush_update(&ob->id, OB_RECALC_OB);
- WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
return OPERATOR_FINISHED;
}
@@ -910,7 +945,6 @@ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_o
/* restricted target-type constraints -------------- */
/* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */
/* curve-based constraints - set the only_curve and only_ob flags */
- case CONSTRAINT_TYPE_TRACKTO:
case CONSTRAINT_TYPE_CLAMPTO:
case CONSTRAINT_TYPE_FOLLOWPATH:
only_curve= 1;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index daa63da03db..54df3ae92da 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -332,12 +332,23 @@ void ED_object_exit_editmode(bContext *C, int flag)
if(freedata) free_editMball(obedit);
}
- /* freedata only 0 now on file saves */
+ /* freedata only 0 now on file saves and render */
if(freedata) {
+ ListBase pidlist;
+ PTCacheID *pid;
+
/* for example; displist make is different in editmode */
scene->obedit= NULL; // XXX for context
+
+ /* flag object caches as outdated */
+ BKE_ptcache_ids_from_object(&pidlist, obedit);
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
+ pid->cache->flag |= PTCACHE_OUTDATED;
+ }
+ BLI_freelistN(&pidlist);
- BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH);
+ BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
/* also flush ob recalc, doesn't take much overhead, but used for particles */
DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA);
@@ -347,10 +358,10 @@ void ED_object_exit_editmode(bContext *C, int flag)
if(flag & EM_WAITCURSOR) waitcursor(0);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
- }
- obedit->mode &= ~OB_MODE_EDIT;
- ED_object_toggle_modes(C, obedit->restore_mode);
+ obedit->mode &= ~OB_MODE_EDIT;
+ ED_object_toggle_modes(C, obedit->restore_mode);
+ }
}
@@ -1947,29 +1958,26 @@ static int object_mode_set_compat(bContext *C, wmOperator *op, Object *ob)
ObjectMode mode = RNA_enum_get(op->ptr, "mode");
if(ob) {
+ if(mode == OB_MODE_OBJECT)
+ return 1;
+
switch(ob->type) {
- case OB_EMPTY:
- case OB_LAMP:
- case OB_CAMERA:
- if(mode & OB_MODE_OBJECT)
- return 1;
- return 0;
case OB_MESH:
- if(mode & ( OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT))
+ if(mode & (OB_MODE_EDIT|OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT))
return 1;
return 0;
case OB_CURVE:
case OB_SURF:
case OB_FONT:
case OB_MBALL:
- if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT))
+ if(mode & (OB_MODE_EDIT))
return 1;
return 0;
case OB_LATTICE:
- if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT))
+ if(mode & (OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT))
return 1;
case OB_ARMATURE:
- if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_POSE))
+ if(mode & (OB_MODE_EDIT|OB_MODE_POSE))
return 1;
}
}
@@ -1985,7 +1993,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
int toggle = RNA_boolean_get(op->ptr, "toggle");
if(!ob || !object_mode_set_compat(C, op, ob))
- return OPERATOR_CANCELLED;
+ return OPERATOR_PASS_THROUGH;
/* Exit current mode if it's not the mode we're setting */
if(ob->mode != OB_MODE_OBJECT && ob->mode != mode)
@@ -2026,7 +2034,7 @@ void OBJECT_OT_mode_set(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- prop= RNA_def_enum(ot->srna, "mode", object_mode_items, 0, "Mode", "");
+ prop= RNA_def_enum(ot->srna, "mode", object_mode_items, OB_MODE_OBJECT, "Mode", "");
RNA_def_enum_funcs(prop, object_mode_set_itemsf);
RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 7d52e9c7c56..474715c593b 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -79,6 +79,7 @@ void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
void OBJECT_OT_select_linked(struct wmOperatorType *ot);
void OBJECT_OT_select_grouped(struct wmOperatorType *ot);
void OBJECT_OT_select_mirror(struct wmOperatorType *ot);
+void OBJECT_OT_select_name(struct wmOperatorType *ot);
/* object_add.c */
void OBJECT_OT_add(struct wmOperatorType *ot);
@@ -88,7 +89,9 @@ void OBJECT_OT_surface_add(struct wmOperatorType *ot);
void OBJECT_OT_metaball_add(struct wmOperatorType *ot);
void OBJECT_OT_text_add(struct wmOperatorType *ot);
void OBJECT_OT_armature_add(struct wmOperatorType *ot);
+void OBJECT_OT_lamp_add(struct wmOperatorType *ot);
void OBJECT_OT_primitive_add(struct wmOperatorType *ot); /* only used as menu */
+void OBJECT_OT_effector_add(struct wmOperatorType *ot);
void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot);
void OBJECT_OT_duplicate(struct wmOperatorType *ot);
@@ -173,5 +176,9 @@ void OBJECT_OT_game_property_remove(struct wmOperatorType *ot);
void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);
void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot);
+/* object_group.c */
+void OBJECT_OT_group_add(struct wmOperatorType *ot);
+void OBJECT_OT_group_remove(struct wmOperatorType *ot);
+
#endif /* ED_OBJECT_INTERN_H */
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index cc8cc420bf7..7f0f1876417 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -110,7 +110,7 @@ int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int ty
}
else if(type == eModifierType_Collision) {
if(!ob->pd)
- ob->pd= object_add_collision_fields();
+ ob->pd= object_add_collision_fields(0);
ob->pd->deflect= 1;
DAG_scene_sort(scene);
@@ -159,8 +159,8 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod
DAG_scene_sort(scene);
}
else if(md->type == eModifierType_Surface) {
- if(ob->pd)
- ob->pd->flag &= ~PFIELD_SURFACE;
+ if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
+ ob->pd->shape = PFIELD_SHAPE_PLANE;
DAG_scene_sort(scene);
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index ddcecdeb1f1..9bfd6a4201c 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -102,6 +102,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_select_linked);
WM_operatortype_append(OBJECT_OT_select_grouped);
WM_operatortype_append(OBJECT_OT_select_mirror);
+ WM_operatortype_append(OBJECT_OT_select_name); /* XXX - weak, not compat with linked objects */
WM_operatortype_append(GROUP_OT_group_create);
WM_operatortype_append(GROUP_OT_objects_remove);
@@ -114,7 +115,9 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_text_add);
WM_operatortype_append(OBJECT_OT_surface_add);
WM_operatortype_append(OBJECT_OT_armature_add);
+ WM_operatortype_append(OBJECT_OT_lamp_add);
WM_operatortype_append(OBJECT_OT_add);
+ WM_operatortype_append(OBJECT_OT_effector_add);
WM_operatortype_append(OBJECT_OT_primitive_add);
WM_operatortype_append(OBJECT_OT_mesh_add);
WM_operatortype_append(OBJECT_OT_metaball_add);
@@ -174,6 +177,9 @@ void ED_operatortypes_object(void)
WM_operatortype_append(LATTICE_OT_select_all_toggle);
WM_operatortype_append(LATTICE_OT_make_regular);
+
+ WM_operatortype_append(OBJECT_OT_group_add);
+ WM_operatortype_append(OBJECT_OT_group_remove);
/* macros */
ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
@@ -183,11 +189,19 @@ void ED_operatortypes_object(void)
}
}
+static int object_mode_poll(bContext *C)
+{
+ Object *ob= CTX_data_active_object(C);
+ return (!ob || ob->mode == OB_MODE_OBJECT);
+}
+
void ED_keymap_object(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0);
+ wmKeyMap *keymap;
wmKeymapItem *kmi;
+ keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0);
+
/* Note: this keymap works disregarding mode */
WM_keymap_add_item(keymap, "OBJECT_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_posemode_toggle", TABKEY, KM_PRESS, KM_CTRL, 0);
@@ -202,7 +216,8 @@ void ED_keymap_object(wmWindowManager *wm)
WM_keymap_add_item(keymap, "OBJECT_OT_center_set", CKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_CTRL, 0);
/* Note: this keymap gets disabled in non-objectmode, */
- keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0);
+ keymap= WM_keymap_find(wm, "Object Mode", 0, 0);
+ keymap->poll= object_mode_poll;
WM_keymap_add_item(keymap, "OBJECT_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -227,11 +242,13 @@ void ED_keymap_object(wmWindowManager *wm)
WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
- WM_keymap_verify_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1);
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "OBJECT_OT_convert", CKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
@@ -244,7 +261,8 @@ void ED_keymap_object(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
/* Lattice */
- keymap= WM_keymap_listbase(wm, "Lattice", 0, 0);
+ keymap= WM_keymap_find(wm, "Lattice", 0, 0);
+ keymap->poll= ED_operator_editlattice;
WM_keymap_add_item(keymap, "LATTICE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 12cb2b95e06..4a0c812f7b1 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -566,8 +566,9 @@ static int parent_set_exec(bContext *C, wmOperator *op)
}
else cu->flag |= CU_FOLLOW;
- /* fall back on regular parenting now */
- partype= PAR_OBJECT;
+ /* fall back on regular parenting now (for follow only) */
+ if(partype == PAR_FOLLOW)
+ partype= PAR_OBJECT;
}
}
else if(partype==PAR_BONE) {
@@ -593,7 +594,9 @@ static int parent_set_exec(bContext *C, wmOperator *op)
/* apply transformation of previous parenting */
ED_object_apply_obmat(ob);
- ob->parent= par;
+ /* set the parent (except for follow-path constraint option) */
+ if(partype != PAR_PATH_CONST)
+ ob->parent= par;
/* handle types */
if (pchan)
@@ -602,7 +605,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
ob->parsubstr[0]= 0;
/* constraint */
- if(partype==PAR_PATH_CONST) {
+ if(partype == PAR_PATH_CONST) {
bConstraint *con;
bFollowPathConstraint *data;
float cmat[4][4], vec[3];
@@ -620,6 +623,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
ob->loc[0] = vec[0];
ob->loc[1] = vec[1];
+ ob->loc[2] = vec[2];
}
else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) {
if(partype == PAR_ARMATURE_NAME)
@@ -645,8 +649,12 @@ static int parent_set_exec(bContext *C, wmOperator *op)
ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
+ if(partype == PAR_PATH_CONST)
+ ; /* don't do anything here, since this is not technically "parenting" */
if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm )
ob->partype= PARSKEL; /* note, dna define, not operator property */
+ else if (partype == PAR_BONE)
+ ob->partype= PARBONE; /* note, dna define, not operator property */
else
ob->partype= PAROBJECT; /* note, dna define, not operator property */
}
@@ -986,7 +994,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
if(lay==0) return OPERATOR_CANCELLED;
- if(v3d && v3d->localview) {
+ if(v3d && v3d->localvd) {
/* now we can move out of localview. */
// XXX if (!okee("Move from localview")) return;
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 50ba4ab2934..98603ee843a 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
#include "DNA_group_types.h"
#include "DNA_material_types.h"
#include "DNA_modifier_types.h"
@@ -53,6 +55,7 @@
#include "BKE_property.h"
#include "BKE_report.h"
#include "BKE_scene.h"
+#include "BKE_utildefines.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -117,22 +120,16 @@ void ED_base_object_activate(bContext *C, Base *base)
/********************** Selection Operators **********************/
-static EnumPropertyItem prop_select_types[] = {
- {0, "EXCLUSIVE", 0, "Exclusive", ""},
- {1, "EXTEND", 0, "Extend", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
/************************ Select by Type *************************/
static int object_select_by_type_exec(bContext *C, wmOperator *op)
{
- short obtype, seltype;
+ short obtype, extend;
obtype = RNA_enum_get(op->ptr, "type");
- seltype = RNA_enum_get(op->ptr, "seltype");
+ extend= RNA_boolean_get(op->ptr, "extend");
- if (seltype == 0) {
+ if (extend == 0) {
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
ED_base_object_select(base, BA_DESELECT);
}
@@ -166,9 +163,9 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_enum(ot->srna, "seltype", prop_select_types, 0, "Selection", "Extend selection or clear selection then select");
+ /* properties */
+ RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
RNA_def_enum(ot->srna, "type", object_type_items, 1, "Type", "");
-
}
/*********************** Selection by Links *********************/
@@ -192,7 +189,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
Tex *tex=0;
int a, b;
int nr = RNA_enum_get(op->ptr, "type");
- short changed = 0, seltype;
+ short changed = 0, extend;
/* events (nr):
* Object Ipo: 1
* ObData: 2
@@ -202,9 +199,9 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
* PSys: 6
*/
- seltype = RNA_enum_get(op->ptr, "seltype");
+ extend= RNA_boolean_get(op->ptr, "extend");
- if (seltype == 0) {
+ if (extend == 0) {
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
ED_base_object_select(base, BA_DESELECT);
}
@@ -327,9 +324,9 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ /* properties */
+ RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", "");
- RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
-
}
/*********************** Selected Grouped ********************/
@@ -575,11 +572,11 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *ob;
int nr = RNA_enum_get(op->ptr, "type");
- short changed = 0, seltype;
+ short changed = 0, extend;
- seltype = RNA_enum_get(op->ptr, "seltype");
+ extend= RNA_boolean_get(op->ptr, "extend");
- if (seltype == 0) {
+ if (extend == 0) {
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
ED_base_object_select(base, BA_DESELECT);
}
@@ -628,8 +625,8 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
+ RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
- RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
}
/************************* Select by Layer **********************/
@@ -637,12 +634,12 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
static int object_select_by_layer_exec(bContext *C, wmOperator *op)
{
unsigned int layernum;
- short seltype;
+ short extend;
- seltype = RNA_enum_get(op->ptr, "seltype");
+ extend= RNA_boolean_get(op->ptr, "extend");
layernum = RNA_int_get(op->ptr, "layer");
- if (seltype == 0) {
+ if (extend == 0) {
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
ED_base_object_select(base, BA_DESELECT);
}
@@ -676,8 +673,9 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ /* properties */
+ RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
RNA_def_int(ot->srna, "layer", 1, 1, 20, "Layer", "", 1, 20);
- RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
}
/************************** Select Inverse *************************/
@@ -878,9 +876,9 @@ void object_flip_name (char *name)
static int object_select_mirror_exec(bContext *C, wmOperator *op)
{
char tmpname[32];
- short seltype;
+ short extend;
- seltype = RNA_enum_get(op->ptr, "seltype");
+ extend= RNA_boolean_get(op->ptr, "extend");
CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) {
@@ -894,7 +892,7 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- if (seltype == 0) ED_base_object_select(primbase, BA_DESELECT);
+ if (extend == 0) ED_base_object_select(primbase, BA_DESELECT);
}
CTX_DATA_END;
@@ -920,7 +918,60 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first.");
+}
+
+
+static int object_select_name_exec(bContext *C, wmOperator *op)
+{
+ char *name= RNA_string_get_alloc(op->ptr, "name", NULL, 0);
+ short extend= RNA_boolean_get(op->ptr, "extend");
+ short changed = 0;
+
+ if(!extend) {
+ CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+ ED_base_object_select(base, BA_DESELECT);
+ }
+ CTX_DATA_END;
+ }
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if(strcmp(name, base->object->id.name+2)==0) {
+ ED_base_object_select(base, BA_SELECT);
+ changed= 1;
+ }
+ }
+ CTX_DATA_END;
+
+ MEM_freeN(name);
+
+ /* undo? */
+ if(changed) {
+ WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void OBJECT_OT_select_name(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Select Name";
+ ot->description = "Select an object with this name";
+ ot->idname= "OBJECT_OT_select_name";
+
+ /* api callbacks */
+ ot->exec= object_select_name_exec;
+ ot->poll= ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_string(ot->srna, "name", "", 0, "Name", "Object name to select.");
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first.");
}
/**************************** Select Random ****************************/
@@ -928,11 +979,11 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
static int object_select_random_exec(bContext *C, wmOperator *op)
{
float percent;
- short seltype;
+ short extend;
- seltype = RNA_enum_get(op->ptr, "seltype");
+ extend= RNA_boolean_get(op->ptr, "extend");
- if (seltype == 0) {
+ if (extend == 0) {
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
ED_base_object_select(base, BA_DESELECT);
}
@@ -967,8 +1018,9 @@ void OBJECT_OT_select_random(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ /* properties */
+ RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "percentage of objects to randomly select", 0.0001f, 1.0f);
- RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
}
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 2b207f2f27c..cd0d97eed44 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
+#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
@@ -115,13 +116,72 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
- /* eulers can only get cleared if they are not protected */
- if((ob->protectflag & OB_LOCK_ROTX)==0)
- ob->rot[0]= ob->drot[0]= 0.0f;
- if((ob->protectflag & OB_LOCK_ROTY)==0)
- ob->rot[1]= ob->drot[1]= 0.0f;
- if((ob->protectflag & OB_LOCK_ROTZ)==0)
- ob->rot[2]= ob->drot[2]= 0.0f;
+ if (ob->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) {
+ /* check if convert to eulers for locking... */
+ if (ob->protectflag & OB_LOCK_ROT4D) {
+ /* perform clamping on a component by component basis */
+ if ((ob->protectflag & OB_LOCK_ROTW) == 0)
+ ob->quat[0]= (ob->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f;
+ if ((ob->protectflag & OB_LOCK_ROTX) == 0)
+ ob->quat[1]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTY) == 0)
+ ob->quat[2]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTZ) == 0)
+ ob->quat[3]= 0.0f;
+ }
+ else {
+ /* perform clamping using euler form (3-components) */
+ float eul[3], oldeul[3], quat1[4];
+
+ if (ob->rotmode == ROT_MODE_QUAT) {
+ QUATCOPY(quat1, ob->quat);
+ QuatToEul(ob->quat, oldeul);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT);
+ }
+ else {
+ VECCOPY(oldeul, ob->rot);
+ }
+
+ eul[0]= eul[1]= eul[2]= 0.0f;
+
+ if (ob->protectflag & OB_LOCK_ROTX)
+ eul[0]= oldeul[0];
+ if (ob->protectflag & OB_LOCK_ROTY)
+ eul[1]= oldeul[1];
+ if (ob->protectflag & OB_LOCK_ROTZ)
+ eul[2]= oldeul[2];
+
+ if (ob->rotmode == ROT_MODE_QUAT) {
+ EulToQuat(eul, ob->quat);
+ /* quaternions flip w sign to accumulate rotations correctly */
+ if ((quat1[0]<0.0f && ob->quat[0]>0.0f) || (quat1[0]>0.0f && ob->quat[0]<0.0f)) {
+ QuatMulf(ob->quat, -1.0f);
+ }
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT);
+ }
+ else {
+ VECCOPY(ob->rot, eul);
+ }
+ }
+ }
+ else {
+ if (ob->rotmode == ROT_MODE_QUAT) {
+ ob->quat[1]=ob->quat[2]=ob->quat[3]= 0.0f;
+ ob->quat[0]= 1.0f;
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ /* by default, make rotation of 0 radians around y-axis (roll) */
+ ob->quat[0]=ob->quat[1]=ob->quat[3]= 0.0f;
+ ob->quat[2]= 1.0f;
+ }
+ else {
+ ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f;
+ }
+ }
}
ob->recalc |= OB_RECALC_OB;
}
diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript
index 5718ae0c217..60b992d2e07 100644
--- a/source/blender/editors/physics/SConscript
+++ b/source/blender/editors/physics/SConscript
@@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' #/intern/guardedalloc ../../gpu'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_physics', sources, Split(incs), [], libtype=['core'], priority=[45] )
diff --git a/source/blender/editors/physics/physics_boids.c b/source/blender/editors/physics/particle_boids.c
index 148359068ad..0b63f1a98ff 100644
--- a/source/blender/editors/physics/physics_boids.c
+++ b/source/blender/editors/physics/particle_boids.c
@@ -25,35 +25,21 @@
* ***** END GPL LICENSE BLOCK *****
*/
-//#include <stdlib.h>
-//#include <string.h>
-//
+#include <stdlib.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_boid_types.h"
#include "DNA_particle_types.h"
-//#include "DNA_curve_types.h"
#include "DNA_object_types.h"
-//#include "DNA_material_types.h"
-//#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
-//#include "DNA_world_types.h"
#include "BKE_boids.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-//#include "BKE_font.h"
-//#include "BKE_library.h"
-//#include "BKE_main.h"
-//#include "BKE_material.h"
#include "BKE_particle.h"
-//#include "BKE_texture.h"
-//#include "BKE_utildefines.h"
-//#include "BKE_world.h"
-//#include "BLI_editVert.h"
#include "BLI_listbase.h"
-//
#include "RNA_access.h"
#include "RNA_enum_types.h"
#include "RNA_define.h"
@@ -61,13 +47,10 @@
#include "WM_api.h"
#include "WM_types.h"
-//#include "ED_curve.h"
-//#include "ED_mesh.h"
-//
-//#include "buttons_intern.h" // own include
+#include "physics_intern.h"
/************************ add/del boid rule operators *********************/
-static int boidrule_add_exec(bContext *C, wmOperator *op)
+static int rule_add_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
@@ -95,29 +78,29 @@ static int boidrule_add_exec(bContext *C, wmOperator *op)
BLI_addtail(&state->rules, rule);
- psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
return OPERATOR_FINISHED;
}
-void BOID_OT_boidrule_add(wmOperatorType *ot)
+void BOID_OT_rule_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Boid Rule";
ot->description = "Add a boid rule to the current boid state.";
- ot->idname= "BOID_OT_boidrule_add";
+ ot->idname= "BOID_OT_rule_add";
/* api callbacks */
ot->invoke= WM_menu_invoke;
- ot->exec= boidrule_add_exec;
+ ot->exec= rule_add_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_enum(ot->srna, "type", boidrule_type_items, 0, "Type", "");
}
-static int boidrule_del_exec(bContext *C, wmOperator *op)
+static int rule_del_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
@@ -146,28 +129,28 @@ static int boidrule_del_exec(bContext *C, wmOperator *op)
rule->flag |= BOIDRULE_CURRENT;
DAG_scene_sort(scene);
- psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
return OPERATOR_FINISHED;
}
-void BOID_OT_boidrule_del(wmOperatorType *ot)
+void BOID_OT_rule_del(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Remove Boid Rule";
- ot->idname= "BOID_OT_boidrule_del";
+ ot->idname= "BOID_OT_rule_del";
/* api callbacks */
- ot->exec= boidrule_del_exec;
+ ot->exec= rule_del_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/************************ move up/down boid rule operators *********************/
-static int boidrule_move_up_exec(bContext *C, wmOperator *op)
+static int rule_move_up_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
@@ -185,7 +168,7 @@ static int boidrule_move_up_exec(bContext *C, wmOperator *op)
BLI_remlink(&state->rules, rule);
BLI_insertlink(&state->rules, rule->prev->prev, rule);
- psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
break;
}
@@ -194,19 +177,19 @@ static int boidrule_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void BOID_OT_boidrule_move_up(wmOperatorType *ot)
+void BOID_OT_rule_move_up(wmOperatorType *ot)
{
ot->name= "Move Up Boid Rule";
ot->description= "Move boid rule up in the list.";
- ot->idname= "BOID_OT_boidrule_move_up";
+ ot->idname= "BOID_OT_rule_move_up";
- ot->exec= boidrule_move_up_exec;
+ ot->exec= rule_move_up_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int boidrule_move_down_exec(bContext *C, wmOperator *op)
+static int rule_move_down_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
@@ -224,7 +207,7 @@ static int boidrule_move_down_exec(bContext *C, wmOperator *op)
BLI_remlink(&state->rules, rule);
BLI_insertlink(&state->rules, rule->next, rule);
- psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
break;
}
@@ -233,13 +216,13 @@ static int boidrule_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void BOID_OT_boidrule_move_down(wmOperatorType *ot)
+void BOID_OT_rule_move_down(wmOperatorType *ot)
{
ot->name= "Move Down Boid Rule";
ot->description= "Move boid rule down in the list.";
- ot->idname= "BOID_OT_boidrule_move_down";
+ ot->idname= "BOID_OT_rule_move_down";
- ot->exec= boidrule_move_down_exec;
+ ot->exec= rule_move_down_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -247,7 +230,7 @@ void BOID_OT_boidrule_move_down(wmOperatorType *ot)
/************************ add/del boid state operators *********************/
-static int boidstate_add_exec(bContext *C, wmOperator *op)
+static int state_add_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= ptr.data;
@@ -273,20 +256,20 @@ static int boidstate_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void BOID_OT_boidstate_add(wmOperatorType *ot)
+void BOID_OT_state_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Boid State";
ot->description = "Add a boid state to the particle system.";
- ot->idname= "BOID_OT_boidstate_add";
+ ot->idname= "BOID_OT_state_add";
/* api callbacks */
- ot->exec= boidstate_add_exec;
+ ot->exec= state_add_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int boidstate_del_exec(bContext *C, wmOperator *op)
+static int state_del_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
@@ -320,28 +303,28 @@ static int boidstate_del_exec(bContext *C, wmOperator *op)
state->flag |= BOIDSTATE_CURRENT;
DAG_scene_sort(scene);
- psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
return OPERATOR_FINISHED;
}
-void BOID_OT_boidstate_del(wmOperatorType *ot)
+void BOID_OT_state_del(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Remove Boid State";
- ot->idname= "BOID_OT_boidstate_del";
+ ot->idname= "BOID_OT_state_del";
/* api callbacks */
- ot->exec= boidstate_del_exec;
+ ot->exec= state_del_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/************************ move up/down boid state operators *********************/
-static int boidstate_move_up_exec(bContext *C, wmOperator *op)
+static int state_move_up_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= ptr.data;
@@ -366,19 +349,19 @@ static int boidstate_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void BOID_OT_boidstate_move_up(wmOperatorType *ot)
+void BOID_OT_state_move_up(wmOperatorType *ot)
{
ot->name= "Move Up Boid State";
ot->description= "Move boid state up in the list.";
- ot->idname= "BOID_OT_boidstate_move_up";
+ ot->idname= "BOID_OT_state_move_up";
- ot->exec= boidstate_move_up_exec;
+ ot->exec= state_move_up_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int boidstate_move_down_exec(bContext *C, wmOperator *op)
+static int state_move_down_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
@@ -395,7 +378,7 @@ static int boidstate_move_down_exec(bContext *C, wmOperator *op)
if(state->flag & BOIDSTATE_CURRENT && state->next) {
BLI_remlink(&boids->states, state);
BLI_insertlink(&boids->states, state->next, state);
- psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
break;
}
}
@@ -403,28 +386,15 @@ static int boidstate_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void BOID_OT_boidstate_move_down(wmOperatorType *ot)
+void BOID_OT_state_move_down(wmOperatorType *ot)
{
ot->name= "Move Down Boid State";
ot->description= "Move boid state down in the list.";
- ot->idname= "BOID_OT_boidstate_move_down";
+ ot->idname= "BOID_OT_state_move_down";
- ot->exec= boidstate_move_down_exec;
+ ot->exec= state_move_down_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-/*******************************************************************************/
-void ED_operatortypes_boids(void)
-{
- WM_operatortype_append(BOID_OT_boidrule_add);
- WM_operatortype_append(BOID_OT_boidrule_del);
- WM_operatortype_append(BOID_OT_boidrule_move_up);
- WM_operatortype_append(BOID_OT_boidrule_move_down);
-
- WM_operatortype_append(BOID_OT_boidstate_add);
- WM_operatortype_append(BOID_OT_boidstate_del);
- WM_operatortype_append(BOID_OT_boidstate_move_up);
- WM_operatortype_append(BOID_OT_boidstate_move_down);
-}
diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/particle_edit.c
index 5acdcb40613..ac47ddebc1f 100644
--- a/source/blender/editors/physics/editparticle.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -106,35 +106,32 @@ static void PTCacheUndo_clear(PTCacheEdit *edit);
/**************************** utilities *******************************/
-static int PE_poll(bContext *C)
+int PE_poll(bContext *C)
{
Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_active_object(C);
- PTCacheEdit *edit;
- if(!scene || !ob)
+ if(!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
return 0;
- edit= PE_get_current(scene, ob);
-
- return (edit && (ob->mode & OB_MODE_PARTICLE_EDIT));
+ return (PE_get_current(scene, ob) != NULL);
}
-static int PE_hair_poll(bContext *C)
+int PE_hair_poll(bContext *C)
{
Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_active_object(C);
PTCacheEdit *edit;
- if(!scene || !ob)
+ if(!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
return 0;
edit= PE_get_current(scene, ob);
- return (edit && edit->psys && (ob->mode & OB_MODE_PARTICLE_EDIT));
+ return (edit && edit->psys);
}
-static int PE_poll_3dview(bContext *C)
+int PE_poll_3dview(bContext *C)
{
return PE_poll(C) && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW;
@@ -675,6 +672,9 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
psmd= psys_get_modifier(ob, psys);
totpart= psys->totpart;
+ if(!psmd->dm)
+ return;
+
tree= BLI_kdtree_new(totpart);
/* insert particles into kd tree */
@@ -803,6 +803,9 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
edit= psys->edit;
psmd= psys_get_modifier(ob, psys);
+ if(!edit->mirror_cache || !psmd->dm)
+ return;
+
/* we delay settings the PARS_EDIT_RECALC for mirrored particles
* to avoid doing mirror twice */
LOOP_POINTS {
@@ -841,6 +844,9 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
psys = edit->psys;
psmd = psys_get_modifier(ob,psys);
+ if(!psmd->dm)
+ return;
+
LOOP_EDITED_POINTS {
psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles + p, hairmat);
@@ -994,6 +1000,9 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys)
float *vec, *nor;
int i, totface, totvert;
+ if(!dm)
+ return;
+
if(edit->emitter_cosnos)
MEM_freeN(edit->emitter_cosnos);
@@ -1079,7 +1088,7 @@ static void update_world_cos(Object *ob, PTCacheEdit *edit)
POINT_P; KEY_K;
float hairmat[4][4];
- if(psys==0 || psys->edit==0)
+ if(psys==0 || psys->edit==0 || psmd->dm==NULL)
return;
LOOP_POINTS {
@@ -1184,6 +1193,9 @@ void PE_update_object(Scene *scene, Object *ob, int useflag)
point->flag &= ~PEP_EDIT_RECALC;
}
+ if(edit->psys)
+ edit->psys->flag &= ~PSYS_HAIR_UPDATED;
+
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
@@ -1761,6 +1773,7 @@ static void rekey_particle(PEData *data, int pa_index)
{
PTCacheEdit *edit= data->edit;
ParticleSystem *psys= edit->psys;
+ ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL};
ParticleData *pa= psys->particles + pa_index;
PTCacheEditPoint *point = edit->points + pa_index;
ParticleKey state;
@@ -1785,7 +1798,7 @@ static void rekey_particle(PEData *data, int pa_index)
/* interpolate new keys from old ones */
for(k=1,key++; k<data->totrekey-1; k++,key++) {
state.time= (float)k / (float)(data->totrekey-1);
- psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0);
+ psys_get_particle_on_path(&sim, pa_index, &state, 0);
VECCOPY(key->co, state.co);
key->time= sta + k * dval;
}
@@ -1853,6 +1866,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float
{
PTCacheEdit *edit= PE_get_current(scene, ob);
ParticleSystem *psys;
+ ParticleSimulationData sim = {scene, ob, edit ? edit->psys : NULL, NULL};
ParticleData *pa;
ParticleKey state;
HairKey *new_keys, *key;
@@ -1872,7 +1886,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float
/* interpolate new keys from old ones (roots stay the same) */
for(k=1, key++; k < pa->totkey; k++, key++) {
state.time= path_time * (float)k / (float)(pa->totkey-1);
- psys_get_particle_on_path(scene, ob, psys, pa_index, &state, 0);
+ psys_get_particle_on_path(&sim, pa_index, &state, 0);
VECCOPY(key->co, state.co);
}
@@ -2044,6 +2058,7 @@ static void subdivide_particle(PEData *data, int pa_index)
{
PTCacheEdit *edit= data->edit;
ParticleSystem *psys= edit->psys;
+ ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL};
ParticleData *pa= psys->particles + pa_index;
PTCacheEditPoint *point = edit->points + pa_index;
ParticleKey state;
@@ -2083,7 +2098,7 @@ static void subdivide_particle(PEData *data, int pa_index)
if(ekey->flag & PEK_SELECT && (ekey+1)->flag & PEK_SELECT) {
nkey->time= (key->time + (key+1)->time)*0.5f;
state.time= (endtime != 0.0f)? nkey->time/endtime: 0.0f;
- psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0);
+ psys_get_particle_on_path(&sim, pa_index, &state, 0);
VECCOPY(nkey->co, state.co);
nekey->co= nkey->co;
@@ -2438,6 +2453,8 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
return;
psmd= psys_get_modifier(ob, psys);
+ if(!psmd->dm)
+ return;
mirrorfaces= mesh_get_x_mirror_faces(ob, NULL);
@@ -2875,12 +2892,13 @@ static void brush_add(PEData *data, short number)
ParticleSystem *psys= edit->psys;
ParticleData *add_pars= MEM_callocN(number*sizeof(ParticleData),"ParticleData add");
ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys);
+ ParticleSimulationData sim = {scene, ob, psys, psmd};
ParticleEditSettings *pset= PE_settings(scene);
int i, k, n= 0, totpart= psys->totpart;
short mco[2];
short dmx= 0, dmy= 0;
float co1[3], co2[3], min_d, imat[4][4];
- float framestep, timestep= psys_get_timestep(psys->part);
+ float framestep, timestep= psys_get_timestep(&sim);
short size= pset->brush[PE_BRUSH_ADD].size;
short size2= size*size;
DerivedMesh *dm=0;
@@ -2975,8 +2993,8 @@ static void brush_add(PEData *data, short number)
}
pa->size= 1.0f;
- initialize_particle(pa,i,ob,psys,psmd);
- reset_particle(scene, pa,psys,psmd,ob,0.0,1.0,0,0,0);
+ initialize_particle(&sim, pa,i);
+ reset_particle(&sim, pa, 0.0, 1.0);
point->flag |= PEP_EDIT_RECALC;
if(pset->flag & PE_X_MIRROR)
point->flag |= PEP_TAG; /* signal for duplicate */
@@ -3013,18 +3031,18 @@ static void brush_add(PEData *data, short number)
hkey->time= pa->time + k * framestep;
key[0].time= hkey->time/ 100.0f;
- psys_get_particle_on_path(scene, ob, psys, ptn[0].index, key, 0);
+ psys_get_particle_on_path(&sim, ptn[0].index, key, 0);
VecMulf(key[0].co, weight[0]);
if(maxw>1) {
key[1].time= key[0].time;
- psys_get_particle_on_path(scene, ob, psys, ptn[1].index, key + 1, 0);
+ psys_get_particle_on_path(&sim, ptn[1].index, key + 1, 0);
VecMulf(key[1].co, weight[1]);
VECADD(key[0].co, key[0].co, key[1].co);
if(maxw>2) {
key[2].time= key[0].time;
- psys_get_particle_on_path(scene, ob, psys, ptn[2].index, key + 2, 0);
+ psys_get_particle_on_path(&sim, ptn[2].index, key + 2, 0);
VecMulf(key[2].co, weight[2]);
VECADD(key[0].co, key[0].co, key[2].co);
}
@@ -3345,7 +3363,7 @@ static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event)
brush_edit_apply_event(C, op, event);
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -3911,7 +3929,6 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
ParticleEditSettings *pset=PE_settings(scene);
- PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C));
uiPopupMenu *pup;
uiLayout *layout;
@@ -3942,58 +3959,3 @@ void PARTICLE_OT_specials_menu(wmOperatorType *ot)
ot->poll= PE_hair_poll;
}
-/**************************** registration **********************************/
-
-void ED_operatortypes_particle(void)
-{
- WM_operatortype_append(PARTICLE_OT_select_all_toggle);
- WM_operatortype_append(PARTICLE_OT_select_first);
- WM_operatortype_append(PARTICLE_OT_select_last);
- WM_operatortype_append(PARTICLE_OT_select_linked);
- WM_operatortype_append(PARTICLE_OT_select_less);
- WM_operatortype_append(PARTICLE_OT_select_more);
-
- WM_operatortype_append(PARTICLE_OT_hide);
- WM_operatortype_append(PARTICLE_OT_reveal);
-
- WM_operatortype_append(PARTICLE_OT_rekey);
- WM_operatortype_append(PARTICLE_OT_subdivide);
- WM_operatortype_append(PARTICLE_OT_remove_doubles);
- WM_operatortype_append(PARTICLE_OT_delete);
- WM_operatortype_append(PARTICLE_OT_mirror);
-
- WM_operatortype_append(PARTICLE_OT_brush_set);
- WM_operatortype_append(PARTICLE_OT_brush_edit);
- WM_operatortype_append(PARTICLE_OT_brush_radial_control);
-
- WM_operatortype_append(PARTICLE_OT_specials_menu);
-
- WM_operatortype_append(PARTICLE_OT_particle_edit_toggle);
- WM_operatortype_append(PARTICLE_OT_edited_clear);
-}
-
-void ED_keymap_particle(wmWindowManager *wm)
-{
- ListBase *keymap= WM_keymap_listbase(wm, "Particle", 0, 0);
-
- WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1);
-
- WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_delete", DELKEY, KM_PRESS, 0, 0);
-
- WM_keymap_add_item(keymap, "PARTICLE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0);
- RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
-
- WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
-
- WM_keymap_add_item(keymap, "PARTICLE_OT_specials_menu", WKEY, KM_PRESS, 0, 0);
-}
-
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
new file mode 100644
index 00000000000..cef630b6711
--- /dev/null
+++ b/source/blender/editors/physics/particle_object.c
@@ -0,0 +1,575 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_main.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_particle.h"
+
+#include "physics_intern.h"
+
+/********************** particle system slot operators *********************/
+
+static int particle_system_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Scene *scene = CTX_data_scene(C);
+
+ if(!scene || !ob)
+ return OPERATOR_CANCELLED;
+
+ object_add_particle_system(scene, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Particle System Slot";
+ ot->idname= "OBJECT_OT_particle_system_add";
+ ot->description="Add a particle system.";
+
+ /* api callbacks */
+ ot->exec= particle_system_add_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int particle_system_remove_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Scene *scene = CTX_data_scene(C);
+
+ if(!scene || !ob)
+ return OPERATOR_CANCELLED;
+
+ object_remove_particle_system(scene, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Particle System Slot";
+ ot->idname= "OBJECT_OT_particle_system_remove";
+ ot->description="Remove the selected particle system.";
+
+ /* api callbacks */
+ ot->exec= particle_system_remove_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new particle settings operator *********************/
+
+static int psys_poll(bContext *C)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ return (ptr.data != NULL);
+}
+
+static int new_particle_settings_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Main *bmain= CTX_data_main(C);
+ ParticleSystem *psys;
+ ParticleSettings *part = NULL;
+ Object *ob;
+ PointerRNA ptr;
+
+ ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+
+ psys = ptr.data;
+
+ /* add or copy particle setting */
+ if(psys->part)
+ part= psys_copy_settings(psys->part);
+ else
+ part= psys_new_settings("ParticleSettings", bmain);
+
+ ob= ptr.id.data;
+
+ if(psys->part)
+ psys->part->id.us--;
+
+ psys->part = part;
+
+ psys_check_boid_data(psys);
+
+ DAG_scene_sort(scene);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New Particle Settings";
+ ot->idname= "PARTICLE_OT_new";
+ ot->description="Add new particle settings.";
+
+ /* api callbacks */
+ ot->exec= new_particle_settings_exec;
+ ot->poll= psys_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** keyed particle target operators *********************/
+
+static int new_particle_target_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ ParticleSystem *psys= ptr.data;
+ Object *ob = ptr.id.data;
+
+ ParticleTarget *pt;
+
+ if(!psys)
+ return OPERATOR_CANCELLED;
+
+ pt = psys->targets.first;
+ for(; pt; pt=pt->next)
+ pt->flag &= ~PTARGET_CURRENT;
+
+ pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target");
+
+ pt->flag |= PTARGET_CURRENT;
+ pt->psys = 1;
+
+ BLI_addtail(&psys->targets, pt);
+
+ DAG_scene_sort(scene);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_new_target(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New Particle Target";
+ ot->idname= "PARTICLE_OT_new_target";
+ ot->description="Add a new particle target.";
+
+ /* api callbacks */
+ ot->exec= new_particle_target_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int remove_particle_target_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ ParticleSystem *psys= ptr.data;
+ Object *ob = ptr.id.data;
+
+ ParticleTarget *pt;
+
+ if(!psys)
+ return OPERATOR_CANCELLED;
+
+ pt = psys->targets.first;
+ for(; pt; pt=pt->next) {
+ if(pt->flag & PTARGET_CURRENT) {
+ BLI_remlink(&psys->targets, pt);
+ MEM_freeN(pt);
+ break;
+ }
+
+ }
+ pt = psys->targets.last;
+
+ if(pt)
+ pt->flag |= PTARGET_CURRENT;
+
+ DAG_scene_sort(scene);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_remove_target(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Particle Target";
+ ot->idname= "PARTICLE_OT_remove_target";
+ ot->description="Remove the selected particle target.";
+
+ /* api callbacks */
+ ot->exec= remove_particle_target_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/************************ move up particle target operator *********************/
+
+static int target_move_up_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ ParticleSystem *psys= ptr.data;
+ Object *ob = ptr.id.data;
+ ParticleTarget *pt;
+
+ if(!psys)
+ return OPERATOR_CANCELLED;
+
+ pt = psys->targets.first;
+ for(; pt; pt=pt->next) {
+ if(pt->flag & PTARGET_CURRENT && pt->prev) {
+ BLI_remlink(&psys->targets, pt);
+ BLI_insertlink(&psys->targets, pt->prev->prev, pt);
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ break;
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_target_move_up(wmOperatorType *ot)
+{
+ ot->name= "Move Up Target";
+ ot->idname= "PARTICLE_OT_target_move_up";
+ ot->description= "Move particle target up in the list.";
+
+ ot->exec= target_move_up_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/************************ move down particle target operator *********************/
+
+static int target_move_down_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ ParticleSystem *psys= ptr.data;
+ Object *ob = ptr.id.data;
+ ParticleTarget *pt;
+
+ if(!psys)
+ return OPERATOR_CANCELLED;
+ pt = psys->targets.first;
+ for(; pt; pt=pt->next) {
+ if(pt->flag & PTARGET_CURRENT && pt->next) {
+ BLI_remlink(&psys->targets, pt);
+ BLI_insertlink(&psys->targets, pt->next, pt);
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ break;
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_target_move_down(wmOperatorType *ot)
+{
+ ot->name= "Move Down Target";
+ ot->idname= "PARTICLE_OT_target_move_down";
+ ot->description= "Move particle target down in the list.";
+
+ ot->exec= target_move_down_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/************************ connect/disconnect hair operators *********************/
+
+static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+{
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ ParticleData *pa;
+ PTCacheEdit *edit;
+ PTCacheEditPoint *point;
+ PTCacheEditKey *ekey = NULL;
+ HairKey *key;
+ int i, k;
+ float hairmat[4][4];
+
+ if(!ob || !psys || psys->flag & PSYS_GLOBAL_HAIR)
+ return;
+
+ if(!psys->part || psys->part->type != PART_HAIR)
+ return;
+
+ edit = psys->edit;
+ point= edit ? edit->points : NULL;
+
+ for(i=0, pa=psys->particles; i<psys->totpart; i++,pa++) {
+ if(point) {
+ ekey = point->keys;
+ point++;
+ }
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ for(k=0,key=pa->hair; k<pa->totkey; k++,key++) {
+ Mat4MulVecfl(hairmat,key->co);
+
+ if(ekey) {
+ ekey->flag &= ~PEK_USE_WCO;
+ ekey++;
+ }
+ }
+ }
+
+ psys_free_path_cache(psys, psys->edit);
+
+ psys->flag |= PSYS_GLOBAL_HAIR;
+
+ PE_update_object(scene, ob, 0);
+}
+
+static int disconnect_hair_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ ParticleSystem *psys= NULL;
+ int all = RNA_boolean_get(op->ptr, "all");
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ if(all) {
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ disconnect_hair(scene, ob, psys);
+ }
+ }
+ else {
+ psys = ptr.data;
+ disconnect_hair(scene, ob, psys);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
+{
+ ot->name= "Disconnect Hair";
+ ot->description= "Disconnect hair from the emitter mesh.";
+ ot->idname= "PARTICLE_OT_disconnect_hair";
+
+ ot->exec= disconnect_hair_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ 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)
+{
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ ParticleData *pa;
+ PTCacheEdit *edit;
+ PTCacheEditPoint *point;
+ PTCacheEditKey *ekey;
+ HairKey *key;
+ BVHTreeFromMesh bvhtree;
+ BVHTreeNearest nearest;
+ MFace *mface;
+ DerivedMesh *dm = NULL;
+ int numverts;
+ int i, k;
+ float hairmat[4][4], imat[4][4];
+ float v[4][3], vec[3];
+
+ if(!psys || !psys->part || psys->part->type != PART_HAIR)
+ return;
+
+ edit= psys->edit;
+ point= edit ? edit->points : NULL;
+
+ if(psmd->dm->deformedOnly)
+ dm= psmd->dm;
+ else
+ dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+
+ numverts = dm->getNumVerts (dm);
+
+ memset( &bvhtree, 0, sizeof(bvhtree) );
+
+ /* convert to global coordinates */
+ for (i=0; i<numverts; i++)
+ Mat4MulVecfl (ob->obmat, CDDM_get_vert(dm, i)->co);
+
+ bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6);
+
+ for(i=0, pa= psys->particles; i<psys->totpart; i++,pa++) {
+ key = pa->hair;
+
+ nearest.index = -1;
+ nearest.dist = FLT_MAX;
+
+ BLI_bvhtree_find_nearest(bvhtree.tree, key->co, &nearest, bvhtree.nearest_callback, &bvhtree);
+
+ if(nearest.index == -1) {
+ printf("No nearest point found for hair root!");
+ continue;
+ }
+
+ mface = CDDM_get_face(dm,nearest.index);
+
+ VecCopyf(v[0], CDDM_get_vert(dm,mface->v1)->co);
+ VecCopyf(v[1], CDDM_get_vert(dm,mface->v2)->co);
+ VecCopyf(v[2], CDDM_get_vert(dm,mface->v3)->co);
+ if(mface->v4) {
+ VecCopyf(v[3], CDDM_get_vert(dm,mface->v4)->co);
+ MeanValueWeights(v, 4, nearest.co, pa->fuv);
+ }
+ else
+ MeanValueWeights(v, 3, nearest.co, pa->fuv);
+
+ pa->num = nearest.index;
+ pa->num_dmcache = psys_particle_dm_face_lookup(ob,psmd->dm,pa->num,pa->fuv,NULL);
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ Mat4Invert(imat,hairmat);
+
+ VECSUB(vec, nearest.co, key->co);
+
+ if(point) {
+ ekey = point->keys;
+ point++;
+ }
+
+ for(k=0,key=pa->hair; k<pa->totkey; k++,key++) {
+ VECADD(key->co, key->co, vec);
+ Mat4MulVecfl(imat,key->co);
+
+ if(ekey) {
+ ekey->flag |= PEK_USE_WCO;
+ ekey++;
+ }
+ }
+ }
+
+ free_bvhtree_from_mesh(&bvhtree);
+ if(!psmd->dm->deformedOnly)
+ dm->release(dm);
+
+ psys_free_path_cache(psys, psys->edit);
+
+ psys->flag &= ~PSYS_GLOBAL_HAIR;
+
+ PE_update_object(scene, ob, 0);
+}
+
+static int connect_hair_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+ ParticleSystem *psys= NULL;
+ int all = RNA_boolean_get(op->ptr, "all");
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ if(all) {
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ connect_hair(scene, ob, psys);
+ }
+ }
+ else {
+ psys = ptr.data;
+ connect_hair(scene, ob, psys);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_connect_hair(wmOperatorType *ot)
+{
+ ot->name= "Connect Hair";
+ ot->description= "Connect hair to the emitter mesh.";
+ ot->idname= "PARTICLE_OT_connect_hair";
+
+ ot->exec= connect_hair_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
+}
+
diff --git a/source/blender/editors/physics/ed_fluidsim.c b/source/blender/editors/physics/physics_fluid.c
index 093fa3f0a49..126c21a554b 100644
--- a/source/blender/editors/physics/ed_fluidsim.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -93,6 +93,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "physics_intern.h" // own include
+
/* enable/disable overall compilation */
#ifndef DISABLE_ELBEEM
@@ -1200,8 +1202,3 @@ void FLUID_OT_bake(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
}
-void ED_operatortypes_fluid(void)
-{
- WM_operatortype_append(FLUID_OT_bake);
-}
-
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index e03649575cb..956f26c478d 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -33,6 +33,72 @@
#ifndef ED_PHYSICS_INTERN_H
#define ED_PHYSICS_INTERN_H
+struct wmOperatorType;
+
+/* particle_edit.c */
+int PE_poll(struct bContext *C);
+int PE_hair_poll(struct bContext *C);
+int PE_poll_3dview(struct bContext *C);
+
+void PARTICLE_OT_select_all_toggle(struct wmOperatorType *ot);
+void PARTICLE_OT_select_first(struct wmOperatorType *ot);
+void PARTICLE_OT_select_last(struct wmOperatorType *ot);
+void PARTICLE_OT_select_linked(struct wmOperatorType *ot);
+void PARTICLE_OT_select_less(struct wmOperatorType *ot);
+void PARTICLE_OT_select_more(struct wmOperatorType *ot);
+
+void PARTICLE_OT_hide(struct wmOperatorType *ot);
+void PARTICLE_OT_reveal(struct wmOperatorType *ot);
+
+void PARTICLE_OT_rekey(struct wmOperatorType *ot);
+void PARTICLE_OT_subdivide(struct wmOperatorType *ot);
+void PARTICLE_OT_remove_doubles(struct wmOperatorType *ot);
+void PARTICLE_OT_delete(struct wmOperatorType *ot);
+void PARTICLE_OT_mirror(struct wmOperatorType *ot);
+
+void PARTICLE_OT_brush_set(struct wmOperatorType *ot);
+void PARTICLE_OT_brush_edit(struct wmOperatorType *ot);
+void PARTICLE_OT_brush_radial_control(struct wmOperatorType *ot);
+
+void PARTICLE_OT_specials_menu(struct wmOperatorType *ot);
+
+void PARTICLE_OT_particle_edit_toggle(struct wmOperatorType *ot);
+void PARTICLE_OT_edited_clear(struct wmOperatorType *ot);
+
+/* particle_object.c */
+void OBJECT_OT_particle_system_add(struct wmOperatorType *ot);
+void OBJECT_OT_particle_system_remove(struct wmOperatorType *ot);
+
+void PARTICLE_OT_new(struct wmOperatorType *ot);
+void PARTICLE_OT_new_target(struct wmOperatorType *ot);
+void PARTICLE_OT_remove_target(struct wmOperatorType *ot);
+void PARTICLE_OT_target_move_up(struct wmOperatorType *ot);
+void PARTICLE_OT_target_move_down(struct wmOperatorType *ot);
+void PARTICLE_OT_connect_hair(struct wmOperatorType *ot);
+void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot);
+
+/* particle_boids.c */
+void BOID_OT_rule_add(struct wmOperatorType *ot);
+void BOID_OT_rule_del(struct wmOperatorType *ot);
+void BOID_OT_rule_move_up(struct wmOperatorType *ot);
+void BOID_OT_rule_move_down(struct wmOperatorType *ot);
+
+void BOID_OT_state_add(struct wmOperatorType *ot);
+void BOID_OT_state_del(struct wmOperatorType *ot);
+void BOID_OT_state_move_up(struct wmOperatorType *ot);
+void BOID_OT_state_move_down(struct wmOperatorType *ot);
+
+/* physics_fluid.c */
+void FLUID_OT_bake(struct wmOperatorType *ot);
+
+/* physics_pointcache.c */
+void PTCACHE_OT_bake_all(struct wmOperatorType *ot);
+void PTCACHE_OT_free_bake_all(struct wmOperatorType *ot);
+void PTCACHE_OT_bake(struct wmOperatorType *ot);
+void PTCACHE_OT_free_bake(struct wmOperatorType *ot);
+void PTCACHE_OT_bake_from_cache(struct wmOperatorType *ot);
+void PTCACHE_OT_add_new(struct wmOperatorType *ot);
+void PTCACHE_OT_remove(struct wmOperatorType *ot);
#endif /* ED_PHYSICS_INTERN_H */
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
new file mode 100644
index 00000000000..a62d3d8fd78
--- /dev/null
+++ b/source/blender/editors/physics/physics_ops.c
@@ -0,0 +1,173 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_physics.h"
+
+#include "physics_intern.h" // own include
+
+/***************************** particles ***********************************/
+
+static void operatortypes_particle(void)
+{
+ WM_operatortype_append(PARTICLE_OT_select_all_toggle);
+ WM_operatortype_append(PARTICLE_OT_select_first);
+ WM_operatortype_append(PARTICLE_OT_select_last);
+ WM_operatortype_append(PARTICLE_OT_select_linked);
+ WM_operatortype_append(PARTICLE_OT_select_less);
+ WM_operatortype_append(PARTICLE_OT_select_more);
+
+ WM_operatortype_append(PARTICLE_OT_hide);
+ WM_operatortype_append(PARTICLE_OT_reveal);
+
+ WM_operatortype_append(PARTICLE_OT_rekey);
+ WM_operatortype_append(PARTICLE_OT_subdivide);
+ WM_operatortype_append(PARTICLE_OT_remove_doubles);
+ WM_operatortype_append(PARTICLE_OT_delete);
+ WM_operatortype_append(PARTICLE_OT_mirror);
+
+ WM_operatortype_append(PARTICLE_OT_brush_set);
+ WM_operatortype_append(PARTICLE_OT_brush_edit);
+ WM_operatortype_append(PARTICLE_OT_brush_radial_control);
+
+ WM_operatortype_append(PARTICLE_OT_specials_menu);
+
+ WM_operatortype_append(PARTICLE_OT_particle_edit_toggle);
+ WM_operatortype_append(PARTICLE_OT_edited_clear);
+
+
+ WM_operatortype_append(OBJECT_OT_particle_system_add);
+ WM_operatortype_append(OBJECT_OT_particle_system_remove);
+
+ WM_operatortype_append(PARTICLE_OT_new);
+ WM_operatortype_append(PARTICLE_OT_new_target);
+ WM_operatortype_append(PARTICLE_OT_remove_target);
+ WM_operatortype_append(PARTICLE_OT_target_move_up);
+ WM_operatortype_append(PARTICLE_OT_target_move_down);
+ WM_operatortype_append(PARTICLE_OT_connect_hair);
+ WM_operatortype_append(PARTICLE_OT_disconnect_hair);
+}
+
+static void keymap_particle(wmWindowManager *wm)
+{
+ wmKeyMap *keymap;
+
+ keymap= WM_keymap_find(wm, "Particle", 0, 0);
+ keymap->poll= PE_poll;
+
+ WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1);
+
+ WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_delete", DELKEY, KM_PRESS, 0, 0);
+
+ WM_keymap_add_item(keymap, "PARTICLE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
+
+ WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
+
+ WM_keymap_add_item(keymap, "PARTICLE_OT_specials_menu", WKEY, KM_PRESS, 0, 0);
+}
+
+/******************************* boids *************************************/
+
+static void operatortypes_boids(void)
+{
+ WM_operatortype_append(BOID_OT_rule_add);
+ WM_operatortype_append(BOID_OT_rule_del);
+ WM_operatortype_append(BOID_OT_rule_move_up);
+ WM_operatortype_append(BOID_OT_rule_move_down);
+
+ WM_operatortype_append(BOID_OT_state_add);
+ WM_operatortype_append(BOID_OT_state_del);
+ WM_operatortype_append(BOID_OT_state_move_up);
+ WM_operatortype_append(BOID_OT_state_move_down);
+}
+
+/********************************* fluid ***********************************/
+
+static void operatortypes_fluid(void)
+{
+ WM_operatortype_append(FLUID_OT_bake);
+}
+
+/**************************** point cache **********************************/
+
+static void operatortypes_pointcache(void)
+{
+ WM_operatortype_append(PTCACHE_OT_bake_all);
+ WM_operatortype_append(PTCACHE_OT_free_bake_all);
+ WM_operatortype_append(PTCACHE_OT_bake);
+ WM_operatortype_append(PTCACHE_OT_free_bake);
+ WM_operatortype_append(PTCACHE_OT_bake_from_cache);
+ WM_operatortype_append(PTCACHE_OT_add_new);
+ WM_operatortype_append(PTCACHE_OT_remove);
+}
+
+//static void keymap_pointcache(wmWindowManager *wm)
+//{
+// wmKeyMap *keymap= WM_keymap_find(wm, "Pointcache", 0, 0);
+//
+// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0);
+// WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0);
+// WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0);
+//}
+
+/****************************** general ************************************/
+
+void ED_operatortypes_physics(void)
+{
+ operatortypes_particle();
+ operatortypes_boids();
+ operatortypes_fluid();
+ operatortypes_pointcache();
+}
+
+void ED_keymap_physics(wmWindowManager *wm)
+{
+ keymap_particle(wm);
+ //keymap_pointcache(wm);
+}
+
+
+
diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index f2c7b64032f..26099a18966 100644
--- a/source/blender/editors/physics/ed_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -27,6 +27,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <stdlib.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
@@ -332,26 +334,4 @@ void PTCACHE_OT_remove(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-/**************************** registration **********************************/
-
-void ED_operatortypes_pointcache(void)
-{
- WM_operatortype_append(PTCACHE_OT_bake_all);
- WM_operatortype_append(PTCACHE_OT_free_bake_all);
- WM_operatortype_append(PTCACHE_OT_bake);
- WM_operatortype_append(PTCACHE_OT_free_bake);
- WM_operatortype_append(PTCACHE_OT_bake_from_cache);
- WM_operatortype_append(PTCACHE_OT_add_new);
- WM_operatortype_append(PTCACHE_OT_remove);
-}
-
-//void ED_keymap_pointcache(wmWindowManager *wm)
-//{
-// ListBase *keymap= WM_keymap_listbase(wm, "Pointcache", 0, 0);
-//
-// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0);
-// WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
-// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0);
-// WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0);
-//}
diff --git a/source/blender/editors/preview/Makefile b/source/blender/editors/render/Makefile
index 48e1dc64673..ed25f0be02a 100644
--- a/source/blender/editors/preview/Makefile
+++ b/source/blender/editors/render/Makefile
@@ -28,7 +28,7 @@
#
# Makes module object directory and bounces make to subdirectories.
-LIBNAME = ed_preview
+LIBNAME = ed_render
DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
diff --git a/source/blender/editors/preview/SConscript b/source/blender/editors/render/SConscript
index 922232822ff..bddc5ed10e0 100644
--- a/source/blender/editors/preview/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -9,4 +9,11 @@ incs += ' #/intern/guardedalloc ../../gpu'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
incs += ' ../../blenloader'
-env.BlenderLib ( 'bf_editors_preview', sources, Split(incs), [], libtype=['core'], priority=[45] )
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
+env.BlenderLib ( 'bf_editors_render', sources, Split(incs), [], libtype=['core'], priority=[45] )
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
new file mode 100644
index 00000000000..dccc2d36002
--- /dev/null
+++ b/source/blender/editors/render/render_intern.h
@@ -0,0 +1,49 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef RENDER_INTERN_H
+#define RENDER_INTERN_H
+
+struct wmOperatorType;
+
+/* render_shading.c */
+void OBJECT_OT_material_slot_add(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_remove(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_assign(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_select(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_deselect(struct wmOperatorType *ot);
+
+void MATERIAL_OT_new(struct wmOperatorType *ot);
+void TEXTURE_OT_new(struct wmOperatorType *ot);
+void WORLD_OT_new(struct wmOperatorType *ot);
+
+void SCENE_OT_render_layer_add(struct wmOperatorType *ot);
+void SCENE_OT_render_layer_remove(struct wmOperatorType *ot);
+
+#endif /* RENDER_INTERN_H */
+
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
new file mode 100644
index 00000000000..8b60582d466
--- /dev/null
+++ b/source/blender/editors/render/render_ops.c
@@ -0,0 +1,54 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include "DNA_windowmanager_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "render_intern.h" // own include
+
+/***************************** render ***********************************/
+
+void ED_operatortypes_render(void)
+{
+ WM_operatortype_append(OBJECT_OT_material_slot_add);
+ WM_operatortype_append(OBJECT_OT_material_slot_remove);
+ WM_operatortype_append(OBJECT_OT_material_slot_assign);
+ WM_operatortype_append(OBJECT_OT_material_slot_select);
+ WM_operatortype_append(OBJECT_OT_material_slot_deselect);
+
+ WM_operatortype_append(MATERIAL_OT_new);
+ WM_operatortype_append(TEXTURE_OT_new);
+ WM_operatortype_append(WORLD_OT_new);
+
+ WM_operatortype_append(SCENE_OT_render_layer_add);
+ WM_operatortype_append(SCENE_OT_render_layer_remove);
+}
+
diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/render/render_preview.c
index 714ebcef0fb..4a671e4d2ba 100644
--- a/source/blender/editors/preview/previewrender.c
+++ b/source/blender/editors/render/render_preview.c
@@ -88,13 +88,12 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_anim_api.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "ED_view3d.h"
#include "UI_interface.h"
-#include "previewrender_intern.h"
+#include "render_intern.h"
#define PR_XMIN 10
#define PR_YMIN 5
@@ -116,7 +115,7 @@ typedef struct ShaderPreview {
MTex *slot;
int sizex, sizey;
- int *pr_rect;
+ unsigned int *pr_rect;
int pr_method;
} ShaderPreview;
@@ -295,6 +294,14 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
}
sce->r.color_mgt_flag = scene->r.color_mgt_flag;
+ /* exception: don't color manage texture previews or icons */
+ if((sp && sp->pr_method==PR_ICON_RENDER) || id_type == ID_TE)
+ sce->r.color_mgt_flag &= ~R_COLOR_MANAGEMENT;
+ if((sp && sp->pr_method==PR_ICON_RENDER) && id_type != ID_WO)
+ sce->r.alphamode= R_ALPHAPREMUL;
+ else
+ sce->r.alphamode= R_ADDSKY;
+
sce->r.cfra= scene->r.cfra;
if(id_type==ID_MA) {
@@ -327,6 +334,19 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
}
}
}
+
+ /* turn off bounce lights for volume,
+ * doesn't make much visual difference and slows it down too */
+ if(mat->material_type == MA_TYPE_VOLUME) {
+ for(base= sce->base.first; base; base= base->next) {
+ if(base->object->type == OB_LAMP) {
+ /* if doesn't match 'Lamp.002' --> main key light */
+ if( strcmp(base->object->id.name+2, "Lamp.002") != 0 ) {
+ base->object->restrictflag |= OB_RESTRICT_RENDER;
+ }
+ }
+ }
+ }
if(sp->pr_method==PR_ICON_RENDER) {
@@ -356,6 +376,8 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if(matar && actcol < base->object->totcol)
(*matar)[actcol]= mat;
+ } else if (base->object->type == OB_LAMP) {
+ base->object->restrictflag &= ~OB_RESTRICT_RENDER;
}
}
}
@@ -365,9 +387,6 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sce->lay= 1<<MA_TEXTURE;
- /* exception: don't color manage texture previews */
- sce->r.color_mgt_flag &= ~R_COLOR_MANAGEMENT;
-
for(base= sce->base.first; base; base= base->next) {
if(base->object->id.name[2]=='t') {
Material *mat= give_current_material(base->object, base->object->actcol);
@@ -427,6 +446,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
/* 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)
{
+ Render *re;
RenderResult rres;
char name[32];
int gamma_correct=0;
@@ -451,7 +471,8 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
}
}
- RE_GetResultImage(RE_GetRender(name), &rres);
+ re= RE_GetRender(name);
+ RE_AcquireResultImage(re, &rres);
if(rres.rectf) {
@@ -463,10 +484,13 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
glTranslatef(offx, 0, 0);
glaDrawPixelsSafe_to32(rect->xmin, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, gamma_correct);
glPopMatrix();
+
+ RE_ReleaseResultImage(re);
return 1;
}
}
+ RE_ReleaseResultImage(re);
return 0;
}
@@ -510,6 +534,12 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
}
}
+/* ******************************** Icon Preview **************************** */
+
+void ED_preview_icon_draw(const bContext *C, void *idp, void *arg1, void *arg2, rcti *rect)
+{
+}
+
/* *************************** Preview for 3d window *********************** */
void view3d_previewrender_progress(RenderResult *rr, volatile rcti *renrect)
@@ -636,7 +666,6 @@ void BIF_view3d_previewrender_clear(ScrArea *sa)
/* afterqueue call */
void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
{
- bContext *C= NULL;
View3D *v3d= sa->spacedata.first;
RegionView3D *rv3d= NULL; // XXX
Render *re;
@@ -736,7 +765,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
/* database can have created render-resol data... */
if(rstats->convertdone)
- ED_anim_dag_flush_update(C); // <--- only current scene XXX
+ DAG_scene_flush_update(scene, scene->lay, 0);
//printf("dbase update\n");
}
@@ -821,7 +850,7 @@ void BIF_view3d_previewdraw(struct ScrArea *sa, struct uiBlock *block)
}
-/* **************************** New preview system ****************** */
+/* **************************** new shader preview system ****************** */
/* inside thread, called by renderer, sets job update value */
static void shader_preview_draw(void *spv, RenderResult *rr, volatile struct rcti *rect)
@@ -908,7 +937,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
/* handle results */
if(sp->pr_method==PR_ICON_RENDER) {
if(sp->pr_rect)
- RE_ResultGet32(re, (unsigned int *)sp->pr_rect);
+ RE_ResultGet32(re, sp->pr_rect);
}
else {
/* validate owner */
@@ -921,7 +950,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
preview_prepare_scene(sp->scene, NULL, GS(id->name), NULL);
}
-/* runs inside thread for material, in foreground for icons */
+/* runs inside thread for material and icons */
static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
{
ShaderPreview *sp= customdata;
@@ -946,63 +975,180 @@ static void shader_preview_free(void *customdata)
MEM_freeN(sp);
}
-void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, MTex *slot, int sizex, int sizey)
+/* ************************* icon preview ********************** */
+
+static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
{
- wmJob *steve;
- ShaderPreview *sp;
+ struct ImBuf *ima;
+ unsigned int *drect, *srect;
+ float scaledx, scaledy;
+ short ex, ey, dx, dy;
- /* XXX ugly global still, but we can't do preview while rendering */
- if(G.rendering)
+ /* paranoia test */
+ if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
return;
- if(GS(id->name) == ID_TE) {
- ntreeTexSetPreviewFlag(1);
+ /* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
+ ima = IMB_dupImBuf(ibuf);
+
+ if (!ima)
+ return;
+
+ if (ima->x > ima->y) {
+ scaledx = (float)w;
+ scaledy = ( (float)ima->y/(float)ima->x )*(float)w;
+ }
+ else {
+ scaledx = ( (float)ima->x/(float)ima->y )*(float)h;
+ scaledy = (float)h;
}
- steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner);
+ ex = (short)scaledx;
+ ey = (short)scaledy;
+
+ dx = (w - ex) / 2;
+ dy = (h - ey) / 2;
+
+ IMB_scalefastImBuf(ima, ex, ey);
+
+ /* if needed, convert to 32 bits */
+ if(ima->rect==NULL)
+ IMB_rect_from_float(ima);
+
+ srect = ima->rect;
+ drect = rect;
+
+ drect+= dy*w+dx;
+ for (;ey > 0; ey--){
+ memcpy(drect,srect, ex * sizeof(int));
+ drect += w;
+ srect += ima->x;
+ }
+
+ IMB_freeImBuf(ima);
+}
+
+static void set_alpha(char *cp, int sizex, int sizey, char alpha)
+{
+ int a, size= sizex*sizey;
+
+ for(a=0; a<size; a++, cp+=4)
+ cp[3]= alpha;
+}
+
+static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
+{
+ ShaderPreview *sp= customdata;
+ ID *id= sp->id;
+ short idtype= GS(id->name);
+
+ if(idtype == ID_IM) {
+ Image *ima= (Image*)id;
+ ImBuf *ibuf= NULL;
+ ImageUser iuser;
+
+ /* ima->ok is zero when Image cannot load */
+ if(ima==NULL || ima->ok==0)
+ return;
+
+ /* setup dummy image user */
+ memset(&iuser, 0, sizeof(ImageUser));
+ iuser.ok= iuser.framenr= 1;
+ iuser.scene= sp->scene;
+
+ /* elubie: this needs to be changed: here image is always loaded if not
+ already there. Very expensive for large images. Need to find a way to
+ only get existing ibuf */
+ ibuf = BKE_image_get_ibuf(ima, &iuser);
+ if(ibuf==NULL || ibuf->rect==NULL)
+ return;
+
+ icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
+
+ *do_update= 1;
+ }
+ else {
+ /* re-use shader job */
+ shader_preview_startjob(customdata, stop, do_update);
+
+ /* world is rendered with alpha=0, so it wasn't displayed
+ this could be render option for sky to, for later */
+ if(idtype == ID_WO) {
+ set_alpha((char*)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
+ else if(idtype == ID_MA) {
+ Material* ma = (Material*)id;
+
+ if(ma->material_type == MA_TYPE_HALO)
+ set_alpha((char*)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
+ }
+}
+
+/* use same function for icon & shader, so the job manager
+ does not run two of them at the same time. */
+
+static void common_preview_startjob(void *customdata, short *stop, short *do_update)
+{
+ ShaderPreview *sp= customdata;
+
+ if(sp->pr_method == PR_ICON_RENDER)
+ icon_preview_startjob(customdata, stop, do_update);
+ else
+ shader_preview_startjob(customdata, stop, do_update);
+}
+
+/* exported functions */
+
+void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey)
+{
+ wmJob *steve;
+ ShaderPreview *sp;
+
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, WM_JOB_EXCL_RENDER);
sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
/* customdata for preview thread */
sp->scene= CTX_data_scene(C);
- sp->owner= owner;
+ sp->owner= id;
sp->sizex= sizex;
sp->sizey= sizey;
- sp->pr_method= PR_DO_RENDER;
+ sp->pr_method= PR_ICON_RENDER;
+ sp->pr_rect= rect;
sp->id = id;
- sp->parent= parent;
- sp->slot= slot;
/* setup job */
WM_jobs_customdata(steve, sp, shader_preview_free);
WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
- WM_jobs_callbacks(steve, shader_preview_startjob, NULL, shader_preview_updatejob);
+ WM_jobs_callbacks(steve, common_preview_startjob, NULL, NULL);
WM_jobs_start(CTX_wm_manager(C), steve);
-
- /* signal to rerender icon in menus */
- BKE_icon_changed(BKE_icon_getid(id));
}
-/* rect should be allocated, sizex/sizy pixels, 32 bits */
-void ED_preview_iconrender(Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
+void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, MTex *slot, int sizex, int sizey)
{
+ wmJob *steve;
ShaderPreview *sp;
- short stop=0, do_update=0;
- sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
-
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, WM_JOB_EXCL_RENDER);
+ sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
+
/* customdata for preview thread */
- sp->scene= scene;
+ sp->scene= CTX_data_scene(C);
+ sp->owner= owner;
sp->sizex= sizex;
sp->sizey= sizey;
- sp->pr_method= PR_ICON_RENDER;
- sp->pr_rect= (int *)rect; /* shouldnt pr_rect be unsigned int also? - Campbell */
+ sp->pr_method= PR_DO_RENDER;
sp->id = id;
-
- shader_preview_startjob(sp, &stop, &do_update);
+ sp->parent= parent;
+ sp->slot= slot;
- MEM_freeN(sp);
+ /* setup job */
+ WM_jobs_customdata(steve, sp, shader_preview_free);
+ WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
+ WM_jobs_callbacks(steve, common_preview_startjob, NULL, shader_preview_updatejob);
+
+ WM_jobs_start(CTX_wm_manager(C), steve);
}
-
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
new file mode 100644
index 00000000000..a31a60ecbd6
--- /dev/null
+++ b/source/blender/editors/render/render_shading.c
@@ -0,0 +1,645 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_curve_types.h"
+#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_texture_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_font.h"
+#include "BKE_icons.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_world.h"
+
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+#include "BLI_listbase.h"
+
+#include "GPU_material.h"
+
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_curve.h"
+#include "ED_mesh.h"
+#include "ED_render.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "render_intern.h" // own include
+
+/***************************** Updates ***********************************
+ * ED_render_id_flush_update gets called from DAG_id_flush_update, to do *
+ * editor level updates when the ID changes. when these ID blocks are in *
+ * the dependency graph, we can get rid of the manual dependency checks */
+
+static int mtex_use_tex(MTex **mtex, int tot, Tex *tex)
+{
+ int a;
+
+ if(!mtex)
+ return 0;
+
+ for(a=0; a<tot; a++)
+ if(mtex[a] && mtex[a]->tex == tex)
+ return 1;
+
+ return 0;
+}
+
+static int nodes_use_tex(bNodeTree *ntree, Tex *tex)
+{
+ bNode *node;
+
+ for(node=ntree->nodes.first; node; node= node->next) {
+ if(node->id) {
+ if(node->id == (ID*)tex) {
+ return 1;
+ }
+ else if(node->type==NODE_GROUP) {
+ if(nodes_use_tex((bNodeTree *)node->id, tex))
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void material_changed(Main *bmain, Material *ma)
+{
+ /* icons */
+ BKE_icon_changed(BKE_icon_getid(&ma->id));
+
+ /* glsl */
+ if(ma->gpumaterial.first)
+ GPU_material_free(ma);
+}
+
+static void texture_changed(Main *bmain, Tex *tex)
+{
+ Material *ma;
+ Lamp *la;
+ World *wo;
+
+ /* 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));
+ else if(ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex));
+ else continue;
+
+ BKE_icon_changed(BKE_icon_getid(&ma->id));
+
+ if(ma->gpumaterial.first)
+ GPU_material_free(ma);
+ }
+
+ /* find lamps */
+ for(la=bmain->lamp.first; la; la=la->id.next) {
+ if(mtex_use_tex(la->mtex, MAX_MTEX, tex));
+ else continue;
+
+ BKE_icon_changed(BKE_icon_getid(&la->id));
+ }
+
+ /* find worlds */
+ for(wo=bmain->world.first; wo; wo=wo->id.next) {
+ if(mtex_use_tex(wo->mtex, MAX_MTEX, tex));
+ else continue;
+
+ BKE_icon_changed(BKE_icon_getid(&wo->id));
+ }
+}
+
+static void lamp_changed(Main *bmain, Lamp *la)
+{
+ Object *ob;
+ Material *ma;
+
+ /* icons */
+ BKE_icon_changed(BKE_icon_getid(&la->id));
+
+ /* glsl */
+ for(ob=bmain->object.first; ob; ob=ob->id.next)
+ if(ob->data == la && ob->gpulamp.first)
+ GPU_lamp_free(ob);
+
+ for(ma=bmain->mat.first; ma; ma=ma->id.next)
+ if(ma->gpumaterial.first)
+ GPU_material_free(ma);
+}
+
+static void world_changed(Main *bmain, World *wo)
+{
+ Material *ma;
+
+ /* icons */
+ BKE_icon_changed(BKE_icon_getid(&wo->id));
+
+ /* glsl */
+ for(ma=bmain->mat.first; ma; ma=ma->id.next)
+ if(ma->gpumaterial.first)
+ GPU_material_free(ma);
+}
+
+void ED_render_id_flush_update(Main *bmain, ID *id)
+{
+ switch(GS(id->name)) {
+ case ID_MA:
+ material_changed(bmain, (Material*)id);
+ break;
+ case ID_TE:
+ texture_changed(bmain, (Tex*)id);
+ break;
+ case ID_WO:
+ world_changed(bmain, (World*)id);
+ break;
+ case ID_LA:
+ lamp_changed(bmain, (Lamp*)id);
+ break;
+ default:
+ break;
+ }
+}
+
+/********************** material slot operators *********************/
+
+static int material_slot_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ object_add_material_slot(ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Material Slot";
+ ot->idname= "OBJECT_OT_material_slot_add";
+ ot->description="Add a new material slot or duplicate the selected one.";
+
+ /* api callbacks */
+ ot->exec= material_slot_add_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_remove_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ object_remove_material_slot(ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Material Slot";
+ ot->idname= "OBJECT_OT_material_slot_remove";
+ ot->description="Remove the selected material slot.";
+
+ /* api callbacks */
+ ot->exec= material_slot_remove_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_assign_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ if(ob && ob->actcol>0) {
+ if(ob->type == OB_MESH) {
+ EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+ EditFace *efa;
+
+ if(em) {
+ for(efa= em->faces.first; efa; efa=efa->next)
+ if(efa->f & SELECT)
+ efa->mat_nr= ob->actcol-1;
+ }
+ }
+ else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+ Nurb *nu;
+
+ if(editnurb) {
+ for(nu= editnurb->first; nu; nu= nu->next)
+ if(isNurbsel(nu))
+ nu->mat_nr= nu->charidx= ob->actcol-1;
+ }
+ }
+ else if(ob->type == OB_FONT) {
+ EditFont *ef= ((Curve*)ob->data)->editfont;
+ int i, selstart, selend;
+
+ if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
+ for(i=selstart; i<=selend; i++)
+ ef->textbufinfo[i].mat_nr = ob->actcol-1;
+ }
+ }
+ }
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Assign Material Slot";
+ ot->idname= "OBJECT_OT_material_slot_assign";
+ ot->description="Assign the material in the selected material slot to the selected vertices.";
+
+ /* api callbacks */
+ ot->exec= material_slot_assign_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_de_select(bContext *C, int select)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ if(ob->type == OB_MESH) {
+ EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+
+ if(em) {
+ if(select)
+ EM_select_by_material(em, ob->actcol-1);
+ else
+ EM_deselect_by_material(em, ob->actcol-1);
+ }
+ }
+ else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+ ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+
+ for(nu= editnurb->first; nu; nu=nu->next) {
+ if(nu->mat_nr==ob->actcol-1) {
+ if(nu->bezt) {
+ a= nu->pntsu;
+ bezt= nu->bezt;
+ while(a--) {
+ if(bezt->hide==0) {
+ if(select) {
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
+ }
+ else {
+ bezt->f1 &= ~SELECT;
+ bezt->f2 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
+ }
+ }
+ bezt++;
+ }
+ }
+ else if(nu->bp) {
+ a= nu->pntsu*nu->pntsv;
+ bp= nu->bp;
+ while(a--) {
+ if(bp->hide==0) {
+ if(select) bp->f1 |= SELECT;
+ else bp->f1 &= ~SELECT;
+ }
+ bp++;
+ }
+ }
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static int material_slot_select_exec(bContext *C, wmOperator *op)
+{
+ return material_slot_de_select(C, 1);
+}
+
+void OBJECT_OT_material_slot_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Select Material Slot";
+ ot->idname= "OBJECT_OT_material_slot_select";
+ ot->description="Select vertices assigned to the selected material slot.";
+
+ /* api callbacks */
+ ot->exec= material_slot_select_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_deselect_exec(bContext *C, wmOperator *op)
+{
+ return material_slot_de_select(C, 0);
+}
+
+void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Deselect Material Slot";
+ ot->idname= "OBJECT_OT_material_slot_deselect";
+ ot->description="Deselect vertices assigned to the selected material slot.";
+
+ /* api callbacks */
+ ot->exec= material_slot_deselect_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new material operator *********************/
+
+static int new_material_exec(bContext *C, wmOperator *op)
+{
+ Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+ Object *ob;
+ PointerRNA ptr;
+ int index;
+
+ /* add or copy material */
+ if(ma)
+ ma= copy_material(ma);
+ else
+ ma= add_material("Material");
+
+ ma->id.us--; /* compensating for us++ in assign_material */
+
+ /* attempt to assign to material slot */
+ ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
+
+ if(ptr.data) {
+ ob= ptr.id.data;
+ index= (Material**)ptr.data - ob->mat;
+
+ assign_material(ob, ma, index+1);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ }
+
+ WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
+
+ return OPERATOR_FINISHED;
+}
+
+void MATERIAL_OT_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New Material";
+ ot->idname= "MATERIAL_OT_new";
+ ot->description="Add a new material.";
+
+ /* api callbacks */
+ ot->exec= new_material_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new texture operator *********************/
+
+static int new_texture_exec(bContext *C, wmOperator *op)
+{
+ Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
+ ID *id;
+ MTex *mtex;
+ PointerRNA ptr;
+
+ /* add or copy texture */
+ if(tex)
+ tex= copy_texture(tex);
+ else
+ tex= add_texture("Texture");
+
+ id_us_min(&tex->id);
+
+ /* attempt to assign to texture slot */
+ ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
+
+ if(ptr.data) {
+ id= ptr.id.data;
+ mtex= ptr.data;
+
+ if(mtex) {
+ if(mtex->tex)
+ id_us_min(&mtex->tex->id);
+ mtex->tex= tex;
+ id_us_plus(&tex->id);
+ }
+
+ /* XXX nodes, notifier .. */
+ }
+
+ WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
+
+ return OPERATOR_FINISHED;
+}
+
+void TEXTURE_OT_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New Texture";
+ ot->idname= "TEXTURE_OT_new";
+ ot->description="Add a new texture.";
+
+ /* api callbacks */
+ ot->exec= new_texture_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new world operator *********************/
+
+static int new_world_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
+
+ /* add or copy world */
+ if(wo)
+ wo= copy_world(wo);
+ else
+ wo= add_world("World");
+
+ /* assign to scene */
+ if(scene->world)
+ id_us_min(&scene->world->id);
+ scene->world= wo;
+
+ WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
+
+ return OPERATOR_FINISHED;
+}
+
+void WORLD_OT_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New World";
+ ot->idname= "WORLD_OT_new";
+ ot->description= "Add a new world.";
+
+ /* api callbacks */
+ ot->exec= new_world_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** render layer operators *********************/
+
+static int render_layer_add_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ scene_add_render_layer(scene);
+ scene->r.actlay= BLI_countlist(&scene->r.layers) - 1;
+
+ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_render_layer_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Render Layer";
+ ot->idname= "SCENE_OT_render_layer_add";
+ ot->description="Add a render layer.";
+
+ /* api callbacks */
+ ot->exec= render_layer_add_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int render_layer_remove_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ SceneRenderLayer *rl;
+ int act= scene->r.actlay;
+
+ if(BLI_countlist(&scene->r.layers) <= 1)
+ return OPERATOR_CANCELLED;
+
+ rl= BLI_findlink(&scene->r.layers, scene->r.actlay);
+ BLI_remlink(&scene->r.layers, rl);
+ MEM_freeN(rl);
+
+ scene->r.actlay= 0;
+
+ if(scene->nodetree) {
+ bNode *node;
+ for(node= scene->nodetree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
+ if(node->custom1==act)
+ node->custom1= 0;
+ else if(node->custom1>act)
+ node->custom1--;
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_render_layer_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Render Layer";
+ ot->idname= "SCENE_OT_render_layer_remove";
+ ot->description="Remove the selected render layer.";
+
+ /* api callbacks */
+ ot->exec= render_layer_remove_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript
index a4f73cfea7e..847a1cddfb4 100644
--- a/source/blender/editors/screen/SConscript
+++ b/source/blender/editors/screen/SConscript
@@ -15,4 +15,11 @@ if not env['WITH_BF_PYTHON']:
if env['WITH_BF_OPENEXR']:
defs += ' WITH_OPENEXR'
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_screen', sources, Split(incs), Split(defs), libtype=['core'], priority=[105] )
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 2cdb75e28e3..87901d75494 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -159,14 +159,8 @@ void ED_area_overdraw_flush(bContext *C, ScrArea *sa, ARegion *ar)
for(az= sa->actionzones.first; az; az= az->next) {
int xs, ys;
- if(az->type==AZONE_AREA) {
- xs= (az->x1+az->x2)/2;
- ys= (az->y1+az->y2)/2;
- }
- else {
- xs= az->x3;
- ys= az->y3;
- }
+ xs= (az->x1+az->x2)/2;
+ ys= (az->y1+az->y2)/2;
/* test if inside */
if(BLI_in_rcti(&ar->winrct, xs, ys)) {
@@ -196,25 +190,42 @@ static void area_draw_azone(short x1, short y1, short x2, short y2)
fdrawline(xmin, ymax-2*dy+1, xmax-2*dx+1, ymin);
}
+
static void region_draw_azone(ScrArea *sa, AZone *az)
{
- if(az->ar==NULL) return;
+ GLUquadricObj *qobj = gluNewQuadric();
+ short midx = az->x1 + (az->x2 - az->x1)/2;
+ short midy = az->y1 + (az->y2 - az->y1)/2;
- UI_SetTheme(sa->spacetype, az->ar->type->regionid);
+ if(az->ar==NULL) return;
- UI_ThemeColor(TH_BACK);
- glBegin(GL_TRIANGLES);
- glVertex2s(az->x1, az->y1);
- glVertex2s(az->x2, az->y2);
- glVertex2s(az->x3, az->y3);
- glEnd();
+ /* only display action zone icons when the region is hidden */
+ if (!(az->ar->flag & RGN_FLAG_HIDDEN)) return;
- UI_ThemeColorShade(TH_BACK, 50);
- sdrawline(az->x1, az->y1, az->x3, az->y3);
+ glPushMatrix();
+ glTranslatef(midx, midy, 0.);
- UI_ThemeColorShade(TH_BACK, -50);
- sdrawline(az->x2, az->y2, az->x3, az->y3);
+ /* outlined circle */
+ glEnable(GL_LINE_SMOOTH);
+
+ glColor4f(1.f, 1.f, 1.f, 0.8f);
+
+ gluQuadricDrawStyle(qobj, GLU_FILL);
+ gluDisk( qobj, 0.0, 4.25f, 16, 1);
+ glColor4f(0.2f, 0.2f, 0.2f, 0.9f);
+
+ gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+ gluDisk( qobj, 0.0, 4.25f, 16, 1);
+
+ glDisable(GL_LINE_SMOOTH);
+
+ glPopMatrix();
+ gluDeleteQuadric(qobj);
+
+ /* + */
+ sdrawline(midx, midy-2, midx, midy+3);
+ sdrawline(midx-2, midy, midx+3, midy);
}
@@ -235,10 +246,11 @@ void ED_area_overdraw(bContext *C)
AZone *az;
for(az= sa->actionzones.first; az; az= az->next) {
if(az->do_draw) {
- if(az->type==AZONE_AREA)
+ if(az->type==AZONE_AREA) {
area_draw_azone(az->x1, az->y1, az->x2, az->y2);
- else if(az->type==AZONE_REGION)
+ } else if(az->type==AZONE_REGION) {
region_draw_azone(sa, az);
+ }
az->do_draw= 0;
}
@@ -449,72 +461,103 @@ static void area_azone_initialize(ScrArea *sa)
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-static void region_azone_initialize(ScrArea *sa, ARegion *ar, char edge)
+#define AZONEPAD_EDGE 4
+#define AZONEPAD_ICON 8
+static void region_azone_edge(AZone *az, ARegion *ar)
{
- AZone *az, *azt;
-
- az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
- BLI_addtail(&(sa->actionzones), az);
- az->type= AZONE_REGION;
- az->ar= ar;
- az->edge= edge;
-
- if(edge=='t') {
- az->x1= ar->winrct.xmin+AZONESPOT;
- az->y1= ar->winrct.ymax;
- az->x2= ar->winrct.xmin+2*AZONESPOT;
+ if(az->edge=='t') {
+ az->x1= ar->winrct.xmin;
+ az->y1= ar->winrct.ymax - AZONEPAD_EDGE;
+ az->x2= ar->winrct.xmax;
az->y2= ar->winrct.ymax;
- az->x3= (az->x1+az->x2)/2;
- az->y3= az->y2+AZONESPOT/2;
- BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y3);
}
- else if(edge=='b') {
- az->x1= ar->winrct.xmin+AZONESPOT;
- az->y1= ar->winrct.ymin;
- az->x2= ar->winrct.xmin+2*AZONESPOT;
+ else if(az->edge=='b') {
+ az->x1= ar->winrct.xmin;
+ az->y1= ar->winrct.ymin + AZONEPAD_EDGE;
+ az->x2= ar->winrct.xmax;
az->y2= ar->winrct.ymin;
- az->x3= (az->x1+az->x2)/2;
- az->y3= az->y2-AZONESPOT/2;
- BLI_init_rcti(&az->rect, az->x1, az->x2, az->y3, az->y1);
}
- else if(edge=='l') {
+ else if(az->edge=='l') {
az->x1= ar->winrct.xmin;
- az->y1= ar->winrct.ymax-AZONESPOT;
- az->x2= ar->winrct.xmin;
- az->y2= ar->winrct.ymax-2*AZONESPOT;
- az->x3= az->x2-AZONESPOT/2;
- az->y3= (az->y1+az->y2)/2;
- BLI_init_rcti(&az->rect, az->x3, az->x1, az->y1, az->y2);
+ az->y1= ar->winrct.ymin;
+ az->x2= ar->winrct.xmin + AZONEPAD_EDGE;
+ az->y2= ar->winrct.ymax;
}
- else { // if(edge=='r') {
+ else { // if(az->edge=='r') {
az->x1= ar->winrct.xmax;
- az->y1= ar->winrct.ymax-AZONESPOT;
- az->x2= ar->winrct.xmax;
- az->y2= ar->winrct.ymax-2*AZONESPOT;
- az->x3= az->x2+AZONESPOT/2;
- az->y3= (az->y1+az->y2)/2;
- BLI_init_rcti(&az->rect, az->x1, az->x3, az->y1, az->y2);
+ az->y1= ar->winrct.ymin;
+ az->x2= ar->winrct.xmax - AZONEPAD_EDGE;
+ az->y2= ar->winrct.ymax;
}
+
+ BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
+}
+
+static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar)
+{
+ AZone *azt;
+
+ if(az->edge=='t') {
+ az->x1= ar->winrct.xmax - AZONEPAD_ICON;
+ az->y1= ar->winrct.ymax + AZONEPAD_ICON;
+ az->x2= ar->winrct.xmax - 2*AZONEPAD_ICON;
+ az->y2= ar->winrct.ymax + 2*AZONEPAD_ICON;
+ }
+ else if(az->edge=='b') {
+ az->x1= ar->winrct.xmin + AZONEPAD_ICON;
+ az->y1= ar->winrct.ymin - AZONEPAD_ICON;
+ az->x2= ar->winrct.xmin + 2*AZONEPAD_ICON;
+ az->y2= ar->winrct.ymin - 2*AZONEPAD_ICON;
+ }
+ else if(az->edge=='l') {
+ az->x1= ar->winrct.xmin - 2*AZONEPAD_ICON;
+ az->y1= ar->winrct.ymax - 2*AZONEPAD_ICON;
+ az->x2= ar->winrct.xmin - AZONEPAD_ICON;
+ az->y2= ar->winrct.ymax - AZONEPAD_ICON;
+ }
+ else { // if(az->edge=='r') {
+ az->x1= ar->winrct.xmax + AZONEPAD_ICON;
+ az->y1= ar->winrct.ymax - 2*AZONEPAD_ICON;
+ az->x2= ar->winrct.xmax + 2*AZONEPAD_ICON;
+ az->y2= ar->winrct.ymax - AZONEPAD_ICON;
+ }
+
+ BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
/* if more azones on 1 spot, set offset */
for(azt= sa->actionzones.first; azt; azt= azt->next) {
if(az!=azt) {
if( ABS(az->x1-azt->x1) < 2 && ABS(az->y1-azt->y1) < 2) {
- if(edge=='t' || edge=='b') {
+ if(az->edge=='t' || az->edge=='b') {
az->x1+= AZONESPOT;
az->x2+= AZONESPOT;
- az->x3+= AZONESPOT;
- BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y3);
+ BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
else {
az->y1-= AZONESPOT;
az->y2-= AZONESPOT;
- az->y3-= AZONESPOT;
- BLI_init_rcti(&az->rect, az->x1, az->x3, az->y1, az->y2);
+ BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
}
}
}
+}
+
+static void region_azone_initialize(ScrArea *sa, ARegion *ar, char edge)
+{
+ AZone *az;
+
+ az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+ BLI_addtail(&(sa->actionzones), az);
+ az->type= AZONE_REGION;
+ az->ar= ar;
+ az->edge= edge;
+
+ if (ar->flag & RGN_FLAG_HIDDEN) {
+ region_azone_icon(sa, az, ar);
+ } else {
+ region_azone_edge(az, ar);
+ }
}
@@ -781,24 +824,24 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla
UI_add_region_handlers(handlers);
}
if(flag & ED_KEYMAP_VIEW2D) {
- ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "View2D", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_MARKERS) {
- ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Markers", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
// XXX need boundbox check urgently!!!
}
if(flag & ED_KEYMAP_ANIMATION) {
- ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Animation", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_FRAMES) {
- ListBase *keymap= WM_keymap_listbase(wm, "Frames", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Frames", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_GPENCIL) {
- ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Grease Pencil", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
}
@@ -873,6 +916,19 @@ void ED_region_init(bContext *C, ARegion *ar)
}
+void ED_region_toggle_hidden(bContext *C, ARegion *ar)
+{
+ ScrArea *sa= CTX_wm_area(C);
+
+ ar->flag ^= RGN_FLAG_HIDDEN;
+ ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
+
+ 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);
+}
/* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
/* area vertices were set */
@@ -1198,7 +1254,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex
pt->draw_header(C, panel);
- uiBlockLayoutResolve(C, block, &xco, &yco);
+ uiBlockLayoutResolve(block, &xco, &yco);
panel->labelofs= xco - triangle;
panel->layout= NULL;
}
@@ -1209,7 +1265,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex
pt->draw(C, panel);
- uiBlockLayoutResolve(C, block, &xco, &yco);
+ uiBlockLayoutResolve(block, &xco, &yco);
panel->layout= NULL;
yco -= 2*style->panelspace;
@@ -1297,7 +1353,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex
void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
// XXX quick hacks for files saved with 2.5 already (i.e. the builtin defaults file)
// scrollbars for button regions
@@ -1310,7 +1366,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
- keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0);
+ keymap= WM_keymap_find(wm, "View2D Buttons List", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -1355,7 +1411,7 @@ void ED_region_header(const bContext *C, ARegion *ar)
maxco= xco;
}
- uiBlockLayoutResolve(C, block, &xco, &yco);
+ uiBlockLayoutResolve(block, &xco, &yco);
/* for view2d */
if(xco > maxco)
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index aa36675fb90..2cc5500c3ef 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1140,7 +1140,7 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event)
if(az->type==AZONE_AREA)
WM_cursor_set(win, CURSOR_EDIT);
else if(az->type==AZONE_REGION) {
- if(az->x1==az->x2)
+ if(az->edge == 'l' || az->edge == 'r')
WM_cursor_set(win, CURSOR_X_MOVE);
else
WM_cursor_set(win, CURSOR_Y_MOVE);
@@ -1580,23 +1580,6 @@ void ED_screen_animation_timer_update(bContext *C, int redraws)
}
}
-unsigned int ED_screen_view3d_layers(bScreen *screen)
-{
- if(screen) {
- unsigned int layer= screen->scene->lay; /* as minimum this */
- ScrArea *sa;
-
- /* get all used view3d layers */
- for(sa= screen->areabase.first; sa; sa= sa->next) {
- if(sa->spacetype==SPACE_VIEW3D)
- layer |= ((View3D *)sa->spacedata.first)->lay;
- }
- return layer;
- }
- return 0;
-}
-
-
/* results in fully updated anim system */
void ED_update_for_newframe(const bContext *C, int mute)
{
@@ -1607,7 +1590,7 @@ void ED_update_for_newframe(const bContext *C, int mute)
/* this function applies the changes too */
/* XXX future: do all windows */
- scene_update_for_newframe(scene, ED_screen_view3d_layers(screen)); /* BKE_scene.h */
+ scene_update_for_newframe(scene, BKE_screen_visible_layers(screen)); /* BKE_scene.h */
//if ( (CFRA>1) && (!mute) && (scene->r.audio.flag & AUDIO_SCRUB))
// audiostream_scrub( CFRA );
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 75da8f5fe06..7f2084d5a76 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -396,15 +396,7 @@ AZone *is_in_area_actionzone(ScrArea *sa, int x, int y)
break;
}
else if(az->type == AZONE_REGION) {
- float v1[2], v2[2], v3[2], pt[2];
-
- v1[0]= az->x1; v1[1]= az->y1;
- v2[0]= az->x2; v2[1]= az->y2;
- v3[0]= az->x3; v3[1]= az->y3;
- pt[0]= x; pt[1]=y;
-
- if(IsPointInTri2D(v1, v2, v3, pt))
- break;
+ break;
}
}
}
@@ -464,7 +456,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
else {
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -596,7 +588,7 @@ static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* add modal handler */
WM_cursor_modal(CTX_wm_window(C), BC_SWAPAREA_CURSOR);
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -612,8 +604,8 @@ static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event)
sad->sa2= screen_areahascursor(CTX_wm_screen(C), event->x, event->y);
break;
case LEFTMOUSE: /* release LMB */
- if(event->val==0) {
- if(sad->sa1 == sad->sa2) {
+ if(event->val==KM_RELEASE) {
+ if(!sad->sa2 || sad->sa1 == sad->sa2) {
return area_swap_cancel(C, op);
}
@@ -878,7 +870,7 @@ static int area_move_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_PASS_THROUGH;
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1168,7 +1160,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event)
area_move_set_limits(CTX_wm_screen(C), dir, &sd->bigger, &sd->smaller);
/* add temp handler for edge move or cancel */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1233,7 +1225,7 @@ static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case LEFTMOUSE:
- if(event->val==0) { /* mouse up */
+ if(event->val==KM_RELEASE) { /* mouse up */
area_split_exit(C, op);
return OPERATOR_FINISHED;
}
@@ -1261,7 +1253,7 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
ot->modal= area_split_modal;
ot->poll= ED_operator_areaactive;
- ot->flag= OPTYPE_REGISTER|OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING;
/* rna */
RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", "");
@@ -1273,7 +1265,9 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
/* ************** scale region edge operator *********************************** */
typedef struct RegionMoveData {
+ AZone *az;
ARegion *ar;
+ ScrArea *sa;
int bigger, smaller, origval;
int origx, origy;
char edge;
@@ -1290,7 +1284,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
op->customdata= rmd;
+ rmd->az = az;
rmd->ar= az->ar;
+ rmd->sa = sad->sa1;
rmd->edge= az->edge;
rmd->origx= event->x;
rmd->origy= event->y;
@@ -1300,7 +1296,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
rmd->origval= rmd->ar->type->minsizey;
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1322,24 +1318,26 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
if(rmd->edge=='l') delta= -delta;
rmd->ar->type->minsizex= rmd->origval + delta;
CLAMP(rmd->ar->type->minsizex, 0, 1000);
- if(rmd->ar->type->minsizex < 10) {
- rmd->ar->type->minsizex= 10;
- rmd->ar->flag |= RGN_FLAG_HIDDEN;
+ if(rmd->ar->type->minsizex < 24) {
+ rmd->ar->type->minsizex= rmd->origval;
+ if(!(rmd->ar->flag & RGN_FLAG_HIDDEN))
+ ED_region_toggle_hidden(C, rmd->ar);
}
- else
- rmd->ar->flag &= ~RGN_FLAG_HIDDEN;
+ else if(rmd->ar->flag & RGN_FLAG_HIDDEN)
+ ED_region_toggle_hidden(C, rmd->ar);
}
else {
delta= event->y - rmd->origy;
if(rmd->edge=='b') delta= -delta;
rmd->ar->type->minsizey= rmd->origval + delta;
CLAMP(rmd->ar->type->minsizey, 0, 1000);
- if(rmd->ar->type->minsizey < 10) {
- rmd->ar->type->minsizey= 10;
- rmd->ar->flag |= RGN_FLAG_HIDDEN;
+ if(rmd->ar->type->minsizey < 24) {
+ rmd->ar->type->minsizey= rmd->origval;
+ if(!(rmd->ar->flag & RGN_FLAG_HIDDEN))
+ ED_region_toggle_hidden(C, rmd->ar);
}
- else
- rmd->ar->flag &= ~RGN_FLAG_HIDDEN;
+ else if(rmd->ar->flag & RGN_FLAG_HIDDEN)
+ ED_region_toggle_hidden(C, rmd->ar);
}
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
@@ -1347,12 +1345,14 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case LEFTMOUSE:
- if(event->val==0) {
+ if(event->val==KM_RELEASE) {
if(ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) {
- rmd->ar->flag ^= RGN_FLAG_HIDDEN;
- WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
- }
+ if(rmd->ar->flag & RGN_FLAG_HIDDEN) {
+ ED_region_toggle_hidden(C, rmd->ar);
+ WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
+ }
+ }
MEM_freeN(op->customdata);
op->customdata = NULL;
@@ -1446,29 +1446,6 @@ static void SCREEN_OT_frame_jump(wmOperatorType *ot)
/* ************** jump to keyframe operator ***************************** */
-/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */
-// TODO: make this an API func?
-static ActKeyColumn *cfra_find_nearest_next_ak (ActKeyColumn *ak, float cframe, short next)
-{
- ActKeyColumn *akn= NULL;
-
- /* sanity checks */
- if (ak == NULL)
- return NULL;
-
- /* check if this is a match, or whether it is in some subtree */
- if (cframe < ak->cfra)
- akn= cfra_find_nearest_next_ak(ak->left, cframe, next);
- else if (cframe > ak->cfra)
- akn= cfra_find_nearest_next_ak(ak->right, cframe, next);
-
- /* if no match found (or found match), just use the current one */
- if (akn == NULL)
- return ak;
- else
- return akn;
-}
-
/* function to be called outside UI context, or for redo */
static int keyframe_jump_exec(bContext *C, wmOperator *op)
{
@@ -1597,7 +1574,7 @@ static int screen_full_area_exec(bContext *C, wmOperator *op)
static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
{
- ot->name = "Toggle Make Area Fullscreen";
+ ot->name = "Toggle Full Screen";
ot->idname = "SCREEN_OT_screen_full_area";
ot->exec= screen_full_area_exec;
@@ -1751,7 +1728,7 @@ static int area_join_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_PASS_THROUGH;
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1851,7 +1828,7 @@ static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event)
}
break;
case LEFTMOUSE:
- if(event->val==0) {
+ if(event->val==KM_RELEASE) {
area_join_apply(C, op);
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
area_join_exit(C, op);
@@ -2120,14 +2097,14 @@ static int region_foursplit_exec(bContext *C, wmOperator *op)
static void SCREEN_OT_region_foursplit(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Split Region in 4 Parts";
+ ot->name= "Toggle Quad View";
ot->idname= "SCREEN_OT_region_foursplit";
/* api callbacks */
// ot->invoke= WM_operator_confirm;
ot->exec= region_foursplit_exec;
ot->poll= ED_operator_areaactive;
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
}
@@ -2165,7 +2142,7 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot)
ot->exec= region_flip_exec;
ot->poll= ED_operator_areaactive;
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
}
@@ -2199,6 +2176,10 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws)
if(redraws & (TIME_SEQ|TIME_ALL_ANIM_WIN))
return 1;
break;
+ case SPACE_NODE:
+ if(redraws & (TIME_NODES))
+ return 1;
+ break;
case SPACE_IMAGE:
if(redraws & TIME_ALL_IMAGE_WIN)
return 1;
@@ -2231,7 +2212,7 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event)
/* sync, don't sync, or follow scene setting */
if(sad->flag & ANIMPLAY_FLAG_SYNC) sync= 1;
else if(sad->flag & ANIMPLAY_FLAG_NO_SYNC) sync= 0;
- else sync= (scene->r.audio.flag & AUDIO_SYNC);
+ else sync= (scene->audio.flag & AUDIO_SYNC);
if(sync) {
/* skip frames */
@@ -2366,7 +2347,7 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
static void SCREEN_OT_animation_play(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Animation player";
+ ot->name= "Play Animation";
ot->idname= "SCREEN_OT_animation_play";
/* api callbacks */
@@ -2722,18 +2703,13 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
}
/* called inside thread! */
-static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
+static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect)
{
- RenderJob *rj= rjv;
- ImBuf *ibuf;
float x1, y1, *rectf= NULL;
int ymin, ymax, xmin, xmax;
int rymin, rxmin;
char *rectc;
- ibuf= BKE_image_get_ibuf(rj->image, &rj->iuser);
- if(ibuf==NULL) return;
-
/* if renrect argument, we only refresh scanlines */
if(renrect) {
/* if ymax==recty, rendering of layer is ready, we should not draw, other things happen... */
@@ -2833,6 +2809,18 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
*(rj->do_update)= 1;
}
+static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
+{
+ RenderJob *rj= rjv;
+ ImBuf *ibuf;
+ void *lock;
+
+ ibuf= BKE_image_acquire_ibuf(rj->image, &rj->iuser, &lock);
+ if(ibuf)
+ image_buffer_rect_update(rj, rr, ibuf, renrect);
+ BKE_image_release_ibuf(rj->image, lock);
+}
+
static void render_startjob(void *rjv, short *stop, short *do_update)
{
RenderJob *rj= rjv;
@@ -2916,7 +2904,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
rj->iuser.ok= 1;
/* setup job */
- steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene);
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
WM_jobs_customdata(steve, rj, render_freejob);
WM_jobs_timer(steve, 0.2, NC_SCENE|ND_RENDER_RESULT, 0);
WM_jobs_callbacks(steve, render_startjob, NULL, NULL);
@@ -2946,7 +2934,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
/* add modal handler for ESC */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -3293,19 +3281,15 @@ static void keymap_modal_set(wmWindowManager *wm)
/* called in spacetypes.c */
void ED_keymap_screen(wmWindowManager *wm)
{
- ListBase *keymap;
-
- /* Screen General ------------------------------------------------ */
- keymap= WM_keymap_listbase(wm, "Screen", 0, 0);
-
+ wmKeyMap *keymap;
- /* standard timers */
- WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0);
+ /* Screen Editing ------------------------------------------------ */
+ keymap= WM_keymap_find(wm, "Screen Editing", 0, 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "modifier", 2);
-
+
/* screen tools */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE_AREA, 0, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE_AREA, 0, 0, 0);
@@ -3314,6 +3298,14 @@ void ED_keymap_screen(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "SCREEN_OT_region_scale", EVT_ACTIONZONE_REGION, 0, 0, 0);
/* area move after action zones */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
+
+
+ /* Screen General ------------------------------------------------ */
+ keymap= WM_keymap_find(wm, "Screen", 0, 0);
+
+ /* standard timers */
+ WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, 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);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
@@ -3327,15 +3319,13 @@ void ED_keymap_screen(wmWindowManager *wm)
WM_keymap_add_item(keymap, "SCREEN_OT_region_foursplit", SKEY, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0);
- #ifdef __APPLE__
- WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_OSKEY, 0);
- #endif
- WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_CTRL, 0);
+
+ WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0);
- RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", F7KEY, KM_PRESS, 0, 0)->ptr, "filename", "test.py");
+ RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", F7KEY, KM_PRESS, 0, 0)->ptr, "path", "test.py");
WM_keymap_verify_item(keymap, "SCRIPT_OT_python_run_ui_scripts", F8KEY, KM_PRESS, 0, 0);
/* files */
@@ -3365,7 +3355,7 @@ void ED_keymap_screen(wmWindowManager *wm)
/* Anim Playback ------------------------------------------------ */
- keymap= WM_keymap_listbase(wm, "Frames", 0, 0);
+ keymap= WM_keymap_find(wm, "Frames", 0, 0);
/* frame offsets */
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10);
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 5ae1bdf84aa..81c3f4d6814 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -73,24 +73,24 @@ static int screenshot_exec(bContext *C, wmOperator *op)
if(scd && scd->dumprect) {
Scene *scene= CTX_data_scene(C);
ImBuf *ibuf;
- char filename[FILE_MAX];
+ char path[FILE_MAX];
- RNA_string_get(op->ptr, "filename", filename);
+ RNA_string_get(op->ptr, "path", path);
- strcpy(G.ima, filename);
- BLI_convertstringcode(filename, G.sce);
+ strcpy(G.ima, path);
+ BLI_convertstringcode(path, G.sce);
/* BKE_add_image_extension() checks for if extension was already set */
if(scene->r.scemode & R_EXTENSION)
- if(strlen(filename)<FILE_MAXDIR+FILE_MAXFILE-5)
- BKE_add_image_extension(scene, filename, scene->r.imtype);
+ if(strlen(path)<FILE_MAXDIR+FILE_MAXFILE-5)
+ BKE_add_image_extension(scene, path, scene->r.imtype);
ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0, 0);
ibuf->rect= scd->dumprect;
if(scene->r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
- BKE_write_ibuf(scene, ibuf, filename, scene->r.imtype, scene->r.subimtype, scene->r.quality);
+ BKE_write_ibuf(scene, ibuf, path, scene->r.imtype, scene->r.subimtype, scene->r.quality);
IMB_freeImBuf(ibuf);
@@ -149,10 +149,10 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *event)
scd->dumprect= dumprect;
op->customdata= scd;
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return screenshot_exec(C, op);
- RNA_string_set(op->ptr, "filename", G.ima);
+ RNA_string_set(op->ptr, "path", G.ima);
WM_event_add_fileselect(C, op);
@@ -173,7 +173,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
ot->flag= 0;
- WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL);
RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "");
}
@@ -284,7 +284,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update)
static int screencast_exec(bContext *C, wmOperator *op)
{
bScreen *screen= CTX_wm_screen(C);
- wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), screen);
+ wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), screen, 0);
ScreenshotJob *sj= MEM_callocN(sizeof(ScreenshotJob), "screenshot job");
/* setup sj */
@@ -327,7 +327,7 @@ void SCREEN_OT_screencast(wmOperatorType *ot)
ot->flag= 0;
- RNA_def_property(ot->srna, "filename", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property(ot->srna, "path", PROP_STRING, PROP_FILEPATH);
RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "");
}
diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript
index 01e1d80c24c..3d2ea89f506 100644
--- a/source/blender/editors/sculpt_paint/SConscript
+++ b/source/blender/editors/sculpt_paint/SConscript
@@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include #/intern/guardedalloc'
incs += ' ../../gpu ../../makesrna'
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), [], libtype=['core'], priority=[40] )
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 870b66cdbbd..d223c423690 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -625,19 +625,6 @@ static void BarycentricWeightsPersp2f(float pt[2], float v1[4], float v2[4], flo
w[0] = w[1] = w[2] = 1.0f/3.0f;
}
-static void VecWeightf(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
-{
- p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
- p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
- p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2];
-}
-
-static void Vec2Weightf(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3])
-{
- p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
- p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
-}
-
static float VecZDepthOrtho(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
{
BarycentricWeights2f(pt, v1, v2, v3, w);
@@ -746,10 +733,10 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float
tf = ps->dm_mtface + face_index;
if (side == 0) {
- Vec2Weightf(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
+ Vec2Lerp3f(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
}
else { /* QUAD */
- Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
+ Vec2Lerp3f(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
}
ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */
@@ -870,8 +857,8 @@ static int project_paint_occlude_ptv_clip(
}
/* Test if we're in the clipped area, */
- if (side) VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
- else VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
+ if (side) VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
+ else VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
Mat4MulVecfl(ps->ob->obmat, wco);
if(!view3d_test_clipping(ps->rv3d, wco)) {
@@ -1146,19 +1133,6 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o
return 1;
}
-/* TODO - move to arithb.c */
-/* Converts an angle to a length that can be used for maintaining an even margin around UV's */
-static float angleToLength(float angle)
-{
- // already accounted for
- if (angle < 0.000001f) {
- return 1.0f;
- }
- else {
- return fabsf(1.0f / cosf(angle * (M_PI/180.0f)));
- }
-}
-
/* Calculate outset UV's, this is not the same as simply scaling the UVs,
* since the outset coords are a margin that keep an even distance from the original UV's,
* note that the image aspect is taken into account */
@@ -1204,15 +1178,15 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
}
if (is_quad) {
- a1 = angleToLength(NormalizedVecAngle2_2D(dir4, dir1));
- a2 = angleToLength(NormalizedVecAngle2_2D(dir1, dir2));
- a3 = angleToLength(NormalizedVecAngle2_2D(dir2, dir3));
- a4 = angleToLength(NormalizedVecAngle2_2D(dir3, dir4));
+ a1 = AngleToLength(NormalizedVecAngle2_2D(dir4, dir1));
+ a2 = AngleToLength(NormalizedVecAngle2_2D(dir1, dir2));
+ a3 = AngleToLength(NormalizedVecAngle2_2D(dir2, dir3));
+ a4 = AngleToLength(NormalizedVecAngle2_2D(dir3, dir4));
}
else {
- a1 = angleToLength(NormalizedVecAngle2_2D(dir3, dir1));
- a2 = angleToLength(NormalizedVecAngle2_2D(dir1, dir2));
- a3 = angleToLength(NormalizedVecAngle2_2D(dir2, dir3));
+ a1 = AngleToLength(NormalizedVecAngle2_2D(dir3, dir1));
+ a2 = AngleToLength(NormalizedVecAngle2_2D(dir1, dir2));
+ a3 = AngleToLength(NormalizedVecAngle2_2D(dir2, dir3));
}
if (is_quad) {
@@ -1329,7 +1303,7 @@ static void screen_px_from_ortho(
float w[3])
{
BarycentricWeights2f(uv, uv1co, uv2co, uv3co, w);
- VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
+ VecLerp3f(pixelScreenCo, v1co, v2co, v3co, w);
}
/* same as screen_px_from_ortho except we need to take into account
@@ -1363,7 +1337,7 @@ static void screen_px_from_persp(
}
/* done re-weighting */
- VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
+ VecLerp3f(pixelScreenCo, v1co, v2co, v3co, w);
}
static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3], int side, unsigned char rgba_ub[4], float rgba_f[4])
@@ -1381,7 +1355,7 @@ static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const
uvCo3 = (float *)tf_other->uv[2];
}
- Vec2Weightf(uv_other, uvCo1, uvCo2, uvCo3, w);
+ Vec2Lerp3f(uv_other, uvCo1, uvCo2, uvCo3, w);
/* use */
uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
@@ -1916,22 +1890,22 @@ static void rect_to_uvspace_ortho(
uv[0] = bucket_bounds->xmax;
uv[1] = bucket_bounds->ymin;
BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
//uv[0] = bucket_bounds->xmax; // set above
uv[1] = bucket_bounds->ymax;
BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
uv[0] = bucket_bounds->xmin;
//uv[1] = bucket_bounds->ymax; // set above
BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
//uv[0] = bucket_bounds->xmin; // set above
uv[1] = bucket_bounds->ymin;
BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
}
/* same as above but use BarycentricWeightsPersp2f */
@@ -1950,22 +1924,22 @@ static void rect_to_uvspace_persp(
uv[0] = bucket_bounds->xmax;
uv[1] = bucket_bounds->ymin;
BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
//uv[0] = bucket_bounds->xmax; // set above
uv[1] = bucket_bounds->ymax;
BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
uv[0] = bucket_bounds->xmin;
//uv[1] = bucket_bounds->ymax; // set above
BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w);
//uv[0] = bucket_bounds->xmin; // set above
uv[1] = bucket_bounds->ymin;
BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w);
}
/* This works as we need it to but we can save a few steps and not use it */
@@ -2209,13 +2183,13 @@ static void project_bucket_clip_face(
if (is_ortho) {
for(i=0; i<(*tot); i++) {
BarycentricWeights2f(isectVCosSS[i], v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
}
}
else {
for(i=0; i<(*tot); i++) {
BarycentricWeightsPersp2f(isectVCosSS[i], v1coSS, v2coSS, v3coSS, w);
- Vec2Weightf(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
+ Vec2Lerp3f(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
}
}
}
@@ -2470,7 +2444,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
/* a pitty we need to get the worldspace pixel location here */
if(ps->rv3d->rflag & RV3D_CLIPPING) {
- VecWeightf(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w);
+ VecLerp3f(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w);
Mat4MulVecfl(ps->ob->obmat, wco);
if(view3d_test_clipping(ps->rv3d, wco)) {
continue; /* Watch out that no code below this needs to run */
@@ -2686,8 +2660,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
/* a pitty we need to get the worldspace pixel location here */
if(ps->rv3d->rflag & RV3D_CLIPPING) {
- if (side) VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
- else VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
+ if (side) VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
+ else VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
Mat4MulVecfl(ps->ob->obmat, wco);
if(view3d_test_clipping(ps->rv3d, wco)) {
@@ -3757,7 +3731,7 @@ static void *do_projectpaint_thread(void *ph_v)
/*if (dist < s->brush->size) {*/ /* correct but uses a sqrtf */
if (dist_nosqrt < brush_size_sqared && (dist=sqrtf(dist_nosqrt)) < size_half) {
- falloff = brush_curve_strength(ps->brush, dist, size_half);
+ falloff = brush_curve_strength_clamp(ps->brush, dist, size_half);
if (falloff > 0.0f) {
if (ps->is_texbrush) {
brush_sample_tex(ps->brush, projPixel->projCoSS, rgba);
@@ -4443,6 +4417,7 @@ typedef struct PaintOperation {
int first;
int prevmouse[2];
+ float prev_pressure; /* need this since we dont get tablet events for pressure change */
int brush_size_orig;
double starttime;
@@ -4722,8 +4697,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
if(wmtab->Active == EVT_TABLET_ERASER)
pop->s.blend= IMB_BLEND_ERASE_ALPHA;
}
- else
- pressure= 1.0f;
+ else /* otherwise airbrush becomes 1.0 pressure instantly */
+ pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f;
if(pop->first) {
pop->prevmouse[0]= mouse[0];
@@ -4732,8 +4707,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
/* special exception here for too high pressure values on first touch in
windows for some tablets, then we just skip first touch .. */
- if ((pop->s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|
- BRUSH_SPACING_PRESSURE|BRUSH_RAD_PRESSURE)) && tablet && (pressure >= 0.99f))
+ if ((pop->s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|BRUSH_SPACING_PRESSURE)) && tablet && (pressure >= 0.99f))
return;
}
@@ -4748,6 +4722,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
/* apply */
paint_apply(C, op, &itemptr);
+
+ pop->prev_pressure= pressure;
}
static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -4762,7 +4738,7 @@ static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
paint_apply_event(C, op, event);
pop= op->customdata;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
if(pop->s.brush->flag & BRUSH_AIRBRUSH)
pop->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
@@ -4897,12 +4873,15 @@ static int paint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *even
static int paint_radial_control_exec(bContext *C, wmOperator *op)
{
+ Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint);
float zoom;
int ret;
char str[256];
get_imapaint_zoom(C, &zoom, &zoom);
- ret = brush_radial_control_exec(op, paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint), 2.0 / zoom);
+ ret = brush_radial_control_exec(op, brush, 2.0 / zoom);
WM_radial_control_string(op, str, 256);
+
+ WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
return ret;
}
@@ -4961,7 +4940,7 @@ static int grab_clone_invoke(bContext *C, wmOperator *op, wmEvent *event)
cmv->starty= event->y;
op->customdata= cmv;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -5216,10 +5195,13 @@ static int texture_paint_radial_control_invoke(bContext *C, wmOperator *op, wmEv
static int texture_paint_radial_control_exec(bContext *C, wmOperator *op)
{
- int ret = brush_radial_control_exec(op, paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint), 2);
+ Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint);
+ int ret = brush_radial_control_exec(op, brush, 2);
char str[256];
WM_radial_control_string(op, str, 256);
+ WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
+
return ret;
}
@@ -5232,6 +5214,11 @@ static int texture_paint_poll(bContext *C)
return 0;
}
+int image_texture_paint_poll(bContext *C)
+{
+ return (texture_paint_poll(C) || image_paint_poll(C));
+}
+
void PAINT_OT_texture_paint_radial_control(wmOperatorType *ot)
{
WM_OT_radial_control_partial(ot);
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index ba1b57a1bef..8251d1a5a1a 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -57,7 +57,10 @@ int paint_poll(bContext *C);
void paint_cursor_start(struct bContext *C, int (*poll)(struct bContext *C));
/* paint_vertex.c */
-int vertex_paint_mode_poll(bContext *C);
+int weight_paint_poll(struct bContext *C);
+int vertex_paint_poll(struct bContext *C);
+int vertex_paint_mode_poll(struct bContext *C);
+
void clear_vpaint(Scene *scene, int selected);
void PAINT_OT_weight_paint_toggle(struct wmOperatorType *ot);
@@ -69,6 +72,8 @@ void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
/* paint_image.c */
+int image_texture_paint_poll(struct bContext *C);
+
void PAINT_OT_image_paint(struct wmOperatorType *ot);
void PAINT_OT_image_paint_radial_control(struct wmOperatorType *ot);
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 19b46f5a941..514c80d929d 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -38,6 +38,7 @@
#include "RNA_enum_types.h"
#include "paint_intern.h"
+#include "sculpt_intern.h"
#include <string.h>
@@ -133,3 +134,48 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_vertex_color_set);
}
+void ED_keymap_paint(wmWindowManager *wm)
+{
+ wmKeyMap *keymap;
+
+ /* Sculpt mode */
+ keymap= WM_keymap_find(wm, "Sculpt", 0, 0);
+ keymap->poll= sculpt_poll;
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
+ RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
+
+ WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+
+ /* Vertex Paint mode */
+ keymap= WM_keymap_find(wm, "Vertex Paint", 0, 0);
+ keymap->poll= vertex_paint_poll;
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
+ WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
+
+ /* Weight Paint mode */
+ keymap= WM_keymap_find(wm, "Weight Paint", 0, 0);
+ keymap->poll= weight_paint_poll;
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
+
+ WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+
+ /* Image/Texture Paint mode */
+ keymap= WM_keymap_find(wm, "Image Paint", 0, 0);
+ keymap->poll= image_texture_paint_poll;
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
+
+ WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+}
+
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index bd9ea50e0f8..b83352ae70c 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -263,7 +263,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* TODO: fix hardcoded event here */
- if(event->type == LEFTMOUSE && event->val == 0) {
+ if(event->type == LEFTMOUSE && event->val == KM_RELEASE) {
/* Exit stroke, free data */
if(stroke->smooth_stroke_cursor)
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 25ff57ca87f..5afc4954c9c 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -119,7 +119,7 @@ int vertex_paint_mode_poll(bContext *C)
return ob && ob->mode == OB_MODE_VERTEX_PAINT;
}
-static int vp_poll(bContext *C)
+int vertex_paint_poll(bContext *C)
{
if(vertex_paint_mode_poll(C) &&
paint_brush(&CTX_data_tool_settings(C)->vpaint->paint)) {
@@ -133,7 +133,7 @@ static int vp_poll(bContext *C)
return 0;
}
-static int wp_poll(bContext *C)
+int weight_paint_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
@@ -710,7 +710,9 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x
if(totface+4>=MAXINDEX) return 0;
- if(size>64.0) size= 64.0;
+ /* brecht: disabled this because it obviously failes for
+ brushes with size > 64, why is this here? */
+ /*if(size>64.0) size= 64.0;*/
ibuf= view3d_read_backbuf(vc, x-size, y-size, x+size, y+size);
if(ibuf) {
@@ -1058,7 +1060,7 @@ static int set_wpaint(bContext *C, wmOperator *op) /* toggle */
wp= scene->toolsettings->wpaint= new_vpaint(1);
paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT);
- paint_cursor_start(C, wp_poll);
+ paint_cursor_start(C, weight_paint_poll);
mesh_octree_table(ob, NULL, NULL, 's');
@@ -1127,14 +1129,18 @@ static int vpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
{
int ret = WM_radial_control_modal(C, op, event);
if(ret != OPERATOR_RUNNING_MODAL)
- paint_cursor_start(C, vp_poll);
+ paint_cursor_start(C, vertex_paint_poll);
return ret;
}
static int vpaint_radial_control_exec(bContext *C, wmOperator *op)
{
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->vpaint->paint);
- return brush_radial_control_exec(op, brush, 1);
+ int ret = brush_radial_control_exec(op, brush, 1);
+
+ WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
+
+ return ret;
}
static int wpaint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -1152,14 +1158,18 @@ static int wpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
{
int ret = WM_radial_control_modal(C, op, event);
if(ret != OPERATOR_RUNNING_MODAL)
- paint_cursor_start(C, wp_poll);
+ paint_cursor_start(C, weight_paint_poll);
return ret;
}
static int wpaint_radial_control_exec(bContext *C, wmOperator *op)
{
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->wpaint->paint);
- return brush_radial_control_exec(op, brush, 1);
+ int ret = brush_radial_control_exec(op, brush, 1);
+
+ WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
+
+ return ret;
}
void PAINT_OT_weight_paint_radial_control(wmOperatorType *ot)
@@ -1172,7 +1182,7 @@ void PAINT_OT_weight_paint_radial_control(wmOperatorType *ot)
ot->invoke= wpaint_radial_control_invoke;
ot->modal= wpaint_radial_control_modal;
ot->exec= wpaint_radial_control_exec;
- ot->poll= wp_poll;
+ ot->poll= weight_paint_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -1188,7 +1198,7 @@ void PAINT_OT_vertex_paint_radial_control(wmOperatorType *ot)
ot->invoke= vpaint_radial_control_invoke;
ot->modal= vpaint_radial_control_modal;
ot->exec= vpaint_radial_control_exec;
- ot->poll= vp_poll;
+ ot->poll= vertex_paint_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -1492,7 +1502,7 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
wpaint_stroke_done);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
op->type->modal(C, op, event);
@@ -1510,7 +1520,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
ot->invoke= wpaint_invoke;
ot->modal= paint_stroke_modal;
/* ot->exec= vpaint_exec; <-- needs stroke property */
- ot->poll= wp_poll;
+ ot->poll= weight_paint_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -1557,7 +1567,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
if(vp==NULL)
vp= scene->toolsettings->vpaint= new_vpaint(0);
- paint_cursor_start(C, vp_poll);
+ paint_cursor_start(C, vertex_paint_poll);
paint_init(&vp->paint, PAINT_CURSOR_VERTEX_PAINT);
}
@@ -1732,6 +1742,10 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
}
Mat4SwapMat4(vc->rv3d->persmat, mat);
+
+ /* was disabled because it is slow, but necessary for blur */
+ if(vp->mode == VP_BLUR)
+ do_shared_vertexcol(me);
ED_region_tag_redraw(vc->ar);
@@ -1761,7 +1775,7 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
vpaint_stroke_done);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
op->type->modal(C, op, event);
@@ -1778,7 +1792,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot)
ot->invoke= vpaint_invoke;
ot->modal= paint_stroke_modal;
/* ot->exec= vpaint_exec; <-- needs stroke property */
- ot->poll= vp_poll;
+ ot->poll= vertex_paint_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index be31ab45af4..e41231442ba 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1155,7 +1155,7 @@ static int sculpt_mode_poll(bContext *C)
return ob && ob->mode & OB_MODE_SCULPT;
}
-static int sculpt_poll(bContext *C)
+int sculpt_poll(bContext *C)
{
return sculpt_mode_poll(C) && paint_poll(C);
}
@@ -1207,8 +1207,11 @@ static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
static int sculpt_radial_control_exec(bContext *C, wmOperator *op)
{
Brush *brush = paint_brush(&CTX_data_tool_settings(C)->sculpt->paint);
+ int ret = brush_radial_control_exec(op, brush, 1);
- return brush_radial_control_exec(op, brush, 1);
+ WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
+
+ return ret;
}
static void SCULPT_OT_radial_control(wmOperatorType *ot)
@@ -1564,7 +1567,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
sculpt_stroke_done);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
op->type->modal(C, op, event);
@@ -1693,10 +1696,10 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT);
paint_cursor_start(C, sculpt_poll);
-
- WM_event_add_notifier(C, NC_SCENE|ND_MODE, CTX_data_scene(C));
}
+ WM_event_add_notifier(C, NC_SCENE|ND_MODE, CTX_data_scene(C));
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 25f97b862e6..15ccacc294a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -33,6 +33,7 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
+struct bContext;
struct Brush;
struct Mesh;
struct Object;
@@ -53,6 +54,8 @@ struct Brush *sculptmode_brush(void);
char sculpt_modifiers_active(struct Object *ob);
void sculpt(Sculpt *sd);
+int sculpt_poll(struct bContext *C);
+
/* Stroke */
struct SculptStroke *sculpt_stroke_new(const int max);
void sculpt_stroke_free(struct SculptStroke *);
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 303ca0eaefd..1121a3bcbcd 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -66,13 +66,13 @@
static int open_exec(bContext *C, wmOperator *op)
{
- char filename[FILE_MAX];
+ char path[FILE_MAX];
bSound *sound;
AUD_SoundInfo info;
- RNA_string_get(op->ptr, "filename", filename);
+ RNA_string_get(op->ptr, "path", path);
- sound = sound_new_file(CTX_data_main(C), filename);
+ sound = sound_new_file(CTX_data_main(C), path);
if (sound==NULL || sound->handle == NULL) {
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
@@ -114,7 +114,7 @@ void SOUND_OT_open(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL);
RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
}
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 89633d0cdfe..865d072d938 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -89,6 +89,44 @@
#include "action_intern.h"
/* ************************************************************************** */
+/* ACTION MANAGEMENT */
+
+/* ******************** New Action Operator *********************** */
+
+static int act_new_exec(bContext *C, wmOperator *op)
+{
+ bAction *action;
+
+ // XXX need to restore behaviour to copy old actions...
+ action= add_empty_action("Action");
+
+ /* combined with RNA property, this will assign & increase user,
+ so decrease here to compensate for that */
+ action->id.us--;
+
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void ACT_OT_new (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New";
+ ot->idname= "ACT_OT_new";
+ ot->description= "Create new action.";
+
+ /* api callbacks */
+ ot->exec= act_new_exec;
+ // NOTE: this is used in the NLA too...
+ //ot->poll= ED_operator_action_active;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ************************************************************************** */
/* KEYFRAME-RANGE STUFF */
/* *************************** Calculate Range ************************** */
diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c
index 8674f481a18..25a5123d1b5 100644
--- a/source/blender/editors/space_action/action_header.c
+++ b/source/blender/editors/space_action/action_header.c
@@ -189,6 +189,7 @@ static void act_edit_keytypesmenu(bContext *C, uiLayout *layout, void *arg_unuse
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_KEYFRAME);
uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_BREAKDOWN);
+ uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_EXTREME);
}
static void act_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused)
@@ -260,61 +261,6 @@ static void do_action_buttons(bContext *C, void *arg, int event)
}
}
-static void saction_idpoin_handle(bContext *C, ID *id, int event)
-{
- SpaceAction *saction= CTX_wm_space_action(C);
- Object *obact= CTX_data_active_object(C);
-
- printf("actedit do id: \n");
-
- switch (event) {
- case UI_ID_BROWSE:
- printf("browse \n");
- case UI_ID_DELETE:
- printf("browse or delete \n");
- saction->action= (bAction*)id;
-
- /* we must set this action to be the one used by active object (if not pinned) */
- if (saction->pin == 0) {
- AnimData *adt= BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */
-
- /* set action */
- printf("\tset action \n");
- adt->action= saction->action;
- adt->action->id.us++;
- }
-
- ED_area_tag_redraw(CTX_wm_area(C));
- ED_undo_push(C, "Assign Action");
- break;
- case UI_ID_RENAME:
- printf("actedit rename \n");
- break;
- case UI_ID_ADD_NEW:
- printf("actedit addnew \n");
- if (saction->pin == 0) {
- AnimData *adt= BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */
-
- /* set new action */
- // XXX need to restore behaviour to copy old actions...
- printf("\tset new action \n");
- adt->action= saction->action= add_empty_action("Action");
- }
- break;
- case UI_ID_OPEN:
- printf("actedit open \n");
- /* XXX not implemented */
- break;
- case UI_ID_ALONE:
- printf("actedit alone \n");
- /* XXX not implemented */
- break;
- case UI_ID_PIN:
- printf("actedit pin \n");
- break;
- }
-}
-
void action_header_buttons(const bContext *C, ARegion *ar)
{
ScrArea *sa= CTX_wm_area(C);
@@ -390,28 +336,18 @@ void action_header_buttons(const bContext *C, ARegion *ar)
/* FILTERING OPTIONS */
xco -= 10;
- //uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Only display selected Objects");
- //uiBlockEndAlign(block);
- xco += 5;
-
- uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Scene Animation");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display World Animation");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display ShapeKeys");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Materials");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Lamps");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Cameras");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Curves");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display MetaBalls");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Particles");
- uiBlockEndAlign(block);
- xco += 30;
+ xco= ANIM_headerUI_standard_buttons(C, &saction->ads, block, xco, yco);
}
else if (saction->mode == SACTCONT_ACTION) {
- /* NAME ETC */
- xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)saction->action, ID_AC, &saction->pin, xco, yco,
- saction_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE|UI_ID_FAKE_USER|UI_ID_ALONE|UI_ID_PIN);
+ uiLayout *layout;
+ bScreen *sc= CTX_wm_screen(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&sc->id, &RNA_SpaceDopeSheetEditor, saction, &ptr);
+
+ layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, 20+3, 20, 1, U.uistyles.first);
+ uiTemplateID(layout, (bContext*)C, &ptr, "action", "ACT_OT_new", NULL, NULL);
+ uiBlockLayoutResolve(block, &xco, NULL);
xco += 8;
}
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index e5f0ab8994e..4326bed62d3 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -99,6 +99,8 @@ void ACT_OT_frame_jump(struct wmOperatorType *ot);
void ACT_OT_snap(struct wmOperatorType *ot);
void ACT_OT_mirror(struct wmOperatorType *ot);
+void ACT_OT_new(struct wmOperatorType *ot);
+
/* defines for snap keyframes
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
*/
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 42b033040b1..00b22232608 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -83,6 +83,7 @@ void action_operatortypes(void)
WM_operatortype_append(ACT_OT_insert_keyframe);
WM_operatortype_append(ACT_OT_copy);
WM_operatortype_append(ACT_OT_paste);
+ WM_operatortype_append(ACT_OT_new);
WM_operatortype_append(ACT_OT_previewrange_set);
WM_operatortype_append(ACT_OT_view_all);
@@ -90,7 +91,7 @@ void action_operatortypes(void)
/* ************************** registration - keymaps **********************************/
-static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
+static void action_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap)
{
wmKeymapItem *kmi;
@@ -165,7 +166,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
void action_keymap(wmWindowManager *wm)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
/* channels */
/* Channels are not directly handled by the Action Editor module, but are inherited from the Animation module.
@@ -174,7 +175,7 @@ void action_keymap(wmWindowManager *wm)
*/
/* keyframes */
- keymap= WM_keymap_listbase(wm, "Action_Keys", SPACE_ACTION, 0);
+ keymap= WM_keymap_find(wm, "Action_Keys", SPACE_ACTION, 0);
action_keymap_keyframes(wm, keymap);
}
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index b7a3df563ea..3b275cab814 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -153,12 +153,12 @@ static SpaceLink *action_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void action_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Action_Keys", SPACE_ACTION, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Action_Keys", SPACE_ACTION, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -216,12 +216,12 @@ static void action_main_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void action_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Animation_Channels", 0, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Animation_Channels", 0, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -323,6 +323,7 @@ static void action_main_area_listener(ARegion *ar, wmNotifier *wmn)
break;
case NC_SCENE:
switch(wmn->data) {
+ case ND_RENDER_OPTIONS:
case ND_OB_ACTIVE:
case ND_FRAME:
case ND_MARKERS:
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index edd5da44526..8c563c98d9b 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -46,8 +46,8 @@
#include "ED_markers.h"
#include "ED_mesh.h"
#include "ED_object.h"
-#include "ED_particle.h"
#include "ED_physics.h"
+#include "ED_render.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_space_api.h"
@@ -92,15 +92,13 @@ void ED_spacetypes_init(void)
ED_operatortypes_sculpt();
ED_operatortypes_uvedit();
ED_operatortypes_paint();
- ED_operatortypes_particle();
+ ED_operatortypes_physics();
ED_operatortypes_curve();
ED_operatortypes_armature();
ED_operatortypes_marker();
- ED_operatortypes_pointcache();
- ED_operatortypes_fluid();
ED_operatortypes_metaball();
- ED_operatortypes_boids();
ED_operatortypes_sound();
+ ED_operatortypes_render();
ui_view2d_operatortypes();
@@ -127,8 +125,9 @@ void ED_spacetypes_keymap(wmWindowManager *wm)
ED_keymap_uvedit(wm);
ED_keymap_curve(wm);
ED_keymap_armature(wm);
- ED_keymap_particle(wm);
+ ED_keymap_physics(wm);
ED_keymap_metaball(wm);
+ ED_keymap_paint(wm);
ED_marker_keymap(wm);
UI_view2d_keymap(wm);
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 635abd429f6..9333ba9209c 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -463,6 +463,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
found= buttons_context_path_texture(C, path);
break;
case BCONTEXT_BONE:
+ case BCONTEXT_BONE_CONSTRAINT:
found= buttons_context_path_bone(path);
if(!found)
found= buttons_context_path_data(path, OB_ARMATURE);
@@ -553,7 +554,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
"world", "object", "mesh", "armature", "lattice", "curve",
"meta_ball", "lamp", "camera", "material", "material_slot",
"texture", "texture_slot", "bone", "edit_bone", "particle_system",
- "cloth", "soft_body", "fluid", "smoke", "smoke_hr", "collision", "brush", NULL};
+ "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL};
CTX_data_dir_set(result, dir);
return 1;
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index a1041bc5106..83dd679c543 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -114,13 +114,15 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
if(sbuts->pathflag & (1<<BCONTEXT_OBJECT))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_OBJECT_DATA, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object");
if(sbuts->pathflag & (1<<BCONTEXT_CONSTRAINT))
- uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint");
+ uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Object Constraints");
if(sbuts->pathflag & (1<<BCONTEXT_DATA))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, sbuts->dataicon, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data");
if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER))
- uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
+ uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifiers");
if(sbuts->pathflag & (1<<BCONTEXT_BONE))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_BONE_DATA, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone");
+ if(sbuts->pathflag & (1<<BCONTEXT_BONE_CONSTRAINT))
+ uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_BONE_CONSTRAINT, 0, 0, "Bone Constraints");
if(sbuts->pathflag & (1<<BCONTEXT_MATERIAL))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MATERIAL, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_MATERIAL, 0, 0, "Material");
if(sbuts->pathflag & (1<<BCONTEXT_TEXTURE))
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 0a5a5714a06..2e95fde8f99 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -64,33 +64,6 @@ void buttons_context_draw(const struct bContext *C, struct uiLayout *layout);
void buttons_context_register(struct ARegionType *art);
/* buttons_ops.c */
-void OBJECT_OT_group_add(struct wmOperatorType *ot);
-void OBJECT_OT_group_remove(struct wmOperatorType *ot);
-
-void OBJECT_OT_material_slot_add(struct wmOperatorType *ot);
-void OBJECT_OT_material_slot_remove(struct wmOperatorType *ot);
-void OBJECT_OT_material_slot_assign(struct wmOperatorType *ot);
-void OBJECT_OT_material_slot_select(struct wmOperatorType *ot);
-void OBJECT_OT_material_slot_deselect(struct wmOperatorType *ot);
-
-void MATERIAL_OT_new(struct wmOperatorType *ot);
-void TEXTURE_OT_new(struct wmOperatorType *ot);
-void WORLD_OT_new(struct wmOperatorType *ot);
-
-void OBJECT_OT_particle_system_add(struct wmOperatorType *ot);
-void OBJECT_OT_particle_system_remove(struct wmOperatorType *ot);
-
-void PARTICLE_OT_new(struct wmOperatorType *ot);
-void PARTICLE_OT_new_target(struct wmOperatorType *ot);
-void PARTICLE_OT_remove_target(struct wmOperatorType *ot);
-void PARTICLE_OT_target_move_up(struct wmOperatorType *ot);
-void PARTICLE_OT_target_move_down(struct wmOperatorType *ot);
-void PARTICLE_OT_connect_hair(struct wmOperatorType *ot);
-void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot);
-
-void SCENE_OT_render_layer_add(struct wmOperatorType *ot);
-void SCENE_OT_render_layer_remove(struct wmOperatorType *ot);
-
void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
void BUTTONS_OT_toolbox(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 481c2d6cfc3..2d961f78243 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -30,53 +30,14 @@
#include "MEM_guardedalloc.h"
-#include "DNA_boid_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_group_types.h"
-#include "DNA_object_types.h"
-#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_node_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "DNA_world_types.h"
-#include "BKE_bvhutils.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_group.h"
-#include "BKE_font.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_material.h"
-#include "BKE_modifier.h"
-#include "BKE_node.h"
-#include "BKE_particle.h"
-#include "BKE_pointcache.h"
-#include "BKE_scene.h"
-#include "BKE_texture.h"
-#include "BKE_utildefines.h"
-#include "BKE_world.h"
-
-#include "BLI_arithb.h"
-#include "BLI_editVert.h"
-#include "BLI_listbase.h"
-
-#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_curve.h"
-#include "ED_mesh.h"
-#include "ED_particle.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
@@ -85,947 +46,6 @@
#include "buttons_intern.h" // own include
-
-/********************** material slot operators *********************/
-
-static int material_slot_add_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
-
- if(!ob)
- return OPERATOR_CANCELLED;
-
- object_add_material_slot(ob);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_material_slot_add(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Add Material Slot";
- ot->idname= "OBJECT_OT_material_slot_add";
- ot->description="Add a new material slot or duplicate the selected one.";
-
- /* api callbacks */
- ot->exec= material_slot_add_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int material_slot_remove_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
-
- if(!ob)
- return OPERATOR_CANCELLED;
-
- object_remove_material_slot(ob);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Remove Material Slot";
- ot->idname= "OBJECT_OT_material_slot_remove";
- ot->description="Remove the selected material slot.";
-
- /* api callbacks */
- ot->exec= material_slot_remove_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int material_slot_assign_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
-
- if(!ob)
- return OPERATOR_CANCELLED;
-
- if(ob && ob->actcol>0) {
- if(ob->type == OB_MESH) {
- EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
- EditFace *efa;
-
- if(em) {
- for(efa= em->faces.first; efa; efa=efa->next)
- if(efa->f & SELECT)
- efa->mat_nr= ob->actcol-1;
- }
- }
- else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
- ListBase *editnurb= ((Curve*)ob->data)->editnurb;
- Nurb *nu;
-
- if(editnurb) {
- for(nu= editnurb->first; nu; nu= nu->next)
- if(isNurbsel(nu))
- nu->mat_nr= nu->charidx= ob->actcol-1;
- }
- }
- else if(ob->type == OB_FONT) {
- EditFont *ef= ((Curve*)ob->data)->editfont;
- int i, selstart, selend;
-
- if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
- for(i=selstart; i<=selend; i++)
- ef->textbufinfo[i].mat_nr = ob->actcol-1;
- }
- }
- }
-
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Assign Material Slot";
- ot->idname= "OBJECT_OT_material_slot_assign";
- ot->description="Assign the material in the selected material slot to the selected vertices.";
-
- /* api callbacks */
- ot->exec= material_slot_assign_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int material_slot_de_select(bContext *C, int select)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
-
- if(!ob)
- return OPERATOR_CANCELLED;
-
- if(ob->type == OB_MESH) {
- EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
-
- if(em) {
- if(select)
- EM_select_by_material(em, ob->actcol-1);
- else
- EM_deselect_by_material(em, ob->actcol-1);
- }
- }
- else if ELEM(ob->type, OB_CURVE, OB_SURF) {
- ListBase *editnurb= ((Curve*)ob->data)->editnurb;
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
-
- for(nu= editnurb->first; nu; nu=nu->next) {
- if(nu->mat_nr==ob->actcol-1) {
- if(nu->bezt) {
- a= nu->pntsu;
- bezt= nu->bezt;
- while(a--) {
- if(bezt->hide==0) {
- if(select) {
- bezt->f1 |= SELECT;
- bezt->f2 |= SELECT;
- bezt->f3 |= SELECT;
- }
- else {
- bezt->f1 &= ~SELECT;
- bezt->f2 &= ~SELECT;
- bezt->f3 &= ~SELECT;
- }
- }
- bezt++;
- }
- }
- else if(nu->bp) {
- a= nu->pntsu*nu->pntsv;
- bp= nu->bp;
- while(a--) {
- if(bp->hide==0) {
- if(select) bp->f1 |= SELECT;
- else bp->f1 &= ~SELECT;
- }
- bp++;
- }
- }
- }
- }
- }
-
- WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
-
- return OPERATOR_FINISHED;
-}
-
-static int material_slot_select_exec(bContext *C, wmOperator *op)
-{
- return material_slot_de_select(C, 1);
-}
-
-void OBJECT_OT_material_slot_select(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Select Material Slot";
- ot->idname= "OBJECT_OT_material_slot_select";
- ot->description="Select vertices assigned to the selected material slot.";
-
- /* api callbacks */
- ot->exec= material_slot_select_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int material_slot_deselect_exec(bContext *C, wmOperator *op)
-{
- return material_slot_de_select(C, 0);
-}
-
-void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Deselect Material Slot";
- ot->idname= "OBJECT_OT_material_slot_deselect";
- ot->description="Deselect vertices assigned to the selected material slot.";
-
- /* api callbacks */
- ot->exec= material_slot_deselect_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/********************** new material operator *********************/
-
-static int new_material_exec(bContext *C, wmOperator *op)
-{
- Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
- Object *ob;
- PointerRNA ptr;
- int index;
-
- /* add or copy material */
- if(ma)
- ma= copy_material(ma);
- else
- ma= add_material("Material");
-
- ma->id.us--; /* compensating for us++ in assign_material */
-
- /* attempt to assign to material slot */
- ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
-
- if(ptr.data) {
- ob= ptr.id.data;
- index= (Material**)ptr.data - ob->mat;
-
- assign_material(ob, ma, index+1);
-
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
- }
-
- WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
-
- return OPERATOR_FINISHED;
-}
-
-void MATERIAL_OT_new(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "New Material";
- ot->idname= "MATERIAL_OT_new";
- ot->description="Add a new material.";
-
- /* api callbacks */
- ot->exec= new_material_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/********************** new texture operator *********************/
-
-static int new_texture_exec(bContext *C, wmOperator *op)
-{
- Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
- ID *id;
- MTex *mtex;
- PointerRNA ptr;
-
- /* add or copy texture */
- if(tex)
- tex= copy_texture(tex);
- else
- tex= add_texture("Texture");
-
- id_us_min(&tex->id);
-
- /* attempt to assign to texture slot */
- ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
-
- if(ptr.data) {
- id= ptr.id.data;
- mtex= ptr.data;
-
- if(mtex) {
- if(mtex->tex)
- id_us_min(&mtex->tex->id);
- mtex->tex= tex;
- id_us_plus(&tex->id);
- }
-
- /* XXX nodes, notifier .. */
- }
-
- WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
-
- return OPERATOR_FINISHED;
-}
-
-void TEXTURE_OT_new(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "New Texture";
- ot->idname= "TEXTURE_OT_new";
- ot->description="Add a new texture.";
-
- /* api callbacks */
- ot->exec= new_texture_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/********************** new world operator *********************/
-
-static int new_world_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
-
- /* add or copy world */
- if(wo)
- wo= copy_world(wo);
- else
- wo= add_world("World");
-
- /* assign to scene */
- if(scene->world)
- id_us_min(&scene->world->id);
- scene->world= wo;
-
- WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
-
- return OPERATOR_FINISHED;
-}
-
-void WORLD_OT_new(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "New World";
- ot->idname= "WORLD_OT_new";
- ot->description= "Add a new world.";
-
- /* api callbacks */
- ot->exec= new_world_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-
-
-/********************** particle system slot operators *********************/
-
-static int particle_system_add_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- Scene *scene = CTX_data_scene(C);
-
- if(!scene || !ob)
- return OPERATOR_CANCELLED;
-
- object_add_particle_system(scene, ob);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_particle_system_add(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Add Particle System Slot";
- ot->idname= "OBJECT_OT_particle_system_add";
- ot->description="Add a particle system.";
-
- /* api callbacks */
- ot->exec= particle_system_add_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int particle_system_remove_exec(bContext *C, wmOperator *op)
-{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- Scene *scene = CTX_data_scene(C);
-
- if(!scene || !ob)
- return OPERATOR_CANCELLED;
-
- object_remove_particle_system(scene, ob);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Remove Particle System Slot";
- ot->idname= "OBJECT_OT_particle_system_remove";
- ot->description="Remove the selected particle system.";
-
- /* api callbacks */
- ot->exec= particle_system_remove_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/********************** new particle settings operator *********************/
-
-static int psys_poll(bContext *C)
-{
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- return (ptr.data != NULL);
-}
-
-static int new_particle_settings_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- Main *bmain= CTX_data_main(C);
- ParticleSystem *psys;
- ParticleSettings *part = NULL;
- Object *ob;
- PointerRNA ptr;
-
- ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
-
- psys = ptr.data;
-
- /* add or copy particle setting */
- if(psys->part)
- part= psys_copy_settings(psys->part);
- else
- part= psys_new_settings("ParticleSettings", bmain);
-
- ob= ptr.id.data;
-
- if(psys->part)
- psys->part->id.us--;
-
- psys->part = part;
-
- psys_check_boid_data(psys);
-
- DAG_scene_sort(scene);
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
-
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_new(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "New Particle Settings";
- ot->idname= "PARTICLE_OT_new";
- ot->description="Add new particle settings.";
-
- /* api callbacks */
- ot->exec= new_particle_settings_exec;
- ot->poll= psys_poll;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/********************** keyed particle target operators *********************/
-
-static int new_particle_target_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- ParticleSystem *psys= ptr.data;
- Object *ob = ptr.id.data;
-
- ParticleTarget *pt;
-
- if(!psys)
- return OPERATOR_CANCELLED;
-
- pt = psys->targets.first;
- for(; pt; pt=pt->next)
- pt->flag &= ~PTARGET_CURRENT;
-
- pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target");
-
- pt->flag |= PTARGET_CURRENT;
- pt->psys = 1;
-
- BLI_addtail(&psys->targets, pt);
-
- DAG_scene_sort(scene);
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
-
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_new_target(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "New Particle Target";
- ot->idname= "PARTICLE_OT_new_target";
- ot->description="Add a new particle target.";
-
- /* api callbacks */
- ot->exec= new_particle_target_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int remove_particle_target_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- ParticleSystem *psys= ptr.data;
- Object *ob = ptr.id.data;
-
- ParticleTarget *pt;
-
- if(!psys)
- return OPERATOR_CANCELLED;
-
- pt = psys->targets.first;
- for(; pt; pt=pt->next) {
- if(pt->flag & PTARGET_CURRENT) {
- BLI_remlink(&psys->targets, pt);
- MEM_freeN(pt);
- break;
- }
-
- }
- pt = psys->targets.last;
-
- if(pt)
- pt->flag |= PTARGET_CURRENT;
-
- DAG_scene_sort(scene);
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
-
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_remove_target(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Remove Particle Target";
- ot->idname= "PARTICLE_OT_remove_target";
- ot->description="Remove the selected particle target.";
-
- /* api callbacks */
- ot->exec= remove_particle_target_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/************************ move up particle target operator *********************/
-
-static int target_move_up_exec(bContext *C, wmOperator *op)
-{
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- ParticleSystem *psys= ptr.data;
- Object *ob = ptr.id.data;
- ParticleTarget *pt;
-
- if(!psys)
- return OPERATOR_CANCELLED;
-
- pt = psys->targets.first;
- for(; pt; pt=pt->next) {
- if(pt->flag & PTARGET_CURRENT && pt->prev) {
- BLI_remlink(&psys->targets, pt);
- BLI_insertlink(&psys->targets, pt->prev->prev, pt);
-
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
- break;
- }
- }
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_target_move_up(wmOperatorType *ot)
-{
- ot->name= "Move Up Target";
- ot->idname= "PARTICLE_OT_target_move_up";
- ot->description= "Move particle target up in the list.";
-
- ot->exec= target_move_up_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/************************ move down particle target operator *********************/
-
-static int target_move_down_exec(bContext *C, wmOperator *op)
-{
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- ParticleSystem *psys= ptr.data;
- Object *ob = ptr.id.data;
- ParticleTarget *pt;
-
- if(!psys)
- return OPERATOR_CANCELLED;
- pt = psys->targets.first;
- for(; pt; pt=pt->next) {
- if(pt->flag & PTARGET_CURRENT && pt->next) {
- BLI_remlink(&psys->targets, pt);
- BLI_insertlink(&psys->targets, pt->next, pt);
-
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
- break;
- }
- }
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_target_move_down(wmOperatorType *ot)
-{
- ot->name= "Move Down Target";
- ot->idname= "PARTICLE_OT_target_move_down";
- ot->description= "Move particle target down in the list.";
-
- ot->exec= target_move_down_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/************************ connect/disconnect hair operators *********************/
-
-static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
-{
- ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
- ParticleData *pa = psys->particles;
- PTCacheEdit *edit = psys->edit;
- PTCacheEditPoint *point = edit ? edit->points : NULL;
- PTCacheEditKey *ekey = NULL;
- HairKey *key;
- int i, k;
- float hairmat[4][4];
-
- if(!ob || !psys || psys->flag & PSYS_GLOBAL_HAIR)
- return;
-
- if(!psys->part || psys->part->type != PART_HAIR)
- return;
-
- for(i=0; i<psys->totpart; i++,pa++) {
- if(point) {
- ekey = point->keys;
- point++;
- }
-
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
-
- for(k=0,key=pa->hair; k<pa->totkey; k++,key++) {
- Mat4MulVecfl(hairmat,key->co);
-
- if(ekey) {
- ekey->flag &= ~PEK_USE_WCO;
- ekey++;
- }
- }
- }
-
- psys_free_path_cache(psys, psys->edit);
-
- psys->flag |= PSYS_GLOBAL_HAIR;
-
- PE_update_object(scene, ob, 0);
-}
-
-static int disconnect_hair_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- ParticleSystem *psys= NULL;
- int all = RNA_boolean_get(op->ptr, "all");
-
- if(!ob)
- return OPERATOR_CANCELLED;
-
- if(all) {
- for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- disconnect_hair(scene, ob, psys);
- }
- }
- else {
- psys = ptr.data;
- disconnect_hair(scene, ob, psys);
- }
-
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
-{
- ot->name= "Disconnect Hair";
- ot->description= "Disconnect hair from the emitter mesh.";
- ot->idname= "PARTICLE_OT_disconnect_hair";
-
- ot->exec= disconnect_hair_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
- 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)
-{
- ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
- ParticleData *pa = psys->particles;
- PTCacheEdit *edit = psys->edit;
- PTCacheEditPoint *point = edit ? edit->points : NULL;
- PTCacheEditKey *ekey;
- HairKey *key;
- BVHTreeFromMesh bvhtree;
- BVHTreeNearest nearest;
- MFace *mface;
- DerivedMesh *dm = NULL;
- int numverts;
- int i, k;
- float hairmat[4][4], imat[4][4];
- float v[4][3], vec[3];
-
- if(!psys || !psys->part || psys->part->type != PART_HAIR)
- return;
-
- if(psmd->dm->deformedOnly)
- dm= psmd->dm;
- else
- dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
-
- numverts = dm->getNumVerts (dm);
-
- memset( &bvhtree, 0, sizeof(bvhtree) );
-
- /* convert to global coordinates */
- for (i=0; i<numverts; i++)
- Mat4MulVecfl (ob->obmat, CDDM_get_vert(dm, i)->co);
-
- bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6);
-
- for(i=0; i<psys->totpart; i++,pa++) {
- key = pa->hair;
-
- nearest.index = -1;
- nearest.dist = FLT_MAX;
-
- BLI_bvhtree_find_nearest(bvhtree.tree, key->co, &nearest, bvhtree.nearest_callback, &bvhtree);
-
- if(nearest.index == -1) {
- printf("No nearest point found for hair root!");
- continue;
- }
-
- mface = CDDM_get_face(dm,nearest.index);
-
- VecCopyf(v[0], CDDM_get_vert(dm,mface->v1)->co);
- VecCopyf(v[1], CDDM_get_vert(dm,mface->v2)->co);
- VecCopyf(v[2], CDDM_get_vert(dm,mface->v3)->co);
- if(mface->v4) {
- VecCopyf(v[3], CDDM_get_vert(dm,mface->v4)->co);
- MeanValueWeights(v, 4, nearest.co, pa->fuv);
- }
- else
- MeanValueWeights(v, 3, nearest.co, pa->fuv);
-
- pa->num = nearest.index;
- pa->num_dmcache = psys_particle_dm_face_lookup(ob,psmd->dm,pa->num,pa->fuv,NULL);
-
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
- Mat4Invert(imat,hairmat);
-
- VECSUB(vec, nearest.co, key->co);
-
- if(point) {
- ekey = point->keys;
- point++;
- }
-
- for(k=0,key=pa->hair; k<pa->totkey; k++,key++) {
- VECADD(key->co, key->co, vec);
- Mat4MulVecfl(imat,key->co);
-
- if(ekey) {
- ekey->flag |= PEK_USE_WCO;
- ekey++;
- }
- }
- }
-
- free_bvhtree_from_mesh(&bvhtree);
- if(!psmd->dm->deformedOnly)
- dm->release(dm);
-
- psys_free_path_cache(psys, psys->edit);
-
- psys->flag &= ~PSYS_GLOBAL_HAIR;
-
- PE_update_object(scene, ob, 0);
-}
-
-static int connect_hair_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
- ParticleSystem *psys= NULL;
- int all = RNA_boolean_get(op->ptr, "all");
-
- if(!ob)
- return OPERATOR_CANCELLED;
-
- if(all) {
- for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- connect_hair(scene, ob, psys);
- }
- }
- else {
- psys = ptr.data;
- connect_hair(scene, ob, psys);
- }
-
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void PARTICLE_OT_connect_hair(wmOperatorType *ot)
-{
- ot->name= "Connect Hair";
- ot->description= "Connect hair to the emitter mesh.";
- ot->idname= "PARTICLE_OT_connect_hair";
-
- ot->exec= connect_hair_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
- RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
-}
-
-/********************** render layer operators *********************/
-
-static int render_layer_add_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
-
- scene_add_render_layer(scene);
- scene->r.actlay= BLI_countlist(&scene->r.layers) - 1;
-
- WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
-
- return OPERATOR_FINISHED;
-}
-
-void SCENE_OT_render_layer_add(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Add Render Layer";
- ot->idname= "SCENE_OT_render_layer_add";
- ot->description="Add a render layer.";
-
- /* api callbacks */
- ot->exec= render_layer_add_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-static int render_layer_remove_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- SceneRenderLayer *rl;
- int act= scene->r.actlay;
-
- if(BLI_countlist(&scene->r.layers) <= 1)
- return OPERATOR_CANCELLED;
-
- rl= BLI_findlink(&scene->r.layers, scene->r.actlay);
- BLI_remlink(&scene->r.layers, rl);
- MEM_freeN(rl);
-
- scene->r.actlay= 0;
-
- if(scene->nodetree) {
- bNode *node;
- for(node= scene->nodetree->nodes.first; node; node= node->next) {
- if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
- if(node->custom1==act)
- node->custom1= 0;
- else if(node->custom1>act)
- node->custom1--;
- }
- }
- }
-
- WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
-
- return OPERATOR_FINISHED;
-}
-
-void SCENE_OT_render_layer_remove(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Remove Render Layer";
- ot->idname= "SCENE_OT_render_layer_remove";
- ot->description="Remove the selected render layer.";
-
- /* api callbacks */
- ot->exec= render_layer_remove_exec;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
/********************** toolbox operator *********************/
static int toolbox_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -1069,10 +89,10 @@ static int file_browse_exec(bContext *C, wmOperator *op)
FileBrowseOp *fbo= op->customdata;
char *str;
- if (RNA_property_is_set(op->ptr, "filename")==0 || fbo==NULL)
+ if (RNA_property_is_set(op->ptr, "path")==0 || fbo==NULL)
return OPERATOR_CANCELLED;
- str= RNA_string_get_alloc(op->ptr, "filename", 0, 0);
+ str= RNA_string_get_alloc(op->ptr, "path", 0, 0);
RNA_property_string_set(&fbo->ptr, fbo->prop, str);
RNA_property_update(C, &fbo->ptr, fbo->prop);
MEM_freeN(str);
@@ -1107,7 +127,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
op->customdata= fbo;
str= RNA_property_string_get_alloc(&ptr, prop, 0, 0);
- RNA_string_set(op->ptr, "filename", str);
+ RNA_string_set(op->ptr, "path", str);
MEM_freeN(str);
WM_event_add_fileselect(C, op);
@@ -1128,6 +148,6 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot)
ot->cancel= file_browse_cancel;
/* properties */
- WM_operator_properties_filesel(ot, 0);
+ WM_operator_properties_filesel(ot, 0, FILE_SPECIAL);
}
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index d4ad77daca7..6ffbb79f273 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -57,7 +57,7 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "buttons_intern.h" // own include
@@ -138,11 +138,11 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "Buttons Generic", SPACE_BUTS, 0);
+ keymap= WM_keymap_find(wm, "Buttons Generic", SPACE_BUTS, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -176,6 +176,8 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, vertical, "modifier", sbuts->mainb);
else if (sbuts->mainb == BCONTEXT_CONSTRAINT)
ED_region_panels(C, ar, vertical, "constraint", sbuts->mainb);
+ else if(sbuts->mainb == BCONTEXT_BONE_CONSTRAINT)
+ ED_region_panels(C, ar, vertical, "bone_constraint", sbuts->mainb);
sbuts->re_align= 0;
sbuts->mainbo= sbuts->mainb;
@@ -183,40 +185,13 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
void buttons_operatortypes(void)
{
- WM_operatortype_append(OBJECT_OT_group_add);
- WM_operatortype_append(OBJECT_OT_group_remove);
-
- WM_operatortype_append(OBJECT_OT_material_slot_add);
- WM_operatortype_append(OBJECT_OT_material_slot_remove);
- WM_operatortype_append(OBJECT_OT_material_slot_assign);
- WM_operatortype_append(OBJECT_OT_material_slot_select);
- WM_operatortype_append(OBJECT_OT_material_slot_deselect);
-
- WM_operatortype_append(MATERIAL_OT_new);
- WM_operatortype_append(TEXTURE_OT_new);
- WM_operatortype_append(WORLD_OT_new);
-
- WM_operatortype_append(OBJECT_OT_particle_system_add);
- WM_operatortype_append(OBJECT_OT_particle_system_remove);
-
- WM_operatortype_append(PARTICLE_OT_new);
- WM_operatortype_append(PARTICLE_OT_new_target);
- WM_operatortype_append(PARTICLE_OT_remove_target);
- WM_operatortype_append(PARTICLE_OT_target_move_up);
- WM_operatortype_append(PARTICLE_OT_target_move_down);
- WM_operatortype_append(PARTICLE_OT_connect_hair);
- WM_operatortype_append(PARTICLE_OT_disconnect_hair);
-
- WM_operatortype_append(SCENE_OT_render_layer_add);
- WM_operatortype_append(SCENE_OT_render_layer_remove);
-
WM_operatortype_append(BUTTONS_OT_toolbox);
WM_operatortype_append(BUTTONS_OT_file_browse);
}
void buttons_keymap(struct wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Buttons Generic", SPACE_BUTS, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Buttons Generic", SPACE_BUTS, 0);
WM_keymap_add_item(keymap, "BUTTONS_OT_toolbox", RIGHTMOUSE, KM_PRESS, 0, 0);
}
@@ -259,58 +234,6 @@ static void buttons_header_area_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
}
-#if 0
-/* add handlers, stuff you only do once or on area/region changes */
-static void buttons_context_area_init(wmWindowManager *wm, ARegion *ar)
-{
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
-}
-
-#define CONTEXTY 30
-
-static void buttons_context_area_draw(const bContext *C, ARegion *ar)
-{
- SpaceButs *sbuts= CTX_wm_space_buts(C);
- uiStyle *style= U.uistyles.first;
- uiBlock *block;
- uiLayout *layout;
- View2D *v2d= &ar->v2d;
- float col[3];
- int x, y, w, h;
-
- buttons_context_compute(C, sbuts);
-
- w= v2d->cur.xmax - v2d->cur.xmin;
- h= v2d->cur.ymax - v2d->cur.ymin;
- UI_view2d_view_ortho(C, v2d);
-
- /* create UI */
- block= uiBeginBlock(C, ar, "buttons_context", UI_EMBOSS);
- layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_PANEL,
- style->panelspace, h - (h-UI_UNIT_Y)/2, w, 20, style);
-
- buttons_context_draw(C, layout);
-
- uiBlockLayoutResolve(C, block, &x, &y);
- uiEndBlock(C, block);
-
- /* draw */
- UI_SetTheme(SPACE_BUTS, RGN_TYPE_WINDOW); /* XXX */
-
- UI_GetThemeColor3fv(TH_BACK, col);
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- UI_view2d_totRect_set(v2d, x, -y);
- UI_view2d_view_ortho(C, v2d);
-
- uiDrawBlock(C, block);
-
- /* restore view matrix */
- UI_view2d_view_restore(C);
-}
-#endif
-
/* reused! */
static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
{
@@ -424,19 +347,6 @@ void ED_spacetype_buttons(void)
art->draw= buttons_header_area_draw;
BLI_addhead(&st->regiontypes, art);
-#if 0
- /* regions: context */
- art= MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
- art->regionid = RGN_TYPE_CHANNELS;
- art->minsizey= CONTEXTY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
- art->init= buttons_context_area_init;
- art->draw= buttons_context_area_draw;;
- art->listener= buttons_area_listener;
-
- BLI_addhead(&st->regiontypes, art);
-#endif
-
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 2120b97becf..ccf7dbff946 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -51,6 +51,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
+#include "BKE_text.h" /* only for character utility funcs */
#include "WM_api.h"
#include "WM_types.h"
@@ -119,6 +120,48 @@ static int console_line_cursor_set(ConsoleLine *cl, int cursor)
return 1;
}
+static char cursor_char(ConsoleLine *cl)
+{
+ /* assume cursor is clamped */
+ return cl->line[cl->cursor];
+}
+
+static char cursor_char_prev(ConsoleLine *cl)
+{
+ /* assume cursor is clamped */
+ if(cl->cursor <= 0)
+ return '\0';
+
+ return cl->line[cl->cursor-1];
+}
+
+static char cursor_char_next(ConsoleLine *cl)
+{
+ /* assume cursor is clamped */
+ if(cl->cursor + 1 >= cl->len)
+ return '\0';
+
+ return cl->line[cl->cursor+1];
+}
+
+static void console_lb_debug__internal(ListBase *lb)
+{
+ ConsoleLine *cl;
+
+ printf("%d: ", BLI_countlist(lb));
+ for(cl= lb->first; cl; cl= cl->next)
+ printf("<%s> ", cl->line);
+ printf("\n");
+
+}
+
+static void console_history_debug(const bContext *C)
+{
+ SpaceConsole *sc= CTX_wm_space_console(C);
+
+ console_lb_debug__internal(&sc->history);
+}
+
static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
{
ConsoleLine *ci= MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
@@ -251,7 +294,7 @@ static EnumPropertyItem move_type_items[]= {
{PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
{NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
{0, NULL, 0, NULL, NULL}};
-
+
static int move_exec(bContext *C, wmOperator *op)
{
ConsoleLine *ci= console_history_verify(C);
@@ -272,6 +315,37 @@ static int move_exec(bContext *C, wmOperator *op)
case NEXT_CHAR:
done= console_line_cursor_set(ci, ci->cursor+1);
break;
+
+ /* - if the character is a delimiter then skip delimiters (including white space)
+ * - when jump over the word */
+ case PREV_WORD:
+ while(text_check_delim(cursor_char_prev(ci)))
+ if(console_line_cursor_set(ci, ci->cursor-1)==FALSE)
+ break;
+
+ while(text_check_delim(cursor_char_prev(ci))==FALSE)
+ if(console_line_cursor_set(ci, ci->cursor-1)==FALSE)
+ break;
+
+ /* This isnt used for NEXT_WORD because when going back
+ * its more useful to have the cursor directly after a word then whitespace */
+ while(text_check_whitespace(cursor_char_prev(ci))==TRUE)
+ if(console_line_cursor_set(ci, ci->cursor-1)==FALSE)
+ break;
+
+ done= 1; /* assume changed */
+ break;
+ case NEXT_WORD:
+ while(text_check_delim(cursor_char(ci))==TRUE)
+ if (console_line_cursor_set(ci, ci->cursor+1)==FALSE)
+ break;
+
+ while(text_check_delim(cursor_char(ci))==FALSE)
+ if (console_line_cursor_set(ci, ci->cursor+1)==FALSE)
+ break;
+
+ done= 1; /* assume changed */
+ break;
}
if(done) {
@@ -466,7 +540,16 @@ static int history_cycle_exec(bContext *C, wmOperator *op)
ConsoleLine *ci= console_history_verify(C); /* TODO - stupid, just prevernts crashes when no command line */
short reverse= RNA_boolean_get(op->ptr, "reverse"); /* assumes down, reverse is up */
-
+
+ /* keep a copy of the line above so when history is cycled
+ * this is the only function that needs to know about the double-up */
+ if(ci->prev) {
+ ConsoleLine *ci_prev= (ConsoleLine *)ci->prev;
+
+ if(strcmp(ci->line, ci_prev->line)==0)
+ console_history_free(sc, ci_prev);
+ }
+
if(reverse) { /* last item in mistory */
ci= sc->history.last;
BLI_remlink(&sc->history, ci);
@@ -477,9 +560,17 @@ static int history_cycle_exec(bContext *C, wmOperator *op)
BLI_remlink(&sc->history, ci);
BLI_addtail(&sc->history, ci);
}
-
+
+ { /* add a duplicate of the new arg and remove all other instances */
+ ConsoleLine *cl;
+ while((cl= console_history_find(sc, ci->line, ci)))
+ console_history_free(sc, cl);
+
+ console_history_add(C, (ConsoleLine *)sc->history.last);
+ }
+
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index dfaaa269970..19fb575ed16 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -147,12 +147,12 @@ static SpaceLink *console_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void console_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -174,6 +174,9 @@ static void console_main_area_draw(const bContext *C, ARegion *ar)
console_scrollback_add_str(C, "Autocomplete: Ctrl+Space", 0);
console_scrollback_add_str(C, "Ctrl +/- Wheel: Zoom", 0);
console_scrollback_add_str(C, "Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.ui", 0);
+
+ /* This is normally set by python but to start with its easier just to set it like this rather then running python with no args */
+ strcpy(sc->prompt, ">>> ");
}
/* clear and setup matrix */
@@ -231,15 +234,15 @@ void console_operatortypes(void)
void console_keymap(struct wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0);
- #ifdef __APPLE__
+#ifdef __APPLE__
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END);
- #endif
+#endif
- RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN);
- RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
+ RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
+ RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript
index e6fba38fb8f..b22a265dcbc 100644
--- a/source/blender/editors/space_file/SConscript
+++ b/source/blender/editors/space_file/SConscript
@@ -15,4 +15,11 @@ if env['WITH_BF_OPENJPEG']:
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_space_file', sources, Split(incs), defs, libtype=['core'], priority=[115] )
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 00024ffa961..77a1b671054 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -133,24 +133,24 @@ static void do_file_buttons(bContext *C, void *arg, int event)
void file_draw_buttons(const bContext *C, ARegion *ar)
{
/* Button layout. */
- const short min_x = 10;
- const short max_x = ar->winx - 10;
- const short line1_y = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2;
- const short line2_y = IMASEL_BUTTONS_MARGIN;
- const short input_minw = 20;
- const short btn_h = UI_UNIT_Y;
- const short btn_fn_w = UI_UNIT_X;
- const short btn_minw = 80;
- const short btn_margin = 20;
- const short separator = 4;
+ const int min_x = 10;
+ const int max_x = ar->winx - 10;
+ const int line1_y = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2;
+ const int line2_y = IMASEL_BUTTONS_MARGIN;
+ const int input_minw = 20;
+ const int btn_h = UI_UNIT_Y;
+ const int btn_fn_w = UI_UNIT_X;
+ const int btn_minw = 80;
+ const int btn_margin = 20;
+ const int separator = 4;
/* Additional locals. */
char name[20];
- short loadbutton;
- short fnumbuttons;
- short available_w = max_x - min_x;
- short line1_w = available_w;
- short line2_w = available_w;
+ int loadbutton;
+ int fnumbuttons;
+ int available_w = max_x - min_x;
+ int line1_w = available_w;
+ int line2_w = available_w;
uiBut* but;
uiBlock* block;
@@ -189,7 +189,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
if (available_w > 0) {
but = uiDefBut(block, TEX, B_FS_DIRNAME, "",
min_x, line1_y, line1_w, btn_h,
- params->dir, 0.0, (float)FILE_MAXDIR-1, 0, 0,
+ params->dir, 0.0, (float)FILE_MAX-1, 0, 0,
"File path.");
uiButSetCompleteFunc(but, autocomplete_directory, NULL);
uiDefBut(block, TEX, B_FS_FILENAME, "",
@@ -230,7 +230,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
}
-static void draw_tile(short sx, short sy, short width, short height, int colorid, int shade)
+static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade)
{
UI_ThemeColorShade(colorid, shade);
uiSetRoundBox(15);
@@ -310,25 +310,25 @@ static int get_file_icon(struct direntry *file)
return ICON_FILE_BLANK;
}
-static void file_draw_icon(short sx, short sy, int icon, short width, short height)
+static void file_draw_icon(int sx, int sy, int icon, int width, int height)
{
float x,y;
- int blend=0;
+ float alpha=1.0f;
x = (float)(sx);
y = (float)(sy-height);
- if (icon == ICON_FILE_BLANK) blend = -80;
+ if (icon == ICON_FILE_BLANK) alpha = 0.375f;
glEnable(GL_BLEND);
- UI_icon_draw_aspect_blended(x, y, icon, 1.f, blend);
+ UI_icon_draw_aspect(x, y, icon, 1.f, alpha);
}
-static void file_draw_string(short sx, short sy, const char* string, float width, short height, int flag)
+static void file_draw_string(int sx, int sy, const char* string, float width, int height, int flag)
{
- short soffs;
+ int soffs;
char fname[FILE_MAXFILE];
float sw;
float x,y;
@@ -350,18 +350,19 @@ void file_calc_previews(const bContext *C, ARegion *ar)
View2D *v2d= &ar->v2d;
ED_fileselect_init_layout(sfile, ar);
- UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
+ /* +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);
}
-static void file_draw_preview(short sx, short sy, ImBuf *imb, FileLayout *layout, short dropshadow)
+static void file_draw_preview(int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow)
{
if (imb) {
float fx, fy;
float dx, dy;
- short xco, yco;
+ int xco, yco;
float scaledx, scaledy;
float scale;
- short ex, ey;
+ int ex, ey;
if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) {
if (imb->x > imb->y) {
@@ -379,8 +380,8 @@ static void file_draw_preview(short sx, short sy, ImBuf *imb, FileLayout *layout
scaledy = (float)imb->y;
scale = 1.0;
}
- ex = (short)scaledx;
- ey = (short)scaledy;
+ ex = (int)scaledx;
+ ey = (int)scaledy;
fx = ((float)layout->prv_w - (float)ex)/2.0f;
fy = ((float)layout->prv_h - (float)ey)/2.0f;
dx = (fx + 0.5f + layout->prv_border_x);
@@ -442,7 +443,7 @@ static void renamebutton_cb(bContext *C, void *arg1, char *oldname)
static void draw_background(FileLayout *layout, View2D *v2d)
{
int i;
- short sy;
+ int sy;
/* alternating flat shade background */
for (i=0; (i <= layout->rows); i+=2)
@@ -457,7 +458,7 @@ static void draw_background(FileLayout *layout, View2D *v2d)
static void draw_dividers(FileLayout *layout, View2D *v2d)
{
- short sx;
+ int sx;
/* vertical column dividers */
sx = v2d->tot.xmin;
@@ -483,7 +484,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
int numfiles;
int numfiles_layout;
int colorid = 0;
- short sx, sy;
+ int sx, sy;
int offset;
int i;
float sw, spos;
@@ -491,12 +492,6 @@ void file_draw_list(const bContext *C, ARegion *ar)
numfiles = filelist_numfiles(files);
- sx = ar->v2d.tot.xmin + layout->tile_border_x/2;
- sy = ar->v2d.cur.ymax - layout->tile_border_y;
-
- offset = ED_fileselect_layout_offset(layout, 0, 0);
- if (offset<0) offset=0;
-
if (params->display != FILE_IMGDISPLAY) {
draw_background(layout, v2d);
@@ -504,9 +499,9 @@ void file_draw_list(const bContext *C, ARegion *ar)
draw_dividers(layout, v2d);
}
- sx = ar->v2d.cur.xmin + layout->tile_border_x;
- sy = ar->v2d.cur.ymax - layout->tile_border_y;
-
+ offset = ED_fileselect_layout_offset(layout, ar->v2d.cur.xmin, -ar->v2d.cur.ymax);
+ if (offset<0) offset=0;
+
numfiles_layout = ED_fileselect_layout_numfiles(layout, ar);
for (i=offset; (i < numfiles) && (i<offset+numfiles_layout); ++i)
@@ -552,7 +547,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
sw = file_string_width(file->relname);
if (file->flags & EDITING) {
- short but_width = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : layout->column_widths[COLUMN_NAME];
+ int but_width = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : layout->column_widths[COLUMN_NAME];
uiBlock *block = uiBeginBlock(C, ar, "FileName", UI_EMBOSS);
uiBut *but = uiDefBut(block, TEX, 1, "", spos, sy-layout->tile_h-3,
but_width, layout->textheight*2, file->relname, 1.0f, (float)FILE_MAX,0,0,"");
@@ -573,15 +568,14 @@ void file_draw_list(const bContext *C, ARegion *ar)
spos += layout->column_widths[COLUMN_NAME] + 12;
if (!(file->type & S_IFDIR)) {
sw = file_string_width(file->size);
- spos += layout->column_widths[COLUMN_SIZE] + 12 - sw;
file_draw_string(spos, sy, file->size, sw+1, layout->tile_h, FILE_SHORTEN_END);
+ spos += layout->column_widths[COLUMN_SIZE] + 12;
}
} else if (params->display == FILE_LONGDISPLAY) {
spos += layout->column_widths[COLUMN_NAME] + 12;
#ifndef WIN32
/* rwx rwx rwx */
- spos += 20;
sw = file_string_width(file->mode1);
file_draw_string(spos, sy, file->mode1, sw, layout->tile_h, FILE_SHORTEN_END);
spos += layout->column_widths[COLUMN_MODE1] + 12;
@@ -609,8 +603,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
if (!(file->type & S_IFDIR)) {
sw = file_string_width(file->size);
- spos += layout->column_widths[COLUMN_SIZE] + 12 - sw;
file_draw_string(spos, sy, file->size, sw, layout->tile_h, FILE_SHORTEN_END);
+ spos += layout->column_widths[COLUMN_SIZE] + 12;
}
}
}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index e1a6e346ce2..75230813a41 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -68,25 +68,15 @@
/* ---------- FILE SELECTION ------------ */
-static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short y, short clamp)
+static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, int x, int y)
{
float fx,fy;
int active_file = -1;
- int numfiles = filelist_numfiles(sfile->files);
View2D* v2d = &ar->v2d;
UI_view2d_region_to_view(v2d, x, y, &fx, &fy);
active_file = ED_fileselect_layout_offset(sfile->layout, v2d->tot.xmin + fx, v2d->tot.ymax - fy);
-
- if(active_file < 0) {
- if(clamp) active_file= 0;
- else active_file= -1;
- }
- else if(active_file >= numfiles) {
- if(clamp) active_file= numfiles-1;
- else active_file= -1;
- }
return active_file;
}
@@ -109,6 +99,31 @@ typedef enum FileSelect { FILE_SELECT_DIR = 1,
FILE_SELECT_FILE = 2 } FileSelect;
+static void clamp_to_filelist(int numfiles, int *first_file, int *last_file)
+{
+ /* border select before the first file */
+ if ( (*first_file < 0) && (*last_file >=0 ) ) {
+ *first_file = 0;
+ }
+ /* don't select if everything is outside filelist */
+ if ( (*first_file >= numfiles) && ((*last_file < 0) || (*last_file >= numfiles)) ) {
+ *first_file = -1;
+ *last_file = -1;
+ }
+
+ /* fix if last file invalid */
+ if ( (*first_file > 0) && (*last_file < 0) )
+ *last_file = numfiles-1;
+
+ /* clamp */
+ if ( (*first_file >= numfiles) ) {
+ *first_file = numfiles-1;
+ }
+ if ( (*last_file >= numfiles) ) {
+ *last_file = numfiles-1;
+ }
+}
+
static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short val)
{
int first_file = -1;
@@ -123,9 +138,11 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s
int numfiles = filelist_numfiles(sfile->files);
params->selstate = NOTACTIVE;
- first_file = find_file_mouse(sfile, ar, rect->xmin, rect->ymax, 1);
- last_file = find_file_mouse(sfile, ar, rect->xmax, rect->ymin, 1);
+ first_file = find_file_mouse(sfile, ar, rect->xmin, rect->ymax);
+ last_file = find_file_mouse(sfile, ar, rect->xmax, rect->ymin);
+ clamp_to_filelist(numfiles, &first_file, &last_file);
+
/* select all valid files between first and last indicated */
if ( (first_file >= 0) && (first_file < numfiles) && (last_file >= 0) && (last_file < numfiles) ) {
for (act_file = first_file; act_file <= last_file; act_file++) {
@@ -137,6 +154,9 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s
}
}
+ /* Don't act on multiple selected files */
+ if (first_file != last_file) selecting= 0;
+
/* make the last file active */
if (selecting && (last_file >= 0 && last_file < numfiles)) {
struct direntry* file = filelist_file(sfile->files, last_file);
@@ -168,7 +188,7 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s
}
}
- }
+ }
return retval;
}
@@ -449,7 +469,7 @@ int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my)
my -= ar->winrct.ymin;
if(BLI_in_rcti(&ar->v2d.mask, mx, my)) {
- actfile = find_file_mouse(sfile, ar, mx , my, 0);
+ actfile = find_file_mouse(sfile, ar, mx , my);
if((actfile >= 0) && (actfile < numfiles))
params->active_file=actfile;
@@ -496,9 +516,26 @@ int file_cancel_exec(bContext *C, wmOperator *unused)
WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_CANCEL);
sfile->op = NULL;
+ if (sfile->files) {
+ filelist_freelib(sfile->files);
+ filelist_free(sfile->files);
+ MEM_freeN(sfile->files);
+ sfile->files= NULL;
+ }
+
return OPERATOR_FINISHED;
}
+int file_operator_poll(bContext *C)
+{
+ int poll = ED_operator_file_active(C);
+ SpaceFile *sfile= CTX_wm_space_file(C);
+
+ if (!sfile || !sfile->op) poll= 0;
+
+ return poll;
+}
+
void FILE_OT_cancel(struct wmOperatorType *ot)
{
/* identifiers */
@@ -507,7 +544,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
/* api callbacks */
ot->exec= file_cancel_exec;
- ot->poll= ED_operator_file_active;
+ ot->poll= file_operator_poll;
}
/* sends events now, so things get handled on windowqueue level */
@@ -520,9 +557,16 @@ int file_exec(bContext *C, wmOperator *unused)
wmOperator *op= sfile->op;
sfile->op = NULL;
+ RNA_string_set(op->ptr, "filename", sfile->params->file);
BLI_strncpy(name, sfile->params->dir, sizeof(name));
+ RNA_string_set(op->ptr, "directory", name);
strcat(name, sfile->params->file);
- RNA_string_set(op->ptr, "filename", name);
+
+ if(RNA_struct_find_property(op->ptr, "relative_paths"))
+ if(RNA_boolean_get(op->ptr, "relative_paths"))
+ BLI_makestringcode(G.sce, name);
+
+ RNA_string_set(op->ptr, "path", name);
/* some ops have multiple files to select */
{
@@ -561,6 +605,11 @@ int file_exec(bContext *C, wmOperator *unused)
BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
fsmenu_write_file(fsmenu_get(), name);
WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC);
+
+ filelist_freelib(sfile->files);
+ filelist_free(sfile->files);
+ MEM_freeN(sfile->files);
+ sfile->files= NULL;
}
return OPERATOR_FINISHED;
@@ -574,7 +623,7 @@ void FILE_OT_execute(struct wmOperatorType *ot)
/* api callbacks */
ot->exec= file_exec;
- ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+ ot->poll= file_operator_poll;
}
@@ -699,7 +748,9 @@ int file_directory_new_exec(bContext *C, wmOperator *unused)
BLI_join_dirfile(tmpstr, tmpstr, tmpdir);
}
BLI_recurdir_fileops(tmpstr);
- if (!BLI_exists(tmpstr)) {
+ if (BLI_exists(tmpstr)) {
+ BLI_strncpy(sfile->params->renamefile, tmpdir, FILE_MAXFILE);
+ } else {
filelist_free(sfile->files);
filelist_parent(sfile->files);
BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX);
@@ -847,13 +898,9 @@ int file_bookmark_toggle_exec(bContext *C, wmOperator *unused)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= file_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
@@ -872,11 +919,13 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot)
int file_filenum_exec(bContext *C, wmOperator *op)
{
SpaceFile *sfile= CTX_wm_space_file(C);
+ ScrArea *sa= CTX_wm_area(C);
int inc = RNA_int_get(op->ptr, "increment");
if(sfile->params && (inc != 0)) {
BLI_newname(sfile->params->file, inc);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ ED_area_tag_redraw(sa);
+ // WM_event_add_notifier(C, NC_WINDOW, NULL);
}
return OPERATOR_FINISHED;
@@ -916,6 +965,24 @@ int file_rename_exec(bContext *C, wmOperator *op)
}
+int file_rename_poll(bContext *C)
+{
+ int poll = ED_operator_file_active(C);
+ SpaceFile *sfile= CTX_wm_space_file(C);
+
+ if (sfile && sfile->params) {
+ if (sfile->params->active_file < 0) {
+ poll= 0;
+ } else {
+ char dir[FILE_MAX], group[FILE_MAX];
+ if (filelist_islibrary(sfile->files, dir, group)) poll= 0;
+ }
+ }
+ else
+ poll= 0;
+ return poll;
+}
+
void FILE_OT_rename(struct wmOperatorType *ot)
{
/* identifiers */
@@ -924,7 +991,7 @@ void FILE_OT_rename(struct wmOperatorType *ot)
/* api callbacks */
ot->exec= file_rename_exec;
- ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+ ot->poll= file_rename_poll;
}
@@ -938,6 +1005,8 @@ int file_delete_poll(bContext *C)
if (sfile->params->active_file < 0) {
poll= 0;
} else {
+ char dir[FILE_MAX], group[FILE_MAX];
+ if (filelist_islibrary(sfile->files, dir, group)) poll= 0;
file = filelist_file(sfile->files, sfile->params->active_file);
if (file && S_ISDIR(file->type)) poll= 0;
}
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 24c3f9b4ca1..1b54277c383 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -181,6 +181,12 @@ static void file_panel_operator(const bContext *C, Panel *pa)
RNA_STRUCT_BEGIN(op->ptr, prop) {
if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
continue;
+ if(strcmp(RNA_property_identifier(prop), "filemode") == 0)
+ continue;
+ if(strcmp(RNA_property_identifier(prop), "path") == 0)
+ continue;
+ if(strcmp(RNA_property_identifier(prop), "directory") == 0)
+ continue;
if(strcmp(RNA_property_identifier(prop), "filename") == 0)
continue;
if(strcmp(RNA_property_identifier(prop), "display") == 0)
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 538c1e4fce7..8257aa5482f 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -60,6 +60,7 @@
#include "BKE_library.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_report.h"
#include "BLO_readfile.h"
#include "DNA_space_types.h"
@@ -109,7 +110,6 @@ typedef struct FileList
{
struct direntry *filelist;
int *fidx;
-
int numfiles;
int numfiltered;
char dir[FILE_MAX];
@@ -118,6 +118,12 @@ typedef struct FileList
short hide_dot;
unsigned int filter;
short changed;
+
+ struct BlendHandle *libfiledata;
+ short hide_parent;
+
+ void (*read)(struct FileList *);
+
ListBase loadimages;
ListBase threads;
} FileList;
@@ -277,12 +283,20 @@ static int compare_extension(const void *a1, const void *a2) {
void filelist_filter(FileList* filelist)
{
+ /* char dir[FILE_MAX], group[GROUP_MAX]; XXXXX */
int num_filtered = 0;
int i, j;
if (!filelist->filelist)
return;
+ /* XXXXX TODO: check if the filter can be handled outside the filelist
+ if ( ( (filelist->type == FILE_LOADLIB) && BIF_filelist_islibrary(filelist, dir, group))
+ || (filelist->type == FILE_MAIN) ) {
+ filelist->filter = 0;
+ }
+ */
+
if (!filelist->filter) {
if (filelist->fidx) {
MEM_freeN(filelist->fidx);
@@ -438,23 +452,29 @@ void folderlist_free(ListBase* folderlist)
folderlist= NULL;
}
+static void filelist_read_main(struct FileList* filelist);
+static void filelist_read_library(struct FileList* filelist);
+static void filelist_read_dir(struct FileList* filelist);
+
//------------------FILELIST------------------------//
-struct FileList* filelist_new()
+struct FileList* filelist_new(short type)
{
FileList* p = MEM_callocN( sizeof(FileList), "filelist" );
- return p;
-}
-
-struct FileList* filelist_copy(struct FileList* filelist)
-{
- FileList* p = filelist_new();
- BLI_strncpy(p->dir, filelist->dir, FILE_MAX);
- p->filelist = NULL;
- p->fidx = NULL;
+ switch(type) {
+ case FILE_MAIN:
+ p->read = filelist_read_main;
+ break;
+ case FILE_LOADLIB:
+ p->read = filelist_read_library;
+ break;
+ default:
+ p->read = filelist_read_dir;
+ }
return p;
}
+
void filelist_free(struct FileList* filelist)
{
int i;
@@ -493,6 +513,18 @@ void filelist_free(struct FileList* filelist)
filelist->hide_dot =0;
}
+void filelist_freelib(struct FileList* filelist)
+{
+ if(filelist->libfiledata)
+ BLO_blendhandle_close(filelist->libfiledata);
+ filelist->libfiledata= 0;
+}
+
+struct BlendHandle *filelist_lib(struct FileList* filelist)
+{
+ return filelist->libfiledata;
+}
+
int filelist_numfiles(struct FileList* filelist)
{
return filelist->numfiltered;
@@ -560,10 +592,12 @@ void filelist_loadimage_timer(struct FileList* filelist)
}
if (limg->done) {
FileImage *oimg = limg;
- BLI_remlink(&filelist->loadimages, oimg);
BLI_remove_thread(&filelist->threads, oimg);
+ /* brecht: keep failed images in the list, otherwise
+ it keeps trying to load them over and over?
+ BLI_remlink(&filelist->loadimages, oimg);
+ MEM_freeN(oimg);*/
limg = oimg->next;
- MEM_freeN(oimg);
refresh = 1;
} else {
limg= limg->next;
@@ -733,16 +767,16 @@ void filelist_setfilter(struct FileList* filelist, unsigned int filter)
filelist->filter = filter;
}
-void filelist_readdir(struct FileList* filelist)
+static void filelist_read_dir(struct FileList* filelist)
{
char wdir[FILE_MAX];
-
if (!filelist) return;
+
filelist->fidx = 0;
filelist->filelist = 0;
BLI_getwdN(wdir);
-
+
BLI_cleanup_dir(G.sce, filelist->dir);
BLI_hide_dot_files(filelist->hide_dot);
filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist));
@@ -750,12 +784,52 @@ void filelist_readdir(struct FileList* filelist)
chdir(wdir);
filelist_setfiletypes(filelist, G.have_quicktime);
filelist_filter(filelist);
-
+
if (!filelist->threads.first) {
BLI_init_threads(&filelist->threads, exec_loadimages, 2);
}
}
+static void filelist_read_main(struct FileList* filelist)
+{
+ if (!filelist) return;
+ filelist_from_main(filelist);
+}
+
+static void filelist_read_library(struct FileList* filelist)
+{
+ if (!filelist) return;
+ BLI_cleanup_dir(G.sce, filelist->dir);
+ filelist_from_library(filelist);
+ if(!filelist->libfiledata) {
+ int num;
+ struct direntry *file;
+
+ BLI_make_exist(filelist->dir);
+ filelist_read_dir(filelist);
+ file = filelist->filelist;
+ for(num=0; num<filelist->numfiles; num++, file++) {
+ if(BLO_has_bfile_extension(file->relname)) {
+ char name[FILE_MAXDIR+FILE_MAXFILE];
+
+ BLI_strncpy(name, filelist->dir, sizeof(name));
+ strcat(name, file->relname);
+
+ /* prevent current file being used as acceptable dir */
+ if (BLI_streq(G.main->name, name)==0) {
+ file->type &= ~S_IFMT;
+ file->type |= S_IFDIR;
+ }
+ }
+ }
+ }
+}
+
+void filelist_readdir(struct FileList* filelist)
+{
+ filelist->read(filelist);
+}
+
int filelist_empty(struct FileList* filelist)
{
return filelist->filelist == 0;
@@ -937,3 +1011,259 @@ void filelist_sort(struct FileList* filelist, short sort)
filelist_filter(filelist);
}
+
+
+int filelist_islibrary(struct FileList* filelist, char* dir, char* group)
+{
+ return BLO_is_a_library(filelist->dir, dir, group);
+}
+
+static int groupname_to_code(char *group)
+{
+ char buf[32];
+ char *lslash;
+
+ BLI_strncpy(buf, group, 31);
+ lslash= BLI_last_slash(buf);
+ if (lslash)
+ lslash[0]= '\0';
+
+ return BLO_idcode_from_name(buf);
+}
+
+void filelist_from_library(struct FileList* filelist)
+{
+ LinkNode *l, *names, *previews;
+ struct ImBuf* ima;
+ int ok, i, nnames, idcode;
+ char filename[FILE_MAXDIR+FILE_MAXFILE];
+ char dir[FILE_MAX], group[GROUP_MAX];
+
+ /* name test */
+ ok= filelist_islibrary(filelist, dir, group);
+ if (!ok) {
+ /* free */
+ if(filelist->libfiledata) BLO_blendhandle_close(filelist->libfiledata);
+ filelist->libfiledata= 0;
+ return;
+ }
+
+ BLI_strncpy(filename, G.sce, sizeof(filename)); // G.sce = last file loaded, for UI
+
+ /* there we go */
+ /* for the time being only read filedata when libfiledata==0 */
+ if (filelist->libfiledata==0) {
+ filelist->libfiledata= BLO_blendhandle_from_file(dir);
+ if(filelist->libfiledata==0) return;
+ }
+
+ idcode= groupname_to_code(group);
+
+ // memory for strings is passed into filelist[i].relname
+ // and free'd in freefilelist
+ previews = NULL;
+ if (idcode) {
+ previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode);
+ names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode);
+ /* ugh, no rewind, need to reopen */
+ BLO_blendhandle_close(filelist->libfiledata);
+ filelist->libfiledata= BLO_blendhandle_from_file(dir);
+
+ } else {
+ names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata);
+ }
+
+ nnames= BLI_linklist_length(names);
+
+ filelist->numfiles= nnames + 1;
+ filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist));
+ memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist));
+
+ filelist->filelist[0].relname= BLI_strdup("..");
+ filelist->filelist[0].type |= S_IFDIR;
+
+ for (i=0, l= names; i<nnames; i++, l= l->next) {
+ char *blockname= l->link;
+
+ filelist->filelist[i + 1].relname= BLI_strdup(blockname);
+ if (!idcode)
+ filelist->filelist[i + 1].type |= S_IFDIR;
+ }
+
+ if(previews) {
+ for (i=0, l= previews; i<nnames; i++, l= l->next) {
+ PreviewImage *img= l->link;
+
+ if (img) {
+ unsigned int w = img->w[PREVIEW_MIPMAP_LARGE];
+ unsigned int h = img->h[PREVIEW_MIPMAP_LARGE];
+ unsigned int *rect = img->rect[PREVIEW_MIPMAP_LARGE];
+
+ /* first allocate imbuf for copying preview into it */
+ if (w > 0 && h > 0 && rect) {
+ ima = IMB_allocImBuf(w, h, 32, IB_rect, 0);
+ memcpy(ima->rect, rect, w*h*sizeof(unsigned int));
+ filelist->filelist[i + 1].image = ima;
+ filelist->filelist[i + 1].flags = IMAGEFILE;
+ }
+ }
+ }
+ }
+
+ BLI_linklist_free(names, free);
+ if (previews) BLI_linklist_free(previews, (void(*)(void*)) MEM_freeN);
+
+ filelist_sort(filelist, FILE_SORT_ALPHA);
+
+ BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change
+
+ filelist->filter = 0;
+ filelist_filter(filelist);
+}
+
+void filelist_hideparent(struct FileList* filelist, short hide)
+{
+ filelist->hide_parent = hide;
+}
+
+void filelist_from_main(struct FileList *filelist)
+{
+ ID *id;
+ struct direntry *files, *firstlib = NULL;
+ ListBase *lb;
+ int a, fake, idcode, ok, totlib, totbl;
+
+ // filelist->type = FILE_MAIN; // XXXXX TODO: add modes to filebrowser
+
+ if(filelist->dir[0]=='/') filelist->dir[0]= 0;
+
+ if(filelist->dir[0]) {
+ idcode= groupname_to_code(filelist->dir);
+ if(idcode==0) filelist->dir[0]= 0;
+ }
+
+ if( filelist->dir[0]==0) {
+
+ /* make directories */
+ filelist->numfiles= 23;
+ filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
+
+ for(a=0; a<filelist->numfiles; a++) {
+ memset( &(filelist->filelist[a]), 0 , sizeof(struct direntry));
+ filelist->filelist[a].type |= S_IFDIR;
+ }
+
+ filelist->filelist[0].relname= BLI_strdup("..");
+ filelist->filelist[2].relname= BLI_strdup("Scene");
+ filelist->filelist[3].relname= BLI_strdup("Object");
+ filelist->filelist[4].relname= BLI_strdup("Mesh");
+ filelist->filelist[5].relname= BLI_strdup("Curve");
+ filelist->filelist[6].relname= BLI_strdup("Metaball");
+ filelist->filelist[7].relname= BLI_strdup("Material");
+ filelist->filelist[8].relname= BLI_strdup("Texture");
+ filelist->filelist[9].relname= BLI_strdup("Image");
+ filelist->filelist[10].relname= BLI_strdup("Ika");
+ filelist->filelist[11].relname= BLI_strdup("Wave");
+ filelist->filelist[12].relname= BLI_strdup("Lattice");
+ filelist->filelist[13].relname= BLI_strdup("Lamp");
+ filelist->filelist[14].relname= BLI_strdup("Camera");
+ filelist->filelist[15].relname= BLI_strdup("Ipo");
+ filelist->filelist[16].relname= BLI_strdup("World");
+ filelist->filelist[17].relname= BLI_strdup("Screen");
+ filelist->filelist[18].relname= BLI_strdup("VFont");
+ filelist->filelist[19].relname= BLI_strdup("Text");
+ filelist->filelist[20].relname= BLI_strdup("Armature");
+ filelist->filelist[21].relname= BLI_strdup("Action");
+ filelist->filelist[22].relname= BLI_strdup("NodeTree");
+ filelist_sort(filelist, FILE_SORT_ALPHA);
+ }
+ else {
+
+ /* make files */
+ idcode= groupname_to_code(filelist->dir);
+
+ lb= wich_libbase(G.main, idcode );
+ if(lb==0) return;
+
+ id= lb->first;
+ filelist->numfiles= 0;
+ while(id) {
+ if (!filelist->hide_dot || id->name[2] != '.') {
+ filelist->numfiles++;
+ }
+
+ id= id->next;
+ }
+
+ /* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */
+ if (!filelist->hide_parent) filelist->numfiles+= 1;
+ filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
+
+ files = filelist->filelist;
+
+ if (!filelist->hide_parent) {
+ memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry));
+ filelist->filelist[0].relname= BLI_strdup("..");
+ filelist->filelist[0].type |= S_IFDIR;
+
+ files++;
+ }
+
+ id= lb->first;
+ totlib= totbl= 0;
+
+ while(id) {
+ ok = 1;
+ if(ok) {
+ if (!filelist->hide_dot || id->name[2] != '.') {
+ memset( files, 0 , sizeof(struct direntry));
+ if(id->lib==NULL)
+ files->relname= BLI_strdup(id->name+2);
+ else {
+ files->relname= MEM_mallocN(FILE_MAXDIR+FILE_MAXFILE+32, "filename for lib");
+ sprintf(files->relname, "%s | %s", id->lib->name, id->name+2);
+ }
+ /* files->type |= S_IFDIR; */
+#if 0 // XXXXX TODO show the selection status of the objects
+ if(!filelist->has_func) { /* F4 DATA BROWSE */
+ if(idcode==ID_OB) {
+ if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE;
+ }
+ else if(idcode==ID_SCE) {
+ if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE;
+ }
+ }
+#endif
+ files->nr= totbl+1;
+ files->poin= id;
+ fake= id->flag & LIB_FAKEUSER;
+ if(idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
+ files->flags |= IMAGEFILE;
+ }
+ if(id->lib && fake) sprintf(files->extra, "LF %d", id->us);
+ else if(id->lib) sprintf(files->extra, "L %d", id->us);
+ else if(fake) sprintf(files->extra, "F %d", id->us);
+ else sprintf(files->extra, " %d", id->us);
+
+ if(id->lib) {
+ if(totlib==0) firstlib= files;
+ totlib++;
+ }
+
+ files++;
+ }
+ totbl++;
+ }
+
+ id= id->next;
+ }
+
+ /* only qsort of library blocks */
+ if(totlib>1) {
+ qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
+ }
+ }
+ filelist->filter = 0;
+ filelist_filter(filelist);
+}
+
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index dd3c2c766c1..a8d909f899e 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -42,12 +42,13 @@ struct FolderList;
struct direntry;
struct BlendHandle;
struct Scene;
+struct Main;
struct rcti;
+struct ReportList;
-struct FileList * filelist_new();
+struct FileList * filelist_new(short type);
void filelist_init_icons();
void filelist_free_icons();
-struct FileList * filelist_copy(struct FileList* filelist);
int filelist_find(struct FileList* filelist, char *file);
void filelist_free(struct FileList* filelist);
void filelist_sort(struct FileList* filelist, short sort);
@@ -71,6 +72,13 @@ int filelist_empty(struct FileList* filelist);
void filelist_parent(struct FileList* filelist);
void filelist_setfiletypes(struct FileList* filelist, short has_quicktime);
+
+int filelist_islibrary (struct FileList* filelist, char* dir, char* group);
+void filelist_from_main(struct FileList* filelist);
+void filelist_from_library(struct FileList* filelist);
+void filelist_freelib(struct FileList* filelist);
+void filelist_hideparent(struct FileList* filelist, short hide);
+
struct ListBase * folderlist_new();
void folderlist_free(struct ListBase* folderlist);
void folderlist_popdir(struct ListBase* folderlist, char *dir);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index f300505933f..1f461f1bbd5 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -123,6 +123,22 @@ short ED_fileselect_set_params(SpaceFile *sfile)
/* set the parameters from the operator, if it exists */
if (op) {
BLI_strncpy(params->title, op->type->name, sizeof(params->title));
+
+ params->type = RNA_int_get(op->ptr, "filemode");
+
+ if (RNA_property_is_set(op->ptr, "path")) {
+ RNA_string_get(op->ptr, "path", name);
+ if (params->type == FILE_LOADLIB) {
+ BLI_strncpy(params->dir, name, sizeof(params->dir));
+ BLI_cleanup_dir(G.sce, params->dir);
+ } else {
+ /* if operator has path set, use it, otherwise keep the last */
+ BLI_convertstringcode(name, G.sce);
+ BLI_split_dirfile(name, dir, file);
+ BLI_strncpy(params->file, file, sizeof(params->file));
+ BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */
+ }
+ }
params->filter = 0;
params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0;
params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0;
@@ -137,36 +153,33 @@ short ED_fileselect_set_params(SpaceFile *sfile)
params->flag |= FILE_FILTER;
params->flag |= FILE_HIDE_DOT;
-
+
+ if (params->type == FILE_LOADLIB) {
+ params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0;
+ params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0;
+ params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0;
+ }
+
if(params->filter & (IMAGEFILE|MOVIEFILE))
params->display= FILE_IMGDISPLAY;
else
params->display= FILE_SHORTDISPLAY;
- /* if operator has path set, use it, otherwise keep the last */
- if (RNA_property_is_set(op->ptr, "filename")) {
- RNA_string_get(op->ptr, "filename", name);
- BLI_convertstringcode(name, G.sce);
- BLI_split_dirfile(name, dir, file);
- BLI_strncpy(params->file, file, sizeof(params->file));
- BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */
- }
} else {
/* default values, if no operator */
+ params->type = FILE_UNIX;
params->flag |= FILE_HIDE_DOT;
params->display = FILE_SHORTDISPLAY;
params->filter = 0;
params->sort = FILE_SORT_ALPHA;
}
- /* new params, refresh file list */
- if(sfile->files) filelist_free(sfile->files);
-
return 1;
}
void ED_fileselect_reset_params(SpaceFile *sfile)
{
+ sfile->params->type = FILE_UNIX;
sfile->params->flag = 0;
sfile->params->title[0] = '\0';
}
@@ -176,14 +189,14 @@ int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar)
int numfiles;
if (layout->flag & FILE_LAYOUT_HOR) {
- short width = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*layout->tile_border_x;
+ int width = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*layout->tile_border_x;
numfiles = width/layout->tile_w + 1;
+ return numfiles*layout->rows;
} else {
- short height = ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*layout->tile_border_y;
+ int height = ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*layout->tile_border_y;
numfiles = height/layout->tile_h + 1;
+ return numfiles*layout->columns;
}
-
- return layout->columns*layout->rows;
}
int ED_fileselect_layout_offset(FileLayout* layout, int x, int y)
@@ -207,7 +220,7 @@ int ED_fileselect_layout_offset(FileLayout* layout, int x, int y)
return active_file;
}
-void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y)
+void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, int *x, int *y)
{
if (layout->flag == FILE_LAYOUT_HOR) {
*x = layout->tile_border_x + (tile/layout->rows)*(layout->tile_w+2*layout->tile_border_x);
@@ -250,7 +263,7 @@ static void column_widths(struct FileList* files, struct FileLayout* layout)
if (file) {
int len;
len = file_string_width(file->relname);
- if (len > layout->column_widths[COLUMN_NAME]) layout->column_widths[COLUMN_NAME] = len;
+ if (len > layout->column_widths[COLUMN_NAME]) layout->column_widths[COLUMN_NAME] = len + 20;
len = file_string_width(file->date);
if (len > layout->column_widths[COLUMN_DATE]) layout->column_widths[COLUMN_DATE] = len;
len = file_string_width(file->time);
@@ -322,18 +335,23 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar)
column_widths(sfile->files, layout);
if (params->display == FILE_SHORTDISPLAY) {
- maxlen = layout->column_widths[COLUMN_NAME] +
+ maxlen = layout->column_widths[COLUMN_NAME] + 12 +
layout->column_widths[COLUMN_SIZE];
- maxlen += 20+2*10; // for icon and space between columns
+ maxlen += 20; // for icon
} else {
- maxlen = layout->column_widths[COLUMN_NAME] +
- layout->column_widths[COLUMN_DATE] +
- layout->column_widths[COLUMN_TIME] +
+ maxlen = layout->column_widths[COLUMN_NAME] + 12 +
+#ifndef WIN32
+ layout->column_widths[COLUMN_MODE1] + 12 +
+ layout->column_widths[COLUMN_MODE2] + 12 +
+ layout->column_widths[COLUMN_MODE3] + 12 +
+ layout->column_widths[COLUMN_OWNER] + 12 +
+#endif
+ layout->column_widths[COLUMN_DATE] + 12 +
+ layout->column_widths[COLUMN_TIME] + 12 +
layout->column_widths[COLUMN_SIZE];
- /* XXX add mode1, mode2, mode3, owner columns for non-windows platforms */
- maxlen += 20+4*10; // for icon and space between columns
+ maxlen += 20; // for icon
}
- layout->tile_w = maxlen + 40;
+ layout->tile_w = maxlen;
if(layout->rows > 0)
layout->columns = numfiles/layout->rows + 1; // XXX dirty, modulo is zero
else {
@@ -357,19 +375,15 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar
void file_change_dir(struct SpaceFile *sfile)
{
if (sfile->params) {
- if (BLI_exists(sfile->params->dir)) {
- filelist_setdir(sfile->files, sfile->params->dir);
+ filelist_setdir(sfile->files, sfile->params->dir);
- if(folderlist_clear_next(sfile))
- folderlist_free(sfile->folders_next);
+ if(folderlist_clear_next(sfile))
+ folderlist_free(sfile->folders_next);
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
- filelist_free(sfile->files);
- sfile->params->active_file = -1;
- } else {
- BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX);
- }
+ filelist_free(sfile->files);
+ sfile->params->active_file = -1;
}
}
@@ -408,13 +422,16 @@ void autocomplete_directory(struct bContext *C, char *str, void *arg_v)
struct direntry* file = filelist_file(sfile->files, i);
const char* dir = filelist_dir(sfile->files);
if (file && S_ISDIR(file->type)) {
- BLI_make_file_string(G.sce, tmp, dir, file->relname);
+ // BLI_make_file_string(G.sce, tmp, dir, file->relname);
+ BLI_join_dirfile(tmp, dir, file->relname);
autocomplete_do_name(autocpl,tmp);
}
}
autocomplete_end(autocpl, str);
if (BLI_exists(str)) {
BLI_add_slash(str);
+ } else {
+ BLI_make_exist(str);
}
}
}
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 722fa475727..77f50d91e77 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -45,6 +45,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_rand.h"
+#include "BLI_storage_types.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -119,6 +120,7 @@ static void file_free(SpaceLink *sl)
SpaceFile *sfile= (SpaceFile *) sl;
if(sfile->files) {
+ filelist_freelib(sfile->files);
filelist_free(sfile->files);
MEM_freeN(sfile->files);
sfile->files= NULL;
@@ -153,7 +155,10 @@ static void file_free(SpaceLink *sl)
/* spacetype; init callback, area size changes, screen set, etc */
static void file_init(struct wmWindowManager *wm, ScrArea *sa)
{
+ SpaceFile *sfile= (SpaceFile*)sa->spacedata.first;
printf("file_init\n");
+
+ if(sfile->layout) sfile->layout->dirty= 1;
}
@@ -165,7 +170,8 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */
sfilen->op = NULL; /* file window doesn't own operators */
- sfilen->files = filelist_new();
+ if (sfileo->params)
+ sfilen->files = filelist_new(sfileo->params->type);
if(sfileo->folders_prev)
sfilen->folders_prev = MEM_dupallocN(sfileo->folders_prev);
@@ -190,7 +196,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
if (!sfile->folders_prev)
sfile->folders_prev = folderlist_new();
if (!sfile->files) {
- sfile->files = filelist_new();
+ sfile->files = filelist_new(params->type);
file_change_dir(sfile);
params->active_file = -1; // added this so it opens nicer (ton)
}
@@ -199,9 +205,20 @@ static void file_refresh(const bContext *C, ScrArea *sa)
if (filelist_empty(sfile->files))
{
filelist_readdir(sfile->files);
+ BLI_strncpy(params->dir, filelist_dir(sfile->files), FILE_MAX);
}
if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort);
-
+
+ if (params->renamefile[0] != '\0') {
+ int idx = filelist_find(sfile->files, params->renamefile);
+ if (idx >= 0) {
+ struct direntry *file= filelist_file(sfile->files, idx);
+ if (file) {
+ file->flags |= EDITING;
+ }
+ }
+ params->renamefile[0] = '\0';
+ }
if (sfile->layout) sfile->layout->dirty= 1;
}
@@ -231,15 +248,15 @@ static void file_listener(ScrArea *sa, wmNotifier *wmn)
/* add handlers, stuff you only do once or on area/region changes */
static void file_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymaps */
- keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
+ keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap= WM_keymap_listbase(wm, "FileMain", SPACE_FILE, 0);
+ keymap= WM_keymap_find(wm, "FileMain", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -351,7 +368,7 @@ void file_keymap(struct wmWindowManager *wm)
{
wmKeymapItem *kmi;
/* keys for all areas */
- ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0);
WM_keymap_add_item(keymap, "FILE_OT_bookmark_toggle", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_add_bookmark", BKEY, KM_PRESS, KM_CTRL, 0);
@@ -360,9 +377,10 @@ void file_keymap(struct wmWindowManager *wm)
WM_keymap_add_item(keymap, "FILE_OT_next", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "FILE_OT_directory_new", IKEY, KM_PRESS, 0, 0); /* XXX needs button */
WM_keymap_add_item(keymap, "FILE_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "FILE_OT_delete", DELKEY, KM_PRESS, 0, 0);
/* keys for main area */
- keymap= WM_keymap_listbase(wm, "FileMain", SPACE_FILE, 0);
+ keymap= WM_keymap_find(wm, "FileMain", SPACE_FILE, 0);
WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0);
@@ -383,7 +401,7 @@ void file_keymap(struct wmWindowManager *wm)
RNA_int_set(kmi->ptr, "increment",-100);
/* keys for button area (top) */
- keymap= WM_keymap_listbase(wm, "FileButtons", SPACE_FILE, 0);
+ keymap= WM_keymap_find(wm, "FileButtons", SPACE_FILE, 0);
WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
RNA_int_set(kmi->ptr, "increment", 1);
@@ -402,12 +420,12 @@ void file_keymap(struct wmWindowManager *wm)
static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
/* own keymaps */
- keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
+ keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -438,15 +456,15 @@ static void file_header_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void file_ui_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap= WM_keymap_listbase(wm, "FileButtons", SPACE_FILE, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "FileButtons", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_file/writeimage.c b/source/blender/editors/space_file/writeimage.c
index 994f38320f2..045c790b9cd 100644
--- a/source/blender/editors/space_file/writeimage.c
+++ b/source/blender/editors/space_file/writeimage.c
@@ -115,15 +115,18 @@ static void save_rendered_image_cb_real(char *name, int confirm)
if(overwrite) {
if(scene->r.imtype==R_MULTILAYER) {
- RenderResult *rr= RE_GetResult(RE_GetRender(scene->id.name));
+ Render *re= RE_GetRender(scene->id.name);
+ RenderResult *rr= RE_AcquireResultRead(re);
if(rr)
RE_WriteRenderResult(rr, str, scene->r.quality);
+ RE_ReleaseResult(re);
}
else {
+ Render *re= RE_GetRender(scene->id.name);
RenderResult rres;
ImBuf *ibuf;
- RE_GetResultImage(RE_GetRender(scene->id.name), &rres);
+ RE_AcquireResultImage(re, &rres);
waitcursor(1); /* from screen.c */
@@ -137,6 +140,8 @@ static void save_rendered_image_cb_real(char *name, int confirm)
BKE_write_ibuf(scene, ibuf, str, scene->r.imtype, scene->r.subimtype, scene->r.quality);
IMB_freeImBuf(ibuf); /* imbuf knows rects are not part of ibuf */
+
+ RE_ReleaseResultImage(re);
}
strcpy(G.ima, name);
@@ -231,9 +236,10 @@ void BIF_save_rendered_image(char *name)
/* calls fileselect */
void BIF_save_rendered_image_fs(Scene *scene)
{
+ Render *re= RE_GetRender(scene->id.name);
RenderResult rres;
- RE_GetResultImage(RE_GetRender(scene->id.name), &rres);
+ RE_AcquireResultImage(re, &rres);
if(!rres.rectf && !rres.rect32) {
error("No image rendered");
@@ -250,6 +256,8 @@ void BIF_save_rendered_image_fs(Scene *scene)
save_image_filesel_str(scene, str);
activate_fileselect(FILE_SPECIAL, str, G.ima, save_rendered_image_cb);
}
+
+ RE_ReleaseResultImage(re);
}
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index fb995285ab7..09008f8d2d1 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -46,15 +46,16 @@
#include "BLI_editVert.h"
#include "BLI_rand.h"
-#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_object.h"
-#include "BKE_global.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
@@ -250,6 +251,22 @@ static int graph_panel_drivers_poll(const bContext *C, PanelType *pt)
return graph_panel_context(C, NULL, NULL);
}
+static void test_obpoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ id= CTX_data_main(C)->object.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ id_lib_extern(id); /* checks lib data, sets correct flag for saving then */
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
/* driver settings for active F-Curve (only for 'Drivers' mode) */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
@@ -427,13 +444,9 @@ static int graph_properties(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= graph_has_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 9ae7e8263ee..57e2208f089 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -91,6 +91,26 @@
extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
/* *************************** */
+/* Utility Drawing Defines */
+
+/* determine the alpha value that should be used when
+ * drawing components for some F-Curve (fcu)
+ * - selected F-Curves should be more visible than partially visible ones
+ */
+#define drawFCurveFade(fcu) ( ((fcu)->flag & FCURVE_SELECTED)? 1.0f : 0.5f )
+
+/* set the colour for some point from some value given packed into an int
+ * - intV: integer value containing color info packed into an int
+ * - alpha: float value describing the
+ */
+#define cpackA(intVC, alpha) \
+ { \
+ float _cpackCol[3]; \
+ cpack_to_rgb(intVC, &_cpackCol[0], &_cpackCol[1], &_cpackCol[2]); \
+ glColor4f(_cpackCol[0], _cpackCol[1], _cpackCol[2], alpha); \
+ }
+
+/* *************************** */
/* F-Curve Modifier Drawing */
/* Envelope -------------- */
@@ -258,22 +278,20 @@ static void draw_fcurve_vertices_handles (FCurve *fcu, View2D *v2d, short sel)
/* helper func - set color to draw F-Curve data with */
static void set_fcurve_vertex_color (SpaceIpo *sipo, FCurve *fcu, short sel)
{
-#if 0
- if (sipo->showkey) {
- if (sel) UI_ThemeColor(TH_TEXT_HI);
- else UI_ThemeColor(TH_TEXT);
- }
-#endif
- if ((fcu->flag & FCURVE_PROTECTED)==0) {
- /* Curve's points are being edited */
- if (sel) UI_ThemeColor(TH_VERTEX_SELECT);
- else UI_ThemeColor(TH_VERTEX);
- }
- else {
- /* Curve's points cannot be edited */
- if (sel) UI_ThemeColor(TH_TEXT_HI);
- else UI_ThemeColor(TH_TEXT);
- }
+ /* Fade the 'intensity' of the vertices based on the selection of the curves too */
+ int alphaOffset= (int)((drawFCurveFade(fcu) - 1.0f) * 255);
+
+ /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
+ if ((fcu->flag & FCURVE_PROTECTED)==0) {
+ /* Curve's points ARE BEING edited */
+ if (sel) UI_ThemeColorShadeAlpha(TH_VERTEX_SELECT, 0, alphaOffset);
+ else UI_ThemeColorShadeAlpha(TH_VERTEX, 0, alphaOffset);
+ }
+ else {
+ /* Curve's points CANNOT BE edited */
+ if (sel) UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, alphaOffset);
+ else UI_ThemeColorShadeAlpha(TH_TEXT, 0, alphaOffset);
+ }
}
@@ -322,7 +340,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
if ((sipo->flag & SIPO_NOHANDLES) || (fcu->flag & FCURVE_PROTECTED) || (fcu->flag & FCURVE_INT_VALUES))
return;
- /* slightly hacky, but we want to draw unselected points before selected ones*/
+ /* slightly hacky, but we want to draw unselected points before selected ones */
for (sel= 0; sel < 2; sel++) {
BezTriple *bezt=fcu->bezt, *prevbezt=NULL;
float *fp;
@@ -337,7 +355,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* only draw first handle if previous segment had handles */
if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) )
{
- cpack(col[(unsigned char)bezt->h1]);
+ cpackA(col[(unsigned char)bezt->h1], drawFCurveFade(fcu));
glBegin(GL_LINE_STRIP);
glVertex2fv(fp); glVertex2fv(fp+3);
glEnd();
@@ -347,7 +365,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* only draw second handle if this segment is bezier */
if (bezt->ipo == BEZT_IPO_BEZ)
{
- cpack(col[(unsigned char)bezt->h2]);
+ cpackA(col[(unsigned char)bezt->h2], drawFCurveFade(fcu));
glBegin(GL_LINE_STRIP);
glVertex2fv(fp+3); glVertex2fv(fp+6);
glEnd();
@@ -359,7 +377,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) )
{
fp= bezt->vec[0];
- cpack(col[(unsigned char)bezt->h1]);
+ cpackA(col[(unsigned char)bezt->h1], drawFCurveFade(fcu));
glBegin(GL_LINE_STRIP);
glVertex2fv(fp); glVertex2fv(fp+3);
@@ -371,7 +389,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
(bezt->ipo == BEZT_IPO_BEZ) )
{
fp= bezt->vec[1];
- cpack(col[(unsigned char)bezt->h2]);
+ cpackA(col[(unsigned char)bezt->h2], drawFCurveFade(fcu));
glBegin(GL_LINE_STRIP);
glVertex2fv(fp); glVertex2fv(fp+3);
@@ -410,7 +428,6 @@ static void draw_fcurve_sample_control (float x, float y, float xscale, float ys
glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f);
/* anti-aliased lines for more consistent appearance */
- // XXX needed here?
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
@@ -506,7 +523,6 @@ static void draw_fcurve_curve (FCurve *fcu, SpaceIpo *sipo, View2D *v2d, View2DG
}
/* helper func - draw a samples-based F-Curve */
-// TODO: add offset stuff...
static void draw_fcurve_curve_samples (FCurve *fcu, View2D *v2d)
{
FPoint *prevfpt= fcu->fpt;
@@ -647,7 +663,7 @@ static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid)
*/
/* resol not depending on horizontal resolution anymore, drivers for example... */
- // XXX need to take into account the scale
+ // TODO: would be nice to make this depend on the scale of the graph too...
if (fcu->driver)
resol= 32;
else
@@ -809,7 +825,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
/* set whatever color the curve has set
* - unselected curves draw less opaque to help distinguish the selected ones
*/
- glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], ((sel) ? 1.0f : 0.5f));
+ glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], drawFCurveFade(fcu));
}
/* anti-aliased lines for less jagged appearance */
@@ -855,7 +871,10 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
if (fcu->bezt) {
/* only draw handles/vertices on keyframes */
- draw_fcurve_handles(sipo, ar, fcu);
+ glEnable(GL_BLEND);
+ draw_fcurve_handles(sipo, ar, fcu);
+ glDisable(GL_BLEND);
+
draw_fcurve_vertices(sipo, ar, fcu);
}
else {
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index d718ef28e99..3e0f9760773 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1296,8 +1296,7 @@ void GRAPH_OT_handle_type (wmOperatorType *ot)
/* set of three euler-rotation F-Curves */
typedef struct tEulerFilter {
ID *id; /* ID-block which owns the channels */
- FCurve *fcu1, *fcu2, *fcu3; /* x,y,z rotation curves */
- int i1, i2, i3; /* current index for each curve */
+ FCurve (*fcurves)[3]; /* 3 Pointers to F-Curves */
} tEulerFilter;
static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
@@ -1336,7 +1335,7 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
if (ELEM(0, fcu->rna_path, strstr(fcu->rna_path, "rotation")))
continue;
if (strstr(fcu->rna_path, "pose.pose_channels")) {
- if (strstr(fcu->rna_path, "euler_rotation") == 0)
+ if (strstr(fcu->rna_path, "rotation_euler") == 0)
continue;
}
@@ -1345,12 +1344,30 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
* - first check if id-blocks are compatible
*/
if ((euf) && (ale->id != euf->id)) {
+ /* if the paths match, add this curve to the set of curves */
+ // NOTE: simple string compare for now... could be a bit more fancy...
}
+ else {
+ /* just add to a new block */
+ euf= MEM_callocN(sizeof(tEulerFilter), "tEulerFilter");
+ BLI_addtail(&eulers, euf);
+
+ euf->id= ale->id;
+ euf->fcurves[fcu->array_index]= fcu;
+ }
}
+ BLI_freelistN(&anim_data);
- // XXX for now
- return OPERATOR_CANCELLED;
+ /* step 2: go through each set of curves, processing the values at each keyframe
+ * - it is assumed that there must be a full set of keyframes at each keyframe position
+ */
+ for (euf= eulers.first; euf; euf= euf->next) {
+
+ }
+ BLI_freelistN(&eulers);
+
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_euler_filter (wmOperatorType *ot)
@@ -1710,13 +1727,18 @@ static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *eve
/* start from 1 to skip the 'Invalid' modifier type */
for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
FModifierTypeInfo *fmi= get_fmodifier_typeinfo(i);
+ PointerRNA props_ptr;
/* check if modifier is valid for this context */
if (fmi == NULL)
continue;
- /* add entry to add this type of modifier */
- uiItemEnumO(layout, fmi->name, 0, "GRAPH_OT_fmodifier_add", "type", i);
+ /* create operator menu item with relevant properties filled in */
+ props_ptr= uiItemFullO(layout, fmi->name, 0, "GRAPH_OT_fmodifier_add", NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
+ /* the only thing that gets set from the menu is the type of F-Modifier to add */
+ RNA_enum_set(&props_ptr, "type", i);
+ /* the following properties are just repeats of existing ones... */
+ RNA_boolean_set(&props_ptr, "only_active", RNA_boolean_get(op->ptr, "only_active"));
}
uiItemS(layout);
@@ -1728,36 +1750,41 @@ static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *eve
static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
- FCurve *fcu;
- FModifier *fcm;
+ int filter;
short type;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
- // xxx call the raw methods here instead?
- ale= get_active_fcurve_channel(&ac);
- if (ale == NULL)
- return OPERATOR_CANCELLED;
- fcu= (FCurve *)ale->data;
- MEM_freeN(ale);
- if (fcu == NULL)
- return OPERATOR_CANCELLED;
-
/* get type of modifier to add */
type= RNA_enum_get(op->ptr, "type");
- /* add F-Modifier of specified type to active F-Curve, and make it the active one */
- fcm= add_fmodifier(&fcu->modifiers, type);
- if (fcm)
- set_active_fmodifier(&fcu->modifiers, fcm);
- else {
- BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details.");
- return OPERATOR_CANCELLED;
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ if (RNA_boolean_get(op->ptr, "only_active"))
+ filter |= ANIMFILTER_ACTIVE;
+ else
+ filter |= ANIMFILTER_SEL;
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* smooth keyframes */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu= (FCurve *)ale->data;
+ FModifier *fcm;
+
+ /* add F-Modifier of specified type to active F-Curve, and make it the active one */
+ fcm= add_fmodifier(&fcu->modifiers, type);
+ if (fcm)
+ set_active_fmodifier(&fcu->modifiers, fcm);
+ else { // TODO: stop when this happens?
+ BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details.");
+ break;
+ }
}
+ BLI_freelistN(&anim_data);
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
@@ -1779,13 +1806,14 @@ void GRAPH_OT_fmodifier_add (wmOperatorType *ot)
/* api callbacks */
ot->invoke= graph_fmodifier_add_invoke;
ot->exec= graph_fmodifier_add_exec;
- ot->poll= graphop_active_fcurve_poll;
+ ot->poll= graphop_selected_fcurve_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* id-props */
RNA_def_enum(ot->srna, "type", fmodifier_type_items, 0, "Type", "");
+ RNA_def_boolean(ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve.");
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c
index dd304cd8cf3..98d58c92da4 100644
--- a/source/blender/editors/space_graph/graph_header.c
+++ b/source/blender/editors/space_graph/graph_header.c
@@ -298,29 +298,7 @@ void graph_header_buttons(const bContext *C, ARegion *ar)
xco+= 120;
/* filtering buttons */
- if (sipo->ads) {
- //uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Only display selected Objects");
- //uiBlockEndAlign(block);
- xco += 5;
-
- uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Scene Animation");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display World Animation");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Materials");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Lamps");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Cameras");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Curves");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display MetaBalls");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Particles");
- uiBlockEndAlign(block);
- xco += 30;
- }
- else {
- // XXX this case shouldn't happen at all... for now, just pad out same amount of space
- xco += 10*XIC + 30;
- }
+ xco= ANIM_headerUI_standard_buttons(C, sipo->ads, block, xco, yco);
/* auto-snap selector */
if (sipo->flag & SIPO_DRAWTIME) {
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 2e8d0655d2d..83a565e485f 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -155,6 +155,7 @@ short fcurve_needs_draw_fmodifier_controls(struct FCurve *fcu, struct FModifier
int graphop_visible_keyframes_poll(struct bContext *C);
int graphop_editable_keyframes_poll(struct bContext *C);
int graphop_active_fcurve_poll(struct bContext *C);
+int graphop_selected_fcurve_poll(struct bContext *C);
/* ***************************************** */
/* graph_ops.c */
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index fc4c05915c9..b82055064f8 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -141,7 +141,7 @@ void graphedit_operatortypes(void)
/* ************************** registration - keymaps **********************************/
-static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
+static void graphedit_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap)
{
wmKeymapItem *kmi;
@@ -221,7 +221,7 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
/* F-Modifiers */
- WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "only_active", 0);
/* transform system */
@@ -232,10 +232,10 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
void graphedit_keymap(wmWindowManager *wm)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
/* keymap for all regions */
- keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0);
+ keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_properties", NKEY, KM_PRESS, 0, 0);
/* channels */
@@ -245,7 +245,7 @@ void graphedit_keymap(wmWindowManager *wm)
*/
/* keyframes */
- keymap= WM_keymap_listbase(wm, "GraphEdit Keys", SPACE_IPO, 0);
+ keymap= WM_keymap_find(wm, "GraphEdit Keys", SPACE_IPO, 0);
graphedit_keymap_keyframes(wm, keymap);
}
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 728c9310a47..7eec9f31d86 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -142,9 +142,13 @@ static void deselect_graph_keys (bAnimContext *ac, short test, short sel)
/* Keyframes First */
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, sel_cb, NULL);
- /* deactivate the F-Curve, and deselect if deselecting keyframes */
+ /* deactivate the F-Curve, and deselect if deselecting keyframes.
+ * otherwise select the F-Curve too since we've selected all the keyframes
+ */
if (sel == SELECT_SUBTRACT)
fcu->flag &= ~FCURVE_SELECTED;
+ else
+ fcu->flag |= FCURVE_SELECTED;
fcu->flag &= ~FCURVE_ACTIVE;
}
@@ -259,8 +263,9 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho
/* select the curve too
* NOTE: this should really only happen if the curve got touched...
*/
- if (selectmode == SELECT_ADD)
+ if (selectmode == SELECT_ADD) {
fcu->flag |= FCURVE_SELECTED;
+ }
}
/* cleanup */
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index f00e7845549..25087441b6a 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -285,4 +285,33 @@ int graphop_active_fcurve_poll (bContext *C)
return has_fcurve;
}
+/* has selected F-Curve that's editable */
+int graphop_selected_fcurve_poll (bContext *C)
+{
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ ScrArea *sa= CTX_wm_area(C);
+ int filter, items;
+ short found = 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* get the editable + selected F-Curves, and as long as we got some, we can return */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ if (items == 0)
+ return 0;
+
+ /* cleanup and return findings */
+ BLI_freelistN(&anim_data);
+ return found;
+}
+
/* ************************************************************** */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 8887d464f30..a7ea2294ed4 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -203,14 +203,14 @@ static SpaceLink *graph_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void graph_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "GraphEdit Keys", SPACE_IPO, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "GraphEdit Keys", SPACE_IPO, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0);
+ keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -281,14 +281,14 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Animation_Channels", 0, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Animation_Channels", 0, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0);
+ keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -352,11 +352,11 @@ static void graph_header_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0);
+ keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -374,6 +374,7 @@ static void graph_region_listener(ARegion *ar, wmNotifier *wmn)
break;
case NC_SCENE:
switch(wmn->data) {
+ case ND_RENDER_OPTIONS:
case ND_OB_ACTIVE:
case ND_FRAME:
case ND_MARKERS:
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 21fccdc65f8..67fb95b1f6b 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -100,8 +100,6 @@
#define B_FACESEL_PAINT_TEST 11
#define B_SIMA_RECORD 12
#define B_SIMA_PLAY 13
-#define B_SIMARANGE 14
-#define B_SIMACURVES 15
#define B_SIMANOTHING 16
#define B_SIMABRUSHCHANGE 17
@@ -116,10 +114,8 @@
#define B_SIMACLONEDELETE 26
/* XXX */
-static int okee() {return 0;}
static int simaFaceDraw_Check() {return 0;}
static int simaUVSel_Check() {return 0;}
-static int is_uv_tface_editing_allowed_silent() {return 0;}
/* XXX */
/* proto */
@@ -135,13 +131,6 @@ static void do_image_panel_events(bContext *C, void *arg, int event)
switch(event) {
case B_REDR:
break;
- case B_SIMACURVES:
- curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima));
- break;
- case B_SIMARANGE:
- curvemapping_set_black_white(sima->cumap, NULL, NULL);
- curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima));
- break;
case B_TRANS_IMAGE:
image_editvertex_buts(C, NULL);
break;
@@ -149,12 +138,11 @@ static void do_image_panel_events(bContext *C, void *arg, int event)
image_editcursor_buts(C, &ar->v2d, NULL);
break;
}
+
/* all events now */
WM_event_add_notifier(C, NC_IMAGE, sima->image);
}
-
-
static void image_info(Image *ima, ImBuf *ibuf, char *str)
{
int ofs= 0;
@@ -168,12 +156,12 @@ static void image_info(Image *ima, ImBuf *ibuf, char *str)
}
if(ima->source==IMA_SRC_MOVIE) {
- ofs= sprintf(str, "Movie ");
+ ofs= sprintf(str, "Movie");
if(ima->anim)
ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim));
}
else
- ofs= sprintf(str, "Image ");
+ ofs= sprintf(str, "Image");
ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y);
@@ -216,11 +204,7 @@ struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
/* this function gets the values for cursor and vertex number buttons */
static void image_transform_but_attr(SpaceImage *sima, int *imx, int *imy, int *step, int *digits) /*, float *xcoord, float *ycoord)*/
{
- ImBuf *ibuf= ED_space_image_buffer(sima);
- if(ibuf) {
- *imx= ibuf->x;
- *imy= ibuf->y;
- }
+ ED_space_image_size(sima, imx, imy);
if (sima->flag & SI_COORDFLOATS) {
*step= 1;
@@ -246,10 +230,6 @@ static void image_editvertex_buts(const bContext *C, uiBlock *block)
EditFace *efa;
MTFace *tf;
- if(obedit==NULL || obedit->type!=OB_MESH) return;
-
- if( is_uv_tface_editing_allowed_silent()==0 ) return;
-
image_transform_but_attr(sima, &imx, &imy, &step, &digits);
em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -354,8 +334,6 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block
int imx= 256, imy= 256;
int step, digits;
- if( is_uv_tface_editing_allowed_silent()==0 ) return;
-
image_transform_but_attr(sima, &imx, &imy, &step, &digits);
if(block) { // do the buttons
@@ -388,59 +366,6 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block
#if 0
static void image_panel_view_properties(const bContext *C, Panel *pa)
{
- SpaceImage *sima= CTX_wm_space_image(C);
- ARegion *ar= CTX_wm_region(C);
- Object *obedit= CTX_data_edit_object(C);
- uiBlock *block;
-
- block= uiLayoutFreeBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_image_panel_events, NULL);
-
- uiDefButBitI(block, TOG, SI_DRAW_TILE, B_REDR, "Repeat Image", 10,160,140,19, &sima->flag, 0, 0, 0, 0, "Repeat/Tile the image display");
- uiDefButBitI(block, TOG, SI_COORDFLOATS, B_REDR, "Normalized Coords", 165,160,145,19, &sima->flag, 0, 0, 0, 0, "Display coords from 0.0 to 1.0 rather then in pixels");
-
- if (sima->image) {
- uiDefBut(block, LABEL, B_NOP, "Image Display:", 10,140,140,19, 0, 0, 0, 0, 0, "");
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_REDR, "AspX:", 10,120,140,19, &sima->image->aspx, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect renderingm 0 disables.");
- uiDefButF(block, NUM, B_REDR, "AspY:", 10,100,140,19, &sima->image->aspy, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect rendering 0 disables.");
- uiBlockEndAlign(block);
- }
-
- if (obedit && obedit->type==OB_MESH) {
- Mesh *me= obedit->data;
- EditMesh *em= BKE_mesh_get_editmesh(me);
-
- if(EM_texFaceCheck(em)) {
- uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 80,120,19, 0, 0, 0, 0, 0, "");
- uiBlockBeginAlign(block);
- uiDefButC(block, ROW, B_REDR, "Outline", 10,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype");
- uiDefButC(block, ROW, B_REDR, "Dash", 68, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype");
- uiDefButC(block, ROW, B_REDR, "Black", 126, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype");
- uiDefButC(block, ROW, B_REDR, "White", 184,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype");
-
- uiBlockEndAlign(block);
- uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,60,60,19, &sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view");
-
-
- uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades in the 3d view and UV editor");
- uiDefButBitI(block, TOG, ME_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor");
-
- uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers");
- uiDefButBitI(block, TOG, SI_DRAW_OTHER, B_REDR, "Other Objs", 230, 30, 80, 19, &sima->flag, 0, 0, 0, 0, "Also draw all 3d view selected mesh objects that use this image");
-
- uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)");
- if (sima->flag & SI_DRAW_STRETCH) {
- uiBlockBeginAlign(block);
- uiDefButC(block, ROW, B_REDR, "Area", 120,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_AREA, 0, 0, "Area distortion between UV's and 3D coords");
- uiDefButC(block, ROW, B_REDR, "Angle", 180,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_ANGLE, 0, 0, "Angle distortion between UV's and 3D coords");
- uiBlockEndAlign(block);
- }
- }
-
- BKE_mesh_end_editmesh(me, em);
- }
- image_editcursor_buts(C, &ar->v2d, block);
}
#endif
@@ -524,8 +449,8 @@ void brush_buttons(const bContext *C, uiBlock *block, short fromsima,
uiDefIconButBitS(block, TOG|BIT, BRUSH_ALPHA_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-20,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets");
uiDefButI(block, NUMSLI, evt_nop, "Size ", 0,yco-40,180,19, &brush->size, 1, 200, 0, 0, "The size of the brush");
uiDefIconButBitS(block, TOG|BIT, BRUSH_SIZE_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-40,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets");
- uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush");
- uiDefIconButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets");
+// uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush");
+// uiDefIconButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets");
uiDefButF(block, NUMSLI, evt_nop, "Spacing ",0,yco-80,180,19, &brush->spacing, 1.0, 100.0, 0, 0, "Repeating paint on %% of brush diameter");
uiDefIconButBitS(block, TOG|BIT, BRUSH_SPACING_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-80,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets");
uiBlockEndAlign(block);
@@ -565,105 +490,36 @@ void brush_buttons(const bContext *C, uiBlock *block, short fromsima,
#endif
}
-static int image_panel_paint_poll(const bContext *C, PanelType *pt)
+static int image_panel_poll(const bContext *C, PanelType *pt)
{
SpaceImage *sima= CTX_wm_space_image(C);
- return (sima->image && (sima->flag & SI_DRAWTOOL));
-}
-
-static void image_panel_paintcolor(const bContext *C, Panel *pa)
-{
- SpaceImage *sima= CTX_wm_space_image(C);
- ToolSettings *settings= CTX_data_tool_settings(C);
- Brush *brush= paint_brush(&settings->imapaint.paint);
- uiBlock *block;
- static float hsv[3], old[3]; // used as temp mem for picker
- static char hexcol[128];
-
- if(!sima->image || (sima->flag & SI_DRAWTOOL)==0)
- return;
-
- block= uiLayoutFreeBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_image_panel_events, NULL);
-
- if(brush)
- uiBlockPickerButtons(block, brush->rgb, hsv, old, hexcol, 'f', B_REDR);
+ return ED_space_image_has_buffer(sima);
}
-static void image_panel_paint(const bContext *C, Panel *pa)
-{
- SpaceImage *sima= CTX_wm_space_image(C);
- uiBlock *block;
-
- if(!sima->image || (sima->flag & SI_DRAWTOOL)==0)
- return;
-
- block= uiLayoutFreeBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_image_panel_events, NULL);
-
- brush_buttons(C, block, 1, B_SIMANOTHING, B_SIMABRUSHCHANGE, B_SIMABRUSHBROWSE, B_SIMABRUSHLOCAL, B_SIMABRUSHDELETE, B_KEEPDATA, B_SIMABTEXBROWSE, B_SIMABTEXDELETE);
-}
-
-static void image_panel_curves_reset(bContext *C, void *cumap_v, void *ibuf_v)
-{
- SpaceImage *sima= CTX_wm_space_image(C);
- CurveMapping *cumap = cumap_v;
- int a;
-
- for(a=0; a<CM_TOT; a++)
- curvemap_reset(cumap->cm+a, &cumap->clipr);
-
- cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f;
- cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f;
- curvemapping_set_black_white(cumap, NULL, NULL);
-
- curvemapping_changed(cumap, 0);
- curvemapping_do_ibuf(cumap, ibuf_v);
-
- WM_event_add_notifier(C, NC_IMAGE, sima->image);
-}
-
-
static void image_panel_curves(const bContext *C, Panel *pa)
{
+ bScreen *sc= CTX_wm_screen(C);
SpaceImage *sima= CTX_wm_space_image(C);
ImBuf *ibuf;
- uiBlock *block;
- uiBut *bt;
-
- /* and we check for spare */
- ibuf= ED_space_image_buffer(sima);
+ PointerRNA simaptr;
+ int levels;
+ void *lock;
- block= uiLayoutFreeBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_image_panel_events, NULL);
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
- if (ibuf) {
- rctf rect;
-
+ if(ibuf) {
if(sima->cumap==NULL)
sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
-
- rect.xmin= 110; rect.xmax= 310;
- rect.ymin= 10; rect.ymax= 200;
- curvemap_buttons(block, sima->cumap, 'c', B_SIMACURVES, B_REDR, &rect);
-
- /* curvemap min/max only works for RGBA */
- if(ibuf->channels==4) {
- bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset", 10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves");
- uiButSetFunc(bt, image_panel_curves_reset, sima->cumap, ibuf);
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level");
- uiDefButF(block, NUM, B_SIMARANGE, "Min G:", 10, 100, 90, 19, sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level");
- uiDefButF(block, NUM, B_SIMARANGE, "Min B:", 10, 80, 90, 19, sima->cumap->black+2, -1000.0f, 1000.0f, 10, 2, "Black level");
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_SIMARANGE, "Max R:", 10, 50, 90, 19, sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level");
- uiDefButF(block, NUM, B_SIMARANGE, "Max G:", 10, 30, 90, 19, sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level");
- uiDefButF(block, NUM, B_SIMARANGE, "Max B:", 10, 10, 90, 19, sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level");
- }
+
+ /* curvemap black/white levels only works for RGBA */
+ levels= (ibuf->channels==4);
+
+ RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &simaptr);
+ uiTemplateCurveMapping(pa->layout, &simaptr, "curves", 'c', levels);
}
+
+ ED_space_image_release_buffer(sima, lock);
}
#if 0
@@ -799,81 +655,11 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVI
uiBlockSetDrawExtraFunc(block, preview_cb);
}
-
-static void image_panel_gpencil(short cntrl) // IMAGE_HANDLER_GREASEPENCIL
-{
- uiBlock *block;
- SpaceImage *sima;
-
- sima= curarea->spacedata.first;
-
- block= uiBeginBlock(C, ar, "image_panel_gpencil", UI_EMBOSS);
- uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
- uiSetPanelHandler(IMAGE_HANDLER_GREASEPENCIL); // for close and esc
- if (uiNewPanel(C, ar, block, "Grease Pencil", "SpaceImage", 100, 30, 318, 204)==0) return;
-
- /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
- if (sima->flag & SI_DISPGP) {
- if (sima->gpd == NULL)
- gpencil_data_setactive(curarea, gpencil_data_addnew());
- }
-
- if (sima->flag & SI_DISPGP) {
- bGPdata *gpd= sima->gpd;
- short newheight;
-
- /* this is a variable height panel, newpanel doesnt force new size on existing panels */
- /* so first we make it default height */
- uiNewPanelHeight(block, 204);
-
- /* draw button for showing gpencil settings and drawings */
- uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor (draw using Shift-LMB)");
-
- /* extend the panel if the contents won't fit */
- newheight= draw_gpencil_panel(block, gpd, curarea);
- uiNewPanelHeight(block, newheight);
- }
- else {
- uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor");
- uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
- }
-}
#endif
/* ********************* callbacks for standard image buttons *************** */
-/* called from fileselect or button */
-static void load_image_cb(bContext *C, char *str, void *ima_pp_v, void *iuser_v)
-{
- Image **ima_pp= (Image **)ima_pp_v;
- Image *ima= NULL;
-
- ima= BKE_add_image_file(str, 0);
- if(ima) {
- if(*ima_pp) {
- (*ima_pp)->id.us--;
- }
- *ima_pp= ima;
-
- BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD);
- WM_event_add_notifier(C, NC_IMAGE, ima);
-
- /* button event gets lost when it goes via filewindow */
-// if(G.buts && G.buts->lockpoin) {
-// Tex *tex= G.buts->lockpoin;
-// if(GS(tex->id.name)==ID_TE) {
-// BIF_preview_changed(ID_TE);
-// allqueue(REDRAWBUTSSHADING, 0);
-// allqueue(REDRAWVIEW3D, 0);
-// allqueue(REDRAWOOPS, 0);
-// }
-// }
- }
-
- ED_undo_push(C, "Load image");
-}
-
static char *layer_menu(RenderResult *rr, short *curlay)
{
RenderLayer *rl;
@@ -937,92 +723,6 @@ static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v)
}
}
-static void image_src_change_cb(bContext *C, void *ima_v, void *iuser_v)
-{
- BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE);
-}
-
-/* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */
-static void image_browse_cb1(bContext *C, void *ima_pp_v, void *iuser_v)
-{
- Image **ima_pp= (Image **)ima_pp_v;
- ImageUser *iuser= iuser_v;
-
- if(ima_pp) {
- Image *ima= *ima_pp;
-
- if(iuser->menunr== -2) {
- // XXX activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser);
- }
- else if (iuser->menunr>0) {
- Image *newima= (Image*) BLI_findlink(&CTX_data_main(C)->image, iuser->menunr-1);
-
- if (newima && newima!=ima) {
- *ima_pp= newima;
- id_us_plus(&newima->id);
- if(ima) ima->id.us--;
-
- BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE);
-
- ED_undo_push(C, "Browse image");
- }
- }
- }
-}
-
-static void image_browse_cb(bContext *C, void *ima_pp_v, void *iuser_v)
-{
- image_browse_cb1(C, ima_pp_v, iuser_v);
-}
-
-static void image_reload_cb(bContext *C, void *ima_v, void *iuser_v)
-{
- if(ima_v) {
- BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD);
- }
-}
-
-static void image_field_test(bContext *C, void *ima_v, void *iuser_v)
-{
- Image *ima= ima_v;
-
- if(ima) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
- if(ibuf) {
- short nr= 0;
- if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1;
- if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1;
- if(nr) {
- BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE);
- }
- }
- }
-}
-
-static void image_unlink_cb(bContext *C, void *ima_pp_v, void *unused)
-{
- Image **ima_pp= (Image **)ima_pp_v;
-
- if(ima_pp && *ima_pp) {
- Image *ima= *ima_pp;
- /* (for time being, texturefaces are no users, conflict in design...) */
- if(ima->id.us>1)
- ima->id.us--;
- *ima_pp= NULL;
- }
-}
-
-static void image_load_fs_cb(bContext *C, void *ima_pp_v, void *iuser_v)
-{
- ScrArea *sa= CTX_wm_area(C);
-// Image **ima_pp= (Image **)ima_pp_v;
-
- if(sa->spacetype==SPACE_IMAGE)
- WM_operator_name_call(C, "IMAGE_OT_open", WM_OP_INVOKE_REGION_WIN, NULL);
- else
- printf("not supported yet\n");
-}
-
/* 5 layer button callbacks... */
static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v)
{
@@ -1077,6 +777,7 @@ static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v)
}
}
+#if 0
static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v)
{
if(ima_v) {
@@ -1106,338 +807,328 @@ static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v)
}
}
}
+#endif
-static void image_load_cb(bContext *C, void *ima_pp_v, void *iuser_v)
-{
- if(ima_pp_v) {
- Image *ima= *((Image **)ima_pp_v);
- ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
- char str[FILE_MAX];
-
- /* name in ima has been changed by button! */
- BLI_strncpy(str, ima->name, FILE_MAX);
- if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
-
- load_image_cb(C, str, ima_pp_v, iuser_v);
- }
-}
-
+#if 0
static void image_freecache_cb(bContext *C, void *ima_v, void *unused)
{
Scene *scene= CTX_data_scene(C);
BKE_image_free_anim_ibufs(ima_v, scene->r.cfra);
WM_event_add_notifier(C, NC_IMAGE, ima_v);
}
+#endif
-static void image_generated_change_cb(bContext *C, void *ima_v, void *iuser_v)
-{
- BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE);
-}
-
+#if 0
static void image_user_change(bContext *C, void *iuser_v, void *unused)
{
Scene *scene= CTX_data_scene(C);
BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0);
}
+#endif
-static void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w)
+static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w)
{
+ uiBlock *block= uiLayoutGetBlock(layout);
uiBut *but;
RenderLayer *rl= NULL;
int wmenu1, wmenu2;
char *strp;
+ uiLayoutRow(layout, 1);
+
/* layer menu is 1/3 larger than pass */
wmenu1= (3*w)/5;
wmenu2= (2*w)/5;
/* menu buts */
strp= layer_menu(rr, &iuser->layer);
- but= uiDefButS(block, MENU, event, strp, x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer");
+ but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer");
uiButSetFunc(but, image_multi_cb, rr, iuser);
MEM_freeN(strp);
rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
strp= pass_menu(rl, &iuser->pass);
- but= uiDefButS(block, MENU, event, strp, x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass");
+ but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass");
uiButSetFunc(but, image_multi_cb, rr, iuser);
MEM_freeN(strp);
}
-static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged)
+static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser)
{
+ uiBlock *block= uiLayoutGetBlock(layout);
+ uiLayout *row;
uiBut *but;
+ row= uiLayoutRow(layout, 1);
+
if(rr==NULL || iuser==NULL)
return;
if(rr->layers.first==NULL) {
- uiDefBut(block, LABEL, 0, "No Layers in Render Result,", 10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
+ uiItemL(row, "No Layers in Render Result.", 0);
return;
}
-
- uiBlockBeginAlign(block);
/* decrease, increase arrows */
- but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer");
+ but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Layer");
uiButSetFunc(but, image_multi_declay_cb, rr, iuser);
- but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer");
+ but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer");
uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
- uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230);
+ uiblock_layer_pass_buttons(row, rr, iuser, 230);
/* decrease, increase arrows */
- but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
+ but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
uiButSetFunc(but, image_multi_decpass_cb, rr, iuser);
- but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass");
+ but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Pass");
uiButSetFunc(but, image_multi_incpass_cb, rr, iuser);
uiBlockEndAlign(block);
-
}
// XXX HACK!
-static int packdummy=0;
+// static int packdummy=0;
-/* The general Image panel with the loadsa callbacks! */
-void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, ImageUser *iuser,
- short redraw, short imagechanged)
+typedef struct RNAUpdateCb {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ ImageUser *iuser;
+} RNAUpdateCb;
+
+static void rna_update_cb(bContext *C, void *arg_cb, void *arg_unused)
+{
+ RNAUpdateCb *cb= (RNAUpdateCb*)arg_cb;
+
+ /* ideally this would be done by RNA itself, but there we have
+ no image user available, so we just update this flag here */
+ cb->iuser->ok= 1;
+
+ /* we call update here on the pointer property, this way the
+ owner of the image pointer can still define it's own update
+ and notifier */
+ RNA_property_update(C, &cb->ptr, cb->prop);
+}
+
+void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *userptr, int compact)
{
+ PropertyRNA *prop;
+ PointerRNA imaptr;
+ RNAUpdateCb *cb;
+ Image *ima;
+ ImageUser *iuser;
+ ImBuf *ibuf;
Scene *scene= CTX_data_scene(C);
- SpaceImage *sima= CTX_wm_space_image(C);
- Image *ima= *ima_pp;
+ uiLayout *row, *split, *col;
+ uiBlock *block;
uiBut *but;
- char str[128], *strp;
+ char str[128];
+ void *lock;
+
+ if(!ptr->data)
+ return;
- /* different stuff when we show viewer */
- if(ima && ima->source==IMA_SRC_VIEWER) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
-
- image_info(ima, ibuf, str);
- uiDefBut(block, LABEL, 0, ima->id.name+2, 10, 180, 300, 20, NULL, 1, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, str, 10, 160, 300, 20, NULL, 1, 0, 0, 0, "");
-
- if(ima->type==IMA_TYPE_COMPOSITE) {
- iuser= ntree_get_active_iuser(scene->nodetree);
- if(iuser) {
- uiBlockBeginAlign(block);
- uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, "");
- uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, "");
- but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, "");
- uiButSetFunc(but, image_freecache_cb, ima, NULL);
-
- if(iuser->frames)
- sprintf(str, "(%d) Frames:", iuser->framenr);
- else strcpy(str, "Frames:");
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
- uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
- }
- }
- else if(ima->type==IMA_TYPE_R_RESULT) {
- /* browse layer/passes */
- uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(scene->id.name)), iuser, imagechanged);
- }
+ prop= RNA_struct_find_property(ptr, propname);
+ if(!prop) {
+ printf("uiTemplateImage: property not found: %s\n", propname);
return;
}
-
- /* the main ima source types */
+
+ block= uiLayoutGetBlock(layout);
+
+ imaptr= RNA_property_pointer_get(ptr, prop);
+ ima= imaptr.data;
+ iuser= userptr->data;
+
+ cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr= *ptr;
+ cb->prop= prop;
+ cb->iuser= iuser;
+
+ if(!compact)
+ uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL);
+
+ // XXX missing: reload, pack
+
if(ima) {
-// XXX uiSetButLock(ima->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
- uiBlockBeginAlign(block);
- uiBlockSetFunc(block, image_src_change_cb, ima, iuser);
- uiDefButS(block, ROW, imagechanged, "Still", 0, 180, 105, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file");
- uiDefButS(block, ROW, imagechanged, "Movie", 105, 180, 105, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file");
- uiDefButS(block, ROW, imagechanged, "Sequence", 210, 180, 105, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence");
- uiDefButS(block, ROW, imagechanged, "Generated", 315, 180, 105, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image");
- uiBlockSetFunc(block, NULL, NULL, NULL);
- }
- else
- uiDefBut(block, LABEL, 0, " ", 0, 180, 440, 20, 0, 0, 0, 0, 0, ""); /* for align in panel */
+ uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ if(ima->source == IMA_SRC_VIEWER) {
+ ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock);
+ image_info(ima, ibuf, str);
+ BKE_image_release_ibuf(ima, lock);
+
+ uiItemL(layout, ima->id.name+2, 0);
+ uiItemL(layout, str, 0);
+
+ if(ima->type==IMA_TYPE_COMPOSITE) {
+ // XXX not working yet
+#if 0
+ iuser= ntree_get_active_iuser(scene->nodetree);
+ if(iuser) {
+ uiBlockBeginAlign(block);
+ uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, "");
+ uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, "");
+ but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, "");
+ uiButSetFunc(but, image_freecache_cb, ima, NULL);
+
+ if(iuser->frames)
+ sprintf(str, "(%d) Frames:", iuser->framenr);
+ else strcpy(str, "Frames:");
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
+ uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
+ }
+#endif
+ }
+ else if(ima->type==IMA_TYPE_R_RESULT) {
+ /* browse layer/passes */
+ Render *re= RE_GetRender(scene->id.name);
+ RenderResult *rr= RE_AcquireResultRead(re);
+ uiblock_layer_pass_arrow_buttons(layout, rr, iuser);
+ RE_ReleaseResult(re);
+ }
+ }
+ else {
+ row= uiLayoutRow(layout, 0);
+ uiItemR(row, NULL, 0, &imaptr, "source", (compact)? 0: UI_ITEM_R_EXPAND);
+
+ if(ima->source != IMA_SRC_GENERATED) {
+ row= uiLayoutRow(layout, 0);
+ uiItemR(row, "", 0, &imaptr, "filename", 0);
+ //uiItemO(row, "Reload", 0, "image.reload");
+ }
+
+ // XXX what was this for?
+#if 0
+ /* check for re-render, only buttons */
+ if(imagechanged==B_IMAGECHANGED) {
+ if(iuser->flag & IMA_ANIM_REFRESHED) {
+ iuser->flag &= ~IMA_ANIM_REFRESHED;
+ WM_event_add_notifier(C, NC_IMAGE, ima);
+ }
+ }
+#endif
+
+ /* multilayer? */
+ if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
+ uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser);
+ }
+ else if(ima->source != IMA_SRC_GENERATED) {
+ ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock);
+ image_info(ima, ibuf, str);
+ BKE_image_release_ibuf(ima, lock);
+ uiItemL(layout, str, 0);
+ }
+
+ if(ima->source != IMA_SRC_GENERATED) {
+ uiItemS(layout);
+
+ split= uiLayoutSplit(layout, 0);
+
+ col= uiLayoutColumn(split, 0);
+ uiItemR(col, NULL, 0, &imaptr, "fields", 0);
+ row= uiLayoutRow(col, 0);
+ uiItemR(row, NULL, 0, &imaptr, "field_order", UI_ITEM_R_EXPAND);
+ uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "fields"));
+
+ col= uiLayoutColumn(split, 0);
+ uiItemR(col, NULL, 0, &imaptr, "antialias", 0);
+ uiItemR(col, NULL, 0, &imaptr, "premultiply", 0);
+ }
+
+ if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ uiItemS(layout);
+
+ split= uiLayoutSplit(layout, 0);
+
+ col= uiLayoutColumn(split, 0);
- /* Browse */
- IMAnames_to_pupstring(&strp, NULL, NULL, &(CTX_data_main(C)->image), NULL, &iuser->menunr);
-
- uiBlockBeginAlign(block);
- but= uiDefButS(block, MENU, imagechanged, strp, 0,155,40,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie");
- uiButSetFunc(but, image_browse_cb, ima_pp, iuser);
-
- MEM_freeN(strp);
-
- /* name + options, or only load */
- if(ima) {
- int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok);
-
- but= uiDefBut(block, TEX, B_IDNAME, "IM:", 40, 155, 220, 20, ima->id.name+2, 0.0, 21.0, 0, 0, "Current Image Datablock name.");
- uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL);
- but= uiDefBut(block, BUT, imagechanged, "Reload", 260, 155, 70, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie");
- uiButSetFunc(but, image_reload_cb, ima, iuser);
-
- but= uiDefIconBut(block, BUT, imagechanged, ICON_X, 330, 155, 40, 20, 0, 0, 0, 0, 0, "Unlink Image block");
- uiButSetFunc(but, image_unlink_cb, ima_pp, NULL);
- sprintf(str, "%d", ima->id.us);
- uiDefBut(block, BUT, B_NOP, str, 370, 155, 40, 20, 0, 0, 0, 0, 0, "Only displays number of users of Image block");
- uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL, 0, 130, 40, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image");
- uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
- but= uiDefBut(block, TEX, imagechanged, "", 40,130, 340+(drawpack?0:20),20, ima->name, 0.0, 239.0, 0, 0, "Image/Movie file name, change to load new");
- uiButSetFunc(but, image_load_cb, ima_pp, iuser);
- uiBlockEndAlign(block);
-
- if(drawpack) {
- if (ima->packedfile) packdummy = 1;
- else packdummy = 0;
- but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 380, 130, 40, 20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image");
- uiButSetFunc(but, image_pack_cb, ima, iuser);
- }
-
- }
- else {
- but= uiDefBut(block, BUT, imagechanged, "Load", 33, 155, 200,20, NULL, 0, 0, 0, 0, "Load new Image of Movie");
- uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
- }
- uiBlockEndAlign(block);
-
- if(ima) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
-
- /* check for re-render, only buttons */
- if(imagechanged==B_IMAGECHANGED) {
- if(iuser->flag & IMA_ANIM_REFRESHED) {
- iuser->flag &= ~IMA_ANIM_REFRESHED;
- WM_event_add_notifier(C, NC_IMAGE, ima);
- }
- }
-
- /* multilayer? */
- if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
- uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged);
- }
- else {
- image_info(ima, ibuf, str);
- uiDefBut(block, LABEL, 0, str, 10, 112, 300, 20, NULL, 1, 0, 0, 0, "");
- }
-
- /* exception, let's do because we only use this panel 3 times in blender... but not real good code! */
- if( (paint_facesel_test(CTX_data_active_object(C))) && sima && &sima->iuser==iuser)
- return;
- /* left side default per-image options, right half the additional options */
-
- /* fields */
-
- but= uiDefButBitS(block, TOGBUT, IMA_FIELDS, imagechanged, "Fields", 0, 80, 200, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
- uiButSetFunc(but, image_field_test, ima, iuser);
- uiDefButBitS(block, TOGBUT, IMA_STD_FIELD, B_NOP, "Odd", 0, 55, 200, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
-
-
- uiBlockSetFunc(block, image_reload_cb, ima, iuser);
- uiDefButBitS(block, TOGBUT, IMA_ANTIALI, B_NOP, "Anti", 0, 5, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
- uiDefButBitS(block, TOGBUT, IMA_DO_PREMUL, imagechanged, "Premul", 0, -20, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha");
-
-
- if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
- sprintf(str, "(%d) Frames:", iuser->framenr);
-
- //uiBlockBeginAlign(block);
- uiBlockSetFunc(block, image_user_change, iuser, NULL);
-
- if(ima->anim) {
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, imagechanged, str, 220, 80, 160, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
- but= uiDefBut(block, BUT, redraw, "<", 380, 80, 40, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
- uiButSetFunc(but, set_frames_cb, ima, iuser);
- uiBlockEndAlign(block);
- }
- else
- uiDefButI(block, NUM, imagechanged, str, 220, 80, 200, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
-
- uiDefButI(block, NUM, imagechanged, "Start Frame:", 220, 55, 200, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
- uiDefButI(block, NUM, imagechanged, "Offset:", 220, 30, 200, 20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
- uiDefButS(block, NUM, imagechanged, "Fields:", 0, 30, 200, 20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
-
- uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 220, 5, 200, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
-
- uiDefButS(block, TOG, imagechanged, "Cyclic", 220, -20, 200, 20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
-
- uiBlockSetFunc(block, NULL, iuser, NULL);
- }
- else if(ima->source==IMA_SRC_GENERATED) {
-
- uiDefBut(block, LABEL, 0, "Size:", 220, 80, 200, 20, 0, 0, 0, 0, 0, "");
-
- uiBlockBeginAlign(block);
- uiBlockSetFunc(block, image_generated_change_cb, ima, iuser);
- uiDefButS(block, NUM, imagechanged, "X:", 220, 55,200,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
- uiDefButS(block, NUM, imagechanged, "Y:", 220, 35,200,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
- uiBlockEndAlign(block);
-
- uiDefButS(block, TOGBUT, imagechanged, "UV Test grid", 220,10,200,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
- uiBlockSetFunc(block, NULL, NULL, NULL);
- }
- }
- uiBlockEndAlign(block);
-}
+ sprintf(str, "(%d) Frames", iuser->framenr);
+ row= uiLayoutRow(col, 1);
+ uiItemR(col, str, 0, userptr, "frames", 0);
+ if(ima->anim) {
+ block= uiLayoutGetBlock(row);
+ but= uiDefBut(block, BUT, 0, "<", 0, 0, UI_UNIT_X*2, UI_UNIT_Y, 0, 0, 0, 0, 0, "Set the number of frames from the movie or sequence.");
+ uiButSetFunc(but, set_frames_cb, ima, iuser);
+ }
+
+ uiItemR(col, "Start", 0, userptr, "start_frame", 0);
+ uiItemR(col, NULL, 0, userptr, "offset", 0);
+
+ col= uiLayoutColumn(split, 0);
+ uiItemR(col, "Fields", 0, userptr, "fields_per_frame", 0);
+ uiItemR(col, NULL, 0, userptr, "auto_refresh", 0);
+ uiItemR(col, NULL, 0, userptr, "cyclic", 0);
+ }
+ else if(ima->source==IMA_SRC_GENERATED) {
+ split= uiLayoutSplit(layout, 0);
+
+ col= uiLayoutColumn(split, 1);
+ uiItemR(col, "X", 0, &imaptr, "generated_width", 0);
+ uiItemR(col, "Y", 0, &imaptr, "generated_height", 0);
+
+ col= uiLayoutColumn(split, 0);
+ uiItemR(col, NULL, 0, &imaptr, "generated_type", UI_ITEM_R_EXPAND);
+ }
+
+ }
+
+ uiBlockSetNFunc(block, NULL, NULL, NULL);
+ }
+
+ MEM_freeN(cb);
+}
void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
{
- uiBlock *block= uiLayoutFreeBlock(layout);
Scene *scene= CTX_data_scene(C);
RenderResult *rr;
/* render layers and passes */
if(ima && iuser) {
- rr= BKE_image_get_renderresult(scene, ima);
+ rr= BKE_image_acquire_renderresult(scene, ima);
- if(rr) {
- uiBlockBeginAlign(block);
- uiblock_layer_pass_buttons(block, rr, iuser, 0, 0, 0, 160);
- uiBlockEndAlign(block);
- }
+ if(rr)
+ uiblock_layer_pass_buttons(layout, rr, iuser, 160);
+
+ BKE_image_release_renderresult(scene, ima);
}
}
-static void image_panel_properties(const bContext *C, Panel *pa)
+static int image_panel_uv_poll(const bContext *C, PanelType *pt)
{
- SpaceImage *sima= CTX_wm_space_image(C);
+ Object *obedit= CTX_data_edit_object(C);
+ return ED_uvedit_test(obedit);
+}
+
+static void image_panel_uv(const bContext *C, Panel *pa)
+{
+ ARegion *ar= CTX_wm_region(C);
uiBlock *block;
block= uiLayoutFreeBlock(pa->layout);
uiBlockSetHandleFunc(block, do_image_panel_events, NULL);
- /* note, it draws no bottom half in facemode, for vertex buttons */
- ED_image_uiblock_panel(C, block, &sima->image, &sima->iuser, B_REDR, B_REDR);
image_editvertex_buts(C, block);
+ image_editcursor_buts(C, &ar->v2d, block);
}
void image_buttons_register(ARegionType *art)
{
PanelType *pt;
- pt= MEM_callocN(sizeof(PanelType), "spacetype image panel properties");
- strcpy(pt->idname, "IMAGE_PT_properties");
- strcpy(pt->label, "Image Properties");
- pt->draw= image_panel_properties;
- BLI_addtail(&art->paneltypes, pt);
-
- pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint");
- strcpy(pt->idname, "IMAGE_PT_paint");
- strcpy(pt->label, "Paint");
- pt->draw= image_panel_paint;
- pt->poll= image_panel_paint_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint color");
- strcpy(pt->idname, "IMAGE_PT_paint_color");
- strcpy(pt->label, "Paint Color");
- pt->draw= image_panel_paintcolor;
- pt->poll= image_panel_paint_poll;
+ pt= MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
+ strcpy(pt->idname, "IMAGE_PT_uv");
+ strcpy(pt->label, "UV");
+ pt->draw= image_panel_uv;
+ pt->poll= image_panel_uv_poll;
BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype image panel curves");
strcpy(pt->idname, "IMAGE_PT_curves");
strcpy(pt->label, "Curves");
pt->draw= image_panel_curves;
+ pt->poll= image_panel_poll;
+ pt->flag |= PNL_DEFAULT_CLOSED;
BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil");
@@ -1452,13 +1143,9 @@ static int image_properties(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= image_has_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index cf9bac1ebee..a42fec30c45 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -533,15 +533,18 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d)
if (onlyv2d) {
/* assume that UI_view2d_ortho(C) has been called... */
SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ void *lock;
+ ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
/* draw grease-pencil ('image' strokes) */
//if (sima->flag & SI_DISPGP)
draw_gpencil_2dimage(C, ibuf);
+
+ ED_space_image_release_buffer(sima, lock);
}
else {
/* assume that UI_view2d_restore(C) has been called... */
- SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C);
+ //SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C);
/* draw grease-pencil ('screen' strokes) */
//if (sima->flag & SI_DISPGP)
@@ -654,6 +657,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
ImBuf *ibuf;
float zoomx, zoomy;
int show_viewer, show_render;
+ void *lock;
/* XXX can we do this in refresh? */
#if 0
@@ -675,11 +679,9 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
}
#endif
- /* put scene context variable in iuser */
- sima->iuser.scene= scene;
/* retrieve the image and information about it */
ima= ED_space_image(sima);
- ibuf= ED_space_image_buffer(sima);
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
ED_space_image_zoom(sima, ar, &zoomx, &zoomy);
show_viewer= (ima && ima->source == IMA_SRC_VIEWER);
@@ -718,5 +720,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
}
}
#endif
+
+ ED_space_image_release_buffer(sima, lock);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index bee06e6892f..89427ba8535 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -112,7 +112,7 @@ static int space_image_poll(bContext *C)
{
SpaceImage *sima= CTX_wm_space_image(C);
if(sima && sima->spacetype==SPACE_IMAGE)
- if(ED_space_image_buffer(sima))
+ if(ED_space_image_has_buffer(sima))
return 1;
return 0;
}
@@ -121,10 +121,15 @@ static int space_image_file_exists_poll(bContext *C)
{
if(space_image_poll(C)) {
SpaceImage *sima= CTX_wm_space_image(C);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ ImBuf *ibuf;
+ void *lock;
+ int poll;
- if(ibuf && BLI_exists(ibuf->name) && BLI_is_writable(ibuf->name))
- return 1;
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+ poll= (ibuf && BLI_exists(ibuf->name) && BLI_is_writable(ibuf->name));
+ ED_space_image_release_buffer(sima, lock);
+
+ return poll;
}
return 0;
}
@@ -161,7 +166,7 @@ static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
vpd->xof= sima->xof;
vpd->yof= sima->yof;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
}
static void view_pan_exit(bContext *C, wmOperator *op, int cancel)
@@ -224,7 +229,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
view_pan_exec(C, op);
break;
case MIDDLEMOUSE:
- if(event->val==0) {
+ if(event->val==KM_RELEASE) {
view_pan_exit(C, op, 0);
return OPERATOR_FINISHED;
}
@@ -280,7 +285,7 @@ static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
vpd->y= event->y;
vpd->zoom= sima->zoom;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
}
static void view_zoom_exit(bContext *C, wmOperator *op, int cancel)
@@ -339,7 +344,7 @@ static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
ED_area_tag_redraw(CTX_wm_area(C));
break;
case MIDDLEMOUSE:
- if(event->val==0) {
+ if(event->val==KM_RELEASE) {
view_zoom_exit(C, op, 0);
return OPERATOR_FINISHED;
}
@@ -388,7 +393,6 @@ static int view_all_exec(bContext *C, wmOperator *op)
ARegion *ar;
Scene *scene;
Object *obedit;
- ImBuf *ibuf;
float aspx, aspy, zoomx, zoomy, w, h;
int width, height;
@@ -398,7 +402,6 @@ static int view_all_exec(bContext *C, wmOperator *op)
scene= (Scene*)CTX_data_scene(C);
obedit= CTX_data_edit_object(C);
- ibuf= ED_space_image_buffer(sima);
ED_space_image_size(sima, &width, &height);
ED_space_image_aspect(sima, &aspx, &aspy);
@@ -445,7 +448,6 @@ static int view_selected_exec(bContext *C, wmOperator *op)
Scene *scene;
Object *obedit;
Image *ima;
- ImBuf *ibuf;
float size, min[2], max[2], d[2];
int width, height;
@@ -456,7 +458,6 @@ static int view_selected_exec(bContext *C, wmOperator *op)
obedit= CTX_data_edit_object(C);
ima= ED_space_image(sima);
- ibuf= ED_space_image_buffer(sima);
ED_space_image_size(sima, &width, &height);
/* get bounds */
@@ -609,7 +610,7 @@ static const EnumPropertyItem image_file_type_items[] = {
static void image_filesel(bContext *C, wmOperator *op, const char *path)
{
- RNA_string_set(op->ptr, "filename", path);
+ RNA_string_set(op->ptr, "path", path);
WM_event_add_fileselect(C, op);
}
@@ -623,14 +624,19 @@ static int open_exec(bContext *C, wmOperator *op)
Image *ima= NULL;
char str[FILE_MAX];
- RNA_string_get(op->ptr, "filename", str);
+ RNA_string_get(op->ptr, "path", str);
ima= BKE_add_image_file(str, scene->r.cfra);
if(!ima)
return OPERATOR_CANCELLED;
+
+ /* already set later */
+ ima->id.us--;
- BKE_image_signal(ima, &sima->iuser, IMA_SIGNAL_RELOAD);
- ED_space_image_set(C, sima, scene, obedit, ima);
+ // XXX other users?
+ BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_RELOAD);
+ if(sima)
+ ED_space_image_set(C, sima, scene, obedit, ima);
return OPERATOR_FINISHED;
}
@@ -638,9 +644,9 @@ static int open_exec(bContext *C, wmOperator *op)
static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceImage *sima= CTX_wm_space_image(C);
- char *path= (sima->image)? sima->image->name: U.textudir;
+ char *path= (sima && sima->image)? sima->image->name: U.textudir;
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return open_exec(C, op);
image_filesel(C, op, path);
@@ -651,19 +657,18 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
void IMAGE_OT_open(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Open Image";
+ ot->name= "Open";
ot->idname= "IMAGE_OT_open";
/* api callbacks */
ot->exec= open_exec;
ot->invoke= open_invoke;
- ot->poll= ED_operator_image_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL);
}
/******************** replace image operator ********************/
@@ -676,7 +681,7 @@ static int replace_exec(bContext *C, wmOperator *op)
if(!sima->image)
return OPERATOR_CANCELLED;
- RNA_string_get(op->ptr, "filename", str);
+ RNA_string_get(op->ptr, "path", str);
BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */
BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD);
@@ -693,7 +698,7 @@ static int replace_invoke(bContext *C, wmOperator *op, wmEvent *event)
if(!sima->image)
return OPERATOR_CANCELLED;
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return replace_exec(C, op);
image_filesel(C, op, path);
@@ -716,7 +721,7 @@ void IMAGE_OT_replace(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL);
}
/******************** save image as operator ********************/
@@ -726,7 +731,8 @@ void IMAGE_OT_replace(wmOperatorType *ot)
static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOperator *op, char *name)
{
Image *ima= ED_space_image(sima);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ void *lock;
+ ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
int len;
if (ibuf) {
@@ -747,7 +753,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOpera
WM_cursor_wait(1);
if(sima->imtypenr==R_MULTILAYER) {
- RenderResult *rr= BKE_image_get_renderresult(scene, ima);
+ RenderResult *rr= BKE_image_acquire_renderresult(scene, ima);
if(rr) {
RE_WriteRenderResult(rr, name, scene->r.quality);
@@ -761,6 +767,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOpera
}
else
BKE_report(op->reports, RPT_ERROR, "Did not write, no Multilayer Image");
+ BKE_image_release_renderresult(scene, ima);
}
else if (BKE_write_ibuf(scene, ibuf, name, sima->imtypenr, scene->r.subimtype, scene->r.quality)) {
BLI_strncpy(ima->name, name, sizeof(ima->name));
@@ -788,6 +795,8 @@ static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOpera
WM_cursor_wait(0);
}
+
+ ED_space_image_release_buffer(sima, lock);
}
static int save_as_exec(bContext *C, wmOperator *op)
@@ -801,7 +810,7 @@ static int save_as_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
sima->imtypenr= RNA_enum_get(op->ptr, "file_type");
- RNA_string_get(op->ptr, "filename", str);
+ RNA_string_get(op->ptr, "path", str);
save_image_doit(C, sima, scene, op, str);
@@ -812,16 +821,19 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceImage *sima= CTX_wm_space_image(C);
Image *ima = ED_space_image(sima);
- ImBuf *ibuf= ED_space_image_buffer(sima);
Scene *scene= CTX_data_scene(C);
+ ImBuf *ibuf;
+ void *lock;
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return save_as_exec(C, op);
if(!ima)
return OPERATOR_CANCELLED;
/* always opens fileselect */
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+
if(ibuf) {
/* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
@@ -838,10 +850,14 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
// XXX note: we can give default menu enums to operator for this
image_filesel(C, op, ibuf->name);
+
+ ED_space_image_release_buffer(sima, lock);
return OPERATOR_RUNNING_MODAL;
}
+ ED_space_image_release_buffer(sima, lock);
+
return OPERATOR_CANCELLED;
}
@@ -861,7 +877,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as.");
- WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL);
}
/******************** save image operator ********************/
@@ -870,12 +886,16 @@ static int save_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima= CTX_wm_space_image(C);
Image *ima = ED_space_image(sima);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ void *lock;
+ ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
Scene *scene= CTX_data_scene(C);
+ RenderResult *rr;
char name[FILE_MAX];
- if(!ima || !ibuf)
+ if(!ima || !ibuf) {
+ ED_space_image_release_buffer(sima, lock);
return OPERATOR_CANCELLED;
+ }
/* if exists, saves over without fileselect */
@@ -884,14 +904,21 @@ static int save_exec(bContext *C, wmOperator *op)
BLI_strncpy(name, G.ima, FILE_MAX);
if(BLI_exists(name) && BLI_is_writable(name)) {
- if(BKE_image_get_renderresult(scene, ima))
+ rr= BKE_image_acquire_renderresult(scene, ima);
+
+ if(rr)
sima->imtypenr= R_MULTILAYER;
else
sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
+
+ BKE_image_release_renderresult(scene, ima);
+ ED_space_image_release_buffer(sima, lock);
save_image_doit(C, sima, scene, op, name);
}
else {
+ ED_space_image_release_buffer(sima, lock);
+
BKE_report(op->reports, RPT_ERROR, "Can not save image.");
return OPERATOR_CANCELLED;
}
@@ -1051,8 +1078,12 @@ static int new_exec(bContext *C, wmOperator *op)
color[3]= RNA_float_get(op->ptr, "alpha");
ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color);
- BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
- ED_space_image_set(C, sima, scene, obedit, ima);
+ ima->id.us--; /* already set later */
+
+ if(sima) { // XXX other users?
+ BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
+ ED_space_image_set(C, sima, scene, obedit, ima);
+ }
return OPERATOR_FINISHED;
}
@@ -1066,7 +1097,6 @@ void IMAGE_OT_new(wmOperatorType *ot)
/* api callbacks */
ot->exec= new_exec;
ot->invoke= WM_operator_props_popup;
- ot->poll= ED_operator_image_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1103,9 +1133,8 @@ static int pack_test(bContext *C, wmOperator *op)
static int pack_exec(bContext *C, wmOperator *op)
{
- SpaceImage *sima= CTX_wm_space_image(C);
- Image *ima= ED_space_image(sima);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ Image *ima= CTX_data_edit_image(C);
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
int as_png= RNA_boolean_get(op->ptr, "as_png");
if(!pack_test(C, op))
@@ -1126,8 +1155,8 @@ static int pack_exec(bContext *C, wmOperator *op)
static int pack_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- SpaceImage *sima= CTX_wm_space_image(C);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ Image *ima= CTX_data_edit_image(C);
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
uiPopupMenu *pup;
uiLayout *layout;
int as_png= RNA_boolean_get(op->ptr, "as_png");
@@ -1287,6 +1316,7 @@ typedef struct ImageSampleInfo {
ARegionType *art;
void *draw_handle;
int x, y;
+ int channels;
char col[4];
float colf[4];
@@ -1303,14 +1333,9 @@ typedef struct ImageSampleInfo {
static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
{
- SpaceImage *sima= CTX_wm_space_image(C);
- ImBuf *ibuf= ED_space_image_buffer(sima);
ImageSampleInfo *info= arg_info;
- if(ibuf == NULL)
- return;
-
- draw_image_info(ar, ibuf->channels, info->x, info->y, info->colp,
+ draw_image_info(ar, info->channels, info->x, info->y, info->colp,
info->colfp, info->zp, info->zfp);
}
@@ -1318,13 +1343,16 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceImage *sima= CTX_wm_space_image(C);
ARegion *ar= CTX_wm_region(C);
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ void *lock;
+ ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
ImageSampleInfo *info= op->customdata;
float fx, fy;
int x, y;
- if(ibuf == NULL)
+ if(ibuf == NULL) {
+ ED_space_image_release_buffer(sima, lock);
return;
+ }
x= event->x - ar->winrct.xmin;
y= event->y - ar->winrct.ymin;
@@ -1341,6 +1369,7 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
info->x= x;
info->y= y;
info->draw= 1;
+ info->channels= ibuf->channels;
info->colp= NULL;
info->colfp= NULL;
@@ -1417,6 +1446,7 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
else
info->draw= 0;
+ ED_space_image_release_buffer(sima, lock);
ED_area_tag_redraw(CTX_wm_area(C));
}
@@ -1433,10 +1463,9 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceImage *sima= CTX_wm_space_image(C);
ARegion *ar= CTX_wm_region(C);
- ImBuf *ibuf= ED_space_image_buffer(sima);
ImageSampleInfo *info;
- if(ibuf == NULL)
+ if(!ED_space_image_has_buffer(sima))
return OPERATOR_CANCELLED;
info= MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo");
@@ -1446,7 +1475,7 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
sample_apply(C, op, event);
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1614,7 +1643,7 @@ static int record_composite_invoke(bContext *C, wmOperator *op, wmEvent *event)
rcd= op->customdata;
rcd->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.0f);
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
if(!record_composite_apply(C, op))
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index c57bc5773b0..4cf59c9a28e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -204,7 +204,7 @@ void image_operatortypes(void)
void image_keymap(struct wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
@@ -212,7 +212,7 @@ void image_keymap(struct wmWindowManager *wm)
WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
- keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0);
+ keymap= WM_keymap_find(wm, "Image", SPACE_IMAGE, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
@@ -232,9 +232,9 @@ void image_keymap(struct wmWindowManager *wm)
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
- WM_keymap_add_item(keymap, "PAINT_OT_image_paint", ACTIONMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", SELECTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SELECTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
@@ -328,7 +328,7 @@ static int image_context(const bContext *C, const char *member, bContextDataResu
/************************** main region ***************************/
/* sets up the fields of the View2D from zoom and offset */
-static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *scene)
+static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar)
{
Image *ima= ED_space_image(sima);
float x1, y1, w, h;
@@ -336,24 +336,9 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *sce
#if 0
if(image_preview_active(curarea, &width, &height));
-#endif
- if(sima->image) {
- ImBuf *ibuf= ED_space_image_buffer(sima);
-
- if(ibuf) {
- width= ibuf->x;
- height= ibuf->y;
- }
- else if(sima->image->type==IMA_TYPE_R_RESULT) {
- /* not very important, just nice */
- width= (scene->r.xsch*scene->r.size)/100;
- height= (scene->r.ysch*scene->r.size)/100;
- }
- else
- ED_space_image_size(sima, &width, &height);
- }
else
- ED_space_image_size(sima, &width, &height);
+#endif
+ ED_space_image_size(sima, &width, &height);
w= width;
h= height;
@@ -374,8 +359,8 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *sce
ar->v2d.mask.ymax= winy;
/* which part of the image space do we see? */
- x1= ar->winrct.xmin+(winx-sima->zoom*w)/2;
- y1= ar->winrct.ymin+(winy-sima->zoom*h)/2;
+ x1= ar->winrct.xmin+(winx-sima->zoom*w)/2.0f;
+ y1= ar->winrct.ymin+(winy-sima->zoom*h)/2.0f;
x1-= sima->zoom*sima->xof;
y1-= sima->zoom*sima->yof;
@@ -398,23 +383,22 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *sce
/* add handlers, stuff you only do once or on area/region changes */
static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
// image space manages own v2d
// UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
/* image paint polls for mode */
- keymap= WM_keymap_listbase(wm, "ImagePaint", SPACE_IMAGE, 0);
+ keymap= WM_keymap_find(wm, "Image Paint", SPACE_IMAGE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- /* XXX need context here?
- keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);*/
+ keymap= WM_keymap_find(wm, "UVEdit", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
/* own keymaps */
- keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0);
+ keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0);
+ keymap= WM_keymap_find(wm, "Image", SPACE_IMAGE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -432,20 +416,25 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
-
+
+ /* put scene context variable in iuser */
+ sima->iuser.scene= scene;
+
/* we set view2d from own zoom and offset each time */
- image_main_area_set_view2d(sima, ar, scene);
+ image_main_area_set_view2d(sima, ar);
/* we draw image in pixelspace */
draw_image_main(sima, ar, scene);
/* and uvs in 0.0-1.0 space */
UI_view2d_view_ortho(C, v2d);
- draw_uvedit_main(sima, ar, scene, obedit);
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST);
+ draw_uvedit_main(sima, ar, scene, obedit);
+
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST);
- /* Grease Pencil too (in addition to UV's) */
- draw_image_grease_pencil((bContext *)C, 1);
+ /* Grease Pencil too (in addition to UV's) */
+ draw_image_grease_pencil((bContext *)C, 1);
+
UI_view2d_view_restore(C);
/* draw Grease Pencil - screen space only */
@@ -457,29 +446,11 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
UI_view2d_scrollers_free(scrollers);*/
}
-static void image_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
-{
- ListBase *keymap;
-
- keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0);
-
- if(stype==NS_EDITMODE_MESH)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-}
-
static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
{
/* context changes */
switch(wmn->category) {
- case NC_SCENE:
- switch(wmn->data) {
- case ND_MODE:
- image_modal_keymaps(wmn->wm, ar, wmn->subtype);
- break;
- }
- break;
+ /* nothing yet */
}
}
@@ -488,11 +459,11 @@ static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
/* add handlers, stuff you only do once or on area/region changes */
static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0);
+ keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -505,7 +476,10 @@ static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
{
/* context changes */
switch(wmn->category) {
-
+ case NC_BRUSH:
+ if(wmn->action==NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
}
}
@@ -635,17 +609,17 @@ void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obe
}
}
-ImBuf *ED_space_image_buffer(SpaceImage *sima)
+ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
{
ImBuf *ibuf;
- if(sima->image) {
+ if(sima && sima->image) {
#if 0
if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
return BIF_render_spare_imbuf();
else
#endif
- ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+ ibuf= BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
if(ibuf && (ibuf->rect || ibuf->rect_float))
return ibuf;
@@ -654,11 +628,32 @@ ImBuf *ED_space_image_buffer(SpaceImage *sima)
return NULL;
}
-void ED_image_size(Image *ima, int *width, int *height)
+void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
+{
+ if(sima && sima->image)
+ BKE_image_release_ibuf(sima->image, lock);
+}
+
+int ED_space_image_has_buffer(SpaceImage *sima)
{
ImBuf *ibuf;
+ void *lock;
+ int has_buffer;
- ibuf= (ima)? BKE_image_get_ibuf(ima, NULL): NULL;
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+ has_buffer= (ibuf != NULL);
+ ED_space_image_release_buffer(sima, lock);
+
+ return has_buffer;
+}
+
+void ED_image_size(Image *ima, int *width, int *height)
+{
+ ImBuf *ibuf= NULL;
+ void *lock;
+
+ if(ima)
+ ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
*width= ibuf->x;
@@ -668,24 +663,36 @@ void ED_image_size(Image *ima, int *width, int *height)
*width= 256;
*height= 256;
}
+
+ if(ima)
+ BKE_image_release_ibuf(ima, lock);
}
void ED_space_image_size(SpaceImage *sima, int *width, int *height)
{
+ Scene *scene= sima->iuser.scene;
ImBuf *ibuf;
+ void *lock;
- ibuf= ED_space_image_buffer(sima);
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
*width= ibuf->x;
*height= ibuf->y;
}
+ else if(sima->image && sima->image->type==IMA_TYPE_R_RESULT && scene) {
+ /* not very important, just nice */
+ *width= (scene->r.xsch*scene->r.size)/100;
+ *height= (scene->r.ysch*scene->r.size)/100;
+ }
/* I know a bit weak... but preview uses not actual image size */
// XXX else if(image_preview_active(sima, width, height));
else {
*width= 256;
*height= 256;
}
+
+ ED_space_image_release_buffer(sima, lock);
}
void ED_image_aspect(Image *ima, float *aspx, float *aspy)
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 640c968742c..f4d8682b8ea 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -300,11 +300,11 @@ void FILE_OT_report_missing_files(wmOperatorType *ot)
static int find_missing_files_exec(bContext *C, wmOperator *op)
{
- char *filename;
+ char *path;
- filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0);
- findMissingFiles(filename);
- MEM_freeN(filename);
+ path= RNA_string_get_alloc(op->ptr, "path", NULL, 0);
+ findMissingFiles(path);
+ MEM_freeN(path);
return OPERATOR_FINISHED;
}
@@ -330,7 +330,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, 0);
+ WM_operator_properties_filesel(ot, 0, FILE_SPECIAL);
}
#if 0
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index 58c1eddb6c1..304c3601cdd 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -124,13 +124,9 @@ static int logic_properties(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= logic_has_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 3040d73bda9..dc8b111821d 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -39,6 +39,9 @@
#include "DNA_screen_types.h"
#include "DNA_sensor_types.h"
#include "DNA_sound_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_action_types.h"
#include "DNA_windowmanager_types.h"
#include "MEM_guardedalloc.h"
@@ -608,6 +611,8 @@ static char *sensor_name(int type)
return "Keyboard";
case SENS_PROPERTY:
return "Property";
+ case SENS_ARMATURE:
+ return "Armature";
case SENS_ACTUATOR:
return "Actuator";
case SENS_DELAY:
@@ -635,7 +640,7 @@ static char *sensor_pup(void)
/* the number needs to match defines in game.h */
return "Sensors %t|Always %x0|Delay %x13|Keyboard %x3|Mouse %x5|"
"Touch %x1|Collision %x6|Near %x2|Radar %x7|"
- "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12";
+ "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12|Armature %x14";
}
static char *controller_name(int type)
@@ -709,6 +714,8 @@ static char *actuator_name(int type)
return "Parent";
case ACT_STATE:
return "State";
+ case ACT_ARMATURE:
+ return "Armature";
}
return "unknown";
}
@@ -721,7 +728,7 @@ static char *actuator_pup(Object *owner)
switch (owner->type)
{
case OB_ARMATURE:
- return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
+ return "Actuators %t|Action %x15|Armature %x23|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|Game %x17"
"|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
@@ -936,6 +943,7 @@ static int get_col_sensor(int type)
case SENS_NEAR: return TH_PANEL;
case SENS_KEYBOARD: return TH_PANEL;
case SENS_PROPERTY: return TH_PANEL;
+ case SENS_ARMATURE: return TH_PANEL;
case SENS_ACTUATOR: return TH_PANEL;
case SENS_MOUSE: return TH_PANEL;
case SENS_RADAR: return TH_PANEL;
@@ -965,6 +973,120 @@ static void verify_logicbutton_func(bContext *C, void *data1, void *data2)
}
}
+static void test_scriptpoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ id= CTX_data_main(C)->text.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
+static void test_actionpoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ id= CTX_data_main(C)->action.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ id_us_plus(id);
+ *idpp= id;
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
+
+static void test_obpoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ id= CTX_data_main(C)->object.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ id_lib_extern(id); /* checks lib data, sets correct flag for saving then */
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
+static void test_meshpoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ if( *idpp ) (*idpp)->us--;
+
+ id= CTX_data_main(C)->mesh.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ id_us_plus(id);
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
+static void test_matpoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ if( *idpp ) (*idpp)->us--;
+
+ id= CTX_data_main(C)->mat.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ id_us_plus(id);
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
+static void test_scenepoin_but(struct bContext *C, char *name, ID **idpp)
+{
+ ID *id;
+
+ if( *idpp ) (*idpp)->us--;
+
+ id= CTX_data_main(C)->scene.first;
+ while(id) {
+ if( strcmp(name, id->name+2)==0 ) {
+ *idpp= id;
+ id_us_plus(id);
+ return;
+ }
+ id= id->next;
+ }
+ *idpp= NULL;
+}
+
+
+static void test_keyboard_event(struct bContext *C, void *arg_ks, void *arg_unused)
+{
+ bKeyboardSensor *ks= (bKeyboardSensor*)arg_ks;
+
+ if(!ISKEYBOARD(ks->key))
+ ks->key= 0;
+ if(!ISKEYBOARD(ks->qual))
+ ks->qual= 0;
+ if(!ISKEYBOARD(ks->qual2))
+ ks->qual2= 0;
+}
/**
* Draws a toggle for pulse mode, a frequency field and a toggle to invert
@@ -1015,12 +1137,51 @@ static void draw_default_sensor_header(bSensor *sens,
"Invert the level (output) of this sensor");
}
-static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname)
+static void check_armature_bone_constraint(Object *ob, char *posechannel, char *constraint)
+{
+ /* check that bone exist in the active object */
+ if (ob->type == OB_ARMATURE && ob->pose) {
+ bPoseChannel *pchan;
+ bPose *pose = ob->pose;
+ for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
+ if (!strcmp(pchan->name, posechannel)) {
+ /* found it, now look for constraint channel */
+ bConstraint *con;
+ for (con=pchan->constraints.first; con; con=con->next) {
+ if (!strcmp(con->name, constraint)) {
+ /* found it, all ok */
+ return;
+ }
+ }
+ /* didn't find constraint, make empty */
+ constraint[0] = 0;
+ return;
+ }
+ }
+ }
+ /* didn't find any */
+ posechannel[0] = 0;
+ constraint[0] = 0;
+}
+
+static void check_armature_sensor(bContext *C, void *arg1_but, void *arg2_sens)
+{
+ bArmatureSensor *sens = arg2_sens;
+ uiBut *but = arg1_but;
+ Object *ob= CTX_data_active_object(C);
+
+ /* check that bone exist in the active object */
+ but->retval = B_REDR;
+ check_armature_bone_constraint(ob, sens->posechannel, sens->constraint);
+}
+
+static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname)
{
bNearSensor *ns = NULL;
bTouchSensor *ts = NULL;
bKeyboardSensor *ks = NULL;
bPropertySensor *ps = NULL;
+ bArmatureSensor *arm = NULL;
bMouseSensor *ms = NULL;
bCollisionSensor *cs = NULL;
bRadarSensor *rs = NULL;
@@ -1030,6 +1191,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
bJoystickSensor *joy = NULL;
bActuatorSensor *as = NULL;
bDelaySensor *ds = NULL;
+ uiBut *but;
short ysize;
char *str;
@@ -1178,12 +1340,15 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
if ((ks->type&1)==0) { /* is All Keys option off? */
/* line 2: hotkey and allkeys toggle */
- uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code");
+ but= uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code");
+ uiButSetFunc(but, test_keyboard_event, ks, NULL);
/* line 3: two key modifyers (qual1, qual2) */
uiDefBut(block, LABEL, 0, "Hold", xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, "");
- uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code");
- uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code");
+ but= uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code");
+ uiButSetFunc(but, test_keyboard_event, ks, NULL);
+ but= uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code");
+ uiButSetFunc(but, test_keyboard_event, ks, NULL);
}
/* line 4: toggle property for string logging mode */
@@ -1242,6 +1407,45 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
yco-= ysize;
break;
}
+ case SENS_ARMATURE:
+ {
+ ysize= 70;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize,
+ (float)xco+width, (float)yco, 1);
+
+ draw_default_sensor_header(sens, block, xco, yco, width);
+ arm= sens->data;
+
+ if (ob->type == OB_ARMATURE) {
+ uiBlockBeginAlign(block);
+ but = uiDefBut(block, TEX, 1, "Bone: ",
+ (xco+10), (yco-44), (width-20)/2, 19,
+ arm->posechannel, 0, 31, 0, 0,
+ "Bone on which you want to check a constraint");
+ uiButSetFunc(but, check_armature_sensor, but, arm);
+ but = uiDefBut(block, TEX, 1, "Cons: ",
+ (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19,
+ arm->constraint, 0, 31, 0, 0,
+ "Name of the constraint you want to control");
+ uiButSetFunc(but, check_armature_sensor, but, arm);
+ uiBlockEndAlign(block);
+
+ str= "Type %t|State changed %x0|Lin error below %x1|Lin error above %x2|Rot error below %x3|Rot error above %x4";
+
+ uiDefButI(block, MENU, B_REDR, str, xco+10,yco-66,0.4*(width-20), 19,
+ &arm->type, 0, 31, 0, 0, "Type");
+
+ if (arm->type != SENS_ARM_STATE_CHANGED)
+ {
+ uiDefButF(block, NUM, 1, "Value: ", xco+10+0.4*(width-20),yco-66,0.6*(width-20), 19,
+ &arm->value, -10000.0, 10000.0, 100, 0, "Test the error against this value");
+ }
+ }
+ yco-= ysize;
+ break;
+ }
case SENS_ACTUATOR:
{
ysize= 48;
@@ -1534,7 +1738,7 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco
uiBlockBeginAlign(block);
uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+4,yco-23, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)");
if(pc->mode==0)
- uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script");
+ uiDefIDPoinBut(block, test_scriptpoin_but, ID_TXT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script");
else {
uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used");
uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-23, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting");
@@ -1576,6 +1780,7 @@ static int get_col_actuator(int type)
case ACT_VISIBILITY: return TH_PANEL;
case ACT_CONSTRAINT: return TH_PANEL;
case ACT_STATE: return TH_PANEL;
+ case ACT_ARMATURE: return TH_PANEL;
default: return TH_PANEL;
}
}
@@ -1656,6 +1861,18 @@ static void check_state_mask(bContext *C, void *arg1_but, void *arg2_mask)
but->retval = B_REDR;
}
+static void check_armature_actuator(bContext *C, void *arg1_but, void *arg2_act)
+{
+ bArmatureActuator *act = arg2_act;
+ uiBut *but = arg1_but;
+ Object *ob= CTX_data_active_object(C);
+
+ /* check that bone exist in the active object */
+ but->retval = B_REDR;
+ check_armature_bone_constraint(ob, act->posechannel, act->constraint);
+}
+
+
static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width)
{
bSoundActuator *sa = NULL;
@@ -1675,6 +1892,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
bTwoDFilterActuator *tdfa = NULL;
bParentActuator *parAct = NULL;
bStateActuator *staAct = NULL;
+ bArmatureActuator *armAct = NULL;
float *fp;
short ysize = 0, wval;
@@ -2702,6 +2920,48 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
yco-= ysize;
break;
+ case ACT_ARMATURE:
+ armAct = act->data;
+
+ if (ob->type == OB_ARMATURE) {
+ str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4";
+ uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, "");
+
+ switch (armAct->type) {
+ case ACT_ARM_RUN:
+ ysize = 28;
+ break;
+ default:
+ uiBlockBeginAlign(block);
+ but = uiDefBut(block, TEX, 1, "Bone: ",
+ (xco+5), (yco-44), (width-10)/2, 19,
+ armAct->posechannel, 0, 31, 0, 0,
+ "Bone on which the constraint is defined");
+ uiButSetFunc(but, check_armature_actuator, but, armAct);
+ but = uiDefBut(block, TEX, 1, "Cons: ",
+ (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19,
+ armAct->constraint, 0, 31, 0, 0,
+ "Name of the constraint you want to controle");
+ uiButSetFunc(but, check_armature_actuator, but, armAct);
+ uiBlockEndAlign(block);
+ ysize = 48;
+ switch (armAct->type) {
+ case ACT_ARM_SETTARGET:
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Target: ", xco+5, yco-64, (width-10), 19, &(armAct->target), "Set this object as the target of the constraint");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Secondary Target: ", xco+5, yco-84, (width-10), 19, &(armAct->subtarget), "Set this object as the secondary target of the constraint (only IK polar target at the moment)");
+ ysize += 40;
+ break;
+ case ACT_ARM_SETWEIGHT:
+ uiDefButF(block, NUM, B_REDR, "Weight:", xco+5+(width-10)*0.35,yco-24,(width-10)*0.65,19,&armAct->weight,0.0,1.0,0.0,0.0,"Set weight of this constraint");
+ break;
+ }
+ }
+ }
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+ yco-= ysize;
+ break;
+
default:
ysize= 4;
@@ -3216,7 +3476,7 @@ void logic_buttons(bContext *C, ARegion *ar)
uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
sens->otype= sens->type;
- yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
+ yco= draw_sensorbuttons(ob, sens, block, xco, yco, width,ob->id.name);
if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
}
else {
diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c
index 3c46522bba2..7043d625ab0 100644
--- a/source/blender/editors/space_logic/space_logic.c
+++ b/source/blender/editors/space_logic/space_logic.c
@@ -188,7 +188,7 @@ void logic_operatortypes(void)
void logic_keymap(struct wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Logic Generic", SPACE_LOGIC, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0);
WM_keymap_add_item(keymap, "LOGIC_OT_properties", NKEY, KM_PRESS, 0, 0);
}
@@ -234,12 +234,12 @@ static int logic_context(const bContext *C, const char *member, bContextDataResu
/* add handlers, stuff you only do once or on area/region changes */
static void logic_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymaps */
- keymap= WM_keymap_listbase(wm, "Logic Generic", SPACE_LOGIC, 0);
+ keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -276,11 +276,11 @@ static void logic_main_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void logic_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "Logic Generic", SPACE_LOGIC, 0);
+ keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 8532d78aa06..b193b89d65a 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -114,34 +114,69 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
if (ANIM_animdata_get_context(C, &ac) == 0)
return 0;
- /* extract list of active channel(s), of which we should only take the first one (expecting it to be an NLA track) */
- filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE);
+ /* extract list of active channel(s), of which we should only take the first one
+ * - we need the channels flag to get the active AnimData block when there are no NLA Tracks
+ */
+ filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE|ANIMFILTER_CHANNELS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
- // TODO: need some way to select active animdata too...
- if (ale->type == ANIMTYPE_NLATRACK) {
- NlaTrack *nlt= (NlaTrack *)ale->data;
- AnimData *adt= ale->adt;
-
- /* found it, now set the pointers */
- if (adt_ptr) {
- /* AnimData pointer */
- RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr);
- }
- if (nlt_ptr) {
- /* NLA-Track pointer */
- RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr);
- }
- if (strip_ptr) {
- /* NLA-Strip pointer */
- NlaStrip *strip= BKE_nlastrip_find_active(nlt);
- RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr);
+ switch (ale->type) {
+ case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */
+ {
+ NlaTrack *nlt= (NlaTrack *)ale->data;
+ AnimData *adt= ale->adt;
+
+ /* found it, now set the pointers */
+ if (adt_ptr) {
+ /* AnimData pointer */
+ RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr);
+ }
+ if (nlt_ptr) {
+ /* NLA-Track pointer */
+ RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr);
+ }
+ if (strip_ptr) {
+ /* NLA-Strip pointer */
+ NlaStrip *strip= BKE_nlastrip_find_active(nlt);
+ RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr);
+ }
+
+ found= 1;
}
-
- found= 1;
- break;
+ break;
+
+ case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */
+ case ANIMTYPE_OBJECT:
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ /* for these channels, we only do AnimData */
+ if (ale->id && ale->adt) {
+ if (adt_ptr) {
+ /* AnimData pointer */
+ RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr);
+
+ /* set found status to -1, since setting to 1 would break the loop
+ * and potentially skip an active NLA-Track in some cases...
+ */
+ found= -1;
+ }
+ }
+ }
+ break;
}
+
+ if (found > 0)
+ break;
}
/* free temp data */
@@ -211,7 +246,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa)
/* Active Action Properties ------------------------------------- */
/* action */
row= uiLayoutRow(layout, 1);
- uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators
+ uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACT_OT_new", NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators
/* extrapolation */
row= uiLayoutRow(layout, 1);
@@ -458,13 +493,9 @@ static int nla_properties(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= nla_has_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index ccf23266427..07dc3f0ad89 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -116,18 +116,22 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
}
/* action to take depends on what channel we've got */
+ // WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c
switch (ale->type) {
case ANIMTYPE_SCENE:
{
Scene *sce= (Scene *)ale->data;
+ AnimData *adt= sce->adt;
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
sce->flag ^= SCE_DS_SELECTED;
+ if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
sce->flag |= SCE_DS_SELECTED;
+ if (adt) adt->flag |= ADT_UI_SELECTED;
}
notifierFlags |= ND_ANIMCHAN_SELECT;
@@ -139,6 +143,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
Scene *sce= (Scene *)ads->source;
Base *base= (Base *)ale->data;
Object *ob= base->object;
+ AnimData *adt= ob->adt;
if (nlaedit_is_tweakmode_on(ac) == 0) {
/* set selection status */
@@ -146,23 +151,30 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
/* swap select */
base->flag ^= SELECT;
ob->flag= base->flag;
+
+ if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
Base *b;
- /* deleselect all */
+ /* deselect all */
+ // TODO: should this deselect all other types of channels too?
for (b= sce->base.first; b; b= b->next) {
b->flag &= ~SELECT;
b->object->flag= b->flag;
+ if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE);
}
/* select object now */
base->flag |= SELECT;
ob->flag |= SELECT;
+ if (adt) adt->flag |= ADT_UI_SELECTED;
}
/* xxx should be ED_base_object_activate(), but we need context pointer for that... */
//set_active_base(base);
+ if ((adt) && (adt->flag & ADT_UI_SELECTED))
+ adt->flag |= ADT_UI_ACTIVE;
/* notifiers - channel was selected */
notifierFlags |= ND_ANIMCHAN_SELECT;
@@ -170,6 +182,39 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
}
break;
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ {
+ /* sanity checking... */
+ if (ale->adt) {
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this AnimData block only */
+ ale->adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ /* select AnimData block by itself */
+ ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ ale->adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* set active? */
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+
+ notifierFlags |= ND_ANIMCHAN_SELECT;
+ }
+ break;
+
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt= (NlaTrack *)ale->data;
diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c
index 0d3bf2cb6b1..4eb9fac5cb8 100644
--- a/source/blender/editors/space_nla/nla_header.c
+++ b/source/blender/editors/space_nla/nla_header.c
@@ -246,31 +246,7 @@ void nla_header_buttons(const bContext *C, ARegion *ar)
uiBlockSetEmboss(block, UI_EMBOSS);
/* filtering buttons */
- if (snla->ads) {
- uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Only display selected Objects");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NLA_NOACT, B_REDR, ICON_ACTION, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Include AnimData blocks with no NLA Data");
- uiBlockEndAlign(block);
- xco += 5;
-
- uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Scene Animation");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display World Animation");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Materials");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Lamps");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Cameras");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Curves");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display MetaBalls");
- uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Particles");
- uiBlockEndAlign(block);
- xco += 15;
- }
- else {
- // XXX this case shouldn't happen at all... for now, just pad out same amount of space
- xco += 10*XIC + 15;
- }
- xco += (XIC + 8);
+ xco= ANIM_headerUI_standard_buttons(C, snla->ads, block, xco, yco);
/* auto-snap selector */
if (snla->flag & SNLA_DRAWTIME) {
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index ad5f5174690..5ea2e99ad6a 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -167,7 +167,7 @@ void nla_operatortypes(void)
/* ************************** registration - keymaps **********************************/
-static void nla_keymap_channels (wmWindowManager *wm, ListBase *keymap)
+static void nla_keymap_channels (wmWindowManager *wm, wmKeyMap *keymap)
{
/* NLA-specific (different to standard channels keymap) -------------------------- */
/* selection */
@@ -210,7 +210,7 @@ static void nla_keymap_channels (wmWindowManager *wm, ListBase *keymap)
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
}
-static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap)
+static void nla_keymap_main (wmWindowManager *wm, wmKeyMap *keymap)
{
wmKeymapItem *kmi;
@@ -284,10 +284,10 @@ static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap)
void nla_keymap(wmWindowManager *wm)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
/* keymap for all regions */
- keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0);
+ keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0);
WM_keymap_add_item(keymap, "NLA_OT_properties", NKEY, KM_PRESS, 0, 0);
/* channels */
@@ -297,11 +297,11 @@ void nla_keymap(wmWindowManager *wm)
*
* However, those operations which involve clicking on channels and/or the placement of them in the view are implemented here instead
*/
- keymap= WM_keymap_listbase(wm, "NLA Channels", SPACE_NLA, 0);
+ keymap= WM_keymap_find(wm, "NLA Channels", SPACE_NLA, 0);
nla_keymap_channels(wm, keymap);
/* data */
- keymap= WM_keymap_listbase(wm, "NLA Data", SPACE_NLA, 0);
+ keymap= WM_keymap_find(wm, "NLA Data", SPACE_NLA, 0);
nla_keymap_main(wm, keymap);
}
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 89d4e7cddf2..41435810889 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -208,15 +208,15 @@ static SpaceLink *nla_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void nla_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
// TODO: cannot use generic copy, need special NLA version
- keymap= WM_keymap_listbase(wm, "NLA Channels", SPACE_NLA, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "NLA Channels", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0);
+ keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -254,14 +254,14 @@ static void nla_channel_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void nla_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "NLA Data", SPACE_NLA, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "NLA Data", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0);
+ keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -354,11 +354,11 @@ static void nla_header_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void nla_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0);
+ keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -409,6 +409,7 @@ static void nla_main_area_listener(ARegion *ar, wmNotifier *wmn)
break;
case NC_SCENE:
switch(wmn->data) {
+ case ND_RENDER_OPTIONS:
case ND_OB_ACTIVE:
case ND_FRAME:
case ND_MARKERS:
diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript
index 5453aa7dd44..fd0dfe83852 100644
--- a/source/blender/editors/space_node/SConscript
+++ b/source/blender/editors/space_node/SConscript
@@ -14,5 +14,12 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
if env['CC'] == 'gcc':
#cf.append('-Werror')
pass
-
+
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_editors_space_node', sources, Split(incs), defs, libtype=['core'], priority=[55], compileflags=cf )
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 05adb5b75ca..b8da42079c4 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -170,9 +170,13 @@ static void node_group_alone_cb(bContext *C, void *node_v, void *unused_v)
/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
-static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_group(uiLayout *layout, PointerRNA *ptr)
{
- if(block && node->id) {
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+
+ if(node->id) {
uiBut *bt;
short width;
@@ -197,112 +201,95 @@ static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *
uiBlockEndAlign(block);
}
- return 19;
}
#endif
-static int node_buts_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_value(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- bNodeSocket *sock= node->outputs.first; /* first socket stores value */
-
- uiDefButF(block, NUM, B_NODE_EXEC, "",
- (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 20,
- sock->ns.vec, sock->ns.min, sock->ns.max, 10, 2, "");
-
- }
- return 20;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ bNodeSocket *sock= node->outputs.first; /* first socket stores value */
+
+ uiDefButF(block, NUM, B_NODE_EXEC, "",
+ (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 20,
+ sock->ns.vec, sock->ns.min, sock->ns.max, 10, 2, "");
}
-static int node_buts_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_rgb(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- bNodeSocket *sock= node->outputs.first; /* first socket stores value */
- if(sock) {
- /* enforce square box drawing */
- uiBlockSetEmboss(block, UI_EMBOSSP);
-
- uiDefButF(block, HSVCUBE, B_NODE_EXEC, "",
- (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 12,
- sock->ns.vec, 0.0f, 1.0f, 3, 0, "");
- uiDefButF(block, HSVCUBE, B_NODE_EXEC, "",
- (short)butr->xmin, (short)butr->ymin+15, butr->xmax-butr->xmin, butr->ymax-butr->ymin -15 -15,
- sock->ns.vec, 0.0f, 1.0f, 2, 0, "");
- uiDefButF(block, COL, B_NOP, "",
- (short)butr->xmin, (short)butr->ymax-12, butr->xmax-butr->xmin, 12,
- sock->ns.vec, 0.0, 0.0, -1, 0, "");
- /* the -1 above prevents col button to popup a color picker */
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- }
- return 30 + (int)(node->width-NODE_DY);
-}
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ bNodeSocket *sock= node->outputs.first; /* first socket stores value */
-static int node_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- uiBut *bt;
- int a_but= (ntree->type==NTREE_COMPOSIT);
+ if(sock) {
+ /* enforce square box drawing */
+ uiBlockSetEmboss(block, UI_EMBOSSP);
- /* blend type */
- uiBlockBeginAlign(block);
- bt=uiDefButS(block, MENU, B_NODE_EXEC, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Overlay %x9|Divide %x5|Difference %x6|Darken %x7|Lighten %x8|Dodge %x10|Burn %x11|Color %x15|Value %x14|Saturation %x13|Hue %x12|Soft Light %x16|Linear Light %x17",
- (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin -(a_but?20:0), 20,
- &node->custom1, 0, 0, 0, 0, "");
- uiButSetFunc(bt, node_but_title_cb, node, bt);
- /* Alpha option, composite */
- if(a_but)
- uiDefIconButS(block, TOG, B_NODE_EXEC, ICON_IMAGE_RGB_ALPHA,
- (short)butr->xmax-20, (short)butr->ymin, 20, 20,
- &node->custom2, 0, 0, 0, 0, "Include Alpha of 2nd input in this operation");
+ uiDefButF(block, HSVCUBE, B_NODE_EXEC, "",
+ (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 12,
+ sock->ns.vec, 0.0f, 1.0f, 3, 0, "");
+ uiDefButF(block, HSVCUBE, B_NODE_EXEC, "",
+ (short)butr->xmin, (short)butr->ymin+15, butr->xmax-butr->xmin, butr->xmax-butr->xmin -15 -15,
+ sock->ns.vec, 0.0f, 1.0f, 2, 0, "");
+ uiDefButF(block, COL, B_NOP, "",
+ (short)butr->xmin, (short)butr->ymax-12, butr->xmax-butr->xmin, 12,
+ sock->ns.vec, 0.0, 0.0, -1, 0, "");
+ /* the -1 above prevents col button to popup a color picker */
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
}
- return 20;
}
-static int node_buts_time(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- CurveMapping *cumap= node->storage;
- short dx= (short)((butr->xmax-butr->xmin)/2);
- butr->ymin += 26;
+static void node_buts_mix_rgb(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *row;
- curvemap_buttons(block, node->storage, 's', B_NODE_EXEC, B_REDR, butr);
-
- if(cumap) {
- //cumap->flag |= CUMA_DRAW_CFRA;
- //if(node->custom1<node->custom2)
- // cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
- }
+ bNodeTree *ntree= (bNodeTree*)ptr->id.data;
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_NODE_EXEC, "Sta:",
- (short)butr->xmin, (short)butr->ymin-22, dx, 19,
- &node->custom1, 1.0, 20000.0, 0, 0, "Start frame");
- uiDefButS(block, NUM, B_NODE_EXEC, "End:",
- (short)butr->xmin+dx, (short)butr->ymin-22, dx, 19,
- &node->custom2, 1.0, 20000.0, 0, 0, "End frame");
- }
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, "", 0, ptr, "blend_type", 0);
+ if(ntree->type == NTREE_COMPOSIT)
+ uiItemR(row, "", ICON_IMAGE_RGB_ALPHA, ptr, "alpha", 0);
+}
+
+static void node_buts_time(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *row;
+#if 0
+ /* XXX no context access here .. */
+ bNode *node= ptr->data;
+ CurveMapping *cumap= node->storage;
- return node->width-NODE_DY;
+ if(cumap) {
+ cumap->flag |= CUMA_DRAW_CFRA;
+ if(node->custom1<node->custom2)
+ cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
+ }
+#endif
+
+ uiTemplateCurveMapping(layout, ptr, "curve", 's', 0);
+
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, "Sta", 0, ptr, "start", 0);
+ uiItemR(row, "End", 0, ptr, "end", 0);
}
-static int node_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_valtorgb(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- if(node->storage) {
- uiBlockColorbandButtons(block, node->storage, butr, B_NODE_EXEC);
- }
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+
+ if(node->storage) {
+ uiBlockColorbandButtons(block, node->storage, butr, B_NODE_EXEC);
}
- return 40;
}
-static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_curvevec(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- curvemap_buttons(block, node->storage, 'v', B_NODE_EXEC, B_REDR, butr);
- }
- return (int)(node->width-NODE_DY);
+ uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0);
}
static float *_sample_col= NULL; // bad bad, 2.5 will do better?
@@ -311,33 +298,31 @@ void node_curvemap_sample(float *col)
_sample_col= col;
}
-static int node_buts_curvecol(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_curvecol(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- CurveMapping *cumap= node->storage;
- if(_sample_col) {
- cumap->flag |= CUMA_DRAW_SAMPLE;
- VECCOPY(cumap->sample, _sample_col);
- }
- else
- cumap->flag &= ~CUMA_DRAW_SAMPLE;
+ bNode *node= ptr->data;
+ CurveMapping *cumap= node->storage;
- curvemap_buttons(block, node->storage, 'c', B_NODE_EXEC, B_REDR, butr);
- }
- return (int)(node->width-NODE_DY);
+ if(_sample_col) {
+ cumap->flag |= CUMA_DRAW_SAMPLE;
+ VECCOPY(cumap->sample, _sample_col);
+ }
+ else
+ cumap->flag &= ~CUMA_DRAW_SAMPLE;
+
+ uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0);
}
-static int node_buts_normal(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_normal(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- bNodeSocket *sock= node->outputs.first; /* first socket stores normal */
-
- uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "",
- (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, butr->ymax-butr->ymin,
- sock->ns.vec, 0.0f, 1.0f, 0, 0, "");
-
- }
- return (int)(node->width-NODE_DY);
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ bNodeSocket *sock= node->outputs.first; /* first socket stores normal */
+
+ uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "",
+ (short)butr->xmin, (short)butr->xmin, butr->xmax-butr->xmin, butr->xmax-butr->xmin,
+ sock->ns.vec, 0.0f, 1.0f, 0, 0, "");
}
static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
@@ -401,8 +386,13 @@ static void node_dynamic_update_cb(bContext *C, void *ntree_v, void *node_v)
// XXX BIF_preview_changed(ID_MA);
}
-static int node_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_texture(uiLayout *layout, PointerRNA *ptr)
{
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
+
short multi = (
node->id &&
((Tex*)node->id)->use_nodes &&
@@ -410,49 +400,44 @@ static int node_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf
(node->type != TEX_NODE_TEXTURE)
);
- if(block) {
- uiBut *bt;
- char *strp;
- short width = (short)(butr->xmax - butr->xmin);
-
- /* browse button texture */
- uiBlockBeginAlign(block);
- IDnames_to_pupstring(&strp, NULL, "", &(G.main->tex), NULL, NULL);
- node->menunr= 0;
- bt= uiDefButS(block, MENU, B_NODE_EXEC, strp,
- butr->xmin, butr->ymin+(multi?30:0), 20, 19,
- &node->menunr, 0, 0, 0, 0, "Browse texture");
- uiButSetFunc(bt, node_browse_tex_cb, ntree, node);
- if(strp) MEM_freeN(strp);
-
- if(node->id) {
- bt= uiDefBut(block, TEX, B_NOP, "TE:",
- butr->xmin+19, butr->ymin+(multi?30:0), butr->xmax-butr->xmin-19, 19,
- node->id->name+2, 0.0, 19.0, 0, 0, "Texture name");
- uiButSetFunc(bt, node_ID_title_cb, node, NULL);
- }
- uiBlockEndAlign(block);
-
- if(multi) {
- char *menustr = ntreeTexOutputMenu(((Tex*)node->id)->nodetree);
- uiDefButS(block, MENU, B_MATPRV, menustr, butr->xmin, butr->ymin, width, 19, &node->custom1, 0, 0, 0, 0, "Which output to use, for multi-output textures");
- free(menustr);
- return 50;
- }
- return 20;
- }
- else return multi? 50: 20;
+ uiBut *bt;
+ char *strp;
+ short width = (short)(butr->xmax - butr->xmin);
+
+ /* browse button texture */
+ uiBlockBeginAlign(block);
+ IDnames_to_pupstring(&strp, NULL, "", &(G.main->tex), NULL, NULL);
+ node->menunr= 0;
+ bt= uiDefButS(block, MENU, B_NODE_EXEC, strp,
+ butr->xmin, butr->ymin+(multi?30:0), 20, 19,
+ &node->menunr, 0, 0, 0, 0, "Browse texture");
+ uiButSetFunc(bt, node_browse_tex_cb, ntree, node);
+ if(strp) MEM_freeN(strp);
+
+ if(node->id) {
+ bt= uiDefBut(block, TEX, B_NOP, "TE:",
+ butr->xmin+19, butr->ymin+(multi?30:0), butr->xmax-butr->xmin-19, 19,
+ node->id->name+2, 0.0, 19.0, 0, 0, "Texture name");
+ uiButSetFunc(bt, node_ID_title_cb, node, NULL);
+ }
+ uiBlockEndAlign(block);
+
+ if(multi) {
+ char *menustr = ntreeTexOutputMenu(((Tex*)node->id)->nodetree);
+ uiDefButS(block, MENU, B_MATPRV, menustr, butr->xmin, butr->ymin, width, 19, &node->custom1, 0, 0, 0, 0, "Which output to use, for multi-output textures");
+ free(menustr);
+ }
}
-static int node_buts_math(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_buts_math(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ uiBut *bt;
- bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14|Less Than %x15|Greater Than %x16", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, "");
- uiButSetFunc(bt, node_but_title_cb, node, bt);
- }
- return 20;
+ bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14|Less Than %x15|Greater Than %x16", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, "");
+ uiButSetFunc(bt, node_but_title_cb, node, bt);
}
@@ -556,192 +541,192 @@ static void node_texmap_cb(bContext *C, void *texmap_v, void *unused_v)
init_mapping(texmap_v);
}
-static int node_shader_buts_material(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_shader_buts_material(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt;
- short dx= (short)((butr->xmax-butr->xmin)/3.0f), has_us= (node->id && node->id->us>1);
- short dy= (short)butr->ymin;
- char *strp;
-
- /* WATCH IT: we use this callback in material buttons, but then only want first row */
- if(butr->ymax-butr->ymin > 21.0f) dy+= 19;
-
- uiBlockBeginAlign(block);
- /* XXX
- if(node->id==NULL) uiBlockSetCol(block, TH_REDALERT);
- else if(has_us) uiBlockSetCol(block, TH_BUT_SETTING1);
- else uiBlockSetCol(block, TH_BUT_SETTING2);
- */
-
- /* browse button */
- IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), NULL, NULL);
- node->menunr= 0;
- bt= uiDefButS(block, MENU, B_NOP, strp,
- butr->xmin, dy, 19, 19,
- &node->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW");
- uiButSetFunc(bt, node_browse_mat_cb, ntree, node);
- if(strp) MEM_freeN(strp);
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
+ uiBut *bt;
+ short dx= (short)((butr->xmax-butr->xmin)/3.0f), has_us= (node->id && node->id->us>1);
+ short dy= (short)butr->ymin;
+ char *strp;
+
+ /* WATCH IT: we use this callback in material buttons, but then only want first row */
+ if(butr->ymax-butr->ymin > 21.0f) dy+= 19;
+
+ uiBlockBeginAlign(block);
+ /* XXX
+ if(node->id==NULL) uiBlockSetCol(block, TH_REDALERT);
+ else if(has_us) uiBlockSetCol(block, TH_BUT_SETTING1);
+ else uiBlockSetCol(block, TH_BUT_SETTING2);
+ */
+
+ /* browse button */
+ IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), NULL, NULL);
+ node->menunr= 0;
+ bt= uiDefButS(block, MENU, B_NOP, strp,
+ butr->xmin, dy, 19, 19,
+ &node->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW");
+ uiButSetFunc(bt, node_browse_mat_cb, ntree, node);
+ if(strp) MEM_freeN(strp);
+
+ /* Add New button */
+ if(node->id==NULL) {
+ bt= uiDefBut(block, BUT, B_NOP, "Add New",
+ butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19,
+ NULL, 0.0, 0.0, 0, 0, "Add new Material");
+ uiButSetFunc(bt, node_new_mat_cb, ntree, node);
+ }
+ else {
+ /* name button */
+ short width= (short)(butr->xmax-butr->xmin-19.0f - (has_us?19.0f:0.0f));
+ bt= uiDefBut(block, TEX, B_NOP, "MA:",
+ butr->xmin+19, dy, width, 19,
+ node->id->name+2, 0.0, 19.0, 0, 0, "Material name");
+ uiButSetFunc(bt, node_ID_title_cb, node, NULL);
- /* Add New button */
- if(node->id==NULL) {
- bt= uiDefBut(block, BUT, B_NOP, "Add New",
- butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19,
- NULL, 0.0, 0.0, 0, 0, "Add new Material");
- uiButSetFunc(bt, node_new_mat_cb, ntree, node);
+ /* user amount */
+ if(has_us) {
+ char str1[32];
+ sprintf(str1, "%d", node->id->us);
+ bt= uiDefBut(block, BUT, B_NOP, str1,
+ butr->xmax-19, dy, 19, 19,
+ NULL, 0, 0, 0, 0, "Displays number of users. Click to make a single-user copy.");
+ uiButSetFunc(bt, node_mat_alone_cb, node, NULL);
}
- else {
- /* name button */
- short width= (short)(butr->xmax-butr->xmin-19.0f - (has_us?19.0f:0.0f));
- bt= uiDefBut(block, TEX, B_NOP, "MA:",
- butr->xmin+19, dy, width, 19,
- node->id->name+2, 0.0, 19.0, 0, 0, "Material name");
- uiButSetFunc(bt, node_ID_title_cb, node, NULL);
-
- /* user amount */
- if(has_us) {
- char str1[32];
- sprintf(str1, "%d", node->id->us);
- bt= uiDefBut(block, BUT, B_NOP, str1,
- butr->xmax-19, dy, 19, 19,
- NULL, 0, 0, 0, 0, "Displays number of users. Click to make a single-user copy.");
- uiButSetFunc(bt, node_mat_alone_cb, node, NULL);
- }
-
- /* WATCH IT: we use this callback in material buttons, but then only want first row */
- if(butr->ymax-butr->ymin > 21.0f) {
- /* node options */
- uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff",
- butr->xmin, butr->ymin, dx, 19,
- &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse");
- uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec",
- butr->xmin+dx, butr->ymin, dx, 19,
- &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular");
- uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal",
- butr->xmax-dx, butr->ymin, dx, 19,
- &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal");
- }
+
+ /* WATCH IT: we use this callback in material buttons, but then only want first row */
+ if(butr->ymax-butr->ymin > 21.0f) {
+ /* node options */
+ uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff",
+ butr->xmin, butr->ymin, dx, 19,
+ &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse");
+ uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec",
+ butr->xmin+dx, butr->ymin, dx, 19,
+ &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular");
+ uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal",
+ butr->xmax-dx, butr->ymin, dx, 19,
+ &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal");
}
- uiBlockEndAlign(block);
- }
- return 38;
+ }
+ uiBlockEndAlign(block);
}
-static int node_shader_buts_mapping(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_shader_buts_mapping(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- TexMapping *texmap= node->storage;
- short dx= (short)((butr->xmax-butr->xmin)/7.0f);
- short dy= (short)(butr->ymax-19);
-
- uiBlockSetFunc(block, node_texmap_cb, texmap, NULL); /* all buttons get this */
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->loc+2, -1000.0f, 1000.0f, 10, 2, "");
- dy-= 19;
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->rot+2, -1000.0f, 1000.0f, 1000, 1, "");
- dy-= 19;
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->size+2, -1000.0f, 1000.0f, 10, 2, "");
- dy-= 25;
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->min+2, -10.0f, 10.0f, 100, 2, "");
- dy-= 19;
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->max+2, -10.0f, 10.0f, 10, 2, "");
- uiBlockEndAlign(block);
-
- /* labels/options */
-
- dy= (short)(butr->ymax-19);
- uiDefBut(block, LABEL, B_NOP, "Loc", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
- dy-= 19;
- uiDefBut(block, LABEL, B_NOP, "Rot", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
- dy-= 19;
- uiDefBut(block, LABEL, B_NOP, "Size", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
- dy-= 25;
- uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
- dy-= 19;
- uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
-
- }
- return 5*19 + 6;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ TexMapping *texmap= node->storage;
+ short dx= (short)((butr->xmax-butr->xmin)/7.0f);
+ short dy= (short)(butr->ymax-19);
+
+ uiBlockSetFunc(block, node_texmap_cb, texmap, NULL); /* all buttons get this */
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->loc+2, -1000.0f, 1000.0f, 10, 2, "");
+ dy-= 19;
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->rot+2, -1000.0f, 1000.0f, 1000, 1, "");
+ dy-= 19;
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->size+2, -1000.0f, 1000.0f, 10, 2, "");
+ dy-= 25;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->min+2, -10.0f, 10.0f, 100, 2, "");
+ dy-= 19;
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, "");
+ uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->max+2, -10.0f, 10.0f, 10, 2, "");
+ uiBlockEndAlign(block);
+
+ /* labels/options */
+
+ dy= (short)(butr->ymax-19);
+ uiDefBut(block, LABEL, B_NOP, "Loc", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
+ dy-= 19;
+ uiDefBut(block, LABEL, B_NOP, "Rot", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
+ dy-= 19;
+ uiDefBut(block, LABEL, B_NOP, "Size", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
+ dy-= 25;
+ uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
+ dy-= 19;
+ uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
}
-static int node_shader_buts_vect_math(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_shader_buts_vect_math(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt;
-
- bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Average %x2|Dot Product %x3 |Cross Product %x4|Normalize %x5", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, "");
- uiButSetFunc(bt, node_but_title_cb, node, bt);
- }
- return 20;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ uiBut *bt;
+
+ bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Average %x2|Dot Product %x3 |Cross Product %x4|Normalize %x5", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, "");
+ uiButSetFunc(bt, node_but_title_cb, node, bt);
}
-static int node_shader_buts_geometry(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_shader_buts_geometry(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *but;
- NodeGeometry *ngeo= (NodeGeometry*)node->storage;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ uiBut *but;
+ NodeGeometry *ngeo= (NodeGeometry*)node->storage;
- // XXX if(!verify_valid_uv_name(ngeo->uvname))
- // XXX uiBlockSetCol(block, TH_REDALERT);
- but= uiDefBut(block, TEX, B_NODE_EXEC, "UV:", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, ngeo->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer");
- // XXX uiButSetCompleteFunc(but, autocomplete_uv, NULL);
+ // XXX if(!verify_valid_uv_name(ngeo->uvname))
+ // XXX uiBlockSetCol(block, TH_REDALERT);
+ but= uiDefBut(block, TEX, B_NODE_EXEC, "UV:", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, ngeo->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer");
+ // XXX uiButSetCompleteFunc(but, autocomplete_uv, NULL);
- if(!verify_valid_vcol_name(ngeo->colname));
+ if(!verify_valid_vcol_name(ngeo->colname));
// uiBlockSetCol(block, TH_REDALERT);
- but= uiDefBut(block, TEX, B_NODE_EXEC, "Col:", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, ngeo->colname, 0, 31, 0, 0, "Set name of vertex color layer to use, default is active vertex color layer");
- uiButSetCompleteFunc(but, autocomplete_vcol, NULL);
- }
-
- return 40;
+ but= uiDefBut(block, TEX, B_NODE_EXEC, "Col:", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, ngeo->colname, 0, 31, 0, 0, "Set name of vertex color layer to use, default is active vertex color layer");
+ uiButSetCompleteFunc(but, autocomplete_vcol, NULL);
}
-static int node_shader_buts_dynamic(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_shader_buts_dynamic(uiLayout *layout, PointerRNA *ptr)
{
- if (block) {
- uiBut *bt;
- // XXX SpaceNode *snode= curarea->spacedata.first;
- short dy= (short)butr->ymin;
- int xoff=0;
-
- /* B_NODE_EXEC is handled in butspace.c do_node_buts */
- if(!node->id) {
- char *strp;
- IDnames_to_pupstring(&strp, NULL, "", &(G.main->text), NULL, NULL);
- node->menunr= 0;
- bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp,
- butr->xmin, dy, 19, 19,
- &node->menunr, 0, 0, 0, 0, "Browses existing choices");
- uiButSetFunc(bt, node_browse_text_cb, ntree, node);
- xoff=19;
- if(strp) MEM_freeN(strp);
- }
- else {
- bt = uiDefBut(block, BUT, B_NOP, "Update",
- butr->xmin+xoff, butr->ymin+20, 50, 19,
- &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)");
- uiButSetFunc(bt, node_dynamic_update_cb, ntree, node);
-
- if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
- // UI_ThemeColor(TH_REDALERT);
- // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect);
- // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin);
- ;
- }
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
+ uiBut *bt;
+ // XXX SpaceNode *snode= curarea->spacedata.first;
+ short dy= (short)butr->ymin;
+ int xoff=0;
+
+ /* B_NODE_EXEC is handled in butspace.c do_node_buts */
+ if(!node->id) {
+ char *strp;
+ IDnames_to_pupstring(&strp, NULL, "", &(G.main->text), NULL, NULL);
+ node->menunr= 0;
+ bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp,
+ butr->xmin, dy, 19, 19,
+ &node->menunr, 0, 0, 0, 0, "Browses existing choices");
+ uiButSetFunc(bt, node_browse_text_cb, ntree, node);
+ xoff=19;
+ if(strp) MEM_freeN(strp);
+ }
+ else {
+ bt = uiDefBut(block, BUT, B_NOP, "Update",
+ butr->xmin+xoff, butr->ymin+20, 50, 19,
+ &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)");
+ uiButSetFunc(bt, node_dynamic_update_cb, ntree, node);
+
+ if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
+ // UI_ThemeColor(TH_REDALERT);
+ // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect);
+ // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin);
+ ;
}
}
- return 20+19;
}
/* only once called */
@@ -752,49 +737,49 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_MATERIAL:
case SH_NODE_MATERIAL_EXT:
- ntype->butfunc= node_shader_buts_material;
+ ntype->uifunc= node_shader_buts_material;
break;
case SH_NODE_TEXTURE:
- ntype->butfunc= node_buts_texture;
+ ntype->uifunc= node_buts_texture;
break;
case SH_NODE_NORMAL:
- ntype->butfunc= node_buts_normal;
+ ntype->uifunc= node_buts_normal;
break;
case SH_NODE_CURVE_VEC:
- ntype->butfunc= node_buts_curvevec;
+ ntype->uifunc= node_buts_curvevec;
break;
case SH_NODE_CURVE_RGB:
- ntype->butfunc= node_buts_curvecol;
+ ntype->uifunc= node_buts_curvecol;
break;
case SH_NODE_MAPPING:
- ntype->butfunc= node_shader_buts_mapping;
+ ntype->uifunc= node_shader_buts_mapping;
break;
case SH_NODE_VALUE:
- ntype->butfunc= node_buts_value;
+ ntype->uifunc= node_buts_value;
break;
case SH_NODE_RGB:
- ntype->butfunc= node_buts_rgb;
+ ntype->uifunc= node_buts_rgb;
break;
case SH_NODE_MIX_RGB:
- ntype->butfunc= node_buts_mix_rgb;
+ ntype->uifunc= node_buts_mix_rgb;
break;
case SH_NODE_VALTORGB:
- ntype->butfunc= node_buts_valtorgb;
+ ntype->uifunc= node_buts_valtorgb;
break;
case SH_NODE_MATH:
- ntype->butfunc= node_buts_math;
+ ntype->uifunc= node_buts_math;
break;
case SH_NODE_VECT_MATH:
- ntype->butfunc= node_shader_buts_vect_math;
+ ntype->uifunc= node_shader_buts_vect_math;
break;
case SH_NODE_GEOMETRY:
- ntype->butfunc= node_shader_buts_geometry;
+ ntype->uifunc= node_shader_buts_geometry;
break;
case NODE_DYNAMIC:
- ntype->butfunc= node_shader_buts_dynamic;
+ ntype->uifunc= node_shader_buts_dynamic;
break;
default:
- ntype->butfunc= NULL;
+ ntype->uifunc= NULL;
}
}
@@ -879,112 +864,102 @@ static void image_layer_cb(bContext *C, void *ima_v, void *iuser_v)
// allqueue(REDRAWNODE, 0);
}
-static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_image(uiLayout *layout, PointerRNA *ptr)
{
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
ImageUser *iuser= node->storage;
+ uiBut *bt;
+ short dy= (short)butr->ymax-19;
+ char *strp;
- if(block) {
- uiBut *bt;
- short dy= (short)butr->ymax-19;
- char *strp;
+ uiBlockBeginAlign(block);
+
+ /* browse button */
+ IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
+ node->menunr= 0;
+ bt= uiDefButS(block, MENU, B_NOP, strp,
+ butr->xmin, dy, 19, 19,
+ &node->menunr, 0, 0, 0, 0, "Browses existing choices");
+ uiButSetFunc(bt, node_browse_image_cb, ntree, node);
+ if(strp) MEM_freeN(strp);
+
+ /* Add New button */
+ if(node->id==NULL) {
+ bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New",
+ butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19,
+ NULL, 0.0, 0.0, 0, 0, "Add new Image");
+ uiButSetFunc(bt, node_active_cb, ntree, node);
+ }
+ else {
+ /* name button + type */
+ Image *ima= (Image *)node->id;
+ short xmin= (short)butr->xmin, xmax= (short)butr->xmax;
+ short width= xmax - xmin - 45;
+ short icon= ICON_IMAGE_DATA;
- uiBlockBeginAlign(block);
+ if(ima->source==IMA_SRC_MOVIE) icon= ICON_SEQUENCE;
+ else if(ima->source==IMA_SRC_SEQUENCE) icon= ICON_IMAGE_COL;
+ else if(ima->source==IMA_SRC_GENERATED) icon= ICON_BLANK1;
- /* browse button */
- IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
- node->menunr= 0;
- bt= uiDefButS(block, MENU, B_NOP, strp,
- butr->xmin, dy, 19, 19,
- &node->menunr, 0, 0, 0, 0, "Browses existing choices");
- uiButSetFunc(bt, node_browse_image_cb, ntree, node);
- if(strp) MEM_freeN(strp);
+ bt= uiDefBut(block, TEX, B_NOP, "IM:",
+ xmin+19, dy, width, 19,
+ node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
+ uiButSetFunc(bt, node_ID_title_cb, node, NULL);
- /* Add New button */
- if(node->id==NULL) {
- bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New",
- butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19,
- NULL, 0.0, 0.0, 0, 0, "Add new Image");
- uiButSetFunc(bt, node_active_cb, ntree, node);
- }
- else {
- /* name button + type */
- Image *ima= (Image *)node->id;
- short xmin= (short)butr->xmin, xmax= (short)butr->xmax;
- short width= xmax - xmin - 45;
- short icon= ICON_IMAGE_DATA;
-
- if(ima->source==IMA_SRC_MOVIE) icon= ICON_SEQUENCE;
- else if(ima->source==IMA_SRC_SEQUENCE) icon= ICON_IMAGE_COL;
- else if(ima->source==IMA_SRC_GENERATED) icon= ICON_BLANK1;
-
- bt= uiDefBut(block, TEX, B_NOP, "IM:",
- xmin+19, dy, width, 19,
- node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
- uiButSetFunc(bt, node_ID_title_cb, node, NULL);
-
- /* buffer type option */
- strp= node_image_type_pup();
- bt= uiDefIconTextButS(block, MENU, B_NOP, icon, strp,
- xmax-26, dy, 26, 19,
- &ima->source, 0.0, 19.0, 0, 0, "Image type");
- uiButSetFunc(bt, node_image_type_cb, node, ima);
- MEM_freeN(strp);
+ /* buffer type option */
+ strp= node_image_type_pup();
+ bt= uiDefIconTextButS(block, MENU, B_NOP, icon, strp,
+ xmax-26, dy, 26, 19,
+ &ima->source, 0.0, 19.0, 0, 0, "Image type");
+ uiButSetFunc(bt, node_image_type_cb, node, ima);
+ MEM_freeN(strp);
+
+ if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) ) {
+ width= (xmax-xmin)/2;
- if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) ) {
- width= (xmax-xmin)/2;
-
- dy-= 19;
- uiDefButI(block, NUM, B_NODE_EXEC, "Frs:",
- xmin, dy, width, 19,
- &iuser->frames, 1.0, MAXFRAMEF, 0, 0, "Amount of images used in animation");
- uiDefButI(block, NUM, B_NODE_EXEC, "SFra:",
- xmin+width, dy, width, 19,
- &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Start frame of animation");
+ dy-= 19;
+ uiDefButI(block, NUM, B_NODE_EXEC, "Frs:",
+ xmin, dy, width, 19,
+ &iuser->frames, 1.0, MAXFRAMEF, 0, 0, "Amount of images used in animation");
+ uiDefButI(block, NUM, B_NODE_EXEC, "SFra:",
+ xmin+width, dy, width, 19,
+ &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Start frame of animation");
+ dy-= 19;
+ uiDefButI(block, NUM, B_NODE_EXEC, "Offs:",
+ xmin, dy, width, 19,
+ &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
+ uiDefButS(block, TOG, B_NODE_EXEC, "Cycl",
+ xmin+width, dy, width-20, 19,
+ &iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic");
+ uiDefIconButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NODE_EXEC, ICON_AUTO,
+ xmax-20, dy, 20, 19,
+ &iuser->flag, 0.0, 0.0, 0, 0, "Always refresh Image on frame changes");
+ }
+ if( ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
+ RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
+ if(rl) {
+ width= (xmax-xmin);
dy-= 19;
- uiDefButI(block, NUM, B_NODE_EXEC, "Offs:",
+ strp= layer_menu(ima->rr);
+ bt= uiDefButS(block, MENU, B_NODE_EXEC, strp,
xmin, dy, width, 19,
- &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
- uiDefButS(block, TOG, B_NODE_EXEC, "Cycl",
- xmin+width, dy, width-20, 19,
- &iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic");
- uiDefIconButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NODE_EXEC, ICON_AUTO,
- xmax-20, dy, 20, 19,
- &iuser->flag, 0.0, 0.0, 0, 0, "Always refresh Image on frame changes");
- }
- if( ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
- RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
- if(rl) {
- width= (xmax-xmin);
- dy-= 19;
- strp= layer_menu(ima->rr);
- bt= uiDefButS(block, MENU, B_NODE_EXEC, strp,
- xmin, dy, width, 19,
- &iuser->layer, 0.0, 10000.0, 0, 0, "Layer");
- uiButSetFunc(bt, image_layer_cb, ima->rr, node->storage);
- MEM_freeN(strp);
- }
+ &iuser->layer, 0.0, 10000.0, 0, 0, "Layer");
+ uiButSetFunc(bt, image_layer_cb, ima->rr, node->storage);
+ MEM_freeN(strp);
}
}
+ }
- }
if(node->id) {
- Image *ima= (Image *)node->id;
- int retval= 19;
-
/* for each draw we test for anim refresh event */
if(iuser->flag & IMA_ANIM_REFRESHED) {
iuser->flag &= ~IMA_ANIM_REFRESHED;
// addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC); XXX
}
-
- if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) )
- retval+= 38;
- if( ima->type==IMA_TYPE_MULTILAYER)
- retval+= 19;
- return retval;
}
- else
- return 19;
}
/* if we use render layers from other scene, we make a nice title */
@@ -1057,9 +1032,14 @@ static void node_browse_scene_cb(bContext *C, void *ntree_v, void *node_v)
}
-static int node_composit_buts_renderlayers(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_renderlayers(uiLayout *layout, PointerRNA *ptr)
{
- if(block && node->id) {
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
+
+ if(node->id) {
Scene *scene= (Scene *)node->id;
uiBut *bt;
char *strp;
@@ -1094,7 +1074,6 @@ static int node_composit_buts_renderlayers(uiBlock *block, bNodeTree *ntree, bNo
&node->custom2, 0, 0, 0, 0, "Re-render this Layer");
}
- return 19;
}
static void node_blur_relative_cb(bContext *C, void *node, void *poin2)
@@ -1126,734 +1105,426 @@ static void node_blur_update_sizey_cb(bContext *C, void *node, void *poin2)
nbd->sizey= (int)(nbd->percenty*nbd->image_in_height);
}
-static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeBlurData *nbd= node->storage;
- uiBut *bt;
- short dy= butr->ymin+58;
- short dx= (butr->xmax-butr->xmin)/2;
- char str[256];
-
- uiBlockBeginAlign(block);
- sprintf(str, "Filter Type%%t|Flat %%x%d|Tent %%x%d|Quad %%x%d|Cubic %%x%d|Gauss %%x%d|Fast Gauss%%x%d|CatRom %%x%d|Mitch %%x%d", R_FILTER_BOX, R_FILTER_TENT, R_FILTER_QUAD, R_FILTER_CUBIC, R_FILTER_GAUSS, R_FILTER_FAST_GAUSS, R_FILTER_CATROM, R_FILTER_MITCH);
- uiDefButS(block, MENU, B_NODE_EXEC,str,
- butr->xmin, dy, dx*2, 19,
- &nbd->filtertype, 0, 0, 0, 0, "Set sampling filter for blur");
- dy-=19;
- if (nbd->filtertype != R_FILTER_FAST_GAUSS) {
- uiDefButC(block, TOG, B_NODE_EXEC, "Bokeh",
- butr->xmin, dy, dx, 19,
- &nbd->bokeh, 0, 0, 0, 0, "Uses circular filter, warning it's slow!");
- uiDefButC(block, TOG, B_NODE_EXEC, "Gamma",
- butr->xmin+dx, dy, dx, 19,
- &nbd->gamma, 0, 0, 0, 0, "Applies filter on gamma corrected values");
- } else {
- uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
- }
- dy-=19;
- bt= uiDefButS(block, TOG, B_NOP, "Relative",
- butr->xmin, dy, dx*2, 19,
- &nbd->relative, 0, 0, 0, 0, "Use relative (percent) values to define blur radius");
- uiButSetFunc(bt, node_blur_relative_cb, node, NULL);
-
- dy-=19;
- if(nbd->relative) {
- bt= uiDefButF(block, NUM, B_NODE_EXEC, "X:",
- butr->xmin, dy, dx, 19,
- &nbd->percentx, 0.0f, 1.0f, 0, 0, "");
- uiButSetFunc(bt, node_blur_update_sizex_cb, node, NULL);
- bt= uiDefButF(block, NUM, B_NODE_EXEC, "Y:",
- butr->xmin+dx, dy, dx, 19,
- &nbd->percenty, 0.0f, 1.0f, 0, 0, "");
- uiButSetFunc(bt, node_blur_update_sizey_cb, node, NULL);
- }
- else {
- uiDefButS(block, NUM, B_NODE_EXEC, "X:",
- butr->xmin, dy, dx, 19,
- &nbd->sizex, 0, 256, 0, 0, "");
- uiDefButS(block, NUM, B_NODE_EXEC, "Y:",
- butr->xmin+dx, dy, dx, 19,
- &nbd->sizey, 0, 256, 0, 0, "");
- }
- uiBlockEndAlign(block);
+ uiLayout *col;
+
+ col= uiLayoutColumn(layout, 0);
+
+ uiItemR(col, "", 0, ptr, "filter_type", 0);
+ /* Only for "Fast Gaussian" */
+ if (RNA_enum_get(ptr, "filter_type")!= 7) {
+ uiItemR(col, NULL, 0, ptr, "bokeh", 0);
+ uiItemR(col, NULL, 0, ptr, "gamma", 0);
+ }
+
+ uiItemR(col, NULL, 0, ptr, "relative", 0);
+ col= uiLayoutColumn(layout, 1);
+ if (RNA_boolean_get(ptr, "relative")== 1) {
+ uiItemR(col, "X", 0, ptr, "factor_x", 0);
+ uiItemR(col, "Y", 0, ptr, "factor_y", 0);
+ }
+ else {
+ uiItemR(col, "X", 0, ptr, "sizex", 0);
+ uiItemR(col, "Y", 0, ptr, "sizey", 0);
}
- return 77;
}
-static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_dblur(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeDBlurData *ndbd = node->storage;
- short dy = butr->ymin + 171;
- short dx = butr->xmax - butr->xmin;
- short halfdx= (short)dx/2;
-
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:",
- butr->xmin, dy, dx, 19,
- &ndbd->iter, 1, 32, 10, 0, "Amount of iterations");
- uiDefButC(block, TOG, B_NODE_EXEC, "Wrap",
- butr->xmin, dy-= 19, dx, 19,
- &ndbd->wrap, 0, 0, 0, 0, "Wrap blur");
- uiBlockEndAlign(block);
-
- dy-= 9;
-
- uiDefBut(block, LABEL, B_NOP, "Center", butr->xmin, dy-= 19, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NODE_EXEC, "X:",
- butr->xmin, dy-= 19, halfdx, 19,
- &ndbd->center_x, 0.0f, 1.0f, 10, 0, "X center in percents");
- uiDefButF(block, NUM, B_NODE_EXEC, "Y:",
- butr->xmin+halfdx, dy, halfdx, 19,
- &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents");
- uiBlockEndAlign(block);
+ uiLayout *col;
+
+ uiItemR(layout, NULL, 0, ptr, "iterations", 0);
+ uiItemR(layout, NULL, 0, ptr, "wrap", 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemL(col, "Center:", 0);
+ uiItemR(col, "X", 0, ptr, "center_x", 0);
+ uiItemR(col, "Y", 0, ptr, "center_y", 0);
+
+ uiItemS(layout);
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "distance", 0);
+ uiItemR(col, NULL, 0, ptr, "angle", 0);
+
+ uiItemS(layout);
+
+ uiItemR(layout, NULL, 0, ptr, "spin", 0);
+ uiItemR(layout, NULL, 0, ptr, "zoom", 0);
+}
- dy-= 9;
+static void node_composit_buts_bilateralblur(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *col;
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "iterations", 0);
+ uiItemR(col, NULL, 0, ptr, "sigma_color", 0);
+ uiItemR(col, NULL, 0, ptr, "sigma_space", 0);
+}
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NODE_EXEC, "Distance:",
- butr->xmin, dy-= 19, dx, 19,
- &ndbd->distance, -1.0f, 1.0f, 10, 0, "Amount of which the image moves");
- uiDefButF(block, NUM, B_NODE_EXEC, "Angle:",
- butr->xmin, dy-= 19, dx, 19,
- &ndbd->angle, 0.0f, 360.0f, 1000, 0, "Angle in which the image will be moved");
- uiBlockEndAlign(block);
+/* qdn: defocus node */
+static void node_composit_buts_defocus(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *sub, *col;
+
+ col= uiLayoutColumn(layout, 0);
+ uiItemL(col, "Bokeh Type:", 0);
+ uiItemR(col, "", 0, ptr, "bokeh", 0);
+ uiItemR(col, NULL, 0, ptr, "angle", 0);
- dy-= 9;
+ uiItemR(layout, NULL, 0, ptr, "gamma_correction", 0);
- uiDefButF(block, NUM, B_NODE_EXEC, "Spin:",
- butr->xmin, dy-= 19, dx, 19,
- &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image");
+ col = uiLayoutColumn(layout, 0);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer")==0);
+ uiItemR(col, NULL, 0, ptr, "f_stop", 0);
- dy-= 9;
+ uiItemR(layout, NULL, 0, ptr, "max_blur", 0);
+ uiItemR(layout, NULL, 0, ptr, "threshold", 0);
+
+ // Preview
+ col = uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "preview", 0);
+ sub = uiLayoutColumn(col, 0);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "preview"));
+ uiItemR(sub, NULL, 0, ptr, "samples", 0);
+
+ // Z-Buffer
+ col = uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "use_zbuffer", 0);
+ sub = uiLayoutColumn(col, 0);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer"));
+ uiItemR(sub, NULL, 0, ptr, "z_scale", 0);
+}
- uiDefButF(block, NUM, B_NODE_EXEC, "Zoom:",
- butr->xmin, dy-= 19, dx, 19,
- &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed");
+/* qdn: glare node */
+static void node_composit_buts_glare(uiLayout *layout, PointerRNA *ptr)
+{
+ uiItemR(layout, "", 0, ptr, "glare_type", 0);
+ uiItemR(layout, "", 0, ptr, "quality", 0);
+ if (RNA_enum_get(ptr, "glare_type")!= 1) {
+ uiItemR(layout, NULL, 0, ptr, "iterations", 0);
+
+ if (RNA_enum_get(ptr, "glare_type")!= 0)
+ uiItemR(layout, NULL, 0, ptr, "color_modulation", UI_ITEM_R_SLIDER);
}
- return 190;
-}
+
+ uiItemR(layout, NULL, 0, ptr, "mix", 0);
+ uiItemR(layout, NULL, 0, ptr, "threshold", 0);
-static int node_composit_buts_bilateralblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- NodeBilateralBlurData *nbbd= node->storage;
- short dy= butr->ymin+38;
- short dx= (butr->xmax-butr->xmin);
-
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:",
- butr->xmin, dy, dx, 19,
- &nbbd->iter, 1, 128, 0, 0, "Amount of iterations");
- dy-=19;
- uiDefButF(block, NUM, B_NODE_EXEC, "Color Sigma:",
- butr->xmin, dy, dx, 19,
- &nbbd->sigma_color,0.01, 3, 10, 0, "Sigma value used to modify color");
- dy-=19;
- uiDefButF(block, NUM, B_NODE_EXEC, "Space Sigma:",
- butr->xmin, dy, dx, 19,
- &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space");
+ if (RNA_enum_get(ptr, "glare_type")== 2) {
+ uiItemR(layout, NULL, 0, ptr, "streaks", 0);
+ uiItemR(layout, NULL, 0, ptr, "angle_offset", 0);
+ }
+ if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) {
+ uiItemR(layout, NULL, 0, ptr, "fade", UI_ITEM_R_SLIDER);
+ if (RNA_enum_get(ptr, "glare_type")== 0)
+ uiItemR(layout, NULL, 0, ptr, "rotate_45", 0);
}
- return 57;
-}
-
-/* qdn: defocus node */
-static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- NodeDefocus *nqd = node->storage;
- short dy = butr->ymin + 209;
- short dx = butr->xmax - butr->xmin;
- char* mstr1 = "Bokeh Type%t|Octagon %x8|Heptagon %x7|Hexagon %x6|Pentagon %x5|Square %x4|Triangle %x3|Disk %x0";
-
- uiDefBut(block, LABEL, B_NOP, "Bokeh Type", butr->xmin, dy, dx, 19, NULL, 0, 0, 0, 0, "");
- uiDefButC(block, MENU, B_NODE_EXEC, mstr1,
- butr->xmin, dy-19, dx, 19,
- &nqd->bktype, 0, 0, 0, 0, "Bokeh type");
- if (nqd->bktype) { /* for some reason rotating a disk doesn't seem to work... ;) */
- uiDefButC(block, NUM, B_NODE_EXEC, "Rotate:",
- butr->xmin, dy-38, dx, 19,
- &nqd->rotation, 0, 90, 0, 0, "Bokeh shape rotation offset in degrees");
- }
- uiDefButC(block, TOG, B_NODE_EXEC, "Gamma Correct",
- butr->xmin, dy-57, dx, 19,
- &nqd->gamco, 0, 0, 0, 0, "Enable gamma correction before and after main process");
- if (nqd->no_zbuf==0) {
- // only needed for zbuffer input
- uiDefButF(block, NUM, B_NODE_EXEC, "fStop:",
- butr->xmin, dy-76, dx, 19,
- &nqd->fstop, 0.5, 128, 10, 0, "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius");
- }
- uiDefButF(block, NUM, B_NODE_EXEC, "Maxblur:",
- butr->xmin, dy-95, dx, 19,
- &nqd->maxblur, 0, 10000, 1000, 0, "blur limit, maximum CoC radius, 0=no limit");
- uiDefButF(block, NUM, B_NODE_EXEC, "BThreshold:",
- butr->xmin, dy-114, dx, 19,
- &nqd->bthresh, 0, 100, 100, 0, "CoC radius threshold, prevents background bleed on in-focus midground, 0=off");
- uiDefButC(block, TOG, B_NODE_EXEC, "Preview",
- butr->xmin, dy-142, dx, 19,
- &nqd->preview, 0, 0, 0, 0, "Enable sampling mode, useful for preview when using low samplecounts");
- if (nqd->preview) {
- /* only visible when sampling mode enabled */
- uiDefButS(block, NUM, B_NODE_EXEC, "Samples:",
- butr->xmin, dy-161, dx, 19,
- &nqd->samples, 16, 256, 0, 0, "Number of samples (16=grainy, higher=less noise)");
- }
- uiDefButS(block, TOG, B_NODE_EXEC, "No zbuffer",
- butr->xmin, dy-190, dx, 19,
- &nqd->no_zbuf, 0, 0, 0, 0, "Enable when using an image as input instead of actual zbuffer (auto enabled if node not image based, eg. time node)");
- if (nqd->no_zbuf) {
- uiDefButF(block, NUM, B_NODE_EXEC, "Zscale:",
- butr->xmin, dy-209, dx, 19,
- &nqd->scale, 0, 1000, 100, 0, "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1");
- }
+ if (RNA_enum_get(ptr, "glare_type")== 1) {
+ uiItemR(layout, NULL, 0, ptr, "size", 0);
}
- return 228;
}
+/* qdn: tonemap node */
+static void node_composit_buts_tonemap(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *col;
-/* qdn: glare node */
-static int node_composit_buts_glare(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- NodeGlare *ndg = node->storage;
- short dy = butr->ymin + 152, dx = butr->xmax - butr->xmin;
- char* mn1 = "Type%t|Ghosts%x3|Streaks%x2|Fog Glow%x1|Simple Star%x0";
- char* mn2 = "Quality/Speed%t|High/Slow%x0|Medium/Medium%x1|Low/Fast%x2";
- uiDefButC(block, MENU, B_NODE_EXEC, mn1,
- butr->xmin, dy, dx, 19,
- &ndg->type, 0, 0, 0, 0, "Glow/Flare/Bloom type");
- uiDefButC(block, MENU, B_NODE_EXEC, mn2,
- butr->xmin, dy-19, dx, 19,
- &ndg->quality, 0, 0, 0, 0,
- "Quality speed trade off, if not set to high quality, effect will be applied to low-res copy of source image");
- if (ndg->type != 1) {
- uiDefButC(block, NUM, B_NODE_EXEC, "Iterations:",
- butr->xmin, dy-38, dx, 19,
- &ndg->iter, 2, 5, 1, 0,
- "higher values will generate longer/more streaks/ghosts");
- if (ndg->type != 0)
- uiDefButF(block, NUM, B_NODE_EXEC, "ColMod:",
- butr->xmin, dy-57, dx, 19,
- &ndg->colmod, 0, 1, 10, 0,
- "Amount of Color Modulation, modulates colors of streaks and ghosts for a spectral dispersion effect");
- }
- uiDefButF(block, NUM, B_NODE_EXEC, "Mix:",
- butr->xmin, dy-76, dx, 19,
- &ndg->mix, -1, 1, 10, 0,
- "Mix balance, -1 is original image only, 0 is exact 50/50 mix, 1 is processed image only");
- uiDefButF(block, NUM, B_NODE_EXEC, "Threshold:",
- butr->xmin, dy-95, dx, 19,
- &ndg->threshold, 0, 1000, 10, 0,
- "Brightness threshold, the glarefilter will be applied only to pixels brighter than this value");
- if ((ndg->type == 2) || (ndg->type == 0))
- {
- if (ndg->type == 2) {
- uiDefButC(block, NUM, B_NODE_EXEC, "streaks:",
- butr->xmin, dy-114, dx, 19,
- &ndg->angle, 2, 16, 1000, 0,
- "Total number of streaks");
- uiDefButC(block, NUM, B_NODE_EXEC, "AngOfs:",
- butr->xmin, dy-133, dx, 19,
- &ndg->angle_ofs, 0, 180, 1000, 0,
- "Streak angle rotation offset in degrees");
- }
- uiDefButF(block, NUM, B_NODE_EXEC, "Fade:",
- butr->xmin, dy-152, dx, 19,
- &ndg->fade, 0.75, 1, 5, 0,
- "Streak fade out factor");
- }
- if (ndg->type == 0)
- uiDefButC(block, TOG, B_NODE_EXEC, "Rot45",
- butr->xmin, dy-114, dx, 19,
- &ndg->angle, 0, 0, 0, 0,
- "simple star filter, add 45 degree rotation offset");
- if ((ndg->type == 1) || (ndg->type > 3)) // PBGH and fog glow
- uiDefButC(block, NUM, B_NODE_EXEC, "Size:",
- butr->xmin, dy-114, dx, 19,
- &ndg->size, 6, 9, 1000, 0,
- "glow/glare size (not actual size, relative to initial size of bright area of pixels)");
+ col = uiLayoutColumn(layout, 0);
+ uiItemR(col, "", 0, ptr, "tonemap_type", 0);
+ if (RNA_enum_get(ptr, "tonemap_type")== 0) {
+ uiItemR(col, NULL, 0, ptr, "key", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "offset", 0);
+ uiItemR(col, NULL, 0, ptr, "gamma", 0);
}
- return 171;
-}
-
-/* qdn: tonemap node */
-static int node_composit_buts_tonemap(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- NodeTonemap *ntm = node->storage;
- short dy = butr->ymin + 76, dx = butr->xmax - butr->xmin;
- char* mn = "Type%t|R/D Photoreceptor%x1|Rh Simple%x0";
-
- uiBlockBeginAlign(block);
- uiDefButI(block, MENU, B_NODE_EXEC, mn,
- butr->xmin, dy, dx, 19,
- &ntm->type, 0, 0, 0, 0,
- "Tone mapping type");
- if (ntm->type == 0) {
- uiDefButF(block, NUM, B_NODE_EXEC, "Key:",
- butr->xmin, dy-19, dx, 19,
- &ntm->key, 0, 1, 5, 0,
- "The value the average luminance is mapped to");
- uiDefButF(block, NUM, B_NODE_EXEC, "Offset:",
- butr->xmin, dy-38, dx, 19,
- &ntm->offset, 0.001, 10, 5, 0,
- "Tonemap offset, normally always 1, but can be used as an extra control to alter the brightness curve");
- uiDefButF(block, NUM, B_NODE_EXEC, "Gamma:",
- butr->xmin, dy-57, dx, 19,
- &ntm->gamma, 0.001, 3, 5, 0,
- "Gamma factor, if not used, set to 1");
- }
- else {
- uiDefButF(block, NUM, B_NODE_EXEC, "Intensity:",
- butr->xmin, dy-19, dx, 19,
- &ntm->f, -8, 8, 10, 0, "if less than zero, darkens image, otherwise makes it brighter");
- uiDefButF(block, NUM, B_NODE_EXEC, "Contrast:",
- butr->xmin, dy-38, dx, 19,
- &ntm->m, 0, 1, 5, 0, "Set to 0 to use estimate from input image");
- uiDefButF(block, NUM, B_NODE_EXEC, "Adaptation:",
- butr->xmin, dy-57, dx, 19,
- &ntm->a, 0, 1, 5, 0, "if 0, global, if 1, based on pixel intensity");
- uiDefButF(block, NUM, B_NODE_EXEC, "ColCorrect:",
- butr->xmin, dy-76, dx, 19,
- &ntm->c, 0, 1, 5, 0, "color correction, if 0, same for all channels, if 1, each independent");
- }
- uiBlockEndAlign(block);
+ else {
+ uiItemR(col, NULL, 0, ptr, "intensity", 0);
+ uiItemR(col, NULL, 0, ptr, "contrast", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "adaptation", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "correction", UI_ITEM_R_SLIDER);
}
- return 95;
}
/* qdn: lens distortion node */
-static int node_composit_buts_lensdist(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeLensDist *nld = node->storage;
- short dy = butr->ymin + 19, dx = butr->xmax - butr->xmin;
- uiBlockBeginAlign(block);
- uiDefButS(block, TOG, B_NODE_EXEC, "Projector",
- butr->xmin, dy, dx, 19,
- &nld->proj, 0, 0, 0, 0,
- "Enable/disable projector mode, effect is applied in horizontal direction only");
- if (!nld->proj) {
- uiDefButS(block, TOG, B_NODE_EXEC, "Jitter",
- butr->xmin, dy-19, dx/2, 19,
- &nld->jit, 0, 0, 0, 0,
- "Enable/disable jittering, faster, but also noisier");
- uiDefButS(block, TOG, B_NODE_EXEC, "Fit",
- butr->xmin+dx/2, dy-19, dx/2, 19,
- &nld->fit, 0, 0, 0, 0,
- "For positive distortion factor only, scale image such that black areas are not visible");
- }
- uiBlockEndAlign(block);
- }
- return 38;
-}
+ uiLayout *col;
+ col= uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "projector", 0);
-static int node_composit_buts_vecblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- PointerRNA ptr;
- short dy= butr->ymin;
- short dx= (butr->xmax-butr->xmin);
-
- RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
-
- uiBlockBeginAlign(block);
- uiDefButR(block, NUM, B_NODE_EXEC, NULL,
- butr->xmin, dy+76, dx, 19,
- &ptr, "samples", 0, 1, 256, 0, 0, NULL);
- uiDefButR(block, NUM, B_NODE_EXEC, NULL,
- butr->xmin, dy+57, dx, 19,
- &ptr, "min_speed", 0, 0, 1024, 0, 0, NULL);
- uiDefButR(block, NUM, B_NODE_EXEC, NULL,
- butr->xmin, dy+38, dx, 19,
- &ptr, "max_speed", 0, 0, 1024, 0, 0, NULL);
- uiDefButR(block, NUM, B_NODE_EXEC, "Blur",
- butr->xmin, dy+19, dx, 19,
- &ptr, "factor", 0, 0, 2, 10, 2, NULL);
- uiDefButR(block, TOG, B_NODE_EXEC, NULL,
- butr->xmin, dy, dx, 19,
- &ptr, "curved", 0, 0, 2, 10, 2, NULL);
- uiBlockEndAlign(block);
- }
- return 95;
+ col = uiLayoutColumn(col, 0);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "projector")==0);
+ uiItemR(col, NULL, 0, ptr, "jitter", 0);
+ uiItemR(col, NULL, 0, ptr, "fit", 0);
}
-static int node_composit_buts_filter(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt;
-
- /* blend type */
- bt=uiDefButS(block, MENU, B_NODE_EXEC, "Soften %x0|Sharpen %x1|Laplace %x2|Sobel %x3|Prewitt %x4|Kirsch %x5|Shadow %x6",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 0, 0, 0, "");
- uiButSetFunc(bt, node_but_title_cb, node, bt);
- }
- return 20;
+ uiLayout *col;
+
+ col= uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "samples", 0);
+ uiItemR(col, "Blur", 0, ptr, "factor", 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemL(col, "Speed:", 0);
+ uiItemR(col, "Min", 0, ptr, "min_speed", 0);
+ uiItemR(col, "Max", 0, ptr, "max_speed", 0);
+
+ uiItemR(layout, NULL, 0, ptr, "curved", 0);
}
-static int node_composit_buts_flip(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_filter(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt;
-
- /* flip x\y */
- bt=uiDefButS(block, MENU, B_NODE_EXEC, "Flip X %x0|Flip Y %x1|Flip X & Y %x2",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 0, 0, 0, "");
- uiButSetFunc(bt, node_but_title_cb, node, bt);
- }
- return 20;
+ uiItemR(layout, "", 0, ptr, "filter_type", 0);
}
-static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_flip(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeTwoXYs *ntxy= node->storage;
- char elementheight = 19;
- short dx= (butr->xmax-butr->xmin)/2;
- short dy= butr->ymax - elementheight;
- short xymin= 0, xymax= 10000;
-
- uiBlockBeginAlign(block);
-
- /* crop image size toggle */
- uiDefButS(block, TOG, B_NODE_EXEC, "Crop Image Size",
- butr->xmin, dy, dx*2, elementheight,
- &node->custom1, 0, 0, 0, 0, "Crop the size of the input image.");
-
- dy-=elementheight;
-
- /* x1 */
- uiDefButS(block, NUM, B_NODE_EXEC, "X1:",
- butr->xmin, dy, dx, elementheight,
- &ntxy->x1, xymin, xymax, 0, 0, "");
- /* y1 */
- uiDefButS(block, NUM, B_NODE_EXEC, "Y1:",
- butr->xmin+dx, dy, dx, elementheight,
- &ntxy->y1, xymin, xymax, 0, 0, "");
-
- dy-=elementheight;
-
- /* x2 */
- uiDefButS(block, NUM, B_NODE_EXEC, "X2:",
- butr->xmin, dy, dx, elementheight,
- &ntxy->x2, xymin, xymax, 0, 0, "");
- /* y2 */
- uiDefButS(block, NUM, B_NODE_EXEC, "Y2:",
- butr->xmin+dx, dy, dx, elementheight,
- &ntxy->y2, xymin, xymax, 0, 0, "");
-
- uiBlockEndAlign(block);
- }
- return 60;
+ uiItemR(layout, "", 0, ptr, "axis", 0);
}
-static int node_composit_buts_splitviewer(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBlockBeginAlign(block);
-
- uiDefButS(block, ROW, B_NODE_EXEC, "X",
- butr->xmin, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20,
- &node->custom2, 0.0, 0.0, 0, 0, "");
- uiDefButS(block, ROW, B_NODE_EXEC, "Y",
- butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20,
- &node->custom2, 0.0, 1.0, 0, 0, "");
-
- uiDefButS(block, NUMSLI, B_NODE_EXEC, "Split %: ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 100, 10, 0, "");
- }
- return 40;
-}
-
-static int node_composit_buts_map_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- TexMapping *texmap= node->storage;
- short xstart= (short)butr->xmin;
- short dy= (short)(butr->ymax-19.0f);
- short dx= (short)(butr->xmax-butr->xmin)/2;
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NODE_EXEC, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, "");
- dy-= 19;
- uiDefButF(block, NUM, B_NODE_EXEC, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, "");
- dy-= 23;
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
- dy-= 19;
- uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
- uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->max, -1000.0f, 1000.0f, 10, 2, "");
- }
- return 80;
+ uiLayout *col;
+
+ uiItemR(layout, NULL, 0, ptr, "crop_size", 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, "Left", 0, ptr, "x1", 0);
+ uiItemR(col, "Right", 0, ptr, "x2", 0);
+ uiItemR(col, "Up", 0, ptr, "y1", 0);
+ uiItemR(col, "Down", 0, ptr, "y2", 0);
}
-static int node_composit_buts_alphaover(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeTwoFloats *ntf= node->storage;
-
- /* alpha type */
- uiDefButS(block, TOG, B_NODE_EXEC, "ConvertPremul",
- butr->xmin, butr->ymin+19, butr->xmax-butr->xmin, 19,
- &node->custom1, 0, 0, 0, 0, "");
- /* mix factor */
- uiDefButF(block, NUM, B_NODE_EXEC, "Premul: ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19,
- &ntf->x, 0.0f, 1.0f, 100, 0, "");
- }
- return 38;
+ uiLayout *row, *col;
+
+ col= uiLayoutColumn(layout, 0);
+ row= uiLayoutRow(col, 0);
+ uiItemR(row, NULL, 0, ptr, "axis", UI_ITEM_R_EXPAND);
+ uiItemR(col, NULL, 0, ptr, "factor", 0);
}
-static int node_composit_buts_hue_sat(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_map_value(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeHueSat *nhs= node->storage;
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Hue: ",
- butr->xmin, butr->ymin+40.0f, butr->xmax-butr->xmin, 20,
- &nhs->hue, 0.0f, 1.0f, 100, 0, "");
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Sat: ",
- butr->xmin, butr->ymin+20.0f, butr->xmax-butr->xmin, 20,
- &nhs->sat, 0.0f, 2.0f, 100, 0, "");
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Val: ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &nhs->val, 0.0f, 2.0f, 100, 0, "");
- }
- return 60;
+ uiLayout *sub, *col;
+
+ col =uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "offset", 0);
+ uiItemR(col, NULL, 0, ptr, "size", 0);
+
+ col =uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "use_min", 0);
+ sub =uiLayoutColumn(col, 0);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
+ uiItemR(sub, "", 0, ptr, "min", 0);
+
+ col =uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "use_max", 0);
+ sub =uiLayoutColumn(col, 0);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
+ uiItemR(sub, "", 0, ptr, "max", 0);
}
-static int node_composit_buts_dilateerode(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_alphaover(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *col;
+
+ col =uiLayoutColumn(layout, 1);
+ /* alpha type */
+ uiItemR(col, NULL, 0, ptr, "convert_premul", 0);
+ /* mix factor */
+ uiItemR(col, NULL, 0, ptr, "premul", 0);
+}
+
+static void node_composit_buts_hue_sat(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiDefButS(block, NUM, B_NODE_EXEC, "Distance:",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom2, -100, 100, 0, 0, "Distance to grow/shrink (number of iterations)");
- }
- return 20;
+ uiLayout *col;
+
+ col =uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "hue", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "sat", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "val", UI_ITEM_R_SLIDER);
}
-static int node_composit_buts_diff_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_dilateerode(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeChroma *c= node->storage;
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ",
- butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20,
- &c->t1, 0.0f, 1.0f, 100, 0, "Color differences below this threshold are keyed.");
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &c->t2, 0.0f, 1.0f, 100, 0, "Color differences below this additional threshold are partially keyed.");
- uiBlockEndAlign(block);
- }
- return 40;
+ uiItemR(layout, NULL, 0, ptr, "distance", 0);
}
-static int node_composit_buts_distance_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_diff_matte(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeChroma *c= node->storage;
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ",
- butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20,
- &c->t1, 0.0f, 1.0f, 100, 0, "Color distances below this threshold are keyed.");
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &c->t2, 0.0f, 1.0f, 100, 0, "Color distances below this additional threshold are partially keyed.");
- uiBlockEndAlign(block);
- }
- return 40;
+ uiLayout *col;
+
+ col =uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "tolerance", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "falloff", UI_ITEM_R_SLIDER);
}
-static int node_composit_buts_color_spill(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_distance_matte(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- short dx= (butr->xmax-butr->xmin)/3;
+ uiLayout *col;
+
+ col =uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "tolerance", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "falloff", UI_ITEM_R_SLIDER);
+}
- NodeChroma *c=node->storage;
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NODE_EXEC, "Enhance: ",
- butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20,
- &c->t1, 0.0f, 0.5f, 100, 2, "Adjusts how much selected channel is affected by color spill algorithm");
- uiDefButS(block, ROW, B_NODE_EXEC, "R",
- butr->xmin,butr->ymin,dx,20,
- &node->custom1,1,1, 0, 0, "Red Spill Suppression");
- uiDefButS(block, ROW, B_NODE_EXEC, "G",
- butr->xmin+dx,butr->ymin,dx,20,
- &node->custom1,1,2, 0, 0, "Green Spill Suppression");
- uiDefButS(block, ROW, B_NODE_EXEC, "B",
- butr->xmin+2*dx,butr->ymin,dx,20,
- &node->custom1, 1, 3, 0, 0, "Blue Spill Suppression");
- uiBlockEndAlign(block);
- }
- return 60;
+static void node_composit_buts_color_spill(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *row, *col;
+
+ col =uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "factor", 0);
+ row= uiLayoutRow(col, 0);
+ uiItemR(row, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND);
}
-static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_chroma_matte(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- short dx=(butr->xmax-butr->xmin)/2;
- NodeChroma *c= node->storage;
- uiBlockBeginAlign(block);
+ uiLayout *col;
+
+ col= uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "acceptance", 0);
+ uiItemR(col, NULL, 0, ptr, "cutoff", 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "lift", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "gain", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "shadow_adjust", UI_ITEM_R_SLIDER);
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ",
- butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20,
- &c->t1, 1.0f, 80.0f, 100, 0, "Tolerance for colors to be considered a keying color");
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Cutoff ",
- butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20,
- &c->t2, 0.0f, 30.0f, 100, 0, "Colors below this will be considered as exact matches for keying color");
-
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Lift ",
- butr->xmin, butr->ymin+20, dx, 20,
- &c->fsize, 0.0f, 1.0f, 100, 0, "Alpha Lift");
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Gain ",
- butr->xmin+dx, butr->ymin+20, dx, 20,
- &c->fstrength, 0.0f, 1.0f, 100, 0, "Alpha Gain");
-
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured");
- uiBlockEndAlign(block);
+// uiBlock *block= uiLayoutFreeBlock(layout);
+// bNode *node= ptr->data;
+// rctf *butr= &node->butr;
+// short dx=(butr->xmax-butr->xmin)/2;
+// NodeChroma *c= node->storage;
- if(c->t2 > c->t1)
- c->t2=c->t1;
- }
- return 80;
+// uiBlockBeginAlign(block);
+//
+// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ", butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20, &c->t1, 1.0f, 80.0f, 100, 0, "Tolerance for colors to be considered a keying color");
+// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Cutoff ", butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, &c->t2, 0.0f, 30.0f, 100, 0, "Colors below this will be considered as exact matches for keying color");
+//
+// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Lift ", butr->xmin, butr->ymin+20, dx, 20, &c->fsize, 0.0f, 1.0f, 100, 0, "Alpha Lift");
+// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Gain ", butr->xmin+dx, butr->ymin+20, dx, 20, &c->fstrength, 0.0f, 1.0f, 100, 0, "Alpha Gain");
+//
+// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured");
+// uiBlockEndAlign(block);
+//
+// if(c->t2 > c->t1)
+// c->t2=c->t1;
}
-static int node_composit_buts_color_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_color_matte(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeChroma *c= node->storage;
- uiBlockBeginAlign(block);
-
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "H: ",
- butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20,
- &c->t1, 0.0f, 0.25f, 100, 0, "Hue tolerance for colors to be considered a keying color");
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "S: ",
- butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20,
- &c->t2, 0.0f, 1.0f, 100, 0, "Saturation Tolerance for the color");
- uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "V: ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &c->t3, 0.0f, 1.0f, 100, 0, "Value Tolerance for the color");
-
- uiBlockEndAlign(block);
- }
- return 60;
+ uiLayout *col;
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, NULL, 0, ptr, "h", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "s", UI_ITEM_R_SLIDER);
+ uiItemR(col, NULL, 0, ptr, "v", UI_ITEM_R_SLIDER);
}
-
-static int node_composit_buts_channel_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_channel_matte(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- short sx= (butr->xmax-butr->xmin)/4;
- short cx= (butr->xmax-butr->xmin)/3;
- NodeChroma *c=node->storage;
- char *c1, *c2, *c3;
-
- /*color space selectors*/
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW,B_NODE_EXEC,"RGB",
- butr->xmin,butr->ymin+60,sx,20,&node->custom1,1,1, 0, 0, "RGB Color Space");
- uiDefButS(block, ROW,B_NODE_EXEC,"HSV",
- butr->xmin+sx,butr->ymin+60,sx,20,&node->custom1,1,2, 0, 0, "HSV Color Space");
- uiDefButS(block, ROW,B_NODE_EXEC,"YUV",
- butr->xmin+2*sx,butr->ymin+60,sx,20,&node->custom1,1,3, 0, 0, "YUV Color Space");
- uiDefButS(block, ROW,B_NODE_EXEC,"YCC",
- butr->xmin+3*sx,butr->ymin+60,sx,20,&node->custom1,1,4, 0, 0, "YCbCr Color Space");
-
- if (node->custom1==1) {
- c1="R"; c2="G"; c3="B";
- }
- else if(node->custom1==2){
- c1="H"; c2="S"; c3="V";
- }
- else if(node->custom1==3){
- c1="Y"; c2="U"; c3="V";
- }
- else { // if(node->custom1==4){
- c1="Y"; c2="Cb"; c3="Cr";
- }
-
- /*channel selector */
- uiDefButS(block, ROW, B_NODE_EXEC, c1,
- butr->xmin,butr->ymin+40,cx,20,&node->custom2,1, 1, 0, 0, "Channel 1");
- uiDefButS(block, ROW, B_NODE_EXEC, c2,
- butr->xmin+cx,butr->ymin+40,cx,20,&node->custom2,1, 2, 0, 0, "Channel 2");
- uiDefButS(block, ROW, B_NODE_EXEC, c3,
- butr->xmin+cx+cx,butr->ymin+40,cx,20,&node->custom2, 1, 3, 0, 0, "Channel 3");
-
- /*tolerance sliders */
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ",
- butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20,
- &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque");
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed");
- uiBlockEndAlign(block);
-
- /*keep t2 (low) less than t1 (high) */
- if(c->t2 > c->t1) {
- c->t2=c->t1;
- }
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ short sx= (butr->xmax-butr->xmin)/4;
+ short cx= (butr->xmax-butr->xmin)/3;
+ NodeChroma *c=node->storage;
+ char *c1, *c2, *c3;
+
+ /*color space selectors*/
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW,B_NODE_EXEC,"RGB",
+ butr->xmin,butr->ymin+60,sx,20,&node->custom1,1,1, 0, 0, "RGB Color Space");
+ uiDefButS(block, ROW,B_NODE_EXEC,"HSV",
+ butr->xmin+sx,butr->ymin+60,sx,20,&node->custom1,1,2, 0, 0, "HSV Color Space");
+ uiDefButS(block, ROW,B_NODE_EXEC,"YUV",
+ butr->xmin+2*sx,butr->ymin+60,sx,20,&node->custom1,1,3, 0, 0, "YUV Color Space");
+ uiDefButS(block, ROW,B_NODE_EXEC,"YCC",
+ butr->xmin+3*sx,butr->ymin+60,sx,20,&node->custom1,1,4, 0, 0, "YCbCr Color Space");
+
+ if (node->custom1==1) {
+ c1="R"; c2="G"; c3="B";
+ }
+ else if(node->custom1==2){
+ c1="H"; c2="S"; c3="V";
+ }
+ else if(node->custom1==3){
+ c1="Y"; c2="U"; c3="V";
+ }
+ else { // if(node->custom1==4){
+ c1="Y"; c2="Cb"; c3="Cr";
+ }
+
+ /*channel selector */
+ uiDefButS(block, ROW, B_NODE_EXEC, c1,
+ butr->xmin,butr->ymin+40,cx,20,&node->custom2,1, 1, 0, 0, "Channel 1");
+ uiDefButS(block, ROW, B_NODE_EXEC, c2,
+ butr->xmin+cx,butr->ymin+40,cx,20,&node->custom2,1, 2, 0, 0, "Channel 2");
+ uiDefButS(block, ROW, B_NODE_EXEC, c3,
+ butr->xmin+cx+cx,butr->ymin+40,cx,20,&node->custom2, 1, 3, 0, 0, "Channel 3");
+
+ /*tolerance sliders */
+ uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ",
+ butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20,
+ &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque");
+ uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ",
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+ &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed");
+ uiBlockEndAlign(block);
+
+ /*keep t2 (low) less than t1 (high) */
+ if(c->t2 > c->t1) {
+ c->t2=c->t1;
}
- return 80;
}
-static int node_composit_buts_luma_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_luma_matte(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeChroma *c=node->storage;
-
- /*tolerance sliders */
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ",
- butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20,
- &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque");
- uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed");
- uiBlockEndAlign(block);
-
- /*keep t2 (low) less than t1 (high) */
- if(c->t2 > c->t1) {
- c->t2=c->t1;
- }
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ NodeChroma *c=node->storage;
+
+ /*tolerance sliders */
+ uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ",
+ butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20,
+ &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque");
+ uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ",
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+ &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed");
+ uiBlockEndAlign(block);
+
+ /*keep t2 (low) less than t1 (high) */
+ if(c->t2 > c->t1) {
+ c->t2=c->t1;
}
- return 40;
}
-static int node_composit_buts_map_uv(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_map_uv(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiDefButS(block, NUM, B_NODE_EXEC, "Alpha:",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 100, 0, 0, "Conversion percentage of UV differences to Alpha");
- }
- return 20;
+ uiItemR(layout, NULL, 0, ptr, "alpha", 0);
}
-static int node_composit_buts_id_mask(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_id_mask(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiDefButS(block, NUM, B_NODE_EXEC, "ID:",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 10000, 0, 0, "Pass Index number to convert to Alpha");
- }
- return 20;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+
+ uiDefButS(block, NUM, B_NODE_EXEC, "ID:",
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+ &node->custom1, 0, 10000, 0, 0, "Pass Index number to convert to Alpha");
}
/* allocate sufficient! */
@@ -1880,58 +1551,58 @@ static void node_set_image_cb(bContext *C, void *ntree_v, void *node_v)
nodeSetActive(ntree, node);
}
-static int node_composit_buts_file_output(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_file_output(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- NodeImageFile *nif= node->storage;
- uiBut *bt;
- short x= (short)butr->xmin;
- short y= (short)butr->ymin;
- short w= (short)butr->xmax-butr->xmin;
- char str[320];
-
- node_imagetype_string(str);
-
- uiBlockBeginAlign(block);
-
- bt = uiDefIconBut(block, BUT, B_NODE_SETIMAGE, ICON_FILESEL,
- x, y+60, 20, 20,
- 0, 0, 0, 0, 0, "Open Fileselect to get Backbuf image");
- uiButSetFunc(bt, node_set_image_cb, ntree, node);
-
- uiDefBut(block, TEX, B_NOP, "",
- 20+x, y+60, w-20, 20,
- nif->name, 0.0f, 240.0f, 0, 0, "");
-
- uiDefButS(block, MENU, B_NOP, str,
- x, y+40, w, 20,
- &nif->imtype, 0.0f, 1.0f, 0, 0, "");
-
- if(nif->imtype==R_OPENEXR) {
- uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_REDR, "Half",
- x, y+20, w/2, 20,
- &nif->subimtype, 0, 0, 0, 0, "");
-
- uiDefButS(block, MENU,B_NOP, "Codec %t|None %x0|Pxr24 (lossy) %x1|ZIP (lossless) %x2|PIZ (lossless) %x3|RLE (lossless) %x4",
- x+w/2, y+20, w/2, 20,
- &nif->codec, 0, 0, 0, 0, "");
- }
- else {
- uiDefButS(block, NUM, B_NOP, "Quality: ",
- x, y+20, w, 20,
- &nif->quality, 10.0f, 100.0f, 10, 0, "");
- }
-
- /* start frame, end frame */
- uiDefButI(block, NUM, B_NODE_EXEC, "SFra: ",
- x, y, w/2, 20,
- &nif->sfra, 1, MAXFRAMEF, 10, 0, "");
- uiDefButI(block, NUM, B_NODE_EXEC, "EFra: ",
- x+w/2, y, w/2, 20,
- &nif->efra, 1, MAXFRAMEF, 10, 0, "");
-
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
+ NodeImageFile *nif= node->storage;
+ uiBut *bt;
+ short x= (short)butr->xmin;
+ short y= (short)butr->ymin;
+ short w= (short)butr->xmax-butr->xmin;
+ char str[320];
+
+ node_imagetype_string(str);
+
+ uiBlockBeginAlign(block);
+
+ bt = uiDefIconBut(block, BUT, B_NODE_SETIMAGE, ICON_FILESEL,
+ x, y+60, 20, 20,
+ 0, 0, 0, 0, 0, "Open Fileselect to get Backbuf image");
+ uiButSetFunc(bt, node_set_image_cb, ntree, node);
+
+ uiDefBut(block, TEX, B_NOP, "",
+ 20+x, y+60, w-20, 20,
+ nif->name, 0.0f, 240.0f, 0, 0, "");
+
+ uiDefButS(block, MENU, B_NOP, str,
+ x, y+40, w, 20,
+ &nif->imtype, 0.0f, 1.0f, 0, 0, "");
+
+ if(nif->imtype==R_OPENEXR) {
+ uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_REDR, "Half",
+ x, y+20, w/2, 20,
+ &nif->subimtype, 0, 0, 0, 0, "");
+
+ uiDefButS(block, MENU,B_NOP, "Codec %t|None %x0|Pxr24 (lossy) %x1|ZIP (lossless) %x2|PIZ (lossless) %x3|RLE (lossless) %x4",
+ x+w/2, y+20, w/2, 20,
+ &nif->codec, 0, 0, 0, 0, "");
}
- return 80;
+ else {
+ uiDefButS(block, NUM, B_NOP, "Quality: ",
+ x, y+20, w, 20,
+ &nif->quality, 10.0f, 100.0f, 10, 0, "");
+ }
+
+ /* start frame, end frame */
+ uiDefButI(block, NUM, B_NODE_EXEC, "SFra: ",
+ x, y, w/2, 20,
+ &nif->sfra, 1, MAXFRAMEF, 10, 0, "");
+ uiDefButI(block, NUM, B_NODE_EXEC, "EFra: ",
+ x+w/2, y, w/2, 20,
+ &nif->efra, 1, MAXFRAMEF, 10, 0, "");
}
static void node_scale_cb(bContext *C, void *node_v, void *unused_v)
@@ -1952,68 +1623,36 @@ static void node_scale_cb(bContext *C, void *node_v, void *unused_v)
}
}
-static int node_composit_buts_scale(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_scale(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt= uiDefButS(block, MENU, B_NODE_EXEC, "Relative %x0|Absolute %x1|Scene Size % %x2|",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 0, 0, 0, "Scale new image to absolute pixel size, size relative to the incoming image, or using the 'percent' size of the scene");
- uiButSetFunc(bt, node_scale_cb, node, NULL);
- }
- return 20;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ uiBut *bt= uiDefButS(block, MENU, B_NODE_EXEC, "Relative %x0|Absolute %x1|Scene Size % %x2|",
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+ &node->custom1, 0, 0, 0, 0, "Scale new image to absolute pixel size, size relative to the incoming image, or using the 'percent' size of the scene");
+ uiButSetFunc(bt, node_scale_cb, node, NULL);
}
-static int node_composit_buts_invert(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_invert(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, CMP_CHAN_RGB, B_NODE_EXEC, "RGB",
- butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 20,
- &node->custom1, 0, 0, 0, 0, "");
- uiDefButBitS(block, TOG, CMP_CHAN_A, B_NODE_EXEC, "A",
- butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 20,
- &node->custom1, 0, 0, 0, 0, "");
- uiBlockEndAlign(block);
- }
- return 20;
+ uiLayout *col;
+
+ col= uiLayoutColumn(layout, 0);
+ uiItemR(col, NULL, 0, ptr, "rgb", 0);
+ uiItemR(col, NULL, 0, ptr, "alpha", 0);
}
-static int node_composit_buts_premulkey(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_premulkey(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- uiBut *bt;
-
- /* blend type */
- bt=uiDefButS(block, MENU, B_NODE_EXEC, "Key to Premul %x0|Premul to Key %x1",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 0, 0, 0, "Conversion between premultiplied alpha and key alpha");
- }
- return 20;
+ uiItemR(layout, "", 0, ptr, "mapping", 0);
}
-static int node_composit_buts_view_levels(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_composit_buts_view_levels(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- short sx= (butr->xmax-butr->xmin)/5;
-
- /*color space selectors*/
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"C",
- butr->xmin,butr->ymin,sx,20,&node->custom1,1,1, 0, 0, "Combined RGB");
- uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"R",
- butr->xmin+sx,butr->ymin,sx,20,&node->custom1,1,2, 0, 0, "Red Channel");
- uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"G",
- butr->xmin+2*sx,butr->ymin,sx,20,&node->custom1,1,3, 0, 0, "Green Channel");
- uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"B",
- butr->xmin+3*sx,butr->ymin,sx,20,&node->custom1,1,4, 0, 0, "Blue Channel");
- uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"L",
- butr->xmin+4*sx,butr->ymin,sx,20,&node->custom1,1,5, 0, 0, "Luminenc Channel");
- uiBlockEndAlign(block);
- }
- return 20;
+ uiItemR(layout, NULL, 0, ptr, "color_space", UI_ITEM_R_EXPAND);
}
-
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2021,181 +1660,181 @@ static void node_composit_set_butfunc(bNodeType *ntype)
/* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */
case CMP_NODE_IMAGE:
- ntype->butfunc= node_composit_buts_image;
+ ntype->uifunc= node_composit_buts_image;
break;
case CMP_NODE_R_LAYERS:
- ntype->butfunc= node_composit_buts_renderlayers;
+ ntype->uifunc= node_composit_buts_renderlayers;
break;
case CMP_NODE_NORMAL:
- ntype->butfunc= node_buts_normal;
+ ntype->uifunc= node_buts_normal;
break;
case CMP_NODE_CURVE_VEC:
- ntype->butfunc= node_buts_curvevec;
+ ntype->uifunc= node_buts_curvevec;
break;
case CMP_NODE_CURVE_RGB:
- ntype->butfunc= node_buts_curvecol;
+ ntype->uifunc= node_buts_curvecol;
break;
case CMP_NODE_VALUE:
- ntype->butfunc= node_buts_value;
+ ntype->uifunc= node_buts_value;
break;
case CMP_NODE_RGB:
- ntype->butfunc= node_buts_rgb;
+ ntype->uifunc= node_buts_rgb;
break;
case CMP_NODE_FLIP:
- ntype->butfunc= node_composit_buts_flip;
+ ntype->uifunc= node_composit_buts_flip;
break;
case CMP_NODE_SPLITVIEWER:
- ntype->butfunc= node_composit_buts_splitviewer;
+ ntype->uifunc= node_composit_buts_splitviewer;
break;
case CMP_NODE_MIX_RGB:
- ntype->butfunc= node_buts_mix_rgb;
+ ntype->uifunc= node_buts_mix_rgb;
break;
case CMP_NODE_VALTORGB:
- ntype->butfunc= node_buts_valtorgb;
+ ntype->uifunc= node_buts_valtorgb;
break;
case CMP_NODE_CROP:
- ntype->butfunc= node_composit_buts_crop;
+ ntype->uifunc= node_composit_buts_crop;
break;
case CMP_NODE_BLUR:
- ntype->butfunc= node_composit_buts_blur;
+ ntype->uifunc= node_composit_buts_blur;
break;
case CMP_NODE_DBLUR:
- ntype->butfunc= node_composit_buts_dblur;
+ ntype->uifunc= node_composit_buts_dblur;
break;
case CMP_NODE_BILATERALBLUR:
- ntype->butfunc= node_composit_buts_bilateralblur;
+ ntype->uifunc= node_composit_buts_bilateralblur;
break;
/* qdn: defocus node */
case CMP_NODE_DEFOCUS:
- ntype->butfunc = node_composit_buts_defocus;
+ ntype->uifunc = node_composit_buts_defocus;
break;
/* qdn: glare node */
case CMP_NODE_GLARE:
- ntype->butfunc = node_composit_buts_glare;
+ ntype->uifunc = node_composit_buts_glare;
break;
/* qdn: tonemap node */
case CMP_NODE_TONEMAP:
- ntype->butfunc = node_composit_buts_tonemap;
+ ntype->uifunc = node_composit_buts_tonemap;
break;
/* qdn: lens distortion node */
case CMP_NODE_LENSDIST:
- ntype->butfunc = node_composit_buts_lensdist;
+ ntype->uifunc = node_composit_buts_lensdist;
break;
case CMP_NODE_VECBLUR:
- ntype->butfunc= node_composit_buts_vecblur;
+ ntype->uifunc= node_composit_buts_vecblur;
break;
case CMP_NODE_FILTER:
- ntype->butfunc= node_composit_buts_filter;
+ ntype->uifunc= node_composit_buts_filter;
break;
case CMP_NODE_MAP_VALUE:
- ntype->butfunc= node_composit_buts_map_value;
+ ntype->uifunc= node_composit_buts_map_value;
break;
case CMP_NODE_TIME:
- ntype->butfunc= node_buts_time;
+ ntype->uifunc= node_buts_time;
break;
case CMP_NODE_ALPHAOVER:
- ntype->butfunc= node_composit_buts_alphaover;
+ ntype->uifunc= node_composit_buts_alphaover;
break;
case CMP_NODE_HUE_SAT:
- ntype->butfunc= node_composit_buts_hue_sat;
+ ntype->uifunc= node_composit_buts_hue_sat;
break;
case CMP_NODE_TEXTURE:
- ntype->butfunc= node_buts_texture;
+ ntype->uifunc= node_buts_texture;
break;
case CMP_NODE_DILATEERODE:
- ntype->butfunc= node_composit_buts_dilateerode;
+ ntype->uifunc= node_composit_buts_dilateerode;
break;
case CMP_NODE_OUTPUT_FILE:
- ntype->butfunc= node_composit_buts_file_output;
+ ntype->uifunc= node_composit_buts_file_output;
break;
case CMP_NODE_DIFF_MATTE:
- ntype->butfunc=node_composit_buts_diff_matte;
+ ntype->uifunc=node_composit_buts_diff_matte;
break;
case CMP_NODE_DIST_MATTE:
- ntype->butfunc=node_composit_buts_distance_matte;
+ ntype->uifunc=node_composit_buts_distance_matte;
break;
case CMP_NODE_COLOR_SPILL:
- ntype->butfunc=node_composit_buts_color_spill;
+ ntype->uifunc=node_composit_buts_color_spill;
break;
case CMP_NODE_CHROMA_MATTE:
- ntype->butfunc=node_composit_buts_chroma_matte;
+ ntype->uifunc=node_composit_buts_chroma_matte;
break;
case CMP_NODE_COLOR_MATTE:
- ntype->butfunc=node_composit_buts_color_matte;
+ ntype->uifunc=node_composit_buts_color_matte;
break;
case CMP_NODE_SCALE:
- ntype->butfunc= node_composit_buts_scale;
+ ntype->uifunc= node_composit_buts_scale;
break;
case CMP_NODE_CHANNEL_MATTE:
- ntype->butfunc= node_composit_buts_channel_matte;
+ ntype->uifunc= node_composit_buts_channel_matte;
break;
case CMP_NODE_LUMA_MATTE:
- ntype->butfunc= node_composit_buts_luma_matte;
+ ntype->uifunc= node_composit_buts_luma_matte;
break;
case CMP_NODE_MAP_UV:
- ntype->butfunc= node_composit_buts_map_uv;
+ ntype->uifunc= node_composit_buts_map_uv;
break;
case CMP_NODE_ID_MASK:
- ntype->butfunc= node_composit_buts_id_mask;
+ ntype->uifunc= node_composit_buts_id_mask;
break;
case CMP_NODE_MATH:
- ntype->butfunc= node_buts_math;
+ ntype->uifunc= node_buts_math;
break;
case CMP_NODE_INVERT:
- ntype->butfunc= node_composit_buts_invert;
+ ntype->uifunc= node_composit_buts_invert;
break;
case CMP_NODE_PREMULKEY:
- ntype->butfunc= node_composit_buts_premulkey;
+ ntype->uifunc= node_composit_buts_premulkey;
break;
case CMP_NODE_VIEW_LEVELS:
- ntype->butfunc=node_composit_buts_view_levels;
+ ntype->uifunc=node_composit_buts_view_levels;
break;
default:
- ntype->butfunc= NULL;
+ ntype->uifunc= NULL;
}
}
/* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
-static int node_texture_buts_bricks(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_texture_buts_bricks(uiLayout *layout, PointerRNA *ptr)
{
- if(block) {
- short w = butr->xmax-butr->xmin;
- short ofw = 32;
-
- uiBlockBeginAlign(block);
-
- /* Offset */
- uiDefButF(
- block, NUM, B_NODE_EXEC, "Offset",
- butr->xmin, butr->ymin+20, w-ofw, 20,
- &node->custom3,
- 0, 1, 0.25, 2,
- "Offset amount" );
- uiDefButS(
- block, NUM, B_NODE_EXEC, "",
- butr->xmin+w-ofw, butr->ymin+20, ofw, 20,
- &node->custom1,
- 2, 99, 0, 0,
- "Offset every N rows" );
-
- /* Squash */
- uiDefButF(
- block, NUM, B_NODE_EXEC, "Squash",
- butr->xmin, butr->ymin+0, w-ofw, 20,
- &node->custom4,
- 0, 99, 0.25, 2,
- "Stretch amount" );
- uiDefButS(
- block, NUM, B_NODE_EXEC, "",
- butr->xmin+w-ofw, butr->ymin+0, ofw, 20,
- &node->custom2,
- 2, 99, 0, 0,
- "Stretch every N rows" );
-
- uiBlockEndAlign(block);
- }
- return 40;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ short w = butr->xmax-butr->xmin;
+ short ofw = 32;
+
+ uiBlockBeginAlign(block);
+
+ /* Offset */
+ uiDefButF(
+ block, NUM, B_NODE_EXEC, "Offset",
+ butr->xmin, butr->ymin+20, w-ofw, 20,
+ &node->custom3,
+ 0, 1, 0.25, 2,
+ "Offset amount" );
+ uiDefButS(
+ block, NUM, B_NODE_EXEC, "",
+ butr->xmin+w-ofw, butr->ymin+20, ofw, 20,
+ &node->custom1,
+ 2, 99, 0, 0,
+ "Offset every N rows" );
+
+ /* Squash */
+ uiDefButF(
+ block, NUM, B_NODE_EXEC, "Squash",
+ butr->xmin, butr->ymin+0, w-ofw, 20,
+ &node->custom4,
+ 0, 99, 0.25, 2,
+ "Stretch amount" );
+ uiDefButS(
+ block, NUM, B_NODE_EXEC, "",
+ butr->xmin+w-ofw, butr->ymin+0, ofw, 20,
+ &node->custom2,
+ 2, 99, 0, 0,
+ "Stretch every N rows" );
+
+ uiBlockEndAlign(block);
}
/* Copied from buttons_shading.c -- needs unifying */
@@ -2206,208 +1845,196 @@ static char* noisebasis_menu()
return nbmenu;
}
-static int node_texture_buts_proc(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_texture_buts_proc(uiLayout *layout, PointerRNA *ptr)
{
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
Tex *tex = (Tex *)node->storage;
short x,y,w,h;
- if( block ) {
- x = butr->xmin;
- y = butr->ymin;
- w = butr->xmax - x;
- h = butr->ymax - y;
- }
- else
- return 0;
+ x = butr->xmin;
+ y = butr->ymin;
+ w = butr->xmax - x;
+ h = butr->ymax - y;
switch( tex->type ) {
case TEX_BLEND:
- if( block ) {
- uiBlockBeginAlign( block );
- uiDefButS( block, MENU, B_NODE_EXEC,
- "Linear %x0|Quad %x1|Ease %x2|Diag %x3|Sphere %x4|Halo %x5|Radial %x6",
- x, y+20, w, 20, &tex->stype, 0, 1, 0, 0, "Blend Type" );
- uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_NODE_EXEC, "Flip XY", x, y, w, 20,
- &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees");
- uiBlockEndAlign( block );
- }
- return 40;
-
+ uiBlockBeginAlign( block );
+ uiDefButS( block, MENU, B_NODE_EXEC,
+ "Linear %x0|Quad %x1|Ease %x2|Diag %x3|Sphere %x4|Halo %x5|Radial %x6",
+ x, y+20, w, 20, &tex->stype, 0, 1, 0, 0, "Blend Type" );
+ uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_NODE_EXEC, "Flip XY", x, y, w, 20,
+ &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees");
+ uiBlockEndAlign( block );
+ break;
case TEX_MARBLE:
- if( block ) {
- uiBlockBeginAlign(block);
+ uiBlockBeginAlign(block);
+
+ uiDefButS(block, ROW, B_NODE_EXEC, "Soft", 0*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Sharp", 1*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Sharper", 2*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble");
- uiDefButS(block, ROW, B_NODE_EXEC, "Soft", 0*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble");
- uiDefButS(block, ROW, B_NODE_EXEC, "Sharp", 1*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble");
- uiDefButS(block, ROW, B_NODE_EXEC, "Sharper", 2*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble");
-
- uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
-
- uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands.");
- uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands");
- uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands");
-
- uiBlockEndAlign(block);
- }
- return 60;
+ uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
+
+ uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands.");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands");
+
+ uiBlockEndAlign(block);
+ break;
case TEX_WOOD:
- if( block ) {
- uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+64, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
-
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "Bands", x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Uses standard noise");
- uiDefButS(block, ROW, B_TEXPRV, "Rings", w/2+x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Lets Noise return RGB value");
-
- uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands.");
- uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands");
- uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands");
-
- uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
- uiBlockEndAlign(block);
- }
- return 80;
+ uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+64, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_TEXPRV, "Bands", x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Uses standard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Rings", w/2+x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Lets Noise return RGB value");
+
+ uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands.");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands");
+
+ uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
+ uiBlockEndAlign(block);
+ break;
case TEX_CLOUDS:
- if( block ) {
- uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+60, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
-
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "B/W", x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise");
- uiDefButS(block, ROW, B_TEXPRV, "Color", w/2+x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value");
- uiDefButS(block, ROW, B_TEXPRV, "Soft", x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_TEXPRV, "Hard", w/2+x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
- uiBlockEndAlign(block);
-
- uiDefButS(block, NUM, B_TEXPRV, "Depth:", x, y, w, 18, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation");
- }
- return 80;
+ uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+60, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_TEXPRV, "B/W", x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Color", w/2+x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value");
+ uiDefButS(block, ROW, B_TEXPRV, "Soft", x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Hard", w/2+x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
+ uiBlockEndAlign(block);
+
+ uiDefButS(block, NUM, B_TEXPRV, "Depth:", x, y, w, 18, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation");
+ break;
case TEX_DISTNOISE:
- if( block ) {
- uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+18, w, 18, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort");
- uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion");
- uiBlockEndAlign(block);
- }
- return 36;
+ uiBlockBeginAlign(block);
+ uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+18, w, 18, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort");
+ uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion");
+ uiBlockEndAlign(block);
+ break;
}
- return 0;
}
-static int node_texture_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_texture_buts_image(uiLayout *layout, PointerRNA *ptr)
{
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ bNodeTree *ntree= ptr->id.data;
+ rctf *butr= &node->butr;
char *strp;
uiBut *bt;
+
+ uiBlockBeginAlign(block);
- if( block ) {
- uiBlockBeginAlign(block);
-
- /* browse button */
- IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
- node->menunr= 0;
- bt= uiDefButS(block, MENU, B_NOP, strp,
- butr->xmin, butr->ymin, 19, 19,
- &node->menunr, 0, 0, 0, 0, "Browses existing choices");
- uiButSetFunc(bt, node_browse_image_cb, ntree, node);
- if(strp) MEM_freeN(strp);
+ /* browse button */
+ IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
+ node->menunr= 0;
+ bt= uiDefButS(block, MENU, B_NOP, strp,
+ butr->xmin, butr->ymin, 19, 19,
+ &node->menunr, 0, 0, 0, 0, "Browses existing choices");
+ uiButSetFunc(bt, node_browse_image_cb, ntree, node);
+ if(strp) MEM_freeN(strp);
+
+ /* Add New button */
+ if(node->id==NULL) {
+ bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New",
+ butr->xmin+19, butr->ymin, (short)(butr->xmax-butr->xmin-19.0f), 19,
+ NULL, 0.0, 0.0, 0, 0, "Add new Image");
+ uiButSetFunc(bt, node_active_cb, ntree, node);
+ }
+ else {
+ /* name button */
+ short xmin= (short)butr->xmin, xmax= (short)butr->xmax;
+ short width= xmax - xmin - 19;
- /* Add New button */
- if(node->id==NULL) {
- bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New",
- butr->xmin+19, butr->ymin, (short)(butr->xmax-butr->xmin-19.0f), 19,
- NULL, 0.0, 0.0, 0, 0, "Add new Image");
- uiButSetFunc(bt, node_active_cb, ntree, node);
- }
- else {
- /* name button */
- short xmin= (short)butr->xmin, xmax= (short)butr->xmax;
- short width= xmax - xmin - 19;
-
- bt= uiDefBut(block, TEX, B_NOP, "IM:",
- xmin+19, butr->ymin, width, 19,
- node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
- uiButSetFunc(bt, node_ID_title_cb, node, NULL);
- }
+ bt= uiDefBut(block, TEX, B_NOP, "IM:",
+ xmin+19, butr->ymin, width, 19,
+ node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
+ uiButSetFunc(bt, node_ID_title_cb, node, NULL);
}
- return 20;
}
-static int node_texture_buts_output(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+static void node_texture_buts_output(uiLayout *layout, PointerRNA *ptr)
{
- if( block ) {
- uiBut *bt;
- short width;
- char *name = ((TexNodeOutput*)node->storage)->name;
-
- uiBlockBeginAlign(block);
-
- width = (short)(butr->xmax - butr->xmin);
-
- bt = uiDefBut(
- block, TEX, B_NOP,
- "Name:",
- butr->xmin, butr->ymin,
- width, 19,
- name, 0, 31,
- 0, 0,
- "Name this output"
- );
-
- uiBlockEndAlign(block);
- }
- return 19;
+ uiBlock *block= uiLayoutFreeBlock(layout);
+ bNode *node= ptr->data;
+ rctf *butr= &node->butr;
+ uiBut *bt;
+ short width;
+ char *name = ((TexNodeOutput*)node->storage)->name;
+
+ uiBlockBeginAlign(block);
+
+ width = (short)(butr->xmax - butr->xmin);
+
+ bt = uiDefBut(
+ block, TEX, B_NOP,
+ "Name:",
+ butr->xmin, butr->ymin,
+ width, 19,
+ name, 0, 31,
+ 0, 0,
+ "Name this output"
+ );
+
+ uiBlockEndAlign(block);
}
/* only once called */
static void node_texture_set_butfunc(bNodeType *ntype)
{
if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) {
- ntype->butfunc = node_texture_buts_proc;
+ ntype->uifunc = node_texture_buts_proc;
}
else switch(ntype->type) {
case TEX_NODE_MATH:
- ntype->butfunc = node_buts_math;
+ ntype->uifunc = node_buts_math;
break;
case TEX_NODE_MIX_RGB:
- ntype->butfunc = node_buts_mix_rgb;
+ ntype->uifunc = node_buts_mix_rgb;
break;
case TEX_NODE_VALTORGB:
- ntype->butfunc = node_buts_valtorgb;
+ ntype->uifunc = node_buts_valtorgb;
break;
case TEX_NODE_CURVE_RGB:
- ntype->butfunc= node_buts_curvecol;
+ ntype->uifunc= node_buts_curvecol;
break;
case TEX_NODE_CURVE_TIME:
- ntype->butfunc = node_buts_time;
+ ntype->uifunc = node_buts_time;
break;
case TEX_NODE_TEXTURE:
- ntype->butfunc = node_buts_texture;
+ ntype->uifunc = node_buts_texture;
break;
case TEX_NODE_BRICKS:
- ntype->butfunc = node_texture_buts_bricks;
+ ntype->uifunc = node_texture_buts_bricks;
break;
case TEX_NODE_IMAGE:
- ntype->butfunc = node_texture_buts_image;
+ ntype->uifunc = node_texture_buts_image;
break;
case TEX_NODE_OUTPUT:
- ntype->butfunc = node_texture_buts_output;
+ ntype->uifunc = node_texture_buts_output;
break;
default:
- ntype->butfunc= NULL;
+ ntype->uifunc= NULL;
}
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index f3df7a29c2e..3fc91fea914 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -48,8 +48,9 @@
#include "DNA_text_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
#include "MEM_guardedalloc.h"
#include "BKE_context.h"
@@ -81,6 +82,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "RNA_access.h"
+
#include "CMP_node.h"
#include "SHD_node.h"
@@ -91,6 +94,50 @@ extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
extern void ui_draw_tria_icon(float x, float y, float aspect, char dir);
+void ED_node_changed_update(bContext *C, bNode *node)
+{
+ SpaceNode *snode= CTX_wm_space_node(C);
+
+ if(!snode)
+ return;
+
+ if(snode->treetype==NTREE_SHADER) {
+ WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id);
+ }
+ else if(snode->treetype==NTREE_COMPOSIT) {
+ NodeTagChanged(snode->edittree, node);
+ /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */
+
+ /* not the best implementation of the world... but we need it to work now :) */
+ if(node->type==CMP_NODE_R_LAYERS && node->custom2) {
+ /* add event for this window (after render curarea can be changed) */
+ //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
+
+ //composite_node_render(snode, node);
+ //snode_handle_recalc(snode);
+
+ /* add another event, a render can go fullscreen and open new window */
+ //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
+ }
+ else {
+ node= node_tree_get_editgroup(snode->nodetree);
+ if(node)
+ NodeTagIDChanged(snode->nodetree, node->id);
+ }
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, CTX_data_scene(C));
+ }
+ else if(snode->treetype==NTREE_TEXTURE) {
+ WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id);
+ }
+
+}
+
+static void do_node_internal_buttons(bContext *C, void *node_v, int event)
+{
+ if(event==B_NODE_EXEC)
+ ED_node_changed_update(C, node_v);
+}
+
static void node_scaling_widget(int color_id, float aspect, float xmin, float ymin, float xmax, float ymax)
{
@@ -110,10 +157,14 @@ static void node_scaling_widget(int color_id, float aspect, float xmin, float ym
}
/* based on settings in node, sets drawing rect info. each redraw! */
-static void node_update(bNode *node)
+static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
{
+ uiLayout *layout;
+ PointerRNA ptr;
bNodeSocket *nsock;
float dy= node->locy;
+ int buty;
+ char str[32];
/* header */
dy-= NODE_DY;
@@ -121,7 +172,7 @@ static void node_update(bNode *node)
/* little bit space in top */
if(node->outputs.first)
dy-= NODE_DYS/2;
-
+
/* output sockets */
for(nsock= node->outputs.first; nsock; nsock= nsock->next) {
if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
@@ -130,13 +181,15 @@ static void node_update(bNode *node)
dy-= NODE_DY;
}
}
-
- node->prvr.xmin= node->butr.xmin= node->locx + NODE_DYS;
- node->prvr.xmax= node->butr.xmax= node->locx + node->width- NODE_DYS;
+
+ node->prvr.xmin= node->locx + NODE_DYS;
+ node->prvr.xmax= node->locx + node->width- NODE_DYS;
/* preview rect? */
if(node->flag & NODE_PREVIEW) {
/* only recalculate size when there's a preview actually, otherwise we use stored result */
+ BLI_lock_thread(LOCK_PREVIEW);
+
if(node->preview && node->preview->rect) {
float aspect= 1.0f;
@@ -172,20 +225,41 @@ static void node_update(bNode *node)
node->prvr.ymin= dy - oldh;
dy= node->prvr.ymin - NODE_DYS/2;
}
+
+ BLI_unlock_thread(LOCK_PREVIEW);
}
/* XXX ugly hack, typeinfo for group is generated */
if(node->type == NODE_GROUP)
- ; // XXX node->typeinfo->butfunc= node_buts_group;
+ ; // XXX node->typeinfo->uifunc= node_buts_group;
+
+ /* ui block */
+ sprintf(str, "node buttons %p", node);
+ node->block= uiBeginBlock(C, CTX_wm_region(C), str, UI_EMBOSS);
+ uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node);
/* buttons rect? */
- if((node->flag & NODE_OPTIONS) && node->typeinfo->butfunc) {
+ if((node->flag & NODE_OPTIONS) && node->typeinfo->uifunc) {
dy-= NODE_DYS/2;
- node->butr.ymax= dy;
- node->butr.ymin= dy - (float)node->typeinfo->butfunc(NULL, NULL, node, NULL);
- dy= node->butr.ymin - NODE_DYS/2;
+
+ /* 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.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,
+ node->locx+NODE_DYS, dy, node->butr.xmax, 20, U.uistyles.first);
+
+ node->typeinfo->uifunc(layout, &ptr);
+ uiBlockEndAlign(node->block);
+ uiBlockLayoutResolve(node->block, NULL, &buty);
+
+ dy= buty - NODE_DYS/2;
}
-
+
/* input sockets */
for(nsock= node->inputs.first; nsock; nsock= nsock->next) {
if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
@@ -198,7 +272,7 @@ static void node_update(bNode *node)
/* little bit space in end */
if(node->inputs.first || (node->flag & (NODE_OPTIONS|NODE_PREVIEW))==0 )
dy-= NODE_DYS/2;
-
+
node->totr.xmin= node->locx;
node->totr.xmax= node->locx + node->width;
node->totr.ymax= node->locy;
@@ -206,11 +280,12 @@ static void node_update(bNode *node)
}
/* based on settings in node, sets drawing rect info. each redraw! */
-static void node_update_hidden(bNode *node)
+static void node_update_hidden(const bContext *C, bNode *node)
{
bNodeSocket *nsock;
float rad, drad, hiddenrad= HIDDEN_RAD;
int totin=0, totout=0, tot;
+ char str[32];
/* calculate minimal radius */
for(nsock= node->inputs.first; nsock; nsock= nsock->next)
@@ -251,6 +326,11 @@ static void node_update_hidden(bNode *node)
rad+= drad;
}
}
+
+ /* ui block */
+ sprintf(str, "node buttons %p", node);
+ node->block= uiBeginBlock(C, CTX_wm_region(C), str, UI_EMBOSS);
+ uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node);
}
static int node_get_colorid(bNode *node)
@@ -275,7 +355,7 @@ static int node_get_colorid(bNode *node)
/* based on settings in node, sets drawing rect info. each redraw! */
/* note: this assumes only 1 group at a time is drawn (linked data) */
/* in node->totr the entire boundbox for the group is stored */
-static void node_update_group(bNode *gnode)
+static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode)
{
bNodeTree *ngroup= (bNodeTree *)gnode->id;
bNode *node;
@@ -288,9 +368,9 @@ static void node_update_group(bNode *gnode)
node->locx+= gnode->locx;
node->locy+= gnode->locy;
if(node->flag & NODE_HIDDEN)
- node_update_hidden(node);
+ node_update_hidden(C, node);
else
- node_update(node);
+ node_update(C, ntree, node);
node->locx-= gnode->locx;
node->locy-= gnode->locy;
}
@@ -492,6 +572,7 @@ static uiBlock *socket_vector_menu(bContext *C, ARegion *ar, void *socket_v)
}
block= uiBeginBlock(C, ar, "socket menu", UI_EMBOSS);
+ uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN);
/* use this for a fake extra empy space around the buttons */
uiDefBut(block, LABEL, 0, "", -4, -4, 188, 68, NULL, 0, 0, 0, 0, "");
@@ -575,61 +656,15 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
}
-static void do_node_internal_buttons(bContext *C, void *node_v, int event)
-{
- SpaceNode *snode= CTX_wm_space_node(C);
-
- if(event==B_NODE_EXEC) {
- if(snode->treetype==NTREE_SHADER) {
- WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id);
- }
- else if(snode->treetype==NTREE_COMPOSIT) {
- bNode *node= node_v;
-
- NodeTagChanged(snode->edittree, node);
- /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */
-
- /* not the best implementation of the world... but we need it to work now :) */
- if(node->type==CMP_NODE_R_LAYERS && node->custom2) {
- /* add event for this window (after render curarea can be changed) */
- //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
-
- //composite_node_render(snode, node);
- //snode_handle_recalc(snode);
-
- /* add another event, a render can go fullscreen and open new window */
- //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
- }
- else {
- node= snode_get_editgroup(snode);
- if(node)
- NodeTagIDChanged(snode->nodetree, node->id);
- }
- WM_event_add_notifier(C, NC_SCENE|ND_NODES, CTX_data_scene(C));
- }
- else if(snode->treetype==NTREE_TEXTURE) {
- WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id);
- }
- }
-
-}
-
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNode *node)
{
bNodeSocket *sock;
- uiBlock *block;
uiBut *bt;
rctf *rct= &node->totr;
float /*slen,*/ iconofs;
int /*ofs,*/ color_id= node_get_colorid(node);
char showname[128]; /* 128 used below */
View2D *v2d = &ar->v2d;
- char str[32];
-
- /* make unique block name, also used for handling blocks in editnode.c */
- sprintf(str, "node buttons %p", node);
- block= uiBeginBlock(C, ar, str, UI_EMBOSS);
- uiBlockSetHandleFunc(block, do_node_internal_buttons, node);
uiSetRoundBox(15-4);
ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
@@ -655,7 +690,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
icon_id= ICON_MATERIAL_DATA;
iconofs-= 18.0f;
glEnable(GL_BLEND);
- UI_icon_draw_aspect_blended(iconofs, rct->ymax-NODE_DY+2, icon_id, snode->aspect, -60);
+ UI_icon_draw_aspect(iconofs, rct->ymax-NODE_DY+2, icon_id, snode->aspect, 0.5f);
glDisable(GL_BLEND);
}
if(node->type == NODE_GROUP) {
@@ -663,21 +698,18 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
iconofs-= 18.0f;
glEnable(GL_BLEND);
if(node->id->lib) {
- glPixelTransferf(GL_GREEN_SCALE, 0.7f);
- glPixelTransferf(GL_BLUE_SCALE, 0.3f);
- UI_icon_draw_aspect(iconofs, rct->ymax-NODE_DY+2, ICON_NODE, snode->aspect);
- glPixelTransferf(GL_GREEN_SCALE, 1.0f);
- glPixelTransferf(GL_BLUE_SCALE, 1.0f);
+ float rgb[3] = {1.0f, 0.7f, 0.3f};
+ UI_icon_draw_aspect_color(iconofs, rct->ymax-NODE_DY+2, ICON_NODE, snode->aspect, rgb);
}
else {
- UI_icon_draw_aspect_blended(iconofs, rct->ymax-NODE_DY+2, ICON_NODE, snode->aspect, -60);
+ UI_icon_draw_aspect(iconofs, rct->ymax-NODE_DY+2, ICON_NODE, snode->aspect, 0.5f);
}
glDisable(GL_BLEND);
}
if(node->typeinfo->flag & NODE_OPTIONS) {
iconofs-= 18.0f;
glEnable(GL_BLEND);
- UI_icon_draw_aspect_blended(iconofs, rct->ymax-NODE_DY+2, ICON_BUTS, snode->aspect, -60);
+ UI_icon_draw_aspect(iconofs, rct->ymax-NODE_DY+2, ICON_BUTS, snode->aspect, 0.5f);
glDisable(GL_BLEND);
}
{ /* always hide/reveal unused sockets */
@@ -690,7 +722,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
else*/
shade= -90;
glEnable(GL_BLEND);
- UI_icon_draw_aspect_blended(iconofs, rct->ymax-NODE_DY+2, ICON_PLUS, snode->aspect, shade);
+ UI_icon_draw_aspect(iconofs, rct->ymax-NODE_DY+2, ICON_PLUS, snode->aspect, 0.5f);
glDisable(GL_BLEND);
}
@@ -715,7 +747,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
else
BLI_strncpy(showname, node->name, 128);
- uiDefBut(block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(rct->ymax-NODE_DY),
+ uiDefBut(node->block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(rct->ymax-NODE_DY),
(int)(iconofs - rct->xmin-18.0f), NODE_DY, NULL, 0, 0, 0, 0, "");
/* body */
@@ -743,7 +775,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* hurmf... another candidate for callback, have to see how this works first */
- if(node->id && block && snode->treetype==NTREE_SHADER)
+ if(node->id && node->block && snode->treetype==NTREE_SHADER)
nodeShaderSynchronizeID(node, 0);
/* socket inputs, buttons */
@@ -751,38 +783,38 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
socket_circle_draw(sock, NODE_SOCKSIZE);
- if(block && sock->link==NULL) {
+ if(node->block && sock->link==NULL) {
float *butpoin= sock->ns.vec;
if(sock->type==SOCK_VALUE) {
- bt= uiDefButF(block, NUM, B_NODE_EXEC, sock->name,
+ bt= uiDefButF(node->block, NUM, B_NODE_EXEC, sock->name,
(short)sock->locx+NODE_DYS, (short)(sock->locy)-9, (short)node->width-NODE_DY, 17,
butpoin, sock->ns.min, sock->ns.max, 10, 2, "");
uiButSetFunc(bt, node_sync_cb, snode, node);
}
else if(sock->type==SOCK_VECTOR) {
- uiDefBlockBut(block, socket_vector_menu, sock, sock->name,
+ uiDefBlockBut(node->block, socket_vector_menu, sock, sock->name,
(short)sock->locx+NODE_DYS, (short)sock->locy-9, (short)node->width-NODE_DY, 17,
"");
}
- else if(block && sock->type==SOCK_RGBA) {
+ else if(node->block && sock->type==SOCK_RGBA) {
short labelw= (short)node->width-NODE_DY-40, width;
if(labelw>0) width= 40; else width= (short)node->width-NODE_DY;
- bt= uiDefButF(block, COL, B_NODE_EXEC, "",
+ bt= uiDefButF(node->block, COL, B_NODE_EXEC, "",
(short)(sock->locx+NODE_DYS), (short)sock->locy-8, width, 15,
butpoin, 0, 0, 0, 0, "");
uiButSetFunc(bt, node_sync_cb, snode, node);
- if(labelw>0) uiDefBut(block, LABEL, 0, sock->name,
+ if(labelw>0) uiDefBut(node->block, LABEL, 0, sock->name,
(short)(sock->locx+NODE_DYS) + 40, (short)sock->locy-8, labelw, 15,
NULL, 0, 0, 0, 0, "");
}
}
else {
- uiDefBut(block, LABEL, 0, sock->name, (short)(sock->locx+3.0f), (short)(sock->locy-9.0f),
+ uiDefBut(node->block, LABEL, 0, sock->name, (short)(sock->locx+3.0f), (short)(sock->locy-9.0f),
(short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, "");
}
}
@@ -803,43 +835,32 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
slen= snode->aspect*UI_GetStringWidth(sock->name+ofs);
}
- uiDefBut(block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f),
+ uiDefBut(node->block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f),
(short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, "");
}
}
/* preview */
- if(node->flag & NODE_PREVIEW)
+ if(node->flag & NODE_PREVIEW) {
+ BLI_lock_thread(LOCK_PREVIEW);
if(node->preview && node->preview->rect)
node_draw_preview(node->preview, &node->prvr);
-
- /* buttons */
- if(node->flag & NODE_OPTIONS) {
- if(block) {
- if(node->typeinfo->butfunc) {
- node->typeinfo->butfunc(block, snode->nodetree, node, &node->butr);
- }
- }
+ BLI_unlock_thread(LOCK_PREVIEW);
}
-
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+
+ uiEndBlock(C, node->block);
+ uiDrawBlock(C, node->block);
+ node->block= NULL;
}
static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, bNode *node)
{
- uiBlock *block;
bNodeSocket *sock;
rctf *rct= &node->totr;
float dx, centy= 0.5f*(rct->ymax+rct->ymin);
float hiddenrad= 0.5f*(rct->ymax-rct->ymin);
int color_id= node_get_colorid(node);
- char str[32], showname[128]; /* 128 is used below */
-
- /* make unique block name, also used for handling blocks in editnode.c */
- sprintf(str, "node buttons %p", node);
- block= uiBeginBlock(C, ar, str, UI_EMBOSS);
- uiBlockSetHandleFunc(block, do_node_internal_buttons, node);
+ char showname[128]; /* 128 is used below */
/* shadow */
uiSetRoundBox(15);
@@ -884,7 +905,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
else
BLI_strncpy(showname, node->name, 128);
- uiDefBut(block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(centy-10),
+ uiDefBut(node->block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(centy-10),
(int)(rct->xmax - rct->xmin-18.0f -12.0f), NODE_DY, NULL, 0, 0, 0, 0, "");
}
@@ -910,9 +931,9 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
socket_circle_draw(sock, NODE_SOCKSIZE);
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
-
+ uiEndBlock(C, node->block);
+ uiDrawBlock(C, node->block);
+ node->block= NULL;
}
static void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree)
@@ -1081,11 +1102,11 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
/* for now, we set drawing coordinates on each redraw */
for(node= snode->nodetree->nodes.first; node; node= node->next) {
if(node->flag & NODE_GROUP_EDIT)
- node_update_group(node);
+ node_update_group(C, snode->nodetree, node);
else if(node->flag & NODE_HIDDEN)
- node_update_hidden(node);
+ node_update_hidden(C, node);
else
- node_update(node);
+ node_update(C, snode->nodetree, node);
}
node_draw_nodetree(C, ar, snode, snode->nodetree);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index bc81c25d106..50a99650ec0 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -58,10 +58,11 @@
#include "BKE_material.h"
#include "BKE_paint.h"
#include "BKE_texture.h"
+#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_utildefines.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "BIF_gl.h"
@@ -84,6 +85,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "UI_interface.h"
#include "UI_view2d.h"
#include "node_intern.h"
@@ -150,7 +152,7 @@ static void compo_startjob(void *cjv, short *stop, short *do_update)
{
CompoJob *cj= cjv;
bNodeTree *ntree= cj->localtree;
-
+
if(cj->scene->use_nodes==0)
return;
@@ -174,8 +176,11 @@ static void compo_startjob(void *cjv, short *stop, short *do_update)
void snode_composite_job(const bContext *C, ScrArea *sa)
{
SpaceNode *snode= sa->spacedata.first;
- wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa);
- CompoJob *cj= MEM_callocN(sizeof(CompoJob), "compo job");
+ wmJob *steve;
+ CompoJob *cj;
+
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, WM_JOB_EXCL_RENDER);
+ cj= MEM_callocN(sizeof(CompoJob), "compo job");
/* customdata for preview thread */
cj->scene= CTX_data_scene(C);
@@ -327,12 +332,12 @@ static void set_node_imagepath(char *str) /* called from fileselect */
#endif /* 0 */
-bNode *snode_get_editgroup(SpaceNode *snode)
+bNode *node_tree_get_editgroup(bNodeTree *nodetree)
{
bNode *gnode;
/* get the groupnode */
- for(gnode= snode->nodetree->nodes.first; gnode; gnode= gnode->next)
+ for(gnode= nodetree->nodes.first; gnode; gnode= gnode->next)
if(gnode->flag & NODE_GROUP_EDIT)
break;
return gnode;
@@ -441,7 +446,7 @@ static void composit_node_event(SpaceNode *snode, short event)
addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
}
else {
- node= snode_get_editgroup(snode);
+ node= node_tree_get_editgroup(snode->nodetree);
if(node)
NodeTagIDChanged(snode->nodetree, node->id);
@@ -722,7 +727,7 @@ void node_set_active(SpaceNode *snode, bNode *node)
NodeTagChanged(snode->edittree, node);
/* if inside group, tag entire group */
- gnode= snode_get_editgroup(snode);
+ gnode= node_tree_get_editgroup(snode->nodetree);
if(gnode)
NodeTagIDChanged(snode->nodetree, gnode->id);
@@ -753,6 +758,8 @@ void node_set_active(SpaceNode *snode, bNode *node)
#endif /* 0 */
}
+/* ***************** Edit Group operator ************* */
+
void snode_make_group_editable(SpaceNode *snode, bNode *gnode)
{
bNode *node;
@@ -768,12 +775,9 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode)
}
if(gnode && gnode->type==NODE_GROUP && gnode->id) {
- if(gnode->id->lib) {
- // XXX if(okee("Make Group Local"))
- // ntreeMakeLocal((bNodeTree *)gnode->id);
- // else
- return;
- }
+ if(gnode->id->lib)
+ ntreeMakeLocal((bNodeTree *)gnode->id);
+
gnode->flag |= NODE_GROUP_EDIT;
snode->edittree= (bNodeTree *)gnode->id;
@@ -794,43 +798,102 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode)
// XXX BIF_preview_changed(-1); /* temp hack to force texture preview to update */
}
+}
+
+static int node_group_edit_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *gnode;
+
+ gnode= nodeGetActive(snode->edittree);
+ snode_make_group_editable(snode, gnode);
+
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *gnode;
+
+ gnode= nodeGetActive(snode->edittree);
+ if(gnode && gnode->type==NODE_GROUP && gnode->id && gnode->id->lib) {
+ uiPupMenuOkee(C, op->type->idname, "Make group local?");
+ return OPERATOR_CANCELLED;
+ }
+
+ return node_group_edit_exec(C, op);
+}
+
+void NODE_OT_group_edit(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edit Group";
+ ot->description = "Edit node group.";
+ ot->idname = "NODE_OT_group_edit";
+
+ /* api callbacks */
+ ot->invoke = node_group_edit_invoke;
+ ot->exec = node_group_edit_exec;
+ ot->poll = ED_operator_node_active;
- // allqueue(REDRAWNODE, 0);
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
-#if 0
+/* ******************** Ungroup operator ********************** */
-void node_ungroup(SpaceNode *snode)
+static int node_group_ungroup_exec(bContext *C, wmOperator *op)
{
+ SpaceNode *snode = CTX_wm_space_node(C);
bNode *gnode;
/* are we inside of a group? */
- gnode= snode_get_editgroup(snode);
+ gnode= node_tree_get_editgroup(snode->nodetree);
if(gnode)
snode_make_group_editable(snode, NULL);
gnode= nodeGetActive(snode->edittree);
- if(gnode==NULL) return;
+ if(gnode==NULL)
+ return OPERATOR_CANCELLED;
- if(gnode->type!=NODE_GROUP)
- error("Not a group");
- else {
- if(nodeGroupUnGroup(snode->edittree, gnode)) {
-
- // allqueue(REDRAWNODE, 0);
- }
- else
- error("Can't ungroup");
+ if(gnode->type!=NODE_GROUP) {
+ BKE_report(op->reports, RPT_ERROR, "Not a group");
+ return OPERATOR_CANCELLED;
+ }
+ else if(!nodeGroupUnGroup(snode->edittree, gnode)) {
+ BKE_report(op->reports, RPT_ERROR, "Can't ungroup");
+ return OPERATOR_CANCELLED;
}
+
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_group_ungroup(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Ungroup";
+ ot->description = "Ungroup selected nodes.";
+ ot->idname = "NODE_OT_group_ungroup";
+
+ /* api callbacks */
+ ot->exec = node_group_ungroup_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
-#endif /* 0 */
/* when links in groups change, inputs/outputs change, nodes added/deleted... */
-static void snode_verify_groups(SpaceNode *snode)
+static void node_tree_verify_groups(bNodeTree *nodetree)
{
bNode *gnode;
- gnode= snode_get_editgroup(snode);
+ gnode= node_tree_get_editgroup(nodetree);
/* does all materials */
if(gnode)
@@ -1156,7 +1219,7 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
nsw->oldwidth= node->width;
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1229,27 +1292,14 @@ Material *editnode_get_active_material(Material *ma)
/* no undo here! */
-void node_deselectall(SpaceNode *snode, int swap)
+void node_deselectall(SpaceNode *snode)
{
bNode *node;
- if(swap) {
- for(node= snode->edittree->nodes.first; node; node= node->next)
- if(node->flag & SELECT)
- break;
- if(node==NULL) {
- for(node= snode->edittree->nodes.first; node; node= node->next)
- node->flag |= SELECT;
- return;
- }
- /* else pass on to deselect */
- }
-
for(node= snode->edittree->nodes.first; node; node= node->next)
node->flag &= ~SELECT;
}
-
int node_has_hidden_sockets(bNode *node)
{
bNodeSocket *sock;
@@ -1276,7 +1326,7 @@ static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node)
sock->flag &= ~SOCK_HIDDEN;
}
else {
- bNode *gnode= snode_get_editgroup(snode);
+ bNode *gnode= node_tree_get_editgroup(snode->nodetree);
/* hiding inside group should not break links in other group users */
if(gnode) {
@@ -1304,7 +1354,7 @@ static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node)
}
// allqueue(REDRAWNODE, 1);
- snode_verify_groups(snode);
+ node_tree_verify_groups(snode->nodetree);
}
@@ -1431,7 +1481,7 @@ void node_active_link_viewer(SpaceNode *snode)
float mx=0, my=0;
// XXX short mval[2];
- gnode= snode_get_editgroup(snode);
+ gnode= node_tree_get_editgroup(snode->nodetree);
if(gnode==NULL) return 0;
// XXX getmouseco_areawin(mval);
@@ -1606,7 +1656,7 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float
{
bNode *node= NULL, *gnode;
- node_deselectall(snode, 0);
+ node_deselectall(snode);
if(type>=NODE_DYNAMIC_MENU) {
node= nodeAddNodeType(snode->edittree, type, NULL, NULL);
@@ -1631,13 +1681,13 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float
node->locy= locy + 60.0f; // arbitrary.. so its visible
node->flag |= SELECT;
- gnode= snode_get_editgroup(snode);
+ gnode= node_tree_get_editgroup(snode->nodetree);
if(gnode) {
node->locx -= gnode->locx;
node->locy -= gnode->locy;
}
- snode_verify_groups(snode);
+ node_tree_verify_groups(snode->nodetree);
node_set_active(snode, node);
if(snode->nodetree->type==NTREE_COMPOSIT) {
@@ -1667,7 +1717,7 @@ void node_mute(SpaceNode *snode)
bNode *node;
/* no disabling inside of groups */
- if(snode_get_editgroup(snode))
+ if(node_tree_get_editgroup(snode->nodetree))
return;
for(node= snode->edittree->nodes.first; node; node= node->next) {
@@ -1693,7 +1743,7 @@ int node_duplicate_exec(bContext *C, wmOperator *op)
ntreeCopyTree(snode->edittree, 1); /* 1 == internally selected nodes */
ntreeSolveOrder(snode->edittree);
- snode_verify_groups(snode);
+ node_tree_verify_groups(snode->nodetree);
snode_handle_recalc(C, snode);
return OPERATOR_FINISHED;
@@ -1904,7 +1954,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
}
ntreeSolveOrder(snode->edittree);
- snode_verify_groups(snode);
+ node_tree_verify_groups(snode->nodetree);
snode_handle_recalc(C, snode);
MEM_freeN(op->customdata);
@@ -1986,7 +2036,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
nldrag->link= nodeAddLink(snode->edittree, NULL, NULL, nldrag->node, nldrag->sock);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -2013,35 +2063,6 @@ void NODE_OT_link(wmOperatorType *ot)
}
-void node_delete(SpaceNode *snode)
-{
- bNode *node, *next;
- bNodeSocket *sock;
-
- for(node= snode->edittree->nodes.first; node; node= next) {
- next= node->next;
- if(node->flag & SELECT) {
- /* set selin and selout NULL if the sockets belong to a node to be deleted */
- for(sock= node->inputs.first; sock; sock= sock->next)
- if(snode->edittree->selin == sock) snode->edittree->selin= NULL;
-
- for(sock= node->outputs.first; sock; sock= sock->next)
- if(snode->edittree->selout == sock) snode->edittree->selout= NULL;
-
- /* check id user here, nodeFreeNode is called for free dbase too */
- if(node->id)
- node->id->us--;
- nodeFreeNode(snode->edittree, node);
- }
- }
-
- snode_verify_groups(snode);
- // NODE_FIX_ME
- // snode_handle_recalc(snode);
- // allqueue(REDRAWNODE, 1);
-}
-
-
void node_hide(SpaceNode *snode)
{
bNode *node;
@@ -2091,32 +2112,6 @@ void node_insert_key(SpaceNode *snode)
}
}
-void node_select_linked(SpaceNode *snode, int out)
-{
- bNodeLink *link;
- bNode *node;
-
- /* NODE_TEST is the free flag */
- for(node= snode->edittree->nodes.first; node; node= node->next)
- node->flag &= ~NODE_TEST;
-
- for(link= snode->edittree->links.first; link; link= link->next) {
- if(out) {
- if(link->fromnode->flag & NODE_SELECT)
- link->tonode->flag |= NODE_TEST;
- }
- else {
- if(link->tonode->flag & NODE_SELECT)
- link->fromnode->flag |= NODE_TEST;
- }
- }
-
- for(node= snode->edittree->nodes.first; node; node= node->next)
- if(node->flag & NODE_TEST)
- node->flag |= NODE_SELECT;
-
-}
-
/* makes a link between selected output and input sockets */
void node_make_link(SpaceNode *snode)
{
@@ -2137,7 +2132,7 @@ void node_make_link(SpaceNode *snode)
else return;
ntreeSolveOrder(snode->edittree);
- snode_verify_groups(snode);
+ node_tree_verify_groups(snode->nodetree);
// XXX snode_handle_recalc(snode);
}
@@ -2192,7 +2187,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
}
ntreeSolveOrder(snode->edittree);
- snode_verify_groups(snode);
+ node_tree_verify_groups(snode->nodetree);
snode_handle_recalc(C, snode);
return OPERATOR_FINISHED;
@@ -2292,15 +2287,16 @@ void imagepaint_composite_tags(bNodeTree *ntree, Image *image, ImageUser *iuser)
}
}
-/* ********************** */
+/* ****************** Make Group operator ******************* */
-void node_make_group(SpaceNode *snode)
+static int node_group_make_exec(bContext *C, wmOperator *op)
{
+ SpaceNode *snode = CTX_wm_space_node(C);
bNode *gnode;
if(snode->edittree!=snode->nodetree) {
-// XXX error("Can not add a new Group in a Group");
- return;
+ BKE_report(op->reports, RPT_ERROR, "Can not add a new Group in a Group");
+ return OPERATOR_CANCELLED;
}
/* for time being... is too complex to handle */
@@ -2310,20 +2306,39 @@ void node_make_group(SpaceNode *snode)
if(gnode->type==CMP_NODE_R_LAYERS)
break;
}
+
if(gnode) {
-// XXX error("Can not add RenderLayer in a Group");
- return;
+ BKE_report(op->reports, RPT_ERROR, "Can not add RenderLayer in a Group");
+ return OPERATOR_CANCELLED;
}
}
gnode= nodeMakeGroupFromSelected(snode->nodetree);
if(gnode==NULL) {
-// XXX error("Can not make Group");
+ BKE_report(op->reports, RPT_ERROR, "Can not make Group");
+ return OPERATOR_CANCELLED;
}
else {
nodeSetActive(snode->nodetree, gnode);
ntreeSolveOrder(snode->nodetree);
}
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_group_make(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Group";
+ ot->description = "Make group from selected nodes.";
+ ot->idname = "NODE_OT_group_make";
+
+ /* api callbacks */
+ ot->exec = node_group_make_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
#if 0
@@ -2451,9 +2466,6 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(fromlib) fromlib= -1;
else toolbox_n_add();
}
- else if(G.qual==0) {
- node_deselectall(snode, 1);
- }
break;
case BKEY:
if(G.qual==0)
@@ -2540,29 +2552,50 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
#endif
-static int node_delete_selection_exec(bContext *C, wmOperator *op)
+/* ****************** Delete operator ******************* */
+
+static int node_delete_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode= CTX_wm_space_node(C);
- ARegion *ar= CTX_wm_region(C);
+ bNode *node, *next;
+ bNodeSocket *sock;
+
+ for(node= snode->edittree->nodes.first; node; node= next) {
+ next= node->next;
+ if(node->flag & SELECT) {
+ /* set selin and selout NULL if the sockets belong to a node to be deleted */
+ for(sock= node->inputs.first; sock; sock= sock->next)
+ if(snode->edittree->selin == sock) snode->edittree->selin= NULL;
+
+ for(sock= node->outputs.first; sock; sock= sock->next)
+ if(snode->edittree->selout == sock) snode->edittree->selout= NULL;
+
+ /* check id user here, nodeFreeNode is called for free dbase too */
+ if(node->id)
+ node->id->us--;
+ nodeFreeNode(snode->edittree, node);
+ }
+ }
- node_delete(snode);
- ED_region_tag_redraw(ar);
+ node_tree_verify_groups(snode->nodetree);
+
+ // NODE_FIX_ME
+ // snode_handle_recalc(snode);
+
WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); /* Do we need to pass the scene? */
return OPERATOR_FINISHED;
}
-/* operators */
-
void NODE_OT_delete(wmOperatorType *ot)
{
-
/* identifiers */
ot->name= "Delete";
+ ot->description = "Delete selected nodes.";
ot->idname= "NODE_OT_delete";
/* api callbacks */
- ot->exec= node_delete_selection_exec;
+ ot->exec= node_delete_exec;
ot->poll= ED_operator_node_active;
/* flags */
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 5c66c902797..2a929472c68 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -58,6 +58,9 @@ void node_keymap(wmWindowManager *wm);
/* node_select.c */
void NODE_OT_select(struct wmOperatorType *ot);
void NODE_OT_select_extend(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_visibility_toggle(struct wmOperatorType *ot);
void NODE_OT_view_all(struct wmOperatorType *ot);
void NODE_OT_select_border(struct wmOperatorType *ot);
@@ -76,9 +79,9 @@ void snode_set_context(SpaceNode *snode, Scene *scene);
void snode_make_group_editable(SpaceNode *snode, bNode *gnode);
void snode_home(ScrArea *sa, ARegion *ar, SpaceNode *snode);
void node_set_active(SpaceNode *snode, bNode *node);
-void node_deselectall(SpaceNode *snode, int swap);
+void node_deselectall(SpaceNode *snode);
void snode_composite_job(const struct bContext *C, ScrArea *sa);
-bNode *snode_get_editgroup(SpaceNode *snode);
+bNode *node_tree_get_editgroup(bNodeTree *ntree);
void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag);
void NODE_OT_duplicate(struct wmOperatorType *ot);
@@ -86,6 +89,9 @@ void NODE_OT_link(struct wmOperatorType *ot);
void NODE_OT_delete(struct wmOperatorType *ot);
void NODE_OT_resize(struct wmOperatorType *ot);
void NODE_OT_links_cut(struct wmOperatorType *ot);
+void NODE_OT_group_make(struct wmOperatorType *ot);
+void NODE_OT_group_ungroup(struct wmOperatorType *ot);
+void NODE_OT_group_edit(struct wmOperatorType *ot);
// XXXXXX
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index f78abb28313..f47e9aa2a6f 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -51,6 +51,9 @@ void node_operatortypes(void)
{
WM_operatortype_append(NODE_OT_select);
WM_operatortype_append(NODE_OT_select_extend);
+ WM_operatortype_append(NODE_OT_select_all);
+ WM_operatortype_append(NODE_OT_select_linked_to);
+ WM_operatortype_append(NODE_OT_select_linked_from);
WM_operatortype_append(NODE_OT_visibility_toggle);
WM_operatortype_append(NODE_OT_view_all);
WM_operatortype_append(NODE_OT_select_border);
@@ -59,12 +62,14 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_resize);
WM_operatortype_append(NODE_OT_links_cut);
WM_operatortype_append(NODE_OT_duplicate);
-
+ WM_operatortype_append(NODE_OT_group_make);
+ WM_operatortype_append(NODE_OT_group_ungroup);
+ WM_operatortype_append(NODE_OT_group_edit);
}
void node_keymap(struct wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Node", SPACE_NODE, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0);
/* mouse select in nodes used to be both keys, it's UI elements... */
RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
@@ -82,6 +87,15 @@ void node_keymap(struct wmWindowManager *wm)
WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_delete", DELKEY, KM_PRESS, 0, 0);
+
+ WM_keymap_add_item(keymap, "NODE_OT_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_select_linked_to", LKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_select_linked_from", LKEY, KM_PRESS, 0, 0);
+
+ WM_keymap_add_item(keymap, "NODE_OT_group_make", GKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_group_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, 0, 0);
transform_keymap_for_space(wm, keymap, SPACE_NODE);
}
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 73becc1ebe8..5e482758c9d 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -83,7 +83,7 @@ static void node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short
}
if(node) {
if((extend & KM_SHIFT)==0)
- node_deselectall(snode, 0);
+ node_deselectall(snode);
if(extend & KM_SHIFT) {
if(node->flag & SELECT)
@@ -140,7 +140,7 @@ static int node_select_modal(bContext *C, wmOperator *op, wmEvent *event)
printf("%d %d\n", event->x, event->y);
break;
case SELECTMOUSE:
- //if (event->val==0) {
+ //if (event->val==KM_RELEASE) {
/* calculate overall delta mouse-movement for redo */
printf("done translating\n");
//WM_cursor_restore(CTX_wm_window(C));
@@ -224,12 +224,6 @@ void NODE_OT_select(wmOperatorType *ot)
/* ****** Border Select ****** */
-static EnumPropertyItem prop_select_types[] = {
- {NODE_EXCLUSIVE, "EXCLUSIVE", 0, "Exclusive", ""}, /* right mouse */
- {NODE_EXTEND, "EXTEND", 0, "Extend", ""}, /* left mouse */
- {0, NULL, 0, NULL, NULL}
-};
-
static int node_borderselect_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode= CTX_wm_space_node(C);
@@ -288,6 +282,122 @@ void NODE_OT_select_border(wmOperatorType *ot)
RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
+}
+
+/* ****** Select/Deselect All ****** */
+
+static int node_select_all_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *first = snode->edittree->nodes.first;
+ bNode *node;
+ int count= 0;
+
+ for(node=first; node; node=node->next)
+ if(node->flag & NODE_SELECT)
+ count++;
+
+ if(count) {
+ for(node=first; node; node=node->next)
+ node->flag &= ~NODE_SELECT;
+ }
+ else {
+ for(node=first; node; node=node->next)
+ node->flag |= NODE_SELECT;
+ }
+
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_select_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select/Deselect All";
+ ot->description = "(De)select all nodes.";
+ ot->idname = "NODE_OT_select_all";
+
+ /* api callbacks */
+ ot->exec = node_select_all_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ****** Select Linked To ****** */
+
+static int node_select_linked_to_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeLink *link;
+ bNode *node;
+
+ for (node=snode->edittree->nodes.first; node; node=node->next)
+ node->flag &= ~NODE_TEST;
+
+ for (link=snode->edittree->links.first; link; link=link->next)
+ if (link->fromnode->flag & NODE_SELECT)
+ link->tonode->flag |= NODE_TEST;
+
+ for (node=snode->edittree->nodes.first; node; node=node->next)
+ if (node->flag & NODE_TEST)
+ node->flag |= NODE_SELECT;
+
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_select_linked_to(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Linked To";
+ ot->description = "Select nodes linked to the selected ones.";
+ ot->idname = "NODE_OT_select_linked_to";
+
+ /* api callbacks */
+ ot->exec = node_select_linked_to_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ****** Select Linked From ****** */
+
+static int node_select_linked_from_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeLink *link;
+ bNode *node;
+
+ for(node=snode->edittree->nodes.first; node; node=node->next)
+ node->flag &= ~NODE_TEST;
+
+ for(link=snode->edittree->links.first; link; link=link->next)
+ if(link->tonode->flag & NODE_SELECT)
+ link->fromnode->flag |= NODE_TEST;
+
+ for(node=snode->edittree->nodes.first; node; node=node->next)
+ if(node->flag & NODE_TEST)
+ node->flag |= NODE_SELECT;
+
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ return OPERATOR_FINISHED;
+}
- RNA_def_enum(ot->srna, "type", prop_select_types, 0, "Type", "");
+void NODE_OT_select_linked_from(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Linked From";
+ ot->description = "Select nodes linked from the selected ones.";
+ ot->idname = "NODE_OT_select_linked_from";
+
+ /* api callbacks */
+ ot->exec = node_select_linked_from_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
+
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index d3a445b18c0..2cfd9d99123 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -48,7 +48,7 @@
#include "BKE_screen.h"
#include "BKE_node.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "ED_space_api.h"
#include "ED_screen.h"
@@ -245,12 +245,12 @@ static void node_channel_area_draw(const bContext *C, ARegion *ar)
/* Initialise main area, setting handlers. */
static void node_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Node", SPACE_NODE, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index a3b47d505fd..e62c1dedb1b 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -4324,7 +4324,7 @@ static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, S
tselem= TREESTORE(te);
- if(*starty >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
+ if(*starty+2*OL_H >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
glEnable(GL_BLEND);
@@ -4579,7 +4579,7 @@ static void outliner_back(ARegion *ar, SpaceOops *soops)
ystart= (int)ar->v2d.tot.ymax;
ystart= OL_H*(ystart/(OL_H));
- while(ystart > ar->v2d.cur.ymin) {
+ while(ystart+2*OL_H > ar->v2d.cur.ymin) {
glRecti(0, ystart, (int)ar->v2d.cur.xmax, ystart+OL_H);
ystart-= 2*OL_H;
}
@@ -4597,7 +4597,7 @@ static void outliner_draw_restrictcols(ARegion *ar, SpaceOops *soops)
ystart= (int)ar->v2d.tot.ymax;
ystart= OL_H*(ystart/(OL_H));
- while(ystart > ar->v2d.cur.ymin) {
+ while(ystart+2*OL_H > ar->v2d.cur.ymin) {
glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+OL_H);
ystart-= 2*OL_H;
}
@@ -4812,7 +4812,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
/* objects have toggle-able restriction flags */
if(tselem->type==0 && te->idcode==ID_OB) {
ob = (Object *)tselem->id;
@@ -4924,7 +4924,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if(tselem->type == TSE_RNA_PROPERTY) {
ptr= &te->rnaptr;
prop= te->directdata;
@@ -5049,6 +5049,8 @@ static char *keymap_mouse_menu(void)
str += sprintf(str, formatstr, "Left Mouse", LEFTMOUSE);
str += sprintf(str, formatstr, "Middle Mouse", MIDDLEMOUSE);
str += sprintf(str, formatstr, "Right Mouse", RIGHTMOUSE);
+ str += sprintf(str, formatstr, "Button4 Mouse ", BUTTON4MOUSE);
+ str += sprintf(str, formatstr, "Button5 Mouse ", BUTTON5MOUSE);
str += sprintf(str, formatstr, "Action Mouse", ACTIONMOUSE);
str += sprintf(str, formatstr, "Select Mouse", SELECTMOUSE);
str += sprintf(str, formatstr, "Mouse Move", MOUSEMOVE);
@@ -5071,6 +5073,8 @@ static char *keymap_tweak_menu(void)
str += sprintf(str, formatstr, "Left Mouse", EVT_TWEAK_L);
str += sprintf(str, formatstr, "Middle Mouse", EVT_TWEAK_M);
str += sprintf(str, formatstr, "Right Mouse", EVT_TWEAK_R);
+ str += sprintf(str, formatstr, "Button4 Mouse ", BUTTON4MOUSE);
+ str += sprintf(str, formatstr, "Button5 Mouse ", BUTTON5MOUSE);
str += sprintf(str, formatstr, "Action Mouse", EVT_TWEAK_A);
str += sprintf(str, formatstr, "Select Mouse", EVT_TWEAK_S);
@@ -5135,7 +5139,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
uiBut *but;
char *str;
int xstart= 240;
@@ -5213,7 +5217,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if(tselem->flag & TSE_TEXTBUT) {
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 2e11eb379b4..a35b91249db 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -76,7 +76,7 @@ void outliner_operatortypes(void)
void outliner_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OUTLINER, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Outliner", SPACE_OUTLINER, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 5058a167a29..e7e6c2d0128 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -72,12 +72,12 @@
static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OUTLINER, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Outliner", SPACE_OUTLINER, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c
index 88b8dccc6c9..c17793b28f8 100644
--- a/source/blender/editors/space_script/script_edit.c
+++ b/source/blender/editors/space_script/script_edit.c
@@ -64,10 +64,10 @@ static int run_pyfile_exec(bContext *C, wmOperator *op)
ARegion *ar= CTX_wm_region(C);
- char filename[512];
- RNA_string_get(op->ptr, "filename", filename);
+ char path[512];
+ RNA_string_get(op->ptr, "path", path);
#ifndef DISABLE_PYTHON
- if(BPY_run_python_script(C, filename, NULL, op->reports)) {
+ if(BPY_run_python_script(C, path, NULL, op->reports)) {
ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -85,7 +85,7 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot)
ot->exec= run_pyfile_exec;
ot->poll= ED_operator_areaactive;
- RNA_def_string_file_path(ot->srna, "filename", "", 512, "Filename", "");
+ RNA_def_string_file_path(ot->srna, "path", "", 512, "Path", "");
}
static int run_ui_scripts_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c
index aa35ba54b7f..0e6ea9cf4fd 100644
--- a/source/blender/editors/space_script/script_ops.c
+++ b/source/blender/editors/space_script/script_ops.c
@@ -65,10 +65,10 @@ void script_operatortypes(void)
void script_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Script", SPACE_SCRIPT, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Script", SPACE_SCRIPT, 0);
/* TODO - this is just while we have no way to load a text datablock */
- RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "filename", "test.py");
+ RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "path", "test.py");
WM_keymap_add_item(keymap, "SCRIPT_OT_python_run_ui_scripts", PKEY, KM_PRESS, KM_SHIFT, 0);
}
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 99233cc5020..a0e73082701 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -133,12 +133,12 @@ static SpaceLink *script_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void script_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Script", SPACE_SCRIPT, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Script", SPACE_SCRIPT, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 8a1b3bf3465..bd5259ddb52 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -289,7 +289,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
Editing *ed= seq_give_editing(scene, TRUE);
struct anim *an;
- char filename[FILE_MAX];
+ char path[FILE_MAX];
Sequence *seq, *soundseq=NULL; /* generic strip vars */
Strip *strip;
@@ -301,12 +301,12 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
channel= RNA_int_get(op->ptr, "channel");
sound = RNA_boolean_get(op->ptr, "sound");
- RNA_string_get(op->ptr, "filename", filename);
+ RNA_string_get(op->ptr, "path", path);
- an = openanim(filename, IB_rect);
+ an = openanim(path, IB_rect);
if (an==NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Filename \"%s\" could not be loaded as a movie", filename);
+ BKE_reportf(op->reports, RPT_ERROR, "File \"%s\" could not be loaded as a movie", path);
return OPERATOR_CANCELLED;
}
@@ -323,7 +323,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- BLI_split_dirfile_basic(filename, strip->dir, se->name);
+ BLI_split_dirfile_basic(path, strip->dir, se->name);
RNA_string_get(op->ptr, "name", seq->name);
@@ -332,7 +332,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
if(sound)
{
- soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, filename);
+ soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, path);
if(soundseq != NULL)
RNA_string_get(op->ptr, "name", soundseq->name);
}
@@ -376,7 +376,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie");
}
@@ -384,7 +384,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
/* add sound operator */
static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
{
- char filename[FILE_MAX];
+ char path[FILE_MAX];
Scene *scene= CTX_data_scene(C);
Sequence *seq; /* generic strip vars */
int start_frame, channel; /* operator props */
@@ -392,9 +392,9 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
start_frame= RNA_int_get(op->ptr, "start_frame");
channel= RNA_int_get(op->ptr, "channel");
- RNA_string_get(op->ptr, "filename", filename);
+ RNA_string_get(op->ptr, "path", path);
- seq = sequencer_add_sound_strip(C, op, start_frame, channel, filename);
+ seq = sequencer_add_sound_strip(C, op, start_frame, channel, path);
if(seq == NULL)
return OPERATOR_CANCELLED;
@@ -442,7 +442,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
}
@@ -455,7 +455,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
int tot_images;
- char filename[FILE_MAX];
+ char path[FILE_MAX];
Sequence *seq; /* generic strip vars */
Strip *strip;
@@ -466,14 +466,14 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
start_frame= RNA_int_get(op->ptr, "start_frame");
channel= RNA_int_get(op->ptr, "channel");
- RNA_string_get(op->ptr, "filename", filename);
+ RNA_string_get(op->ptr, "path", path);
seq = alloc_sequence(ed->seqbasep, start_frame, channel);
seq->type= SEQ_IMAGE;
/* basic defaults */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
- BLI_split_dirfile_basic(filename, strip->dir, NULL);
+ BLI_split_dirfile_basic(path, strip->dir, NULL);
tot_images= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
@@ -490,7 +490,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
RNA_END;
}
else {
- BLI_split_dirfile_basic(filename, NULL, se->name);
+ BLI_split_dirfile_basic(path, NULL, se->name);
}
RNA_string_get(op->ptr, "name", seq->name);
@@ -538,7 +538,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
@@ -606,15 +606,15 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
if (seq->type==SEQ_PLUGIN) {
- char filename[FILE_MAX];
- RNA_string_get(op->ptr, "filename", filename);
+ char path[FILE_MAX];
+ RNA_string_get(op->ptr, "path", path);
- sh.init_plugin(seq, filename);
+ sh.init_plugin(seq, path);
if(seq->plugin==NULL) {
BLI_remlink(ed->seqbasep, seq);
seq_free_sequence(scene, seq);
- BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", filename);
+ BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", path);
return OPERATOR_CANCELLED;
}
}
@@ -673,7 +673,7 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, 0);
+ WM_operator_properties_filesel(ot, 0, FILE_SPECIAL);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME);
RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type");
RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f);
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index 789843f5490..72cbacd9b6d 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -112,13 +112,9 @@ static int sequencer_properties(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= sequencer_has_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 74f22b86b75..ac125c10b2d 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -105,7 +105,7 @@ void sequencer_operatortypes(void)
void sequencer_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Sequencer", SPACE_SEQ, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Sequencer", SPACE_SEQ, 0);
wmKeymapItem *kmi;
WM_keymap_add_item(keymap, "SEQUENCER_OT_properties", NKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 26ffd88ae67..c2756b05946 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -185,12 +185,12 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Sequencer", SPACE_SEQ, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Sequencer", SPACE_SEQ, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_sound/space_sound.c b/source/blender/editors/space_sound/space_sound.c
index f8ef2b21ae7..6713e19b6de 100644
--- a/source/blender/editors/space_sound/space_sound.c
+++ b/source/blender/editors/space_sound/space_sound.c
@@ -142,12 +142,12 @@ static SpaceLink *sound_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void sound_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Sound", SPACE_SOUND, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Sound", SPACE_SOUND, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 1f919fc9cd7..e068c1a70bb 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -208,7 +208,9 @@ static void text_operatortypes(void)
static void text_keymap(struct wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Text", SPACE_TEXT, 0);
+ wmKeyMap *keymap;
+
+ keymap= WM_keymap_find(wm, "Text", SPACE_TEXT, 0);
#ifdef __APPLE__
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
@@ -329,12 +331,12 @@ static int text_context(const bContext *C, const char *member, bContextDataResul
/* add handlers, stuff you only do once or on area/region changes */
static void text_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Text", SPACE_TEXT, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "Text", SPACE_TEXT, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 9721fbc2b9c..5996770c206 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -425,60 +425,6 @@ static void format_draw_color(char formatchar)
}
}
-/*********************** utilities ************************/
-
-int text_check_bracket(char ch)
-{
- int a;
- char opens[] = "([{";
- char close[] = ")]}";
-
- for(a=0; a<3; a++) {
- if(ch==opens[a])
- return a+1;
- else if(ch==close[a])
- return -(a+1);
- }
- return 0;
-}
-
-int text_check_delim(char ch)
-{
- int a;
- char delims[] = "():\"\' ~!%^&*-+=[]{};/<>|.#\t,";
-
- for(a=0; a<28; a++) {
- if(ch==delims[a])
- return 1;
- }
- return 0;
-}
-
-int text_check_digit(char ch)
-{
- if(ch < '0') return 0;
- if(ch <= '9') return 1;
- return 0;
-}
-
-int text_check_identifier(char ch)
-{
- if(ch < '0') return 0;
- if(ch <= '9') return 1;
- if(ch < 'A') return 0;
- if(ch <= 'Z' || ch == '_') return 1;
- if(ch < 'a') return 0;
- if(ch <= 'z') return 1;
- return 0;
-}
-
-int text_check_whitespace(char ch)
-{
- if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
- return 1;
- return 0;
-}
-
/************************** draw text *****************************/
/***********************/ /*
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index 089436cfcf9..d0a02f558e1 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -186,15 +186,6 @@ ARegion *text_has_properties_region(ScrArea *sa)
return arnew;
}
-void text_toggle_properties_region(bContext *C, ScrArea *sa, ARegion *ar)
-{
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
-}
-
static int properties_poll(bContext *C)
{
return (CTX_wm_space_text(C) != NULL);
@@ -206,7 +197,7 @@ static int properties_exec(bContext *C, wmOperator *op)
ARegion *ar= text_has_properties_region(sa);
if(ar)
- text_toggle_properties_region(C, sa, ar);
+ ED_region_toggle_hidden(C, ar);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 3411d9114df..8e81336912b 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -192,7 +192,7 @@ static int open_exec(bContext *C, wmOperator *op)
Text *text;
char str[FILE_MAX];
- RNA_string_get(op->ptr, "filename", str);
+ RNA_string_get(op->ptr, "path", str);
text= add_text(str, G.sce);
@@ -211,10 +211,10 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
Text *text= CTX_data_edit_text(C);
char *path= (text && text->name)? text->name: G.sce;
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return open_exec(C, op);
- RNA_string_set(op->ptr, "filename", path);
+ RNA_string_set(op->ptr, "path", path);
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -233,7 +233,7 @@ void TEXT_OT_open(wmOperatorType *ot)
ot->poll= text_new_poll;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL);
}
/******************* reload operator *********************/
@@ -420,7 +420,7 @@ static int save_as_exec(bContext *C, wmOperator *op)
if(!text)
return OPERATOR_CANCELLED;
- RNA_string_get(op->ptr, "filename", str);
+ RNA_string_get(op->ptr, "path", str);
if(text->name) MEM_freeN(text->name);
text->name= BLI_strdup(str);
@@ -438,7 +438,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
Text *text= CTX_data_edit_text(C);
char *str;
- if(RNA_property_is_set(op->ptr, "filename"))
+ if(RNA_property_is_set(op->ptr, "path"))
return save_as_exec(C, op);
if(text->name)
@@ -448,7 +448,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
else
str= G.sce;
- RNA_string_set(op->ptr, "filename", str);
+ RNA_string_set(op->ptr, "path", str);
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -467,7 +467,7 @@ void TEXT_OT_save_as(wmOperatorType *ot)
ot->poll= text_edit_poll;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL);
}
/******************* run script operator *********************/
@@ -1731,7 +1731,7 @@ static int scroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
st->flags|= ST_SCROLL_SELECT;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1860,7 +1860,7 @@ static int scroll_bar_invoke(bContext *C, wmOperator *op, wmEvent *event)
st->flags|= ST_SCROLL_SELECT;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -2115,7 +2115,7 @@ static int set_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
scu->sell= txt_get_span(st->text->lines.first, st->text->sell);
scu->selc= st->text->selc;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
set_cursor_apply(C, op, event);
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 8f7486f81d9..0f05eb0149d 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -202,12 +202,12 @@ static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar
/* add handlers, stuff you only do once or on area/region changes */
static void time_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "TimeLine", SPACE_TIME, 0); /* XXX weak? */
+ keymap= WM_keymap_find(wm, "TimeLine", SPACE_TIME, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c
index a833cca095c..2b073f269bf 100644
--- a/source/blender/editors/space_time/time_ops.c
+++ b/source/blender/editors/space_time/time_ops.c
@@ -142,7 +142,7 @@ void time_operatortypes(void)
void time_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "TimeLine", SPACE_TIME, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "TimeLine", SPACE_TIME, 0);
WM_keymap_add_item(keymap, "TIME_OT_start_frame_set", SKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TIME_OT_end_frame_set", EKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile
index 07102157854..9204f2482c6 100644
--- a/source/blender/editors/space_view3d/Makefile
+++ b/source/blender/editors/space_view3d/Makefile
@@ -53,6 +53,9 @@ CPPFLAGS += -I../../render/extern/include
CPPFLAGS += -I../../blenfont
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I$(NAN_SMOKE)/include
-# own include
+ifneq ($(NAN_NO_KETSJI),true)
+ CPPFLAGS += -I../../../kernel/gen_system
+endif
+# own include
CPPFLAGS += -I../include
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index fa810677fe8..028d666dc71 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -639,7 +639,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
/* figure out the sizes of spheres */
if (ebone) {
- /* this routine doesn't call set_matrix_editbone() that calculates it */
+ /* this routine doesn't call get_matrix_editbone() that calculates it */
ebone->length = VecLenf(ebone->head, ebone->tail);
length= ebone->length;
@@ -749,7 +749,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
/* figure out the sizes of spheres */
if (ebone) {
- /* this routine doesn't call set_matrix_editbone() that calculates it */
+ /* this routine doesn't call get_matrix_editbone() that calculates it */
ebone->length = VecLenf(ebone->head, ebone->tail);
length= ebone->length;
@@ -1516,15 +1516,25 @@ static void draw_pose_dofs(Object *ob)
}
}
+static void bone_matrix_translate_y(float mat[][4], float y)
+{
+ float trans[3];
+
+ VECCOPY(trans, mat[1]);
+ VecMulf(trans, y);
+ VecAddf(mat[3], mat[3], trans);
+}
+
/* assumes object is Armature with pose */
-static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
+static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt)
{
+ RegionView3D *rv3d= ar->regiondata;
Object *ob= base->object;
bArmature *arm= ob->data;
bPoseChannel *pchan;
Bone *bone;
GLfloat tmp;
- float smat[4][4], imat[4][4];
+ float smat[4][4], imat[4][4], bmat[4][4];
int index= -1;
short do_dashed= 3, draw_wire= 0;
short flag, constflag;
@@ -1809,15 +1819,21 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
/* Draw names of bone */
if (arm->flag & ARM_DRAWNAMES) {
VecMidf(vec, pchan->pose_head, pchan->pose_tail);
- view3d_object_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10);
+ view3d_cached_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10);
}
/* Draw additional axes on the bone tail */
if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) {
glPushMatrix();
- glMultMatrixf(pchan->pose_mat);
- glTranslatef(0.0f, pchan->bone->length, 0.0f);
- drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS);
+ Mat4CpyMat4(bmat, pchan->pose_mat);
+ bone_matrix_translate_y(bmat, pchan->bone->length);
+ glMultMatrixf(bmat);
+
+ /* do cached text draw immediate to include transform */
+ view3d_cached_text_draw_begin();
+ drawaxes(pchan->bone->length*0.25f, 0, OB_ARROWS);
+ view3d_cached_text_draw_end(v3d, ar, 1, bmat);
+
glPopMatrix();
}
}
@@ -1830,32 +1846,28 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
}
/* in editmode, we don't store the bone matrix... */
-static void set_matrix_editbone(EditBone *eBone)
+static void get_matrix_editbone(EditBone *eBone, float bmat[][4])
{
- float delta[3],offset[3];
- float mat[3][3], bmat[4][4];
+ float delta[3];
+ float mat[3][3];
/* Compose the parent transforms (i.e. their translations) */
- VECCOPY(offset, eBone->head);
-
- glTranslatef(offset[0],offset[1],offset[2]);
-
VecSubf(delta, eBone->tail, eBone->head);
eBone->length = (float)sqrt(delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]);
vec_roll_to_mat3(delta, eBone->roll, mat);
Mat4CpyMat3(bmat, mat);
-
- glMultMatrixf(bmat);
-
+
+ VecAddf(bmat[3], bmat[3], eBone->head);
}
-static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
+static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
{
+ RegionView3D *rv3d= ar->regiondata;
EditBone *eBone;
bArmature *arm= ob->data;
- float smat[4][4], imat[4][4];
+ float smat[4][4], imat[4][4], bmat[4][4];
unsigned int index;
int flag;
@@ -1893,7 +1905,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A)==0) {
glPushMatrix();
- set_matrix_editbone(eBone);
+ get_matrix_editbone(eBone, bmat);
+ glMultMatrixf(bmat);
/* catch exception for bone with hidden parent */
flag= eBone->flag;
@@ -1941,7 +1954,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
}
else {
glPushMatrix();
- set_matrix_editbone(eBone);
+ get_matrix_editbone(eBone, bmat);
+ glMultMatrixf(bmat);
if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
@@ -1994,14 +2008,20 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
if (arm->flag & ARM_DRAWNAMES) {
VecMidf(vec, eBone->head, eBone->tail);
glRasterPos3fv(vec);
- view3d_object_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10);
+ view3d_cached_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10);
}
/* Draw additional axes */
if (arm->flag & ARM_DRAWAXES) {
glPushMatrix();
- set_matrix_editbone(eBone);
- glTranslatef(0.0f, eBone->length, 0.0f);
+ get_matrix_editbone(eBone, bmat);
+ bone_matrix_translate_y(bmat, eBone->length);
+ glMultMatrixf(bmat);
+
+ /* do cached text draw immediate to include transform */
+ view3d_cached_text_draw_begin();
drawaxes(eBone->length*0.25f, 0, OB_ARROWS);
+ view3d_cached_text_draw_end(v3d, ar, 1, bmat);
+
glPopMatrix();
}
@@ -2021,8 +2041,9 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
/* draw bone paths
* - in view space
*/
-static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
+static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob)
{
+ RegionView3D *rv3d= ar->regiondata;
AnimData *adt= BKE_animdata_from_id(&ob->id);
bArmature *arm= ob->data;
bPoseChannel *pchan;
@@ -2155,12 +2176,12 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
/* only draw framenum if several consecutive highlighted points don't occur on same point */
if (a == 0) {
sprintf(str, "%d", (a+sfra));
- view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+ view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
}
else if ((a > stepsize) && (a < len-stepsize)) {
if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) {
sprintf(str, "%d", (a+sfra));
- view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+ view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
}
}
}
@@ -2202,7 +2223,7 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
char str[32];
sprintf(str, "%d", (a+sfra));
- view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+ view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
}
}
}
@@ -2253,7 +2274,7 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
/* draw ghosts that occur within a frame range
* note: object should be in posemode
*/
-static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob= base->object;
AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2295,7 +2316,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2315,7 +2336,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d
/* draw ghosts on keyframes in action within range
* - object should be in posemode
*/
-static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob= base->object;
AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2374,7 +2395,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d,
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2394,7 +2415,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d,
/* draw ghosts around current frame
* - object is supposed to be armature in posemode
*/
-static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob= base->object;
AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2444,7 +2465,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
}
@@ -2459,7 +2480,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
}
}
@@ -2480,7 +2501,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
/* ********************************** Armature Drawing - Main ************************* */
/* called from drawobject.c, return 1 if nothing was drawn */
-int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
+int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag)
{
Object *ob= base->object;
bArmature *arm= ob->data;
@@ -2504,7 +2525,7 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
/* editmode? */
if(arm->edbo) {
arm->flag |= ARM_EDITMODE;
- draw_ebones(v3d, rv3d, ob, dt);
+ draw_ebones(v3d, ar, ob, dt);
arm->flag &= ~ARM_EDITMODE;
}
else{
@@ -2513,32 +2534,36 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
/* drawing posemode selection indices or colors only in these cases */
if(!(base->flag & OB_FROMDUPLI)) {
if(G.f & G_PICKSEL) {
- if(ob->mode & OB_MODE_POSE)
+ if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
+ if(ob==modifiers_isDeformedByArmature(OBACT))
+ arm->flag |= ARM_POSEMODE;
+ }
+ else if(ob->mode & OB_MODE_POSE)
arm->flag |= ARM_POSEMODE;
}
else if(ob->mode & OB_MODE_POSE) {
if (arm->ghosttype == ARM_GHOST_RANGE) {
- draw_ghost_poses_range(scene, v3d, rv3d, base);
+ draw_ghost_poses_range(scene, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_KEYS) {
- draw_ghost_poses_keys(scene, v3d, rv3d, base);
+ draw_ghost_poses_keys(scene, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_CUR) {
if (arm->ghostep)
- draw_ghost_poses(scene, v3d, rv3d, base);
+ draw_ghost_poses(scene, v3d, ar, base);
}
if ((flag & DRAW_SCENESET)==0) {
if(ob==OBACT)
arm->flag |= ARM_POSEMODE;
- else if(ob->mode & OB_MODE_WEIGHT_PAINT) {
- if(OBACT && ob==modifiers_isDeformedByArmature(OBACT))
+ else if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
+ if(ob==modifiers_isDeformedByArmature(OBACT))
arm->flag |= ARM_POSEMODE;
}
- draw_pose_paths(scene, v3d, rv3d, ob);
+ draw_pose_paths(scene, v3d, ar, ob);
}
}
}
- draw_pose_channels(scene, v3d, rv3d, base, dt);
+ draw_pose_channels(scene, v3d, ar, base, dt);
arm->flag &= ~ARM_POSEMODE;
if(ob->mode & OB_MODE_POSE)
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index fb53184b890..eedcc33af37 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -435,11 +435,11 @@ void drawaxes(float size, int flag, char drawtype)
// patch for 3d cards crashing on glSelect for text drawing (IBM)
if((flag & DRAW_PICKING) == 0) {
if (axis==0)
- view3d_object_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
+ view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
else if (axis==1)
- view3d_object_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
+ view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
else
- view3d_object_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
+ view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
}
}
break;
@@ -497,23 +497,32 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se
if(v3d->zbuf) glDepthFunc(GL_LEQUAL);
}
-/* *********** text drawing for object ************* */
-static ListBase strings= {NULL, NULL};
+/* *********** text drawing for object/particles/armature ************* */
-typedef struct ViewObjectString {
- struct ViewObjectString *next, *prev;
+static ListBase CachedText[3];
+static int CachedTextLevel= 0;
+
+typedef struct ViewCachedString {
+ struct ViewCachedString *next, *prev;
float vec[3], col[4];
char str[128];
short mval[2];
short xoffs;
-} ViewObjectString;
+} ViewCachedString;
+void view3d_cached_text_draw_begin()
+{
+ ListBase *strings= &CachedText[CachedTextLevel];
+ strings->first= strings->last= NULL;
+ CachedTextLevel++;
+}
-void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs)
+void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs)
{
- ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
+ ListBase *strings= &CachedText[CachedTextLevel-1];
+ ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString");
- BLI_addtail(&strings, vos);
+ BLI_addtail(strings, vos);
BLI_strncpy(vos->str, str, 128);
vos->vec[0]= x;
vos->vec[1]= y;
@@ -522,22 +531,23 @@ void view3d_object_text_draw_add(float x, float y, float z, char *str, short xof
vos->xoffs= xoffs;
}
-static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
{
- ViewObjectString *vos;
- int tot= 0;
+ RegionView3D *rv3d= ar->regiondata;
+ ListBase *strings= &CachedText[CachedTextLevel-1];
+ ViewCachedString *vos;
+ int a, tot= 0;
/* project first and test */
- for(vos= strings.first; vos; vos= vos->next) {
+ for(vos= strings->first; vos; vos= vos->next) {
+ if(mat)
+ Mat4MulVecfl(mat, vos->vec);
view3d_project_short_clip(ar, vos->vec, vos->mval);
if(vos->mval[0]!=IS_CLIPPED)
tot++;
}
-
+
if(tot) {
- RegionView3D *rv3d= ar->regiondata;
- int a;
-
if(rv3d->rflag & RV3D_CLIPPING)
for(a=0; a<6; a++)
glDisable(GL_CLIP_PLANE0+a);
@@ -545,16 +555,22 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
wmPushMatrix();
ED_region_pixelspace(ar);
- if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ if(depth_write) {
+ if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ }
+ else glDepthMask(0);
- for(vos= strings.first; vos; vos= vos->next) {
+ for(vos= strings->first; vos; vos= vos->next) {
if(vos->mval[0]!=IS_CLIPPED) {
glColor3fv(vos->col);
- BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 0.0, vos->str);
+ BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str);
}
}
- if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ if(depth_write) {
+ if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+ else glDepthMask(1);
wmPopMatrix();
@@ -563,10 +579,14 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
glEnable(GL_CLIP_PLANE0+a);
}
- if(strings.first)
- BLI_freelistN(&strings);
+ if(strings->first)
+ BLI_freelistN(strings);
+
+ CachedTextLevel--;
}
+/* ******************** primitive drawing ******************* */
+
static void drawcube(void)
{
@@ -2240,7 +2260,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
else
sprintf(val, conv_float, VecLenf(v1, v2));
- view3d_object_text_draw_add(x, y, z, val, 0);
+ view3d_cached_text_draw_add(x, y, z, val, 0);
}
}
}
@@ -2279,7 +2299,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
else
sprintf(val, conv_float, area);
- view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
+ view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
}
}
}
@@ -2319,31 +2339,31 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) {
/* Vec 1 */
- sprintf(val,"%.3f", VecAngle3(v4, v1, v2));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2)));
VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f);
- view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
+ view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
}
if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) {
/* Vec 2 */
- sprintf(val,"%.3f", VecAngle3(v1, v2, v3));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3)));
VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f);
- view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+ view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
}
if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) {
/* Vec 3 */
if(efa->v4)
- sprintf(val,"%.3f", VecAngle3(v2, v3, v4));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v4)));
else
- sprintf(val,"%.3f", VecAngle3(v2, v3, v1));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1)));
VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f);
- view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+ view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
}
/* Vec 4 */
if(efa->v4) {
if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) {
- sprintf(val,"%.3f", VecAngle3(v3, v4, v1));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1)));
VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f);
- view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+ view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
}
}
}
@@ -3336,82 +3356,8 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
return retval;
}
-/* *********** text drawing for particles ************* */
-static ListBase pstrings= {NULL, NULL};
-
-typedef struct ViewParticleString {
- struct ViewParticleString *next, *prev;
- float vec[3], col[4];
- char str[128];
- short mval[2];
- short xoffs;
-} ViewParticleString;
-
-
-void view3d_particle_text_draw_add(float x, float y, float z, char *str, short xoffs)
-{
- ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
-
- BLI_addtail(&pstrings, vos);
- BLI_strncpy(vos->str, str, 128);
- vos->vec[0]= x;
- vos->vec[1]= y;
- vos->vec[2]= z;
- glGetFloatv(GL_CURRENT_COLOR, vos->col);
- vos->xoffs= xoffs;
-}
-
-static void view3d_particle_text_draw(View3D *v3d, ARegion *ar)
-{
- ViewObjectString *vos;
- int tot= 0;
-
- /* project first and test */
- for(vos= pstrings.first; vos; vos= vos->next) {
- project_short(ar, vos->vec, vos->mval);
- if(vos->mval[0]!=IS_CLIPPED)
- tot++;
- }
-
- if(tot) {
- RegionView3D *rv3d= ar->regiondata;
- int a;
-
- if(rv3d->rflag & RV3D_CLIPPING)
- for(a=0; a<6; a++)
- glDisable(GL_CLIP_PLANE0+a);
-
- wmPushMatrix();
- ED_region_pixelspace(ar);
-
- if(v3d->zbuf) glDepthMask(0);
+/* *********** drawing for particles ************* */
- for(vos= pstrings.first; vos; vos= vos->next) {
- if(vos->mval[0]!=IS_CLIPPED) {
- glColor3fv(vos->col);
- BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 2.0, vos->str);
- }
- }
-
- if(v3d->zbuf) glDepthMask(1);
-
- wmPopMatrix();
-
- if(rv3d->rflag & RV3D_CLIPPING)
- for(a=0; a<6; a++)
- glEnable(GL_CLIP_PLANE0+a);
- }
-
- if(pstrings.first)
- BLI_freelistN(&pstrings);
-}
-typedef struct ParticleDrawData {
- float *vdata, *vd;
- float *ndata, *nd;
- float *cdata, *cd;
- float *vedata, *ved;
- float *ma_r, *ma_g, *ma_b;
-} ParticleDrawData;
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
{
float vec[3], vec2[3];
@@ -3576,7 +3522,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
ParticleData *pars, *pa;
ParticleKey state, *states=0;
ParticleBillboardData bb;
- ParticleDrawData pdd;
+ ParticleSimulationData sim = {scene, ob, psys, NULL};
+ ParticleDrawData *pdd = psys->pdd;
Material *ma;
float vel[3], imat[4][4];
float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
@@ -3607,9 +3554,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(part->draw_as==PART_DRAW_NOT) return;
/* 2. */
+ sim.psmd = psmd = psys_get_modifier(ob,psys);
+
if(part->phystype==PART_PHYS_KEYED){
if(psys->flag&PSYS_KEYED){
- psys_count_keyed_targets(ob,psys);
+ psys_count_keyed_targets(&sim);
if(psys->totkeyed==0)
return;
}
@@ -3627,8 +3576,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
totchild=0;
else
totchild=psys->totchild*part->disp/100;
-
- memset(&pdd, 0, sizeof(ParticleDrawData));
ma= give_current_material(ob,part->omat);
@@ -3643,18 +3590,18 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
ma_g = ma->g;
ma_b = ma->b;
- pdd.ma_r = &ma_r;
- pdd.ma_g = &ma_g;
- pdd.ma_b = &ma_b;
+ if(pdd) {
+ pdd->ma_r = &ma_r;
+ pdd->ma_g = &ma_g;
+ pdd->ma_b = &ma_b;
+ }
create_cdata = 1;
}
else
cpack(0);
- psmd= psys_get_modifier(ob,psys);
-
- timestep= psys_get_timestep(part);
+ timestep= psys_get_timestep(&sim);
if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
float mat[4][4];
@@ -3748,54 +3695,65 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
/* 4. */
if(draw_as && draw_as!=PART_DRAW_PATH) {
int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
-
+
+ if(!pdd)
+ pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData");
+
if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
tot_vec_size *= part->trail_count;
psys_make_temp_pointcache(ob, psys);
}
+ if(pdd->tot_vec_size != tot_vec_size)
+ psys_free_pdd(psys);
+
if(draw_as!=PART_DRAW_CIRC) {
switch(draw_as) {
case PART_DRAW_AXIS:
case PART_DRAW_CROSS:
if(draw_as != PART_DRAW_CROSS || create_cdata)
- pdd.cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
- pdd.vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
+ if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
+ if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
break;
case PART_DRAW_LINE:
if(create_cdata)
- pdd.cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
- pdd.vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
+ if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
+ if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
break;
case PART_DRAW_BB:
if(create_cdata)
- pdd.cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
- pdd.vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
- pdd.ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
+ if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
+ if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
+ if(!pdd->ndata) pdd->ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
break;
default:
if(create_cdata)
- pdd.cdata=MEM_callocN(tot_vec_size, "particle_cdata");
- pdd.vdata=MEM_callocN(tot_vec_size, "particle_vdata");
+ if(!pdd->cdata) pdd->cdata=MEM_callocN(tot_vec_size, "particle_cdata");
+ if(!pdd->vdata) pdd->vdata=MEM_callocN(tot_vec_size, "particle_vdata");
}
}
if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
- pdd.vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
+ if(!pdd->vedata) pdd->vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
need_v = 1;
}
- pdd.vd= pdd.vdata;
- pdd.ved= pdd.vedata;
- pdd.cd= pdd.cdata;
- pdd.nd= pdd.ndata;
+ pdd->vd= pdd->vdata;
+ pdd->ved= pdd->vedata;
+ pdd->cd= pdd->cdata;
+ pdd->nd= pdd->ndata;
+ pdd->tot_vec_size= tot_vec_size;
- psys->lattice= psys_get_lattice(scene, ob, psys);
+ psys->lattice= psys_get_lattice(&sim);
}
if(draw_as){
/* 5. */
- for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
+ if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED)
+ && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) {
+ totpoint = pdd->totpoint; /* draw data is up to date */
+ }
+ else for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
/* setup per particle individual stuff */
if(a<totpart){
if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
@@ -3805,9 +3763,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pa_birthtime=pa->time;
pa_dietime = pa->dietime;
pa_size=pa->size;
- if(part->phystype==PART_PHYS_BOIDS) {
+ if(part->phystype==PART_PHYS_BOIDS)
pa_health = pa->boid->data.health;
- }
else
pa_health = -1.0;
@@ -3842,10 +3799,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
#endif // XXX old animation system
- BLI_srandom(psys->seed+a);
-
- r_tilt = 2.0f*(BLI_frand() - 0.5f);
- r_length = BLI_frand();
+ r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
+ r_length = PSYS_FRAND(a + 22);
}
else{
ChildParticle *cpa= &psys->child[a-totpart];
@@ -3876,8 +3831,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pa_health = -1.0;
- r_tilt = 2.0f * cpa->rand[2];
- r_length = cpa->rand[1];
+ r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
+ r_length = PSYS_FRAND(a + 22);
}
if(draw_as!=PART_DRAW_PATH){
@@ -3899,7 +3854,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
continue;
state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
- psys_get_particle_on_path(scene,ob,psys,a,&state,need_v);
+ psys_get_particle_on_path(&sim,a,&state,need_v);
if(psys->parent)
Mat4MulVecfl(psys->parent->obmat, state.co);
@@ -3911,7 +3866,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
bb.time = ct;
}
- draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
+ draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
totpoint++;
drawn = 1;
@@ -3920,7 +3875,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
else
{
state.time=cfra;
- if(psys_get_particle_state(scene,ob,psys,a,&state,0)){
+ if(psys_get_particle_state(&sim,a,&state,0)){
if(psys->parent)
Mat4MulVecfl(psys->parent->obmat, state.co);
@@ -3931,7 +3886,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
bb.time = pa_time;
}
- draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
+ draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
totpoint++;
drawn = 1;
@@ -3941,13 +3896,13 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(drawn) {
/* additional things to draw for each particle */
/* (velocity, size and number) */
- if(pdd.vedata){
- VECCOPY(pdd.ved,state.co);
- pdd.ved+=3;
+ if(pdd->vedata){
+ VECCOPY(pdd->ved,state.co);
+ pdd->ved+=3;
VECCOPY(vel,state.vel);
VecMulf(vel,timestep);
- VECADD(pdd.ved,state.co,vel);
- pdd.ved+=3;
+ VECADD(pdd->ved,state.co,vel);
+ pdd->ved+=3;
totve++;
}
@@ -3971,7 +3926,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
sprintf(val, "%s %.2f", val, pa_health);
/* in path drawing state.co is the end point */
- view3d_particle_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0);
+ view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0);
}
}
}
@@ -4059,17 +4014,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glDisableClientState(GL_COLOR_ARRAY);
/* setup created data arrays */
- if(pdd.vdata){
+ if(pdd->vdata){
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pdd.vdata);
+ glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
}
else
glDisableClientState(GL_VERTEX_ARRAY);
/* billboards are drawn this way */
- if(pdd.ndata && ob_dt>OB_WIRE){
+ if(pdd->ndata && ob_dt>OB_WIRE){
glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 0, pdd.ndata);
+ glNormalPointer(GL_FLOAT, 0, pdd->ndata);
glEnable(GL_LIGHTING);
}
else{
@@ -4077,9 +4032,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glDisable(GL_LIGHTING);
}
- if(pdd.cdata){
+ if(pdd->cdata){
glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(3, GL_FLOAT, 0, pdd.cdata);
+ glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
}
/* draw created data arrays */
@@ -4101,14 +4056,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glDrawArrays(GL_POINTS, 0, totpoint);
break;
}
+
+ pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
+ pdd->totpoint = totpoint;
}
- if(pdd.vedata){
+ if(pdd->vedata){
glDisableClientState(GL_COLOR_ARRAY);
cpack(0xC0C0C0);
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pdd.vedata);
+ glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
glDrawArrays(GL_LINES, 0, 2*totve);
}
@@ -4125,14 +4083,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(states)
MEM_freeN(states);
- if(pdd.vdata)
- MEM_freeN(pdd.vdata);
- if(pdd.vedata)
- MEM_freeN(pdd.vedata);
- if(pdd.cdata)
- MEM_freeN(pdd.cdata);
- if(pdd.ndata)
- MEM_freeN(pdd.ndata);
psys->flag &= ~PSYS_DRAWING;
@@ -4159,10 +4109,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj
float *pathcol = NULL, *pcol;
- if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) {
+ if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
PE_update_object(scene, ob, 0);
- edit->psys->flag &= ~PSYS_HAIR_UPDATED;
- }
/* create path and child path cache if it doesn't exist already */
if(edit->pathcache==0)
@@ -5193,8 +5141,9 @@ static void drawtexspace(Object *ob)
}
/* draws wire outline */
-static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
+ RegionView3D *rv3d= ar->regiondata;
Object *ob= base->object;
glLineWidth(2.0);
@@ -5213,7 +5162,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
}
else if(ob->type==OB_ARMATURE) {
if(!(ob->mode & OB_MODE_POSE))
- draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0);
+ draw_armature(scene, v3d, ar, base, OB_WIRE, 0);
}
glLineWidth(1.0);
@@ -5323,11 +5272,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data)
glVertex3fv(v);
glEnd();
if (axis==0)
- view3d_object_text_draw_add(v[0], v[1], v[2], "px", 0);
+ view3d_cached_text_draw_add(v[0], v[1], v[2], "px", 0);
else if (axis==1)
- view3d_object_text_draw_add(v[0], v[1], v[2], "py", 0);
+ view3d_cached_text_draw_add(v[0], v[1], v[2], "py", 0);
else
- view3d_object_text_draw_add(v[0], v[1], v[2], "pz", 0);
+ view3d_cached_text_draw_add(v[0], v[1], v[2], "pz", 0);
}
glLineWidth (1.0f);
setlinestyle(0);
@@ -5370,6 +5319,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
}
+ /* no return after this point, otherwise leaks */
+ view3d_cached_text_draw_begin();
+
/* draw keys? */
#if 0 // XXX old animation system
if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) {
@@ -5554,7 +5506,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=scene->obedit && (flag && DRAW_SCENESET)==0) {
if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) {
- drawSolidSelect(scene, v3d, rv3d, base);
+ drawSolidSelect(scene, v3d, ar, base);
}
}
}
@@ -5700,7 +5652,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
break;
case OB_ARMATURE:
if(dt>OB_WIRE) GPU_enable_material(0, NULL); // we use default material
- empty_object= draw_armature(scene, v3d, rv3d, base, dt, flag);
+ empty_object= draw_armature(scene, v3d, ar, base, dt, flag);
if(dt>OB_WIRE) GPU_disable_material();
break;
default:
@@ -5720,10 +5672,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
wmLoadMatrix(rv3d->viewmat);
+ view3d_cached_text_draw_begin();
+
for(psys=ob->particlesystem.first; psys; psys=psys->next)
draw_new_particle_system(scene, v3d, rv3d, base, psys, dt);
- view3d_particle_text_draw(v3d, ar);
+ view3d_cached_text_draw_end(v3d, ar, 0, NULL);
wmMultMatrix(ob->obmat);
@@ -5791,16 +5745,61 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
{
if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG))
{
+// #if 0
smd->domain->tex = NULL;
GPU_create_smoke(smd, 0);
- draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow);
+ draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow);
GPU_free_smoke(smd);
+// #endif
+#if 0
+ int x, y, z;
+ float *density = smoke_get_density(smd->domain->fluid);
+
+ wmLoadMatrix(rv3d->viewmat);
+ // wmMultMatrix(ob->obmat);
+
+ if(col || (ob->flag & SELECT)) cpack(0xFFFFFF);
+ glDepthMask(GL_FALSE);
+ glEnable(GL_BLEND);
+
+
+ // glPointSize(3.0);
+ bglBegin(GL_POINTS);
+
+ for(x = 0; x < smd->domain->res[0]; x++)
+ for(y = 0; y < smd->domain->res[1]; y++)
+ for(z = 0; z < smd->domain->res[2]; z++)
+ {
+ float tmp[3];
+ int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
+
+ if(density[index] > FLT_EPSILON)
+ {
+ float color[3];
+ VECCOPY(tmp, smd->domain->p0);
+ tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5;
+ tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5;
+ tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5;
+ color[0] = color[1] = color[2] = density[index];
+ glColor3fv(color);
+ bglVertex3fv(tmp);
+ }
+ }
+
+ bglEnd();
+ glPointSize(1.0);
+
+ wmMultMatrix(ob->obmat);
+ glDisable(GL_BLEND);
+ glDepthMask(GL_TRUE);
+ if(col) cpack(col);
+#endif
}
- else if(smd->domain->wt || (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG))
+ else if(smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG))
{
smd->domain->tex = NULL;
GPU_create_smoke(smd, 1);
- draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow);
+ draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow);
GPU_free_smoke(smd);
}
}
@@ -5830,7 +5829,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
/* but, we also dont draw names for sets or duplicators */
if(flag == 0) {
- view3d_object_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
+ view3d_cached_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
}
}
/*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
@@ -5853,7 +5852,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
/* return warning, this is cached text draw */
- view3d_object_text_draw(v3d, ar);
+ view3d_cached_text_draw_end(v3d, ar, 1, NULL);
wmLoadMatrix(rv3d->viewmat);
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index c8eda10566c..ef3627e2b12 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -121,31 +121,7 @@
struct GPUTexture;
-/* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
-static float cv[][3] = {
- {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
- {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
-};
-
-// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
-static float edges[12][2][3] = {
- {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
- {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
- {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
- {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
-
- {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
- {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
- {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
- {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
-
- {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
- {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
- {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
- {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}
-};
-
-int intersect_edges(float *points, float a, float b, float c, float d)
+int intersect_edges(float *points, float a, float b, float c, float d, float edges[12][2][3])
{
int i;
float t;
@@ -154,7 +130,7 @@ int intersect_edges(float *points, float a, float b, float c, float d)
for (i=0; i<12; i++) {
t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d)
/ (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]);
- if ((t>0)&&(t<2)) {
+ if ((t>0)&&(t<1)) {
points[numpoints * 3 + 0] = edges[i][0][0] + edges[i][1][0]*t;
points[numpoints * 3 + 1] = edges[i][0][1] + edges[i][1][1]*t;
points[numpoints * 3 + 2] = edges[i][0][2] + edges[i][1][2]*t;
@@ -191,9 +167,8 @@ static int larger_pow2(int n)
return n*2;
}
-void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3], float dx, GPUTexture *tex_shadow)
+void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow)
{
- Object *ob = base->object;
RegionView3D *rv3d= ar->regiondata;
float viewnormal[3];
@@ -204,6 +179,30 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
float cor[3] = {1.,1.,1.};
int gl_depth = 0, gl_blend = 0;
+ /* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
+ float cv[][3] = {
+ {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
+ {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
+ };
+
+ // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
+ float edges[12][2][3] = {
+ {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
+ {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
+ {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
+ {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
+
+ {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}},
+ {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}},
+ {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}},
+ {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}},
+
+ {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}},
+ {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}},
+ {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}},
+ {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}
+ };
+
/* Fragment program to calculate the 3dview of smoke */
/* using 2 textures, density and shadow */
const char *text = "!!ARBfp1.0\n"
@@ -223,13 +222,84 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
"MUL temp.b, temp.b, shadow.r;\n"
"MOV result.color, temp;\n"
"END\n";
- unsigned int prog;
+ GLuint prog;
+
+
+ float size[3];
+
+ VECSUB(size, max, min);
+
+ // maxx, maxy, maxz
+ cv[0][0] = max[0];
+ cv[0][1] = max[1];
+ cv[0][2] = max[2];
+ // minx, maxy, maxz
+ cv[1][0] = min[0];
+ cv[1][1] = max[1];
+ cv[1][2] = max[2];
+ // minx, miny, maxz
+ cv[2][0] = min[0];
+ cv[2][1] = min[1];
+ cv[2][2] = max[2];
+ // maxx, miny, maxz
+ cv[3][0] = max[0];
+ cv[3][1] = min[1];
+ cv[3][2] = max[2];
+
+ // maxx, maxy, minz
+ cv[4][0] = max[0];
+ cv[4][1] = max[1];
+ cv[4][2] = min[2];
+ // minx, maxy, minz
+ cv[5][0] = min[0];
+ cv[5][1] = max[1];
+ cv[5][2] = min[2];
+ // minx, miny, minz
+ cv[6][0] = min[0];
+ cv[6][1] = min[1];
+ cv[6][2] = min[2];
+ // maxx, miny, minz
+ cv[7][0] = max[0];
+ cv[7][1] = min[1];
+ cv[7][2] = min[2];
+
+ VECCOPY(edges[0][0], cv[4]); // maxx, maxy, minz
+ VECCOPY(edges[1][0], cv[5]); // minx, maxy, minz
+ VECCOPY(edges[2][0], cv[6]); // minx, miny, minz
+ VECCOPY(edges[3][0], cv[7]); // maxx, miny, minz
+
+ VECCOPY(edges[4][0], cv[3]); // maxx, miny, maxz
+ VECCOPY(edges[5][0], cv[2]); // minx, miny, maxz
+ VECCOPY(edges[6][0], cv[6]); // minx, miny, minz
+ VECCOPY(edges[7][0], cv[7]); // maxx, miny, minz
+
+ VECCOPY(edges[8][0], cv[1]); // minx, maxy, maxz
+ VECCOPY(edges[9][0], cv[2]); // minx, miny, maxz
+ VECCOPY(edges[10][0], cv[6]); // minx, miny, minz
+ VECCOPY(edges[11][0], cv[5]); // minx, maxy, minz
+
+ // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]);
+
+ edges[0][1][2] = size[2];
+ edges[1][1][2] = size[2];
+ edges[2][1][2] = size[2];
+ edges[3][1][2] = size[2];
+
+ edges[4][1][1] = size[1];
+ edges[5][1][1] = size[1];
+ edges[6][1][1] = size[1];
+ edges[7][1][1] = size[1];
+
+ edges[8][1][0] = size[0];
+ edges[9][1][0] = size[0];
+ edges[10][1][0] = size[0];
+ edges[11][1][0] = size[0];
glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend);
glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth);
wmLoadMatrix(rv3d->viewmat);
- wmMultMatrix(ob->obmat);
+ // wmMultMatrix(ob->obmat);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
@@ -248,17 +318,19 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
y = cv[i][1] + viewnormal[1];
z = cv[i][2] + viewnormal[2];
- if ((x>=-1.0f)&&(x<=1.0f)
- &&(y>=-1.0f)&&(y<=1.0f)
- &&(z>=-1.0f)&&(z<=1.0f)) {
+ if ((x>=min[0])&&(x<=max[0])
+ &&(y>=min[1])&&(y<=max[1])
+ &&(z>=min[2])&&(z<=max[2])) {
break;
}
}
- if(GLEW_ARB_fragment_program)
+ // printf("i: %d\n", i);
+
+ if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program"))
{
- glGenProgramsARB(1, &prog);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ glGenProgramsARB(1, &prog);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog);
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text);
@@ -268,10 +340,14 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
// custom parameter for smoke style (higher = thicker)
glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0);
}
+ else
+ printf("Your gfx card does not support 3dview smoke drawing.\n");
GPU_texture_bind(tex, 0);
if(tex_shadow)
GPU_texture_bind(tex_shadow, 1);
+ else
+ printf("No volume shadow\n");
if (!GLEW_ARB_texture_non_power_of_two) {
cor[0] = (float)res[0]/(float)larger_pow2(res[0]);
@@ -295,7 +371,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
float p0[3];
// intersect_edges returns the intersection points of all cube edges with
// the given plane that lie within the cube
- numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d);
+ numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d, edges);
if (numpoints > 2) {
VECCOPY(p0, points);
@@ -318,7 +394,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
glBegin(GL_POLYGON);
for (i = 0; i < numpoints; i++) {
glColor3f(1.0, 1.0, 1.0);
- glTexCoord3d((points[i * 3 + 0] + 1.0)*cor[0]/2.0, (points[i * 3 + 1] + 1)*cor[1]/2.0, (points[i * 3 + 2] + 1.0)*cor[2]/2.0);
+ glTexCoord3d((points[i * 3 + 0] - min[0] )*cor[0]/size[0], (points[i * 3 + 1] - min[1])*cor[1]/size[1], (points[i * 3 + 2] - min[2])*cor[2]/size[2]);
glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
}
glEnd();
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2250c2e7718..c175f835d67 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -190,6 +190,8 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->lens= 35.0f;
v3d->near= 0.01f;
v3d->far= 500.0f;
+
+ v3d->twtype= V3D_MANIP_TRANSLATE;
/* header */
ar= MEM_callocN(sizeof(ARegion), "header for view3d");
@@ -257,7 +259,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
if(v3do->localvd) {
v3do->localvd= NULL;
v3do->properties_storage= NULL;
- v3do->localview= 0;
v3do->lay= v3dn->localvd->lay;
v3do->lay &= 0xFFFFFF;
}
@@ -273,101 +274,68 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
return (SpaceLink *)v3dn;
}
-static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
-{
- RegionView3D *rv3d= ar->regiondata;
- ListBase *keymap;
-
- /* copy last mode, then we can re-init the region maps */
- rv3d->lastmode= stype;
-
- keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0);
- if(ELEM(stype, 0, NS_MODE_OBJECT))
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0);
- if(stype==NS_EDITMODE_MESH)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Curve", 0, 0);
- if(stype==NS_EDITMODE_CURVE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
- if(stype==NS_EDITMODE_ARMATURE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
- if(stype==NS_MODE_POSE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Metaball", 0, 0);
- if(stype==NS_EDITMODE_MBALL)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Lattice", 0, 0);
- if(stype==NS_EDITMODE_LATTICE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- /* armature sketching needs to take over mouse */
- keymap= WM_keymap_listbase(wm, "Armature_Sketch", 0, 0);
- if(stype==NS_EDITMODE_ARMATURE)
- WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Particle", 0, 0);
- if(stype==NS_MODE_PARTICLE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- /* editfont keymap swallows all... */
- keymap= WM_keymap_listbase(wm, "Font", 0, 0);
- if(stype==NS_EDITMODE_TEXT)
- WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-}
-
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- RegionView3D *rv3d= ar->regiondata;
- ListBase *keymap;
+ wmKeyMap *keymap;
+
+ /* object ops. */
+ keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* own keymap */
- keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ /* pose is not modal, operator poll checks for this */
+ keymap= WM_keymap_find(wm, "Pose", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Object Mode", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Image Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Vertex Paint", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
+
+ keymap= WM_keymap_find(wm, "Weight Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Sculpt", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* object ops. */
- keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0);
+ keymap= WM_keymap_find(wm, "EditMesh", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* pose is not modal, operator poll checks for this */
- keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
+ keymap= WM_keymap_find(wm, "Curve", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* modal ops keymaps */
- view3d_modal_keymaps(wm, ar, rv3d->lastmode);
- /* operator poll checks for modes */
- keymap= WM_keymap_listbase(wm, "ImagePaint", 0, 0);
+ keymap= WM_keymap_find(wm, "Armature", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Pose", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Metaball", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Lattice", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ /* armature sketching needs to take over mouse */
+ keymap= WM_keymap_find(wm, "Armature_Sketch", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Particle", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ /* editfont keymap swallows all... */
+ keymap= WM_keymap_find(wm, "Font", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ /* own keymap, last so modes can override it */
+ keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -442,7 +410,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
case ND_MODE:
- view3d_modal_keymaps(wmn->wm, ar, wmn->subtype);
ED_region_tag_redraw(ar);
break;
}
@@ -452,6 +419,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
case ND_TRANSFORM:
+ case ND_POSE:
case ND_DRAW:
case ND_MODIFIER:
case ND_CONSTRAINT:
@@ -480,12 +448,21 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
}
+ break;
+ case NC_WORLD:
+ switch(wmn->data) {
+ case ND_WORLD_DRAW:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
case NC_LAMP:
switch(wmn->data) {
case ND_LIGHTING_DRAW:
ED_region_tag_redraw(ar);
break;
}
+ break;
case NC_IMAGE:
/* this could be more fine grained checks if we had
* more context than just the region */
@@ -514,7 +491,7 @@ static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -550,11 +527,11 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -592,6 +569,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
case ND_TRANSFORM:
+ case ND_POSE:
case ND_DRAW:
case ND_KEYS:
ED_region_tag_redraw(ar);
@@ -606,6 +584,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
break;
}
break;
+ case NC_BRUSH:
+ if(wmn->action==NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
case NC_SPACE:
if(wmn->data == ND_SPACE_VIEW3D)
ED_region_tag_redraw(ar);
@@ -616,16 +598,14 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
-
-
static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
{
ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1);
@@ -910,7 +890,7 @@ void ED_spacetype_view3d(void)
/* regions: listview/buttons */
art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region");
art->regionid = RGN_TYPE_UI;
- art->minsizex= 220; // XXX
+ art->minsizex= 180; // XXX
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
art->listener= view3d_buttons_area_listener;
art->init= view3d_buttons_area_init;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 54a8c375e69..ec72d72013b 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -302,60 +302,68 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
if((ob->parent) && (ob->partype == PARBONE)) but_y = 135;
else but_y = 150;
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
- uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
- uiBlockEndAlign(block);
+
memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
uiBlockBeginAlign(block);
if(tot==1) {
uiDefBut(block, LABEL, 0, "Vertex:", 0, 130, 200, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
- if(totw==1)
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 0, 50, 200, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
- uiBlockEndAlign(block);
-
- if(defstr[0]) {
- uiDefBut(block, LABEL, 1, "Vertex Deform Groups", 0, 40, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
-
+
+ if(totw==1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
+ uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
+ uiBlockEndAlign(block);
+ if(totweight)
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
+ }
+ else {
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NOP, "Weight:", 10, 20, 150, 20, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
- uiDefButI(block, MENU, B_REDR, defstr, 160, 20, 140, 20, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
+ uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
+ uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
uiBlockEndAlign(block);
+ if(totweight)
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
}
- else if(totweight)
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
-
}
else {
- uiDefBut(block, LABEL, 0, "Median:", 0, 130, 200, 20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Median:", 0, 130, 200, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
- if(totw==tot)
+ if(totw==tot) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
- uiBlockEndAlign(block);
- if(totweight)
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
- }
-
- if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */
- uiBlockBeginAlign(block);
- uiDefBut(block, BUT,B_SETPT_AUTO,"Auto", 10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)");
- uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)");
- uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
- uiDefBut(block, BUT,B_SETPT_FREE,"Free", 227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
- uiBlockEndAlign(block);
+ uiBlockEndAlign(block);
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
+ uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
+ uiBlockEndAlign(block);
+ if(totweight)
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
+ uiBlockEndAlign(block);
+ }
+ else {
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
+ uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
+ uiBlockEndAlign(block);
+ if(totweight)
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
+ uiBlockEndAlign(block);
+ }
}
-
+
if(totedge==1)
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
else if(totedge>1)
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:", 0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
}
else { // apply
@@ -468,6 +476,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
}
}
+#if 0
/* assumes armature active */
static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
{
@@ -486,10 +495,10 @@ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c
}
}
+#endif
static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
{
- uiBut *but;
bArmature *arm;
bPoseChannel *pchan;
Bone *bone= NULL;
@@ -503,22 +512,18 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
break;
}
- if (!pchan || !bone) return;
-
- if((ob->parent) && (ob->partype == PARBONE))
- but= uiDefBut (block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, bone->name, 1, 31, 0, 0, "");
- else
- but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
- uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
+ if (!pchan) {
+ uiDefBut(block, LABEL, 0, "No Bone Active", 0, 240, 100, 20, 0, 0, 0, 0, 0, "");
+ return;
+ }
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float quat[4];
/* convert to euler, passing through quats... */
AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]);
QuatToEul(quat, tfp->ob_eul);
}
- else if (pchan->rotmode == PCHAN_ROT_QUAT)
+ else if (pchan->rotmode == ROT_MODE_QUAT)
QuatToEul(pchan->quat, tfp->ob_eul);
else
VecCopyf(tfp->ob_eul, pchan->eul);
@@ -526,29 +531,43 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
tfp->ob_eul[1]*= 180.0/M_PI;
tfp->ob_eul[2]*= 180.0/M_PI;
+ uiDefBut(block, LABEL, 0, "Location:", 0, 240, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 10,140,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:", 30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 10,120,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:", 30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 10,100,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:", 30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
-
+ uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:", 0, 220, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:", 0, 200, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:", 0, 180, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 125, 220, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Location value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 125, 200, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Location value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 180, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed");
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 0, "Rotation:", 0, 160, 100, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_ARMATUREPANEL3, "X:", 0, 140, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL3, "Y:", 0, 120, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL3, "Z:", 0, 100, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 10,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:", 30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 10,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:", 30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 10,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:", 30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 125, 140, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Rotation value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 125, 120, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 125, 100, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed");
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 0, "Scale:", 0, 80, 100, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:", 0, 60, 120, 19, pchan->size, -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:", 0, 40, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:", 0, 20, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 160,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:", 180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 160,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:", 180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 160,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:", 180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 125, 60, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Scale value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 125, 40, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Scale value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 125, 20, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects z Scale value from being Transformed");
uiBlockEndAlign(block);
}
@@ -572,7 +591,6 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
{
bArmature *arm= ob->data;
EditBone *ebone;
- uiBut *but;
TransformProperties *tfp= v3d->properties_storage;
ebone= arm->edbo->first;
@@ -585,34 +603,31 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
if (!ebone)
return;
- if((ob->parent) && (ob->partype == PARBONE))
- but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, "");
- else
- but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
- uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
-
+ uiDefBut(block, LABEL, 0, "Head:", 0, 210, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:", 10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:", 10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:", 10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 190, 100, 19, ebone->head, -lim, lim, 10, 3, "X Location of the head end of the bone");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Y:", 0, 170, 100, 19, ebone->head+1, -lim, lim, 10, 3, "Y Location of the head end of the bone");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Z:", 0, 150, 100, 19, ebone->head+2, -lim, lim, 10, 3, "Z Location of the head end of the bone");
+ if (ebone->parent && ebone->flag & BONE_CONNECTED )
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:", 0, 130, 100, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "Head radius. Visualize with the Envelope display option");
+ else
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:", 0, 130, 100, 19, &ebone->rad_head, 0, lim, 10, 3, "Head radius. Visualize with the Envelope display option");
+ uiBlockEndAlign(block);
+
+ uiBlockEndAlign(block);
+ uiDefBut(block, LABEL, 0, "Tail:", 0, 110, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:", 160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:", 160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:", 160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 90, 100, 19, ebone->tail, -lim, lim, 10, 3, "X Location of the tail end of the bone");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Y:", 0, 70, 100, 19, ebone->tail+1, -lim, lim, 10, 3, "Y Location of the tail end of the bone");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Z:", 0, 50, 100, 19, ebone->tail+2, -lim, lim, 10, 3, "Z Location of the tail end of the bone");
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:", 0, 30, 100, 19, &ebone->rad_tail, 0, lim, 10, 3, "Tail radius. Visualize with the Envelope display option");
uiBlockEndAlign(block);
tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
-
- uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, B_REDR, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode");
-
+ uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 0, 0, 100, 19, tfp->ob_eul, -lim, lim, 1000, 3, "Bone rotation around head-tail axis");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
- if (ebone->parent && ebone->flag & BONE_CONNECTED )
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:", 10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
- else
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:", 10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
- uiBlockEndAlign(block);
+
+
}
static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
@@ -851,13 +866,13 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
eul[1]= M_PI*tfp->ob_eul[1]/180.0;
eul[2]= M_PI*tfp->ob_eul[2]/180.0;
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float quat[4];
/* convert to axis-angle, passing through quats */
EulToQuat(eul, quat);
QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]);
}
- else if (pchan->rotmode == PCHAN_ROT_QUAT)
+ else if (pchan->rotmode == ROT_MODE_QUAT)
EulToQuat(eul, pchan->quat);
else
VecCopyf(pchan->eul, eul);
@@ -871,7 +886,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
}
break;
case B_TRANSFORMSPACEADD:
- BIF_manageTransformOrientation(C, 1, 0);
+ BIF_createTransformOrientation(C, NULL, "", 1, 0);
break;
case B_TRANSFORMSPACECLEAR:
BIF_clearTransformOrientation(C);
@@ -1083,19 +1098,8 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) {
}
else {
- //bt= uiDefBut(block, TEX, B_IDNAME, "OB: ", 10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, "");
- //uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
-
if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) {
- // uiBlockBeginAlign(block);
- // uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object");
- if((ob->parent) && (ob->partype == PARBONE)) {
- // bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, "");
- // uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent);
- }
- else {
- strcpy(ob->parsubstr, "");
- }
+ strcpy(ob->parsubstr, "");
uiBlockEndAlign(block);
}
}
@@ -1113,14 +1117,18 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
else {
BoundBox *bb = NULL;
- uiDefBut(block, LABEL, 0, "Location:", 10, 170, 100, 20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Location:", 0, 300, 100, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 0, 280, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANEL, "Y:", 0, 260, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANEL, "Z:", 0, 240, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 10,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 10,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANEL, "Y:", 30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 10,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANEL, "Z:", 30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 125, 280, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Location value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 125, 260, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Location value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 240, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed");
+ uiBlockEndAlign(block);
tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
@@ -1128,40 +1136,53 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
uiBlockBeginAlign(block);
if ((ob->parent) && (ob->partype == PARBONE)) {
- uiDefBut(block, LABEL, 0, "Rotation:", 160, 170, 100, 20, 0, 0, 0, 0, 0, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 160,90,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
+ uiDefBut(block, LABEL, 0, "Rotation:", 0, 220, 100, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 0, 200, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 0, 180, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 0, 160, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 125, 200, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Rotation from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 125, 180, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 125, 160, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed");
+ uiBlockEndAlign(block);
}
else {
- uiDefBut(block, LABEL, 0, "Rotation:", 160, 170, 100, 20, 0, 0, 0, 0, 0, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 160,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
+ uiDefBut(block, LABEL, 0, "Rotation:", 0, 220, 100, 20, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 0, 200, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 0, 180, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 0, 160, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 125, 200, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Rotation value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 125, 180, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 125, 160, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed");
+ uiBlockEndAlign(block);
}
tfp->ob_scale[0]= ob->size[0];
tfp->ob_scale[1]= ob->size[1];
tfp->ob_scale[2]= ob->size[2];
- uiDefBut(block, LABEL, 0, "Scale:", 10, 90, 100, 20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Scale:", 0, 140, 100, 20, 0, 0, 0, 0, 0, "");
+ uiDefButS(block, OPTION, B_REDR, "Link", 60, 140, 50, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions");
uiBlockBeginAlign(block);
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 10, 70, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELSCALE, "X:", 30, 70, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 10, 50, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Y:", 30, 50, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
- uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 10, 30, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
- uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Z:", 30, 30, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELSCALE, "X:", 0, 120, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Y:", 0, 100, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
+ uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Z:", 0, 80, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
uiBlockEndAlign(block);
- uiDefButS(block, TOG, B_REDR, "Link Scale", 10, 0, 140, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions");
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 125, 120, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Scale value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 125, 100, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Scale value from being Transformed");
+ uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 125, 80, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Scale value from being Transformed");
+
+
bb= object_get_boundbox(ob);
if (bb) {
@@ -1175,19 +1196,19 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
if ((ob->parent) && (ob->partype == PARBONE)) {
- uiDefBut(block, LABEL, 0, "Dimensions:", 160, 90, 100, 20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Dimensions:", 0, 60, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
- uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
- uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
+ uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 0, 40, 150, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate X bounding box size");
+ uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 0, 20, 150, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate Y bounding box size");
+ uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 0, 0, 150, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate Z bounding box size");
}
else {
- uiDefBut(block, LABEL, 0, "Dimensions:", 160, 90, 100, 20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Dimensions:", 0, 60, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
- uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
- uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
+ uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 0, 40, 150, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate X bounding box size");
+ uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 0, 20, 150, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate Y bounding box size");
+ uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 0, 0, 150, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate Z bounding box size");
}
uiBlockEndAlign(block);
@@ -1430,25 +1451,12 @@ void view3d_buttons_register(ARegionType *art)
pt->draw= view3d_panel_transform_spaces;
BLI_addtail(&art->paneltypes, pt);
- pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
- strcpy(pt->idname, "VIEW3D_PT_gpencil");
- strcpy(pt->label, "Greas Pencil");
- pt->draw= view3d_panel_gpencil;
- BLI_addtail(&art->paneltypes, pt);*/
-
pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces");
strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces");
strcpy(pt->label, "Bone Sketching");
pt->draw= view3d_panel_bonesketch_spaces;
pt->poll= view3d_panel_bonesketch_spaces_poll;
BLI_addtail(&art->paneltypes, pt);
-
- /*
- pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo");
- strcpy(pt->idname, "VIEW3D_PT_redo");
- strcpy(pt->label, "Last Operator");
- pt->draw= view3d_panel_operator_redo;
- BLI_addtail(&art->paneltypes, pt);
*/
// XXX view3d_panel_preview(C, ar, 0);
}
@@ -1458,13 +1466,9 @@ static int view3d_properties(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= view3d_has_buttons_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 66113ec4941..5612e60e899 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -732,7 +732,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d)
char *name = view3d_get_name(v3d, rv3d);
char *printable = NULL;
- if (v3d->localview) {
+ if (v3d->localvd) {
printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */
strcpy(printable, name);
strcat(printable, " (Local)");
@@ -742,10 +742,10 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d)
if (printable) {
UI_ThemeColor(TH_TEXT_HI);
- BLF_draw_default(10, ar->winy-20, 0.0f, printable);
+ BLF_draw_default(22, ar->winy-17, 0.0f, printable);
}
- if (v3d->localview) {
+ if (v3d->localvd) {
free(printable);
}
}
@@ -1416,12 +1416,9 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
-// glaDefine2DArea(&ar->winrct);
+ /* need to use wm push/pop matrix because ED_region_pixelspace
+ uses the wm functions too, otherwise gets out of sync */
+ wmPushMatrix();
ED_region_pixelspace(ar);
glEnable(GL_BLEND);
@@ -1433,10 +1430,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
glPixelZoom(1.0, 1.0);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+ wmPopMatrix();
glDisable(GL_BLEND);
if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index bbcee0415f8..c07d9108993 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -239,9 +239,10 @@ typedef struct ViewOpsData {
float ofs[3], obofs[3];
float reverse, dist0;
float grid, far;
+ short axis_snap; /* view rotate only */
int origx, origy, oldx, oldy;
- int origkey;
+ int origkey; /* the key that triggered the operator */
} ViewOpsData;
@@ -289,7 +290,7 @@ static void viewops_data(bContext *C, wmOperator *op, wmEvent *event)
QUATCOPY(vod->oldquat, rv3d->viewquat);
vod->origx= vod->oldx= event->x;
vod->origy= vod->oldy= event->y;
- vod->origkey= event->type;
+ vod->origkey= event->type; /* the key that triggered the operator. */
/* lookup, we dont pass on v3d to prevent confusement */
vod->grid= v3d->grid;
@@ -357,11 +358,52 @@ static float snapquats[39][6] = {
{0.0, 0.0, 0.0, 1.0, 0, 0}
};
+enum {
+ VIEW_PASS= 0,
+ VIEW_APPLY,
+ VIEW_CONFIRM
+};
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+#define VIEW_MODAL_CONFIRM 1 /* used for all view operations */
+#define VIEWROT_MODAL_AXIS_SNAP_ENABLE 2
+#define VIEWROT_MODAL_AXIS_SNAP_DISABLE 3
+
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void viewrotate_modal_keymap(wmWindowManager *wm)
+{
+ static EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Cancel", ""},
+
+ {VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Enable Axis Snap", ""},
+ {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Enable Axis Snap", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Rotate Modal");
-static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(wm, "View3D Rotate Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
+
+}
+
+static void viewrotate_apply(ViewOpsData *vod, int x, int y)
{
RegionView3D *rv3d= vod->rv3d;
- int use_sel= 0; /* XXX */
+ int use_sel= U.uiflag & USER_ORBIT_SELECTION;
rv3d->view= 0; /* need to reset everytime because of view snapping */
@@ -462,7 +504,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
}
/* check for view snap */
- if (ctrl){
+ if (vod->axis_snap){
int i;
float viewmat[3][3];
@@ -496,23 +538,41 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
{
ViewOpsData *vod= op->customdata;
+ short event_code= VIEW_PASS;
/* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- viewrotate_apply(vod, event->x, event->y, event->ctrl);
- break;
+ if(event->type==MOUSEMOVE) {
+ event_code= VIEW_APPLY;
+ }
+ else if(event->type==EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code= VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
+ vod->axis_snap= TRUE;
+ event_code= VIEW_APPLY;
+ break;
+ case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
+ vod->axis_snap= FALSE;
+ event_code= VIEW_APPLY;
+ break;
+ }
+ }
+ else if(event->type==vod->origkey && event->val==KM_RELEASE) {
+ event_code= VIEW_CONFIRM;
+ }
- default:
- /* origkey may be zero when invoked from a button */
- if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) {
- request_depth_update(CTX_wm_region_view3d(C));
+ if(event_code==VIEW_APPLY) {
+ viewrotate_apply(vod, event->x, event->y);
+ }
+ else if (event_code==VIEW_CONFIRM) {
+ request_depth_update(CTX_wm_region_view3d(C));
- MEM_freeN(vod);
- op->customdata= NULL;
+ MEM_freeN(vod);
+ op->customdata= NULL;
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
return OPERATOR_RUNNING_MODAL;
@@ -541,19 +601,19 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
-void VIEW3D_OT_viewrotate(wmOperatorType *ot)
+void VIEW3D_OT_rotate(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Rotate view";
ot->description = "Rotate the view.";
- ot->idname= "VIEW3D_OT_viewrotate";
+ ot->idname= "VIEW3D_OT_rotate";
/* api callbacks */
ot->invoke= viewrotate_invoke;
@@ -566,6 +626,33 @@ void VIEW3D_OT_viewrotate(wmOperatorType *ot)
/* ************************ viewmove ******************************** */
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void viewmove_modal_keymap(wmWindowManager *wm)
+{
+ static EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Move Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(wm, "View3D Move Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
+}
+
+
static void viewmove_apply(ViewOpsData *vod, int x, int y)
{
if(vod->rv3d->persp==V3D_CAMOB) {
@@ -596,24 +683,35 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
{
+
ViewOpsData *vod= op->customdata;
+ short event_code= VIEW_PASS;
/* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- viewmove_apply(vod, event->x, event->y);
- break;
+ if(event->type==MOUSEMOVE) {
+ event_code= VIEW_APPLY;
+ }
+ else if(event->type==EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code= VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if(event->type==vod->origkey && event->val==KM_RELEASE) {
+ event_code= VIEW_CONFIRM;
+ }
- default:
- /* origkey may be zero when invoked from a button */
- if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) {
- request_depth_update(CTX_wm_region_view3d(C));
+ if(event_code==VIEW_APPLY) {
+ viewmove_apply(vod, event->x, event->y);
+ }
+ else if (event_code==VIEW_CONFIRM) {
+ request_depth_update(CTX_wm_region_view3d(C));
- MEM_freeN(vod);
- op->customdata= NULL;
+ MEM_freeN(vod);
+ op->customdata= NULL;
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
return OPERATOR_RUNNING_MODAL;
@@ -625,19 +723,19 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
viewops_data(C, op, event);
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
-void VIEW3D_OT_viewmove(wmOperatorType *ot)
+void VIEW3D_OT_move(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Move view";
ot->description = "Move the view.";
- ot->idname= "VIEW3D_OT_viewmove";
+ ot->idname= "VIEW3D_OT_move";
/* api callbacks */
ot->invoke= viewmove_invoke;
@@ -650,6 +748,29 @@ void VIEW3D_OT_viewmove(wmOperatorType *ot)
/* ************************ viewzoom ******************************** */
+/* called in transform_ops.c, on each regeneration of keymaps */
+void viewzoom_modal_keymap(wmWindowManager *wm)
+{
+ static EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Zoom Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(wm, "View3D Zoom Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
+}
+
static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
{
RegionView3D *rv3d= ar->regiondata;
@@ -758,23 +879,33 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y)
static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
{
ViewOpsData *vod= op->customdata;
+ short event_code= VIEW_PASS;
/* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- viewzoom_apply(vod, event->x, event->y);
- break;
+ if(event->type==MOUSEMOVE) {
+ event_code= VIEW_APPLY;
+ }
+ else if(event->type==EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code= VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if(event->type==vod->origkey && event->val==KM_RELEASE) {
+ event_code= VIEW_CONFIRM;
+ }
- default:
- /* origkey may be zero when invoked from a button */
- if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) {
- request_depth_update(CTX_wm_region_view3d(C));
+ if(event_code==VIEW_APPLY) {
+ viewzoom_apply(vod, event->x, event->y);
+ }
+ else if (event_code==VIEW_CONFIRM) {
+ request_depth_update(CTX_wm_region_view3d(C));
- MEM_freeN(vod);
- op->customdata= NULL;
+ MEM_freeN(vod);
+ op->customdata= NULL;
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
return OPERATOR_RUNNING_MODAL;
@@ -823,7 +954,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
viewops_data(C, op, event);
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -925,7 +1056,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
void VIEW3D_OT_view_all(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "View home";
+ ot->name= "View All";
ot->description = "View all objects in scene.";
ot->idname= "VIEW3D_OT_view_all";
@@ -1064,7 +1195,7 @@ void VIEW3D_OT_view_center(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "View center";
+ ot->name= "View Selected";
ot->description = "Move the view to the selection center.";
ot->idname= "VIEW3D_OT_view_center";
@@ -1628,7 +1759,7 @@ static int viewpersportho_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_view_persportho(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "View persp/ortho";
+ ot->name= "View Persp/Ortho";
ot->description = "Switch the current view from perspective/orthographic.";
ot->idname= "VIEW3D_OT_view_persportho";
@@ -1850,8 +1981,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
// XXX notifier for scene */
ED_area_tag_redraw(CTX_wm_area(C));
- /* prevent other mouse ops to fail */
- return OPERATOR_PASS_THROUGH;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_cursor3d(wmOperatorType *ot)
@@ -2339,7 +2469,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
if (use_sel) {
QuatConj(q1); /* conj == inv for unit quat */
- VecSubf(v3d->ofs, v3d->ofs, obofs);
+ VecSubf(rv3d->ofs, rv3d->ofs, obofs);
QuatMulVecf(q1, rv3d->ofs);
VecAddf(rv3d->ofs, rv3d->ofs, obofs);
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index a633969d557..45828d654aa 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -177,7 +177,7 @@ static void handle_view3d_lock(bContext *C)
View3D *v3d= CTX_wm_view3d(C);
if (v3d != NULL && sa != NULL) {
- if(v3d->localview==0 && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) {
+ if(v3d->localvd==NULL && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) {
/* copy to scene */
scene->lay= v3d->lay;
@@ -195,27 +195,38 @@ static int layers_exec(bContext *C, wmOperator *op)
View3D *v3d= sa->spacedata.first;
int nr= RNA_int_get(op->ptr, "nr");
- if(nr<=0)
+ if(nr < 0)
return OPERATOR_CANCELLED;
- nr--;
-
- if(RNA_boolean_get(op->ptr, "extend"))
- v3d->lay |= (1<<nr);
- else
- v3d->lay = (1<<nr);
-
- /* set active layer, ensure to always have one */
- if(v3d->lay & (1<<nr))
- v3d->layact= 1<<nr;
- else if((v3d->lay & v3d->layact)==0) {
- int bit= 0;
+
+
+ if(nr == 0) {
+ /* all layers */
+ v3d->lay |= (1<<20)-1;
+
+ if(!v3d->layact)
+ v3d->layact= 1;
+ }
+ else {
+ nr--;
+
+ if(RNA_boolean_get(op->ptr, "extend"))
+ v3d->lay |= (1<<nr);
+ else
+ v3d->lay = (1<<nr);
- while(bit<32) {
- if(v3d->lay & (1<<bit)) {
- v3d->layact= 1<<bit;
- break;
+ /* set active layer, ensure to always have one */
+ if(v3d->lay & (1<<nr))
+ v3d->layact= 1<<nr;
+ else if((v3d->lay & v3d->layact)==0) {
+ int bit= 0;
+
+ while(bit<32) {
+ if(v3d->lay & (1<<bit)) {
+ v3d->layact= 1<<bit;
+ break;
+ }
+ bit++;
}
- bit++;
}
}
@@ -263,8 +274,8 @@ void VIEW3D_OT_layers(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "", 0, 20);
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "");
+ RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20);
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers");
}
#if 0
@@ -1801,8 +1812,10 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
ED_area_tag_redraw(sa);
break;
case B_NDOF:
+ ED_area_tag_redraw(sa);
break;
case B_MAN_MODE:
+ ED_area_tag_redraw(sa);
break;
case B_VIEW_BUTSEDIT:
break;
@@ -2076,7 +2089,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
/* LAYERS */
- if(obedit==NULL && v3d->localview==0) {
+ if(obedit==NULL && v3d->localvd==NULL) {
int ob_lay = ob ? ob->lay : 0;
uiBlockBeginAlign(block);
for(a=0; a<5; a++) {
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 00b0b5c4fd1..e7ab79ab955 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -66,8 +66,8 @@ void view3d_keymap(struct wmWindowManager *wm);
/* view3d_edit.c */
void VIEW3D_OT_zoom(struct wmOperatorType *ot);
-void VIEW3D_OT_viewmove(struct wmOperatorType *ot);
-void VIEW3D_OT_viewrotate(struct wmOperatorType *ot);
+void VIEW3D_OT_move(struct wmOperatorType *ot);
+void VIEW3D_OT_rotate(struct wmOperatorType *ot);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot);
void VIEW3D_OT_view_center(struct wmOperatorType *ot);
@@ -89,10 +89,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline);
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob);
void drawaxes(float size, int flag, char drawtype);
-void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs);
+
+void view3d_cached_text_draw_begin(void);
+void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs);
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]);
/* drawarmature.c */
-int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag);
+int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag);
/* drawmesh.c */
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, struct DerivedMesh *dm, int faceselect);
@@ -121,6 +124,7 @@ void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot);
void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
+void VIEW3D_OT_fly(struct wmOperatorType *ot);
int boundbox_clip(RegionView3D *rv3d, float obmat[][4], struct BoundBox *bb);
@@ -132,6 +136,11 @@ void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat
void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for picking */
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void fly_modal_keymap(struct wmWindowManager *wm);
+void viewrotate_modal_keymap(struct wmWindowManager *wm);
+void viewmove_modal_keymap(struct wmWindowManager *wm);
+void viewzoom_modal_keymap(struct wmWindowManager *wm);
+
/* view3d_buttons.c */
void VIEW3D_OT_properties(struct wmOperatorType *ot);
void view3d_buttons_register(struct ARegionType *art);
@@ -157,7 +166,7 @@ ARegion *view3d_has_buttons_region(ScrArea *sa);
ARegion *view3d_has_tools_region(ScrArea *sa);
/* draw_volume.c */
-void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, int res[3], float dx, struct GPUTexture *tex_shadow);
+void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, float *min, float *max, int res[3], float dx, struct GPUTexture *tex_shadow);
#endif /* ED_VIEW3D_INTERN_H */
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 7da2e591b10..f9cedbd28a1 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -62,8 +62,8 @@
void view3d_operatortypes(void)
{
- WM_operatortype_append(VIEW3D_OT_viewrotate);
- WM_operatortype_append(VIEW3D_OT_viewmove);
+ WM_operatortype_append(VIEW3D_OT_rotate);
+ WM_operatortype_append(VIEW3D_OT_move);
WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_view_all);
WM_operatortype_append(VIEW3D_OT_viewnumpad);
@@ -85,6 +85,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_drawtype);
WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_game_start);
+ WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_layers);
WM_operatortype_append(VIEW3D_OT_properties);
@@ -103,44 +104,28 @@ void view3d_operatortypes(void)
void view3d_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ wmKeyMap *keymap;
wmKeymapItem *km;
+ keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0);
+
WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_toolbar", TKEY, KM_PRESS, 0, 0);
/* only for region 3D window */
- keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
-
- /* paint poll checks mode */
- WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0);
-
- WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
-
- WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
-
- /* sketch poll checks mode */
- WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(km->ptr, "snap", 1);
- WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
- km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(km->ptr, "snap", 1);
+ keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center", PADPERIOD, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_SHIFT, 0);
+
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
@@ -175,6 +160,7 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0);
/* 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);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", TWOKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 2);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", THREEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 3);
@@ -201,7 +187,25 @@ void view3d_keymap(wmWindowManager *wm)
/* selection*/
WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "center", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "enumerate", TRUE);
+
+ /* selection key-combinations */
+ km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
+ RNA_boolean_set(km->ptr, "center", TRUE);
+ RNA_boolean_set(km->ptr, "extend", TRUE);
+ km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ RNA_boolean_set(km->ptr, "center", TRUE);
+ RNA_boolean_set(km->ptr, "enumerate", TRUE);
+ km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0);
+ RNA_boolean_set(km->ptr, "extend", TRUE);
+ RNA_boolean_set(km->ptr, "enumerate", TRUE);
+ km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL|KM_ALT, 0);
+ RNA_boolean_set(km->ptr, "center", TRUE);
+ RNA_boolean_set(km->ptr, "extend", TRUE);
+ RNA_boolean_set(km->ptr, "enumerate", TRUE);
+
WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1);
@@ -214,20 +218,12 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0);
-
- /* radial control */
- RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
- RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
-
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
+ fly_modal_keymap(wm);
+ viewrotate_modal_keymap(wm);
+ viewmove_modal_keymap(wm);
+ viewzoom_modal_keymap(wm);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index a7696d9fe31..a37e916064c 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -53,6 +53,7 @@
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_rand.h"
+#include "BLI_linklist.h"
#include "BKE_action.h"
#include "BKE_context.h"
@@ -845,56 +846,87 @@ static void deselectall_except(Scene *scene, Base *b) /* deselect all except b
}
}
-static Base *mouse_select_menu(ViewContext *vc, unsigned int *buffer, int hits, short *mval)
+static Base *mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, short *mval, short extend)
{
- Scene *scene= vc->scene;
- View3D *v3d= vc->v3d;
- Base *baseList[SEL_MENU_SIZE]={NULL}; /*baseList is used to store all possible bases to bring up a menu */
- Base *base;
short baseCount = 0;
- char menuText[20 + SEL_MENU_SIZE*32] = "Select Object%t"; /* max ob name = 22 */
- char str[32];
-
- for(base=FIRSTBASE; base; base= base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- baseList[baseCount] = NULL;
-
- /* two selection methods, the CTRL select uses max dist of 15 */
- if(buffer) {
- int a;
- for(a=0; a<hits; a++) {
- /* index was converted */
- if(base->selcol==buffer[ (4 * a) + 3 ]) baseList[baseCount] = base;
- }
- }
- else {
- int temp, dist=15;
-
- project_short(vc->ar, base->object->obmat[3], &base->sx);
-
- temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
- if(temp<dist ) baseList[baseCount] = base;
+ short ok;
+ LinkNode *linklist= NULL;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ ok= FALSE;
+
+ /* two selection methods, the CTRL select uses max dist of 15 */
+ if(buffer) {
+ int a;
+ for(a=0; a<hits; a++) {
+ /* index was converted */
+ if(base->selcol==buffer[ (4 * a) + 3 ])
+ ok= TRUE;
}
+ }
+ else {
+ int temp, dist=15;
+
+ project_short(vc->ar, base->object->obmat[3], &base->sx);
- if(baseList[baseCount]) {
- if (baseCount < SEL_MENU_SIZE) {
- baseList[baseCount] = base;
- sprintf(str, "|%s %%x%d", base->object->id.name+2, baseCount+1); /* max ob name == 22 */
- strcat(menuText, str);
- baseCount++;
- }
- }
+ temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
+ if(temp < dist)
+ ok= TRUE;
+ }
+
+ if(ok) {
+ baseCount++;
+ BLI_linklist_prepend(&linklist, base);
+
+ if (baseCount==SEL_MENU_SIZE)
+ break;
}
}
+ CTX_DATA_END;
+
+ if(baseCount)
- if(baseCount<=1) return baseList[0];
+
+ if(baseCount==0) {
+ return NULL;
+ }
+ if(baseCount == 1) {
+ Base *base= (Base *)linklist->link;
+ BLI_linklist_free(linklist, NULL);
+ return base;
+ }
else {
- baseCount = -1; // XXX = pupmenu(menuText);
-
- if (baseCount != -1) { /* If nothing is selected then dont do anything */
- return baseList[baseCount-1];
+ /* UI */
+ uiPopupMenu *pup= uiPupMenuBegin(C, "Select Object", 0);
+ uiLayout *layout= uiPupMenuLayout(pup);
+ uiLayout *split= uiLayoutSplit(layout, 0);
+ uiLayout *column= uiLayoutColumn(split, 0);
+ LinkNode *node;
+
+ node= linklist;
+ while(node) {
+ Base *base=node->link;
+ Object *ob= base->object;
+ char *name= ob->id.name+2;
+ /* annoying!, since we need to set 2 props cant use this. */
+ /* uiItemStringO(column, name, 0, "OBJECT_OT_select_name", "name", name); */
+
+ {
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, "OBJECT_OT_select_name");
+ RNA_string_set(&ptr, "name", name);
+ RNA_boolean_set(&ptr, "extend", extend);
+ uiItemFullO(column, name, uiIconFromID((ID *)ob), "OBJECT_OT_select_name", ptr.data, WM_OP_EXEC_DEFAULT, 0);
+ }
+
+ node= node->next;
}
- else return NULL;
+
+ uiPupMenuEnd(C, pup);
+
+ BLI_linklist_free(linklist, NULL);
+ return NULL;
}
}
@@ -958,14 +990,13 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
/* mval is region coords */
-static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
+static void mouse_select(bContext *C, short *mval, short extend, short obcenter, short enumerate)
{
ViewContext vc;
ARegion *ar= CTX_wm_region(C);
View3D *v3d= CTX_wm_view3d(C);
Scene *scene= CTX_data_scene(C);
Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
- unsigned int buffer[4*MAXPICKBUF];
int temp, a, dist=100;
short hits;
@@ -981,10 +1012,9 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
if(vc.obedit==NULL && obcenter) {
/* note; shift+alt goes to group-flush-selecting */
- /* XXX solve */
- if(0)
- basact= mouse_select_menu(&vc, NULL, 0, mval);
- else {
+ if(enumerate) {
+ basact= mouse_select_menu(C, &vc, NULL, 0, mval, extend);
+ } else {
base= startbase;
while(base) {
if (BASE_SELECTABLE(v3d, base)) {
@@ -1006,6 +1036,8 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
}
}
else {
+ unsigned int buffer[4*MAXPICKBUF];
+
/* if objects have posemode set, the bones are in the same selection buffer */
hits= mixed_bones_object_selectbuffer(&vc, buffer, mval);
@@ -1016,9 +1048,9 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
for(a=0; a<hits; a++) if(buffer[4*a+3] & 0xFFFF0000) has_bones= 1;
/* note; shift+alt goes to group-flush-selecting */
- if(has_bones==0 && 0)
- basact= mouse_select_menu(&vc, buffer, hits, mval);
- else {
+ if(has_bones==0 && enumerate) {
+ basact= mouse_select_menu(C, &vc, buffer, hits, mval, extend);
+ } else {
static short lastmval[2]={-100, -100};
int donearest= 0;
@@ -1116,7 +1148,7 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if(basact->object->mode & OB_MODE_WEIGHT_PAINT) {
+ if(BASACT && BASACT->object->mode & OB_MODE_WEIGHT_PAINT) {
/* prevent activating */
basact= NULL;
}
@@ -1560,7 +1592,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first.");
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first.");
}
/* ****** Mouse Select ****** */
@@ -1571,6 +1603,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
Object *obedit= CTX_data_edit_object(C);
Object *obact= CTX_data_active_object(C);
short extend= RNA_boolean_get(op->ptr, "extend");
+ short center= RNA_boolean_get(op->ptr, "center");
+ short enumerate= RNA_boolean_get(op->ptr, "enumerate");
view3d_operator_needs_opengl(C);
@@ -1590,7 +1624,7 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT)
PE_mouse_particles(C, event->mval, extend);
else
- mouse_select(C, event->mval, extend, 0);
+ mouse_select(C, event->mval, extend, center, enumerate);
/* allowing tweaks */
return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
@@ -1611,7 +1645,9 @@ void VIEW3D_OT_select(wmOperatorType *ot)
ot->flag= OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first.");
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first.");
+ RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting (object mode only).");
+ RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only).");
}
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index b4b54cd1d88..767f18649fa 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -1122,13 +1122,13 @@ static int snap_menu_invoke(bContext *C, wmOperator *unused, wmEvent *event)
uiPopupMenu *pup= uiPupMenuBegin(C, "Snap", 0);
uiLayout *layout= uiPupMenuLayout(pup);
- uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_grid");
- uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_cursor");
- uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_center");
+ uiItemO(layout, "Selected to Grid", 0, "VIEW3D_OT_snap_selected_to_grid");
+ uiItemO(layout, "Selected to Cursor", 0, "VIEW3D_OT_snap_selected_to_cursor");
+ uiItemO(layout, "Selected to Center", 0, "VIEW3D_OT_snap_selected_to_center");
uiItemS(layout);
- uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_cursor_to_selected");
- uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_cursor_to_grid");
- uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_cursor_to_active");
+ uiItemO(layout, "Cursor to Selected", 0, "VIEW3D_OT_snap_cursor_to_selected");
+ uiItemO(layout, "Cursor to Grid", 0, "VIEW3D_OT_snap_cursor_to_grid");
+ uiItemO(layout, "Cursor to Active", 0, "VIEW3D_OT_snap_cursor_to_active");
uiPupMenuEnd(C, pup);
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 58248f675da..e1c6f70bde0 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -163,7 +163,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
if(op==NULL)
return;
- if(op->type->poll && op->type->poll((bContext *)C)==0)
+ if(WM_operator_poll((bContext*)C, op->type) == 0)
return;
block= uiLayoutGetBlock(pa->layout);
@@ -208,7 +208,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u
for(; ot; ot= ot->next) {
if(BLI_strcasestr(ot->name, str)) {
- if(ot->poll==NULL || ot->poll((bContext *)C)) {
+ if(WM_operator_poll((bContext*)C, ot)) {
if(0==uiSearchItemAdd(items, ot->name, ot, 0))
break;
@@ -309,13 +309,9 @@ static int view3d_toolbar(bContext *C, wmOperator *op)
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= view3d_has_tools_region(sa);
- if(ar) {
- ar->flag ^= RGN_FLAG_HIDDEN;
- ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
- }
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 7831d604ddf..f722a97963d 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -56,9 +56,11 @@
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
+#include "BKE_depsgraph.h" /* for fly mode updating */
#include "RE_pipeline.h" // make_stars
@@ -110,7 +112,7 @@ void view3d_operator_needs_opengl(const bContext *C)
float *give_cursor(Scene *scene, View3D *v3d)
{
- if(v3d && v3d->localview) return v3d->cursor;
+ if(v3d && v3d->localvd) return v3d->cursor;
else return scene->cursor;
}
@@ -384,26 +386,31 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
}
-static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
+static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d= CTX_wm_region_view3d(C);
- Object *ob;
float dvec[3];
- ob= v3d->camera;
dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
dvec[2]= rv3d->dist*rv3d->viewinv[2][2];
VECCOPY(ob->loc, dvec);
- VecSubf(ob->loc, ob->loc, v3d->ofs);
+ VecSubf(ob->loc, ob->loc, rv3d->ofs);
rv3d->viewquat[0]= -rv3d->viewquat[0];
QuatToEul(rv3d->viewquat, ob->rot);
rv3d->viewquat[0]= -rv3d->viewquat[0];
ob->recalc= OB_RECALC_OB;
+}
+
+
+static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+
+ setcameratoview3d(v3d, rv3d, v3d->camera);
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C));
@@ -1303,7 +1310,6 @@ static void initlocalview(Scene *scene, ScrArea *sa)
base->object->lay= base->lay;
}
}
- v3d->localview= 0;
}
}
@@ -1325,7 +1331,6 @@ static void restore_localviewdata(ScrArea *sa, int free)
if(free) {
MEM_freeN(v3d->localvd);
v3d->localvd= NULL;
- v3d->localview= 0;
}
for(ar= sa->regionbase.first; ar; ar= ar->next) {
@@ -1416,8 +1421,6 @@ static void SaveState(bContext *C)
glPushAttrib(GL_ALL_ATTRIB_BITS);
- GPU_state_init();
-
if(obact && obact->mode & OB_MODE_TEXTURE_PAINT)
GPU_paint_set_mipmap(1);
@@ -1446,6 +1449,8 @@ static void RestoreState(bContext *C)
win->queue= queue_back;
+ GPU_state_init();
+
glPopAttrib();
}
@@ -1574,6 +1579,802 @@ void VIEW3D_OT_game_start(wmOperatorType *ot)
ot->poll= game_engine_poll;
}
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+#define FLY_MODAL_CANCEL 1
+#define FLY_MODAL_CONFIRM 2
+#define FLY_MODAL_ACCELERATE 3
+#define FLY_MODAL_DECELERATE 4
+#define FLY_MODAL_PAN_ENABLE 5
+#define FLY_MODAL_PAN_DISABLE 6
+#define FLY_MODAL_DIR_FORWARD 7
+#define FLY_MODAL_DIR_BACKWARD 8
+#define FLY_MODAL_DIR_LEFT 9
+#define FLY_MODAL_DIR_RIGHT 10
+#define FLY_MODAL_DIR_UP 11
+#define FLY_MODAL_DIR_DOWN 12
+#define FLY_MODAL_AXIS_LOCK_X 13
+#define FLY_MODAL_AXIS_LOCK_Z 14
+#define FLY_MODAL_PRECISION_ENABLE 15
+#define FLY_MODAL_PRECISION_DISABLE 16
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void fly_modal_keymap(wmWindowManager *wm)
+{
+ static EnumPropertyItem modal_items[] = {
+ {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
+ {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
+
+ {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""},
+ {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""},
+
+ {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""},
+ {FLY_MODAL_DIR_BACKWARD,"BACKWARD", 0, "Fly Backward", ""},
+ {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""},
+ {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""},
+ {FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""},
+ {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""},
+
+ {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
+ {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
+
+ {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""},
+ {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Fly Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(wm, "View3D Fly Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL);
+
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
+
+ WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE);
+ WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE);
+ WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE);
+ WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE);
+
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */
+
+ /* WASD */
+ WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD);
+ WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD);
+ WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT);
+ WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT);
+ WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP);
+ WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN);
+
+ WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X);
+ WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z);
+
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
+
+}
+
+typedef struct FlyInfo {
+ /* context stuff */
+ RegionView3D *rv3d;
+ View3D *v3d;
+ ARegion *ar;
+ Scene *scene;
+
+ wmTimer *timer; /* needed for redraws */
+
+ short state;
+ short use_precision;
+ short redraw;
+ short mval[2];
+
+ /* fly state state */
+ float speed; /* the speed the view is moving per redraw */
+ short axis; /* Axis index to move allong by default Z to move allong the view */
+ short pan_view; /* when true, pan the view instead of rotating */
+
+ /* relative view axis locking - xlock, zlock
+ 0; disabled
+ 1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed
+ when the mouse moves, locking is set to 2 so checks are done.
+ 2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */
+ short xlock, zlock;
+ float xlock_momentum, zlock_momentum; /* nicer dynamics */
+ float grid; /* world scale 1.0 default */
+
+ /* backup values */
+ float dist_backup; /* backup the views distance since we use a zero dist for fly mode */
+ float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */
+ float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */
+ short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
+
+ /* compare between last state */
+ double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
+ double time_lastdraw; /* time between draws */
+
+ /* use for some lag */
+ float dvec_prev[3]; /* old for some lag */
+
+} FlyInfo;
+
+/* FlyInfo->state */
+#define FLY_RUNNING 0
+#define FLY_CANCEL 1
+#define FLY_CONFIRM 2
+
+int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
+{
+ float upvec[3]; // tmp
+ float mat[3][3];
+
+ fly->rv3d= CTX_wm_region_view3d(C);
+ fly->v3d = CTX_wm_view3d(C);
+ fly->ar = CTX_wm_region(C);
+ fly->scene= CTX_data_scene(C);
+
+ if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->id.lib) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
+ return FALSE;
+ }
+
+ if(fly->v3d->ob_centre) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object");
+ return FALSE;
+ }
+
+ if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->constraints.first) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
+ return FALSE;
+ }
+
+ fly->state= FLY_RUNNING;
+ fly->speed= 0.0f;
+ fly->axis= 2;
+ fly->pan_view= FALSE;
+ fly->xlock= FALSE;
+ fly->zlock= TRUE;
+ fly->xlock_momentum=0.0f;
+ fly->zlock_momentum=0.0f;
+ fly->grid= 1.0f;
+ fly->use_precision= 0;
+
+ fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f;
+
+ fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+
+
+ /* we have to rely on events to give proper mousecoords after a warp_pointer */
+//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]);
+ //fly->mval[0]= (fly->sa->winx)/2;
+ //fly->mval[1]= (fly->sa->winy)/2;
+
+ fly->mval[0] = event->x - fly->ar->winrct.xmin;
+ fly->mval[1] = event->y - fly->ar->winrct.ymin;
+
+
+ fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer();
+
+ fly->rv3d->rflag |= RV3D_FLYMODE; /* so we draw the corner margins */
+
+ /* detect weather to start with Z locking */
+ upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f;
+ Mat3CpyMat4(mat, fly->rv3d->viewinv);
+ Mat3MulVecfl(mat, upvec);
+ if (fabs(upvec[2]) < 0.1)
+ fly->zlock = 1;
+ upvec[0]=0; upvec[1]=0; upvec[2]=0;
+
+ fly->persp_backup= fly->rv3d->persp;
+ fly->dist_backup= fly->rv3d->dist;
+ if (fly->rv3d->persp==V3D_CAMOB) {
+ /* store the origoinal camera loc and rot */
+ VECCOPY(fly->ofs_backup, fly->v3d->camera->loc);
+ VECCOPY(fly->rot_backup, fly->v3d->camera->rot);
+
+ where_is_object(fly->scene, fly->v3d->camera);
+ VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
+ VecMulf(fly->rv3d->ofs, -1.0f); /*flip the vector*/
+
+ fly->rv3d->dist=0.0;
+ fly->rv3d->viewbut=0;
+
+ /* used for recording */
+//XXX2.5 if(v3d->camera->ipoflag & OB_ACTION_OB)
+//XXX2.5 actname= "Object";
+
+ } else {
+ /* perspective or ortho */
+ if (fly->rv3d->persp==V3D_ORTHO)
+ fly->rv3d->persp= V3D_PERSP; /*if ortho projection, make perspective */
+ QUATCOPY(fly->rot_backup, fly->rv3d->viewquat);
+ VECCOPY(fly->ofs_backup, fly->rv3d->ofs);
+ fly->rv3d->dist= 0.0;
+
+ upvec[2]= fly->dist_backup; /*x and y are 0*/
+ Mat3MulVecfl(mat, upvec);
+ VecSubf(fly->rv3d->ofs, fly->rv3d->ofs, upvec);
+ /*Done with correcting for the dist*/
+ }
+
+ return 1;
+}
+
+static int flyEnd(bContext *C, FlyInfo *fly)
+{
+ RegionView3D *rv3d= fly->rv3d;
+ View3D *v3d = fly->v3d;
+
+ float upvec[3];
+
+ if(fly->state == FLY_RUNNING)
+ return OPERATOR_RUNNING_MODAL;
+
+ WM_event_remove_window_timer(CTX_wm_window(C), fly->timer);
+
+ rv3d->dist= fly->dist_backup;
+
+ if (fly->state == FLY_CANCEL) {
+ /* Revert to original view? */
+ if (fly->persp_backup==V3D_CAMOB) { /* a camera view */
+ rv3d->viewbut=1;
+ VECCOPY(v3d->camera->loc, fly->ofs_backup);
+ VECCOPY(v3d->camera->rot, fly->rot_backup);
+ DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+ } else {
+ /* Non Camera we need to reset the view back to the original location bacause the user canceled*/
+ QUATCOPY(rv3d->viewquat, fly->rot_backup);
+ VECCOPY(rv3d->ofs, fly->ofs_backup);
+ rv3d->persp= fly->persp_backup;
+ }
+ }
+ else if (fly->persp_backup==V3D_CAMOB) { /* camera */
+ float mat3[3][3];
+ Mat3CpyMat4(mat3, v3d->camera->obmat);
+ Mat3ToCompatibleEul(mat3, v3d->camera->rot, fly->rot_backup);
+
+ DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+#if 0 //XXX2.5
+ if (IS_AUTOKEY_MODE(NORMAL)) {
+ allqueue(REDRAWIPO, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWTIME, 0);
+ }
+#endif
+ }
+ else { /* not camera */
+ /* Apply the fly mode view */
+ /*restore the dist*/
+ float mat[3][3];
+ upvec[0]= upvec[1]= 0;
+ upvec[2]= fly->dist_backup; /*x and y are 0*/
+ Mat3CpyMat4(mat, rv3d->viewinv);
+ Mat3MulVecfl(mat, upvec);
+ VecAddf(rv3d->ofs, rv3d->ofs, upvec);
+ /*Done with correcting for the dist */
+ }
+
+ rv3d->rflag &= ~RV3D_FLYMODE;
+//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
+
+
+ if(fly->state == FLY_CONFIRM) {
+ MEM_freeN(fly);
+ return OPERATOR_FINISHED;
+ }
+
+ MEM_freeN(fly);
+ return OPERATOR_CANCELLED;
+}
+
+void flyEvent(FlyInfo *fly, wmEvent *event)
+{
+ if (event->type == TIMER) {
+ fly->redraw = 1;
+ }
+ else if (event->type == MOUSEMOVE) {
+ fly->mval[0] = event->x - fly->ar->winrct.xmin;
+ fly->mval[1] = event->y - fly->ar->winrct.ymin;
+ } /* handle modal keymap first */
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case FLY_MODAL_CANCEL:
+ fly->state = FLY_CANCEL;
+ break;
+ case FLY_MODAL_CONFIRM:
+ fly->state = FLY_CONFIRM;
+ break;
+
+ case FLY_MODAL_ACCELERATE:
+ {
+ double time_currwheel;
+ float time_wheel;
+
+ time_currwheel= PIL_check_seconds_timer();
+ time_wheel = (float)(time_currwheel - fly->time_lastwheel);
+ fly->time_lastwheel = time_currwheel;
+ /*printf("Wheel %f\n", time_wheel);*/
+ /*Mouse wheel delays range from 0.5==slow to 0.01==fast*/
+ time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */
+
+ if (fly->speed<0.0f) fly->speed= 0.0f;
+ else {
+ if (event->shift)
+ fly->speed+= fly->grid*time_wheel*0.1;
+ else
+ fly->speed+= fly->grid*time_wheel;
+ }
+ break;
+ }
+ case FLY_MODAL_DECELERATE:
+ {
+ double time_currwheel;
+ float time_wheel;
+
+ time_currwheel= PIL_check_seconds_timer();
+ time_wheel = (float)(time_currwheel - fly->time_lastwheel);
+ fly->time_lastwheel = time_currwheel;
+ time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */
+
+ if (fly->speed>0) fly->speed=0;
+ else {
+ if (event->shift)
+ fly->speed-= fly->grid*time_wheel*0.1;
+ else
+ fly->speed-= fly->grid*time_wheel;
+ }
+ break;
+ }
+ case FLY_MODAL_PAN_ENABLE:
+ fly->pan_view= TRUE;
+ break;
+ case FLY_MODAL_PAN_DISABLE:
+//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]);
+ fly->pan_view= FALSE;
+ break;
+
+ /* impliment WASD keys */
+ case FLY_MODAL_DIR_FORWARD:
+ if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */
+ else fly->speed += fly->grid; /* increse like mousewheel if were alredy moving in that difection*/
+ fly->axis= 2;
+ break;
+ case FLY_MODAL_DIR_BACKWARD:
+ if (fly->speed>0) fly->speed= -fly->speed;
+ else fly->speed -= fly->grid;
+ fly->axis= 2;
+ break;
+ case FLY_MODAL_DIR_LEFT:
+ if (fly->speed < 0.0f) fly->speed= -fly->speed;
+ fly->axis= 0;
+ break;
+ case FLY_MODAL_DIR_RIGHT:
+ if (fly->speed > 0.0f) fly->speed= -fly->speed;
+ fly->axis= 0;
+ break;
+
+ case FLY_MODAL_DIR_UP:
+ if (fly->speed < 0.0f) fly->speed= -fly->speed;
+ fly->axis= 1;
+ break;
+
+ case FLY_MODAL_DIR_DOWN:
+ if (fly->speed > 0.0f) fly->speed= -fly->speed;
+ fly->axis= 1;
+ break;
+
+ case FLY_MODAL_AXIS_LOCK_X:
+ if (fly->xlock) fly->xlock=0;
+ else {
+ fly->xlock = 2;
+ fly->xlock_momentum = 0.0;
+ }
+ break;
+ case FLY_MODAL_AXIS_LOCK_Z:
+ if (fly->zlock) fly->zlock=0;
+ else {
+ fly->zlock = 2;
+ fly->zlock_momentum = 0.0;
+ }
+ break;
+
+ case FLY_MODAL_PRECISION_ENABLE:
+ fly->use_precision= TRUE;
+ break;
+ case FLY_MODAL_PRECISION_DISABLE:
+ fly->use_precision= FALSE;
+ break;
+
+ }
+ }
+}
+
+//int fly_exec(bContext *C, wmOperator *op)
+int flyApply(FlyInfo *fly)
+{
+ /*
+ fly mode - Shift+F
+ a fly loop where the user can move move the view as if they are flying
+ */
+ RegionView3D *rv3d= fly->rv3d;
+ View3D *v3d = fly->v3d;
+ ARegion *ar = fly->ar;
+ Scene *scene= fly->scene;
+
+ float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */
+ dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */
+
+ /* Camera Uprighting variables */
+ upvec[3]={0,0,0}, /* stores the view's up vector */
+
+ moffset[2], /* mouse offset from the views center */
+ tmp_quat[4]; /* used for rotating the view */
+
+ int cent_orig[2], /* view center */
+//XXX- can avoid using // cent[2], /* view center modified */
+ xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */
+ unsigned char
+ apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/
+
+ /* for recording */
+#if 0 //XXX2.5 todo, get animation recording working again.
+ int playing_anim = 0; //XXX has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
+ int cfra = -1; /*so the first frame always has a key added */
+ char *actname="";
+#endif
+ /* the dist defines a vector that is infront of the offset
+ to rotate the view about.
+ this is no good for fly mode because we
+ want to rotate about the viewers center.
+ but to correct the dist removal we must
+ alter offset so the view doesn't jump. */
+
+ xmargin= ar->winx/20.0f;
+ ymargin= ar->winy/20.0f;
+
+ cent_orig[0]= ar->winrct.xmin + ar->winx/2;
+ cent_orig[1]= ar->winrct.ymin + ar->winy/2;
+
+ {
+
+ /* mouse offset from the center */
+ moffset[0]= fly->mval[0]- ar->winx/2;
+ moffset[1]= fly->mval[1]- ar->winy/2;
+
+ /* enforce a view margin */
+ if (moffset[0]>xmargin) moffset[0]-=xmargin;
+ else if (moffset[0] < -xmargin) moffset[0]+=xmargin;
+ else moffset[0]=0;
+
+ if (moffset[1]>ymargin) moffset[1]-=ymargin;
+ else if (moffset[1] < -ymargin) moffset[1]+=ymargin;
+ else moffset[1]=0;
+
+
+ /* 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)
+ *
+ * the mouse moves isnt linear */
+
+ if(moffset[0]) {
+ moffset[0] /= ar->winx - (xmargin*2);
+ moffset[0] *= fabs(moffset[0]);
+ }
+
+ if(moffset[1]) {
+ moffset[1] /= ar->winy - (ymargin*2);
+ moffset[1] *= fabs(moffset[1]);
+ }
+
+ /* Should we redraw? */
+ if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) {
+ float dvec_tmp[3];
+ double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */
+ float time_redraw_clamped;
+
+ time_current= PIL_check_seconds_timer();
+ time_redraw= (float)(time_current - fly->time_lastdraw);
+ time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */
+ fly->time_lastdraw= time_current;
+ /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */
+
+ /* Scale the time to use shift to scale the speed down- just like
+ shift slows many other areas of blender down */
+ if (fly->use_precision)
+ fly->speed= fly->speed * (1.0f-time_redraw_clamped);
+
+ Mat3CpyMat4(mat, rv3d->viewinv);
+
+ if (fly->pan_view==TRUE) {
+ /* pan only */
+ dvec_tmp[0]= -moffset[0];
+ dvec_tmp[1]= -moffset[1];
+ dvec_tmp[2]= 0;
+
+ if (fly->use_precision) {
+ dvec_tmp[0] *= 0.1;
+ dvec_tmp[1] *= 0.1;
+ }
+
+ Mat3MulVecfl(mat, dvec_tmp);
+ VecMulf(dvec_tmp, time_redraw*200.0 * fly->grid);
+
+ } else {
+ float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/
+
+ /* rotate about the X axis- look up/down */
+ if (moffset[1]) {
+ upvec[0]=1;
+ upvec[1]=0;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+ VecRotToQuat( upvec, (float)moffset[1]*-time_redraw*20, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ if (fly->xlock) fly->xlock = 2; /*check for rotation*/
+ if (fly->zlock) fly->zlock = 2;
+ fly->xlock_momentum= 0.0f;
+ }
+
+ /* rotate about the Y axis- look left/right */
+ if (moffset[0]) {
+
+ /* if we're upside down invert the moffset */
+ upvec[0]=0;
+ upvec[1]=1;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+
+ if(upvec[2] < 0.0f)
+ moffset[0]= -moffset[0];
+
+ /* make the lock vectors */
+ if (fly->zlock) {
+ upvec[0]=0;
+ upvec[1]=0;
+ upvec[2]=1;
+ } else {
+ upvec[0]=0;
+ upvec[1]=1;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+ }
+
+ VecRotToQuat( upvec, (float)moffset[0]*time_redraw*20, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ if (fly->xlock) fly->xlock = 2;/*check for rotation*/
+ if (fly->zlock) fly->zlock = 2;
+ }
+
+ if (fly->zlock==2) {
+ upvec[0]=1;
+ upvec[1]=0;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+
+ /*make sure we have some z rolling*/
+ if (fabs(upvec[2]) > 0.00001f) {
+ roll= upvec[2]*5;
+ upvec[0]=0; /*rotate the view about this axis*/
+ upvec[1]=0;
+ upvec[2]=1;
+
+ Mat3MulVecfl(mat, upvec);
+ VecRotToQuat( upvec, roll*time_redraw_clamped*fly->zlock_momentum*0.1, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ fly->zlock_momentum += 0.05f;
+ } else {
+ fly->zlock=1; /* dont check until the view rotates again */
+ fly->zlock_momentum= 0.0f;
+ }
+ }
+
+ if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/
+ upvec[0]=0;
+ upvec[1]=0;
+ upvec[2]=1;
+ Mat3MulVecfl(mat, upvec);
+ /*make sure we have some z rolling*/
+ if (fabs(upvec[2]) > 0.00001) {
+ roll= upvec[2] * -5;
+
+ upvec[0]= 1.0f; /*rotate the view about this axis*/
+ upvec[1]= 0.0f;
+ upvec[2]= 0.0f;
+
+ Mat3MulVecfl(mat, upvec);
+
+ VecRotToQuat( upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ fly->xlock_momentum += 0.05f;
+ } else {
+ fly->xlock=1; /* see above */
+ fly->xlock_momentum= 0.0f;
+ }
+ }
+
+
+ if (apply_rotation) {
+ /* Normal operation */
+ /* define dvec, view direction vector */
+ dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f;
+ /* move along the current axis */
+ dvec_tmp[fly->axis]= 1.0f;
+
+ Mat3MulVecfl(mat, dvec_tmp);
+
+ VecMulf(dvec_tmp, fly->speed * time_redraw * 0.25f);
+ }
+ }
+
+ /* impose a directional lag */
+ VecLerpf(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f))));
+
+ if (rv3d->persp==V3D_CAMOB) {
+ if (v3d->camera->protectflag & OB_LOCK_LOCX)
+ dvec[0] = 0.0;
+ if (v3d->camera->protectflag & OB_LOCK_LOCY)
+ dvec[1] = 0.0;
+ if (v3d->camera->protectflag & OB_LOCK_LOCZ)
+ dvec[2] = 0.0;
+ }
+
+ VecAddf(rv3d->ofs, rv3d->ofs, dvec);
+#if 0 //XXX2.5
+ if (fly->zlock && fly->xlock)
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ else if (fly->zlock)
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ else if (fly->xlock)
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ else
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+#endif
+
+//XXX2.5 do_screenhandlers(G.curscreen); /* advance the next frame */
+
+ /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
+ if (rv3d->persp==V3D_CAMOB) {
+ rv3d->persp= V3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */
+ setviewmatrixview3d(scene, v3d, rv3d);
+
+ setcameratoview3d(v3d, rv3d, v3d->camera);
+
+ { //XXX - some reason setcameratoview3d doesnt copy, shouldnt not be needed!
+ VECCOPY(v3d->camera->loc, rv3d->ofs);
+ VecNegf(v3d->camera->loc);
+ }
+
+ rv3d->persp= V3D_CAMOB;
+#if 0 //XXX2.5
+ /* record the motion */
+ if (IS_AUTOKEY_MODE(NORMAL) && (!playing_anim || cfra != G.scene->r.cfra)) {
+ cfra = G.scene->r.cfra;
+
+ if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) {
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_X, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Y, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Z, 0);
+ }
+ if (fly->speed) {
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_X, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Y, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Z, 0);
+ }
+ }
+#endif
+ }
+//XXX2.5 scrarea_do_windraw(curarea);
+//XXX2.5 screen_swapbuffers();
+ } else
+ /*were not redrawing but we need to update the time else the view will jump */
+ fly->time_lastdraw= PIL_check_seconds_timer();
+ /* end drawing */
+ VECCOPY(fly->dvec_prev, dvec);
+ }
+
+/* moved to flyEnd() */
+
+ return OPERATOR_FINISHED;
+}
+
+
+
+static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+ FlyInfo *fly;
+
+ if(rv3d->viewlock)
+ return OPERATOR_CANCELLED;
+
+ fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation");
+
+ op->customdata= fly;
+
+ if(initFlyInfo(C, fly, op, event)==FALSE) {
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+ }
+
+ flyEvent(fly, event);
+
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int fly_cancel(bContext *C, wmOperator *op)
+{
+ FlyInfo *fly = op->customdata;
+
+ fly->state = FLY_CANCEL;
+ flyEnd(C, fly);
+ op->customdata= NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
+static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int exit_code;
+
+ FlyInfo *fly = op->customdata;
+
+ fly->redraw= 0;
+
+ flyEvent(fly, event);
+
+ if(event->type==TIMER)
+ flyApply(fly);
+
+ if(fly->redraw) {;
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
+
+ exit_code = flyEnd(C, fly);
+
+ if(exit_code!=OPERATOR_RUNNING_MODAL)
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return exit_code;
+}
+
+void VIEW3D_OT_fly(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Fly Navigation";
+ ot->description= "Interactively fly around the scene.";
+ ot->idname= "VIEW3D_OT_fly";
+
+ /* api callbacks */
+ ot->invoke= fly_invoke;
+ ot->cancel= fly_cancel;
+ ot->modal= fly_modal;
+ ot->poll= ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag= OPTYPE_BLOCKING;
+
+}
+
/* ************************************** */
void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3])
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index e877f1fecae..84e42294946 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -100,6 +100,7 @@
#include "ED_markers.h"
#include "ED_util.h"
#include "ED_view3d.h"
+#include "ED_mesh.h"
#include "UI_view2d.h"
#include "WM_types.h"
@@ -108,6 +109,8 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
+#include "BLI_ghash.h"
+#include "BLI_linklist.h"
#include "PIL_time.h" /* sleep */
@@ -1318,7 +1321,12 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
if (t->flag & T_MODAL)
{
ts->prop_mode = t->prop_mode;
- ts->proportional = proportional;
+
+ /* only save back if it wasn't automatically disabled */
+ if ((t->options & CTX_NO_PET) == 0)
+ {
+ ts->proportional = proportional;
+ }
if(t->spacetype == SPACE_VIEW3D)
{
@@ -1428,6 +1436,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
case TFM_BONE_ENVELOPE:
initBoneEnvelope(t);
break;
+ case TFM_EDGE_SLIDE:
+ initEdgeSlide(t);
+ break;
case TFM_BONE_ROLL:
initBoneRoll(t);
break;
@@ -1705,38 +1716,30 @@ static void constraintTransLim(TransInfo *t, TransData *td)
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
bConstraintOb cob;
bConstraint *con;
-
+
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
Mat4One(cob.matrix);
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- cob.matrix[3][0]= tdi->locx[0];
- cob.matrix[3][1]= tdi->locy[0];
- cob.matrix[3][2]= tdi->locz[0];
- }
- else {
- VECCOPY(cob.matrix[3], td->loc);
- }
-
+ VECCOPY(cob.matrix[3], td->loc);
+
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
float tmat[4][4];
-
+
/* only consider constraint if enabled */
if (con->flag & CONSTRAINT_DISABLE) continue;
if (con->enforce == 0.0f) continue;
-
+
/* only use it if it's tagged for this purpose (and the right type) */
if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
bLocLimitConstraint *data= con->data;
-
+
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
-
+
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -1747,10 +1750,10 @@ static void constraintTransLim(TransInfo *t, TransData *td)
/* skip... incompatable spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -1759,17 +1762,9 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
}
}
-
+
/* copy results from cob->matrix */
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- tdi->locx[0]= cob.matrix[3][0];
- tdi->locy[0]= cob.matrix[3][1];
- tdi->locz[0]= cob.matrix[3][2];
- }
- else {
- VECCOPY(td->loc, cob.matrix[3]);
- }
+ VECCOPY(td->loc, cob.matrix[3]);
}
}
@@ -1785,25 +1780,14 @@ static void constraintRotLim(TransInfo *t, TransData *td)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */
if (td->ext)
QuatToMat4(td->ext->quat, cob.matrix);
else
return;
}
- else if (td->tdi) { // XXX depreceated
- /* ipo-keys eulers */
- TransDataIpokey *tdi= td->tdi;
- float eul[3];
-
- eul[0]= tdi->rotx[0];
- eul[1]= tdi->roty[0];
- eul[2]= tdi->rotz[0];
-
- EulOToMat4(eul, td->rotOrder, cob.matrix);
- }
- else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* axis angle */
if (td->ext)
AxisAngleToMat4(&td->ext->quat[1], td->ext->quat[0], cob.matrix);
@@ -1857,22 +1841,11 @@ static void constraintRotLim(TransInfo *t, TransData *td)
}
/* copy results from cob->matrix */
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
/* quats */
Mat4ToQuat(cob.matrix, td->ext->quat);
}
- else if (td->tdi) {
- /* ipo-keys eulers */
- TransDataIpokey *tdi= td->tdi;
- float eul[3];
-
- Mat4ToEulO(cob.matrix, eul, td->rotOrder);
-
- tdi->rotx[0]= eul[0];
- tdi->roty[0]= eul[1];
- tdi->rotz[0]= eul[2];
- }
- else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* axis angle */
Mat4ToAxisAngle(cob.matrix, &td->ext->quat[1], &td->ext->quat[0]);
}
@@ -1889,22 +1862,13 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob;
bConstraint *con;
-
+
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- float size[3];
-
- size[0]= tdi->sizex[0];
- size[1]= tdi->sizey[0];
- size[2]= tdi->sizez[0];
- SizeToMat4(size, cob.matrix);
- }
- else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
return; // TODO: fix this case
}
@@ -1912,25 +1876,25 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
-
+
SizeToMat4(td->ext->size, cob.matrix);
}
-
+
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
/* only consider constraint if enabled */
if (con->flag & CONSTRAINT_DISABLE) continue;
if (con->enforce == 0.0f) continue;
-
+
/* we're only interested in Limit-Scale constraints */
if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
bSizeLimitConstraint *data= con->data;
float tmat[4][4];
-
+
/* only use it if it's tagged for this purpose */
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
-
+
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -1941,10 +1905,10 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* skip... incompatable spacetype */
continue;
}
-
+
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
-
+
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -1953,19 +1917,9 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
}
}
}
-
+
/* copy results from cob->matrix */
- if (td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- float size[3];
-
- Mat4ToSize(cob.matrix, size);
-
- tdi->sizex[0]= size[0];
- tdi->sizey[0]= size[1];
- tdi->sizez[0]= size[2];
- }
- else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
return; // TODO: fix this case
}
@@ -1973,7 +1927,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
-
+
Mat4ToSize(cob.matrix, td->ext->size);
}
}
@@ -1985,21 +1939,21 @@ void initWarp(TransInfo *t)
{
float max[3], min[3];
int i;
-
+
t->mode = TFM_WARP;
t->transform = Warp;
t->handleEvent = handleEventWarp;
-
+
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 5.0f;
t->snap[2] = 1.0f;
-
+
t->flag |= T_NO_CONSTRAINT;
-
+
/* we need min/max in view space */
for(i = 0; i < t->total; i++) {
float center[3];
@@ -2014,7 +1968,7 @@ void initWarp(TransInfo *t)
VECCOPY(min, center);
}
}
-
+
t->center[0]= (min[0]+max[0])/2.0f;
t->center[1]= (min[1]+max[1])/2.0f;
t->center[2]= (min[2]+max[2])/2.0f;
@@ -2026,7 +1980,7 @@ void initWarp(TransInfo *t)
int handleEventWarp(TransInfo *t, wmEvent *event)
{
int status = 0;
-
+
if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
{
// Use customData pointer to signal warp direction
@@ -2034,10 +1988,10 @@ int handleEventWarp(TransInfo *t, wmEvent *event)
t->customData = (void*)1;
else
t->customData = 0;
-
+
status = 1;
}
-
+
return status;
}
@@ -2047,7 +2001,7 @@ int Warp(TransInfo *t, short mval[2])
float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3];
int i;
char str[50];
-
+
curs= give_cursor(t->scene, t->view);
/*
* gcursor is the one used for helpline.
@@ -2068,73 +2022,73 @@ int Warp(TransInfo *t, short mval[2])
}
Mat4MulVecfl(t->viewmat, cursor);
VecSubf(cursor, cursor, t->viewmat[3]);
-
+
/* amount of degrees for warp */
circumfac = 360.0f * t->values[0];
-
+
if (t->customData) /* non-null value indicates reversed input */
{
circumfac *= -1;
}
-
+
snapGrid(t, &circumfac);
applyNumInput(&t->num, &circumfac);
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "Warp: %s", c);
}
else {
/* default header print */
sprintf(str, "Warp: %.3f", circumfac);
}
-
+
circumfac*= (float)(-M_PI/360.0);
-
+
for(i = 0; i < t->total; i++, td++) {
float loc[3];
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
/* translate point to center, rotate in such a way that outline==distance */
VECCOPY(vec, td->iloc);
Mat3MulVecfl(td->mtx, vec);
Mat4MulVecfl(t->viewmat, vec);
VecSubf(vec, vec, t->viewmat[3]);
-
+
dist= vec[0]-cursor[0];
-
+
/* t->val is X dimension projected boundbox */
phi0= (circumfac*dist/t->val);
-
+
vec[1]= (vec[1]-cursor[1]);
-
+
co= (float)cos(phi0);
si= (float)sin(phi0);
loc[0]= -si*vec[1]+cursor[0];
loc[1]= co*vec[1]+cursor[1];
loc[2]= vec[2];
-
+
Mat4MulVecfl(t->viewinv, loc);
VecSubf(loc, loc, t->viewinv[3]);
Mat3MulVecfl(td->smtx, loc);
-
+
VecSubf(loc, loc, td->iloc);
VecMulf(loc, td->factor);
VecAddf(td->loc, td->iloc, loc);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -2145,22 +2099,22 @@ void initShear(TransInfo *t)
t->mode = TFM_SHEAR;
t->transform = Shear;
t->handleEvent = handleEventShear;
-
+
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
+
t->flag |= T_NO_CONSTRAINT;
}
int handleEventShear(TransInfo *t, wmEvent *event)
{
int status = 0;
-
+
if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
{
// Use customData pointer to signal Shear direction
@@ -2174,10 +2128,10 @@ int handleEventShear(TransInfo *t, wmEvent *event)
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
t->customData = 0;
}
-
+
status = 1;
}
-
+
return status;
}
@@ -2190,47 +2144,47 @@ int Shear(TransInfo *t, short mval[2])
float value;
int i;
char str[50];
-
+
Mat3CpyMat4(persmat, t->viewmat);
Mat3Inv(persinv, persmat);
-
+
value = 0.05f * t->values[0];
-
+
snapGrid(t, &value);
-
+
applyNumInput(&t->num, &value);
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "Shear: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "Shear: %.3f %s", value, t->proptext);
}
-
+
Mat3One(smat);
-
+
// Custom data signals shear direction
if (t->customData == 0)
smat[1][0] = value;
else
smat[0][1] = value;
-
+
Mat3MulMat3(tmat, smat, persmat);
Mat3MulMat3(totmat, persinv, tmat);
-
+
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (t->obedit) {
float mat3[3][3];
Mat3MulMat3(mat3, totmat, td->mtx);
@@ -2240,19 +2194,19 @@ int Shear(TransInfo *t, short mval[2])
Mat3CpyMat3(tmat, totmat);
}
VecSubf(vec, td->center, t->center);
-
+
Mat3MulVecfl(tmat, vec);
-
+
VecAddf(vec, vec, t->center);
VecSubf(vec, vec, td->center);
-
+
VecMulf(vec, td->factor);
-
+
VecAddf(td->loc, td->iloc, vec);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
return 1;
@@ -2264,9 +2218,9 @@ void initResize(TransInfo *t)
{
t->mode = TFM_RESIZE;
t->transform = Resize;
-
+
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
-
+
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
@@ -2274,7 +2228,7 @@ void initResize(TransInfo *t)
t->flag |= T_NO_ZERO;
t->num.flag |= NUM_NO_ZERO;
}
-
+
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
@@ -2292,7 +2246,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
sprintf(&tvec[20], "%.4f", vec[1]);
sprintf(&tvec[40], "%.4f", vec[2]);
}
-
+
if (t->con.mode & CON_APPLY) {
switch(t->num.idx_max) {
case 0:
@@ -2320,14 +2274,14 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
static void TransMat3ToSize( float mat[][3], float smat[][3], float *size)
{
float vec[3];
-
+
VecCopyf(vec, mat[0]);
size[0]= Normalize(vec);
VecCopyf(vec, mat[1]);
size[1]= Normalize(vec);
VecCopyf(vec, mat[2]);
size[2]= Normalize(vec);
-
+
/* first tried with dotproduct... but the sign flip is crucial */
if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0];
if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1];
@@ -2338,7 +2292,7 @@ static void TransMat3ToSize( float mat[][3], float smat[][3], float *size)
static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
float tmat[3][3], smat[3][3], center[3];
float vec[3];
-
+
if (t->flag & T_EDIT) {
Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->smtx, smat);
@@ -2346,18 +2300,18 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
else {
Mat3CpyMat3(tmat, mat);
}
-
+
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
-
+
/* local constraint shouldn't alter center */
if (t->around == V3D_LOCAL) {
if (t->flag & T_OBJECT) {
VECCOPY(center, td->center);
}
else if (t->flag & T_EDIT) {
-
+
if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
VECCOPY(center, td->center);
}
@@ -2372,10 +2326,10 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
else {
VECCOPY(center, t->center);
}
-
+
if (td->ext) {
float fsize[3];
-
+
if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) {
float obsizemat[3][3];
// Reorient the size mat to fit the oriented object.
@@ -2387,28 +2341,14 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
else {
Mat3ToSize(tmat, fsize);
}
-
+
protectedSizeBits(td->protectflag, fsize);
-
+
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself
- /* handle ipokeys? */
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- /* calculate delta size (equal for size and dsize) */
-
- vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor;
- vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor;
- vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor;
-
- add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]);
- add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]);
- add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]);
-
- }
- else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
+ if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
/* scale val and reset size */
*td->val = td->ival * fsize[0] * td->factor;
-
+
td->ext->size[0] = td->ext->isize[0];
td->ext->size[1] = td->ext->isize[1];
td->ext->size[2] = td->ext->isize[2];
@@ -2417,46 +2357,39 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
*td->val = td->ival;
-
+
td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor;
td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor;
td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor;
}
}
-
+
constraintSizeLim(t, td);
}
-
+
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_POINTS)
VecSubf(vec, td->iloc, center);
else
VecSubf(vec, td->center, center);
-
+
Mat3MulVecfl(tmat, vec);
-
+
VecAddf(vec, vec, center);
if (t->flag & T_POINTS)
VecSubf(vec, vec, td->iloc);
else
VecSubf(vec, vec, td->center);
-
+
VecMulf(vec, td->factor);
-
+
if (t->flag & (T_OBJECT|T_POSE)) {
Mat3MulVecfl(td->smtx, vec);
}
-
+
protectedTransBits(td->protectflag, vec);
-
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
- }
- else VecAddf(td->loc, td->iloc, vec);
-
+ VecAddf(td->loc, td->iloc, vec);
+
constraintTransLim(t, td);
}
@@ -2467,7 +2400,7 @@ int Resize(TransInfo *t, short mval[2])
float ratio;
int i;
char str[200];
-
+
/* for manipulator, center handle, the scaling can't be done relative to center */
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0)
{
@@ -2477,60 +2410,60 @@ int Resize(TransInfo *t, short mval[2])
{
ratio = t->values[0];
}
-
+
size[0] = size[1] = size[2] = ratio;
-
+
snapGrid(t, size);
-
+
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
-
+
applySnapping(t, size);
-
+
if (t->flag & T_AUTOVALUES)
{
VECCOPY(size, t->auto_values);
}
-
+
VECCOPY(t->values, size);
-
+
SizeToMat3(size, mat);
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
+
Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+
headerResize(t, size, str);
-
+
for(i = 0, td=t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
ElementResize(t, td, mat);
}
-
+
/* evil hack - redo resize if cliping needed */
if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) {
SizeToMat3(size, mat);
-
+
if (t->con.applySize)
t->con.applySize(t, NULL, mat);
-
+
for(i = 0, td=t->data; i < t->total; i++, td++)
ElementResize(t, td, mat);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -2540,26 +2473,26 @@ void initToSphere(TransInfo *t)
{
TransData *td = t->data;
int i;
-
+
t->mode = TFM_TOSPHERE;
t->transform = ToSphere;
-
+
initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
+
t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
-
+
// Calculate average radius
for(i = 0 ; i < t->total; i++, td++) {
t->val += VecLenf(t->center, td->iloc);
}
-
+
t->val /= (float)t->total;
}
@@ -2570,56 +2503,56 @@ int ToSphere(TransInfo *t, short mval[2])
int i;
char str[64];
TransData *td = t->data;
-
+
ratio = t->values[0];
-
+
snapGrid(t, &ratio);
-
+
applyNumInput(&t->num, &ratio);
-
+
if (ratio < 0)
ratio = 0.0f;
else if (ratio > 1)
ratio = 1.0f;
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "To Sphere: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "To Sphere: %.4f %s", ratio, t->proptext);
}
-
-
+
+
for(i = 0 ; i < t->total; i++, td++) {
float tratio;
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
VecSubf(vec, td->iloc, t->center);
-
+
radius = Normalize(vec);
-
+
tratio = ratio * td->factor;
-
+
VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio);
-
+
VecAddf(td->loc, t->center, vec);
}
-
-
+
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -2630,19 +2563,19 @@ void initRotation(TransInfo *t)
{
t->mode = TFM_ROTATION;
t->transform = Rotation;
-
+
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
-
+
t->ndof.axis = 16;
/* Scale down and flip input for rotation */
t->ndof.factor[0] = -0.2f;
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
-
+
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
}
@@ -2651,7 +2584,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
float vec[3], totmat[3][3], smat[3][3];
float eul[3], fmat[3][3], quat[4];
float *center = t->center;
-
+
/* local constraint shouldn't alter center */
if (around == V3D_LOCAL) {
if (t->flag & (T_OBJECT|T_POSE)) {
@@ -2664,27 +2597,28 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
}
}
}
-
+
if (t->flag & T_POINTS) {
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
-
+
VecSubf(vec, td->iloc, center);
Mat3MulVecfl(smat, vec);
-
+
VecAddf(td->loc, vec, center);
-
+
VecSubf(vec,td->loc,td->iloc);
protectedTransBits(td->protectflag, vec);
VecAddf(td->loc, td->iloc, vec);
-
+
+
if(td->flag & TD_USEQUAT) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
-
+
if(td->ext->quat){
QuatMul(td->ext->quat, quat, td->ext->iquat);
-
+
/* is there a reason not to have this here? -jahka */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
@@ -2704,48 +2638,48 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
*/
else if (t->flag & T_POSE) {
float pmtx[3][3], imtx[3][3];
-
+
// Extract and invert armature object matrix
Mat3CpyMat4(pmtx, t->poseobj->obmat);
Mat3Inv(imtx, pmtx);
-
+
if ((td->flag & TD_NO_LOC) == 0)
{
VecSubf(vec, td->center, center);
-
+
Mat3MulVecfl(pmtx, vec); // To Global space
Mat3MulVecfl(mat, vec); // Applying rotation
Mat3MulVecfl(imtx, vec); // To Local space
-
+
VecAddf(vec, vec, center);
/* vec now is the location where the object has to be */
-
+
VecSubf(vec, vec, td->center); // Translation needed from the initial location
-
+
Mat3MulVecfl(pmtx, vec); // To Global space
Mat3MulVecfl(td->smtx, vec);// To Pose space
-
+
protectedTransBits(td->protectflag, vec);
-
+
VecAddf(td->loc, td->iloc, vec);
-
+
constraintTransLim(t, td);
}
-
+
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
/* euler or quaternion/axis-angle? */
- if (td->flag & TD_USEQUAT) {
+ if (td->rotOrder == ROT_MODE_QUAT) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
-
+
Mat3ToQuat(fmat, quat); // Actual transform
-
+
QuatMul(td->ext->quat, quat, td->ext->iquat);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
- else if (td->rotOrder == PCHAN_ROT_AXISANGLE) {
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
float iquat[4];
@@ -2797,93 +2731,67 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
/* vec now is the location where the object has to be */
VecSubf(vec, vec, td->center);
Mat3MulVecfl(td->smtx, vec);
-
+
protectedTransBits(td->protectflag, vec);
-
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
- }
- else VecAddf(td->loc, td->iloc, vec);
+
+ VecAddf(td->loc, td->iloc, vec);
}
-
-
+
+
constraintTransLim(t, td);
-
+
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
/* euler or quaternion? */
- if (td->flag & TD_USEQUAT) {
+ if ((td->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
-
+
QuatMul(td->ext->quat, quat, td->ext->iquat);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
+ else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+ /* calculate effect based on quats */
+ float iquat[4];
+
+ /* td->ext->(i)quat is in axis-angle form, not quats! */
+ AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]);
+
+ Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+ Mat3ToQuat(fmat, quat); // Actual transform
+
+ QuatMul(td->ext->quat, quat, iquat);
+
+ /* make temp copy (since stored in same place) */
+ QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro
+ QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]);
+
+ /* this function works on end result */
+ protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
else {
float obmat[3][3];
-
- /* are there ipo keys? */
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- float current_rot[3];
- float rot[3];
-
- /* current IPO value for compatible euler */
- current_rot[0] = (tdi->rotx) ? tdi->rotx[0] : 0.0f;
- current_rot[1] = (tdi->roty) ? tdi->roty[0] : 0.0f;
- current_rot[2] = (tdi->rotz) ? tdi->rotz[0] : 0.0f;
- VecMulf(current_rot, (float)(M_PI_2 / 9.0));
-
- /* calculate the total rotatation in eulers */
- VecAddf(eul, td->ext->irot, td->ext->drot);
- EulToMat3(eul, obmat);
- /* mat = transform, obmat = object rotation */
- Mat3MulMat3(fmat, mat, obmat);
-
- Mat3ToCompatibleEul(fmat, eul, current_rot);
-
- /* correct back for delta rot */
- if(tdi->flag & TOB_IPODROT) {
- VecSubf(rot, eul, td->ext->irot);
- }
- else {
- VecSubf(rot, eul, td->ext->drot);
- }
-
- VecMulf(rot, (float)(9.0/M_PI_2));
- VecSubf(rot, rot, tdi->oldrot);
-
- protectedRotateBits(td->protectflag, rot, tdi->oldrot);
-
- add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]);
- add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]);
- add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]);
- }
- else {
- Mat3MulMat3(totmat, mat, td->mtx);
- Mat3MulMat3(smat, td->smtx, totmat);
-
- /* calculate the total rotatation in eulers */
- VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
- EulToMat3(eul, obmat);
- /* mat = transform, obmat = object rotation */
- Mat3MulMat3(fmat, smat, obmat);
-
- Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
-
- /* correct back for delta rot */
- VecSubf(eul, eul, td->ext->drot);
-
- /* and apply */
- protectedRotateBits(td->protectflag, eul, td->ext->irot);
- VECCOPY(td->ext->rot, eul);
- }
+
+ Mat3MulMat3(totmat, mat, td->mtx);
+ Mat3MulMat3(smat, td->smtx, totmat);
+
+ /* calculate the total rotatation in eulers */
+ VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
+ EulOToMat3(eul, td->rotOrder, obmat);
+ /* mat = transform, obmat = object rotation */
+ Mat3MulMat3(fmat, smat, obmat);
+
+ Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder);
+
+ /* correct back for delta rot */
+ VecSubf(eul, eul, td->ext->drot);
+
+ /* and apply */
+ protectedRotateBits(td->protectflag, eul, td->ext->irot);
+ VECCOPY(td->ext->rot, eul);
}
-
+
constraintRotLim(t, td);
}
}
@@ -2894,17 +2802,17 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
TransData *td = t->data;
float mat[3][3];
int i;
-
+
VecRotToMat3(axis, angle, mat);
-
+
for(i = 0 ; i < t->total; i++, td++) {
-
+
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (t->con.applyRot) {
t->con.applyRot(t, td, axis, NULL);
VecRotToMat3(axis, angle * td->factor, mat);
@@ -2912,7 +2820,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
else if (t->flag & T_PROP_EDIT) {
VecRotToMat3(axis, angle * td->factor, mat);
}
-
+
ElementRotation(t, td, mat, t->around);
}
}
@@ -2920,62 +2828,62 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
int Rotation(TransInfo *t, short mval[2])
{
char str[64];
-
+
float final;
-
+
float axis[3];
float mat[3][3];
-
+
VECCOPY(axis, t->viewinv[2]);
VecMulf(axis, -1.0f);
Normalize(axis);
-
+
final = t->values[0];
-
+
applyNDofInput(&t->ndof, &final);
-
+
snapGrid(t, &final);
-
+
if (t->con.applyRot) {
t->con.applyRot(t, NULL, axis, &final);
}
-
+
applySnapping(t, &final);
-
+
if (hasNumInput(&t->num)) {
char c[20];
-
+
applyNumInput(&t->num, &final);
-
+
outputNumInput(&(t->num), c);
-
+
sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
-
+
/* Clamp between -180 and 180 */
while (final >= 180.0)
final -= 360.0;
-
+
while (final <= -180.0)
final += 360.0;
-
+
final *= (float)(M_PI / 180.0);
}
else {
sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext);
}
-
+
VecRotToMat3(axis, final, mat);
-
+
// TRANSFORM_FIX_ME
// t->values[0] = final; // used in manipulator
// Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+
applyRotation(t, final, axis);
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -3193,10 +3101,10 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
/* handle snapping rotation before doing the translation */
if (usingSnappingNormal(t))
{
@@ -3207,26 +3115,26 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
float quat[4];
float mat[3][3];
float angle;
-
+
Crossf(axis, original_normal, t->tsnap.snapNormal);
angle = saacos(Inpf(original_normal, t->tsnap.snapNormal));
-
+
AxisAngleToQuat(quat, axis, angle);
-
+
QuatToMat3(quat, mat);
-
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
else
{
float mat[3][3];
-
+
Mat3One(mat);
-
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
}
-
+
if (t->con.applyVec) {
float pvec[3];
t->con.applyVec(t, td, vec, tvec, pvec);
@@ -3234,21 +3142,14 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
else {
VECCOPY(tvec, vec);
}
-
+
Mat3MulVecfl(td->smtx, tvec);
VecMulf(tvec, td->factor);
-
+
protectedTransBits(td->protectflag, tvec);
-
- /* transdata ipokey */
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, tvec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, tvec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]);
- }
- else VecAddf(td->loc, td->iloc, tvec);
-
+
+ VecAddf(td->loc, td->iloc, tvec);
+
constraintTransLim(t, td);
}
}
@@ -3915,7 +3816,7 @@ int BoneSize(TransInfo *t, short mval[2])
float ratio;
int i;
char str[60];
-
+
// TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
/* for manipulator, center handle, the scaling can't be done relative to center */
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0)
@@ -3926,40 +3827,40 @@ int BoneSize(TransInfo *t, short mval[2])
{
ratio = t->values[0];
}
-
+
size[0] = size[1] = size[2] = ratio;
-
+
snapGrid(t, size);
-
+
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
-
+
SizeToMat3(size, mat);
-
+
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
-
+
Mat3CpyMat3(t->mat, mat); // used in manipulator
-
+
headerBoneSize(t, size, str);
-
+
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
ElementBoneSize(t, td, mat);
}
-
+
recalcData(t);
-
+
ED_area_headerprint(t->sa, str);
-
+
return 1;
}
@@ -3970,15 +3871,15 @@ void initBoneEnvelope(TransInfo *t)
{
t->mode = TFM_BONE_ENVELOPE;
t->transform = BoneEnvelope;
-
+
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
-
+
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3988,31 +3889,31 @@ int BoneEnvelope(TransInfo *t, short mval[2])
float ratio;
int i;
char str[50];
-
+
ratio = t->values[0];
-
+
snapGrid(t, &ratio);
-
+
applyNumInput(&t->num, &ratio);
-
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
-
+
outputNumInput(&(t->num), c);
sprintf(str, "Envelope: %s", c);
}
else {
sprintf(str, "Envelope: %3f", ratio);
}
-
+
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
if (td->val) {
/* if the old/original value was 0.0f, then just use ratio */
if (td->ival)
@@ -4021,6 +3922,693 @@ int BoneEnvelope(TransInfo *t, short mval[2])
*td->val= ratio;
}
}
+
+ recalcData(t);
+
+ ED_area_headerprint(t->sa, str);
+
+ return 1;
+}
+
+/* ******************** Edge Slide *************** */
+
+static int createSlideVerts(TransInfo *t)
+{
+ Mesh *me = t->obedit->data;
+ EditMesh *em = me->edit_mesh;
+ EditFace *efa;
+ EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
+ EditVert *ev, *nearest = NULL;
+ LinkNode *edgelist = NULL, *vertlist=NULL, *look;
+ GHash *vertgh;
+ TransDataSlideVert *tempsv;
+ float perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4];
+ float shiftlabda= 0.0f,len = 0.0f;
+ int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
+ int wasshift = 0;
+ /* UV correction vars */
+ GHash **uvarray= NULL;
+ SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ int uvlay_idx;
+ TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
+ RegionView3D *v3d = t->ar->regiondata;
+ float projectMat[4][4];
+ float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
+ float vec[3];
+ //short mval[2], mvalo[2];
+ float labda = 0.0f, totvec=0.0;
+
+ if (!v3d) {
+ /*ok, let's try to survive this*/
+ Mat4One(projectMat);
+ } else {
+ view3d_get_object_project_mat(v3d, t->obedit, projectMat);
+ }
+
+ //mvalo[0] = -1; mvalo[1] = -1;
+ numsel =0;
+
+ // Get number of selected edges and clear some flags
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ eed->f1 = 0;
+ eed->f2 = 0;
+ if(eed->f & SELECT) numsel++;
+ }
+
+ for(ev=em->verts.first;ev;ev=ev->next) {
+ ev->f1 = 0;
+ }
+
+ //Make sure each edge only has 2 faces
+ // make sure loop doesn't cross face
+ for(efa=em->faces.first;efa;efa=efa->next) {
+ int ct = 0;
+ if(efa->e1->f & SELECT) {
+ ct++;
+ efa->e1->f1++;
+ if(efa->e1->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ if(efa->e2->f & SELECT) {
+ ct++;
+ efa->e2->f1++;
+ if(efa->e2->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ if(efa->e3->f & SELECT) {
+ ct++;
+ efa->e3->f1++;
+ if(efa->e3->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ if(efa->e4 && efa->e4->f & SELECT) {
+ ct++;
+ efa->e4->f1++;
+ if(efa->e4->f1 > 2) {
+ //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
+ return 0;
+ }
+ }
+ // Make sure loop is not 2 edges of same face
+ if(ct > 1) {
+ //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
+ return 0;
+ }
+ }
+
+ // Get # of selected verts
+ for(ev=em->verts.first;ev;ev=ev->next) {
+ if(ev->f & SELECT) vertsel++;
+ }
+
+ // Test for multiple segments
+ if(vertsel > numsel+1) {
+ //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop");
+ return 0;
+ }
+
+ // Get the edgeloop in order - mark f1 with SELECT once added
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if((eed->f & SELECT) && !(eed->f1 & SELECT)) {
+ // If this is the first edge added, just put it in
+ if(!edgelist) {
+ BLI_linklist_prepend(&edgelist,eed);
+ numadded++;
+ first = eed;
+ last = eed;
+ eed->f1 = SELECT;
+ } else {
+ if(editedge_getSharedVert(eed, last)) {
+ BLI_linklist_append(&edgelist,eed);
+ eed->f1 = SELECT;
+ numadded++;
+ last = eed;
+ } else if(editedge_getSharedVert(eed, first)) {
+ BLI_linklist_prepend(&edgelist,eed);
+ eed->f1 = SELECT;
+ numadded++;
+ first = eed;
+ }
+ }
+ }
+ if(eed->next == NULL && numadded != numsel) {
+ eed=em->edges.first;
+ timesthrough++;
+ }
+
+ // It looks like there was an unexpected case - Hopefully should not happen
+ if(timesthrough >= numsel*2) {
+ BLI_linklist_free(edgelist,NULL);
+ //BKE_report(op->reports, RPT_ERROR, "Could not order loop");
+ return 0;
+ }
+ }
+
+ // Put the verts in order in a linklist
+ look = edgelist;
+ while(look) {
+ eed = look->link;
+ if(!vertlist) {
+ if(look->next) {
+ temp = look->next->link;
+
+ //This is the first entry takes care of extra vert
+ if(eed->v1 != temp->v1 && eed->v1 != temp->v2) {
+ BLI_linklist_append(&vertlist,eed->v1);
+ eed->v1->f1 = 1;
+ } else {
+ BLI_linklist_append(&vertlist,eed->v2);
+ eed->v2->f1 = 1;
+ }
+ } else {
+ //This is the case that we only have 1 edge
+ BLI_linklist_append(&vertlist,eed->v1);
+ eed->v1->f1 = 1;
+ }
+ }
+ // for all the entries
+ if(eed->v1->f1 != 1) {
+ BLI_linklist_append(&vertlist,eed->v1);
+ eed->v1->f1 = 1;
+ } else if(eed->v2->f1 != 1) {
+ BLI_linklist_append(&vertlist,eed->v2);
+ eed->v2->f1 = 1;
+ }
+ look = look->next;
+ }
+
+ // populate the SlideVerts
+
+ vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ look = vertlist;
+ while(look) {
+ i=0;
+ j=0;
+ ev = look->link;
+ tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert");
+ tempsv->up = NULL;
+ tempsv->down = NULL;
+ tempsv->origvert.co[0] = ev->co[0];
+ tempsv->origvert.co[1] = ev->co[1];
+ tempsv->origvert.co[2] = ev->co[2];
+ tempsv->origvert.no[0] = ev->no[0];
+ tempsv->origvert.no[1] = ev->no[1];
+ tempsv->origvert.no[2] = ev->no[2];
+ // i is total edges that vert is on
+ // j is total selected edges that vert is on
+
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if(eed->v1 == ev || eed->v2 == ev) {
+ i++;
+ if(eed->f & SELECT) {
+ j++;
+ }
+ }
+ }
+ // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges
+ if(i == 4 && j == 2) {
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if(editedge_containsVert(eed, ev)) {
+ if(!(eed->f & SELECT)) {
+ if(!tempsv->up) {
+ tempsv->up = eed;
+ } else if (!(tempsv->down)) {
+ tempsv->down = eed;
+ }
+ }
+ }
+ }
+ }
+ // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected
+ if(i >= 3 && j == 1) {
+ for(eed=em->edges.first;eed;eed=eed->next) {
+ if(editedge_containsVert(eed, ev) && eed->f & SELECT) {
+ for(efa = em->faces.first;efa;efa=efa->next) {
+ if(editface_containsEdge(efa, eed)) {
+ if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e1;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e1;
+ }
+ }
+ if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e2;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e2;
+ }
+ }
+ if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e3;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e3;
+ }
+ }
+ if(efa->e4) {
+ if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) {
+ if(!tempsv->up) {
+ tempsv->up = efa->e4;
+ } else if (!(tempsv->down)) {
+ tempsv->down = efa->e4;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ if(i > 4 && j == 2) {
+ BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(vertlist,NULL);
+ BLI_linklist_free(edgelist,NULL);
+ return 0;
+ }
+ BLI_ghash_insert(vertgh,ev,tempsv);
+
+ look = look->next;
+ }
+
+ // make sure the UPs nad DOWNs are 'faceloops'
+ // Also find the nearest slidevert to the cursor
+
+ look = vertlist;
+ nearest = NULL;
+ vertdist = -1;
+ while(look) {
+ tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+
+ if(!tempsv->up || !tempsv->down) {
+ //BKE_report(op->reports, RPT_ERROR, "Missing rails");
+ BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(vertlist,NULL);
+ BLI_linklist_free(edgelist,NULL);
+ return 0;
+ }
+
+ if(me->drawflag & ME_DRAW_EDGELEN) {
+ if(!(tempsv->up->f & SELECT)) {
+ tempsv->up->f |= SELECT;
+ tempsv->up->f2 |= 16;
+ } else {
+ tempsv->up->f2 |= ~16;
+ }
+ if(!(tempsv->down->f & SELECT)) {
+ tempsv->down->f |= SELECT;
+ tempsv->down->f2 |= 16;
+ } else {
+ tempsv->down->f2 |= ~16;
+ }
+ }
+
+ if(look->next != NULL) {
+ TransDataSlideVert *sv;
+
+ ev = (EditVert*)look->next->link;
+ sv = BLI_ghash_lookup(vertgh, ev);
+
+ if(sv) {
+ float co[3], co2[3], vec[3];
+
+ ev = (EditVert*)look->link;
+
+ if(!sharesFace(em, tempsv->up,sv->up)) {
+ EditEdge *swap;
+ swap = sv->up;
+ sv->up = sv->down;
+ sv->down = swap;
+ }
+
+ if (v3d) {
+ view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat);
+ view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat);
+ }
+
+ if (ev == tempsv->up->v1) {
+ VecSubf(vec, co, co2);
+ } else {
+ VecSubf(vec, co2, co);
+ }
+
+ VecAddf(start, start, vec);
+
+ if (v3d) {
+ view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat);
+ view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat);
+ }
+
+ if (ev == tempsv->down->v1) {
+ VecSubf(vec, co2, co);
+ } else {
+ VecSubf(vec, co, co2);
+ }
+
+ VecAddf(end, end, vec);
+
+ totvec += 1.0f;
+ nearest = (EditVert*)look->link;
+ }
+ }
+
+
+
+ look = look->next;
+ }
+
+ VecAddf(start, start, end);
+ VecMulf(start, 0.5*(1.0/totvec));
+ VECCOPY(vec, start);
+ start[0] = t->mval[0];
+ start[1] = t->mval[1];
+ VecAddf(end, start, vec);
+
+ sld->start[0] = (short) start[0];
+ sld->start[1] = (short) start[1];
+ sld->end[0] = (short) end[0];
+ sld->end[1] = (short) end[1];
+
+ if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+ int maxnum = 0;
+
+ uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
+ sld->totuv = uvlay_tot;
+ suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */
+ suv = NULL;
+
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+
+ uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ for(ev=em->verts.first;ev;ev=ev->next) {
+ ev->tmp.l = 0;
+ }
+ look = vertlist;
+ while(look) {
+ float *uv_new;
+ tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+
+ ev = look->link;
+ suv = NULL;
+ for(efa = em->faces.first;efa;efa=efa->next) {
+ if (ev->tmp.l != -1) { /* test for self, in this case its invalid */
+ int k=-1; /* face corner */
+
+ /* Is this vert in the faces corner? */
+ if (efa->v1==ev) k=0;
+ else if (efa->v2==ev) k=1;
+ else if (efa->v3==ev) k=2;
+ else if (efa->v4 && efa->v4==ev) k=3;
+
+ if (k != -1) {
+ MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx);
+ EditVert *ev_up, *ev_down;
+
+ uv_new = tf->uv[k];
+
+ if (ev->tmp.l) {
+ if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) {
+ ev->tmp.l = -1; /* Tag as invalid */
+ BLI_linklist_free(suv->fuv_list,NULL);
+ suv->fuv_list = NULL;
+ BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
+ suv = NULL;
+ break;
+ }
+ } else {
+ ev->tmp.l = 1;
+ suv = suv_last;
+
+ suv->fuv_list = NULL;
+ suv->uv_up = suv->uv_down = NULL;
+ suv->origuv[0] = uv_new[0];
+ suv->origuv[1] = uv_new[1];
+
+ BLI_linklist_prepend(&suv->fuv_list, uv_new);
+ BLI_ghash_insert(uvarray[uvlay_idx],ev,suv);
+
+ suv_last++; /* advance to next slide UV */
+ maxnum++;
+ }
+
+ /* Now get the uvs along the up or down edge if we can */
+ if (suv) {
+ if (!suv->uv_up) {
+ ev_up = editedge_getOtherVert(tempsv->up,ev);
+ if (efa->v1==ev_up) suv->uv_up = tf->uv[0];
+ else if (efa->v2==ev_up) suv->uv_up = tf->uv[1];
+ else if (efa->v3==ev_up) suv->uv_up = tf->uv[2];
+ else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3];
+ }
+ if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */
+ ev_down = editedge_getOtherVert(tempsv->down,ev);
+ if (efa->v1==ev_down) suv->uv_down = tf->uv[0];
+ else if (efa->v2==ev_down) suv->uv_down = tf->uv[1];
+ else if (efa->v3==ev_down) suv->uv_down = tf->uv[2];
+ else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3];
+ }
+
+ /* Copy the pointers to the face UV's */
+ BLI_linklist_prepend(&suv->fuv_list, uv_new);
+ }
+ }
+ }
+ }
+ look = look->next;
+ }
+ } /* end uv layer loop */
+ } /* end uvlay_tot */
+
+ sld->uvhash = uvarray;
+ sld->slideuv = slideuvs;
+ sld->vhash = vertgh;
+ sld->nearest = nearest;
+ sld->vertlist = vertlist;
+ sld->edgelist = edgelist;
+ sld->suv_last = suv_last;
+ sld->uvlay_tot = uvlay_tot;
+
+ // we should have enough info now to slide
+
+ t->customData = sld;
+
+ return 1;
+}
+
+void freeSlideVerts(TransInfo *t)
+{
+ TransDataSlideUv *suv;
+ SlideData *sld = t->customData;
+ int uvlay_idx;
+
+ //BLI_ghash_free(edgesgh, freeGHash, NULL);
+ BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(sld->vertlist, NULL);
+ BLI_linklist_free(sld->edgelist, NULL);
+
+ if (sld->uvlay_tot) {
+ for (uvlay_idx=0; uvlay_idx<sld->uvlay_tot; uvlay_idx++) {
+ BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL);
+ }
+
+ suv = sld->suv_last-1;
+ while (suv >= sld->slideuv) {
+ if (suv->fuv_list) {
+ BLI_linklist_free(suv->fuv_list,NULL);
+ }
+ suv--;
+ }
+
+ MEM_freeN(sld->slideuv);
+ MEM_freeN(sld->uvhash);
+ }
+
+ MEM_freeN(sld);
+ t->customData = NULL;
+}
+
+void initEdgeSlide(TransInfo *t)
+{
+ SlideData *sld;
+
+ t->mode = TFM_EDGE_SLIDE;
+ t->transform = EdgeSlide;
+
+ createSlideVerts(t);
+ sld = t->customData;
+
+ if (!sld)
+ return;
+
+ t->customFree = freeSlideVerts;
+
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+ setCustomPoints(t, &t->mouse, sld->end, sld->start);
+
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = (float)((5.0/180)*M_PI);
+ t->snap[2] = t->snap[1] * 0.2f;
+
+ t->flag |= T_NO_CONSTRAINT;
+}
+
+int doEdgeSlide(TransInfo *t, float perc)
+{
+ Mesh *me= t->obedit->data;
+ EditMesh *em = me->edit_mesh;
+ SlideData *sld = t->customData;
+ EditEdge *first=NULL,*last=NULL, *temp = NULL;
+ EditVert *ev, *nearest = sld->nearest;
+ EditVert *centerVert, *upVert, *downVert;
+ LinkNode *edgelist = sld->edgelist, *vertlist=sld->vertlist, *look;
+ GHash *vertgh = sld->vhash;
+ TransDataSlideVert *tempsv;
+ float shiftlabda= 0.0f,len = 0.0f;
+ int i = 0, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
+ int wasshift = 0;
+ /* UV correction vars */
+ GHash **uvarray= sld->uvhash;
+ int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ int uvlay_idx;
+ TransDataSlideUv *slideuvs=sld->slideuv, *suv=sld->slideuv, *suv_last=NULL;
+ float uv_tmp[2];
+ LinkNode *fuv_link;
+ float labda = 0.0f;
+
+ len = 0.0f;
+
+ tempsv = BLI_ghash_lookup(vertgh,nearest);
+
+ centerVert = editedge_getSharedVert(tempsv->up, tempsv->down);
+ upVert = editedge_getOtherVert(tempsv->up, centerVert);
+ downVert = editedge_getOtherVert(tempsv->down, centerVert);
+
+ len = MIN2(perc, VecLenf(upVert->co,downVert->co));
+ len = MAX2(len, 0);
+
+ //Adjust Edgeloop
+ if(prop) {
+ look = vertlist;
+ while(look) {
+ EditVert *tempev;
+ ev = look->link;
+ tempsv = BLI_ghash_lookup(vertgh,ev);
+
+ tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
+ VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
+
+ if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+ suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+ if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+ Vec2Lerpf(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc));
+ fuv_link = suv->fuv_list;
+ while (fuv_link) {
+ VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+ fuv_link = fuv_link->next;
+ }
+ }
+ }
+ }
+
+ look = look->next;
+ }
+ }
+ else {
+ //Non prop code
+ look = vertlist;
+ while(look) {
+ float newlen;
+ ev = look->link;
+ tempsv = BLI_ghash_lookup(vertgh,ev);
+ newlen = (len / VecLenf(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co));
+ if(newlen > 1.0) {newlen = 1.0;}
+ if(newlen < 0.0) {newlen = 0.0;}
+ if(flip == 0) {
+ VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
+ if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ /* dont do anything if no UVs */
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+ suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+ if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+ Vec2Lerpf(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen));
+ fuv_link = suv->fuv_list;
+ while (fuv_link) {
+ VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+ fuv_link = fuv_link->next;
+ }
+ }
+ }
+ }
+ } else{
+ VecLerpf(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
+
+ if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ /* dont do anything if no UVs */
+ for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+ suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+ if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+ Vec2Lerpf(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen));
+ fuv_link = suv->fuv_list;
+ while (fuv_link) {
+ VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+ fuv_link = fuv_link->next;
+ }
+ }
+ }
+ }
+ }
+ look = look->next;
+ }
+
+ }
+
+ return 1;
+}
+
+int EdgeSlide(TransInfo *t, short mval[2])
+{
+ TransData *td = t->data;
+ char str[50];
+ float final;
+
+ final = t->values[0];
+
+ snapGrid(t, &final);
+
+ if (hasNumInput(&t->num)) {
+ char c[20];
+
+ applyNumInput(&t->num, &final);
+
+ outputNumInput(&(t->num), c);
+
+ sprintf(str, "Edge Slide Percent: %s", &c[0]);
+ }
+ else {
+ sprintf(str, "Edge Slide Percent: %.2f", final);
+ }
+
+ CLAMP(final, -1.0f, 1.0f);
+
+ /*do stuff here*/
+ if (t->customData)
+ doEdgeSlide(t, final);
+ else {
+ strcpy(str, "Invalid Edge Selection");
+ t->state = TRANS_CANCEL;
+ }
recalcData(t);
@@ -4029,7 +4617,6 @@ int BoneEnvelope(TransInfo *t, short mval[2])
return 1;
}
-
/* ******************** EditBone roll *************** */
void initBoneRoll(TransInfo *t)
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index e5bd405c0cd..2c19bf932eb 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -32,10 +32,13 @@
#include "ED_transform.h"
+#include "BLI_editVert.h"
+
/* ************************** Types ***************************** */
struct TransInfo;
struct TransData;
+struct TransformOrientation;
struct TransSnap;
struct NumInput;
struct Object;
@@ -52,6 +55,7 @@ struct bContext;
struct wmEvent;
struct wmTimer;
struct ARegion;
+struct ReportList;
typedef struct NDofInput {
int flag;
@@ -118,20 +122,9 @@ typedef struct TransCon {
/* Apply function pointer for rotation transformation */
} TransCon;
-typedef struct TransDataIpokey {
- int flag; /* which keys */
- float *locx, *locy, *locz; /* channel pointers */
- float *rotx, *roty, *rotz;
- float *quatx, *quaty, *quatz, *quatw;
- float *sizex, *sizey, *sizez;
- float oldloc[9]; /* storage old values */
- float oldrot[9];
- float oldsize[9];
- float oldquat[12];
-} TransDataIpokey;
-
typedef struct TransDataExtension {
float drot[3]; /* Initial object drot */
+ float dquat[4]; /* Initial object dquat */
float dsize[3]; /* Initial object dsize */
float *rot; /* Rotation of the data to transform (Faculative) */
float irot[3]; /* Initial rotation */
@@ -179,6 +172,31 @@ typedef struct TransDataNla {
int handle; /* handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends */
} TransDataNla;
+struct LinkNode;
+struct EditEdge;
+struct EditVert;
+struct GHash;
+typedef struct TransDataSlideUv {
+ float origuv[2];
+ float *uv_up, *uv_down;
+ //float *fuv[4];
+ struct LinkNode *fuv_list;
+} TransDataSlideUv;
+
+typedef struct TransDataSlideVert {
+ struct EditEdge *up, *down;
+ struct EditVert origvert;
+} TransDataSlideVert;
+
+typedef struct SlideData {
+ TransDataSlideUv *slideuv, *suv_last;
+ int totuv, uvlay_tot;
+ struct GHash *vhash, **uvhash;
+ struct EditVert *nearest;
+ struct LinkNode *edgelist, *vertlist;
+ short start[2], end[2];
+} SlideData;
+
typedef struct TransData {
float dist; /* Distance needed to affect element (for Proportionnal Editing) */
float rdist; /* Distance to the nearest element (for Proportionnal Editing) */
@@ -194,7 +212,6 @@ typedef struct TransData {
struct Object *ob;
struct bConstraint *con; /* for objects/bones, the first constraint in its constraint stack */
TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */
- TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */
TransDataCurveHandleFlags *hdata; /* for curves, stores handle flags for modification/cancel */
void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */
short flag; /* Various flags */
@@ -210,6 +227,7 @@ typedef struct MouseInput {
short precision_mval[2]; /* mouse position when precision key was pressed */
int center[2];
float factor;
+ void *data; /* additional data, if needed by the particular function */
} MouseInput;
typedef struct TransInfo {
@@ -263,6 +281,7 @@ typedef struct TransInfo {
struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */
void *customData; /* Per Transform custom data */
+ void (*customFree)(struct TransInfo *); /* if a special free function is needed */
/*************** NEW STUFF *********************/
@@ -466,6 +485,9 @@ int BoneEnvelope(TransInfo *t, short mval[2]);
void initBoneRoll(TransInfo *t);
int BoneRoll(TransInfo *t, short mval[2]);
+void initEdgeSlide(TransInfo *t);
+int EdgeSlide(TransInfo *t, short mval[2]);
+
void initTimeTranslate(TransInfo *t);
int TimeTranslate(TransInfo *t, short mval[2]);
@@ -575,7 +597,8 @@ typedef enum {
INPUT_HORIZONTAL_RATIO,
INPUT_HORIZONTAL_ABSOLUTE,
INPUT_VERTICAL_RATIO,
- INPUT_VERTICAL_ABSOLUTE
+ INPUT_VERTICAL_ABSOLUTE,
+ INPUT_CUSTOM_RATIO
} MouseInputMode;
void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], short mval[2]);
@@ -583,6 +606,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event);
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, short mval[2], float output[3]);
+void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2]);
+
/*********************** Generics ********************************/
int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event);
@@ -640,18 +665,17 @@ int handleNDofInput(NDofInput *n, struct wmEvent *event);
void initTransformOrientation(struct bContext *C, TransInfo *t);
-int manageObjectSpace(struct bContext *C, int confirm, int set);
-int manageMeshSpace(struct bContext *C, int confirm, int set);
-int manageBoneSpace(struct bContext *C, int confirm, int set);
+struct TransformOrientation *createObjectSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite);
+struct TransformOrientation *createMeshSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite);
+struct TransformOrientation *createBoneSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite);
/* Those two fill in mat and return non-zero on success */
int createSpaceNormal(float mat[3][3], float normal[3]);
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
-int addMatrixSpace(struct bContext *C, float mat[3][3], char name[]);
+struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite);
int addObjectSpace(struct bContext *C, struct Object *ob);
-void applyTransformOrientation(const struct bContext *C, TransInfo *t);
-
+void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name);
#define ORIENTATION_NONE 0
#define ORIENTATION_NORMAL 1
@@ -663,6 +687,8 @@ int getTransformOrientation(const struct bContext *C, float normal[3], float pla
int createSpaceNormal(float mat[3][3], float normal[3]);
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
+void freeSlideVerts(TransInfo *t);
+
#endif
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 6386c0d4eb7..f6d30a7bec9 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -379,7 +379,6 @@ static void createTransEdge(bContext *C, TransInfo *t) {
Mat3CpyMat3(td->mtx, mtx);
td->ext = NULL;
- td->tdi = NULL;
if (t->mode == TFM_BWEIGHT) {
td->val = &(eed->bweight);
td->ival = eed->bweight;
@@ -509,7 +508,7 @@ static short apply_targetless_ik(Object *ob)
/* rotation */
if (parchan->rotmode > 0)
Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode);
- else if (parchan->rotmode == PCHAN_ROT_AXISANGLE)
+ else if (parchan->rotmode == ROT_MODE_AXISANGLE)
Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]);
else
Mat3ToQuat(rmat3, parchan->quat);
@@ -519,7 +518,7 @@ static short apply_targetless_ik(Object *ob)
if (data->flag & CONSTRAINT_IK_STRETCH) {
if (parchan->rotmode > 0)
EulOToMat3(parchan->eul, parchan->rotmode, qrmat);
- else if (parchan->rotmode == PCHAN_ROT_AXISANGLE)
+ else if (parchan->rotmode == ROT_MODE_AXISANGLE)
AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat);
else
QuatToMat3(parchan->quat, qrmat);
@@ -556,10 +555,6 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ob = ob;
td->flag = TD_SELECTED;
- if (pchan->rotmode == PCHAN_ROT_QUAT)
- {
- td->flag |= TD_USEQUAT;
- }
if (bone->flag & BONE_HINGE_CHILD_TRANSFORM)
{
td->flag |= TD_NOCENTER;
@@ -584,15 +579,14 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ext->quat= NULL;
VECCOPY(td->ext->irot, pchan->eul);
- td->rotOrder= pchan->rotmode;
}
else {
td->ext->rot= NULL;
td->ext->quat= pchan->quat;
QUATCOPY(td->ext->iquat, pchan->quat);
- td->rotOrder= pchan->rotmode;
}
+ td->rotOrder= pchan->rotmode;
/* proper way to get parent transform + own transform + constraints transform */
@@ -1016,7 +1010,6 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob)
tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt");
for(i=0; i<t->total; i++, td++, tdx++) {
td->ext= tdx;
- td->tdi = NULL;
td->val = NULL;
}
@@ -1100,7 +1093,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1116,7 +1108,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1151,7 +1142,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
Mat3Ortho(td->axismtx);
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1168,7 +1158,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->flag= TD_SELECTED;
td->ext = NULL;
- td->tdi = NULL;
td++;
}
@@ -1196,7 +1185,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
}
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td++;
@@ -1219,7 +1207,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->extra = ebo; /* to fix roll */
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td++;
@@ -1272,7 +1259,6 @@ static void createTransMBallVerts(bContext *C, TransInfo *t)
Mat3CpyMat3(td->mtx, mtx);
td->ext = tx;
- td->tdi = NULL;
/* Radius of MetaElem (mass of MetaElem influence) */
if(ml->flag & MB_SCALE_RAD){
@@ -1437,7 +1423,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
else td->flag= 0;
}
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
hdata = initTransDataCurveHandes(td, bezt);
@@ -1458,7 +1443,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
td->ext = NULL;
- td->tdi = NULL;
if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
td->val = &(bezt->radius);
@@ -1498,7 +1482,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
else td->flag= 0;
}
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
if (hdata==NULL) { /* if the handle was not saved by the previous handle */
@@ -1538,7 +1521,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
if(bp->f1 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
td->ext = NULL;
- td->tdi = NULL;
if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) {
td->val = &(bp->radius);
@@ -1614,7 +1596,6 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t)
Mat3CpyMat3(td->mtx, mtx);
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td++;
@@ -1725,7 +1706,6 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
td->ob = ob;
td->ext = tx;
- td->tdi = NULL;
if(t->mode == TFM_BAKE_TIME) {
td->val = key->time;
td->ival = *(key->time);
@@ -1949,7 +1929,6 @@ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert
td->axismtx[1][2] = 0.0f;
td->ext = NULL;
- td->tdi = NULL;
td->val = NULL;
td->extra = NULL;
if (t->mode == TFM_BWEIGHT) {
@@ -2429,7 +2408,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
if(selected) {
td->flag |= TD_SELECTED;
@@ -2729,7 +2708,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0f;
@@ -2760,7 +2739,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0f;
@@ -3311,7 +3290,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
/* store AnimData info in td->extra, for applying mapping when flushing */
td->extra= adt;
@@ -3744,98 +3723,6 @@ void flushTransGraphData(TransInfo *t)
}
}
-/* **************** IpoKey stuff, for Object TransData ********** */
-
-/* while transforming */
-void add_tdi_poin(float *poin, float *old, float delta)
-{
- if(poin) {
- poin[0]= old[0]+delta;
- poin[-3]= old[3]+delta;
- poin[3]= old[6]+delta;
- }
-}
-
-#if 0 // TRANSFORM_FIX_ME
-/* storage of bezier triple. thats why -3 and +3! */
-static void set_tdi_old(float *old, float *poin)
-{
- old[0]= *(poin);
- old[3]= *(poin-3);
- old[6]= *(poin+3);
-}
-
-/* fill ipokey transdata with old vals and pointers */
-static void ipokey_to_transdata(IpoKey *ik, TransData *td)
-{
- extern int ob_ar[]; // blenkernel ipo.c
- TransDataIpokey *tdi= td->tdi;
- BezTriple *bezt;
- int a, delta= 0;
-
- td->val= NULL; // is read on ESC
-
- for(a=0; a<OB_TOTIPO; a++) {
- if(ik->data[a]) {
- bezt= ik->data[a];
-
- switch( ob_ar[a] ) {
- case OB_LOC_X:
- case OB_DLOC_X:
- tdi->locx= &(bezt->vec[1][1]); break;
- case OB_LOC_Y:
- case OB_DLOC_Y:
- tdi->locy= &(bezt->vec[1][1]); break;
- case OB_LOC_Z:
- case OB_DLOC_Z:
- tdi->locz= &(bezt->vec[1][1]); break;
-
- case OB_DROT_X:
- delta= 1;
- case OB_ROT_X:
- tdi->rotx= &(bezt->vec[1][1]); break;
- case OB_DROT_Y:
- delta= 1;
- case OB_ROT_Y:
- tdi->roty= &(bezt->vec[1][1]); break;
- case OB_DROT_Z:
- delta= 1;
- case OB_ROT_Z:
- tdi->rotz= &(bezt->vec[1][1]); break;
-
- case OB_SIZE_X:
- case OB_DSIZE_X:
- tdi->sizex= &(bezt->vec[1][1]); break;
- case OB_SIZE_Y:
- case OB_DSIZE_Y:
- tdi->sizey= &(bezt->vec[1][1]); break;
- case OB_SIZE_Z:
- case OB_DSIZE_Z:
- tdi->sizez= &(bezt->vec[1][1]); break;
- }
- }
- }
-
- /* oldvals for e.g. undo */
- if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
- if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
- if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
-
- /* remember, for mapping curves ('1'=10 degrees) */
- if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
- if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
- if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
-
- /* this is not allowed to be dsize! */
- if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
- if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
- if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
-
- tdi->flag= TOB_IPO;
- if(delta) tdi->flag |= TOB_IPODROT;
-}
-#endif
-
/* *************************** Object Transform data ******************* */
/* Little helper function for ObjectToTransData used to give certain
@@ -4053,7 +3940,7 @@ static TransData *SeqToTransData(TransInfo *t, TransData *td, TransData2D *td2d,
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0;
@@ -4194,20 +4081,20 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
if (skip_invert == 0 && (ob->track || constinv==0)) {
track= ob->track;
ob->track= NULL;
-
+
if (constinv == 0) {
fakecons.first = ob->constraints.first;
fakecons.last = ob->constraints.last;
ob->constraints.first = ob->constraints.last = NULL;
}
-
+
where_is_object(t->scene, ob);
-
+
if (constinv == 0) {
ob->constraints.first = fakecons.first;
ob->constraints.last = fakecons.last;
}
-
+
ob->track= track;
}
else
@@ -4221,6 +4108,10 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
td->ext->rot = ob->rot;
VECCOPY(td->ext->irot, ob->rot);
VECCOPY(td->ext->drot, ob->drot);
+
+ td->ext->quat = ob->quat;
+ QUATCOPY(td->ext->iquat, ob->quat);
+ QUATCOPY(td->ext->dquat, ob->dquat);
td->ext->size = ob->size;
VECCOPY(td->ext->isize, ob->size);
@@ -4262,7 +4153,7 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *
/* it deselects Bases, so we have to call the clear function always after */
static void set_trans_object_base_flags(bContext *C, TransInfo *t)
{
- Scene *sce = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
View3D *v3d = t->view;
/*
@@ -4279,15 +4170,15 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t)
copy_baseflags(t->scene);
/* handle pending update events, otherwise they got copied below */
- for (base= sce->base.first; base; base= base->next) {
+ for (base= scene->base.first; base; base= base->next) {
if(base->object->recalc)
object_handle_update(t->scene, base->object);
}
- for (base= sce->base.first; base; base= base->next) {
+ for (base= scene->base.first; base; base= base->next) {
base->flag &= ~BA_WAS_SEL;
- if(TESTBASELIB(v3d, base)) {
+ if(TESTBASELIB_BGMODE(v3d, base)) {
Object *ob= base->object;
Object *parsel= ob->parent;
@@ -4319,7 +4210,7 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t)
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
- for (base= sce->base.first; base; base= base->next) {
+ for (base= scene->base.first; base; base= base->next) {
if(base->object->recalc & OB_RECALC_OB)
base->flag |= BA_HAS_RECALC_OB;
if(base->object->recalc & OB_RECALC_DATA)
@@ -4516,15 +4407,16 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
}
if (doRot) {
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
- sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
+ // FIXME: better to just use the keyingsets for this instead...
+ if (pchan->rotmode == ROT_MODE_QUAT) {
+ sprintf(buf, "pose.pose_channels[\"%s\"].rotation_quaternion", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag);
}
else {
- sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name);
+ sprintf(buf, "pose.pose_channels[\"%s\"].rotation_euler", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
@@ -4544,7 +4436,8 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ // FIXME: better to just use the keyingsets for this instead...
+ if (pchan->rotmode == ROT_MODE_QUAT) {
sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
@@ -4552,7 +4445,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag);
}
else {
- sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name);
+ sprintf(buf, "pose.pose_channels[\"%s\"].rotation_euler", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
@@ -4932,7 +4825,7 @@ void special_aftertrans_update(TransInfo *t)
// allqueue(REDRAWBUTSEDIT, 0);
}
- else if(t->scene->basact && (ob = t->scene->basact->object) && ob->mode & OB_MODE_PARTICLE_EDIT) {
+ else if(t->scene->basact && (ob = t->scene->basact->object) && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, ob)) {
;
}
else {
@@ -4946,8 +4839,19 @@ void special_aftertrans_update(TransInfo *t)
ob= base->object;
if (base->flag & SELECT && (t->mode != TFM_DUMMY)) {
+ ListBase pidlist;
+ PTCacheID *pid;
+
+ /* flag object caches as outdated */
+ BKE_ptcache_ids_from_object(&pidlist, ob);
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
+ pid->cache->flag |= PTCACHE_OUTDATED;
+ }
+ BLI_freelistN(&pidlist);
+
/* pointcache refresh */
- if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
+ if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
ob->recalc |= OB_RECALC_DATA;
/* Needed for proper updating of "quick cached" dynamics. */
@@ -4991,30 +4895,7 @@ static void createTransObject(bContext *C, TransInfo *t)
set_trans_object_base_flags(C, t);
/* count */
-#if 0 // TRANSFORM_FIX_ME
- CTX_DATA_BEGIN(C, Object*, ob, selected_objects)
- {
- /* store ipo keys? */
- if ((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) {
- elems.first= elems.last= NULL;
- make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */
-
- pushdata(&elems, sizeof(ListBase));
-
- for(ik= elems.first; ik; ik= ik->next)
- t->total++;
-
- if(elems.first==NULL)
- t->total++;
- }
-// else {
- t->total++;
-// }
- }
- CTX_DATA_END;
-#else
t->total= CTX_DATA_COUNT(C, selected_objects);
-#endif
if(!t->total) {
/* clear here, main transform function escapes too */
@@ -5028,92 +4909,27 @@ static void createTransObject(bContext *C, TransInfo *t)
CTX_DATA_BEGIN(C, Base*, base, selected_bases)
{
Object *ob= base->object;
-
+
td->flag = TD_SELECTED;
td->protectflag= ob->protectflag;
td->ext = tx;
-
+ td->rotOrder= ob->rotmode;
+
if (base->flag & BA_TRANSFORM_CHILD)
{
td->flag |= TD_NOCENTER;
td->flag |= TD_NO_LOC;
}
-
+
/* select linked objects, but skip them later */
if (ob->id.lib != 0) {
td->flag |= TD_SKIP;
}
-
- /* store ipo keys? */
- // TRANSFORM_FIX_ME
-#if 0
- if((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) {
-
- popfirst(&elems); // bring back pushed listbase
-
- if(elems.first) {
- int cfraont;
- int ipoflag;
-
- base->flag |= BA_DO_IPO+BA_WAS_SEL;
- base->flag &= ~SELECT;
-
- cfraont= CFRA;
- set_no_parent_ipo(1);
- ipoflag= ob->ipoflag;
- ob->ipoflag &= ~OB_OFFS_OB;
-
- /*
- * This is really EVIL code that pushes down Object values
- * (loc, dloc, orig, size, dsize, rot, drot)
- * */
-
- pushdata((void*)ob->loc, 7 * 3 * sizeof(float)); // tsk! tsk!
-
- for(ik= elems.first; ik; ik= ik->next) {
-
- /* weak... this doesn't correct for floating values, giving small errors */
- CFRA= (int)(ik->val/t->scene->r.framelen);
-
- do_ob_ipo(ob);
- ObjectToTransData(C, t, td, ob); // does where_is_object()
-
- td->flag= TD_SELECTED;
-
- td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey");
- /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */
- ipokey_to_transdata(ik, td);
-
- td++;
- tx++;
- if(ik->next) td->ext= tx; // prevent corrupting mem!
- }
- free_ipokey(&elems);
-
- poplast(ob->loc);
- set_no_parent_ipo(0);
-
- CFRA= cfraont;
- ob->ipoflag= ipoflag;
-
- where_is_object(t->scene, ob); // restore
- }
- else {
- ObjectToTransData(C, t, td, ob);
- td->tdi = NULL;
- td->val = NULL;
- td++;
- tx++;
- }
- }
-#endif
-// else {
- ObjectToTransData(C, t, td, ob);
- td->tdi = NULL;
- td->val = NULL;
- td++;
- tx++;
-// }
+
+ ObjectToTransData(C, t, td, ob);
+ td->val = NULL;
+ td++;
+ tx++;
}
CTX_DATA_END;
}
@@ -5135,7 +4951,7 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
- td->ext= NULL; td->tdi= NULL; td->val= NULL;
+ td->ext= NULL; td->val= NULL;
td->flag |= TD_SELECTED;
td->dist= 0.0;
@@ -5279,7 +5095,7 @@ void createTransData(bContext *C, TransInfo *t)
{
if(ob_armature->type==OB_ARMATURE)
{
- if(ob_armature->mode & OB_MODE_POSE)
+ if((ob_armature->mode & OB_MODE_POSE) && ob_armature == modifiers_isDeformedByArmature(ob))
{
createTransPose(C, t, ob_armature);
break;
@@ -5302,6 +5118,8 @@ void createTransData(bContext *C, TransInfo *t)
}
else {
t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */
+ t->options |= CTX_NO_PET;
+
createTransObject(C, t);
t->flag |= T_OBJECT;
@@ -5309,7 +5127,7 @@ void createTransData(bContext *C, TransInfo *t)
{
View3D *v3d = t->view;
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
+ if(rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
{
t->flag |= T_CAMERA;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 0b7029adde0..6637122ffb8 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -92,6 +92,7 @@
#include "ED_markers.h"
#include "ED_mesh.h"
#include "ED_retopo.h"
+#include "ED_particle.h"
#include "ED_screen_types.h"
#include "ED_space_api.h"
#include "ED_uvedit.h"
@@ -125,19 +126,19 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3])
if (t->persp != V3D_ORTHO)
{
float p1[4], p2[4];
-
+
VECCOPY(p1, coord);
p1[3] = 1.0f;
VECCOPY(p2, p1);
p2[3] = 1.0f;
Mat4MulVec4fl(t->viewmat, p2);
-
+
p2[0] = 2.0f * p2[0];
p2[1] = 2.0f * p2[1];
p2[2] = 2.0f * p2[2];
-
+
Mat4MulVec4fl(t->viewinv, p2);
-
+
VecSubf(vec, p1, p2);
}
else {
@@ -153,11 +154,11 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
ModifierData *md= ob->modifiers.first;
float tolerance[3] = {0.0f, 0.0f, 0.0f};
int axis = 0;
-
+
for (; md; md=md->next) {
if (md->type==eModifierType_Mirror) {
MirrorModifierData *mmd = (MirrorModifierData*) md;
-
+
if(mmd->flag & MOD_MIR_CLIPPING) {
axis = 0;
if(mmd->flag & MOD_MIR_AXIS_X) {
@@ -176,35 +177,35 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
float mtx[4][4], imtx[4][4];
int i;
TransData *td = t->data;
-
+
if (mmd->mirror_ob) {
float obinv[4][4];
-
+
Mat4Invert(obinv, mmd->mirror_ob->obmat);
Mat4MulMat4(mtx, ob->obmat, obinv);
Mat4Invert(imtx, mtx);
}
-
+
for(i = 0 ; i < t->total; i++, td++) {
int clip;
float loc[3], iloc[3];
-
+
if (td->flag & TD_NOACTION)
break;
if (td->loc==NULL)
break;
-
+
if (td->flag & TD_SKIP)
continue;
-
+
VecCopyf(loc, td->loc);
VecCopyf(iloc, td->iloc);
-
+
if (mmd->mirror_ob) {
VecMat4MulVecfl(loc, mtx, loc);
VecMat4MulVecfl(iloc, mtx, iloc);
}
-
+
clip = 0;
if(axis & 1) {
if(fabs(iloc[0])<=tolerance[0] ||
@@ -213,7 +214,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
clip = 1;
}
}
-
+
if(axis & 2) {
if(fabs(iloc[1])<=tolerance[1] ||
loc[1]*iloc[1]<0.0f) {
@@ -236,7 +237,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
}
}
}
-
+
}
}
}
@@ -248,7 +249,7 @@ static void editmesh_apply_to_mirror(TransInfo *t)
TransData *td = t->data;
EditVert *eve;
int i;
-
+
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
@@ -256,7 +257,7 @@ static void editmesh_apply_to_mirror(TransInfo *t)
break;
if (td->flag & TD_SKIP)
continue;
-
+
eve = td->extra;
if(eve) {
eve->co[0]= -td->loc[0];
@@ -346,7 +347,7 @@ void recalcData(TransInfo *t)
if (t->obedit) {
}
- else if(base && base->object->mode & OB_MODE_PARTICLE_EDIT) {
+ else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(scene, base->object)) {
flushTransParticles(t);
}
if (t->spacetype==SPACE_NODE) {
@@ -620,9 +621,9 @@ void recalcData(TransInfo *t)
if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
Curve *cu= t->obedit->data;
Nurb *nu= cu->editnurb->first;
-
+
DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
-
+
if (t->state == TRANS_CANCEL) {
while(nu) {
calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
@@ -648,11 +649,11 @@ void recalcData(TransInfo *t)
else if (t->obedit->type == OB_MESH) {
if(t->spacetype==SPACE_IMAGE) {
SpaceImage *sima= t->sa->spacedata.first;
-
+
flushTransUVs(t);
if(sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_re_solve();
-
+
DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
} else {
EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh;
@@ -667,9 +668,9 @@ void recalcData(TransInfo *t)
}
if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
editmesh_apply_to_mirror(t);
-
+
DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
-
+
recalc_editnormals(em);
}
}
@@ -679,10 +680,10 @@ void recalcData(TransInfo *t)
EditBone *ebo;
TransData *td = t->data;
int i;
-
+
/* Ensure all bones are correctly adjusted */
for (ebo = edbo->first; ebo; ebo = ebo->next){
-
+
if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
/* If this bone has a parent tip that has been moved */
if (ebo->parent->flag & BONE_TIPSEL){
@@ -695,7 +696,7 @@ void recalcData(TransInfo *t)
if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head;
}
}
-
+
/* on extrude bones, oldlength==0.0f, so we scale radius of points */
ebo->length= VecLenf(ebo->head, ebo->tail);
if(ebo->oldlength==0.0f) {
@@ -715,8 +716,8 @@ void recalcData(TransInfo *t)
ebo->oldlength= ebo->length;
}
}
-
-
+
+
if (t->mode != TFM_BONE_ROLL)
{
/* fix roll */
@@ -726,10 +727,10 @@ void recalcData(TransInfo *t)
{
float vec[3], up_axis[3];
float qrot[4];
-
+
ebo = td->extra;
VECCOPY(up_axis, td->axismtx[2]);
-
+
if (t->mode != TFM_ROTATION)
{
VecSubf(vec, ebo->tail, ebo->head);
@@ -741,15 +742,15 @@ void recalcData(TransInfo *t)
{
Mat3MulVecfl(t->mat, up_axis);
}
-
+
ebo->roll = ED_rollBoneToVector(ebo, up_axis);
}
}
}
-
+
if(arm->flag & ARM_MIRROR_EDIT)
transform_armature_mirror_update(t->obedit);
-
+
}
else
DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */
@@ -757,7 +758,7 @@ void recalcData(TransInfo *t)
else if( (t->flag & T_POSE) && t->poseobj) {
Object *ob= t->poseobj;
bArmature *arm= ob->data;
-
+
/* if animtimer is running, and the object already has animation data,
* check if the auto-record feature means that we should record 'samples'
* (i.e. uneditable animation values)
@@ -769,7 +770,7 @@ void recalcData(TransInfo *t)
animrecord_check_state(t->scene, &ob->id, t->animtimer);
autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
}
-
+
/* old optimize trick... this enforces to bypass the depgraph */
if (!(arm->flag & ARM_DELAYDEFORM)) {
DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
@@ -780,13 +781,13 @@ void recalcData(TransInfo *t)
else {
for(base= FIRSTBASE; base; base= base->next) {
Object *ob= base->object;
-
+
/* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
if(base->flag & BA_HAS_RECALC_OB)
ob->recalc |= OB_RECALC_OB;
if(base->flag & BA_HAS_RECALC_DATA)
ob->recalc |= OB_RECALC_DATA;
-
+
/* if object/base is selected */
if ((base->flag & SELECT) || (ob->flag & SELECT)) {
/* if animtimer is running, and the object already has animation data,
@@ -799,7 +800,7 @@ void recalcData(TransInfo *t)
autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode);
}
}
-
+
/* proxy exception */
if(ob->proxy)
ob->proxy->recalc |= ob->recalc;
@@ -807,7 +808,7 @@ void recalcData(TransInfo *t)
group_tag_recalc(ob->proxy_group->dup_group);
}
}
-
+
/* update shaded drawmode while transform */
if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED)
reshadeall_displist(t->scene);
@@ -821,18 +822,18 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
if (t->spacetype == SPACE_VIEW3D)
{
View3D *v3d = t->view;
-
+
glPushMatrix();
-
+
//if(t->obedit) glLoadMatrixf(t->obedit->obmat); // sets opengl viewing
-
-
+
+
VecCopyf(v3, dir);
VecMulf(v3, v3d->far);
-
+
VecSubf(v2, center, v3);
VecAddf(v1, center, v3);
-
+
if (options & DRAWLIGHT) {
col[0] = col[1] = col[2] = 220;
}
@@ -841,13 +842,13 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
}
UI_make_axis_color(col, col2, axis);
glColor3ubv((GLubyte *)col2);
-
+
setlinestyle(0);
glBegin(GL_LINE_STRIP);
glVertex3fv(v1);
glVertex3fv(v2);
glEnd();
-
+
glPopMatrix();
}
}
@@ -864,33 +865,33 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
ARegion *ar = CTX_wm_region(C);
ScrArea *sa = CTX_wm_area(C);
Object *obedit = CTX_data_edit_object(C);
-
+
/* moving: is shown in drawobject() (transform color) */
// TRANSFORM_FIX_ME
// if(obedit || (t->flag & T_POSE) ) G.moving= G_TRANSFORM_EDIT;
// else if(G.f & G_PARTICLEEDIT) G.moving= G_TRANSFORM_PARTICLE;
// else G.moving= G_TRANSFORM_OBJ;
-
+
t->scene = sce;
t->sa = sa;
t->ar = ar;
t->obedit = obedit;
t->settings = ts;
-
+
t->data = NULL;
t->ext = NULL;
-
+
t->helpline = HLP_NONE;
-
+
t->flag = 0;
-
+
t->redraw = 1; /* redraw first time */
-
+
if (event)
{
t->imval[0] = event->x - t->ar->winrct.xmin;
t->imval[1] = event->y - t->ar->winrct.ymin;
-
+
t->event_type = event->type;
}
else
@@ -898,45 +899,45 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->imval[0] = 0;
t->imval[1] = 0;
}
-
+
t->con.imval[0] = t->imval[0];
t->con.imval[1] = t->imval[1];
-
+
t->mval[0] = t->imval[0];
t->mval[1] = t->imval[1];
-
+
t->transform = NULL;
t->handleEvent = NULL;
-
+
t->total = 0;
-
+
t->val = 0.0f;
-
+
t->vec[0] =
t->vec[1] =
t->vec[2] = 0.0f;
-
+
t->center[0] =
t->center[1] =
t->center[2] = 0.0f;
-
+
Mat3One(t->mat);
-
+
t->spacetype = sa->spacetype;
if(t->spacetype == SPACE_VIEW3D)
{
View3D *v3d = sa->spacedata.first;
-
+
t->view = v3d;
t->animtimer= CTX_wm_screen(C)->animtimer;
-
+
if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
t->around = v3d->around;
-
+
if (op && RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_orientation"))
{
t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation");
-
+
if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C) - 1)
{
t->current_orientation = V3D_MANIP_GLOBAL;
@@ -958,10 +959,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
{
// XXX for now, get View2D from the active region
t->view = &ar->v2d;
-
+
t->around = V3D_CENTER;
}
-
+
if (op && RNA_struct_find_property(op->ptr, "mirror") && RNA_property_is_set(op->ptr, "mirror"))
{
if (RNA_boolean_get(op->ptr, "mirror"))
@@ -977,57 +978,66 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->flag |= T_MIRROR;
}
}
-
- /* setting PET flag */
- if (op && RNA_struct_find_property(op->ptr, "proportional") && RNA_property_is_set(op->ptr, "proportional"))
+
+ /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
+ if (op && RNA_struct_find_property(op->ptr, "proportional"))
{
- switch(RNA_enum_get(op->ptr, "proportional"))
+ if (RNA_property_is_set(op->ptr, "proportional"))
{
- case 2: /* XXX connected constant */
- t->flag |= T_PROP_CONNECTED;
- case 1: /* XXX prop on constant */
- t->flag |= T_PROP_EDIT;
- break;
+ switch(RNA_enum_get(op->ptr, "proportional"))
+ {
+ case 2: /* XXX connected constant */
+ t->flag |= T_PROP_CONNECTED;
+ case 1: /* XXX prop on constant */
+ t->flag |= T_PROP_EDIT;
+ break;
+ }
}
- }
- else
- {
- if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) {
- t->flag |= T_PROP_EDIT;
-
- if(ts->proportional == 2)
- t->flag |= T_PROP_CONNECTED; // yes i know, has to become define
+ else
+ {
+ if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) {
+ t->flag |= T_PROP_EDIT;
+
+ if(ts->proportional == 2)
+ t->flag |= T_PROP_CONNECTED; // yes i know, has to become define
+ }
+ }
+
+ if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size"))
+ {
+ t->prop_size = RNA_float_get(op->ptr, "proportional_size");
+ }
+ else
+ {
+ t->prop_size = ts->proportional_size;
+ }
+
+
+ /* TRANSFORM_FIX_ME rna restrictions */
+ if (t->prop_size <= 0)
+ {
+ t->prop_size = 1.0f;
+ }
+
+ if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
+ {
+ t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff");
+ }
+ else
+ {
+ t->prop_mode = ts->prop_mode;
}
}
-
- if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size"))
- {
- t->prop_size = RNA_float_get(op->ptr, "proportional_size");
- }
- else
- {
- t->prop_size = ts->proportional_size;
- }
-
- if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
- {
- t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff");
- }
- else
- {
- t->prop_mode = ts->prop_mode;
- }
-
- /* TRANSFORM_FIX_ME rna restrictions */
- if (t->prop_size <= 0)
+ else /* add not pet option to context when not available */
{
- t->prop_size = 1.0f;
+ t->options |= CTX_NO_PET;
}
-
+
+
setTransformViewMatrices(t);
initNumInput(&t->num);
initNDofInput(&t->ndof);
-
+
return 1;
}
@@ -1035,45 +1045,53 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
void postTrans (TransInfo *t)
{
TransData *td;
-
+
if (t->draw_handle)
{
ED_region_draw_cb_exit(t->ar->type, t->draw_handle);
}
-
+
/* postTrans can be called when nothing is selected, so data is NULL already */
if (t->data) {
int a;
-
+
/* since ipokeys are optional on objects, we mallocced them per trans-data */
for(a=0, td= t->data; a<t->total; a++, td++) {
- if(td->tdi) MEM_freeN(td->tdi);
- if (td->flag & TD_BEZTRIPLE) MEM_freeN(td->hdata);
+ if (td->flag & TD_BEZTRIPLE)
+ MEM_freeN(td->hdata);
}
MEM_freeN(t->data);
}
-
+
if (t->ext) MEM_freeN(t->ext);
if (t->data2d) {
MEM_freeN(t->data2d);
t->data2d= NULL;
}
-
+
if(t->spacetype==SPACE_IMAGE) {
SpaceImage *sima= t->sa->spacedata.first;
if(sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
}
- else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) {
- if (t->customData)
- MEM_freeN(t->customData);
+
+ if (t->mouse.data)
+ {
+ MEM_freeN(t->mouse.data);
+ }
+
+ if (t->customFree) {
+ t->customFree(t);
+ }
+ else if (t->customData) {
+ MEM_freeN(t->customData);
}
}
void applyTransObjects(TransInfo *t)
{
TransData *td;
-
+
for (td = t->data; td < t->data + t->total; td++) {
VECCOPY(td->iloc, td->loc);
if (td->ext->rot) {
@@ -1086,16 +1104,6 @@ void applyTransObjects(TransInfo *t)
recalcData(t);
}
-/* helper for below */
-static void restore_ipokey(float *poin, float *old)
-{
- if(poin) {
- poin[0]= old[0];
- poin[-3]= old[3];
- poin[3]= old[6];
- }
-}
-
static void restoreElement(TransData *td) {
/* TransData for crease has no loc */
if (td->loc) {
@@ -1111,45 +1119,27 @@ static void restoreElement(TransData *td) {
if (td->ext->size) {
VECCOPY(td->ext->size, td->ext->isize);
}
- if(td->flag & TD_USEQUAT) {
- if (td->ext->quat) {
- QUATCOPY(td->ext->quat, td->ext->iquat);
- }
+ if (td->ext->quat) {
+ QUATCOPY(td->ext->quat, td->ext->iquat);
}
}
-
+
if (td->flag & TD_BEZTRIPLE) {
*(td->hdata->h1) = td->hdata->ih1;
*(td->hdata->h2) = td->hdata->ih2;
}
-
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
-
- restore_ipokey(tdi->locx, tdi->oldloc);
- restore_ipokey(tdi->locy, tdi->oldloc+1);
- restore_ipokey(tdi->locz, tdi->oldloc+2);
-
- restore_ipokey(tdi->rotx, tdi->oldrot);
- restore_ipokey(tdi->roty, tdi->oldrot+1);
- restore_ipokey(tdi->rotz, tdi->oldrot+2);
-
- restore_ipokey(tdi->sizex, tdi->oldsize);
- restore_ipokey(tdi->sizey, tdi->oldsize+1);
- restore_ipokey(tdi->sizez, tdi->oldsize+2);
- }
}
void restoreTransObjects(TransInfo *t)
{
TransData *td;
-
+
for (td = t->data; td < t->data + t->total; td++) {
restoreElement(td);
}
-
+
Mat3One(t->mat);
-
+
recalcData(t);
}
@@ -1158,7 +1148,7 @@ void calculateCenter2D(TransInfo *t)
if (t->flag & (T_EDIT|T_POSE)) {
Object *ob= t->obedit?t->obedit:t->poseobj;
float vec[3];
-
+
VECCOPY(vec, t->center);
Mat4MulVecfl(ob->obmat, vec);
projectIntView(t, vec, t->center2d);
@@ -1171,21 +1161,21 @@ void calculateCenter2D(TransInfo *t)
void calculateCenterCursor(TransInfo *t)
{
float *cursor;
-
+
cursor = give_cursor(t->scene, t->view);
VECCOPY(t->center, cursor);
-
+
/* If edit or pose mode, move cursor in local space */
if (t->flag & (T_EDIT|T_POSE)) {
Object *ob = t->obedit?t->obedit:t->poseobj;
float mat[3][3], imat[3][3];
-
+
VecSubf(t->center, t->center, ob->obmat[3]);
Mat3CpyMat4(mat, ob->obmat);
Mat3Inv(imat, mat);
Mat3MulVecfl(imat, t->center);
}
-
+
calculateCenter2D(t);
}
@@ -1193,15 +1183,15 @@ void calculateCenterCursor2D(TransInfo *t)
{
View2D *v2d= t->view;
float aspx=1.0, aspy=1.0;
-
+
if(t->spacetype==SPACE_IMAGE) /* only space supported right now but may change */
ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
-
+
if (v2d) {
t->center[0] = v2d->cursor[0] * aspx;
t->center[1] = v2d->cursor[1] * aspy;
}
-
+
calculateCenter2D(t);
}
@@ -1210,7 +1200,7 @@ void calculateCenterMedian(TransInfo *t)
float partial[3] = {0.0f, 0.0f, 0.0f};
int total = 0;
int i;
-
+
for(i = 0; i < t->total; i++) {
if (t->data[i].flag & TD_SELECTED) {
if (!(t->data[i].flag & TD_NOCENTER))
@@ -1230,7 +1220,7 @@ void calculateCenterMedian(TransInfo *t)
if(i)
VecMulf(partial, 1.0f / total);
VECCOPY(t->center, partial);
-
+
calculateCenter2D(t);
}
@@ -1260,7 +1250,7 @@ void calculateCenterBound(TransInfo *t)
}
VecAddf(t->center, min, max);
VecMulf(t->center, 0.5);
-
+
calculateCenter2D(t);
}
@@ -1296,7 +1286,7 @@ void calculateCenter(TransInfo *t)
break;
} /* END EDIT MODE ACTIVE ELEMENT */
#endif
-
+
calculateCenterMedian(t);
if((t->flag & (T_EDIT|T_POSE))==0)
{
@@ -1308,10 +1298,10 @@ void calculateCenter(TransInfo *t)
projectIntView(t, t->center, t->center2d);
}
}
-
+
}
}
-
+
/* setting constraint center */
VECCOPY(t->con.center, t->center);
if(t->flag & (T_EDIT|T_POSE))
@@ -1319,8 +1309,8 @@ void calculateCenter(TransInfo *t)
Object *ob= t->obedit?t->obedit:t->poseobj;
Mat4MulVecfl(ob->obmat, t->con.center);
}
-
- /* voor panning from cameraview */
+
+ /* for panning from cameraview */
if(t->flag & T_OBJECT)
{
if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW)
@@ -1328,21 +1318,21 @@ void calculateCenter(TransInfo *t)
View3D *v3d = t->view;
Scene *scene = t->scene;
RegionView3D *rv3d = t->ar->regiondata;
-
+
if(v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
{
float axis[3];
/* persinv is nasty, use viewinv instead, always right */
VECCOPY(axis, t->viewinv[2]);
Normalize(axis);
-
+
/* 6.0 = 6 grid units */
axis[0]= t->center[0]- 6.0f*axis[0];
axis[1]= t->center[1]- 6.0f*axis[1];
axis[2]= t->center[2]- 6.0f*axis[2];
-
+
projectIntView(t, axis, t->center2d);
-
+
/* rotate only needs correct 2d center, grab needs initgrabz() value */
if(t->mode==TFM_TRANSLATION)
{
@@ -1352,14 +1342,14 @@ void calculateCenter(TransInfo *t)
}
}
}
-
+
if(t->spacetype==SPACE_VIEW3D)
{
/* initgrabz() defines a factor for perspective depth correction, used in window_to_3d_delta() */
if(t->flag & (T_EDIT|T_POSE)) {
Object *ob= t->obedit?t->obedit:t->poseobj;
float vec[3];
-
+
VECCOPY(vec, t->center);
Mat4MulVecfl(ob->obmat, vec);
initgrabz(t->ar->regiondata, vec[0], vec[1], vec[2]);
@@ -1399,7 +1389,7 @@ void calculatePropRatio(TransInfo *t)
/* Use rdist for falloff calculations, it is the real distance */
td->flag &= ~TD_NOACTION;
dist= (t->prop_size-td->rdist)/t->prop_size;
-
+
/*
* Clamp to positive numbers.
* Certain corner cases with connectivity and individual centers
@@ -1407,7 +1397,7 @@ void calculatePropRatio(TransInfo *t)
*/
if (dist < 0.0f)
dist = 0.0f;
-
+
switch(t->prop_mode) {
case PROP_SHARP:
td->factor= dist*dist;
@@ -1474,20 +1464,20 @@ float get_drawsize(ARegion *ar, float *co)
{
RegionView3D *rv3d= ar->regiondata;
float size, vec[3], len1, len2;
-
+
/* size calculus, depending ortho/persp settings, like initgrabz() */
size= rv3d->persmat[0][3]*co[0]+ rv3d->persmat[1][3]*co[1]+ rv3d->persmat[2][3]*co[2]+ rv3d->persmat[3][3];
-
+
VECCOPY(vec, rv3d->persinv[0]);
len1= Normalize(vec);
VECCOPY(vec, rv3d->persinv[1]);
len2= Normalize(vec);
-
+
size*= 0.01f*(len1>len2?len1:len2);
-
+
/* correct for window size to make widgets appear fixed size */
if(ar->winx > ar->winy) size*= 1000.0f/(float)ar->winx;
else size*= 1000.0f/(float)ar->winy;
-
+
return size;
}
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 6bd0a8c8d42..83d4a314057 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -34,7 +34,7 @@
#include "transform.h"
-
+#include "MEM_guardedalloc.h"
/* ************************** INPUT FROM MOUSE *************************** */
@@ -163,6 +163,47 @@ void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float ou
output[0] = Inpf(t->viewinv[1], vec) * 2.0f;
}
+void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2])
+{
+ short *data = mi->data;
+
+ data[0] = start[0];
+ data[1] = start[1];
+ data[2] = end[0];
+ data[3] = end[1];
+}
+
+void InputCustomRatio(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
+{
+ float length;
+ float distance;
+ short *data = mi->data;
+ short dx, dy;
+
+ dx = data[2] - data[0];
+ dy = data[3] - data[1];
+
+ length = (float)sqrtf(dx*dx + dy*dy);
+
+ if (mi->precision) {
+ /* deal with Shift key by adding motion / 10 to motion before shift press */
+ short mdx, mdy;
+ mdx = (mi->precision_mval[0] + (float)(mval[0] - mi->precision_mval[0]) / 10.0f) - data[2];
+ mdy = (mi->precision_mval[1] + (float)(mval[1] - mi->precision_mval[1]) / 10.0f) - data[3];
+
+ distance = (mdx*dx + mdy*dy) / length;
+ }
+ else {
+ short mdx, mdy;
+ mdx = mval[0] - data[2];
+ mdy = mval[1] - data[3];
+
+ distance = (mdx*dx + mdy*dy) / length;
+ }
+
+ output[0] = distance / length;
+}
+
void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3])
{
double dx2 = mval[0] - mi->center[0];
@@ -291,6 +332,11 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
mi->apply = InputVerticalAbsolute;
t->helpline = HLP_VARROW;
break;
+ case INPUT_CUSTOM_RATIO:
+ mi->apply = InputCustomRatio;
+ t->helpline = HLP_NONE;
+ mi->data = MEM_callocN(sizeof(short) * 4, "custom points");
+ break;
case INPUT_NONE:
default:
mi->apply = NULL;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 93bc02d7180..bdf0a91bf89 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -412,6 +412,9 @@ int calc_manipulator_stats(const bContext *C)
if(ob && totsel) {
switch(v3d->twmode) {
+
+ case V3D_MANIP_GLOBAL:
+ break; /* nothing to do */
case V3D_MANIP_NORMAL:
if(obedit || ob->mode & OB_MODE_POSE) {
@@ -473,8 +476,12 @@ int calc_manipulator_stats(const bContext *C)
}
break;
default: /* V3D_MANIP_CUSTOM */
- // XXX applyTransformOrientation(C, t);
- break;
+ {
+ float mat[3][3];
+ applyTransformOrientation(C, mat, NULL);
+ Mat4CpyMat3(rv3d->twmat, mat);
+ break;
+ }
}
}
@@ -1602,7 +1609,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
break;
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr);
}
else if (drawflags & MAN_SCALE_C) {
switch(drawflags) {
@@ -1632,10 +1639,10 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
break;
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_resize", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr);
}
else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */
- WM_operator_name_call(C, "TFM_OT_trackball", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_trackball", WM_OP_INVOKE_DEFAULT, op->ptr);
}
else if (drawflags & MAN_ROT_C) {
switch(drawflags) {
@@ -1650,7 +1657,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
break;
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_rotate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+ WM_operator_name_call(C, "TFM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr);
}
}
/* after transform, restore drawflags */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 4ae0bca3284..0440a957539 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -99,6 +99,7 @@ char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten";
char OP_TILT[] = "TFM_OT_tilt";
char OP_TRACKBALL[] = "TFM_OT_trackball";
char OP_MIRROR[] = "TFM_OT_mirror";
+char OP_EDGE_SLIDE[] = "TFM_OT_edge_slide";
TransformModeItem transform_modes[] =
@@ -113,6 +114,7 @@ TransformModeItem transform_modes[] =
{OP_TILT, TFM_TILT},
{OP_TRACKBALL, TFM_TRACKBALL},
{OP_MIRROR, TFM_MIRROR},
+ {OP_EDGE_SLIDE, TFM_EDGE_SLIDE},
{NULL, 0}
};
@@ -150,8 +152,9 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot)
/* identifiers */
ot->name = "Select Orientation";
- ot->description= "Select orientation type.";
+ ot->description= "Select transformation orientation.";
ot->idname = "TFM_OT_select_orientation";
+ ot->flag = OPTYPE_UNDO;
/* api callbacks */
ot->invoke = select_orientation_invoke;
@@ -162,6 +165,92 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot)
RNA_def_enum_funcs(prop, select_orientation_itemf);
}
+
+static int delete_orientation_exec(bContext *C, wmOperator *op)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+
+ BIF_removeTransformOrientationIndex(C, selected_index);
+
+ return OPERATOR_FINISHED;
+}
+
+static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return delete_orientation_exec(C, op);
+}
+
+static int delete_orientation_poll(bContext *C)
+{
+ int selected_index = -1;
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (ED_operator_areaactive(C) == 0)
+ return 0;
+
+
+ if(v3d) {
+ selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+ }
+
+ return selected_index >= 0;
+}
+
+void TFM_OT_delete_orientation(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Delete Orientation";
+ ot->description= "Delete transformation orientation.";
+ ot->idname = "TFM_OT_delete_orientation";
+ ot->flag = OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = delete_orientation_invoke;
+ ot->exec = delete_orientation_exec;
+ ot->poll = delete_orientation_poll;
+}
+
+static int create_orientation_exec(bContext *C, wmOperator *op)
+{
+ char name[36];
+ int use = RNA_boolean_get(op->ptr, "use");
+ int overwrite = RNA_boolean_get(op->ptr, "overwrite");
+
+ RNA_string_get(op->ptr, "name", name);
+
+ BIF_createTransformOrientation(C, op->reports, name, use, overwrite);
+
+ /* Do we need more refined tags? */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return create_orientation_exec(C, op);
+}
+
+void TFM_OT_create_orientation(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Create Orientation";
+ ot->description= "Create transformation orientation from selection.";
+ ot->idname = "TFM_OT_create_orientation";
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = create_orientation_invoke;
+ ot->exec = create_orientation_exec;
+ ot->poll = ED_operator_areaactive;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_string(ot->srna, "name", "", 35, "Name", "Text to insert at the cursor position.");
+ RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation");
+ RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name");
+}
+
static void transformops_exit(bContext *C, wmOperator *op)
{
saveTransform(C, op->customdata, op);
@@ -270,7 +359,7 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
TransInfo *t = op->customdata;
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
t->flag |= T_MODAL; // XXX meh maybe somewhere else
@@ -523,7 +612,7 @@ void TFM_OT_tosphere(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_areaactive;
- RNA_def_float_percentage(ot->srna, "value", 0, 0, 1, "Percentage", "", 0, 1);
+ RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
Properties_Proportional(ot);
@@ -549,6 +638,26 @@ void TFM_OT_mirror(struct wmOperatorType *ot)
Properties_Constraints(ot);
}
+void TFM_OT_edge_slide(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edge Slide";
+ ot->description= "Slide an edge loop along a mesh.";
+ ot->idname = OP_EDGE_SLIDE;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh;
+
+ RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
+}
+
void TFM_OT_transform(struct wmOperatorType *ot)
{
static EnumPropertyItem transform_mode_types[] = {
@@ -578,6 +687,7 @@ void TFM_OT_transform(struct wmOperatorType *ot)
{TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
{TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
{TFM_ALIGN, "ALIGN", 0, "Align", ""},
+ {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -617,11 +727,14 @@ void transform_operatortypes(void)
WM_operatortype_append(TFM_OT_tilt);
WM_operatortype_append(TFM_OT_trackball);
WM_operatortype_append(TFM_OT_mirror);
+ WM_operatortype_append(TFM_OT_edge_slide);
WM_operatortype_append(TFM_OT_select_orientation);
+ WM_operatortype_append(TFM_OT_create_orientation);
+ WM_operatortype_append(TFM_OT_delete_orientation);
}
-void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid)
+void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid)
{
wmKeymapItem *km;
@@ -641,7 +754,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
@@ -651,6 +764,9 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
+ km = WM_keymap_add_item(keymap, "TFM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ RNA_boolean_set(km->ptr, "use", 1);
+
break;
case SPACE_ACTION:
km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 9416425704f..c9344b97fb2 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -23,6 +23,7 @@
*/
#include <string.h>
+#include <ctype.h>
#include "MEM_guardedalloc.h"
@@ -43,6 +44,7 @@
#include "BKE_utildefines.h"
#include "BKE_armature.h"
#include "BKE_context.h"
+#include "BKE_report.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -67,108 +69,131 @@
void BIF_clearTransformOrientation(bContext *C)
{
+ View3D *v3d = CTX_wm_view3d(C);
+
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
BLI_freelistN(transform_spaces);
- // TRANSFORM_FIX_ME
// Need to loop over all view3d
-// if (G.vd->twmode >= V3D_MANIP_CUSTOM)
-// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ if(v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
+ v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ }
+}
+
+TransformOrientation* findOrientationName(bContext *C, char *name)
+{
+ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
+ TransformOrientation *ts= NULL;
+
+ for (ts = transform_spaces->first; ts; ts = ts->next) {
+ if (strncmp(ts->name, name, 35) == 0) {
+ return ts;
+ }
+ }
+
+ return NULL;
+}
+
+void uniqueOrientationName(bContext *C, char *name)
+{
+ if (findOrientationName(C, name) != NULL)
+ {
+ char tempname[64];
+ int number;
+ char *dot;
+
+
+ number = strlen(name);
+
+ if (number && isdigit(name[number-1]))
+ {
+ dot = strrchr(name, '.'); // last occurrence
+ if (dot)
+ *dot=0;
+ }
+
+ for (number = 1; number <= 999; number++)
+ {
+ sprintf(tempname, "%s.%03d", name, number);
+ if (findOrientationName(C, tempname) == NULL)
+ {
+ BLI_strncpy(name, tempname, 32);
+ break;
+ }
+ }
+ }
}
-
-void BIF_manageTransformOrientation(bContext *C, int confirm, int set) {
+
+void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use, int overwrite)
+{
Object *obedit = CTX_data_edit_object(C);
Object *ob = CTX_data_active_object(C);
- int index = -1;
+ TransformOrientation *ts = NULL;
if (obedit) {
if (obedit->type == OB_MESH)
- index = manageMeshSpace(C, confirm, set);
+ ts = createMeshSpace(C, reports, name, overwrite);
else if (obedit->type == OB_ARMATURE)
- index = manageBoneSpace(C, confirm, set);
+ ts = createBoneSpace(C, reports, name, overwrite);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- index = manageBoneSpace(C, confirm, set);
+ ts = createBoneSpace(C, reports, name, overwrite);
}
else {
- index = manageObjectSpace(C, confirm, set);
+ ts = createObjectSpace(C, reports, name, overwrite);
}
- if (set && index != -1)
+ if (use && ts != NULL)
{
- BIF_selectTransformOrientationValue(C, V3D_MANIP_CUSTOM + index);
+ BIF_selectTransformOrientation(C, ts);
}
}
-int manageObjectSpace(bContext *C, int confirm, int set) {
+TransformOrientation *createObjectSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
Base *base = CTX_data_active_base(C);
+ Object *ob;
+ float mat[3][3];
if (base == NULL)
- return -1;
-
-//XXX if (confirm == 0) {
-// if (set && pupmenu("Custom Orientation %t|Add and Use Active Object%x1") != 1) {
-// return -1;
-// }
-// else if (set == 0 && pupmenu("Custom Orientation %t|Add Active Object%x1") != 1) {
-// return -1;
-// }
-// }
-
- return addObjectSpace(C, base->object);
-}
+ return NULL;
-/* return 1 on confirm */
-int confirmSpace(int set, char text[])
-{
- char menu[64];
+
+ ob = base->object;
- if (set) {
- sprintf(menu, "Custom Orientation %%t|Add and Use %s%%x1", text);
- }
- else {
- sprintf(menu, "Custom Orientation %%t|Add %s%%x1", text);
+ Mat3CpyMat4(mat, ob->obmat);
+ Mat3Ortho(mat);
+
+ /* use object name if no name is given */
+ if (name[0] == 0)
+ {
+ strncpy(name, ob->id.name+2, 35);
}
-
-//XXX if (pupmenu(menu) == 1) {
- return 1;
-// }
-// else {
-// return 0;
-// }
+
+ return addMatrixSpace(C, mat, name, overwrite);
}
-int manageBoneSpace(bContext *C, int confirm, int set) {
+TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
float mat[3][3];
float normal[3], plane[3];
- char name[36] = "";
- int index;
getTransformOrientation(C, normal, plane, 0);
-
- if (confirm == 0 && confirmSpace(set, "Bone") == 0) {
- return -1;
- }
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
-//XXX error("Cannot use zero-length bone");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use zero-length bone");
+ return NULL;
}
- strcpy(name, "Bone");
-
- /* Input name */
-//XXX sbutton(name, 1, 35, "name: ");
+ if (name[0] == 0)
+ {
+ strcpy(name, "Bone");
+ }
- index = addMatrixSpace(C, mat, name);
- return index;
+ return addMatrixSpace(C, mat, name, overwrite);
}
-int manageMeshSpace(bContext *C, int confirm, int set) {
+TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
float mat[3][3];
float normal[3], plane[3];
- char name[36] = "";
- int index;
int type;
type = getTransformOrientation(C, normal, plane, 0);
@@ -176,51 +201,44 @@ int manageMeshSpace(bContext *C, int confirm, int set) {
switch (type)
{
case ORIENTATION_VERT:
- if (confirm == 0 && confirmSpace(set, "vertex") == 0) {
- return -1;
- }
-
if (createSpaceNormal(mat, normal) == 0) {
-// XXX error("Cannot use vertex with zero-length normal");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use vertex with zero-length normal");
+ return NULL;
}
- strcpy(name, "Vertex");
+ if (name[0] == 0)
+ {
+ strcpy(name, "Vertex");
+ }
break;
case ORIENTATION_EDGE:
- if (confirm == 0 && confirmSpace(set, "Edge") == 0) {
- return -1;
- }
-
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
-// XXX error("Cannot use zero-length edge");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use zero-length edge");
+ return NULL;
}
- strcpy(name, "Edge");
+ if (name[0] == 0)
+ {
+ strcpy(name, "Edge");
+ }
break;
case ORIENTATION_FACE:
- if (confirm == 0 && confirmSpace(set, "Face") == 0) {
- return -1;
- }
-
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
-// XXX error("Cannot use zero-area face");
- return -1;
+ BKE_reports_prepend(reports, "Cannot use zero-area face");
+ return NULL;
}
- strcpy(name, "Face");
+ if (name[0] == 0)
+ {
+ strcpy(name, "Face");
+ }
break;
default:
- return -1;
+ return NULL;
break;
}
- /* Input name */
-//XXX sbutton(name, 1, 35, "name: ");
-
- index = addMatrixSpace(C, mat, name);
- return index;
+ return addMatrixSpace(C, mat, name, overwrite);
}
int createSpaceNormal(float mat[3][3], float normal[3])
@@ -271,32 +289,17 @@ int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3])
return 1;
}
-
-int addObjectSpace(bContext *C, Object *ob) {
- float mat[3][3];
- char name[36] = "";
-
- Mat3CpyMat4(mat, ob->obmat);
- Mat3Ortho(mat);
-
- strncpy(name, ob->id.name+2, 35);
-
- /* Input name */
-//XXX sbutton(name, 1, 35, "name: ");
-
- return addMatrixSpace(C, mat, name);
-}
-
-int addMatrixSpace(bContext *C, float mat[3][3], char name[]) {
+TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) {
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
- TransformOrientation *ts;
- int index = 0;
+ TransformOrientation *ts = NULL;
- /* if name is found in list, reuse that transform space */
- for (index = 0, ts = transform_spaces->first; ts; ts = ts->next, index++) {
- if (strncmp(ts->name, name, 35) == 0) {
- break;
- }
+ if (overwrite)
+ {
+ ts = findOrientationName(C, name);
+ }
+ else
+ {
+ uniqueOrientationName(C, name);
}
/* if not, create a new one */
@@ -310,31 +313,61 @@ int addMatrixSpace(bContext *C, float mat[3][3], char name[]) {
/* copy matrix into transform space */
Mat3CpyMat3(ts->mat, mat);
- ED_undo_push(C, "Add/Update Transform Orientation");
-
- return index;
+ return ts;
}
void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) {
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
TransformOrientation *ts = transform_spaces->first;
- //int selected_index = (G.vd->twmode - V3D_MANIP_CUSTOM);
int i;
for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
if (ts == target) {
- // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
-// if (selected_index == i) {
-// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
-// }
-// else if (selected_index > i)
-// G.vd->twmode--;
+ View3D *v3d = CTX_wm_view3d(C);
+ if(v3d) {
+ int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+
+ // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
+ if (selected_index == i) {
+ v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ }
+ else if (selected_index > i) {
+ v3d->twmode--;
+ }
+
+ }
+
+ BLI_freelinkN(transform_spaces, ts);
+ break;
+ }
+ }
+}
+
+void BIF_removeTransformOrientationIndex(bContext *C, int index) {
+ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
+ TransformOrientation *ts = transform_spaces->first;
+ int i;
+
+ for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
+ if (i == index) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if(v3d) {
+ int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
+
+ // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
+ if (selected_index == i) {
+ v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ }
+ else if (selected_index > i) {
+ v3d->twmode--;
+ }
+
+ }
BLI_freelinkN(transform_spaces, ts);
break;
}
}
- ED_undo_push(C, "Remove Transform Orientation");
}
void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) {
@@ -353,7 +386,8 @@ void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) {
void BIF_selectTransformOrientationValue(bContext *C, int orientation) {
View3D *v3d = CTX_wm_view3d(C);
- v3d->twmode = orientation;
+ if(v3d) /* currently using generic poll */
+ v3d->twmode = orientation;
}
EnumPropertyItem *BIF_enumTransformOrientation(bContext *C)
@@ -432,7 +466,7 @@ int BIF_countTransformOrientation(const bContext *C) {
return count;
}
-void applyTransformOrientation(const bContext *C, TransInfo *t) {
+void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) {
TransformOrientation *ts;
View3D *v3d = CTX_wm_view3d(C);
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
@@ -441,8 +475,11 @@ void applyTransformOrientation(const bContext *C, TransInfo *t) {
if (selected_index >= 0) {
for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) {
if (selected_index == i) {
- strcpy(t->spacename, ts->name);
- Mat3CpyMat3(t->spacemtx, ts->mat);
+
+ if (name)
+ strcpy(name, ts->name);
+
+ Mat3CpyMat3(mat, ts->mat);
break;
}
}
@@ -557,7 +594,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
}
break;
default: /* V3D_MANIP_CUSTOM */
- applyTransformOrientation(C, t);
+ applyTransformOrientation(C, t->spacemtx, t->spacename);
break;
}
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 9438581409b..84dc9e69e7a 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -539,7 +539,6 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
float no[3];
int found = 0;
int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
- SnapMode mode;
if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME)
{
@@ -634,16 +633,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
}
else
{
- if (t->obedit == NULL)
- {
- mode = SNAP_NOT_SELECTED;
- }
- else
- {
- mode = SNAP_NOT_OBEDIT;
- }
-
- found = snapObjectsTransform(t, t->mval, &dist, loc, no, mode);
+ found = snapObjectsTransform(t, t->mval, &dist, loc, no, t->tsnap.mode);
}
if (found == 1)
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index a58ee9772e9..fbd12007c16 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -251,17 +251,17 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
if(efa->v4) {
#if 0 /* Simple but slow, better reuse normalized vectors */
- uvang1 = VecAngle3_2D(tf_uv[3], tf_uv[0], tf_uv[1]);
- ang1 = VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co);
+ uvang1 = RAD2DEG(Vec2Angle3(tf_uv[3], tf_uv[0], tf_uv[1]));
+ ang1 = RAD2DEG(VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co));
- uvang2 = VecAngle3_2D(tf_uv[0], tf_uv[1], tf_uv[2]);
- ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co);
+ uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2]));
+ ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co));
- uvang3 = VecAngle3_2D(tf_uv[1], tf_uv[2], tf_uv[3]);
- ang3 = VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co);
+ uvang3 = RAD2DEG(Vec2Angle3(tf_uv[1], tf_uv[2], tf_uv[3]));
+ ang3 = RAD2DEG(VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co));
- uvang4 = VecAngle3_2D(tf_uv[2], tf_uv[3], tf_uv[0]);
- ang4 = VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co);
+ uvang4 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[3], tf_uv[0]));
+ ang4 = RAD2DEG(VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co));
#endif
/* uv angles */
@@ -315,14 +315,14 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
}
else {
#if 0 /* Simple but slow, better reuse normalized vectors */
- uvang1 = VecAngle3_2D(tf_uv[2], tf_uv[0], tf_uv[1]);
- ang1 = VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co);
+ uvang1 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[0], tf_uv[1]));
+ ang1 = RAD2DEG(VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co));
- uvang2 = VecAngle3_2D(tf_uv[0], tf_uv[1], tf_uv[2]);
- ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co);
+ uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2]));
+ ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co));
- uvang3 = 180-(uvang1+uvang2);
- ang3 = 180-(ang1+ang2);
+ uvang3 = M_PI-(uvang1+uvang2);
+ ang3 = M_PI-(ang1+ang2);
#endif
/* uv angles */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 9051300e117..9216cfb5cdc 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -77,7 +77,7 @@ int ED_uvedit_test(Object *obedit)
EditMesh *em;
int ret;
- if(obedit->type != OB_MESH)
+ if(!obedit || obedit->type != OB_MESH)
return 0;
em = BKE_mesh_get_editmesh(obedit->data);
@@ -180,7 +180,13 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
{
int width, height;
- ED_space_image_size(sima, &width, &height);
+ if(sima) {
+ ED_space_image_size(sima, &width, &height);
+ }
+ else {
+ width= 256;
+ height= 256;
+ }
dist[0]= pixeldist/width;
dist[1]= pixeldist/height;
@@ -1097,11 +1103,11 @@ static int stitch_exec(bContext *C, wmOperator *op)
if(RNA_boolean_get(op->ptr, "use_limit")) {
UvVertMap *vmap;
UvMapVert *vlist, *iterv;
- float newuv[2], limit[2], pixels;
+ float newuv[2], limit[2];
int a, vtot;
- pixels= RNA_float_get(op->ptr, "limit");
- uvedit_pixel_to_float(sima, limit, pixels);
+ limit[0]= RNA_float_get(op->ptr, "limit");
+ limit[1]= limit[0];
EM_init_index_arrays(em, 0, 0, 1);
vmap= EM_make_uv_vert_map(em, 1, 0, limit);
@@ -1255,7 +1261,7 @@ void UV_OT_stitch(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "use_limit", 1, "Use Limit", "Stitch UVs within a specified limit distance.");
- RNA_def_float(ot->srna, "limit", 20.0, 0.0f, FLT_MAX, "Limit", "Limit distance in image pixels.", -FLT_MAX, FLT_MAX);
+ RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit", "Limit distance in normalized coordinates.", -FLT_MAX, FLT_MAX);
}
/* ******************** (de)select all operator **************** */
@@ -1439,7 +1445,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
else {
sync= 0;
selectmode= ts->uv_selectmode;
- sticky= sima->sticky;
+ sticky= (sima)? sima->sticky: 1;
}
/* find nearest element */
@@ -2471,13 +2477,18 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
{
EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
- Image *ima= sima->image;
+ Image *ima;
EditFace *efa;
MTFace *tface;
int width= 0, height= 0;
float w, h;
short change = 0;
+ if(!sima)
+ return 0;
+
+ ima= sima->image;
+
ED_space_image_size(sima, &width, &height);
w = (float)width;
h = (float)height;
@@ -2657,6 +2668,7 @@ static int hide_exec(bContext *C, wmOperator *op)
EditFace *efa;
MTFace *tf;
int swap= RNA_boolean_get(op->ptr, "unselected");
+ int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
if(ts->uv_flag & UV_SYNC_SELECTION) {
EM_hide_mesh(em, swap);
@@ -2670,7 +2682,7 @@ static int hide_exec(bContext *C, wmOperator *op)
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->f & SELECT) {
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- if(sima->flag & SI_SELACTFACE) {
+ if(facemode) {
/* Pretend face mode */
if(( (efa->v4==NULL &&
( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) ||
@@ -2715,7 +2727,7 @@ static int hide_exec(bContext *C, wmOperator *op)
if(efa->f & SELECT) {
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- if(sima->flag & SI_SELACTFACE) {
+ if(facemode) {
if( (efa->v4==NULL &&
( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) ||
( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) {
@@ -2799,6 +2811,8 @@ static int reveal_exec(bContext *C, wmOperator *op)
EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
+ int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
+ int stickymode= sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
/* call the mesh function if we are in mesh sync sel */
if(ts->uv_flag & UV_SYNC_SELECTION) {
@@ -2809,7 +2823,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- if(sima->flag & SI_SELACTFACE) {
+ if(facemode) {
if(em->selectmode == SCE_SELECT_FACE) {
for(efa= em->faces.first; efa; efa= efa->next) {
if(!(efa->h) && !(efa->f & SELECT)) {
@@ -2821,7 +2835,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
}
else {
/* enable adjacent faces to have disconnected UV selections if sticky is disabled */
- if(sima->sticky == SI_STICKY_DISABLE) {
+ if(!stickymode) {
for(efa= em->faces.first; efa; efa= efa->next) {
if(!(efa->h) && !(efa->f & SELECT)) {
/* All verts must be unselected for the face to be selected in the UV view */
@@ -3072,7 +3086,10 @@ void ED_operatortypes_uvedit(void)
void ED_keymap_uvedit(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0);
+ wmKeyMap *keymap;
+
+ keymap= WM_keymap_find(wm, "UVEdit", 0, 0);
+ keymap->poll= ED_operator_uvedit;
/* pick selection */
WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index ccdc51430bc..c7258e616fa 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -342,7 +342,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *event)
minimize_stretch_iteration(C, op, 1);
ms= op->customdata;
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
ms->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
return OPERATOR_RUNNING_MODAL;
@@ -423,7 +423,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry.");
- RNA_def_float_percentage(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original.", 0.0f, 1.0f);
+ RNA_def_float_factor(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original.", 0.0f, 1.0f);
RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively.", 0, 100);
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index d7b54e425fd..55e4b337a77 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -346,25 +346,34 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
tex->number = 0;
glBindTexture(tex->target, tex->bindcode);
+ GPU_print_error("3D glBindTexture");
+
type = GL_FLOAT; // GL_UNSIGNED_BYTE
format = GL_RED;
- internalformat = GL_RED;
+ internalformat = GL_INTENSITY;
//if (fpixels)
// pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, 0);
+ GPU_print_error("3D glTexImage3D");
+
if (fpixels) {
glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
+ GPU_print_error("3D glTexSubImage3D");
}
+
glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor);
+ GPU_print_error("3D GL_TEXTURE_BORDER_COLOR");
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ GPU_print_error("3D GL_LINEAR");
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
+ GPU_print_error("3D GL_CLAMP_TO_BORDER");
if (pixels)
MEM_freeN(pixels);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index c0fb069fc41..d01266c8765 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -846,37 +846,35 @@ static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *o
}
}
-static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, int flip, GPUNodeLink **in)
+static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
{
- float flipf = (flip)? 1.0f: 0.0;
-
switch(blendtype) {
case MTEX_BLEND:
- GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in);
break;
case MTEX_MUL:
- GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in);
break;
case MTEX_SCREEN:
- GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in);
break;
case MTEX_SUB:
- GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in);
break;
case MTEX_ADD:
- GPU_link(mat, "mtex_value_add", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in);
break;
case MTEX_DIV:
- GPU_link(mat, "mtex_value_div", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in);
break;
case MTEX_DIFF:
- GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in);
break;
case MTEX_DARK:
- GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in);
break;
case MTEX_LIGHT:
- GPU_link(mat, "mtex_value_light", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in);
break;
default:
GPU_link(mat, "set_value_zero", &in);
@@ -893,7 +891,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
GPUNodeLink *texco_norm, *texco_orco, *texco_object, *texco_tangent;
GPUNodeLink *texco_global, *texco_uv = NULL;
- GPUNodeLink *colfac, *newnor, *varfac, *orn;
+ GPUNodeLink *newnor, *orn;
char *lastuvname = NULL;
float one = 1.0f, norfac, ofs[3];
int tex_nr, rgbnor, talpha;
@@ -993,11 +991,6 @@ static void do_material_tex(GPUShadeInput *shi)
/* mapping */
if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
/* stencil maps on the texture control slider, not texture intensity value */
- if(mtex->colfac == 1.0f)
- colfac = stencil;
- else
- GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
-
if((rgbnor & TEX_RGB)==0) {
GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
}
@@ -1012,21 +1005,30 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "set_value_one", &tin);
}
- if(mtex->mapto & MAP_COL)
+ if(mtex->mapto & MAP_COL) {
+ GPUNodeLink *colfac;
+
+ if(mtex->colfac == 1.0f) colfac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
+
texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
+ }
- if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC))
- texture_rgb_blend(mat, tcol, shi->specrgb, tin, colfac, mtex->blendtype, &shi->specrgb);
+ if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
+ GPUNodeLink *colspecfac;
+
+ if(mtex->colspecfac == 1.0f) colspecfac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
+
+ texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
+ }
}
if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
- if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
- else tex->norfac= mtex->norfac;
-
if((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) {
tex->norfac = mtex->norfac;
- if(mtex->maptoneg & MAP_NORM)
+ if(tex->norfac < 0.0f)
GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
if(mtex->normapspace == MTEX_NSPACE_TANGENT)
@@ -1034,7 +1036,7 @@ static void do_material_tex(GPUShadeInput *shi)
else
newnor = tnor;
- norfac = MIN2(mtex->norfac, 1.0);
+ norfac = MIN2(fabsf(mtex->norfac), 1.0);
if(norfac == 1.0f && !GPU_link_changed(stencil)) {
shi->vn = newnor;
}
@@ -1053,11 +1055,6 @@ static void do_material_tex(GPUShadeInput *shi)
}
if((mtex->mapto & MAP_VARS)) {
- if(mtex->varfac == 1.0f)
- varfac = stencil;
- else
- GPU_link(mat, "math_multiply", GPU_uniform(&mtex->varfac), stencil, &varfac);
-
if(rgbnor & TEX_RGB) {
if(talpha)
GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
@@ -1066,34 +1063,58 @@ static void do_material_tex(GPUShadeInput *shi)
}
if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
- int flip= mtex->maptoneg & MAP_REF;
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, varfac, mtex->blendtype, flip, &shi->refl);
+ GPUNodeLink *difffac;
+
+ if(mtex->difffac == 1.0f) difffac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
+
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl);
GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
}
if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
- int flip= mtex->maptoneg & MAP_SPEC;
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, varfac, mtex->blendtype, flip, &shi->spec);
+ GPUNodeLink *specfac;
+
+ if(mtex->specfac == 1.0f) specfac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
+
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec);
GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
}
if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
- int flip= mtex->maptoneg & MAP_EMIT;
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, varfac, mtex->blendtype, flip, &shi->emit);
+ GPUNodeLink *emitfac;
+
+ if(mtex->emitfac == 1.0f) emitfac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
+
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit);
GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
}
if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
- int flip= mtex->maptoneg & MAP_HAR;
+ GPUNodeLink *hardfac;
+
+ if(mtex->hardfac == 1.0f) hardfac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
+
GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, varfac, mtex->blendtype, flip, &shi->har);
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har);
GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
}
if(mtex->mapto & MAP_ALPHA) {
- int flip= mtex->maptoneg & MAP_ALPHA;
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, varfac, mtex->blendtype, flip, &shi->alpha);
+ GPUNodeLink *alphafac;
+
+ if(mtex->alphafac == 1.0f) alphafac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
+
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha);
GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
}
if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
- int flip= mtex->maptoneg & MAP_AMB;
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, varfac, mtex->blendtype, flip, &shi->amb);
+ GPUNodeLink *ambfac;
+
+ if(mtex->ambfac == 1.0f) ambfac = stencil;
+ else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
+
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb);
GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
}
}
diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl b/source/blender/gpu/intern/gpu_shader_material.glsl
index 16ed38cb47d..0d7e00a541b 100644
--- a/source/blender/gpu/intern/gpu_shader_material.glsl
+++ b/source/blender/gpu/intern/gpu_shader_material.glsl
@@ -847,66 +847,66 @@ void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 i
incol.rgb = col.rgb;
}
-void mtex_value_vars(inout float fact, float facg, out float facm, float flip)
+void mtex_value_vars(inout float fact, float facg, out float facm)
{
- fact *= facg;
+ fact *= abs(facg);
facm = 1.0-fact;
- if(flip != 0.0) {
+ if(facg < 0.0) {
float tmp = fact;
fact = facm;
facm = tmp;
}
}
-void mtex_value_blend(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
incol = fact*texcol + facm*outcol;
}
-void mtex_value_mul(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
facm = 1.0 - facg;
incol = (facm + fact*texcol)*outcol;
}
-void mtex_value_screen(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
facm = 1.0 - facg;
incol = 1.0 - (facm + fact*(1.0 - texcol))*(1.0 - outcol);
}
-void mtex_value_sub(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
fact = -fact;
incol = fact*texcol + outcol;
}
-void mtex_value_add(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
fact = fact;
incol = fact*texcol + outcol;
}
-void mtex_value_div(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
if(texcol != 0.0)
incol = facm*outcol + fact*outcol/texcol;
@@ -914,27 +914,27 @@ void mtex_value_div(float outcol, float texcol, float fact, float facg, float fl
incol = 0.0;
}
-void mtex_value_diff(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
incol = facm*outcol + fact*abs(texcol - outcol);
}
-void mtex_value_dark(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
float col = fact*texcol;
if(col < outcol) incol = col; else incol = outcol;
}
-void mtex_value_light(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
{
float facm;
- mtex_value_vars(fact, facg, facm, flip);
+ mtex_value_vars(fact, facg, facm);
float col = fact*texcol;
if(col > outcol) incol = col; else incol = outcol;
diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h
new file mode 100644
index 00000000000..a259d0aa62a
--- /dev/null
+++ b/source/blender/ikplugin/BIK_api.h
@@ -0,0 +1,93 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIK_API_H
+#define BIK_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Object;
+struct bPoseChannel;
+struct bPose;
+struct bArmature;
+struct Scene;
+struct bConstraint;
+
+enum BIK_ParamType {
+ BIK_PARAM_TYPE_FLOAT = 0,
+ BIK_PARAM_TYPE_INT,
+ BIK_PARAM_TYPE_STRING,
+};
+
+struct BIK_ParamValue {
+ short type; /* BIK_PARAM_TYPE_.. */
+ short length; /* for string, does not include terminating 0 */
+ union {
+ float f[8];
+ int i[8];
+ char s[32];
+ } value;
+};
+typedef struct BIK_ParamValue BIK_ParamValue;
+
+void BIK_initialize_tree(struct Scene *scene, struct Object *ob, float ctime);
+void BIK_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
+void BIK_release_tree(struct Scene *scene, struct Object *ob, float ctime);
+void BIK_clear_data(struct bPose *pose);
+void BIK_clear_cache(struct bPose *pose);
+void BIK_update_param(struct bPose *pose);
+void BIK_test_constraint(struct Object *ob, struct bConstraint *cons);
+// not yet implemented
+int BIK_get_constraint_param(struct bPose *pose, struct bConstraint *cons, int id, BIK_ParamValue *value);
+int BIK_get_channel_param(struct bPose *pose, struct bPoseChannel *pchan, int id, BIK_ParamValue *value);
+int BIK_get_solver_param(struct bPose *pose, struct bPoseChannel *pchan, int id, BIK_ParamValue *value);
+
+// number of solver available
+// 0 = iksolver
+// 1 = iTaSC
+#define BIK_SOLVER_COUNT 2
+
+/* for use in BIK_get_constraint_param */
+#define BIK_PARAM_CONSTRAINT_ERROR 0
+
+/* for use in BIK_get_channel_param */
+#define BIK_PARAM_CHANNEL_JOINT 0
+
+/* for use in BIK_get_solver_param */
+#define BIK_PARAM_SOLVER_RANK 0
+#define BIK_PARAM_SOLVER_ITERATION 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BIK_API_H
+
diff --git a/release/scripts/vertexpaint_gradient.py b/source/blender/ikplugin/CMakeLists.txt
index 17eccb4f67f..5790d4ef12f 100644
--- a/release/scripts/vertexpaint_gradient.py
+++ b/source/blender/ikplugin/CMakeLists.txt
@@ -1,15 +1,4 @@
-#!BPY
-"""
-Name: 'VCol Gradient...'
-Blender: 245
-Group: 'VertexPaint'
-Tooltip: 'Click on the start and end grad points for the mesh for selected faces.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-
+# $Id: CMakeLists.txt 20156 2009-05-11 16:31:30Z ben2610 $
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
@@ -26,21 +15,21 @@ __version__ = "0.1"
# 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 *****
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jacques Beaurain.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+FILE(GLOB SRC intern/*.c intern/*.cpp)
-import mesh_gradient
-import Blender
+SET(INC
+ ../../../intern/guardedalloc ../../../intern/iksolver/extern
+ ../../../intern/itasc ../../../extern/Eigen2
+ ../blenlib ../makesdna ../blenkernel ../include ../ikplugin
+)
-def main():
- scn= Blender.Scene.GetCurrent()
- ob= scn.getActiveObject()
-
- if not ob or ob.getType() != 'Mesh':
- Blender.Draw.PupMenu('Error, no active mesh object, aborting.')
- return
-
- mesh_gradient.vertexGradientPick(ob, 1)
-
-
-if __name__ == '__main__':
- main()
+BLENDERLIB(bf_ikplugin "${SRC}" "${INC}")
diff --git a/source/blender/ikplugin/Makefile b/source/blender/ikplugin/Makefile
new file mode 100644
index 00000000000..370ed418464
--- /dev/null
+++ b/source/blender/ikplugin/Makefile
@@ -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+#
+# Bounces make to subdirectories.
+
+SOURCEDIR = source/blender/ikplugin
+DIRS = intern
+
+include nan_subdirs.mk
diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript
new file mode 100644
index 00000000000..a745a93077a
--- /dev/null
+++ b/source/blender/ikplugin/SConscript
@@ -0,0 +1,9 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp')
+
+incs = '#/intern/guardedalloc #/intern/iksolver/extern ../makesdna ../blenlib'
+incs += ' ../blenkernel ../include ../ikplugin #/intern/itasc #/extern/Eigen2'
+
+env.BlenderLib ( 'bf_ikplugin', sources, Split(incs), [], libtype=['core','player'], priority=[180, 190] )
diff --git a/source/blender/ikplugin/intern/Makefile b/source/blender/ikplugin/intern/Makefile
new file mode 100644
index 00000000000..0c54e5d1264
--- /dev/null
+++ b/source/blender/ikplugin/intern/Makefile
@@ -0,0 +1,51 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You 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.
+#
+# 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 *****
+#
+#
+
+LIBNAME = ikplugin
+DIR = $(OCGDIR)/blender/ikplugin
+
+include nan_compile.mk
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+CFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CFLAGS += -I../../makesdna
+CFLAGS += -I../../blenkernel
+CFLAGS += -I../../blenlib
+CFLAGS += -I../../include
+CFLAGS += -I../../../../intern/itasc
+CFLAGS += -I../../../../extern/Eigen2
+CFLAGS += -I..
+
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_IKSOLVER)/include
+CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../blenkernel
+CPPFLAGS += -I../../blenlib
+CPPFLAGS += -I../../include
+CPPFLAGS += -I../../../../intern/itasc
+CPPFLAGS += -I../../../../extern/Eigen2
+CPPFLAGS += -I..
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
new file mode 100644
index 00000000000..f106302dbaf
--- /dev/null
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -0,0 +1,138 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BIK_api.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "BKE_armature.h"
+#include "BKE_utildefines.h"
+#include "DNA_object_types.h"
+#include "DNA_action_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_armature_types.h"
+
+#include "ikplugin_api.h"
+#include "iksolver_plugin.h"
+#include "itasc_plugin.h"
+
+
+static IKPlugin ikplugin_tab[BIK_SOLVER_COUNT] = {
+ /* Legacy IK solver */
+ {
+ iksolver_initialize_tree,
+ iksolver_execute_tree,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ },
+ /* iTaSC IK solver */
+ {
+ itasc_initialize_tree,
+ itasc_execute_tree,
+ itasc_release_tree,
+ itasc_clear_data,
+ itasc_clear_cache,
+ itasc_update_param,
+ itasc_test_constraint,
+ }
+};
+
+
+static IKPlugin *get_plugin(bPose *pose)
+{
+ if (!pose || pose->iksolver < 0 || pose->iksolver >= BIK_SOLVER_COUNT)
+ return NULL;
+
+ return &ikplugin_tab[pose->iksolver];
+}
+
+/*----------------------------------------*/
+/* Plugin API */
+
+void BIK_initialize_tree(Scene *scene, Object *ob, float ctime)
+{
+ IKPlugin *plugin = get_plugin(ob->pose);
+
+ if (plugin && plugin->initialize_tree_func)
+ plugin->initialize_tree_func(scene, ob, ctime);
+}
+
+void BIK_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan, float ctime)
+{
+ IKPlugin *plugin = get_plugin(ob->pose);
+
+ if (plugin && plugin->execute_tree_func)
+ plugin->execute_tree_func(scene, ob, pchan, ctime);
+}
+
+void BIK_release_tree(struct Scene *scene, Object *ob, float ctime)
+{
+ IKPlugin *plugin = get_plugin(ob->pose);
+
+ if (plugin && plugin->release_tree_func)
+ plugin->release_tree_func(scene, ob, ctime);
+}
+
+void BIK_clear_data(struct bPose *pose)
+{
+ IKPlugin *plugin = get_plugin(pose);
+
+ if (plugin && plugin->remove_armature_func)
+ plugin->remove_armature_func(pose);
+}
+
+void BIK_clear_cache(struct bPose *pose)
+{
+ IKPlugin *plugin = get_plugin(pose);
+
+ if (plugin && plugin->clear_cache)
+ plugin->clear_cache(pose);
+}
+
+void BIK_update_param(struct bPose *pose)
+{
+ IKPlugin *plugin = get_plugin(pose);
+
+ if (plugin && plugin->update_param)
+ plugin->update_param(pose);
+}
+
+void BIK_test_constraint(struct Object *ob, struct bConstraint *cons)
+{
+ IKPlugin *plugin = get_plugin(ob->pose);
+
+ if (plugin && plugin->test_constraint)
+ plugin->test_constraint(ob, cons);
+}
diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h
new file mode 100644
index 00000000000..cc4dff4ec75
--- /dev/null
+++ b/source/blender/ikplugin/intern/ikplugin_api.h
@@ -0,0 +1,60 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef IKPLUGIN_API_H
+#define IKPLUGIN_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Object;
+struct bPoseChannel;
+struct bArmature;
+struct Scene;
+
+
+struct IKPlugin {
+ void (*initialize_tree_func)(struct Scene *scene, struct Object *ob, float ctime);
+ void (*execute_tree_func)(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
+ void (*release_tree_func)(struct Scene *scene, struct Object *ob, float ctime);
+ void (*remove_armature_func)(struct bPose *pose);
+ void (*clear_cache)(struct bPose *pose);
+ void (*update_param)(struct bPose *pose);
+ void (*test_constraint)(struct Object *ob, struct bConstraint *cons);
+};
+
+typedef struct IKPlugin IKPlugin;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IKPLUGIN_API_H
+
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
new file mode 100644
index 00000000000..68afbcd0db2
--- /dev/null
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -0,0 +1,530 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BIK_api.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "BKE_armature.h"
+#include "BKE_constraint.h"
+#include "BKE_utildefines.h"
+#include "DNA_object_types.h"
+#include "DNA_action_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_armature_types.h"
+
+#include "IK_solver.h"
+#include "iksolver_plugin.h"
+
+#include <string.h> /* memcpy */
+
+/* ********************** THE IK SOLVER ******************* */
+
+/* allocates PoseTree, and links that to root bone/channel */
+/* Note: detecting the IK chain is duplicate code... in drawarmature.c and in transform_conversions.c */
+static void initialize_posetree(struct Object *ob, bPoseChannel *pchan_tip)
+{
+ bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan;
+ PoseTree *tree;
+ PoseTarget *target;
+ bConstraint *con;
+ bKinematicConstraint *data;
+ int a, segcount= 0, size, newsize, *oldparent, parent;
+
+ /* find IK constraint, and validate it */
+ for(con= pchan_tip->constraints.first; con; con= con->next) {
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ data=(bKinematicConstraint*)con->data;
+ if (data->flag & CONSTRAINT_IK_AUTO) break;
+ if (data->tar==NULL) continue;
+ if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0) continue;
+ if ((con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF))==0 && (con->enforce!=0.0)) break;
+ }
+ }
+ if(con==NULL) return;
+
+ /* exclude tip from chain? */
+ if(!(data->flag & CONSTRAINT_IK_TIP))
+ pchan_tip= pchan_tip->parent;
+
+ /* Find the chain's root & count the segments needed */
+ for (curchan = pchan_tip; curchan; curchan=curchan->parent){
+ pchan_root = curchan;
+
+ curchan->flag |= POSE_CHAIN; // don't forget to clear this
+ chanlist[segcount]=curchan;
+ segcount++;
+
+ if(segcount==data->rootbone || segcount>255) break; // 255 is weak
+ }
+ if (!segcount) return;
+
+ /* setup the chain data */
+
+ /* we make tree-IK, unless all existing targets are in this chain */
+ for(tree= pchan_root->iktree.first; tree; tree= tree->next) {
+ for(target= tree->targets.first; target; target= target->next) {
+ curchan= tree->pchan[target->tip];
+ if(curchan->flag & POSE_CHAIN)
+ curchan->flag &= ~POSE_CHAIN;
+ else
+ break;
+ }
+ if(target) break;
+ }
+
+ /* create a target */
+ target= MEM_callocN(sizeof(PoseTarget), "posetarget");
+ target->con= con;
+ pchan_tip->flag &= ~POSE_CHAIN;
+
+ if(tree==NULL) {
+ /* make new tree */
+ tree= MEM_callocN(sizeof(PoseTree), "posetree");
+
+ tree->iterations= data->iterations;
+ tree->totchannel= segcount;
+ tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);
+
+ tree->pchan= MEM_callocN(segcount*sizeof(void*), "ik tree pchan");
+ tree->parent= MEM_callocN(segcount*sizeof(int), "ik tree parent");
+ for(a=0; a<segcount; a++) {
+ tree->pchan[a]= chanlist[segcount-a-1];
+ tree->parent[a]= a-1;
+ }
+ target->tip= segcount-1;
+
+ /* AND! link the tree to the root */
+ BLI_addtail(&pchan_root->iktree, tree);
+ }
+ else {
+ tree->iterations= MAX2(data->iterations, tree->iterations);
+ tree->stretch= tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);
+
+ /* skip common pose channels and add remaining*/
+ size= MIN2(segcount, tree->totchannel);
+ for(a=0; a<size && tree->pchan[a]==chanlist[segcount-a-1]; a++);
+ parent= a-1;
+
+ segcount= segcount-a;
+ target->tip= tree->totchannel + segcount - 1;
+
+ if (segcount > 0) {
+ /* resize array */
+ newsize= tree->totchannel + segcount;
+ oldchan= tree->pchan;
+ oldparent= tree->parent;
+
+ tree->pchan= MEM_callocN(newsize*sizeof(void*), "ik tree pchan");
+ tree->parent= MEM_callocN(newsize*sizeof(int), "ik tree parent");
+ memcpy(tree->pchan, oldchan, sizeof(void*)*tree->totchannel);
+ memcpy(tree->parent, oldparent, sizeof(int)*tree->totchannel);
+ MEM_freeN(oldchan);
+ MEM_freeN(oldparent);
+
+ /* add new pose channels at the end, in reverse order */
+ for(a=0; a<segcount; a++) {
+ tree->pchan[tree->totchannel+a]= chanlist[segcount-a-1];
+ tree->parent[tree->totchannel+a]= tree->totchannel+a-1;
+ }
+ tree->parent[tree->totchannel]= parent;
+
+ tree->totchannel= newsize;
+ }
+
+ /* move tree to end of list, for correct evaluation order */
+ BLI_remlink(&pchan_root->iktree, tree);
+ BLI_addtail(&pchan_root->iktree, tree);
+ }
+
+ /* add target to the tree */
+ BLI_addtail(&tree->targets, target);
+ /* mark root channel having an IK tree */
+ pchan_root->flag |= POSE_IKTREE;
+}
+
+
+/* transform from bone(b) to bone(b+1), store in chan_mat */
+static void make_dmats(bPoseChannel *pchan)
+{
+ if (pchan->parent) {
+ float iR_parmat[4][4];
+ Mat4Invert(iR_parmat, pchan->parent->pose_mat);
+ Mat4MulMat4(pchan->chan_mat, pchan->pose_mat, iR_parmat); // delta mat
+ }
+ else Mat4CpyMat4(pchan->chan_mat, pchan->pose_mat);
+}
+
+/* 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
+{
+ float vec[3], ikmat[4][4];
+
+ Mat4CpyMat3(ikmat, ik_mat);
+
+ if (pchan->parent)
+ Mat4MulSerie(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat, NULL, NULL, NULL, NULL, NULL);
+ else
+ Mat4MulMat4(pchan->pose_mat, ikmat, pchan->chan_mat);
+
+ /* calculate head */
+ VECCOPY(pchan->pose_head, pchan->pose_mat[3]);
+ /* calculate tail */
+ VECCOPY(vec, pchan->pose_mat[1]);
+ VecMulf(vec, pchan->bone->length);
+ VecAddf(pchan->pose_tail, pchan->pose_head, vec);
+
+ pchan->flag |= POSE_DONE;
+}
+
+
+/* called from within the core where_is_pose loop, all animsystems and constraints
+were executed & assigned. Now as last we do an IK pass */
+static void execute_posetree(Object *ob, PoseTree *tree)
+{
+ float R_parmat[3][3], identity[3][3];
+ float iR_parmat[3][3];
+ float R_bonemat[3][3];
+ float goalrot[3][3], goalpos[3];
+ float rootmat[4][4], imat[4][4];
+ float goal[4][4], goalinv[4][4];
+ float irest_basis[3][3], full_basis[3][3];
+ float end_pose[4][4], world_pose[4][4];
+ float length, basis[3][3], rest_basis[3][3], start[3], *ikstretch=NULL;
+ float resultinf=0.0f;
+ int a, flag, hasstretch=0, resultblend=0;
+ bPoseChannel *pchan;
+ IK_Segment *seg, *parent, **iktree, *iktarget;
+ IK_Solver *solver;
+ PoseTarget *target;
+ bKinematicConstraint *data, *poleangledata=NULL;
+ Bone *bone;
+
+ if (tree->totchannel == 0)
+ return;
+
+ iktree= MEM_mallocN(sizeof(void*)*tree->totchannel, "ik tree");
+
+ for(a=0; a<tree->totchannel; a++) {
+ pchan= tree->pchan[a];
+ bone= pchan->bone;
+
+ /* set DoF flag */
+ flag= 0;
+ if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP))
+ flag |= IK_XDOF;
+ if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP))
+ flag |= IK_YDOF;
+ if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP))
+ flag |= IK_ZDOF;
+
+ if(tree->stretch && (pchan->ikstretch > 0.0)) {
+ flag |= IK_TRANS_YDOF;
+ hasstretch = 1;
+ }
+
+ seg= iktree[a]= IK_CreateSegment(flag);
+
+ /* find parent */
+ if(a == 0)
+ parent= NULL;
+ else
+ parent= iktree[tree->parent[a]];
+
+ IK_SetParent(seg, parent);
+
+ /* get the matrix that transforms from prevbone into this bone */
+ Mat3CpyMat4(R_bonemat, pchan->pose_mat);
+
+ /* gather transformations for this IK segment */
+
+ if (pchan->parent)
+ Mat3CpyMat4(R_parmat, pchan->parent->pose_mat);
+ else
+ Mat3One(R_parmat);
+
+ /* bone offset */
+ if (pchan->parent && (a > 0))
+ VecSubf(start, pchan->pose_head, pchan->parent->pose_tail);
+ else
+ /* only root bone (a = 0) has no parent */
+ start[0]= start[1]= start[2]= 0.0f;
+
+ /* change length based on bone size */
+ length= bone->length*VecLength(R_bonemat[1]);
+
+ /* compute rest basis and its inverse */
+ Mat3CpyMat3(rest_basis, bone->bone_mat);
+ Mat3CpyMat3(irest_basis, bone->bone_mat);
+ Mat3Transp(irest_basis);
+
+ /* compute basis with rest_basis removed */
+ Mat3Inv(iR_parmat, R_parmat);
+ Mat3MulMat3(full_basis, iR_parmat, R_bonemat);
+ Mat3MulMat3(basis, irest_basis, full_basis);
+
+ /* basis must be pure rotation */
+ Mat3Ortho(basis);
+
+ /* transform offset into local bone space */
+ Mat3Ortho(iR_parmat);
+ Mat3MulVecfl(iR_parmat, start);
+
+ IK_SetTransform(seg, start, rest_basis, basis, length);
+
+ if (pchan->ikflag & BONE_IK_XLIMIT)
+ IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]);
+ if (pchan->ikflag & BONE_IK_YLIMIT)
+ IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]);
+ if (pchan->ikflag & BONE_IK_ZLIMIT)
+ IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]);
+
+ IK_SetStiffness(seg, IK_X, pchan->stiffness[0]);
+ IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
+ IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);
+
+ if(tree->stretch && (pchan->ikstretch > 0.0)) {
+ float ikstretch = pchan->ikstretch*pchan->ikstretch;
+ IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.99));
+ IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10);
+ }
+ }
+
+ solver= IK_CreateSolver(iktree[0]);
+
+ /* set solver goals */
+
+ /* first set the goal inverse transform, assuming the root of tree was done ok! */
+ pchan= tree->pchan[0];
+ if (pchan->parent)
+ /* transform goal by parent mat, so this rotation is not part of the
+ segment's basis. otherwise rotation limits do not work on the
+ local transform of the segment itself. */
+ Mat4CpyMat4(rootmat, pchan->parent->pose_mat);
+ else
+ Mat4One(rootmat);
+ VECCOPY(rootmat[3], pchan->pose_head);
+
+ Mat4MulMat4 (imat, rootmat, ob->obmat);
+ Mat4Invert (goalinv, imat);
+
+ for (target=tree->targets.first; target; target=target->next) {
+ float polepos[3];
+ int poleconstrain= 0;
+
+ data= (bKinematicConstraint*)target->con->data;
+
+ /* 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(target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+
+ /* and set and transform goal */
+ Mat4MulMat4(goal, rootmat, goalinv);
+
+ VECCOPY(goalpos, goal[3]);
+ Mat3CpyMat4(goalrot, goal);
+
+ /* same for pole vector target */
+ if(data->poletar) {
+ get_constraint_target_matrix(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 */
+ break;
+ }
+ else {
+ Mat4MulMat4(goal, rootmat, goalinv);
+ VECCOPY(polepos, goal[3]);
+ poleconstrain= 1;
+
+ /* for pole targets, we blend the result of the ik solver
+ * instead of the target position, otherwise we can't get
+ * a smooth transition */
+ resultblend= 1;
+ resultinf= target->con->enforce;
+
+ if(data->flag & CONSTRAINT_IK_GETANGLE) {
+ poleangledata= data;
+ data->flag &= ~CONSTRAINT_IK_GETANGLE;
+ }
+ }
+ }
+
+ /* do we need blending? */
+ if (!resultblend && target->con->enforce!=1.0) {
+ float q1[4], q2[4], q[4];
+ float fac= target->con->enforce;
+ float mfac= 1.0-fac;
+
+ pchan= tree->pchan[target->tip];
+
+ /* end effector in world space */
+ Mat4CpyMat4(end_pose, pchan->pose_mat);
+ VECCOPY(end_pose[3], pchan->pose_tail);
+ Mat4MulSerie(world_pose, goalinv, ob->obmat, end_pose, 0, 0, 0, 0, 0);
+
+ /* blend position */
+ goalpos[0]= fac*goalpos[0] + mfac*world_pose[3][0];
+ goalpos[1]= fac*goalpos[1] + mfac*world_pose[3][1];
+ goalpos[2]= fac*goalpos[2] + mfac*world_pose[3][2];
+
+ /* blend rotation */
+ Mat3ToQuat(goalrot, q1);
+ Mat4ToQuat(world_pose, q2);
+ QuatInterpol(q, q1, q2, mfac);
+ QuatToMat3(q, goalrot);
+ }
+
+ iktarget= iktree[target->tip];
+
+ if(data->weight != 0.0) {
+ if(poleconstrain)
+ IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
+ polepos, data->poleangle*M_PI/180, (poleangledata == data));
+ IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
+ }
+ if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0))
+ if((data->flag & CONSTRAINT_IK_AUTO)==0)
+ IK_SolverAddGoalOrientation(solver, iktarget, goalrot,
+ data->orientweight);
+ }
+
+ /* solve */
+ IK_Solve(solver, 0.0f, tree->iterations);
+
+ if(poleangledata)
+ poleangledata->poleangle= IK_SolverGetPoleAngle(solver)*180/M_PI;
+
+ IK_FreeSolver(solver);
+
+ /* gather basis changes */
+ tree->basis_change= MEM_mallocN(sizeof(float[3][3])*tree->totchannel, "ik basis change");
+ if(hasstretch)
+ ikstretch= MEM_mallocN(sizeof(float)*tree->totchannel, "ik stretch");
+
+ for(a=0; a<tree->totchannel; a++) {
+ IK_GetBasisChange(iktree[a], tree->basis_change[a]);
+
+ if(hasstretch) {
+ /* have to compensate for scaling received from parent */
+ float parentstretch, stretch;
+
+ pchan= tree->pchan[a];
+ parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0;
+
+ if(tree->stretch && (pchan->ikstretch > 0.0)) {
+ float trans[3], length;
+
+ IK_GetTranslationChange(iktree[a], trans);
+ length= pchan->bone->length*VecLength(pchan->pose_mat[1]);
+
+ ikstretch[a]= (length == 0.0)? 1.0: (trans[1]+length)/length;
+ }
+ else
+ ikstretch[a] = 1.0;
+
+ stretch= (parentstretch == 0.0)? 1.0: ikstretch[a]/parentstretch;
+
+ VecMulf(tree->basis_change[a][0], stretch);
+ VecMulf(tree->basis_change[a][1], stretch);
+ VecMulf(tree->basis_change[a][2], stretch);
+ }
+
+ if(resultblend && resultinf!=1.0f) {
+ Mat3One(identity);
+ Mat3BlendMat3(tree->basis_change[a], identity,
+ tree->basis_change[a], resultinf);
+ }
+
+ IK_FreeSegment(iktree[a]);
+ }
+
+ MEM_freeN(iktree);
+ if(ikstretch) MEM_freeN(ikstretch);
+}
+
+static void free_posetree(PoseTree *tree)
+{
+ BLI_freelistN(&tree->targets);
+ if(tree->pchan) MEM_freeN(tree->pchan);
+ if(tree->parent) MEM_freeN(tree->parent);
+ if(tree->basis_change) MEM_freeN(tree->basis_change);
+ MEM_freeN(tree);
+}
+
+///----------------------------------------
+/// Plugin API for legacy iksolver
+
+void iksolver_initialize_tree(struct Scene *scene, struct Object *ob, float ctime)
+{
+ bPoseChannel *pchan;
+
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if(pchan->constflag & PCHAN_HAS_IK) // flag is set on editing constraints
+ initialize_posetree(ob, pchan); // will attach it to root!
+ }
+ ob->pose->flag &= ~POSE_WAS_REBUILT;
+}
+
+void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime)
+{
+ while(pchan->iktree.first) {
+ PoseTree *tree= pchan->iktree.first;
+ int a;
+
+ /* 4. walk over the tree for regular solving */
+ for(a=0; a<tree->totchannel; a++) {
+ if(!(tree->pchan[a]->flag & POSE_DONE)) // successive trees can set the flag
+ where_is_pose_bone(scene, ob, tree->pchan[a], ctime);
+ // tell blender that this channel was controlled by IK, it's cleared on each where_is_pose()
+ tree->pchan[a]->flag |= POSE_CHAIN;
+ }
+ /* 5. execute the IK solver */
+ execute_posetree(ob, tree);
+
+ /* 6. apply the differences to the channels,
+ we need to calculate the original differences first */
+ for(a=0; a<tree->totchannel; a++)
+ make_dmats(tree->pchan[a]);
+
+ for(a=0; a<tree->totchannel; a++)
+ /* sets POSE_DONE */
+ where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
+
+ /* 7. and free */
+ BLI_remlink(&pchan->iktree, tree);
+ free_posetree(tree);
+ }
+}
+
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h
new file mode 100644
index 00000000000..d5d1d9a77da
--- /dev/null
+++ b/source/blender/ikplugin/intern/iksolver_plugin.h
@@ -0,0 +1,47 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef IKSOLVER_PLUGIN_H
+#define IKSOLVER_PLUGIN_H
+
+#include "ikplugin_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void iksolver_initialize_tree(struct Scene *scene, struct Object *ob, float ctime);
+void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IKSOLVER_PLUGIN_H
+
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
new file mode 100644
index 00000000000..dc0c2c4c12f
--- /dev/null
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -0,0 +1,1777 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <vector>
+
+// iTaSC headers
+#include "Armature.hpp"
+#include "MovingFrame.hpp"
+#include "CopyPose.hpp"
+#include "WSDLSSolver.hpp"
+#include "WDLSSolver.hpp"
+#include "Scene.hpp"
+#include "Cache.hpp"
+#include "Distance.hpp"
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "BIK_api.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "BKE_global.h"
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_utildefines.h"
+#include "BKE_constraint.h"
+#include "DNA_object_types.h"
+#include "DNA_action_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_scene_types.h"
+};
+
+#include "itasc_plugin.h"
+
+// default parameters
+bItasc DefIKParam;
+
+// in case of animation mode, feedback and timestep is fixed
+#define ANIM_TIMESTEP 1.0
+#define ANIM_FEEDBACK 0.8
+#define ANIM_QMAX 0.52
+
+
+// Structure pointed by bPose.ikdata
+// It contains everything needed to simulate the armatures
+// There can be several simulation islands independent to each other
+struct IK_Data
+{
+ struct IK_Scene* first;
+};
+
+typedef float Vector3[3];
+typedef float Vector4[4];
+struct IK_Target;
+typedef void (*ErrorCallback)(const iTaSC::ConstraintValues* values, unsigned int nvalues, IK_Target* iktarget);
+// For some reason, gcc doesn't find the declaration of this function in linux
+void KDL::SetToZero(JntArray& array);
+
+// one structure for each target in the scene
+struct IK_Target
+{
+ iTaSC::MovingFrame* target;
+ iTaSC::ConstraintSet* constraint;
+ struct bConstraint* blenderConstraint;
+ struct bPoseChannel* rootChannel;
+ Object* owner; //for auto IK
+ ErrorCallback errorCallback;
+ std::string targetName;
+ std::string constraintName;
+ unsigned short controlType;
+ short channel; //index in IK channel array of channel on which this target is defined
+ short ee; //end effector number
+ bool simulation; //true when simulation mode is used (update feedback)
+ bool eeBlend; //end effector affected by enforce blending
+ float eeRest[4][4]; //end effector initial pose relative to armature
+
+ IK_Target() {
+ target = NULL;
+ constraint = NULL;
+ blenderConstraint = NULL;
+ rootChannel = NULL;
+ owner = NULL;
+ controlType = 0;
+ channel = 0;
+ ee = 0;
+ eeBlend = true;
+ simulation = true;
+ targetName.reserve(32);
+ constraintName.reserve(32);
+ }
+ ~IK_Target() {
+ if (constraint)
+ delete constraint;
+ if (target)
+ delete target;
+ }
+};
+
+struct IK_Channel {
+ bPoseChannel* pchan; // channel where we must copy matrix back
+ KDL::Frame frame; // frame of the bone relative to object base, not armature base
+ std::string tail; // segment name of the joint from which we get the bone tail
+ std::string head; // segment name of the joint from which we get the bone head
+ int parent; // index in this array of the parent channel
+ short jointType; // type of joint, combination of IK_SegmentFlag
+ char ndof; // number of joint angles for this channel
+ char jointValid; // set to 1 when jointValue has been computed
+ // for joint constraint
+ Object* owner; // for pose and IK param
+ double jointValue[4]; // computed joint value
+
+ IK_Channel() {
+ pchan = NULL;
+ parent = -1;
+ jointType = 0;
+ ndof = 0;
+ jointValid = 0;
+ owner = NULL;
+ jointValue[0] = 0.0;
+ jointValue[1] = 0.0;
+ jointValue[2] = 0.0;
+ jointValue[3] = 0.0;
+ }
+};
+
+struct IK_Scene
+{
+ IK_Scene* next;
+ int numchan; // number of channel in pchan
+ int numjoint; // number of joint in jointArray
+ // array of bone information, one per channel in the tree
+ IK_Channel* channels;
+ iTaSC::Armature* armature;
+ iTaSC::Cache* cache;
+ iTaSC::Scene* scene;
+ iTaSC::MovingFrame* base; // armature base object
+ KDL::Frame baseFrame; // frame of armature base relative to blArmature
+ KDL::JntArray jointArray; // buffer for storing temporary joint array
+ iTaSC::Solver* solver;
+ Object* blArmature;
+ struct bConstraint* polarConstraint;
+ std::vector<IK_Target*> targets;
+
+ IK_Scene() {
+ next = NULL;
+ channels = NULL;
+ armature = NULL;
+ cache = NULL;
+ scene = NULL;
+ base = NULL;
+ solver = NULL;
+ blArmature = NULL;
+ numchan = 0;
+ numjoint = 0;
+ polarConstraint = NULL;
+ }
+
+ ~IK_Scene() {
+ // delete scene first
+ if (scene)
+ delete scene;
+ for(std::vector<IK_Target*>::iterator it = targets.begin(); it != targets.end(); ++it)
+ delete (*it);
+ targets.clear();
+ if (channels)
+ delete [] channels;
+ if (solver)
+ delete solver;
+ if (armature)
+ delete armature;
+ if (base)
+ delete base;
+ // delete cache last
+ if (cache)
+ delete cache;
+ }
+};
+
+// type of IK joint, can be combined to list the joints corresponding to a bone
+enum IK_SegmentFlag {
+ IK_XDOF = 1,
+ IK_YDOF = 2,
+ IK_ZDOF = 4,
+ IK_SWING = 8,
+ IK_REVOLUTE = 16,
+ IK_TRANSY = 32,
+};
+
+enum IK_SegmentAxis {
+ IK_X = 0,
+ IK_Y = 1,
+ IK_Z = 2,
+ IK_TRANS_X = 3,
+ IK_TRANS_Y = 4,
+ IK_TRANS_Z = 5
+};
+
+static int initialize_chain(Object *ob, bPoseChannel *pchan_tip, bConstraint *con)
+{
+ bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan;
+ PoseTree *tree;
+ PoseTarget *target;
+ bKinematicConstraint *data;
+ int a, t, segcount= 0, size, newsize, *oldparent, parent, rootbone, treecount;
+
+ data=(bKinematicConstraint*)con->data;
+
+ /* exclude tip from chain? */
+ if(!(data->flag & CONSTRAINT_IK_TIP))
+ pchan_tip= pchan_tip->parent;
+
+ rootbone = data->rootbone;
+ /* Find the chain's root & count the segments needed */
+ for (curchan = pchan_tip; curchan; curchan=curchan->parent){
+ pchan_root = curchan;
+
+ if (++segcount > 255) // 255 is weak
+ break;
+
+ if(segcount==rootbone){
+ // reached this end of the chain but if the chain is overlapping with a
+ // previous one, we must go back up to the root of the other chain
+ if ((curchan->flag & POSE_CHAIN) && curchan->iktree.first == NULL){
+ rootbone++;
+ continue;
+ }
+ break;
+ }
+
+ if (curchan->iktree.first != NULL)
+ // Oh oh, there is already a chain starting from this channel and our chain is longer...
+ // Should handle this by moving the previous chain up to the begining of our chain
+ // For now we just stop here
+ break;
+ }
+ if (!segcount) return 0;
+ // we reached a limit and still not the end of a previous chain, quit
+ if ((pchan_root->flag & POSE_CHAIN) && pchan_root->iktree.first == NULL) return 0;
+
+ // now that we know how many segment we have, set the flag
+ for (rootbone = segcount, segcount = 0, curchan = pchan_tip; segcount < rootbone; segcount++, curchan=curchan->parent) {
+ chanlist[segcount]=curchan;
+ curchan->flag |= POSE_CHAIN;
+ }
+
+ /* setup the chain data */
+ /* create a target */
+ target= (PoseTarget*)MEM_callocN(sizeof(PoseTarget), "posetarget");
+ target->con= con;
+ // by contruction there can be only one tree per channel and each channel can be part of at most one tree.
+ tree = (PoseTree*)pchan_root->iktree.first;
+
+ if(tree==NULL) {
+ /* make new tree */
+ tree= (PoseTree*)MEM_callocN(sizeof(PoseTree), "posetree");
+
+ tree->iterations= data->iterations;
+ tree->totchannel= segcount;
+ tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);
+
+ tree->pchan= (bPoseChannel**)MEM_callocN(segcount*sizeof(void*), "ik tree pchan");
+ tree->parent= (int*)MEM_callocN(segcount*sizeof(int), "ik tree parent");
+ for(a=0; a<segcount; a++) {
+ tree->pchan[a]= chanlist[segcount-a-1];
+ tree->parent[a]= a-1;
+ }
+ target->tip= segcount-1;
+
+ /* AND! link the tree to the root */
+ BLI_addtail(&pchan_root->iktree, tree);
+ // new tree
+ treecount = 1;
+ }
+ else {
+ tree->iterations= MAX2(data->iterations, tree->iterations);
+ tree->stretch= tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);
+
+ /* skip common pose channels and add remaining*/
+ size= MIN2(segcount, tree->totchannel);
+ a = t = 0;
+ while (a<size && t<tree->totchannel) {
+ // locate first matching channel
+ for (;t<tree->totchannel && tree->pchan[t]!=chanlist[segcount-a-1];t++);
+ if (t>=tree->totchannel)
+ break;
+ for(; a<size && t<tree->totchannel && tree->pchan[t]==chanlist[segcount-a-1]; a++, t++);
+ }
+ parent= a-1;
+ segcount= segcount-a;
+ target->tip= tree->totchannel + segcount - 1;
+
+ if (segcount > 0) {
+ /* resize array */
+ newsize= tree->totchannel + segcount;
+ oldchan= tree->pchan;
+ oldparent= tree->parent;
+
+ tree->pchan= (bPoseChannel**)MEM_callocN(newsize*sizeof(void*), "ik tree pchan");
+ tree->parent= (int*)MEM_callocN(newsize*sizeof(int), "ik tree parent");
+ memcpy(tree->pchan, oldchan, sizeof(void*)*tree->totchannel);
+ memcpy(tree->parent, oldparent, sizeof(int)*tree->totchannel);
+ MEM_freeN(oldchan);
+ MEM_freeN(oldparent);
+
+ /* add new pose channels at the end, in reverse order */
+ for(a=0; a<segcount; a++) {
+ tree->pchan[tree->totchannel+a]= chanlist[segcount-a-1];
+ tree->parent[tree->totchannel+a]= tree->totchannel+a-1;
+ }
+ tree->parent[tree->totchannel]= parent;
+
+ tree->totchannel= newsize;
+ }
+ // reusing tree
+ treecount = 0;
+ }
+
+ /* add target to the tree */
+ BLI_addtail(&tree->targets, target);
+ /* mark root channel having an IK tree */
+ pchan_root->flag |= POSE_IKTREE;
+ return treecount;
+}
+
+static bool is_cartesian_constraint(bConstraint *con)
+{
+ //bKinematicConstraint* data=(bKinematicConstraint*)con->data;
+
+ return true;
+}
+
+static bool constraint_valid(bConstraint *con)
+{
+ bKinematicConstraint* data=(bKinematicConstraint*)con->data;
+
+ if (data->flag & CONSTRAINT_IK_AUTO)
+ return true;
+ if (con->flag & CONSTRAINT_DISABLE)
+ return false;
+ if (is_cartesian_constraint(con)) {
+ /* cartesian space constraint */
+ if (data->tar==NULL)
+ return false;
+ if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0)
+ return false;
+ }
+ return true;
+}
+
+int initialize_scene(Object *ob, bPoseChannel *pchan_tip)
+{
+ bConstraint *con;
+ int treecount;
+
+ /* find all IK constraints and validate them */
+ treecount = 0;
+ for(con= (bConstraint *)pchan_tip->constraints.first; con; con= (bConstraint *)con->next) {
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ if (constraint_valid(con))
+ treecount += initialize_chain(ob, pchan_tip, con);
+ }
+ }
+ return treecount;
+}
+
+static IK_Data* get_ikdata(bPose *pose)
+{
+ if (pose->ikdata)
+ return (IK_Data*)pose->ikdata;
+ pose->ikdata = MEM_callocN(sizeof(IK_Data), "iTaSC ikdata");
+ // here init ikdata if needed
+ // now that we have scene, make sure the default param are initialized
+ if (!DefIKParam.iksolver)
+ init_pose_itasc(&DefIKParam);
+
+ return (IK_Data*)pose->ikdata;
+}
+static double EulerAngleFromMatrix(const KDL::Rotation& R, int axis)
+{
+ double t = KDL::sqrt(R(0,0)*R(0,0) + R(0,1)*R(0,1));
+
+ if (t > 16.0*KDL::epsilon) {
+ if (axis == 0) return -KDL::atan2(R(1,2), R(2,2));
+ else if(axis == 1) return KDL::atan2(-R(0,2), t);
+ else return -KDL::atan2(R(0,1), R(0,0));
+ } else {
+ if (axis == 0) return -KDL::atan2(-R(2,1), R(1,1));
+ else if(axis == 1) return KDL::atan2(-R(0,2), t);
+ else return 0.0f;
+ }
+}
+
+static double ComputeTwist(const KDL::Rotation& R)
+{
+ // qy and qw are the y and w components of the quaternion from R
+ double qy = R(0,2) - R(2,0);
+ double qw = R(0,0) + R(1,1) + R(2,2) + 1;
+
+ double tau = 2*KDL::atan2(qy, qw);
+
+ return tau;
+}
+
+static void RemoveEulerAngleFromMatrix(KDL::Rotation& R, double angle, int axis)
+{
+ // compute twist parameter
+ KDL::Rotation T;
+ switch (axis) {
+ case 0:
+ T = KDL::Rotation::RotX(-angle);
+ break;
+ case 1:
+ T = KDL::Rotation::RotY(-angle);
+ break;
+ case 2:
+ T = KDL::Rotation::RotZ(-angle);
+ break;
+ default:
+ return;
+ }
+ // remove angle
+ R = R*T;
+}
+
+#if 0
+static void GetEulerXZY(const KDL::Rotation& R, double& X,double& Z,double& Y)
+{
+ if (fabs(R(0,1)) > 1.0 - KDL::epsilon ) {
+ X = -KDL::sign(R(0,1)) * KDL::atan2(R(1,2), R(1,0));
+ Z = -KDL::sign(R(0,1)) * KDL::PI / 2;
+ Y = 0.0 ;
+ } else {
+ X = KDL::atan2(R(2,1), R(1,1));
+ Z = KDL::atan2(-R(0,1), KDL::sqrt( KDL::sqr(R(0,0)) + KDL::sqr(R(0,2))));
+ Y = KDL::atan2(R(0,2), R(0,0));
+ }
+}
+
+static void GetEulerXYZ(const KDL::Rotation& R, double& X,double& Y,double& Z)
+{
+ if (fabs(R(0,2)) > 1.0 - KDL::epsilon ) {
+ X = KDL::sign(R(0,2)) * KDL::atan2(-R(1,0), R(1,1));
+ Y = KDL::sign(R(0,2)) * KDL::PI / 2;
+ Z = 0.0 ;
+ } else {
+ X = KDL::atan2(-R(1,2), R(2,2));
+ Y = KDL::atan2(R(0,2), KDL::sqrt( KDL::sqr(R(0,0)) + KDL::sqr(R(0,1))));
+ Z = KDL::atan2(-R(0,1), R(0,0));
+ }
+}
+#endif
+
+static void GetJointRotation(KDL::Rotation& boneRot, int type, double* rot)
+{
+ switch (type & ~IK_TRANSY)
+ {
+ default:
+ // fixed bone, no joint
+ break;
+ case IK_XDOF:
+ // RX only, get the X rotation
+ rot[0] = EulerAngleFromMatrix(boneRot, 0);
+ break;
+ case IK_YDOF:
+ // RY only, get the Y rotation
+ rot[0] = ComputeTwist(boneRot);
+ break;
+ case IK_ZDOF:
+ // RZ only, get the Z rotation
+ rot[0] = EulerAngleFromMatrix(boneRot, 2);
+ break;
+ case IK_XDOF|IK_YDOF:
+ rot[1] = ComputeTwist(boneRot);
+ RemoveEulerAngleFromMatrix(boneRot, rot[1], 1);
+ rot[0] = EulerAngleFromMatrix(boneRot, 0);
+ break;
+ case IK_SWING:
+ // RX+RZ
+ boneRot.GetXZRot().GetValue(rot);
+ break;
+ case IK_YDOF|IK_ZDOF:
+ // RZ+RY
+ rot[1] = ComputeTwist(boneRot);
+ RemoveEulerAngleFromMatrix(boneRot, rot[1], 1);
+ rot[0] = EulerAngleFromMatrix(boneRot, 2);
+ break;
+ case IK_SWING|IK_YDOF:
+ rot[2] = ComputeTwist(boneRot);
+ RemoveEulerAngleFromMatrix(boneRot, rot[2], 1);
+ boneRot.GetXZRot().GetValue(rot);
+ break;
+ case IK_REVOLUTE:
+ boneRot.GetRot().GetValue(rot);
+ break;
+ }
+}
+
+static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
+{
+ IK_Target* target = (IK_Target*)param;
+ // compute next target position
+ // get target matrix from constraint.
+ bConstraint* constraint = (bConstraint*)target->blenderConstraint;
+ float tarmat[4][4];
+
+ get_constraint_target_matrix(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
+ // if the armature was in rest position. This information is available in eeRest
+ if (constraint->enforce != 1.0f && target->eeBlend) {
+ // eeRest is relative to the reference frame of the IK root
+ // get this frame in world reference
+ float restmat[4][4];
+ bPoseChannel* pchan = target->rootChannel;
+ if (pchan->parent) {
+ pchan = pchan->parent;
+ float chanmat[4][4];
+ Mat4CpyMat4(chanmat, pchan->pose_mat);
+ VECCOPY(chanmat[3], pchan->pose_tail);
+ Mat4MulSerie(restmat, target->owner->obmat, chanmat, target->eeRest, NULL, NULL, NULL, NULL, NULL);
+ }
+ else {
+ Mat4MulMat4(restmat, target->eeRest, target->owner->obmat);
+ }
+ // blend the target
+ Mat4BlendMat4(tarmat, restmat, tarmat, constraint->enforce);
+ }
+ next.setValue(&tarmat[0][0]);
+ return true;
+}
+
+static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
+{
+ IK_Scene* ikscene = (IK_Scene*)param;
+ // compute next armature base pose
+ // algorithm:
+ // ikscene->pchan[0] is the root channel of the tree
+ // if it has a parent, get the pose matrix from it and replace [3] by parent pchan->tail
+ // then multiply by the armature matrix to get ikscene->armature base position
+ bPoseChannel* pchan = ikscene->channels[0].pchan;
+ float rootmat[4][4];
+ if (pchan->parent) {
+ pchan = pchan->parent;
+ float chanmat[4][4];
+ Mat4CpyMat4(chanmat, pchan->pose_mat);
+ VECCOPY(chanmat[3], pchan->pose_tail);
+ // save the base as a frame too so that we can compute deformation
+ // after simulation
+ ikscene->baseFrame.setValue(&chanmat[0][0]);
+ Mat4MulMat4(rootmat, chanmat, ikscene->blArmature->obmat);
+ }
+ else {
+ Mat4CpyMat4(rootmat, ikscene->blArmature->obmat);
+ ikscene->baseFrame = iTaSC::F_identity;
+ }
+ next.setValue(&rootmat[0][0]);
+ // if there is a polar target (only during solving otherwise we don't have end efffector)
+ if (ikscene->polarConstraint && timestamp.update) {
+ // compute additional rotation of base frame so that armature follows the polar target
+ float imat[4][4]; // IK tree base inverse matrix
+ float polemat[4][4]; // polar target in IK tree base frame
+ float goalmat[4][4]; // target in IK tree base frame
+ float mat[4][4]; // temp matrix
+ bKinematicConstraint* poledata = (bKinematicConstraint*)ikscene->polarConstraint->data;
+
+ Mat4Invert(imat, rootmat);
+ // polar constraint imply only one target
+ IK_Target *iktarget = ikscene->targets[0];
+ // root channel from which we take the bone initial orientation
+ IK_Channel &rootchan = ikscene->channels[0];
+
+ // get polar target matrix in world space
+ get_constraint_target_matrix(ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
+ // convert to armature space
+ Mat4MulMat4(polemat, mat, imat);
+ // get the target in world space (was computed before as target object are defined before base object)
+ iktarget->target->getPose().getValue(mat[0]);
+ // convert to armature space
+ Mat4MulMat4(goalmat, mat, imat);
+ // take position of target, polar target, end effector, in armature space
+ KDL::Vector goalpos(goalmat[3]);
+ KDL::Vector polepos(polemat[3]);
+ KDL::Vector endpos = ikscene->armature->getPose(iktarget->ee).p;
+ // get root bone orientation
+ KDL::Frame rootframe;
+ ikscene->armature->getRelativeFrame(rootframe, rootchan.tail);
+ KDL::Vector rootx = rootframe.M.UnitX();
+ KDL::Vector rootz = rootframe.M.UnitZ();
+ // and compute root bone head
+ double q_rest[3], q[3], length;
+ const KDL::Joint* joint;
+ const KDL::Frame* tip;
+ ikscene->armature->getSegment(rootchan.tail, 3, joint, q_rest[0], q[0], tip);
+ length = (joint->getType() == KDL::Joint::TransY) ? q[0] : tip->p(1);
+ KDL::Vector rootpos = rootframe.p - length*rootframe.M.UnitY();
+
+ // compute main directions
+ KDL::Vector dir = KDL::Normalize(endpos - rootpos);
+ KDL::Vector poledir = KDL::Normalize(goalpos-rootpos);
+ // compute up directions
+ KDL::Vector poleup = KDL::Normalize(polepos-rootpos);
+ KDL::Vector up = rootx*KDL::cos(poledata->poleangle) + rootz*KDL::sin(poledata->poleangle);
+ // from which we build rotation matrix
+ KDL::Rotation endrot, polerot;
+ // for the armature, using the root bone orientation
+ KDL::Vector x = KDL::Normalize(dir*up);
+ endrot.UnitX(x);
+ endrot.UnitY(KDL::Normalize(x*dir));
+ endrot.UnitZ(-dir);
+ // for the polar target
+ x = KDL::Normalize(poledir*poleup);
+ polerot.UnitX(x);
+ polerot.UnitY(KDL::Normalize(x*poledir));
+ polerot.UnitZ(-poledir);
+ // the difference between the two is the rotation we want to apply
+ KDL::Rotation result(polerot*endrot.Inverse());
+ // apply on base frame as this is an artificial additional rotation
+ next.M = next.M*result;
+ ikscene->baseFrame.M = ikscene->baseFrame.M*result;
+ }
+ return true;
+}
+
+static bool copypose_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintValues* const _values, unsigned int _nvalues, void* _param)
+{
+ IK_Target* iktarget =(IK_Target*)_param;
+ bKinematicConstraint *condata = (bKinematicConstraint *)iktarget->blenderConstraint->data;
+ iTaSC::ConstraintValues* values = _values;
+ bItasc* ikparam = (bItasc*) iktarget->owner->pose->ikparam;
+
+ // we need default parameters
+ if (!ikparam)
+ ikparam = &DefIKParam;
+
+ if (iktarget->blenderConstraint->flag & CONSTRAINT_OFF) {
+ if (iktarget->controlType & iTaSC::CopyPose::CTL_POSITION) {
+ values->alpha = 0.0;
+ values->action = iTaSC::ACT_ALPHA;
+ values++;
+ }
+ if (iktarget->controlType & iTaSC::CopyPose::CTL_ROTATION) {
+ values->alpha = 0.0;
+ values->action = iTaSC::ACT_ALPHA;
+ values++;
+ }
+ } else {
+ if (iktarget->controlType & iTaSC::CopyPose::CTL_POSITION) {
+ // update error
+ values->alpha = condata->weight;
+ values->action = iTaSC::ACT_ALPHA|iTaSC::ACT_FEEDBACK;
+ values->feedback = (iktarget->simulation) ? ikparam->feedback : ANIM_FEEDBACK;
+ values++;
+ }
+ if (iktarget->controlType & iTaSC::CopyPose::CTL_ROTATION) {
+ // update error
+ values->alpha = condata->orientweight;
+ values->action = iTaSC::ACT_ALPHA|iTaSC::ACT_FEEDBACK;
+ values->feedback = (iktarget->simulation) ? ikparam->feedback : ANIM_FEEDBACK;
+ values++;
+ }
+ }
+ return true;
+}
+
+static void copypose_error(const iTaSC::ConstraintValues* values, unsigned int nvalues, IK_Target* iktarget)
+{
+ iTaSC::ConstraintSingleValue* value;
+ double error;
+ int i;
+
+ if (iktarget->controlType & iTaSC::CopyPose::CTL_POSITION) {
+ // update error
+ for (i=0, error=0.0, value=values->values; i<values->number; ++i, ++value)
+ error += KDL::sqr(value->y - value->yd);
+ iktarget->blenderConstraint->lin_error = (float)KDL::sqrt(error);
+ values++;
+ }
+ if (iktarget->controlType & iTaSC::CopyPose::CTL_ROTATION) {
+ // update error
+ for (i=0, error=0.0, value=values->values; i<values->number; ++i, ++value)
+ error += KDL::sqr(value->y - value->yd);
+ iktarget->blenderConstraint->rot_error = (float)KDL::sqrt(error);
+ values++;
+ }
+}
+
+static bool distance_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintValues* const _values, unsigned int _nvalues, void* _param)
+{
+ IK_Target* iktarget =(IK_Target*)_param;
+ bKinematicConstraint *condata = (bKinematicConstraint *)iktarget->blenderConstraint->data;
+ iTaSC::ConstraintValues* values = _values;
+ bItasc* ikparam = (bItasc*) iktarget->owner->pose->ikparam;
+ // we need default parameters
+ if (!ikparam)
+ ikparam = &DefIKParam;
+
+ // update weight according to mode
+ if (iktarget->blenderConstraint->flag & CONSTRAINT_OFF) {
+ values->alpha = 0.0;
+ } else {
+ switch (condata->mode) {
+ case LIMITDIST_INSIDE:
+ values->alpha = (values->values[0].y > condata->dist) ? condata->weight : 0.0;
+ break;
+ case LIMITDIST_OUTSIDE:
+ values->alpha = (values->values[0].y < condata->dist) ? condata->weight : 0.0;
+ break;
+ default:
+ values->alpha = condata->weight;
+ break;
+ }
+ if (!timestamp.substep) {
+ // only update value on first timestep
+ switch (condata->mode) {
+ case LIMITDIST_INSIDE:
+ values->values[0].yd = condata->dist*0.95;
+ break;
+ case LIMITDIST_OUTSIDE:
+ values->values[0].yd = condata->dist*1.05;
+ break;
+ default:
+ values->values[0].yd = condata->dist;
+ break;
+ }
+ values->values[0].action = iTaSC::ACT_VALUE|iTaSC::ACT_FEEDBACK;
+ values->feedback = (iktarget->simulation) ? ikparam->feedback : ANIM_FEEDBACK;
+ }
+ }
+ values->action |= iTaSC::ACT_ALPHA;
+ return true;
+}
+
+static void distance_error(const iTaSC::ConstraintValues* values, unsigned int _nvalues, IK_Target* iktarget)
+{
+ iktarget->blenderConstraint->lin_error = (float)(values->values[0].y - values->values[0].yd);
+}
+
+static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintValues* const _values, unsigned int _nvalues, void* _param)
+{
+ IK_Channel* ikchan = (IK_Channel*)_param;
+ bItasc* ikparam = (bItasc*)ikchan->owner->pose->ikparam;
+ bPoseChannel* chan = ikchan->pchan;
+ int dof;
+
+ // a channel can be splitted into multiple joints, so we get called multiple
+ // times for one channel (this callback is only for 1 joint in the armature)
+ // the IK_JointTarget structure is shared between multiple joint constraint
+ // and the target joint values is computed only once, remember this in jointValid
+ // Don't forget to reset it before each frame
+ if (!ikchan->jointValid) {
+ float rmat[3][3];
+
+ if (chan->rotmode > 0) {
+ /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
+ EulOToMat3(chan->eul, chan->rotmode, rmat);
+ }
+ else if (chan->rotmode == ROT_MODE_AXISANGLE) {
+ /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
+ AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat);
+ }
+ else {
+ /* quats are normalised before use to eliminate scaling issues */
+ NormalQuat(chan->quat);
+ QuatToMat3(chan->quat, rmat);
+ }
+ KDL::Rotation jointRot(
+ rmat[0][0], rmat[1][0], rmat[2][0],
+ rmat[0][1], rmat[1][1], rmat[2][1],
+ rmat[0][2], rmat[1][2], rmat[2][2]);
+ GetJointRotation(jointRot, ikchan->jointType, ikchan->jointValue);
+ ikchan->jointValid = 1;
+ }
+ // determine which part of jointValue is used for this joint
+ // closely related to the way the joints are defined
+ switch (ikchan->jointType & ~IK_TRANSY)
+ {
+ case IK_XDOF:
+ case IK_YDOF:
+ case IK_ZDOF:
+ dof = 0;
+ break;
+ case IK_XDOF|IK_YDOF:
+ // X + Y
+ dof = (_values[0].id == iTaSC::Armature::ID_JOINT_RX) ? 0 : 1;
+ break;
+ case IK_SWING:
+ // XZ
+ dof = 0;
+ break;
+ case IK_YDOF|IK_ZDOF:
+ // Z + Y
+ dof = (_values[0].id == iTaSC::Armature::ID_JOINT_RZ) ? 0 : 1;
+ break;
+ case IK_SWING|IK_YDOF:
+ // XZ + Y
+ dof = (_values[0].id == iTaSC::Armature::ID_JOINT_RY) ? 2 : 0;
+ break;
+ case IK_REVOLUTE:
+ dof = 0;
+ break;
+ default:
+ dof = -1;
+ break;
+ }
+ if (dof >= 0) {
+ for (unsigned int i=0; i<_nvalues; i++, dof++) {
+ _values[i].values[0].yd = ikchan->jointValue[dof];
+ _values[i].alpha = chan->ikrotweight;
+ _values[i].feedback = ikparam->feedback;
+ }
+ }
+ return true;
+}
+
+// build array of joint corresponding to IK chain
+static int convert_channels(IK_Scene *ikscene, PoseTree *tree)
+{
+ IK_Channel *ikchan;
+ bPoseChannel *pchan;
+ Bone *bone;
+ int a, flag, njoint;
+
+ njoint = 0;
+ for(a=0, ikchan = ikscene->channels; a<ikscene->numchan; ++a, ++ikchan) {
+ pchan= tree->pchan[a];
+ bone= pchan->bone;
+ ikchan->pchan = pchan;
+ ikchan->parent = (a>0) ? tree->parent[a] : -1;
+ ikchan->owner = ikscene->blArmature;
+
+ /* set DoF flag */
+ flag = 0;
+ if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP) &&
+ (!(pchan->ikflag & BONE_IK_XLIMIT) || pchan->limitmin[0]<0.f || pchan->limitmax[0]>0.f))
+ flag |= IK_XDOF;
+ if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP) &&
+ (!(pchan->ikflag & BONE_IK_YLIMIT) || pchan->limitmin[1]<0.f || pchan->limitmax[1]>0.f))
+ flag |= IK_YDOF;
+ if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP) &&
+ (!(pchan->ikflag & BONE_IK_ZLIMIT) || pchan->limitmin[2]<0.f || pchan->limitmax[2]>0.f))
+ flag |= IK_ZDOF;
+
+ if(tree->stretch && (pchan->ikstretch > 0.0)) {
+ flag |= IK_TRANSY;
+ }
+ /*
+ Logic to create the segments:
+ RX,RY,RZ = rotational joints with no length
+ RY(tip) = rotational joints with a fixed length arm = (0,length,0)
+ TY = translational joint on Y axis
+ F(pos) = fixed joint with an arm at position pos
+ Conversion rule of the above flags:
+ - ==> F(tip)
+ X ==> RX(tip)
+ Y ==> RY(tip)
+ Z ==> RZ(tip)
+ XY ==> RX+RY(tip)
+ XZ ==> RX+RZ(tip)
+ YZ ==> RZ+RY(tip)
+ XYZ ==> full spherical unless there are limits, in which case RX+RZ+RY(tip)
+ In case of stretch, tip=(0,0,0) and there is an additional TY joint
+ The frame at last of these joints represents the tail of the bone.
+ The head is computed by a reverse translation on Y axis of the bone length
+ or in case of TY joint, by the frame at previous joint.
+ In case of separation of bones, there is an additional F(head) joint
+
+ Computing rest pose and length is complicated: the solver works in world space
+ Here is the logic:
+ rest position is computed only from bone->bone_mat.
+ bone length is computed from bone->length multiplied by the scaling factor of
+ the armature. Non-uniform scaling will give bad result!
+
+ */
+ switch (flag & (IK_XDOF|IK_YDOF|IK_ZDOF))
+ {
+ default:
+ ikchan->jointType = 0;
+ ikchan->ndof = 0;
+ break;
+ case IK_XDOF:
+ // RX only, get the X rotation
+ ikchan->jointType = IK_XDOF;
+ ikchan->ndof = 1;
+ break;
+ case IK_YDOF:
+ // RY only, get the Y rotation
+ ikchan->jointType = IK_YDOF;
+ ikchan->ndof = 1;
+ break;
+ case IK_ZDOF:
+ // RZ only, get the Zz rotation
+ ikchan->jointType = IK_ZDOF;
+ ikchan->ndof = 1;
+ break;
+ case IK_XDOF|IK_YDOF:
+ ikchan->jointType = IK_XDOF|IK_YDOF;
+ ikchan->ndof = 2;
+ break;
+ case IK_XDOF|IK_ZDOF:
+ // RX+RZ
+ ikchan->jointType = IK_SWING;
+ ikchan->ndof = 2;
+ break;
+ case IK_YDOF|IK_ZDOF:
+ // RZ+RY
+ ikchan->jointType = IK_ZDOF|IK_YDOF;
+ ikchan->ndof = 2;
+ break;
+ case IK_XDOF|IK_YDOF|IK_ZDOF:
+ // spherical joint
+ if (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_YLIMIT|BONE_IK_ZLIMIT))
+ // decompose in a Swing+RotY joint
+ ikchan->jointType = IK_SWING|IK_YDOF;
+ else
+ ikchan->jointType = IK_REVOLUTE;
+ ikchan->ndof = 3;
+ break;
+ }
+ if (flag & IK_TRANSY) {
+ ikchan->jointType |= IK_TRANSY;
+ ikchan->ndof++;
+ }
+ njoint += ikchan->ndof;
+ }
+ // njoint is the joint coordinate, create the Joint Array
+ ikscene->jointArray.resize(njoint);
+ ikscene->numjoint = njoint;
+ return njoint;
+}
+
+// compute array of joint value corresponding to current pose
+static void convert_pose(IK_Scene *ikscene)
+{
+ KDL::Rotation boneRot;
+ bPoseChannel *pchan;
+ IK_Channel *ikchan;
+ Bone *bone;
+ float rmat[4][4]; // rest pose of bone with parent taken into account
+ float bmat[4][4]; // difference
+ float scale;
+ double *rot;
+ int a, joint;
+
+ // assume uniform scaling and take Y scale as general scale for the armature
+ scale = VecLength(ikscene->blArmature->obmat[1]);
+ rot = &ikscene->jointArray(0);
+ for(joint=a=0, ikchan = ikscene->channels; a<ikscene->numchan && joint<ikscene->numjoint; ++a, ++ikchan) {
+ pchan= ikchan->pchan;
+ bone= pchan->bone;
+
+ if (pchan->parent) {
+ Mat4One(bmat);
+ Mat4MulMat43(bmat, pchan->parent->pose_mat, bone->bone_mat);
+ } else {
+ Mat4CpyMat4(bmat, bone->arm_mat);
+ }
+ Mat4Invert(rmat, bmat);
+ Mat4MulMat4(bmat, pchan->pose_mat, rmat);
+ Mat4Ortho(bmat);
+ boneRot.setValue(bmat[0]);
+ GetJointRotation(boneRot, ikchan->jointType, rot);
+ if (ikchan->jointType & IK_TRANSY) {
+ // compute actual length
+ rot[ikchan->ndof-1] = VecLenf(pchan->pose_tail, pchan->pose_head) * scale;
+ }
+ rot += ikchan->ndof;
+ joint += ikchan->ndof;
+ }
+}
+
+// compute array of joint value corresponding to current pose
+static void rest_pose(IK_Scene *ikscene)
+{
+ bPoseChannel *pchan;
+ IK_Channel *ikchan;
+ Bone *bone;
+ float scale;
+ double *rot;
+ int a, joint;
+
+ // assume uniform scaling and take Y scale as general scale for the armature
+ scale = VecLength(ikscene->blArmature->obmat[1]);
+ // rest pose is 0
+ KDL::SetToZero(ikscene->jointArray);
+ // except for transY joints
+ rot = &ikscene->jointArray(0);
+ for(joint=a=0, ikchan = ikscene->channels; a<ikscene->numchan && joint<ikscene->numjoint; ++a, ++ikchan) {
+ pchan= ikchan->pchan;
+ bone= pchan->bone;
+
+ if (ikchan->jointType & IK_TRANSY)
+ rot[ikchan->ndof-1] = bone->length*scale;
+ rot += ikchan->ndof;
+ joint += ikchan->ndof;
+ }
+}
+
+static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
+{
+ PoseTree *tree = (PoseTree*)pchan->iktree.first;
+ PoseTarget *target;
+ bKinematicConstraint *condata;
+ bConstraint *polarcon;
+ bItasc *ikparam;
+ iTaSC::Armature* arm;
+ iTaSC::Scene* scene;
+ IK_Scene* ikscene;
+ IK_Channel* ikchan;
+ KDL::Frame initPose;
+ KDL::Rotation boneRot;
+ Bone *bone;
+ int a, numtarget;
+ unsigned int t;
+ float length;
+ bool ret = true, ingame;
+ double *rot;
+
+ if (tree->totchannel == 0)
+ return NULL;
+
+ ikscene = new IK_Scene;
+ arm = new iTaSC::Armature();
+ scene = new iTaSC::Scene();
+ ikscene->channels = new IK_Channel[tree->totchannel];
+ ikscene->numchan = tree->totchannel;
+ ikscene->armature = arm;
+ ikscene->scene = scene;
+ ikparam = (bItasc*)ob->pose->ikparam;
+ ingame = (ob->pose->flag & POSE_GAME_ENGINE);
+ if (!ikparam) {
+ // you must have our own copy
+ ikparam = &DefIKParam;
+ } else if (ingame) {
+ // tweak the param when in game to have efficient stepping
+ // using fixed substep is not effecient since frames in the GE are often
+ // shorter than in animation => move to auto step automatically and set
+ // the target substep duration via min/max
+ if (!(ikparam->flag & ITASC_AUTO_STEP)) {
+ float timestep = blscene->r.frs_sec_base/blscene->r.frs_sec;
+ if (ikparam->numstep > 0)
+ timestep /= ikparam->numstep;
+ // with equal min and max, the algorythm will take this step and the indicative substep most of the time
+ ikparam->minstep = ikparam->maxstep = timestep;
+ ikparam->flag |= ITASC_AUTO_STEP;
+ }
+ }
+ if ((ikparam->flag & ITASC_SIMULATION) && !ingame)
+ // no cache in animation mode
+ ikscene->cache = new iTaSC::Cache();
+
+ switch (ikparam->solver) {
+ case ITASC_SOLVER_SDLS:
+ ikscene->solver = new iTaSC::WSDLSSolver();
+ break;
+ case ITASC_SOLVER_DLS:
+ ikscene->solver = new iTaSC::WDLSSolver();
+ break;
+ default:
+ delete ikscene;
+ return NULL;
+ }
+ ikscene->blArmature = ob;
+
+ std::string joint;
+ std::string root("root");
+ std::string parent;
+ std::vector<double> weights;
+ double weight[3];
+ // assume uniform scaling and take Y scale as general scale for the armature
+ float scale = VecLength(ob->obmat[1]);
+ // build the array of joints corresponding to the IK chain
+ convert_channels(ikscene, tree);
+ if (ingame) {
+ // in the GE, set the initial joint angle to match the current pose
+ // this will update the jointArray in ikscene
+ convert_pose(ikscene);
+ } else {
+ // in Blender, the rest pose is always 0 for joints
+ rest_pose(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);
+ Vector3 *fl = bone->bone_mat;
+ KDL::Frame head(KDL::Rotation(
+ 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(bone->head[0], bone->head[1], bone->head[2])*scale);
+
+ // rest pose length of the bone taking scaling into account
+ length= bone->length*scale;
+ 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) {
+ joint = bone->name;
+ joint += ":H";
+ ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, head);
+ parent = joint;
+ }
+ if (!(ikchan->jointType & IK_TRANSY)) {
+ // fixed length, put it in tip
+ tip.p[1] = length;
+ }
+ joint = bone->name;
+ weight[0] = (1.0-pchan->stiffness[0]);
+ weight[1] = (1.0-pchan->stiffness[1]);
+ weight[2] = (1.0-pchan->stiffness[2]);
+ switch (ikchan->jointType & ~IK_TRANSY)
+ {
+ case 0:
+ // fixed bone
+ if (!(ikchan->jointType & IK_TRANSY)) {
+ joint += ":F";
+ ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, tip);
+ }
+ break;
+ case IK_XDOF:
+ // RX only, get the X rotation
+ joint += ":RX";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotX, rot[0], tip);
+ weights.push_back(weight[0]);
+ break;
+ case IK_YDOF:
+ // RY only, get the Y rotation
+ joint += ":RY";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotY, rot[0], tip);
+ weights.push_back(weight[1]);
+ break;
+ case IK_ZDOF:
+ // RZ only, get the Zz rotation
+ joint += ":RZ";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotZ, rot[0], tip);
+ weights.push_back(weight[2]);
+ break;
+ case IK_XDOF|IK_YDOF:
+ joint += ":RX";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotX, rot[0]);
+ weights.push_back(weight[0]);
+ if (ret) {
+ parent = joint;
+ joint = bone->name;
+ joint += ":RY";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotY, rot[1], tip);
+ weights.push_back(weight[1]);
+ }
+ break;
+ case IK_SWING:
+ joint += ":SW";
+ ret = arm->addSegment(joint, parent, KDL::Joint::Swing, rot[0], tip);
+ weights.push_back(weight[0]);
+ weights.push_back(weight[2]);
+ break;
+ case IK_YDOF|IK_ZDOF:
+ // RZ+RY
+ joint += ":RZ";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotZ, rot[0]);
+ weights.push_back(weight[2]);
+ if (ret) {
+ parent = joint;
+ joint = bone->name;
+ joint += ":RY";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotY, rot[1], tip);
+ weights.push_back(weight[1]);
+ }
+ break;
+ case IK_SWING|IK_YDOF:
+ // decompose in a Swing+RotY joint
+ joint += ":SW";
+ ret = arm->addSegment(joint, parent, KDL::Joint::Swing, rot[0]);
+ weights.push_back(weight[0]);
+ weights.push_back(weight[2]);
+ if (ret) {
+ parent = joint;
+ joint = bone->name;
+ joint += ":RY";
+ ret = arm->addSegment(joint, parent, KDL::Joint::RotY, rot[2], tip);
+ weights.push_back(weight[1]);
+ }
+ break;
+ case IK_REVOLUTE:
+ joint += ":SJ";
+ ret = arm->addSegment(joint, parent, KDL::Joint::Sphere, rot[0], tip);
+ weights.push_back(weight[0]);
+ weights.push_back(weight[1]);
+ weights.push_back(weight[2]);
+ break;
+ }
+ if (ret && (ikchan->jointType & IK_TRANSY)) {
+ parent = joint;
+ joint = bone->name;
+ joint += ":TY";
+ ret = arm->addSegment(joint, parent, KDL::Joint::TransY, rot[ikchan->ndof-1]);
+ float ikstretch = pchan->ikstretch*pchan->ikstretch;
+ weight[1] = (1.0-MIN2(1.0-ikstretch, 0.99));
+ weights.push_back(weight[1]);
+ }
+ if (!ret)
+ // error making the armature??
+ break;
+ // joint points to the segment that correspond to the bone per say
+ ikchan->tail = joint;
+ ikchan->head = parent;
+ // in case of error
+ ret = false;
+ if ((ikchan->jointType & IK_XDOF) && (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ROTCTL))) {
+ joint = bone->name;
+ joint += ":RX";
+ if (pchan->ikflag & BONE_IK_XLIMIT) {
+ if (arm->addLimitConstraint(joint, 0, pchan->limitmin[0], pchan->limitmax[0]) < 0)
+ break;
+ }
+ if (pchan->ikflag & BONE_IK_ROTCTL) {
+ if (arm->addConstraint(joint, joint_callback, ikchan, false, false) < 0)
+ break;
+ }
+ }
+ if ((ikchan->jointType & IK_YDOF) && (pchan->ikflag & (BONE_IK_YLIMIT|BONE_IK_ROTCTL))) {
+ joint = bone->name;
+ joint += ":RY";
+ if (pchan->ikflag & BONE_IK_YLIMIT) {
+ if (arm->addLimitConstraint(joint, 0, pchan->limitmin[1], pchan->limitmax[1]) < 0)
+ break;
+ }
+ if (pchan->ikflag & BONE_IK_ROTCTL) {
+ if (arm->addConstraint(joint, joint_callback, ikchan, false, false) < 0)
+ break;
+ }
+ }
+ if ((ikchan->jointType & IK_ZDOF) && (pchan->ikflag & (BONE_IK_ZLIMIT|BONE_IK_ROTCTL))) {
+ joint = bone->name;
+ joint += ":RZ";
+ if (pchan->ikflag & BONE_IK_ZLIMIT) {
+ if (arm->addLimitConstraint(joint, 0, pchan->limitmin[2], pchan->limitmax[2]) < 0)
+ break;
+ }
+ if (pchan->ikflag & BONE_IK_ROTCTL) {
+ if (arm->addConstraint(joint, joint_callback, ikchan, false, false) < 0)
+ break;
+ }
+ }
+ if ((ikchan->jointType & IK_SWING) && (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT|BONE_IK_ROTCTL))) {
+ joint = bone->name;
+ joint += ":SW";
+ if (pchan->ikflag & BONE_IK_XLIMIT) {
+ if (arm->addLimitConstraint(joint, 0, pchan->limitmin[0], pchan->limitmax[0]) < 0)
+ break;
+ }
+ if (pchan->ikflag & BONE_IK_ZLIMIT) {
+ if (arm->addLimitConstraint(joint, 1, pchan->limitmin[2], pchan->limitmax[2]) < 0)
+ break;
+ }
+ if (pchan->ikflag & BONE_IK_ROTCTL) {
+ if (arm->addConstraint(joint, joint_callback, ikchan, false, false) < 0)
+ break;
+ }
+ }
+ if ((ikchan->jointType & IK_REVOLUTE) && (pchan->ikflag & BONE_IK_ROTCTL)) {
+ joint = bone->name;
+ joint += ":SJ";
+ if (arm->addConstraint(joint, joint_callback, ikchan, false, false) < 0)
+ break;
+ }
+ // no error, so restore
+ ret = true;
+ rot += ikchan->ndof;
+ }
+ if (!ret) {
+ delete ikscene;
+ return NULL;
+ }
+ // for each target, we need to add an end effector in the armature
+ for (numtarget=0, polarcon=NULL, ret = true, target=(PoseTarget*)tree->targets.first; target; target=(PoseTarget*)target->next) {
+ condata= (bKinematicConstraint*)target->con->data;
+ pchan = tree->pchan[target->tip];
+
+ if (is_cartesian_constraint(target->con)) {
+ // add the end effector
+ IK_Target* iktarget = new IK_Target();
+ ikscene->targets.push_back(iktarget);
+ iktarget->ee = arm->addEndEffector(ikscene->channels[target->tip].tail);
+ if (iktarget->ee == -1) {
+ ret = false;
+ break;
+ }
+ // initialize all the fields that we can set at this time
+ iktarget->blenderConstraint = target->con;
+ iktarget->channel = target->tip;
+ iktarget->simulation = (ikparam->flag & ITASC_SIMULATION);
+ iktarget->rootChannel = ikscene->channels[0].pchan;
+ iktarget->owner = ob;
+ iktarget->targetName = pchan->bone->name;
+ iktarget->targetName += ":T:";
+ iktarget->targetName += target->con->name;
+ iktarget->constraintName = pchan->bone->name;
+ iktarget->constraintName += ":C:";
+ iktarget->constraintName += target->con->name;
+ numtarget++;
+ if (condata->poletar)
+ // this constraint has a polar target
+ polarcon = target->con;
+ }
+ }
+ // deal with polar target if any
+ if (numtarget == 1 && polarcon) {
+ ikscene->polarConstraint = polarcon;
+ }
+ // we can now add the armature
+ // the armature is based on a moving frame.
+ // initialize with the correct position in case there is no cache
+ base_callback(iTaSC::Timestamp(), iTaSC::F_identity, initPose, ikscene);
+ ikscene->base = new iTaSC::MovingFrame(initPose);
+ ikscene->base->setCallback(base_callback, ikscene);
+ std::string armname;
+ armname = ob->id.name;
+ armname += ":B";
+ ret = scene->addObject(armname, ikscene->base);
+ armname = ob->id.name;
+ armname += ":AR";
+ if (ret)
+ ret = scene->addObject(armname, ikscene->armature, ikscene->base);
+ if (!ret) {
+ delete ikscene;
+ return NULL;
+ }
+ // set the weight
+ e_matrix& Wq = arm->getWq();
+ assert(Wq.cols() == (int)weights.size());
+ for (int q=0; q<Wq.cols(); q++)
+ Wq(q,q)=weights[q];
+ // get the inverse rest pose frame of the base to compute relative rest pose of end effectors
+ // this is needed to handle the enforce parameter
+ // ikscene->pchan[0] is the root channel of the tree
+ // if it has no parent, then it's just the identify Frame
+ float invBaseFrame[4][4];
+ pchan = ikscene->channels[0].pchan;
+ if (pchan->parent) {
+ // it has a parent, get the pose matrix from it
+ float baseFrame[4][4];
+ pchan = pchan->parent;
+ Mat4CpyMat4(baseFrame, pchan->bone->arm_mat);
+ // move to the tail and scale to get rest pose of armature base
+ VecCopyf(baseFrame[3], pchan->bone->arm_tail);
+ Mat4Invert(invBaseFrame, baseFrame);
+ } else {
+ Mat4One(invBaseFrame);
+ }
+ // finally add the constraint
+ for (t=0; t<ikscene->targets.size(); t++) {
+ IK_Target* iktarget = ikscene->targets[t];
+ condata= (bKinematicConstraint*)iktarget->blenderConstraint->data;
+ pchan = tree->pchan[iktarget->channel];
+ unsigned int controltype, bonecnt;
+ double bonelen;
+ float mat[4][4];
+
+ // add the end effector
+ // estimate the average bone length, used to clamp feedback error
+ for (bonecnt=0, bonelen=0.f, a=iktarget->channel; a>=0; a=tree->parent[a], bonecnt++)
+ bonelen += scale*tree->pchan[a]->bone->length;
+ bonelen /= bonecnt;
+
+ // store the rest pose of the end effector to compute enforce target
+ Mat4CpyMat4(mat, pchan->bone->arm_mat);
+ VecCopyf(mat[3], pchan->bone->arm_tail);
+ // get the rest pose relative to the armature base
+ Mat4MulMat4(iktarget->eeRest, mat, invBaseFrame);
+ iktarget->eeBlend = (!ikscene->polarConstraint && condata->type==CONSTRAINT_IK_COPYPOSE) ? true : false;
+ // use target_callback to make sure the initPose includes enforce coefficient
+ target_callback(iTaSC::Timestamp(), iTaSC::F_identity, initPose, iktarget);
+ iktarget->target = new iTaSC::MovingFrame(initPose);
+ iktarget->target->setCallback(target_callback, iktarget);
+ ret = scene->addObject(iktarget->targetName, iktarget->target);
+ if (!ret)
+ break;
+
+ switch (condata->type) {
+ case CONSTRAINT_IK_COPYPOSE:
+ controltype = 0;
+ if ((condata->flag & CONSTRAINT_IK_ROT) && (condata->orientweight != 0.0))
+ controltype |= iTaSC::CopyPose::CTL_ROTATION;
+ if ((condata->weight != 0.0))
+ controltype |= iTaSC::CopyPose::CTL_POSITION;
+ if (controltype) {
+ iktarget->constraint = new iTaSC::CopyPose(controltype, controltype, bonelen);
+ // set the gain
+ if (controltype & iTaSC::CopyPose::CTL_POSITION)
+ iktarget->constraint->setControlParameter(iTaSC::CopyPose::ID_POSITION, iTaSC::ACT_ALPHA, condata->weight);
+ if (controltype & iTaSC::CopyPose::CTL_ROTATION)
+ iktarget->constraint->setControlParameter(iTaSC::CopyPose::ID_ROTATION, iTaSC::ACT_ALPHA, condata->orientweight);
+ iktarget->constraint->registerCallback(copypose_callback, iktarget);
+ iktarget->errorCallback = copypose_error;
+ iktarget->controlType = controltype;
+ // add the constraint
+ ret = scene->addConstraintSet(iktarget->constraintName, iktarget->constraint, armname, iktarget->targetName, ikscene->channels[iktarget->channel].tail);
+ }
+ break;
+ case CONSTRAINT_IK_DISTANCE:
+ iktarget->constraint = new iTaSC::Distance(bonelen);
+ iktarget->constraint->setControlParameter(iTaSC::Distance::ID_DISTANCE, iTaSC::ACT_VALUE, condata->dist);
+ iktarget->constraint->registerCallback(distance_callback, iktarget);
+ iktarget->errorCallback = distance_error;
+ // we can update the weight on each substep
+ iktarget->constraint->substep(true);
+ // add the constraint
+ ret = scene->addConstraintSet(iktarget->constraintName, iktarget->constraint, armname, iktarget->targetName, ikscene->channels[iktarget->channel].tail);
+ break;
+ }
+ if (!ret)
+ break;
+ }
+ if (!ret ||
+ !scene->addCache(ikscene->cache) ||
+ !scene->addSolver(ikscene->solver) ||
+ !scene->initialize()) {
+ delete ikscene;
+ ikscene = NULL;
+ }
+ return ikscene;
+}
+
+static void create_scene(Scene *scene, Object *ob)
+{
+ bPoseChannel *pchan;
+
+ // create the IK scene
+ for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= (bPoseChannel *)pchan->next) {
+ // by construction there is only one tree
+ PoseTree *tree = (PoseTree*)pchan->iktree.first;
+ if (tree) {
+ IK_Data* ikdata = get_ikdata(ob->pose);
+ // convert tree in iTaSC::Scene
+ IK_Scene* ikscene = convert_tree(scene, ob, pchan);
+ if (ikscene) {
+ ikscene->next = ikdata->first;
+ ikdata->first = ikscene;
+ }
+ // delete the trees once we are done
+ while(tree) {
+ BLI_remlink(&pchan->iktree, tree);
+ BLI_freelistN(&tree->targets);
+ if(tree->pchan) MEM_freeN(tree->pchan);
+ if(tree->parent) MEM_freeN(tree->parent);
+ if(tree->basis_change) MEM_freeN(tree->basis_change);
+ MEM_freeN(tree);
+ tree = (PoseTree*)pchan->iktree.first;
+ }
+ }
+ }
+}
+
+static void init_scene(Object *ob)
+{
+ if (ob->pose->ikdata) {
+ for(IK_Scene* scene = ((IK_Data*)ob->pose->ikdata)->first;
+ scene != NULL;
+ scene = scene->next) {
+ scene->channels[0].pchan->flag |= POSE_IKTREE;
+ }
+ }
+}
+
+static void execute_scene(Scene* blscene, IK_Scene* ikscene, bItasc* ikparam, float ctime, float frtime)
+{
+ int i;
+ IK_Channel* ikchan;
+ if (ikparam->flag & ITASC_SIMULATION) {
+ for (i=0, ikchan=ikscene->channels; i<ikscene->numchan; i++, ++ikchan) {
+ // In simulation mode we don't allow external contraint to change our bones, mark the channel done
+ // also tell Blender that this channel is part of IK tree (cleared on each where_is_pose()
+ ikchan->pchan->flag |= (POSE_DONE|POSE_CHAIN);
+ ikchan->jointValid = 0;
+ }
+ } else {
+ // in animation mode, we must get the bone position from action and constraints
+ for(i=0, ikchan=ikscene->channels; i<ikscene->numchan; i++, ++ikchan) {
+ if (!(ikchan->pchan->flag & POSE_DONE))
+ where_is_pose_bone(blscene, ikscene->blArmature, ikchan->pchan, ctime);
+ // tell blender that this channel was controlled by IK, it's cleared on each where_is_pose()
+ ikchan->pchan->flag |= (POSE_DONE|POSE_CHAIN);
+ ikchan->jointValid = 0;
+ }
+ }
+ // only run execute the scene if at least one of our target is enabled
+ for (i=ikscene->targets.size(); i > 0; --i) {
+ IK_Target* iktarget = ikscene->targets[i-1];
+ if (!(iktarget->blenderConstraint->flag & CONSTRAINT_OFF))
+ break;
+ }
+ if (i == 0 && ikscene->armature->getNrOfConstraints() == 0)
+ // all constraint disabled
+ return;
+
+ // compute timestep
+ double timestamp = ctime * frtime + 2147483.648;
+ double timestep = frtime;
+ bool reiterate = (ikparam->flag & ITASC_REITERATION) ? true : false;
+ int numstep = (ikparam->flag & ITASC_AUTO_STEP) ? 0 : ikparam->numstep;
+ bool simulation = true;
+
+ if (ikparam->flag & ITASC_SIMULATION) {
+ ikscene->solver->setParam(iTaSC::Solver::DLS_QMAX, ikparam->maxvel);
+ }
+ else {
+ // in animation mode we start from the pose after action and constraint
+ convert_pose(ikscene);
+ ikscene->armature->setJointArray(ikscene->jointArray);
+ // and we don't handle velocity
+ reiterate = true;
+ simulation = false;
+ // time is virtual, so take fixed value for velocity parameters (see itasc_update_param)
+ // and choose 1s timestep to allow having velocity parameters in radiant
+ timestep = 1.0;
+ // use auto setup to let the solver test the variation of the joints
+ numstep = 0;
+ }
+
+ if (ikscene->cache && !reiterate && simulation) {
+ iTaSC::CacheTS sts, cts;
+ sts = cts = (iTaSC::CacheTS)(timestamp*1000.0+0.5);
+ if (ikscene->cache->getPreviousCacheItem(ikscene->armature, 0, &cts) == NULL || cts == 0) {
+ // the cache is empty before this time, reiterate
+ if (ikparam->flag & ITASC_INITIAL_REITERATION)
+ reiterate = true;
+ } else {
+ // can take the cache as a start point.
+ sts -= cts;
+ timestep = sts/1000.0;
+ }
+ }
+ // don't cache if we are reiterating because we don't want to distroy the cache unnecessarily
+ ikscene->scene->update(timestamp, timestep, numstep, false, !reiterate, simulation);
+ if (reiterate) {
+ // how many times do we reiterate?
+ for (i=0; i<ikparam->numiter; i++) {
+ if (ikscene->armature->getMaxJointChange() < ikparam->precision ||
+ ikscene->armature->getMaxEndEffectorChange() < ikparam->precision)
+ break;
+ ikscene->scene->update(timestamp, timestep, numstep, true, false, simulation);
+ }
+ if (simulation) {
+ // one more fake iteration to cache
+ ikscene->scene->update(timestamp, 0.0, 1, true, true, true);
+ }
+ }
+ // compute constraint error
+ for (i=ikscene->targets.size(); i > 0; --i) {
+ IK_Target* iktarget = ikscene->targets[i-1];
+ if (!(iktarget->blenderConstraint->flag & CONSTRAINT_OFF)) {
+ unsigned int nvalues;
+ const iTaSC::ConstraintValues* values;
+ values = iktarget->constraint->getControlParameters(&nvalues);
+ iktarget->errorCallback(values, nvalues, iktarget);
+ }
+ }
+ // Apply result to bone:
+ // walk the ikscene->channels
+ // for each, get the Frame of the joint corresponding to the bone relative to its parent
+ // combine the parent and the joint frame to get the frame relative to armature
+ // a backward translation of the bone length gives the head
+ // if TY, compute the scale as the ratio of the joint length with rest pose length
+ iTaSC::Armature* arm = ikscene->armature;
+ KDL::Frame frame;
+ double q_rest[3], q[3];
+ const KDL::Joint* joint;
+ const KDL::Frame* tip;
+ bPoseChannel* pchan;
+ float scale;
+ float length;
+ float yaxis[3];
+ for (i=0, ikchan=ikscene->channels; i<ikscene->numchan; ++i, ++ikchan) {
+ if (i == 0) {
+ if (!arm->getRelativeFrame(frame, ikchan->tail))
+ break;
+ // this frame is relative to base, make it relative to object
+ ikchan->frame = ikscene->baseFrame * frame;
+ }
+ else {
+ if (!arm->getRelativeFrame(frame, ikchan->tail, ikscene->channels[ikchan->parent].tail))
+ break;
+ // combine with parent frame to get frame relative to object
+ ikchan->frame = ikscene->channels[ikchan->parent].frame * frame;
+ }
+ // ikchan->frame is the tail frame relative to object
+ // get bone length
+ if (!arm->getSegment(ikchan->tail, 3, joint, q_rest[0], q[0], tip))
+ break;
+ if (joint->getType() == KDL::Joint::TransY) {
+ // stretch bones have a TY joint, compute the scale
+ scale = (float)(q[0]/q_rest[0]);
+ // the length is the joint itself
+ length = (float)q[0];
+ }
+ else {
+ scale = 1.0f;
+ // for fixed bone, the length is in the tip (always along Y axis)
+ length = tip->p(1);
+ }
+ // ready to compute the pose mat
+ pchan = ikchan->pchan;
+ // tail mat
+ ikchan->frame.getValue(&pchan->pose_mat[0][0]);
+ VECCOPY(pchan->pose_tail, pchan->pose_mat[3]);
+ // shift to head
+ VECCOPY(yaxis, pchan->pose_mat[1]);
+ VecMulf(yaxis, length);
+ VecSubf(pchan->pose_mat[3], pchan->pose_mat[3], yaxis);
+ VECCOPY(pchan->pose_head, pchan->pose_mat[3]);
+ // add scale
+ VecMulf(pchan->pose_mat[0], scale);
+ VecMulf(pchan->pose_mat[1], scale);
+ VecMulf(pchan->pose_mat[2], scale);
+ }
+ if (i<ikscene->numchan) {
+ // big problem
+ ;
+ }
+}
+
+//---------------------------------------------------
+// plugin interface
+//
+void itasc_initialize_tree(struct Scene *scene, Object *ob, float ctime)
+{
+ bPoseChannel *pchan;
+ int count = 0;
+
+ if (ob->pose->ikdata != NULL && !(ob->pose->flag & POSE_WAS_REBUILT)) {
+ init_scene(ob);
+ return;
+ }
+ // first remove old scene
+ itasc_clear_data(ob->pose);
+ // we should handle all the constraint and mark them all disabled
+ // for blender but we'll start with the IK constraint alone
+ for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= (bPoseChannel *)pchan->next) {
+ if(pchan->constflag & PCHAN_HAS_IK)
+ 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);
+ // 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_Data* ikdata = (IK_Data*)ob->pose->ikdata;
+ bItasc* ikparam = (bItasc*) ob->pose->ikparam;
+ // we need default parameters
+ if (!ikparam) ikparam = &DefIKParam;
+
+ for (IK_Scene* ikscene = ikdata->first; ikscene; ikscene = ikscene->next) {
+ if (ikscene->channels[0].pchan == pchan) {
+ float timestep = scene->r.frs_sec_base/scene->r.frs_sec;
+ if (ob->pose->flag & POSE_GAME_ENGINE) {
+ timestep = ob->pose->ctime;
+ // limit the timestep to avoid excessive number of iteration
+ if (timestep > 0.2f)
+ timestep = 0.2f;
+ }
+ execute_scene(scene, ikscene, ikparam, ctime, timestep);
+ break;
+ }
+ }
+ }
+}
+
+void itasc_release_tree(struct Scene *scene, struct Object *ob, float ctime)
+{
+ // not used for iTaSC
+}
+
+void itasc_clear_data(struct bPose *pose)
+{
+ if (pose->ikdata) {
+ IK_Data* ikdata = (IK_Data*)pose->ikdata;
+ for (IK_Scene* scene = ikdata->first; scene; scene = ikdata->first) {
+ ikdata->first = scene->next;
+ delete scene;
+ }
+ MEM_freeN(ikdata);
+ pose->ikdata = NULL;
+ }
+}
+
+void itasc_clear_cache(struct bPose *pose)
+{
+ if (pose->ikdata) {
+ IK_Data* ikdata = (IK_Data*)pose->ikdata;
+ for (IK_Scene* scene = ikdata->first; scene; scene = scene->next) {
+ if (scene->cache)
+ // clear all cache but leaving the timestamp 0 (=rest pose)
+ scene->cache->clearCacheFrom(NULL, 1);
+ }
+ }
+}
+
+void itasc_update_param(struct bPose *pose)
+{
+ if (pose->ikdata && pose->ikparam) {
+ IK_Data* ikdata = (IK_Data*)pose->ikdata;
+ bItasc* ikparam = (bItasc*)pose->ikparam;
+ for (IK_Scene* ikscene = ikdata->first; ikscene; ikscene = ikscene->next) {
+ double armlength = ikscene->armature->getArmLength();
+ ikscene->solver->setParam(iTaSC::Solver::DLS_LAMBDA_MAX, ikparam->dampmax*armlength);
+ ikscene->solver->setParam(iTaSC::Solver::DLS_EPSILON, ikparam->dampeps*armlength);
+ if (ikparam->flag & ITASC_SIMULATION) {
+ ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, ikparam->minstep);
+ ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, ikparam->maxstep);
+ ikscene->solver->setParam(iTaSC::Solver::DLS_QMAX, ikparam->maxvel);
+ ikscene->armature->setControlParameter(CONSTRAINT_ID_ALL, iTaSC::Armature::ID_JOINT, iTaSC::ACT_FEEDBACK, ikparam->feedback);
+ } else {
+ // in animation mode timestep is 1s by convention =>
+ // qmax becomes radiant and feedback becomes fraction of error gap corrected in one iteration
+ ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, 1.0);
+ ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, 1.0);
+ ikscene->solver->setParam(iTaSC::Solver::DLS_QMAX, 0.52);
+ ikscene->armature->setControlParameter(CONSTRAINT_ID_ALL, iTaSC::Armature::ID_JOINT, iTaSC::ACT_FEEDBACK, 0.8);
+ }
+ }
+ }
+}
+
+void itasc_test_constraint(struct Object *ob, struct bConstraint *cons)
+{
+ struct bKinematicConstraint *data = (struct bKinematicConstraint *)cons->data;
+
+ /* only for IK constraint */
+ if (cons->type != CONSTRAINT_TYPE_KINEMATIC || data == NULL)
+ return;
+
+ switch (data->type) {
+ case CONSTRAINT_IK_COPYPOSE:
+ case CONSTRAINT_IK_DISTANCE:
+ /* cartesian space constraint */
+ break;
+ }
+}
+
diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h
new file mode 100644
index 00000000000..25e48965a52
--- /dev/null
+++ b/source/blender/ikplugin/intern/itasc_plugin.h
@@ -0,0 +1,52 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Original author: Benoit Bolsee
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef ITASC_PLUGIN_H
+#define ITASC_PLUGIN_H
+
+#include "ikplugin_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void itasc_initialize_tree(struct Scene *scene, struct Object *ob, float ctime);
+void itasc_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
+void itasc_release_tree(struct Scene *scene, struct Object *ob, float ctime);
+void itasc_clear_data(struct bPose *pose);
+void itasc_clear_cache(struct bPose *pose);
+void itasc_update_param(struct bPose *pose);
+void itasc_test_constraint(struct Object *ob, struct bConstraint *cons);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ITASC_PLUGIN_H
+
diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c
index a2dbdfbe483..1aaba620f3a 100644
--- a/source/blender/imbuf/intern/anim.c
+++ b/source/blender/imbuf/intern/anim.c
@@ -608,7 +608,7 @@ static int startffmpeg(struct anim * anim) {
anim->pFrameDeinterlaced = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame();
- if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
+ if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y)
!= anim->x * anim->y * 4) {
fprintf (stderr,
"ffmpeg has changed alloc scheme ... ARGHHH!\n");
@@ -642,7 +642,7 @@ static int startffmpeg(struct anim * anim) {
anim->pCodecCtx->pix_fmt,
anim->pCodecCtx->width,
anim->pCodecCtx->height,
- PIX_FMT_BGR32,
+ PIX_FMT_RGBA,
SWS_FAST_BILINEAR | SWS_PRINT_INFO,
NULL, NULL, NULL);
@@ -671,11 +671,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
if (anim == 0) return (0);
- ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect, 0);
avpicture_fill((AVPicture*) anim->pFrameRGB,
(unsigned char*) ibuf->rect,
- PIX_FMT_BGR32, anim->x, anim->y);
+ PIX_FMT_RGBA, anim->x, anim->y);
if (position != anim->curposition + 1) {
if (position > anim->curposition + 1
@@ -748,6 +748,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
if (frameFinished && !pos_found) {
if (packet.dts >= pts_to_search) {
pos_found = 1;
+ anim->curposition = position;
}
}
@@ -811,21 +812,21 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
for (y = 0; y < h; y++) {
unsigned char tmp[4];
- unsigned long * tmp_l =
- (unsigned long*) tmp;
+ unsigned int * tmp_l =
+ (unsigned int*) tmp;
tmp[3] = 0xff;
for (x = 0; x < w; x++) {
- tmp[0] = bottom[3];
- tmp[1] = bottom[2];
- tmp[2] = bottom[1];
+ tmp[0] = bottom[0];
+ tmp[1] = bottom[1];
+ tmp[2] = bottom[2];
- bottom[0] = top[3];
- bottom[1] = top[2];
- bottom[2] = top[1];
+ bottom[0] = top[0];
+ bottom[1] = top[1];
+ bottom[2] = top[2];
bottom[3] = 0xff;
- *(unsigned long*) top
+ *(unsigned int*) top
= *tmp_l;
bottom +=4;
@@ -848,8 +849,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
0, 0, 0 };
int i;
unsigned char* r;
-
-
+
sws_scale(anim->img_convert_ctx,
input->data,
input->linesize,
@@ -857,8 +857,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
anim->pCodecCtx->height,
dst2,
dstStride2);
-
- /* workaround: sws_scale
+
+ /* workaround: sws_scale
sets alpha = 0... */
r = (unsigned char*) ibuf->rect;
@@ -867,7 +867,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
r[3] = 0xff;
r+=4;
}
-
+
av_free_packet(&packet);
break;
}
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 6e1a176a5d2..e84a9302bbf 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -190,7 +190,11 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
to = (unsigned char *) ibuf->rect;
}
- if (profile == IB_PROFILE_SRGB && (channels == 3 || channels == 4)) {
+ if(channels==1) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
+ to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
+ }
+ else if (profile == IB_PROFILE_SRGB) {
if(channels == 3) {
for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
srgb[0]= linearrgb_to_srgb(tof[0]);
@@ -207,12 +211,8 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
floatbuf_to_srgb_byte(tof, to, 0, ibuf->x, 0, ibuf->y, ibuf->x);
}
}
- else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_LINEAR_RGB) && (dither==0.0f || channels!=4)) {
- if(channels==1) {
- for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
- to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
- }
- else if(channels==3) {
+ else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_LINEAR_RGB) && dither==0.0f) {
+ if(channels==3) {
for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
to[0] = FTOCHAR(tof[0]);
to[1] = FTOCHAR(tof[1]);
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 6217cd6bea2..2583a155d6a 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -230,7 +230,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags)
rect_float[2]= (float)(image->comps[2].data[index] + signed_offsets[2]) / float_divs[2];
if (image->numcomps >= 4)
- rect_float[3]= (float)(image->comps[2].data[index] + signed_offsets[3]) / float_divs[3];
+ rect_float[3]= (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3];
else
rect_float[3]= 1.0f;
}
@@ -260,7 +260,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags)
rect[2]= image->comps[2].data[index] + signed_offsets[2];
if (image->numcomps >= 4)
- rect[3]= image->comps[2].data[index] + signed_offsets[3];
+ rect[3]= image->comps[3].data[index] + signed_offsets[3];
else
rect[3]= 255;
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 9e5212e159f..0c38421a3f5 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -155,40 +155,37 @@ typedef struct PreviewImage {
#endif
/* ID from database */
-#define ID_SCE MAKE_ID2('S', 'C')
-#define ID_LI MAKE_ID2('L', 'I')
-#define ID_OB MAKE_ID2('O', 'B')
-#define ID_ME MAKE_ID2('M', 'E')
-#define ID_CU MAKE_ID2('C', 'U')
-#define ID_MB MAKE_ID2('M', 'B')
-#define ID_MA MAKE_ID2('M', 'A')
-#define ID_TE MAKE_ID2('T', 'E')
-#define ID_IM MAKE_ID2('I', 'M')
-#define ID_IK MAKE_ID2('I', 'K')
-#define ID_WV MAKE_ID2('W', 'V')
-#define ID_LT MAKE_ID2('L', 'T')
-#define ID_SE MAKE_ID2('S', 'E')
-#define ID_LF MAKE_ID2('L', 'F')
-#define ID_LA MAKE_ID2('L', 'A')
-#define ID_CA MAKE_ID2('C', 'A')
-#define ID_IP MAKE_ID2('I', 'P')
-#define ID_KE MAKE_ID2('K', 'E')
-#define ID_WO MAKE_ID2('W', 'O')
-#define ID_SCR MAKE_ID2('S', 'R')
-#define ID_SCRN MAKE_ID2('S', 'N')
-#define ID_VF MAKE_ID2('V', 'F')
-#define ID_TXT MAKE_ID2('T', 'X')
-#define ID_SO MAKE_ID2('S', 'O')
-#define ID_GR MAKE_ID2('G', 'R')
-#define ID_ID MAKE_ID2('I', 'D')
-#define ID_AR MAKE_ID2('A', 'R')
-#define ID_AC MAKE_ID2('A', 'C')
-#define ID_SCRIPT MAKE_ID2('P', 'Y')
-#define ID_NT MAKE_ID2('N', 'T')
-#define ID_BR MAKE_ID2('B', 'R')
-#define ID_PA MAKE_ID2('P', 'A')
-#define ID_GD MAKE_ID2('G', 'D')
-#define ID_WM MAKE_ID2('W', 'M')
+#define ID_SCE MAKE_ID2('S', 'C') /* Scene */
+#define ID_LI MAKE_ID2('L', 'I') /* Library */
+#define ID_OB MAKE_ID2('O', 'B') /* Object */
+#define ID_ME MAKE_ID2('M', 'E') /* Mesh */
+#define ID_CU MAKE_ID2('C', 'U') /* Curve */
+#define ID_MB MAKE_ID2('M', 'B') /* MetaBall */
+#define ID_MA MAKE_ID2('M', 'A') /* Material */
+#define ID_TE MAKE_ID2('T', 'E') /* Texture */
+#define ID_IM MAKE_ID2('I', 'M') /* Image */
+#define ID_WV MAKE_ID2('W', 'V') /* Wave (unused) */
+#define ID_LT MAKE_ID2('L', 'T') /* Lattice */
+#define ID_LA MAKE_ID2('L', 'A') /* Lamp */
+#define ID_CA MAKE_ID2('C', 'A') /* Camera */
+#define ID_IP MAKE_ID2('I', 'P') /* Ipo (depreciated, replaced by FCurves) */
+#define ID_KE MAKE_ID2('K', 'E') /* Key (shape key) */
+#define ID_WO MAKE_ID2('W', 'O') /* World */
+#define ID_SCR MAKE_ID2('S', 'R') /* Screen */
+#define ID_SCRN MAKE_ID2('S', 'N') /* (depreciated?) */
+#define ID_VF MAKE_ID2('V', 'F') /* VectorFont */
+#define ID_TXT MAKE_ID2('T', 'X') /* Text */
+#define ID_SO MAKE_ID2('S', 'O') /* Sound */
+#define ID_GR MAKE_ID2('G', 'R') /* Group */
+#define ID_ID MAKE_ID2('I', 'D') /* (internal use only) */
+#define ID_AR MAKE_ID2('A', 'R') /* Armature */
+#define ID_AC MAKE_ID2('A', 'C') /* Action */
+#define ID_SCRIPT MAKE_ID2('P', 'Y') /* Script (depreciated) */
+#define ID_NT MAKE_ID2('N', 'T') /* NodeTree */
+#define ID_BR MAKE_ID2('B', 'R') /* Brush */
+#define ID_PA MAKE_ID2('P', 'A') /* ParticleSettings */
+#define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */
+#define ID_WM MAKE_ID2('W', 'M') /* WindowManager */
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
#define ID_SEQ MAKE_ID2('S', 'Q')
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 318204e3dd8..3201a1df6a5 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -146,7 +146,9 @@ typedef struct bPoseChannel {
float limitmin[3], limitmax[3]; /* DOF constraint */
float stiffness[3]; /* DOF stiffness */
float ikstretch;
-
+ float ikrotweight; /* weight of joint rotation constraint */
+ float iklinweight; /* weight of joint stretch constraint */
+
float *path; /* totpath x 3 x float */
struct Object *custom; /* draws custom object instead of this channel */
} bPoseChannel;
@@ -166,7 +168,8 @@ typedef enum ePchan_Flag {
POSE_CHAIN = 0x0200,
POSE_DONE = 0x0400,
POSE_KEY = 0x1000,
- POSE_STRIDE = 0x2000
+ POSE_STRIDE = 0x2000,
+ POSE_IKTREE = 0x4000,
} ePchan_Flag;
/* PoseChannel constflag (constraint detection) */
@@ -190,28 +193,34 @@ typedef enum ePchan_IkFlag {
BONE_IK_YLIMIT = (1<<4),
BONE_IK_ZLIMIT = (1<<5),
+ BONE_IK_ROTCTL = (1<<6),
+ BONE_IK_LINCTL = (1<<7),
+
BONE_IK_NO_XDOF_TEMP = (1<<10),
BONE_IK_NO_YDOF_TEMP = (1<<11),
- BONE_IK_NO_ZDOF_TEMP = (1<<12)
+ BONE_IK_NO_ZDOF_TEMP = (1<<12),
+
} ePchan_IkFlag;
-/* PoseChannel->rotmode */
-typedef enum ePchan_RotMode {
+/* PoseChannel->rotmode and Object->rotmode */
+typedef enum eRotationModes {
/* quaternion rotations (default, and for older Blender versions) */
- PCHAN_ROT_QUAT = 0,
+ ROT_MODE_QUAT = 0,
/* euler rotations - keep in sync with enum in BLI_arithb.h */
- PCHAN_ROT_XYZ = 1, /* Blender 'default' (classic) - must be as 1 to sync with PoseChannel rotmode */
- PCHAN_ROT_XZY,
- PCHAN_ROT_YXZ,
- PCHAN_ROT_YZX,
- PCHAN_ROT_ZXY,
- PCHAN_ROT_ZYX,
+ ROT_MODE_EUL = 1, /* Blender 'default' (classic) - must be as 1 to sync with arithb defines */
+ ROT_MODE_XYZ = 1, /* Blender 'default' (classic) - must be as 1 to sync with arithb defines */
+ ROT_MODE_XZY,
+ ROT_MODE_YXZ,
+ ROT_MODE_YZX,
+ ROT_MODE_ZXY,
+ ROT_MODE_ZYX,
/* NOTE: space is reserved here for 18 other possible
* euler rotation orders not implemented
*/
+ ROT_MODE_MAX, /* sentinel for Py API */
/* axis angle rotations */
- PCHAN_ROT_AXISANGLE = -1
-} ePchan_RotMode;
+ ROT_MODE_AXISANGLE = -1
+} eRotationModes;
/* Pose ------------------------------------ */
@@ -233,7 +242,9 @@ typedef struct bPose {
ListBase agroups; /* list of bActionGroups */
int active_group; /* index of active group (starts from 1) */
- int pad;
+ int iksolver; /* ik solver to use, see ePose_IKSolverType */
+ void *ikdata; /* temporary IK data, depends on the IK solver. Not saved in file */
+ void *ikparam; /* IK solver parameters, structure depends on iksolver */
} bPose;
@@ -249,8 +260,55 @@ typedef enum ePose_Flags {
POSE_CONSTRAINTS_TIMEDEPEND = (1<<3),
/* recalculate bone paths */
POSE_RECALCPATHS = (1<<4),
+ /* set by armature_rebuild_pose to give a chance to the IK solver to rebuild IK tree */
+ POSE_WAS_REBUILT = (1<<5),
+ /* set by game_copy_pose to indicate that this pose is used in the game engine */
+ POSE_GAME_ENGINE = (1<<6),
} ePose_Flags;
+/* IK Solvers ------------------------------------ */
+
+/* bPose->iksolver and bPose->ikparam->iksolver */
+typedef enum {
+ IKSOLVER_LEGACY = 0,
+ IKSOLVER_ITASC,
+} ePose_IKSolverType;
+
+/* header for all bPose->ikparam structures */
+typedef struct bIKParam {
+ int iksolver;
+} bIKParam;
+
+/* bPose->ikparam when bPose->iksolver=1 */
+typedef struct bItasc {
+ int iksolver;
+ float precision;
+ short numiter;
+ short numstep;
+ float minstep;
+ float maxstep;
+ short solver;
+ short flag;
+ float feedback;
+ float maxvel; /* max velocity to SDLS solver */
+ float dampmax; /* maximum damping for DLS solver */
+ float dampeps; /* threshold of singular value from which the damping start progressively */
+} bItasc;
+
+/* bItasc->flag */
+typedef enum {
+ ITASC_AUTO_STEP = (1<<0),
+ ITASC_INITIAL_REITERATION = (1<<1),
+ ITASC_REITERATION = (1<<2),
+ ITASC_SIMULATION = (1<<3),
+} eItasc_Flags;
+
+/* bItasc->solver */
+typedef enum {
+ ITASC_SOLVER_SDLS = 0, /* selective damped least square, suitable for CopyPose constraint */
+ ITASC_SOLVER_DLS /* damped least square with numerical filtering of damping */
+} eItasc_Solver;
+
/* ************************************************ */
/* Action */
@@ -372,12 +430,13 @@ typedef enum DOPESHEET_FILTERFLAG {
ADS_FILTER_NOSCE = (1<<15),
ADS_FILTER_NOPART = (1<<16),
ADS_FILTER_NOMBA = (1<<17),
+ ADS_FILTER_NOARM = (1<<18),
/* NLA-specific filters */
ADS_FILTER_NLA_NOACT = (1<<20), /* if the AnimData block has no NLA data, don't include to just show Action-line */
/* combination filters (some only used at runtime) */
- ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART),
+ ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART|ADS_FILTER_NOARM),
} DOPESHEET_FILTERFLAG;
/* DopeSheet general flags */
@@ -494,5 +553,4 @@ typedef enum ACHAN_FLAG {
ACHAN_MOVED = (1<<31),
} ACHAN_FLAG;
-
#endif
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 278da27faf9..58fa38ae159 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -142,7 +142,7 @@ typedef struct bGroupActuator {
char name[32]; /* property or groupkey */
short pad[3], cur, butsta, butend;/* not referenced, can remove? */
- struct Group *group; /* only during game */
+ /* struct Group *group; not used, remove */
} bGroupActuator;
@@ -224,6 +224,15 @@ typedef struct bStateActuator {
unsigned int mask; /* the bits to change */
} bStateActuator;
+typedef struct bArmatureActuator {
+ char posechannel[32];
+ char constraint[32];
+ int type; /* 0=run, 1=enable, 2=disable, 3=set target, 4=set weight */
+ float weight;
+ struct Object *target;
+ struct Object *subtarget;
+} bArmatureActuator;
+
typedef struct bActuator {
struct bActuator *next, *prev, *mynew;
short type;
@@ -295,6 +304,7 @@ typedef struct FreeCamera {
#define ACT_PARENT 20
#define ACT_SHAPEACTION 21
#define ACT_STATE 22
+#define ACT_ARMATURE 23
/* actuator flag */
#define ACT_SHOW 1
@@ -484,6 +494,15 @@ typedef struct FreeCamera {
#define ACT_PARENT_COMPOUND 1
#define ACT_PARENT_GHOST 2
+/* armatureactuator->type */
+#define ACT_ARM_RUN 0
+#define ACT_ARM_ENABLE 1
+#define ACT_ARM_DISABLE 2
+#define ACT_ARM_SETTARGET 3
+#define ACT_ARM_SETWEIGHT 4
+/* update this define if more type are addedd */
+#define ACT_ARM_MAXTYPE 4
+
#endif
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index f75ed273164..9921878e926 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -632,7 +632,7 @@ typedef enum eKSP_TemplateTypes {
KSP_TEMPLATE_CONSTRAINT = (1<<2), /* #con - active only */
KSP_TEMPLATE_NODE = (1<<3), /* #nod - selected node */
- KSP_TEMPLATE_PCHAN_ROT = (1<<16), /* modify rotation paths based on rotation mode of Pose Channel */
+ KSP_TEMPLATE_ROT = (1<<16), /* modify rotation paths based on rotation mode of Object or Pose Channel */
} eKSP_TemplateTypes;
/* ---------------- */
@@ -763,6 +763,11 @@ typedef enum eAnimData_Flag {
/* don't execute drivers */
ADT_DRIVERS_DISABLED = (1<<11),
+ /* AnimData block is selected in UI */
+ ADT_UI_SELECTED = (1<<14),
+ /* AnimData block is active in UI */
+ ADT_UI_ACTIVE = (1<<15),
+
/* F-Curves from this AnimData block are not visible in the Graph Editor */
ADT_CURVES_NOT_VISIBLE = (1<<16),
} eAnimData_Flag;
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index bb60fb107ff..590e7dadcdc 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -31,6 +31,8 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
+struct AnimData;
+
/* this system works on different transformation space levels;
1) Bone Space; with each Bone having own (0,0,0) origin
@@ -69,6 +71,7 @@ typedef struct Bone {
typedef struct bArmature {
ID id;
+ struct AnimData *adt;
ListBase bonebase;
ListBase chainbase;
ListBase *edbo; /* editbone listbase, we use pointer so we can check state */
@@ -102,7 +105,8 @@ typedef enum eArmature_Flag {
ARM_AUTO_IK = (1<<9),
ARM_NO_CUSTOM = (1<<10), /* made option negative, for backwards compat */
ARM_COL_CUSTOM = (1<<11), /* draw custom colours */
- ARM_GHOST_ONLYSEL = (1<<12) /* when ghosting, only show selected bones (this should belong to ghostflag instead) */
+ ARM_GHOST_ONLYSEL = (1<<12), /* when ghosting, only show selected bones (this should belong to ghostflag instead) */
+ ARM_DS_EXPAND = (1<<13)
} eArmature_Flag;
/* armature->drawtype */
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index a3a1a342584..1bbccd20486 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -56,7 +56,7 @@ typedef struct Brush {
short flag, blend; /* general purpose flag, blend mode */
int size; /* brush diameter */
- float innerradius; /* inner radius after which the falloff starts */
+ float jitter; /* jitter the position of the brush */
float spacing; /* spacing of paint operations */
int smooth_stroke_radius; /* turning radius (in pixels) for smooth stroke */
float smooth_stroke_factor; /* higher values limit fast changes in the stroke direction */
@@ -76,7 +76,7 @@ typedef struct Brush {
#define BRUSH_TORUS 2
#define BRUSH_ALPHA_PRESSURE 4
#define BRUSH_SIZE_PRESSURE 8
-#define BRUSH_RAD_PRESSURE 16
+#define BRUSH_JITTER_PRESSURE 16 /* was BRUSH_RAD_PRESSURE */
#define BRUSH_SPACING_PRESSURE 32
#define BRUSH_FIXED_TEX 64
#define BRUSH_RAKE 128
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 5cfecf7cc01..9423e871c77 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -79,6 +79,8 @@ typedef struct ClothSimSettings
short vgroup_struct; /* vertex group for scaling structural stiffness */
short presets; /* used for presets on GUI */
short pad;
+
+ struct EffectorWeights *effector_weights;
} ClothSimSettings;
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 70430af3fc8..fccec7a556f 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -66,6 +66,9 @@ typedef struct bConstraint {
int pad;
struct Ipo *ipo; /* local influence ipo or driver */ // XXX depreceated for 2.5... old animation system hack
+ /* below are readonly fields that are set at runtime by the solver for use in the GE (only IK atm) */
+ float lin_error; /* residual error on constraint expressed in blender unit*/
+ float rot_error; /* residual error on constraint expressed in radiant */
} bConstraint;
@@ -119,24 +122,34 @@ typedef struct bPythonConstraint {
} bPythonConstraint;
-/* Inverse-Kinematics (IK) constraint */
+/* inverse-Kinematics (IK) constraint
+ This constraint supports a variety of mode determine by the type field
+ according to B_CONSTRAINT_IK_TYPE.
+ Some fields are used by all types, some are specific to some types
+ This is indicated in the comments for each field
+ */
typedef struct bKinematicConstraint {
- Object *tar;
- short iterations; /* Maximum number of iterations to try */
- short flag; /* Like CONSTRAINT_IK_TIP */
- short rootbone; /* index to rootbone, if zero go all the way to mother bone */
- short max_rootbone; /* for auto-ik, maximum length of chain */
- char subtarget[32]; /* String to specify sub-object target */
-
- Object *poletar; /* Pole vector target */
- char polesubtarget[32]; /* Pole vector sub-object target */
- float poleangle; /* Pole vector rest angle */
-
- float weight; /* Weight of goal in IK tree */
- float orientweight; /* Amount of rotation a target applies on chain */
- float grabtarget[3]; /* for target-less IK */
+ Object *tar; /* All: target object in case constraint needs a target */
+ short iterations; /* All: Maximum number of iterations to try */
+ short flag; /* All & CopyPose: some options Like CONSTRAINT_IK_TIP */
+ short rootbone; /* All: index to rootbone, if zero go all the way to mother bone */
+ short max_rootbone; /* CopyPose: for auto-ik, maximum length of chain */
+ char subtarget[32]; /* All: String to specify sub-object target */
+ Object *poletar; /* All: Pole vector target */
+ char polesubtarget[32]; /* All: Pole vector sub-object target */
+ float poleangle; /* All: Pole vector rest angle */
+ float weight; /* All: Weight of constraint in IK tree */
+ float orientweight; /* CopyPose: Amount of rotation a target applies on chain */
+ float grabtarget[3]; /* CopyPose: for target-less IK */
+ short type; /* subtype of IK constraint: B_CONSTRAINT_IK_TYPE */
+ short mode; /* Distance: how to limit in relation to clamping sphere: LIMITDIST_.. */
+ float dist; /* Distance: distance (radius of clamping sphere) from target */
} bKinematicConstraint;
+typedef enum B_CONSTRAINT_IK_TYPE {
+ CONSTRAINT_IK_COPYPOSE = 0, /* 'standard' IK constraint: match position and/or orientation of target */
+ CONSTRAINT_IK_DISTANCE /* maintain distance with target */
+} B_CONSTRAINT_IK_TYPE;
/* Single-target subobject constraints --------------------- */
/* Track To Constraint */
@@ -376,7 +389,9 @@ typedef enum B_CONSTRAINT_FLAG {
/* influence ipo is on constraint itself, not in action channel */
CONSTRAINT_OWN_IPO = (1<<7),
/* indicates that constraint was added locally (i.e. didn't come from the proxy-lib) */
- CONSTRAINT_PROXY_LOCAL = (1<<8)
+ CONSTRAINT_PROXY_LOCAL = (1<<8),
+ /* indicates that constraint is temporarily disabled (only used in GE) */
+ CONSTRAINT_OFF = (1<<9)
} B_CONSTRAINT_FLAG;
/* bConstraint->ownspace/tarspace */
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 109a9528de2..6cfeb646cf2 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -310,6 +310,7 @@ typedef enum eBezTriple_Interpolation {
/* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */
typedef enum eBezTriple_KeyframeType {
BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */
+ BEZT_KEYTYPE_EXTREME, /* 'extreme' keyframe */
BEZT_KEYTYPE_BREAKDOWN, /* 'breakdown' keyframe */
} eBezTriple_KeyframeType;
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 55e3c9107e4..a925b60ac33 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -50,26 +50,23 @@ struct Ipo;
typedef struct VolumeSettings {
float density;
float emission;
- float absorption;
float scattering;
+ float reflection;
float emission_col[3];
- float absorption_col[3];
+ float transmission_col[3];
+ float reflection_col[3];
+
float density_scale;
float depth_cutoff;
-
- short phasefunc_type;
- short vpad[3];
- float phasefunc_g;
-
- float stepsize;
- float shade_stepsize;
+ float asymmetry;
short stepsize_type;
short shadeflag;
short shade_type;
short precache_resolution;
-
+
+ float stepsize;
float ms_diff;
float ms_intensity;
int ms_steps;
@@ -160,9 +157,8 @@ typedef struct Material {
float sss_front, sss_back;
short sss_flag, sss_preset;
- /* yafray: absorption color, dispersion parameters and material preset menu */
- float YF_ar, YF_ag, YF_ab, YF_dscale, YF_dpwr;
- int YF_dsmp, YF_preset, YF_djit;
+ int mapto_textured; /* render-time cache to optimise texture lookups */
+ int pad4;
ListBase gpumaterial; /* runtime */
} Material;
@@ -317,15 +313,17 @@ typedef struct Material {
#define MAP_AMB 2048
#define MAP_DISPLACE 4096
#define MAP_WARP 8192
-#define MAP_LAYER 16384
+#define MAP_LAYER 16384 /* unused */
/* volume mapto - reuse definitions for now - a bit naughty! */
-#define MAP_DENSITY 128
-#define MAP_EMISSION 64
-#define MAP_EMISSION_COL 1
-#define MAP_ABSORPTION 512
-#define MAP_ABSORPTION_COL 8
-#define MAP_SCATTERING 16
+#define MAP_DENSITY 128
+#define MAP_EMISSION 64
+#define MAP_EMISSION_COL 1
+#define MAP_SCATTERING 16
+#define MAP_TRANSMISSION_COL 8
+#define MAP_REFLECTION_COL 4
+#define MAP_REFLECTION 32
+
/* mapto for halo */
//#define MAP_HA_COL 1
@@ -386,13 +384,5 @@ typedef struct Material {
#define MA_VOL_SHADE_MULTIPLE 2
#define MA_VOL_SHADE_SINGLEPLUSMULTIPLE 3
-/* vol_phasefunc_type */
-#define MA_VOL_PH_ISOTROPIC 0
-#define MA_VOL_PH_MIEHAZY 1
-#define MA_VOL_PH_MIEMURKY 2
-#define MA_VOL_PH_RAYLEIGH 3
-#define MA_VOL_PH_HG 4
-#define MA_VOL_PH_SCHLICK 5
-
#endif
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index be7452c4ae1..7c76a5c099d 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1,7 +1,28 @@
/**
+ *
* $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
*/
+#include "DNA_listBase.h"
+
#ifndef DNA_MODIFIER_TYPES_H
#define DNA_MODIFIER_TYPES_H
@@ -438,9 +459,7 @@ typedef struct CollisionModifierData {
unsigned int numverts;
unsigned int numfaces;
- short absorption; /* used for forces, in % */
- short pad;
- float time; /* cfra time of modifier */
+ float time, pad; /* cfra time of modifier */
struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
} CollisionModifierData;
@@ -469,8 +488,8 @@ typedef struct BooleanModifierData {
int operation, pad;
} BooleanModifierData;
-#define MOD_MDEF_INVERT_VGROUP (1<<0)
-#define MOD_MDEF_DYNAMIC_BIND (1<<1)
+#define MOD_MDEF_INVERT_VGROUP (1<<0)
+#define MOD_MDEF_DYNAMIC_BIND (1<<1)
typedef struct MDefInfluence {
int vertex;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index b10de02dbb4..e70221df9ab 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -40,6 +40,7 @@ struct bNodeLink;
struct bNodeType;
struct bNodeGroup;
struct AnimData;
+struct uiBlock;
#define NODE_MAXSTR 32
@@ -131,6 +132,7 @@ typedef struct bNode {
rctf butr; /* optional buttons area */
rctf prvr; /* optional preview area */
bNodePreview *preview; /* optional preview image */
+ struct uiBlock *block; /* runtime during drawing */
struct bNodeType *typeinfo; /* lookup of callbacks and defaults */
diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h
index 09288b24c20..da55fb1d47c 100644
--- a/source/blender/makesdna/DNA_object_fluidsim.h
+++ b/source/blender/makesdna/DNA_object_fluidsim.h
@@ -41,6 +41,7 @@ struct Ipo;
struct MVert;
typedef struct FluidsimSettings {
+ struct FluidsimModifierData *fmd; /* for fast RNA access */
/* domain,fluid or obstacle */
short type;
/* display advanced options in fluid sim tab (on=1,off=0)*/
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 986a75f1a96..e7e785e605b 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -35,45 +35,91 @@ extern "C" {
#endif
#include "DNA_listBase.h"
+
+/* pd->forcefield: Effector Fields types */
+typedef enum PFieldType {
+ PFIELD_NULL = 0, /* (this is used for general effector weight) */
+ PFIELD_FORCE, /* Force away/towards a point depending on force strength */
+ PFIELD_VORTEX, /* Force around the effector normal */
+ PFIELD_MAGNET, /* Force from the cross product of effector normal and point velocity */
+ PFIELD_WIND, /* Force away and towards a point depending which side of the effector */
+ /* normal the point is */
+ PFIELD_GUIDE, /* Force along curve for dynamics, a shaping curve for hair paths */
+ PFIELD_TEXTURE, /* Force based on texture values calculated at point coordinates */
+ PFIELD_HARMONIC, /* Force of a harmonic (damped) oscillator */
+ PFIELD_CHARGE, /* Force away/towards a point depending on point charge */
+ PFIELD_LENNARDJ, /* Force due to a Lennard-Jones potential */
+ PFIELD_BOID, /* Defines predator / goal for boids */
+ PFIELD_TURBULENCE, /* Force defined by BLI_gTurbulence */
+ PFIELD_DRAG, /* Linear & quadratic drag */
+ NUM_PFIELD_TYPES
+} PFieldType;
typedef struct PartDeflect {
- short deflect; /* Deflection flag - does mesh deflect particles*/
- short forcefield; /* Force field type, do the vertices attract / repel particles ? */
- short flag; /* general settings flag */
- short falloff; /* fall-off type*/
+ short deflect; /* Deflection flag - does mesh deflect particles */
+ short forcefield; /* Force field type, do the vertices attract / repel particles? */
+ short flag; /* general settings flag */
+ short falloff; /* fall-off type */
+ short shape; /* point, plane or surface */
+ short tex_mode; /* texture effector */
+ short kink, kink_axis; /* for curve guide */
+ short zdir, rt;
+ /* Main effector values */
+ float f_strength; /* The strength of the force (+ or - ) */
+ float f_damp; /* Damping ratio of the harmonic effector. */
+ float f_flow; /* How much force is converted into "air flow", i.e. */
+ /* force used as the velocity of surrounding medium. */
+
+ float f_size;
+
+ /* fall-off */
+ float f_power; /* The power law - real gravitation is 2 (square) */
+ float maxdist; /* if indicated, use this maximum */
+ float mindist; /* if indicated, use this minimum */
+ float f_power_r; /* radial fall-off power */
+ float maxrad; /* radial versions of above */
+ float minrad;
+
+ /* particle collisions */
float pdef_damp; /* Damping factor for particle deflection */
float pdef_rdamp; /* Random element of damping for deflection */
float pdef_perm; /* Chance of particle passing through mesh */
float pdef_frict; /* Friction factor for particle deflection */
float pdef_rfrict; /* Random element of friction for deflection */
- float f_strength; /* The strength of the force (+ or - ) */
- float f_power; /* The power law - real gravitation is 2 (square) */
- float f_dist;
- float f_damp; /* The dampening factor, currently only for harmonic force */
- float maxdist; /* if indicated, use this maximum */
- float mindist; /* if indicated, use this minimum */
- float maxrad; /* radial versions of above */
- float minrad;
- float f_power_r; /* radial fall-off power*/
+ float absorption, pad; /* used for forces */
+ /* softbody collisions */
float pdef_sbdamp; /* Damping factor for softbody deflection */
float pdef_sbift; /* inner face thickness for softbody deflection */
float pdef_sboft; /* outer face thickness for softbody deflection */
- /* variables for guide curve */
+ /* guide curve, same as for particle child effects */
float clump_fac, clump_pow;
float kink_freq, kink_shape, kink_amp, free_end;
- float tex_nabla;
- short tex_mode, kink, kink_axis, rt2;
- struct Tex *tex; /* Texture of the texture effector */
- struct RNG *rng; /* random noise generator for e.g. wind */
- float f_noise; /* noise of force (currently used for wind) */
- int seed; /* wind noise random seed */
+ /* texture effector */
+ float tex_nabla; /* Used for calculating partial derivatives */
+ struct Tex *tex; /* Texture of the texture effector */
+
+ /* effector noise */
+ struct RNG *rng; /* random noise generator for e.g. wind */
+ float f_noise; /* noise of force */
+ int seed; /* noise random seed */
} PartDeflect;
+typedef struct EffectorWeights {
+ struct Group *group; /* only use effectors from this group of objects */
+
+ float weight[13]; /* effector type specific weights */
+ float global_gravity;
+ short flag, rt[3];
+} EffectorWeights;
+
+/* EffectorWeights->flag */
+#define EFF_WEIGHT_DO_HAIR 1
+
/* Point cache file data types:
* - used as (1<<flag) so poke jahka if you reach the limit of 15
* - to add new data types update:
@@ -254,48 +300,51 @@ typedef struct SoftBody {
struct PointCache *pointcache;
struct ListBase ptcaches;
-} SoftBody;
+ struct EffectorWeights *effector_weights;
-/* pd->forcefield: Effector Fields types */
-#define PFIELD_FORCE 1
-#define PFIELD_VORTEX 2
-#define PFIELD_MAGNET 3
-#define PFIELD_WIND 4
-#define PFIELD_GUIDE 5
-#define PFIELD_TEXTURE 6
-#define PFIELD_HARMONIC 7
-#define PFIELD_CHARGE 8
-#define PFIELD_LENNARDJ 9
-#define PFIELD_BOID 10
+} SoftBody;
/* pd->flag: various settings */
#define PFIELD_USEMAX 1
#define PDEFLE_DEFORM 2
-#define PFIELD_GUIDE_PATH_ADD 4
-#define PFIELD_PLANAR 8
+#define PFIELD_GUIDE_PATH_ADD 4 /* TODO: do_versions for below */
+#define PFIELD_PLANAR 8 /* used for do_versions */
#define PDEFLE_KILL_PART 16
-#define PFIELD_POSZ 32
+#define PFIELD_POSZ 32 /* used for do_versions */
#define PFIELD_TEX_OBJECT 64
+#define PFIELD_GLOBAL_CO 64 /* used for turbulence */
#define PFIELD_TEX_2D 128
#define PFIELD_USEMIN 256
#define PFIELD_USEMAXR 512
#define PFIELD_USEMINR 1024
#define PFIELD_TEX_ROOTCO 2048
-#define PFIELD_SURFACE 4096
+#define PFIELD_SURFACE (1<<12) /* used for do_versions */
+#define PFIELD_VISIBILITY (1<<13)
+#define PFIELD_DO_LOCATION (1<<14)
+#define PFIELD_DO_ROTATION (1<<15)
/* pd->falloff */
#define PFIELD_FALL_SPHERE 0
#define PFIELD_FALL_TUBE 1
#define PFIELD_FALL_CONE 2
-//reserved for near future
-//#define PFIELD_FALL_INSIDE 3
+
+/* pd->shape */
+#define PFIELD_SHAPE_POINT 0
+#define PFIELD_SHAPE_PLANE 1
+#define PFIELD_SHAPE_SURFACE 2
+#define PFIELD_SHAPE_POINTS 3
/* pd->tex_mode */
#define PFIELD_TEX_RGB 0
#define PFIELD_TEX_GRAD 1
#define PFIELD_TEX_CURL 2
+/* pd->zdir */
+#define PFIELD_Z_BOTH 0
+#define PFIELD_Z_POS 1
+#define PFIELD_Z_NEG 2
+
/* pointcache->flag */
#define PTCACHE_BAKED 1
#define PTCACHE_OUTDATED 2
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index a89f8e1fb2e..ade22e4ebd4 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -134,7 +134,7 @@ typedef struct Object {
float loc[3], dloc[3], orig[3];
float size[3], dsize[3];
float rot[3], drot[3];
- /* float quat[4], dquat[4]; (not used yet) */
+ float quat[4], dquat[4];
float obmat[4][4];
float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */
float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */
@@ -176,9 +176,11 @@ typedef struct Object {
float max_vel; /* clamp the maximum velocity 0.0 is disabled */
float min_vel; /* clamp the maximum velocity 0.0 is disabled */
float m_contactProcessingThreshold;
-
+
+ short rotmode; /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */
+
char dt, dtx;
- char empty_drawtype, pad1[5];
+ char empty_drawtype, pad1[3];
float empty_drawsize;
float dupfacesca; /* dupliface scale */
@@ -243,6 +245,7 @@ typedef struct Object {
ListBase gpulamp; /* runtime, for lamps only */
ListBase pc_ids;
+ ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */
} Object;
/* Warning, this is not used anymore because hooks are now modifiers */
@@ -263,6 +266,14 @@ typedef struct ObHook {
float force;
} ObHook;
+typedef struct DupliObject {
+ struct DupliObject *next, *prev;
+ struct Object *ob;
+ unsigned int origlay;
+ int index, no_draw, type, animated;
+ float mat[4][4], omat[4][4];
+ float orco[3], uv[2];
+} DupliObject;
/* this work object is defined in object.c */
extern Object workob;
@@ -304,6 +315,7 @@ extern Object workob;
/* (short) transflag */
#define OB_OFFS_LOCAL 1
+ // XXX OB_QUAT was never used, but is now depreceated in favour of standard rotation handling...
#define OB_QUAT 2
#define OB_NEG_SCALE 4
#define OB_DUPLI (8+16+256+512+2048)
@@ -393,6 +405,7 @@ extern Object workob;
#define BA_HAS_RECALC_OB 4
#define BA_HAS_RECALC_DATA 8
+ // XXX DEPRECEATED SETTING...
#define BA_DO_IPO 32
#define BA_FROMSET 128
@@ -406,7 +419,7 @@ extern Object workob;
#define OB_FROMDUPLI 512
#define OB_DONE 1024
-#define OB_RADIO 2048
+#define OB_RADIO 2048 /* deprecated */
#define OB_FROMGROUP 4096
/* ob->recalc (flag bits!) */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 6a0a0e1d912..4c620ae527e 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -67,7 +67,7 @@ typedef struct ChildParticle {
int pa[4]; /* nearest particles to the child, used for the interpolation */
float w[4]; /* interpolation weights for the above particles */
float fuv[4], foffset; /* face vertex weights and offset */
- float rand[3];
+ float rt;
} ChildParticle;
typedef struct ParticleTarget {
@@ -114,6 +114,8 @@ typedef struct ParticleSettings {
struct BoidSettings *boids;
+ struct EffectorWeights *effector_weights;
+
int flag;
short type, from, distr;
/* physics modes */
@@ -176,10 +178,8 @@ typedef struct ParticleSettings {
/* keyed particles */
int keyed_loops;
- float effector_weight[10];
-
struct Group *dup_group;
- struct Group *eff_group;
+ struct Group *eff_group; // deprecated
struct Object *dup_ob;
struct Object *bb_ob;
struct Ipo *ipo; // xxx depreceated... old animation system
@@ -209,8 +209,6 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
struct Object *lattice;
struct Object *parent; /* particles from global space -> parent space */
- struct ListBase effectors, reactevents; /* runtime */
-
struct ListBase targets; /* used for keyed and boid physics */
char name[32]; /* particle system name */
@@ -233,14 +231,20 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
struct PointCache *pointcache;
struct ListBase ptcaches;
+ struct ListBase *effectors;
+
struct KDTree *tree; /* used for interactions with self and other systems */
+
+ struct ParticleDrawData *pdd;
+
+ float *frand; /* array of 1024 random floats for fast lookups */
}ParticleSystem;
/* part->type */
/* hair is allways baked static in object/geometry space */
/* other types (normal particles) are in global space and not static baked */
#define PART_EMITTER 0
-#define PART_REACTOR 1
+//#define PART_REACTOR 1
#define PART_HAIR 2
#define PART_FLUID 3
@@ -266,7 +270,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_ROT_DYN (1<<14) /* dynamic rotation */
#define PART_SIZEMASS (1<<16)
-//#define PART_KEYED_TIMING (1<<15)
+//#define PART_HAIR_GRAVITY (1<<15)
//#define PART_ABS_TIME (1<<17)
//#define PART_GLOB_TIME (1<<18)
@@ -325,7 +329,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_DRAW_EMITTER 8 /* render emitter also */
#define PART_DRAW_HEALTH 16
#define PART_ABS_PATH_TIME 32
-//#define PART_DRAW_TRAIL 64
+//#define PART_DRAW_TRAIL 64 /* deprecated */
#define PART_DRAW_BB_LOCK 128
#define PART_DRAW_PARENT 256
#define PART_DRAW_NUM 512
@@ -403,11 +407,13 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_CHILD_FACES 2
/* psys->recalc */
-#define PSYS_RECALC_REDO 1 /* only do pathcache etc */
-#define PSYS_RECALC_RESET 2 /* reset everything including pointcache */
-#define PSYS_RECALC_TYPE 4 /* handle system type change */
-#define PSYS_RECALC_CHILD 16 /* only child settings changed */
-#define PSYS_RECALC_PHYS 32 /* physics type changed */
+/* starts from 8 so that the first bits can be ob->recalc */
+#define PSYS_RECALC_REDO 8 /* only do pathcache etc */
+#define PSYS_RECALC_RESET 16 /* reset everything including pointcache */
+#define PSYS_RECALC_TYPE 32 /* handle system type change */
+#define PSYS_RECALC_CHILD 64 /* only child settings changed */
+#define PSYS_RECALC_PHYS 128 /* physics type changed */
+#define PSYS_RECALC 248
/* psys->flag */
#define PSYS_CURRENT 1
@@ -422,17 +428,17 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PSYS_HAIR_DONE 512
#define PSYS_KEYED 1024
#define PSYS_EDITED 2048
-//#define PSYS_PROTECT_CACHE 4096
+//#define PSYS_PROTECT_CACHE 4096 /* deprecated */
#define PSYS_DISABLED 8192
/* pars->flag */
#define PARS_UNEXIST 1
#define PARS_NO_DISP 2
-//#define PARS_STICKY 4
+//#define PARS_STICKY 4 /* deprecated */
#define PARS_REKEY 8
/* pars->alive */
-#define PARS_KILLED 0
+//#define PARS_KILLED 0 /* deprecated */
#define PARS_DEAD 1
#define PARS_UNBORN 2
#define PARS_ALIVE 3
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 73afc3d1a53..c5691b47157 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -93,6 +93,8 @@ typedef struct FFMpegCodecData {
int audio_codec;
int video_bitrate;
int audio_bitrate;
+ int audio_mixrate;
+ float audio_volume;
int gop_size;
int flags;
@@ -106,10 +108,13 @@ typedef struct FFMpegCodecData {
typedef struct AudioData {
- int mixrate;
- float main; /* Main mix in dB */
+ int mixrate; // 2.5: now in FFMpegCodecData: audio_mixrate
+ float main; // 2.5: now in FFMpegCodecData: audio_volume
+ float speed_of_sound;
+ float doppler_factor;
+ int distance_model;
short flag;
- short pad[3];
+ short pad;
} AudioData;
typedef struct SceneRenderLayer {
@@ -170,7 +175,6 @@ typedef struct RenderData {
struct AviCodecData *avicodecdata;
struct QuicktimeCodecData *qtcodecdata;
struct FFMpegCodecData ffcodecdata;
- struct AudioData audio; /* new in 2.5 */
int cfra, sfra, efra; /* frames as in 'images' */
int psfra, pefra; /* start+end frames of preview range */
@@ -663,6 +667,11 @@ typedef struct UnitSettings {
short flag; /* imperial, metric etc */
} UnitSettings;
+typedef struct PhysicsSettings {
+ float gravity[3];
+ int flag;
+} PhysicsSettings;
+
typedef struct Scene {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
@@ -697,7 +706,7 @@ typedef struct Scene {
/* migrate or replace? depends on some internal things... */
/* no, is on the right place (ton) */
struct RenderData r;
- struct AudioData audio; /* DEPRECATED 2.5 */
+ struct AudioData audio;
ListBase markers;
ListBase transform_spaces;
@@ -727,6 +736,9 @@ typedef struct Scene {
/* Grease Pencil */
struct bGPdata *gpd;
+
+ /* Physics simulation settings */
+ struct PhysicsSettings physics_settings;
} Scene;
@@ -1123,6 +1135,9 @@ typedef enum SculptFlags {
#define SK_RETARGET_ROLL_VIEW 1
#define SK_RETARGET_ROLL_JOINT 2
+/* physics_settings->flag */
+#define PHYS_GLOBAL_GRAVITY 1
+
/* UnitSettings */
/* UnitSettings->system */
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index cc998de7eec..a5ba5886ed5 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -126,6 +126,13 @@ typedef struct bRaySensor {
int axisflag;
} bRaySensor;
+typedef struct bArmatureSensor {
+ char posechannel[32];
+ char constraint[32];
+ int type;
+ float value;
+} bArmatureSensor;
+
typedef struct bMessageSensor {
/**
* (Possible future use) pointer to a single sender object
@@ -202,6 +209,15 @@ typedef struct bJoystickSensor {
#define SENS_MESG_MESG 0
#define SENS_MESG_PROP 1
+/* bArmatureSensor->type */
+#define SENS_ARM_STATE_CHANGED 0
+#define SENS_ARM_LIN_ERROR_BELOW 1
+#define SENS_ARM_LIN_ERROR_ABOVE 2
+#define SENS_ARM_ROT_ERROR_BELOW 3
+#define SENS_ARM_ROT_ERROR_ABOVE 4
+/* update this when adding new type */
+#define SENS_ARM_MAXTYPE 4
+
/* sensor->type */
#define SENS_ALWAYS 0
#define SENS_TOUCH 1
@@ -217,6 +233,7 @@ typedef struct bJoystickSensor {
#define SENS_JOYSTICK 11
#define SENS_ACTUATOR 12
#define SENS_DELAY 13
+#define SENS_ARMATURE 14
/* sensor->flag */
#define SENS_SHOW 1
#define SENS_DEL 2
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 6fdc3a7787b..2cd47e340bd 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -153,25 +153,25 @@ typedef struct FileSelectParams {
char title[24]; /* title, also used for the text of the execute button */
char dir[240]; /* directory */
char file[80]; /* file */
+ char renamefile[80];
- short flag; /* settings for filter, hiding files and display mode */
+ short type; /* XXXXX for now store type here, should be moved to the operator */
+ short flag; /* settings for filter, hiding dots files,... */
short sort; /* sort order */
short display; /* display mode flag */
short filter; /* filter when (flags & FILE_FILTER) is true */
/* XXX - temporary, better move to filelist */
short active_bookmark;
- short pad;
int active_file;
int selstate;
+ /* short */
/* XXX --- still unused -- */
short f_fp; /* show font preview */
short menu; /* currently selected option in pupmenu */
char fp_str[8]; /* string to use for font preview */
-
char *pupmenu; /* allows menu for save options - result stored in menup */
-
/* XXX --- end unused -- */
} FileSelectParams;
@@ -569,18 +569,19 @@ typedef struct SpaceUserPref {
/* buts->mainb new */
-#define BCONTEXT_SCENE 0
-#define BCONTEXT_WORLD 1
-#define BCONTEXT_OBJECT 2
-#define BCONTEXT_DATA 3
-#define BCONTEXT_MATERIAL 4
-#define BCONTEXT_TEXTURE 5
-#define BCONTEXT_PARTICLE 6
-#define BCONTEXT_PHYSICS 7
-#define BCONTEXT_BONE 9
-#define BCONTEXT_MODIFIER 10
-#define BCONTEXT_CONSTRAINT 12
-#define BCONTEXT_TOT 13
+#define BCONTEXT_SCENE 0
+#define BCONTEXT_WORLD 1
+#define BCONTEXT_OBJECT 2
+#define BCONTEXT_DATA 3
+#define BCONTEXT_MATERIAL 4
+#define BCONTEXT_TEXTURE 5
+#define BCONTEXT_PARTICLE 6
+#define BCONTEXT_PHYSICS 7
+#define BCONTEXT_BONE 9
+#define BCONTEXT_MODIFIER 10
+#define BCONTEXT_CONSTRAINT 12
+#define BCONTEXT_BONE_CONSTRAINT 13
+#define BCONTEXT_TOT 14
/* sbuts->flag */
#define SB_PRV_OSA 1
@@ -833,6 +834,7 @@ enum {
#define TIME_SEQ 32
#define TIME_ALL_IMAGE_WIN 64
#define TIME_CONTINUE_PHYSICS 128
+#define TIME_NODES 256
/* sseq->mainb */
#define SEQ_DRAW_SEQUENCE 0
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index c13c0522004..a43e5c7ae13 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -61,9 +61,27 @@ typedef struct MTex {
float r, g, b, k;
float def_var, rt;
- float colfac, norfac, varfac;
- float dispfac;
- float warpfac;
+ /* common */
+ float colfac, varfac;
+
+ /* material */
+ float norfac, dispfac, warpfac;
+ float colspecfac, mirrfac, alphafac;
+ float difffac, specfac, emitfac, hardfac;
+ float raymirrfac, translfac, ambfac;
+ float colemitfac, colreflfac, coltransfac;
+ float densfac, scatterfac, reflfac;
+
+ /* particles */
+ float timefac, lengthfac, clumpfac;
+ float kinkfac, roughfac, padensfac;
+ float lifefac, sizefac, ivelfac, pvelfac;
+
+ /* lamp */
+ float shadowfac;
+
+ /* world */
+ float zenupfac, zendownfac, blendfac;
} MTex;
#ifndef DNA_USHORT_FIX
@@ -167,7 +185,8 @@ typedef struct VoxelData {
int interp_type;
short file_format;
short flag;
- int pad;
+ short extend;
+ short pad;
struct Object *object; /* for rendering smoke sims */
float int_multiplier;
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index e221524eac2..f67a242b469 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -89,9 +89,7 @@ typedef struct RegionView3D {
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */
float pixsize;
float ofs[3];
- short camzoom, viewbut;
-
- int lastmode; /* for modal keymap switching, int because it stores notifier code */
+ short camzoom, viewbut, pad[2];
short rflag, viewlock;
short persp;
@@ -146,7 +144,7 @@ typedef struct View3D {
* The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID,
* OB_SHADED or OB_TEXTURE */
short drawtype;
- short localview;
+ short pad2;
short scenelock, around, pad3;
short flag, flag2;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 10f83c8b9ec..ea9d0e86c38 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -1,5 +1,5 @@
/**
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -80,6 +80,7 @@ typedef enum ReportType {
enum ReportListFlags {
RPT_PRINT = 1,
RPT_STORE = 2,
+ RPT_FREE = 4,
};
typedef struct Report {
struct Report *next, *prev;
@@ -161,7 +162,8 @@ typedef struct wmWindow {
ListBase timers;
ListBase queue; /* all events (ghost level events were handled) */
- ListBase handlers; /* window+screen handlers, overriding all queues */
+ ListBase handlers; /* window+screen handlers, handled last */
+ ListBase modalhandlers; /* priority handlers, handled first */
ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */
ListBase gesture; /* gesture stuff */
@@ -226,6 +228,7 @@ typedef struct wmOperatorType {
/* only used for operators defined with python
* use to store pointers to python functions */
void *pyop_data;
+ int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot);
} wmOperatorType;
@@ -264,6 +267,9 @@ typedef struct wmKeyMap {
short pad;
void *items; /* struct EnumPropertyItem for now */
+
+ /* verify if the keymap is enabled in the current context */
+ int (*poll)(struct bContext *);
} wmKeyMap;
@@ -297,7 +303,6 @@ typedef struct wmOperator {
#define OPERATOR_PASS_THROUGH 8
/* wmOperator flag */
-#define OPERATOR_REPORT_FREE 1
/* ************** wmEvent ************************ */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 05f39d73842..9ea7725b855 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -249,7 +249,6 @@ extern StructRNA RNA_LimitDistanceConstraint;
extern StructRNA RNA_LimitLocationConstraint;
extern StructRNA RNA_LimitRotationConstraint;
extern StructRNA RNA_LimitScaleConstraint;
-extern StructRNA RNA_LocalLamp;
extern StructRNA RNA_LockedTrackConstraint;
extern StructRNA RNA_MagicTexture;
extern StructRNA RNA_Main;
@@ -329,10 +328,12 @@ extern StructRNA RNA_PointCache;
extern StructRNA RNA_PointDensity;
extern StructRNA RNA_PointDensityTexture;
extern StructRNA RNA_PointerProperty;
+extern StructRNA RNA_PointLamp;
extern StructRNA RNA_Pose;
extern StructRNA RNA_PoseChannel;
extern StructRNA RNA_Property;
extern StructRNA RNA_PropertySensor;
+extern StructRNA RNA_ArmatureSensor;
extern StructRNA RNA_PythonConstraint;
extern StructRNA RNA_PythonController;
extern StructRNA RNA_RadarSensor;
@@ -586,6 +587,7 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
+int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension);
int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]);
char RNA_property_array_item_char(PropertyRNA *prop, int index);
@@ -691,6 +693,7 @@ char *RNA_path_back(const char *path);
int RNA_path_resolve(PointerRNA *ptr, const char *path,
PointerRNA *r_ptr, PropertyRNA **r_prop);
+char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
#if 0
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 42c5343dbff..37b175fbf12 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -83,6 +83,7 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont, const char *identifier
PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
+PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_enum(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);
@@ -101,6 +102,8 @@ PropertyRNA *RNA_def_float_dynamic_array(StructOrFunctionRNA *cont, const char *
*/
PropertyRNA *RNA_def_float_percentage(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_factor(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_pointer(StructOrFunctionRNA *cont, const char *identifier, const char *type,
const char *ui_name, const char *ui_description);
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index c6fed5cd8e6..98df8c34d58 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -89,13 +89,15 @@ typedef enum PropertySubType {
/* strings */
PROP_FILEPATH = 1,
PROP_DIRPATH = 2,
+ PROP_FILENAME = 3,
/* numbers */
PROP_UNSIGNED = 13,
PROP_PERCENTAGE = 14,
- PROP_ANGLE = 15|PROP_UNIT_ROTATION,
- PROP_TIME = 16|PROP_UNIT_TIME,
- PROP_DISTANCE = 17|PROP_UNIT_LENGTH,
+ PROP_FACTOR = 15,
+ PROP_ANGLE = 16|PROP_UNIT_ROTATION,
+ PROP_TIME = 17|PROP_UNIT_TIME,
+ PROP_DISTANCE = 18|PROP_UNIT_LENGTH,
/* number arrays */
PROP_COLOR = 20,
@@ -106,11 +108,9 @@ typedef enum PropertySubType {
PROP_MATRIX = 25,
PROP_EULER = 26|PROP_UNIT_ROTATION,
PROP_QUATERNION = 27,
- PROP_XYZ = 28,
- PROP_RGB = 29,
-
- /* pointers */
- PROP_NEVER_NULL = 30,
+ PROP_AXISANGLE = 28,
+ PROP_XYZ = 29,
+ PROP_RGB = 30,
/* booleans */
PROP_LAYER = 40,
@@ -148,6 +148,7 @@ typedef enum PropertyFlag {
/* pointers */
PROP_ID_REFCOUNT = 64,
+ PROP_NEVER_NULL = 262144,
/* internal flags */
PROP_BUILTIN = 128,
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index 845abf636e2..72dc6be683c 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -7,7 +7,7 @@ o = SConscript('intern/SConscript')
objs += o
incs = '#/intern/guardedalloc ../blenkernel ../blenlib ../makesdna intern .'
-incs += ' ../windowmanager ../editors/include ../imbuf'
+incs += ' ../windowmanager ../editors/include ../imbuf ../ikplugin'
incs += ' ../render/extern/include'
defs = []
@@ -40,4 +40,12 @@ if env['WITH_BF_GAMEENGINE']:
if env['BF_UNIT_TEST']:
defs.append('UNIT_TEST')
+
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core','player'], priority = [165,20] )
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 709c5d017ec..c9c02fbecde 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -39,9 +39,13 @@ SET(SRC
../../../../intern/guardedalloc/intern/mallocn.c
../../../../intern/guardedalloc/intern/mmap_win.c)
-INCLUDE_DIRECTORIES(../../../../intern/guardedalloc .. ../../makesdna ../../blenkernel ../../blenlib ../../windowmanager ../../editors/include ../../imbuf ../../render/extern/include .)
+INCLUDE_DIRECTORIES(../../../../intern/guardedalloc .. ../../makesdna ../../blenkernel ../../blenlib ../../ikplugin ../../windowmanager ../../editors/include ../../imbuf ../../render/extern/include .)
FILE(GLOB INC_FILES ../*.h ../../makesdna/*.h)
+IF(WIN32)
+ SET(INC ${INC} ${PTHREADS_INC})
+ENDIF(WIN32)
+
IF(WITH_GAMEENGINE)
ADD_DEFINITIONS(-DGAMEBLENDER)
ENDIF(WITH_GAMEENGINE)
diff --git a/source/blender/makesrna/intern/Makefile b/source/blender/makesrna/intern/Makefile
index 4a4e41edd15..7923ea1e7de 100644
--- a/source/blender/makesrna/intern/Makefile
+++ b/source/blender/makesrna/intern/Makefile
@@ -49,6 +49,7 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../imbuf
+CPPFLAGS += -I../../ikplugin
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../windowmanager
CPPFLAGS += -I../../editors/include
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index 569f0547731..c63b63ce5f7 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -30,7 +30,7 @@ makesrna_tool.Append(CCFLAGS = '-DBASE_HEADER="\\"source/blender/makesrna/\\"" '
defs = []
incs = '#/intern/guardedalloc ../../blenlib ../../blenkernel'
-incs += ' ../../imbuf ../../makesdna ../../makesrna'
+incs += ' ../../imbuf ../../makesdna ../../makesrna ../../ikplugin'
incs += ' ../../windowmanager ../../editors/include'
incs += ' ../../render/extern/include'
@@ -74,6 +74,14 @@ if env['WITH_BF_JACK']:
if env['BF_UNIT_TEST']:
defs.append('UNIT_TEST')
+
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
makesrna_tool.Append(CPPDEFINES=defs)
makesrna_tool.Append (CPPPATH = Split(incs))
@@ -126,7 +134,7 @@ rna.Depends (generated_files, makesrna)
# this seems bad, how to retrieve it from scons?
build_dir = root_build_dir + os.sep +'source' + os.sep + 'blender' + os.sep + 'makesrna' + os.sep + 'intern' + os.sep
-
+
if env['OURPLATFORM'] != 'linuxcross':
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
rna.Command (generated_files, '', "\"" + root_build_dir+os.sep+"makesrna.exe\" \"" + build_dir )
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index d0c7824dc9d..63b58f27c53 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1406,6 +1406,7 @@ static const char *rna_property_subtypename(PropertyType type)
case PROP_DIRPATH: return "PROP_DIRPATH";
case PROP_UNSIGNED: return "PROP_UNSIGNED";
case PROP_PERCENTAGE: return "PROP_PERCENTAGE";
+ case PROP_FACTOR: return "PROP_FACTOR";
case PROP_ANGLE: return "PROP_ANGLE";
case PROP_TIME: return "PROP_TIME";
case PROP_DISTANCE: return "PROP_DISTANCE";
@@ -1415,11 +1416,11 @@ static const char *rna_property_subtypename(PropertyType type)
case PROP_MATRIX: return "PROP_MATRIX";
case PROP_EULER: return "PROP_EULER";
case PROP_QUATERNION: return "PROP_QUATERNION";
+ case PROP_AXISANGLE: return "PROP_AXISANGLE";
case PROP_VELOCITY: return "PROP_VELOCITY";
case PROP_ACCELERATION: return "PROP_ACCELERATION";
case PROP_XYZ: return "PROP_XYZ";
case PROP_RGB: return "PROP_RGB";
- case PROP_NEVER_NULL: return "PROP_NEVER_NULL";
case PROP_LAYER: return "PROP_LAYER";
case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER";
default: {
@@ -1969,7 +1970,7 @@ RNAProcessItem PROCESS_ITEMS[]= {
{"rna_rna.c", NULL, RNA_def_rna},
{"rna_ID.c", NULL, RNA_def_ID},
{"rna_texture.c", NULL, RNA_def_texture},
- {"rna_action.c", NULL, RNA_def_action},
+ {"rna_action.c", "rna_action_api.c", RNA_def_action},
{"rna_animation.c", "rna_animation_api.c", RNA_def_animation},
{"rna_actuator.c", NULL, RNA_def_actuator},
{"rna_armature.c", NULL, RNA_def_armature},
@@ -1986,12 +1987,12 @@ RNAProcessItem PROCESS_ITEMS[]= {
{"rna_fluidsim.c", NULL, RNA_def_fluidsim},
{"rna_gpencil.c", NULL, RNA_def_gpencil},
{"rna_group.c", NULL, RNA_def_group},
- {"rna_image.c", NULL, RNA_def_image},
+ {"rna_image.c", "rna_image_api.c", RNA_def_image},
{"rna_key.c", NULL, RNA_def_key},
{"rna_lamp.c", NULL, RNA_def_lamp},
{"rna_lattice.c", NULL, RNA_def_lattice},
{"rna_main.c", "rna_main_api.c", RNA_def_main},
- {"rna_material.c", NULL, RNA_def_material},
+ {"rna_material.c", "rna_material_api.c", RNA_def_material},
{"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh},
{"rna_meta.c", NULL, RNA_def_meta},
{"rna_modifier.c", NULL, RNA_def_modifier},
@@ -2001,7 +2002,7 @@ RNAProcessItem PROCESS_ITEMS[]= {
{"rna_object_force.c", NULL, RNA_def_object_force},
{"rna_packedfile.c", NULL, RNA_def_packedfile},
{"rna_particle.c", NULL, RNA_def_particle},
- {"rna_pose.c", NULL, RNA_def_pose},
+ {"rna_pose.c", "rna_pose_api.c", RNA_def_pose},
{"rna_property.c", NULL, RNA_def_gameproperty},
{"rna_render.c", NULL, RNA_def_render},
{"rna_scene.c", "rna_scene_api.c", RNA_def_scene},
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index f5c6063e892..8ab5a1442c7 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -178,6 +178,18 @@ StructRNA* rna_IDPropertyGroup_refine(PointerRNA *ptr)
return ptr->type;
}
+ID *rna_ID_copy(ID *id)
+{
+ ID *newid;
+
+ if(id_copy(id, &newid, 0)) {
+ if(newid) newid->us--;
+ return newid;
+ }
+
+ return NULL;
+}
+
#else
static void rna_def_ID_properties(BlenderRNA *brna)
@@ -243,7 +255,8 @@ static void rna_def_ID_properties(BlenderRNA *brna)
static void rna_def_ID(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *prop, *parm;
srna= RNA_def_struct(brna, "ID", NULL);
RNA_def_struct_ui_text(srna, "ID", "Base type for datablocks, defining a unique name, linking from other libraries and garbage collection.");
@@ -271,6 +284,12 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "lib");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Library", "Library file the datablock is linked from.");
+
+ /* functions */
+ func= RNA_def_function(srna, "copy", "rna_ID_copy");
+ RNA_def_function_ui_description(func, "Create a copy of this datablock (not supported for all datablocks).");
+ parm= RNA_def_pointer(func, "id", "ID", "", "New copy of the ID.");
+ RNA_def_function_return(func, parm);
}
static void rna_def_library(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index e4bda24cf20..21fbc9fa66d 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -225,6 +225,18 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
}
}
+static int rna_ensure_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
+{
+ if(prop->magic == RNA_MAGIC) {
+ return (prop->getlength || prop->totarraylength) ? 1:0;
+ }
+ else {
+ IDProperty *idprop= (IDProperty*)prop;
+
+ return idprop->type == IDP_ARRAY ? 1:0;
+ }
+}
+
static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
{
if(prop->magic == RNA_MAGIC) {
@@ -574,6 +586,11 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
return rna_ensure_property_array_length(ptr, prop);
}
+int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
+{
+ return rna_ensure_property_array_check(ptr, prop);
+}
+
/* used by BPY to make an array from the python object */
int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
{
@@ -603,7 +620,7 @@ char RNA_property_array_item_char(PropertyRNA *prop, int index)
PropertySubType subtype= rna_ensure_property(prop)->subtype;
/* get string to use for array index */
- if ((index < 4) && (subtype == PROP_QUATERNION))
+ if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE))
return quatitem[index];
else if((index < 4) && ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
return vectoritem[index];
@@ -1392,10 +1409,17 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
{
- PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
+ IDProperty *idprop;
- if(pprop->set)
- pprop->set(ptr, ptr_value);
+ if((idprop=rna_idproperty_check(&prop, ptr))) {
+ /* not supported */
+ }
+ else {
+ PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
+
+ if(pprop->set && !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL))
+ pprop->set(ptr, ptr_value);
+ }
}
void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
@@ -2363,12 +2387,11 @@ char *RNA_path_back(const char *path)
return result;
}
-char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
+char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
{
- char *ptrpath=NULL, *path;
- const char *propname;
+ char *ptrpath=NULL;
- if(!ptr->id.data || !ptr->data || !prop)
+ if(!ptr->id.data || !ptr->data)
return NULL;
if(!RNA_struct_is_ID(ptr->type)) {
@@ -2394,6 +2417,20 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
else
return NULL;
}
+
+ return ptrpath;
+}
+
+char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
+{
+ const char *propname;
+ char *ptrpath, *path;
+
+ if(!ptr->id.data || !ptr->data || !prop)
+ return NULL;
+
+ /* path from ID to the struct holding this property */
+ ptrpath= RNA_path_from_ID_to_struct(ptr);
propname= RNA_property_identifier(prop);
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index e376d3125e3..eaa11b4ad38 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -38,7 +38,7 @@
#else
-void rna_def_action_group(BlenderRNA *brna)
+static void rna_def_action_group(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -76,7 +76,7 @@ void rna_def_action_group(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Custom Color", "Index of custom color set.");
}
-void rna_def_action(BlenderRNA *brna)
+static void rna_def_action(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -100,6 +100,8 @@ void rna_def_action(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "markers", NULL);
RNA_def_property_struct_type(prop, "TimelineMarker");
RNA_def_property_ui_text(prop, "Pose Markers", "Markers specific to this Action, for labeling poses.");
+
+ RNA_api_action(srna);
}
/* --------- */
diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c
new file mode 100644
index 00000000000..991a8251cc5
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_action_api.c
@@ -0,0 +1,80 @@
+/**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Arystanbek Dyussenov
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#include "DNA_action_types.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_action.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_curve_types.h"
+
+/* XXX disabled until RNA allows returning arrays */
+#if 0
+/* return frame range of all curves (min, max) or (0, 1) if there are no keys */
+int *rna_Action_get_frame_range(bAction *act, int *ret_length)
+{
+ int *ret;
+ float start, end;
+
+ calc_action_range(act, &start, &end, 1);
+
+ *ret_length= 2;
+ ret= MEM_callocN(*ret_length * sizeof(int), "rna_Action_get_frame_range");
+
+ ret[0]= (int)start;
+ ret[1]= (int)end;
+
+ return ret;
+}
+#endif
+
+#else
+
+void RNA_api_action(StructRNA *srna)
+{
+#if 0
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "get_frame_range", "rna_Action_get_frame_range");
+ RNA_def_function_ui_description(func, "Get action frame range as a (min, max) tuple.");
+ parm= RNA_def_int_array(func, "frame_range", 1, NULL, 0, 0, "", "Action frame range.", 0, 0);
+ RNA_def_property_flag(parm, PROP_DYNAMIC_ARRAY);
+ RNA_def_function_return(func, parm);
+#endif
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 473e726db60..ce83d1c469b 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -58,6 +58,7 @@ void RNA_def_actuator(BlenderRNA *brna)
{ACT_PARENT, "PARENT", 0, "Parent", ""},
{ACT_SHAPEACTION, "SHAPE_ACTION", 0, "Shape Action", ""},
{ACT_STATE, "STATE", 0, "State", ""},
+ {ACT_ARMATURE, "ARMATURE", 0, "Armature", ""},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Actuator", NULL);
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index e4bea893992..4b2c11c2e0d 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -57,6 +57,12 @@ static int rna_AnimData_action_editable(PointerRNA *ptr)
return 1;
}
+static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
+{
+ AnimData *adt= (AnimData*)(ptr->data);
+ adt->action= value.data;
+}
+
static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value)
{
KS_Path *ksp= (KS_Path *)ptr->data;
@@ -93,7 +99,7 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value)
#else
-void rna_def_keyingset_path(BlenderRNA *brna)
+static void rna_def_keyingset_path(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -132,7 +138,7 @@ void rna_def_keyingset_path(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Entire Array", "When an 'array/vector' type is chosen (Location, Rotation, Color, etc.), entire array is to be used.");
}
-void rna_def_keyingset(BlenderRNA *brna)
+static void rna_def_keyingset(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -202,8 +208,11 @@ void rna_def_animdata(BlenderRNA *brna)
/* Active Action */
prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
- RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock.");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE); /* this flag as well as the dynamic test must be defined for this to be editable... */
RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
+ RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock.");
+
/* Active Action Settings */
prop= RNA_def_property(srna, "action_extrapolation", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 57eb3c1de4a..5dbfdd3e6f1 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -52,6 +52,7 @@ static void rna_Armature_update_data(bContext *C, PointerRNA *ptr)
DAG_id_flush_update(id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, id);
+ //WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL);
}
static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr)
@@ -61,6 +62,11 @@ static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr)
WM_event_add_notifier(C, NC_GEOM|ND_DATA, id);
}
+static char *rna_Bone_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("bones[\"%s\"]", ((Bone*)ptr->data)->name);
+}
+
static void rna_bone_layer_set(short *layer, const int *values)
{
int i, tot= 0;
@@ -430,6 +436,7 @@ static void rna_def_bone(BlenderRNA *brna)
srna= RNA_def_struct(brna, "Bone", NULL);
RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature datablock.");
RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
+ RNA_def_struct_path_func(srna, "rna_Bone_path");
/* pointers/collections */
/* parent (pointer) */
@@ -457,6 +464,37 @@ static void rna_def_bone(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED);
RNA_def_property_ui_text(prop, "Selected", "");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
+
+ /* XXX better matrix descriptions possible (Arystan) */
+ prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "bone_mat");
+ RNA_def_property_array(prop, 9);
+ RNA_def_property_ui_text(prop, "Bone Matrix", "3x3 bone matrix.");
+
+ prop= RNA_def_property(srna, "armature_matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "arm_mat");
+ RNA_def_property_array(prop, 16);
+ RNA_def_property_ui_text(prop, "Bone Armature-Relative Matrix", "4x4 bone matrix relative to armature.");
+
+ prop= RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "tail");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone.");
+
+ prop= RNA_def_property(srna, "armature_tail", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "arm_tail");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Armature-Relative Tail", "Location of tail end of the bone relative to armature.");
+
+ prop= RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "head");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone.");
+
+ prop= RNA_def_property(srna, "armature_head", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "arm_head");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Armature-Relative Head", "Location of head end of the bone relative to armature.");
}
static void rna_def_edit_bone(BlenderRNA *brna)
@@ -520,29 +558,43 @@ static void rna_def_edit_bone(BlenderRNA *brna)
RNA_define_verify_sdna(1);
}
-void rna_def_armature(BlenderRNA *brna)
+static void rna_def_armature(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem prop_drawtype_items[] = {
- {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Draw bones as octahedral shape (default)."},
- {ARM_LINE, "STICK", 0, "Stick", "Draw bones as simple 2D lines with dots."},
- {ARM_B_BONE, "BBONE", 0, "B-Bone", "Draw bones as boxes, showing subdivision and B-Splines"},
- {ARM_ENVELOPE, "ENVELOPE", 0, "Envelope", "Draw bones as extruded spheres, showing defomation influence volume."},
+ {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Display bones as octahedral shape (default)."},
+ {ARM_LINE, "STICK", 0, "Stick", "Display bones as simple 2D lines with dots."},
+ {ARM_B_BONE, "BBONE", 0, "B-Bone", "Display bones as boxes, showing subdivision and B-Splines"},
+ {ARM_ENVELOPE, "ENVELOPE", 0, "Envelope", "Display bones as extruded spheres, showing defomation influence volume."},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_ghost_type_items[] = {
- {ARM_GHOST_CUR, "CURRENT_FRAME", 0, "Around Current Frame", "Draw Ghosts of poses within a fixed number of frames around the current frame."},
- {ARM_GHOST_RANGE, "RANGE", 0, "In Range", "Draw Ghosts of poses within specified range."},
- {ARM_GHOST_KEYS, "KEYS", 0, "On Keyframes", "Draw Ghosts of poses on Keyframes."},
+ {ARM_GHOST_CUR, "CURRENT_FRAME", 0, "Around Frame", "Display Ghosts of poses within a fixed number of frames around the current frame."},
+ {ARM_GHOST_RANGE, "RANGE", 0, "In Range", "Display Ghosts of poses within specified range."},
+ {ARM_GHOST_KEYS, "KEYS", 0, "On Keyframes", "Display Ghosts of poses on Keyframes."},
+ {0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem prop_paths_type_items[]= {
+ {ARM_PATH_ACFRA, "CURRENT_FRAME", 0, "Around Frame", "Display Paths of poses within a fixed number of frames around the current frame."},
+ {0, "RANGE", 0, "In Range", "Display Paths of poses within specified range."},
+ {0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem prop_paths_location_items[]= {
+ {ARM_PATH_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"},
+ {0, "TAILS", 0, "Tails", "Calculate bone paths from tails"},
+ {0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem prop_pose_position_items[]= {
+ {0, "POSE_POSITION", 0, "Pose Position", "Show armature in posed state."},
+ {ARM_RESTPOS, "REST_POSITION", 0, "Rest Position", "Show Armature in binding pose state. No posing possible."},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Armature", "ID");
RNA_def_struct_ui_text(srna, "Armature", "Armature datablock containing a hierarchy of bones, usually used for rigging characters.");
RNA_def_struct_ui_icon(srna, ICON_ARMATURE_DATA);
-
RNA_def_struct_sdna(srna, "bArmature");
+ /* Animation Data */
+ rna_def_animdata_common(srna);
+
/* Collections */
prop= RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
@@ -556,6 +608,17 @@ void rna_def_armature(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Edit Bones", "");
/* Enum values */
+// prop= RNA_def_property(srna, "rest_position", PROP_BOOLEAN, PROP_NONE);
+// RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_RESTPOS);
+// RNA_def_property_ui_text(prop, "Rest Position", "Show Armature in Rest Position. No posing possible.");
+// RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+
+ prop= RNA_def_property(srna, "pose_position", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, prop_pose_position_items);
+ RNA_def_property_ui_text(prop, "Pose Position", "Show armature in binding pose or final posed state.");
+ RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+
prop= RNA_def_property(srna, "drawtype", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_drawtype_items);
RNA_def_property_ui_text(prop, "Draw Type", "");
@@ -564,7 +627,19 @@ void rna_def_armature(BlenderRNA *brna)
prop= RNA_def_property(srna, "ghost_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ghosttype");
RNA_def_property_enum_items(prop, prop_ghost_type_items);
- RNA_def_property_ui_text(prop, "Ghost Drawing", "Method of Onion-skinning for active Action");
+ RNA_def_property_ui_text(prop, "Ghost Type", "Method of Onion-skinning for active Action");
+ RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
+
+ prop= RNA_def_property(srna, "paths_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "pathflag");
+ RNA_def_property_enum_items(prop, prop_paths_type_items);
+ RNA_def_property_ui_text(prop, "Paths Type", "Type of range to show for Bone Paths");
+ RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
+
+ prop= RNA_def_property(srna, "paths_location", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "pathflag");
+ RNA_def_property_enum_items(prop, prop_paths_location_items);
+ RNA_def_property_ui_text(prop, "Paths Location", "When calculating Bone Paths, use Head or Tips");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
/* Boolean values */
@@ -574,7 +649,7 @@ void rna_def_armature(BlenderRNA *brna)
RNA_def_property_array(prop, 16);
RNA_def_property_ui_text(prop, "Visible Layers", "Armature layer visibility.");
RNA_def_property_boolean_funcs(prop, NULL, "rna_Armature_layer_set");
- RNA_def_property_update(prop, NC_OBJECT|ND_POSE, NULL);
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
/* layer protection */
@@ -585,10 +660,7 @@ void rna_def_armature(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
/* flag */
- prop= RNA_def_property(srna, "rest_position", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_RESTPOS);
- RNA_def_property_ui_text(prop, "Rest Position", "Show Armature in Rest Position. No posing possible.");
- RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+
prop= RNA_def_property(srna, "draw_axes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWAXES);
@@ -626,8 +698,8 @@ void rna_def_armature(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
prop= RNA_def_property(srna, "ghost_only_selected", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ARM_GHOST_ONLYSEL);
- RNA_def_property_ui_text(prop, "Draw Ghosts on Selected Keyframes Only", "");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_GHOST_ONLYSEL);
+ RNA_def_property_ui_text(prop, "Draw Ghosts on Selected Bones Only", "");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
/* deformflag */
@@ -672,15 +744,6 @@ void rna_def_armature(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Paths Show Keyframe Numbers", "When drawing Armature in Pose Mode, show frame numbers of Keyframes on Bone Paths");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
- prop= RNA_def_property(srna, "paths_show_around_current_frame", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "pathflag", ARM_PATH_ACFRA);
- RNA_def_property_ui_text(prop, "Paths Around Current Frame", "When drawing Armature in Pose Mode, only show section of Bone Paths that falls around current frame");
- RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
- prop= RNA_def_property(srna, "paths_calculate_head_positions", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "pathflag", ARM_PATH_HEADS);
- RNA_def_property_ui_text(prop, "Paths Use Heads", "When calculating Bone Paths, use Head locations instead of Tips");
- RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
/* Number fields */
/* ghost/onionskining settings */
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 8002aa89313..36a648c8a82 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -74,44 +74,33 @@ EnumPropertyItem boidruleset_type_items[] ={
static void rna_Boids_reset(bContext *C, PointerRNA *ptr)
{
- Scene *scene = CTX_data_scene(C);
- ParticleSettings *part;
-
if(ptr->type==&RNA_ParticleSystem) {
ParticleSystem *psys = (ParticleSystem*)ptr->data;
- Object *ob = psys_find_object(scene, psys);
psys->recalc = PSYS_RECALC_RESET;
- if(ob)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
- else {
- part = ptr->id.data;
- psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
+ DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
}
+ else
+ DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
}
static void rna_Boids_reset_deps(bContext *C, PointerRNA *ptr)
{
Scene *scene = CTX_data_scene(C);
- ParticleSettings *part;
if(ptr->type==&RNA_ParticleSystem) {
ParticleSystem *psys = (ParticleSystem*)ptr->data;
- Object *ob = psys_find_object(scene, psys);
psys->recalc = PSYS_RECALC_RESET;
- if(ob)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
- else {
- part = ptr->id.data;
- psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
- DAG_scene_sort(scene);
+ DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
}
+ else
+ DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET);
+
+ DAG_scene_sort(scene);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 448a2046855..e87c8434a7d 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Contributor(s): Blender Foundation (2008), Juho Vepsäläinen
+ * Contributor(s): Blender Foundation (2008), Juho Veps�l�inen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -51,6 +51,9 @@ EnumPropertyItem brush_sculpt_tool_items[] = {
#include "BKE_texture.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
static void rna_Brush_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Brush *brush= (Brush*)ptr->data;
@@ -87,9 +90,58 @@ static void rna_Brush_active_texture_set(PointerRNA *ptr, PointerRNA value)
}
}
+static void rna_Brush_update(bContext *C, PointerRNA *ptr)
+{
+ Brush *br= (Brush*)ptr->data;
+ WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, br);
+}
+
+static float rna_BrushTextureSlot_angle_get(PointerRNA *ptr)
+{
+ MTex *tex= (MTex*)ptr->data;
+ const float conv = 57.295779506;
+ return tex->rot * conv;
+}
+
+static void rna_BrushTextureSlot_angle_set(PointerRNA *ptr, float v)
+{
+ MTex *tex= (MTex*)ptr->data;
+ const float conv = 0.017453293;
+ tex->rot = v * conv;
+}
+
#else
-void rna_def_brush(BlenderRNA *brna)
+static void rna_def_brush_texture_slot(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_map_mode_items[] = {
+ {MTEX_MAP_MODE_FIXED, "FIXED", 0, "Fixed", ""},
+ {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""},
+ {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "BrushTextureSlot", "TextureSlot");
+ RNA_def_struct_sdna(srna, "MTex");
+ RNA_def_struct_ui_text(srna, "Brush Texture Slot", "Texture slot for textures in a Brush datablock.");
+
+ prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "rot");
+ RNA_def_property_range(prop, 0, 360);
+ RNA_def_property_float_funcs(prop, "rna_BrushTextureSlot_angle_get", "rna_BrushTextureSlot_angle_set", NULL);
+ RNA_def_property_ui_text(prop, "Angle", "Defines brush texture rotation.");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
+
+ prop= RNA_def_property(srna, "map_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode");
+ RNA_def_property_enum_items(prop, prop_map_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
+}
+
+static void rna_def_brush(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -104,6 +156,11 @@ void rna_def_brush(BlenderRNA *brna)
{IMB_BLEND_ERASE_ALPHA, "ERASE_ALPHA", 0, "Erase Alpha", "Erase alpha while painting."},
{IMB_BLEND_ADD_ALPHA, "ADD_ALPHA", 0, "Add Alpha", "Add alpha while painting."},
{0, NULL, 0, NULL, NULL}};
+
+ static const EnumPropertyItem prop_flip_direction_items[]= {
+ {0, "ADD", 0, "Add", "Add effect of brush"},
+ {BRUSH_DIR_IN, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"},
+ {0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Brush", "ID");
RNA_def_struct_ui_text(srna, "Brush", "Brush datablock for storing brush settings for painting and sculpting.");
@@ -113,128 +170,157 @@ void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_blend_items);
RNA_def_property_ui_text(prop, "Blending mode", "Brush blending mode.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "sculpt_tool", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_sculpt_tool_items);
RNA_def_property_ui_text(prop, "Sculpt Tool", "");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop= RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, prop_flip_direction_items);
+ RNA_def_property_ui_text(prop, "Direction", "Mapping type to use for this image in the game engine.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
/* number values */
prop= RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 1, 200);
RNA_def_property_ui_text(prop, "Size", "Diameter of the brush.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "innerradius");
+ prop= RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "jitter");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Falloff", "Falloff radius of the brush.");
-
+ RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush while painting.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop= RNA_def_property(srna, "spacing", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spacing");
RNA_def_property_range(prop, 1.0f, 100.0f);
RNA_def_property_ui_text(prop, "Spacing", "Spacing between brush stamps.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "smooth_stroke_radius", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 10, 200);
RNA_def_property_ui_text(prop, "Smooth Stroke Radius", "Minimum distance from last point before stroke continues.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "smooth_stroke_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.5, 0.99);
RNA_def_property_ui_text(prop, "Smooth Stroke Factor", "Higher values give a smoother stroke.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "rate", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rate");
RNA_def_property_range(prop, 0.010f, 1.0f);
RNA_def_property_ui_text(prop, "Rate", "Number of paints per second for Airbrush.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "rgb");
RNA_def_property_ui_text(prop, "Color", "");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "alpha");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Strength", "The amount of pressure on the brush.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
/* flag */
- prop= RNA_def_property(srna, "airbrush", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_airbrush", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_AIRBRUSH);
RNA_def_property_ui_text(prop, "Airbrush", "Keep applying paint effect while holding mouse (spray).");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "wrap", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_wrap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_TORUS);
RNA_def_property_ui_text(prop, "Wrap", "Enable torus wrapping while painting.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "strength_pressure", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "size_pressure", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_size_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SIZE_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "falloff_pressure", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RAD_PRESSURE);
+ prop= RNA_def_property(srna, "use_jitter_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_JITTER_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
- RNA_def_property_ui_text(prop, "Falloff Pressure", "Enable tablet pressure sensitivity for falloff.");
-
- prop= RNA_def_property(srna, "spacing_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Jitter Pressure", "Enable tablet pressure sensitivity for jitter.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop= RNA_def_property(srna, "use_spacing_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACING_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Spacing Pressure", "Enable tablet pressure sensitivity for spacing.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "rake", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_rake", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RAKE);
RNA_def_property_ui_text(prop, "Rake", "Rotate the brush texture to match the stroke direction.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "anchored", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_anchor", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ANCHORED);
RNA_def_property_ui_text(prop, "Anchored", "Keep the brush anchored to the initial location.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "flip_direction", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_DIR_IN);
- RNA_def_property_ui_text(prop, "Flip Direction", "Move vertices in the opposite direction.");
-
- prop= RNA_def_property(srna, "space", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_space", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE);
RNA_def_property_ui_text(prop, "Space", "Limit brush application to the distance specified by spacing.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "smooth_stroke", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_smooth_stroke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SMOOTH_STROKE);
RNA_def_property_ui_text(prop, "Smooth Stroke", "Brush lags behind mouse and follows a smoother path.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop= RNA_def_property(srna, "persistent", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_persistent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_PERSISTENT);
RNA_def_property_ui_text(prop, "Persistent", "Sculpts on a persistent layer of the mesh.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
/* not exposed in the interface yet
prop= RNA_def_property(srna, "fixed_tex", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_FIXED_TEX);
- RNA_def_property_ui_text(prop, "Fixed Texture", "Keep texture origin in fixed position.");*/
+ RNA_def_property_ui_text(prop, "Fixed Texture", "Keep texture origin in fixed position.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update"); */
- prop= RNA_def_property(srna, "curve", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Curve", "Editable falloff curve.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
/* texture */
rna_def_mtex_common(srna, "rna_Brush_mtex_begin", "rna_Brush_active_texture_get",
- "rna_Brush_active_texture_set", "TextureSlot");
+ "rna_Brush_active_texture_set", "BrushTextureSlot", "rna_Brush_update");
/* clone tool */
prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "clone.image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Clone Image", "Image for clone tool.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "clone_opacity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clone.alpha");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Clone Opacity", "Opacity of clone image display.");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "clone_offset", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "clone.offset");
RNA_def_property_ui_text(prop, "Clone Offset", "");
RNA_def_property_ui_range(prop, -1.0f , 1.0f, 10.0f, 3);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
}
@@ -286,6 +372,7 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna)
void RNA_def_brush(BlenderRNA *brna)
{
rna_def_brush(brna);
+ rna_def_brush_texture_slot(brna);
rna_def_operator_stroke_element(brna);
}
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 9c33b0afb00..6254041c7ef 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -22,7 +22,9 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#define _USE_MATH_DEFINES
#include <stdlib.h>
+#include <math.h>
#include "RNA_define.h"
#include "RNA_types.h"
@@ -35,6 +37,19 @@
#ifdef RNA_RUNTIME
+static void rna_Camera_angle_update(bContext *C, PointerRNA *ptr)
+{
+ Camera *cam= (Camera*)ptr->id.data;
+ cam->lens = 16.0f / tan(M_PI*cam->angle/360.0f);
+}
+
+static void rna_Camera_lens_update(bContext *C, PointerRNA *ptr)
+{
+ Camera *cam= (Camera*)ptr->id.data;
+ cam->angle= 360.0f * atan(16.0f/cam->lens) / M_PI;
+}
+
+
#else
void RNA_def_camera(BlenderRNA *brna)
@@ -62,7 +77,7 @@ void RNA_def_camera(BlenderRNA *brna)
/* Number values */
- prop= RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "passepartalpha");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view.");
@@ -72,7 +87,7 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Angle", "Perspective Camera lend field of view in degrees.");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_angle_update");
prop= RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clipsta");
@@ -90,7 +105,7 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "lens");
RNA_def_property_range(prop, 1.0f, 250.0f);
RNA_def_property_ui_text(prop, "Lens", "Perspective Camera lens value in mm.");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_lens_update");
prop= RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ortho_scale");
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 22cc2e2c9c3..d64e2c7119b 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -306,6 +306,11 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bending Stiffness Vertex Group", "Vertex group for fine control over bending stiffness.");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "EffectorWeights");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Effector Weights", "");
+
/* unused */
/* unused still
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 420add2622a..4cef6fa481f 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -216,13 +216,15 @@ static void rna_def_curvemapping(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "CurveMap");
RNA_def_property_ui_text(prop, "Curves", "");
- prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_COLOR);
+ prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_RGB);
RNA_def_property_float_sdna(prop, NULL, "black");
+ RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Black Level", "For RGB curves, the color that black is mapped to");
RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_black_level_set", NULL);
- prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_COLOR);
+ prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_RGB);
RNA_def_property_float_sdna(prop, NULL, "white");
+ RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "White Level", "For RGB curves, the color that white is mapped to");
RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_white_level_set", NULL);
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 815023ee315..b630e61a680 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -33,6 +33,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "ED_object.h"
#include "WM_types.h"
EnumPropertyItem constraint_type_items[] ={
@@ -80,6 +81,19 @@ EnumPropertyItem space_object_items[] = {
{1, "LOCAL", 0, "Local (Without Parent) Space", ""},
{0, NULL, 0, NULL, NULL}};
+EnumPropertyItem constraint_ik_type_items[] ={
+ {CONSTRAINT_IK_COPYPOSE, "COPY_POSE", 0, "Copy Pose", ""},
+ {CONSTRAINT_IK_DISTANCE, "DISTANCE", 0, "Distance", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static EnumPropertyItem constraint_distance_items[] = {
+ {LIMITDIST_INSIDE, "LIMITDIST_INSIDE", 0, "Inside", ""},
+ {LIMITDIST_OUTSIDE, "LIMITDIST_OUTSIDE", 0, "Outside", ""},
+ {LIMITDIST_ONSURFACE, "LIMITDIST_ONSURFACE", 0, "On Surface", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "BKE_action.h"
@@ -89,7 +103,7 @@ EnumPropertyItem space_object_items[] = {
#include "ED_object.h"
-StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
+static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
{
bConstraint *con= (bConstraint*)ptr->data;
@@ -160,24 +174,12 @@ static char *rna_Constraint_path(PointerRNA *ptr)
static void rna_Constraint_update(bContext *C, PointerRNA *ptr)
{
- Object *ob= ptr->id.data;
-
- if(ob->pose) update_pose_constraint_flags(ob->pose);
-
- object_test_constraints(ob);
-
- if(ob->type==OB_ARMATURE) DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB);
- else DAG_id_flush_update(&ob->id, OB_RECALC_OB);
+ ED_object_constraint_update(ptr->id.data);
}
static void rna_Constraint_dependency_update(bContext *C, PointerRNA *ptr)
{
- Object *ob= ptr->id.data;
-
- rna_Constraint_update(C, ptr);
-
- if(ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
- DAG_scene_sort(CTX_data_scene(C));
+ ED_object_constraint_dependency_update(CTX_data_scene(C), ptr->id.data);
}
static void rna_Constraint_influence_update(bContext *C, PointerRNA *ptr)
@@ -190,6 +192,24 @@ static void rna_Constraint_influence_update(bContext *C, PointerRNA *ptr)
rna_Constraint_update(C, ptr);
}
+static void rna_Constraint_ik_type_set(struct PointerRNA *ptr, int value)
+{
+ bConstraint *con = ptr->data;
+ bKinematicConstraint *ikdata = con->data;
+
+ if (ikdata->type != value) {
+ // the type of IK constraint has changed, set suitable default values
+ // in case constraints reuse same fields incompatible
+ switch (value) {
+ case CONSTRAINT_IK_COPYPOSE:
+ break;
+ case CONSTRAINT_IK_DISTANCE:
+ break;
+ }
+ ikdata->type = value;
+ }
+}
+
static EnumPropertyItem *rna_Constraint_owner_space_itemf(bContext *C, PointerRNA *ptr, int *free)
{
Object *ob= (Object*)ptr->id.data;
@@ -253,6 +273,22 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *C, PointerR
return space_object_items;
}
+static void rna_ActionConstraint_minmax_range(PointerRNA *ptr, float *min, float *max)
+{
+ bConstraint *con= (bConstraint*)ptr->data;
+ bActionConstraint *acon = (bActionConstraint *)con->data;
+
+ /* 0, 1, 2 = magic numbers for rotX, rotY, rotZ */
+ if (ELEM3(acon->type, 0, 1, 2)) {
+ *min= -90.f;
+ *max= 90.f;
+ } else {
+ *min= -1000.f;
+ *max= 1000.f;
+ }
+}
+
+
#else
static void rna_def_constrainttarget(BlenderRNA *brna)
@@ -440,21 +476,40 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna)
prop= RNA_def_property(srna, "tail", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_TIP);
RNA_def_property_ui_text(prop, "Use Tail", "Include bone's tail as last element in chain.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
prop= RNA_def_property(srna, "rotation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_ROT);
RNA_def_property_ui_text(prop, "Rotation", "Chain follows rotation of target.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
prop= RNA_def_property(srna, "targetless", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_AUTO);
RNA_def_property_ui_text(prop, "Targetless", "Use targetless IK.");
- RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
prop= RNA_def_property(srna, "stretch", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_STRETCH);
RNA_def_property_ui_text(prop, "Stretch", "Enable IK Stretching.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop= RNA_def_property(srna, "ik_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_funcs(prop, NULL, "rna_Constraint_ik_type_set", NULL);
+ RNA_def_property_enum_items(prop, constraint_ik_type_items);
+ RNA_def_property_ui_text(prop, "IK Type", "");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop= RNA_def_property(srna, "limit_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mode");
+ RNA_def_property_enum_items(prop, constraint_distance_items);
+ RNA_def_property_ui_text(prop, "Limit Mode", "Distances in relation to sphere of influence to allow.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "dist");
+ RNA_def_property_range(prop, 0.0, 100.f);
+ RNA_def_property_ui_text(prop, "Distance", "Radius of limiting sphere.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
@@ -575,7 +630,7 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target.");
- prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
@@ -781,15 +836,17 @@ static void rna_def_constraint_action(BlenderRNA *brna)
prop= RNA_def_property(srna, "maximum", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
- RNA_def_property_range(prop, 0.0, 1000.f);
+ RNA_def_property_range(prop, -1000.f, 1000.f);
RNA_def_property_ui_text(prop, "Maximum", "Maximum value for target channel range.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range");
prop= RNA_def_property(srna, "minimum", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min");
- RNA_def_property_range(prop, 0.0, 1000.f);
+ RNA_def_property_range(prop, -1000.f, 1000.f);
RNA_def_property_ui_text(prop, "Minimum", "Minimum value for target channel range.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range");
}
static void rna_def_constraint_locked_track(BlenderRNA *brna)
@@ -875,10 +932,10 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Offset", "Offset from the position corresponding to the time frame.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
- prop= RNA_def_property(srna, "offset_percentage", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "offset_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "offset"); // XXX we might be better with another var or some hackery?
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Offset Percentage", "Percentage value defining target position along length of bone.");
+ RNA_def_property_ui_text(prop, "Offset Factor", "Percentage value defining target position along length of bone.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
prop= RNA_def_property(srna, "forward", PROP_ENUM, PROP_NONE);
@@ -1457,12 +1514,6 @@ static void rna_def_constraint_distance_limit(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem distance_items[] = {
- {LIMITDIST_INSIDE, "LIMITDIST_INSIDE", 0, "Inside", ""},
- {LIMITDIST_OUTSIDE, "LIMITDIST_OUTSIDE", 0, "Outside", ""},
- {LIMITDIST_ONSURFACE, "LIMITDIST_ONSURFACE", 0, "On Surface", ""},
- {0, NULL, 0, NULL, NULL}};
-
srna= RNA_def_struct(brna, "LimitDistanceConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Limit Distance Constraint", "Limits the distance from target object.");
RNA_def_struct_sdna_from(srna, "bDistLimitConstraint", "data");
@@ -1486,7 +1537,7 @@ static void rna_def_constraint_distance_limit(BlenderRNA *brna)
prop= RNA_def_property(srna, "limit_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
- RNA_def_property_enum_items(prop, distance_items);
+ RNA_def_property_enum_items(prop, constraint_distance_items);
RNA_def_property_ui_text(prop, "Limit Mode", "Distances in relation to sphere of influence to allow.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
@@ -1599,12 +1650,23 @@ void RNA_def_constraint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Proxy Local", "Constraint was added in this proxy instance (i.e. did not belong to source Armature).");
/* values */
- prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "enforce");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Influence", "Amount of influence constraint will have on the final solution.");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_influence_update");
-
+
+ /* readonly values */
+ prop= RNA_def_property(srna, "lin_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "lin_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Lin error", "Amount of residual error in Blender space unit for constraints that work on position.");
+
+ prop= RNA_def_property(srna, "rot_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "rot_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Rot error", "Amount of residual error in radiant for constraints that work on orientation.");
+
/* pointers */
rna_def_constrainttarget(brna);
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index da4abe81f24..3b6bd2255f2 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -54,6 +54,7 @@ EnumPropertyItem beztriple_interpolation_mode_items[] = {
EnumPropertyItem beztriple_keyframe_type_items[] = {
{BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""},
{BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""},
+ {BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", ""},
{0, NULL, 0, NULL, NULL}};
#ifdef RNA_RUNTIME
@@ -66,7 +67,7 @@ EnumPropertyItem beztriple_keyframe_type_items[] = {
#include "WM_api.h"
-StructRNA *rna_Curve_refine(PointerRNA *ptr)
+static StructRNA *rna_Curve_refine(PointerRNA *ptr)
{
Curve *cu= (Curve*)ptr->data;
short obtype= curve_type(cu);
@@ -167,12 +168,18 @@ static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int
}
-static void rna_Curve_2d_set(PointerRNA *ptr, int value)
+static void rna_Curve_dimension_set(PointerRNA *ptr, int value)
{
Curve *cu= (Curve*)ptr->id.data;
Nurb *nu= cu->editnurb ? cu->editnurb->first : cu->nurb.first;
- if(value) {
+ if(value==CU_3D) {
+ cu->flag |= CU_3D;
+ for( ; nu; nu= nu->next) {
+ nu->flag &= ~CU_2D;
+ }
+ }
+ else {
cu->flag &= ~CU_3D;
for( ; nu; nu= nu->next) {
nu->flag |= CU_2D;
@@ -183,12 +190,6 @@ static void rna_Curve_2d_set(PointerRNA *ptr, int value)
calchandlesNurb(nu);
}
}
- else {
- cu->flag |= CU_3D;
- for( ; nu; nu= nu->next) {
- nu->flag &= ~CU_2D;
- }
- }
}
@@ -675,6 +676,11 @@ static void rna_def_curve(BlenderRNA *brna)
{CU_TWIST_TANGENT, "TANGENT", 0, "Tangent", "Use the tangent to calculate twist"},
{0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem curve_axis_items[]= {
+ {0, "2D", 0, "2D", "Clamp the Z axis of of the curve"},
+ {CU_3D, "3D", 0, "3D", "Allow editing on the Z axis of this curve, also alows tilt and curve radius to be used."},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "Curve", "ID");
RNA_def_struct_ui_text(srna, "Curve", "Curve datablock storing curves, splines and NURBS.");
RNA_def_struct_ui_icon(srna, ICON_CURVE_DATA);
@@ -778,10 +784,12 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
/* Flags */
- prop= RNA_def_property(srna, "curve_2d", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CU_3D);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_Curve_2d_set");
- RNA_def_property_ui_text(prop, "2D Curve", "Define curve in two dimensions only. Note that fill only works when this is enabled.");
+
+ prop= RNA_def_property(srna, "dimensions", PROP_ENUM, PROP_NONE); /* as an enum */
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, curve_axis_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_Curve_dimension_set", NULL);
+ RNA_def_property_ui_text(prop, "Dimensions", "Select 2D or 3D curve type.");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop= RNA_def_property(srna, "front", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 8d05cbde74c..cc86da18a0b 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -66,7 +66,7 @@ void rna_addtail(ListBase *listbase, void *vlink)
listbase->last = link;
}
-void rna_remlink(ListBase *listbase, void *vlink)
+static void rna_remlink(ListBase *listbase, void *vlink)
{
Link *link= vlink;
@@ -134,7 +134,7 @@ PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
if(!DefRNA.preprocess) {
/* we should never get here */
- fprintf(stderr, "rna_find_property_def: only at preprocess time.\n");
+ fprintf(stderr, "rna_find_struct_property_def: only at preprocess time.\n");
return NULL;
}
@@ -155,7 +155,8 @@ PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
return NULL;
}
-PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
+#if 0
+static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
{
PropertyDefRNA *dprop;
@@ -175,6 +176,7 @@ PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
return NULL;
}
+#endif
FunctionDefRNA *rna_find_function_def(FunctionRNA *func)
{
@@ -239,7 +241,7 @@ PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm)
return NULL;
}
-ContainerDefRNA *rna_find_container_def(ContainerRNA *cont)
+static ContainerDefRNA *rna_find_container_def(ContainerRNA *cont)
{
StructDefRNA *ds;
FunctionDefRNA *dfunc;
@@ -888,7 +890,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
fprop->softmin= 0.0f;
fprop->softmax= 1.0f;
}
- else if(subtype == PROP_PERCENTAGE) {
+ else if(subtype == PROP_FACTOR) {
fprop->softmin= fprop->hardmin= 0.0f;
fprop->softmax= fprop->hardmax= 1.0f;
}
@@ -1528,7 +1530,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const
iprop->softmax= 10000;
}
- if(prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE)
+ if(prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE || prop->subtype == PROP_FACTOR)
iprop->hardmin= iprop->softmin= 0;
}
}
@@ -2113,6 +2115,20 @@ PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *ide
return prop;
}
+PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen,
+ const char *ui_name, const char *ui_description)
+{
+ ContainerRNA *cont= cont_;
+ PropertyRNA *prop;
+
+ prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME);
+ if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
+ if(default_value) RNA_def_property_string_default(prop, default_value);
+ RNA_def_property_ui_text(prop, ui_name, ui_description);
+
+ return prop;
+}
+
PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value,
const char *ui_name, const char *ui_description)
{
@@ -2245,6 +2261,21 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *id
return prop;
}
+PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
+ float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
+{
+ ContainerRNA *cont= cont_;
+ PropertyRNA *prop;
+
+ prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_default(prop, default_value);
+ if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
+ RNA_def_property_ui_text(prop, ui_name, ui_description);
+ RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
+
+ return prop;
+}
+
PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
const char *ui_name, const char *ui_description)
{
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index bafe83f1812..2802665c639 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -52,7 +52,7 @@ EnumPropertyItem fmodifier_type_items[] = {
/* --------- */
-StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr)
+static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr)
{
FModifier *fcm= (FModifier *)ptr->data;
@@ -460,7 +460,7 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna)
/* --------- */
-void rna_def_fmodifier(BlenderRNA *brna)
+static void rna_def_fmodifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -510,7 +510,7 @@ void rna_def_fmodifier(BlenderRNA *brna)
/* *********************** */
-void rna_def_drivertarget(BlenderRNA *brna)
+static void rna_def_drivertarget(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -536,7 +536,7 @@ void rna_def_drivertarget(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property used (if applicable)");
}
-void rna_def_channeldriver(BlenderRNA *brna)
+static void rna_def_channeldriver(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -590,7 +590,7 @@ static void rna_def_fpoint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Point", "Point coordinates");
}
-void rna_def_fcurve(BlenderRNA *brna)
+static void rna_def_fcurve(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index a62002365c9..c415b3d716a 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -151,6 +151,14 @@ static int rna_DomainFluidSettings_memory_estimate_length(PointerRNA *ptr)
return 32;
}
+static char *rna_FluidSettings_path(PointerRNA *ptr)
+{
+ FluidsimSettings *fss = (FluidsimSettings*)ptr->data;
+ ModifierData *md= (ModifierData *)fss->fmd;
+
+ return BLI_sprintfN("modifiers[%s].settings", md->name);
+}
+
#else
static void rna_def_fluidsim_slip(StructRNA *srna)
@@ -509,6 +517,7 @@ void RNA_def_fluidsim(BlenderRNA *brna)
srna= RNA_def_struct(brna, "FluidSettings", NULL);
RNA_def_struct_sdna(srna, "FluidsimSettings");
RNA_def_struct_refine_func(srna, "rna_FluidSettings_refine");
+ RNA_def_struct_path_func(srna, "rna_FluidSettings_path");
RNA_def_struct_ui_text(srna, "Fluid Simulation Settings", "Fluid simulation settings for an object taking part in the simulation.");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 72e77e93607..2a4ff112c3c 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -48,7 +48,7 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr)
return 1;
}
-void rna_GPencilLayer_active_set(PointerRNA *ptr, int value)
+static void rna_GPencilLayer_active_set(PointerRNA *ptr, int value)
{
bGPdata *gpd= ptr->id.data;
bGPDlayer *gpl= ptr->data;
@@ -68,7 +68,7 @@ void rna_GPencilLayer_active_set(PointerRNA *ptr, int value)
#else
-void rna_def_gpencil_stroke_point(BlenderRNA *brna)
+static void rna_def_gpencil_stroke_point(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -88,7 +88,7 @@ void rna_def_gpencil_stroke_point(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it.");
}
-void rna_def_gpencil_stroke(BlenderRNA *brna)
+static void rna_def_gpencil_stroke(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -107,7 +107,7 @@ void rna_def_gpencil_stroke(BlenderRNA *brna)
// TODO...
}
-void rna_def_gpencil_frame(BlenderRNA *brna)
+static void rna_def_gpencil_frame(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -138,7 +138,7 @@ void rna_def_gpencil_frame(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Selected", "Frame is selected for editing in the DopeSheet.");
}
-void rna_def_gpencil_layer(BlenderRNA *brna)
+static void rna_def_gpencil_layer(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -215,7 +215,7 @@ void rna_def_gpencil_layer(BlenderRNA *brna)
}
-void rna_def_gpencil_data(BlenderRNA *brna)
+static void rna_def_gpencil_data(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -233,7 +233,7 @@ void rna_def_gpencil_data(BlenderRNA *brna)
/* Flags */
prop= RNA_def_property(srna, "view_space_draw", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN);
RNA_def_property_ui_text(prop, "Stick to View", "Newly drawn strokes get added in view space (i.e. sketches stick to data when view is manipulated).");
}
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 31bc6ccc74b..dddc2062f07 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -33,7 +33,7 @@
#ifdef RNA_RUNTIME
-PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
+static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
{
ListBaseIterator *internal= iter->internal;
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 4d04f4ee1f3..521756b8539 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -37,6 +37,14 @@
#include "WM_types.h"
+static EnumPropertyItem image_source_items[]= {
+ {IMA_SRC_FILE, "FILE", 0, "File", "Single image file"},
+ {IMA_SRC_SEQUENCE, "SEQUENCE", 0, "Sequence", "Multiple image files, as a sequence"},
+ {IMA_SRC_MOVIE, "MOVIE", 0, "Movie", "Movie file"},
+ {IMA_SRC_GENERATED, "GENERATED", 0, "Generated", "Generated image"},
+ {IMA_SRC_VIEWER, "VIEWER", 0, "Viewer", "Compositing node viewer"},
+ {0, NULL, 0, NULL, NULL}};
+
#ifdef RNA_RUNTIME
#include "IMB_imbuf_types.h"
@@ -66,6 +74,110 @@ static int rna_Image_dirty_get(PointerRNA *ptr)
return 0;
}
+static void rna_Image_source_update(bContext *C, PointerRNA *ptr)
+{
+ Image *ima= ptr->id.data;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_SRC_CHANGE);
+}
+
+static void rna_Image_fields_update(bContext *C, PointerRNA *ptr)
+{
+ Image *ima= ptr->id.data;
+ ImBuf *ibuf;
+ void *lock;
+
+ ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if(ibuf) {
+ short nr= 0;
+
+ if(!(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields)) nr= 1;
+ if((ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields)) nr= 1;
+
+ if(nr)
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
+ }
+
+ BKE_image_release_ibuf(ima, lock);
+}
+
+static void rna_Image_reload_update(bContext *C, PointerRNA *ptr)
+{
+ Image *ima= ptr->id.data;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
+ printf("reload %p\n", ima);
+}
+
+static void rna_Image_generated_update(bContext *C, PointerRNA *ptr)
+{
+ Image *ima= ptr->id.data;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
+}
+
+static void rna_ImageUser_update(bContext *C, PointerRNA *ptr)
+{
+ Scene *scene= CTX_data_scene(C);
+ ImageUser *iuser= ptr->data;
+
+ BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0);
+}
+
+static EnumPropertyItem *rna_Image_source_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ Image *ima= (Image*)ptr->data;
+ EnumPropertyItem *item= NULL;
+ int totitem= 0;
+
+ if(C==NULL) /* needed for doc generation */
+ return image_source_items;
+
+ if(ima->source == IMA_SRC_VIEWER) {
+ RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_VIEWER);
+ }
+ else {
+ RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_FILE);
+ RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_SEQUENCE);
+ RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_MOVIE);
+ RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_GENERATED);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *free= 1;
+
+ return item;
+}
+
+static int rna_Image_has_data_get(PointerRNA *ptr)
+{
+ Image *im= (Image*)ptr->data;
+
+ if (im->ibufs.first)
+ return 1;
+
+ return 0;
+}
+
+static int rna_Image_depth_get(PointerRNA *ptr)
+{
+ Image *im= (Image*)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+ int depth;
+
+ ibuf= BKE_image_acquire_ibuf(im, NULL, &lock);
+
+ if(!ibuf)
+ depth= 0;
+ else if(ibuf->rect_float)
+ depth= 128;
+ else
+ depth= ibuf->depth;
+
+ BKE_image_release_ibuf(im, lock);
+
+ return depth;
+}
+
#else
static void rna_def_imageuser(BlenderRNA *brna)
@@ -79,29 +191,35 @@ static void rna_def_imageuser(BlenderRNA *brna)
prop= RNA_def_property(srna, "auto_refresh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANIM_ALWAYS);
RNA_def_property_ui_text(prop, "Auto Refresh", "Always refresh image on frame changes.");
+ RNA_def_property_update(prop, 0, "rna_ImageUser_update");
/* animation */
prop= RNA_def_property(srna, "cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cycl", 0);
RNA_def_property_ui_text(prop, "Cyclic", "Cycle the images in the movie.");
+ RNA_def_property_update(prop, 0, "rna_ImageUser_update");
prop= RNA_def_property(srna, "frames", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Frames", "Sets the number of images of a movie to use.");
+ RNA_def_property_update(prop, 0, "rna_ImageUser_update");
prop= RNA_def_property(srna, "offset", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation.");
+ RNA_def_property_update(prop, 0, "rna_ImageUser_update");
prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "sfra");
RNA_def_property_range(prop, 1.0f, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Start Frame", "Sets the global starting frame of the movie.");
+ RNA_def_property_update(prop, 0, "rna_ImageUser_update");
prop= RNA_def_property(srna, "fields_per_frame", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "fie_ima");
RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Fields per Frame", "The number of fields per rendered frame (2 fields is 1 image).");
+ RNA_def_property_update(prop, 0, "rna_ImageUser_update");
prop= RNA_def_property(srna, "multilayer_layer", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "layer");
@@ -121,25 +239,22 @@ static void rna_def_image(BlenderRNA *brna)
static const EnumPropertyItem prop_type_items[]= {
{IMA_TYPE_IMAGE, "IMAGE", 0, "Image", ""},
{IMA_TYPE_MULTILAYER, "MULTILAYER", 0, "Multilayer", ""},
- {IMA_TYPE_UV_TEST, "UVTEST", 0, "UV Test", ""},
- {IMA_TYPE_R_RESULT, "RENDERRESULT", 0, "Render Result", ""},
+ {IMA_TYPE_UV_TEST, "UV_TEST", 0, "UV Test", ""},
+ {IMA_TYPE_R_RESULT, "RENDER_RESULT", 0, "Render Result", ""},
{IMA_TYPE_COMPOSITE, "COMPOSITING", 0, "Compositing", ""},
{0, NULL, 0, NULL, NULL}};
- static const EnumPropertyItem prop_source_items[]= {
- {IMA_SRC_FILE, "FILE", 0, "File", "Single image file"},
- {IMA_SRC_SEQUENCE, "SEQUENCE", 0, "Sequence", "Multiple image files, as a sequence"},
- {IMA_SRC_MOVIE, "MOVIE", 0, "Movie", "Movie file"},
- {IMA_SRC_GENERATED, "GENERATED", 0, "Generated", "Generated image"},
- {IMA_SRC_VIEWER, "VIEWER", 0, "Viewer", "Compositing node viewer"},
- {0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem prop_generated_type_items[]= {
{0, "BLANK", 0, "Blank", "Generate a blank image"},
- {1, "UVTESTGRID", 0, "UV Test Grid", "Generated grid to test UV mappings"},
+ {1, "UVGRID", 0, "UV Grid", "Generated grid to test UV mappings"},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem prop_mapping_items[]= {
{0, "UV", 0, "UV Coordinates", "Use UV coordinates for mapping the image"},
{IMA_REFLECT, "REFLECTION", 0, "Reflection", "Use reflection mapping for mapping the image"},
{0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem prop_field_order_items[]= {
+ {0, "EVEN", 0, "Even", "Even Fields first"},
+ {IMA_STD_FIELD, "ODD", 0, "Odd", "Odd Fields first"},
+ {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.");
@@ -147,36 +262,36 @@ static void rna_def_image(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update");
prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, prop_source_items);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
+ RNA_def_property_enum_items(prop, image_source_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Image_source_itemf");
RNA_def_property_ui_text(prop, "Source", "Where the image comes from.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_source_update");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "How to generate the image.");
RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
RNA_def_property_ui_text(prop, "Packed File", "");
-
+
+ prop= RNA_def_property(srna, "field_order", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, prop_field_order_items);
+ RNA_def_property_ui_text(prop, "Field Order", "Order of video fields. Select which lines are displayed first.");
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+
/* booleans */
prop= RNA_def_property(srna, "fields", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS);
RNA_def_property_ui_text(prop, "Fields", "Use fields of the image.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
-
- prop= RNA_def_property(srna, "odd_fields", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_STD_FIELD);
- RNA_def_property_ui_text(prop, "Odd Fields", "Standard field toggle.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_fields_update");
prop= RNA_def_property(srna, "antialias", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANTIALI);
@@ -198,19 +313,19 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "gen_type");
RNA_def_property_enum_items(prop, prop_generated_type_items);
RNA_def_property_ui_text(prop, "Generated Type", "Generated image type.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_generated_update");
prop= RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gen_x");
RNA_def_property_range(prop, 1, 16384);
RNA_def_property_ui_text(prop, "Generated Width", "Generated image width.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_generated_update");
prop= RNA_def_property(srna, "generated_height", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gen_y");
RNA_def_property_range(prop, 1, 16384);
RNA_def_property_ui_text(prop, "Generated Height", "Generated image height.");
- RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+ RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_generated_update");
/* realtime properties */
prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
@@ -275,6 +390,22 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_V);
RNA_def_property_ui_text(prop, "Clamp Y", "Disable texture repeating vertically.");
RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+
+ /*
+ Image.has_data and Image.depth are temporary,
+ Update import_obj.py when they are replaced (Arystan)
+ */
+ prop= RNA_def_property(srna, "has_data", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_Image_has_data_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Has data", "True if this image has data.");
+
+ prop= RNA_def_property(srna, "depth", PROP_INT, PROP_NONE);
+ RNA_def_property_int_funcs(prop, "rna_Image_depth_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Depth", "Image bit depth.");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ RNA_api_image(srna);
}
void RNA_def_image(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
new file mode 100644
index 00000000000..2bb7905fc03
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -0,0 +1,101 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Arystanbek Dyussenov
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+/*
+ User should check if returned path exists before copying a file there.
+
+ TODO: it would be better to return a (abs, rel) tuple.
+*/
+static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel)
+{
+ int length = FILE_MAX;
+ char *path= MEM_callocN(length, "image file path");
+
+ if (!BKE_get_image_export_path(image, dest_dir, rel ? NULL : path, length, rel ? path : NULL, length )) {
+ MEM_freeN(path);
+ return NULL;
+ }
+
+ return path;
+}
+
+char *rna_Image_get_abs_filename(Image *image, bContext *C)
+{
+ char *filename= MEM_callocN(FILE_MAX, "Image.get_abs_filename()");
+
+ BLI_strncpy(filename, image->name, FILE_MAXDIR + FILE_MAXFILE);
+ BLI_convertstringcode(filename, CTX_data_main(C)->name);
+ BLI_convertstringframe(filename, CTX_data_scene(C)->r.cfra);
+
+ return filename;
+}
+
+#else
+
+void RNA_api_image(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "get_export_path", "rna_Image_get_export_path");
+ RNA_def_function_ui_description(func, "Produce image export path.");
+ parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_boolean(func, "get_rel_path", 1, "", "Return relative path if True.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "get_abs_filename", "rna_Image_get_abs_filename");
+ RNA_def_function_ui_description(func, "Get absolute filename.");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ parm= RNA_def_string_file_path(func, "abs_filename", NULL, 0, "", "Image/movie absolute filename.");
+ RNA_def_function_return(func, parm);
+}
+
+#endif
+
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 7de80843f27..1ebf03425d4 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -173,7 +173,7 @@ void RNA_def_world(struct BlenderRNA *brna);
void rna_def_animdata_common(struct StructRNA *srna);
void rna_def_texmat_common(struct StructRNA *srna, const char *texspace_editable);
-void rna_def_mtex_common(struct StructRNA *srna, const char *begin, const char *activeget, const char *activeset, const char *structname);
+void rna_def_mtex_common(struct StructRNA *srna, const char *begin, const char *activeget, const char *activeset, const char *structname, const char *update);
void rna_def_render_layer_common(struct StructRNA *srna, int scene);
void rna_ID_name_get(struct PointerRNA *ptr, char *value);
@@ -197,17 +197,23 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch
void rna_Object_update(struct bContext *C, struct PointerRNA *ptr);
void rna_Object_update_data(struct bContext *C, struct PointerRNA *ptr);
void rna_Mesh_update_draw(struct bContext *C, struct PointerRNA *ptr);
+void rna_TextureSlot_update(struct bContext *C, struct PointerRNA *ptr);
/* API functions */
+void RNA_api_action(StructRNA *srna);
+void RNA_api_image(struct StructRNA *srna);
void RNA_api_keyingset(struct StructRNA *srna);
void RNA_api_main(struct StructRNA *srna);
+void RNA_api_material(StructRNA *srna);
void RNA_api_mesh(struct StructRNA *srna);
void RNA_api_object(struct StructRNA *srna);
-void RNA_api_scene(struct StructRNA *srna);
+void RNA_api_scene(struct StructRNA *srna);
+void RNA_api_text(struct StructRNA *srna);
void RNA_api_ui_layout(struct StructRNA *srna);
void RNA_api_wm(struct StructRNA *srna);
+
/* ID Properties */
extern StringPropertyRNA rna_IDProperty_string;
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index fbe339fe7f3..e1551404438 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -257,6 +257,11 @@ static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter)
return rna_pointer_inherit_refine(&iter->parent, type, rna_iterator_array_get(iter));
}
+static char *rna_ShapeKey_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("keys[\"%s\"]", ((KeyBlock*)ptr->data)->name);
+}
+
static void rna_Key_update_data(bContext *C, PointerRNA *ptr)
{
Main *bmain= CTX_data_main(C);
@@ -343,6 +348,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
srna= RNA_def_struct(brna, "ShapeKey", NULL);
RNA_def_struct_ui_text(srna, "Shape Key", "Shape key in a shape keys datablock.");
RNA_def_struct_sdna(srna, "KeyBlock");
+ RNA_def_struct_path_func(srna, "rna_ShapeKey_path");
RNA_def_struct_ui_icon(srna, ICON_SHAPEKEY_DATA);
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
@@ -414,7 +420,8 @@ static void rna_def_key(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Key", "Shape keys datablock containing different shapes of geometric datablocks.");
RNA_def_struct_ui_icon(srna, ICON_SHAPEKEY_DATA);
- prop= RNA_def_property(srna, "reference_key", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "reference_key", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_sdna(prop, NULL, "refkey");
RNA_def_property_ui_text(prop, "Reference Key", "");
@@ -426,7 +433,8 @@ static void rna_def_key(BlenderRNA *brna)
rna_def_animdata_common(srna);
- prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "from");
RNA_def_property_ui_text(prop, "User", "Datablock using these shape keys.");
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 57aa1ba2736..4315a118c84 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -33,14 +33,17 @@
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
-#include "WM_types.h"
-
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
+#include "BKE_depsgraph.h"
+#include "BKE_main.h"
#include "BKE_texture.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
static void rna_Lamp_buffer_size_set(PointerRNA *ptr, int value)
{
Lamp *la= (Lamp*)ptr->data;
@@ -99,7 +102,7 @@ static StructRNA* rna_Lamp_refine(struct PointerRNA *ptr)
switch(la->type) {
case LA_LOCAL:
- return &RNA_LocalLamp;
+ return &RNA_PointLamp;
case LA_SUN:
return &RNA_SunLamp;
case LA_SPOT:
@@ -113,6 +116,30 @@ static StructRNA* rna_Lamp_refine(struct PointerRNA *ptr)
}
}
+static void rna_Lamp_update(bContext *C, PointerRNA *ptr)
+{
+ Lamp *la= ptr->id.data;
+
+ DAG_id_flush_update(&la->id, 0);
+ WM_event_add_notifier(C, NC_LAMP|ND_LIGHTING, la);
+}
+
+static void rna_Lamp_draw_update(bContext *C, PointerRNA *ptr)
+{
+ Lamp *la= ptr->id.data;
+
+ DAG_id_flush_update(&la->id, 0);
+ WM_event_add_notifier(C, NC_LAMP|ND_LIGHTING_DRAW, la);
+}
+
+static void rna_Lamp_sky_update(bContext *C, PointerRNA *ptr)
+{
+ Lamp *la= ptr->id.data;
+
+ DAG_id_flush_update(&la->id, 0);
+ WM_event_add_notifier(C, NC_LAMP|ND_SKY, la);
+}
+
#else
static void rna_def_lamp_mtex(BlenderRNA *brna)
@@ -144,24 +171,24 @@ static void rna_def_lamp_mtex(BlenderRNA *brna)
prop= RNA_def_property(srna, "map_color", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", LAMAP_COL);
RNA_def_property_ui_text(prop, "Color", "Lets the texture affect the basic color of the lamp.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "map_shadow", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", LAMAP_SHAD);
RNA_def_property_ui_text(prop, "Shadow", "Lets the texture affect the shadow color of the lamp.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Color Factor", "Amount texture affects color values.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_float_sdna(prop, NULL, "shadowfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Shadow Factor", "Amount texture affects shadow.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
}
static void rna_def_lamp_sky_settings(BlenderRNA *brna)
@@ -203,92 +230,92 @@ static void rna_def_lamp_sky_settings(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "sky_colorspace");
RNA_def_property_enum_items(prop, prop_skycolorspace_items);
RNA_def_property_ui_text(prop, "Sky Color Space", "Color space to use for internal XYZ->RGB color conversion.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "sky_blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "skyblendtype");
RNA_def_property_enum_items(prop, prop_blendmode_items);
RNA_def_property_ui_text(prop, "Sky Blend Mode", "Blend mode for combining sun sky with world sky.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
/* Number values */
prop= RNA_def_property(srna, "horizon_brightness", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 20.0f);
RNA_def_property_ui_text(prop, "Horizon Brightness", "Horizon brightness.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "spread", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Horizon Spread", "Horizon Spread.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "sun_brightness", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Sun Brightness", "Sun brightness.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "sun_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Sun Size", "Sun size.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "backscattered_light", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Backscattered Light", "Backscattered light.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "sun_intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Sun Intensity", "Sun intensity.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "atmosphere_turbidity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "atm_turbidity");
RNA_def_property_range(prop, 1.0f, 30.0f);
RNA_def_property_ui_text(prop, "Atmosphere Turbidity", "Sky turbidity.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "atmosphere_inscattering", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "atm_inscattering_factor");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Atmosphere Inscatter", "Scatter contribution factor.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "atmosphere_extinction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "atm_extinction_factor");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Atmosphere Extinction", "Extinction scattering contribution factor.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "atmosphere_distance_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "atm_distance_factor");
RNA_def_property_range(prop, 0.0f, 500.0f);
RNA_def_property_ui_text(prop, "Atmosphere Distance Factor", "Multiplier to convert blender units to physical distance.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "sky_blend", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "skyblendfac");
RNA_def_property_range(prop, 0.0f, 2.0f);
RNA_def_property_ui_text(prop, "Sky Blend", "Blend factor with sky.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "sky_exposure", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 20.0f);
RNA_def_property_ui_text(prop, "Sky Exposure", "Strength of sky shading exponential exposure correction.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
/* boolean */
prop= RNA_def_property(srna, "sky", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sun_effect_type", LA_SUN_EFFECT_SKY);
RNA_def_property_ui_text(prop, "Sky", "Apply sun effect on sky.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
prop= RNA_def_property(srna, "atmosphere", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sun_effect_type", LA_SUN_EFFECT_AP);
RNA_def_property_ui_text(prop, "Atmosphere", "Apply sun effect on atmosphere.");
- RNA_def_property_update(prop, NC_LAMP|ND_SKY, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_sky_update");
}
static void rna_def_lamp(BlenderRNA *brna)
@@ -312,48 +339,48 @@ static void rna_def_lamp(BlenderRNA *brna)
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of Lamp.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist");
RNA_def_property_ui_range(prop, 0, 1000, 1.0, 2);
RNA_def_property_ui_text(prop, "Distance", "Falloff distance - the light is at half the original intensity at this point.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_range(prop, 0, 10.0, 0.1, 2);
RNA_def_property_ui_text(prop, "Energy", "Amount of light that the lamp emits.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "r");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Color", "Light color.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_LAYER);
RNA_def_property_ui_text(prop, "Layer", "Illuminates objects only on the same layer the lamp is on.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "negative", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_NEG);
RNA_def_property_ui_text(prop, "Negative", "Lamp casts negative light.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "specular", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_SPEC);
RNA_def_property_ui_text(prop, "Specular", "Lamp creates specular highlights.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "diffuse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_DIFF);
RNA_def_property_ui_text(prop, "Diffuse", "Lamp does diffuse shading.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
/* textures */
rna_def_mtex_common(srna, "rna_Lamp_mtex_begin", "rna_Lamp_active_texture_get",
- "rna_Lamp_active_texture_set", "LampTextureSlot");
+ "rna_Lamp_active_texture_set", "LampTextureSlot", "rna_Lamp_update");
}
static void rna_def_lamp_falloff(StructRNA *srna)
@@ -371,29 +398,29 @@ static void rna_def_lamp_falloff(StructRNA *srna)
prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_fallofftype_items);
RNA_def_property_ui_text(prop, "Falloff Type", "Intensity Decay with distance.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "falloff_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "curfalloff");
RNA_def_property_ui_text(prop, "Falloff Curve", "Custom Lamp Falloff Curve");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "sphere", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_SPHERE);
RNA_def_property_ui_text(prop, "Sphere", "Sets light intensity to zero beyond lamp distance.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "linear_attenuation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "att1");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Linear Attenuation", "Linear distance attentuation.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "quadratic_attenuation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "att2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Quadratic Attenuation", "Quadratic distance attentuation.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
}
static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area)
@@ -426,64 +453,65 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, (spot)? prop_spot_shadow_items: prop_shadow_items);
RNA_def_property_ui_text(prop, "Shadow Method", "Method to compute lamp shadow with.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "shdwr");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Shadow Color", "Color of shadows casted by the lamp.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_ui_text(prop, "Shadow Color", "Color of shadows cast by the lamp.");
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "only_shadow", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_ONLYSHADOW);
RNA_def_property_ui_text(prop, "Only Shadow", "Causes light to cast shadows only without illuminating objects.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_ray_sampling_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ray_samp_method");
RNA_def_property_enum_items(prop, (area)? prop_spot_ray_sampling_method_items: prop_ray_sampling_method_items);
RNA_def_property_ui_text(prop, "Shadow Ray Sampling Method", "Method for generating shadow samples: Adaptive QMC is fastest, Constant QMC is less noisy but slower.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, (area)? "shadow_ray_samples_x": "shadow_ray_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ray_samp");
RNA_def_property_range(prop, 1, 64);
RNA_def_property_ui_text(prop, (area)? "Shadow Ray Samples": "Shadow Ray Samples X","Amount of samples taken extra (samples x samples).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
if(area) {
prop= RNA_def_property(srna, "shadow_ray_samples_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ray_sampy");
RNA_def_property_range(prop, 1, 64);
RNA_def_property_ui_text(prop, "Shadow Ray Samples Y", "Amount of samples taken extra (samples x samples).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
}
prop= RNA_def_property(srna, "shadow_adaptive_threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "adapt_thresh");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Shadow Adaptive Threshold", "Threshold for Adaptive Sampling (Raytraced shadows).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "soft");
RNA_def_property_ui_range(prop, 0, 100, 0.1, 3);
RNA_def_property_ui_text(prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_LAYER_SHADOW);
RNA_def_property_ui_text(prop, "Shadow Layer", "Causes only objects on the same layer to cast shadows.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
}
-static void rna_def_local_lamp(BlenderRNA *brna)
+static void rna_def_point_lamp(BlenderRNA *brna)
{
StructRNA *srna;
- srna= RNA_def_struct(brna, "LocalLamp", "Lamp");
+ srna= RNA_def_struct(brna, "PointLamp", "Lamp");
RNA_def_struct_sdna(srna, "Lamp");
- RNA_def_struct_ui_text(srna, "Local Lamp", "Omnidirectional point lamp.");
+ RNA_def_struct_ui_text(srna, "Point Lamp", "Omnidirectional point lamp.");
+ RNA_def_struct_ui_icon(srna, ICON_LAMP_POINT);
rna_def_lamp_falloff(srna);
rna_def_lamp_shadow(srna, 0, 0);
@@ -502,47 +530,48 @@ static void rna_def_area_lamp(BlenderRNA *brna)
srna= RNA_def_struct(brna, "AreaLamp", "Lamp");
RNA_def_struct_sdna(srna, "Lamp");
RNA_def_struct_ui_text(srna, "Area Lamp", "Directional area lamp.");
+ RNA_def_struct_ui_icon(srna, ICON_LAMP_AREA);
rna_def_lamp_shadow(srna, 0, 1);
prop= RNA_def_property(srna, "umbra", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ray_samp_type", LA_SAMP_UMBRA);
RNA_def_property_ui_text(prop, "Umbra", "Emphasize parts that are fully shadowed (Constant Jittered sampling).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "dither", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ray_samp_type", LA_SAMP_DITHER);
RNA_def_property_ui_text(prop, "Dither", "Use 2x2 dithering for sampling (Constant Jittered sampling).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "jitter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ray_samp_type", LA_SAMP_JITTER);
RNA_def_property_ui_text(prop, "Jitter", "Use noise for sampling (Constant Jittered sampling).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shape", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "area_shape");
RNA_def_property_enum_items(prop, prop_areashape_items);
RNA_def_property_ui_text(prop, "Shape", "Shape of the area lamp.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "area_size");
RNA_def_property_ui_range(prop, 0, 100, 0.1, 3);
RNA_def_property_ui_text(prop, "Size", "Size of the area of the area Lamp, X direction size for Rectangle shapes.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "size_y", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "area_sizey");
RNA_def_property_ui_range(prop, 0, 100, 0.1, 3);
RNA_def_property_ui_text(prop, "Size Y", "Size of the area of the area Lamp in the Y direction for Rectangle shapes.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "k");
RNA_def_property_ui_range(prop, 0.001, 2.0, 0.1, 3);
RNA_def_property_ui_text(prop, "Gamma", "Light gamma correction value.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
}
static void rna_def_spot_lamp(BlenderRNA *brna)
@@ -571,6 +600,7 @@ static void rna_def_spot_lamp(BlenderRNA *brna)
srna= RNA_def_struct(brna, "SpotLamp", "Lamp");
RNA_def_struct_sdna(srna, "Lamp");
RNA_def_struct_ui_text(srna, "Spot Lamp", "Directional cone lamp.");
+ RNA_def_struct_ui_icon(srna, ICON_LAMP_SPOT);
rna_def_lamp_falloff(srna);
rna_def_lamp_shadow(srna, 1, 0);
@@ -578,101 +608,101 @@ static void rna_def_spot_lamp(BlenderRNA *brna)
prop= RNA_def_property(srna, "square", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_SQUARE);
RNA_def_property_ui_text(prop, "Square", "Casts a square spot light shape.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "halo", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", LA_HALO);
RNA_def_property_ui_text(prop, "Halo", "Renders spotlight with a volumetric halo (Buffer Shadows).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "halo_intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "haint");
RNA_def_property_ui_range(prop, 0, 5.0, 0.1, 3);
RNA_def_property_ui_text(prop, "Halo Intensity", "Brightness of the spotlight's halo cone (Buffer Shadows).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "halo_step", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "shadhalostep");
RNA_def_property_range(prop, 0, 12);
RNA_def_property_ui_text(prop, "Halo Step", "Volumetric halo sampling frequency.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
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_ui_text(prop, "Shadow Buffer Size", "Resolution of the shadow buffer, higher values give crisper shadows but use more memory");
RNA_def_property_int_funcs(prop, NULL, "rna_Lamp_buffer_size_set", NULL);
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "filtertype");
RNA_def_property_enum_items(prop, prop_shadbuffiltertype_items);
RNA_def_property_ui_text(prop, "Shadow Filter Type", "Type of shadow filter (Buffer Shadows).");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_sample_buffers", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "buffers");
RNA_def_property_enum_items(prop, prop_numbuffer_items);
RNA_def_property_ui_text(prop, "Shadow Sample Buffers", "Number of shadow buffers to render for better AA, this increases memory usage.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "spot_blend", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spotblend");
RNA_def_property_range(prop, 0.0f ,1.0f);
RNA_def_property_ui_text(prop, "Spot Blend", "The softness of the spotlight edge.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "spot_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spotsize");
RNA_def_property_range(prop, 1.0f ,180.0f);
RNA_def_property_ui_text(prop, "Spot Size", "Angle of the spotlight beam in degrees.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "shadow_buffer_clip_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipsta");
RNA_def_property_range(prop, 0.0f, 9999.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Clip Start", "Shadow map clip start: objects closer will not generate shadows");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "shadow_buffer_clip_end", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipend");
RNA_def_property_range(prop, 0.0f, 9999.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Clip End", "Shadow map clip end beyond which objects will not generate shadows.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "shadow_buffer_bias", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bias");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Shadow buffer sampling bias.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_buffer_soft", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "soft");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Soft", "Size of shadow buffer sampling area.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_buffer_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samp");
RNA_def_property_range(prop, 1, 16);
RNA_def_property_ui_text(prop, "Samples", "Number of shadow buffer samples.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "shadow_buffer_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "buftype");
RNA_def_property_enum_items(prop, prop_shadbuftype_items);
RNA_def_property_ui_text(prop, "Shadow Buffer Type", "Type of shadow buffer.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop= RNA_def_property(srna, "auto_clip_start", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_START);
RNA_def_property_ui_text(prop, "Autoclip Start", "Automatic calculation of clipping-start, based on visible vertices.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "auto_clip_end", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_END);
RNA_def_property_ui_text(prop, "Autoclip End", "Automatic calculation of clipping-end, based on visible vertices.");
- RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
}
static void rna_def_sun_lamp(BlenderRNA *brna)
@@ -683,11 +713,13 @@ static void rna_def_sun_lamp(BlenderRNA *brna)
srna= RNA_def_struct(brna, "SunLamp", "Lamp");
RNA_def_struct_sdna(srna, "Lamp");
RNA_def_struct_ui_text(srna, "Sun Lamp", "Constant direction parallel ray lamp.");
+ RNA_def_struct_ui_icon(srna, ICON_LAMP_SUN);
rna_def_lamp_shadow(srna, 0, 0);
/* sky */
- prop= RNA_def_property(srna, "sky", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "sky", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "LampSkySettings");
RNA_def_property_pointer_funcs(prop, "rna_Lamp_sky_settings_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Sky Settings", "Sky related settings for sun lamps.");
@@ -702,12 +734,13 @@ static void rna_def_hemi_lamp(BlenderRNA *brna)
srna= RNA_def_struct(brna, "HemiLamp", "Lamp");
RNA_def_struct_sdna(srna, "Lamp");
RNA_def_struct_ui_text(srna, "Hemi Lamp", "180 degree constant lamp.");
+ RNA_def_struct_ui_icon(srna, ICON_LAMP_HEMI);
}
void RNA_def_lamp(BlenderRNA *brna)
{
rna_def_lamp(brna);
- rna_def_local_lamp(brna);
+ rna_def_point_lamp(brna);
rna_def_area_lamp(brna);
rna_def_spot_lamp(brna);
rna_def_sun_lamp(brna);
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 344135acaff..910a15890cb 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -259,9 +259,9 @@ void RNA_def_main(BlenderRNA *brna)
{"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", NULL, NULL},
{"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", NULL, NULL},
{"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL, NULL},
- {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks.", NULL, NULL},
+ {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED).", NULL, NULL},
{"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", NULL, NULL},
- {"sounds", "ID", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", NULL, NULL},
+ {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", NULL, NULL},
{"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", NULL, NULL},
{"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", NULL, NULL},
{"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", NULL, NULL},
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 6d56b2b00f9..379cf75d450 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -31,23 +31,32 @@
#include "RNA_define.h"
#include "RNA_types.h"
+#include "RNA_enum_types.h"
+
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#ifdef RNA_RUNTIME
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_library.h"
+#include "BKE_object.h"
+#include "BKE_material.h"
+#include "BKE_image.h"
+#include "BKE_texture.h"
-#include "DNA_mesh_types.h"
+#include "DNA_lamp_types.h"
-Mesh *rna_Main_add_mesh(Main *main, char *name)
+static Mesh *rna_Main_add_mesh(Main *main, char *name)
{
Mesh *me= add_mesh(name);
me->id.us--;
return me;
}
-void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me)
+static void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me)
{
if(me->id.us == 0)
free_libblock(&main->mesh, me);
@@ -57,24 +66,130 @@ void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me)
/* XXX python now has invalid pointer? */
}
+static Lamp *rna_Main_add_lamp(Main *main, char *name)
+{
+ Lamp *la= add_lamp(name);
+ la->id.us--;
+ return la;
+}
+
+/*
+static void rna_Main_remove_lamp(Main *main, ReportList *reports, Lamp *la)
+{
+ if(la->id.us == 0)
+ free_libblock(&main->lamp, la);
+ else
+ BKE_report(reports, RPT_ERROR, "Lamp must have zero users to be removed.");
+}
+*/
+
+static Object* rna_Main_add_object(Main *main, int type, char *name)
+{
+ Object *ob= add_only_object(type, name);
+ ob->id.us--;
+ return ob;
+}
+
+/*
+ NOTE: the following example shows when this function should _not_ be called
+
+ ob = bpy.data.add_object()
+ scene.add_object(ob)
+
+ # ob is freed here
+ scene.remove_object(ob)
+
+ # don't do this since ob is already freed!
+ bpy.data.remove_object(ob)
+*/
+static void rna_Main_remove_object(Main *main, ReportList *reports, Object *ob)
+{
+ if(ob->id.us == 0)
+ free_libblock(&main->object, ob);
+ else
+ BKE_report(reports, RPT_ERROR, "Object must have zero users to be removed.");
+}
+
+static Material *rna_Main_add_material(Main *main, char *name)
+{
+ return add_material(name);
+}
+
+/* TODO: remove material? */
+
+struct Tex *rna_Main_add_texture(Main *main, char *name)
+{
+ return add_texture(name);
+}
+
+/* TODO: remove texture? */
+
+struct Image *rna_Main_add_image(Main *main, char *filename)
+{
+ return BKE_add_image_file(filename, 0);
+}
+
#else
void RNA_api_main(StructRNA *srna)
{
FunctionRNA *func;
- PropertyRNA *prop;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "add_object", "rna_Main_add_object");
+ RNA_def_function_ui_description(func, "Add a new object.");
+ parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_string(func, "name", "Object", 0, "", "New name for the datablock.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "object", "Object", "", "New object.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove_object", "rna_Main_remove_object");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove an object if it has zero users.");
+ parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
func= RNA_def_function(srna, "add_mesh", "rna_Main_add_mesh");
RNA_def_function_ui_description(func, "Add a new mesh.");
- prop= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock.");
- prop= RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh.");
- RNA_def_function_return(func, prop);
+ parm= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh.");
+ RNA_def_function_return(func, parm);
func= RNA_def_function(srna, "remove_mesh", "rna_Main_remove_mesh");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Remove a mesh if it has zero users.");
- prop= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove.");
- RNA_def_property_flag(prop, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "add_lamp", "rna_Main_add_lamp");
+ RNA_def_function_ui_description(func, "Add a new lamp.");
+ parm= RNA_def_string(func, "name", "Lamp", 0, "", "New name for the datablock.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "mesh", "Lamp", "", "New lamp.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "add_material", "rna_Main_add_material");
+ RNA_def_function_ui_description(func, "Add a new material.");
+ parm= RNA_def_string(func, "name", "Material", 0, "", "New name for the datablock."); /* optional */
+ parm= RNA_def_pointer(func, "material", "Material", "", "New material.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "add_texture", "rna_Main_add_texture");
+ RNA_def_function_ui_description(func, "Add a new texture.");
+ parm= RNA_def_string(func, "name", "Tex", 0, "", "New name for the datablock."); /* optional */
+ parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "add_image", "rna_Main_add_image");
+ RNA_def_function_ui_description(func, "Add a new image.");
+ parm= RNA_def_string(func, "filename", "", 0, "", "Filename to load image from.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "image", "Image", "", "New image.");
+ RNA_def_function_return(func, parm);
+
}
#endif
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index cd1159bc138..661b1c5e1c3 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -33,6 +33,7 @@
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
+#include "WM_api.h"
#include "WM_types.h"
static EnumPropertyItem prop_texture_coordinates_items[] = {
@@ -53,10 +54,28 @@ static EnumPropertyItem prop_texture_coordinates_items[] = {
#include "MEM_guardedalloc.h"
+#include "BKE_depsgraph.h"
+#include "BKE_main.h"
#include "BKE_texture.h"
#include "ED_node.h"
+static void rna_Material_update(bContext *C, PointerRNA *ptr)
+{
+ Material *ma= ptr->id.data;
+
+ DAG_id_flush_update(&ma->id, 0);
+ WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, ma);
+}
+
+static void rna_Material_draw_update(bContext *C, PointerRNA *ptr)
+{
+ Material *ma= ptr->id.data;
+
+ DAG_id_flush_update(&ma->id, 0);
+ WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING_DRAW, ma);
+}
+
static PointerRNA rna_Material_mirror_get(PointerRNA *ptr)
{
return rna_pointer_inherit_refine(ptr, &RNA_MaterialRaytraceMirror, ptr->id.data);
@@ -212,7 +231,7 @@ static void rna_Material_use_specular_ramp_set(PointerRNA *ptr, int value)
ma->ramp_spec= add_colorband(0);
}
-void rna_Material_use_nodes_set(PointerRNA *ptr, int value)
+static void rna_Material_use_nodes_set(PointerRNA *ptr, int value)
{
Material *ma= (Material*)ptr->data;
@@ -308,291 +327,302 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_texture_coordinates_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Material_texture_coordinates_itemf");
RNA_def_property_ui_text(prop, "Texture Coordinates", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object");
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvname");
RNA_def_property_ui_text(prop, "UV Layer", "UV layer to use for mapping with UV texture coordinates.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_DUPLI_MAPTO);
RNA_def_property_ui_text(prop, "From Dupli", "Dupli's instanced from verts, faces or particles, inherit texture coordinate from their parent.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "from_original", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_OB_DUPLI_ORIG);
RNA_def_property_ui_text(prop, "From Original", "Dupli's derive their object coordinates from the original objects transformation.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_colordiff", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COL);
RNA_def_property_ui_text(prop, "Diffuse Color", "Causes the texture to affect basic color of the material");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_NORM);
RNA_def_property_ui_text(prop, "Normal", "Causes the texture to affect the rendered normal");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_colorspec", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COLSPEC);
RNA_def_property_ui_text(prop, "Specular Color", "Causes the texture to affect the specularity color");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_mirror", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COLMIR);
RNA_def_property_ui_text(prop, "Mirror", "Causes the texture to affect the mirror color");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_diffuse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REF);
RNA_def_property_ui_text(prop, "Diffuse", "Causes the texture to affect the value of the materials diffuse reflectivity");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_specular", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_SPEC);
RNA_def_property_ui_text(prop, "Specular", "Causes the texture to affect the value of specular reflectivity");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_ambient", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_AMB);
RNA_def_property_ui_text(prop, "Ambient", "Causes the texture to affect the value of ambient");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_hardness", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_HAR);
RNA_def_property_ui_text(prop, "Hardness", "Causes the texture to affect the hardness value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_raymir", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_RAYMIRR);
RNA_def_property_ui_text(prop, "Ray-Mirror", "Causes the texture to affect the ray-mirror value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ALPHA);
RNA_def_property_ui_text(prop, "Alpha", "Causes the texture to affect the alpha value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_emit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMIT);
RNA_def_property_ui_text(prop, "Emit", "Causes the texture to affect the emit value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_translucency", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_TRANSLU);
RNA_def_property_ui_text(prop, "Translucency", "Causes the texture to affect the translucency value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_displacement", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_DISPLACE);
RNA_def_property_ui_text(prop, "Displacement", "Let the texture displace the surface");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_warp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_WARP);
RNA_def_property_ui_text(prop, "Warp", "Let the texture warp texture coordinates of next channels");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "x_mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projx");
RNA_def_property_enum_items(prop, prop_x_mapping_items);
RNA_def_property_ui_text(prop, "X Mapping", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "y_mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projy");
RNA_def_property_enum_items(prop, prop_y_mapping_items);
RNA_def_property_ui_text(prop, "Y Mapping", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "z_mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projz");
RNA_def_property_enum_items(prop, prop_z_mapping_items);
RNA_def_property_ui_text(prop, "Z Mapping", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_mapping_items);
RNA_def_property_ui_text(prop, "Mapping", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- /* XXX: pmapto, pmaptoneg */
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "normal_map_space", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "normapspace");
RNA_def_property_enum_items(prop, prop_normal_map_space_items);
RNA_def_property_ui_text(prop, "Normal Map Space", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- /* XXX: MTex.which_output */
-
- /* XXX: MTex.k */
+ prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "norfac");
+ RNA_def_property_ui_range(prop, 0, 5, 10, 3);
+ RNA_def_property_ui_text(prop, "Normal Factor", "Amount texture affects normal values.");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "displacement_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "dispfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Displacement Factor", "Amount texture displaces the surface.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "warp_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "warpfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Warp Factor", "Amount texture affects texture coordinates of next channels.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "colorspec_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_float_sdna(prop, NULL, "colspecfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Specular Color Factor", "Amount texture affects specular color.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "colordiff_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Diffuse Color Factor", "Amount texture affects diffuse color.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "mirror_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_float_sdna(prop, NULL, "mirrfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Mirror Factor", "Amount texture affects mirror color.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "alpha_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "alphafac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Alpha Factor", "Amount texture affects alpha.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "difffac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Diffuse Factor", "Amount texture affects diffuse reflectivity.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "specfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Specular Factor", "Amount texture affects specular reflectivity.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "emit_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "emitfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Emit Factor", "Amount texture affects emission.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "hardness_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "hardfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Hardness Factor", "Amount texture affects hardness.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "raymir_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "raymirrfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Ray Mirror Factor", "Amount texture affects ray mirror.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "translucency_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "translfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Translucency Factor", "Amount texture affects translucency.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ambient_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "ambfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Ambient Factor", "Amount texture affects ambient.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
/* volume material */
prop= RNA_def_property(srna, "map_coloremission", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMISSION_COL);
- RNA_def_property_ui_text(prop, "Emission Color", "Causes the texture to affect the colour of emission");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_ui_text(prop, "Emission Color", "Causes the texture to affect the color of emission");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "map_colorabsorption", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ABSORPTION_COL);
- RNA_def_property_ui_text(prop, "Absorption Color", "Causes the texture to affect the result colour after absorption");
+ prop= RNA_def_property(srna, "map_colorreflection", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REFLECTION_COL);
+ RNA_def_property_ui_text(prop, "Reflection Color", "Causes the texture to affect the color of scattered light");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
+ prop= RNA_def_property(srna, "map_colortransmission", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_TRANSMISSION_COL);
+ RNA_def_property_ui_text(prop, "Transmission Color", "Causes the texture to affect the result color after other light has been scattered/absorbed");
RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_density", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_DENSITY);
RNA_def_property_ui_text(prop, "Density", "Causes the texture to affect the volume's density");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_emission", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMISSION);
RNA_def_property_ui_text(prop, "Emission", "Causes the texture to affect the volume's emission");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- prop= RNA_def_property(srna, "map_absorption", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ABSORPTION);
- RNA_def_property_ui_text(prop, "Absorption", "Causes the texture to affect the volume's absorption");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "map_scattering", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_SCATTERING);
RNA_def_property_ui_text(prop, "Scattering", "Causes the texture to affect the volume's scattering");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
+ prop= RNA_def_property(srna, "map_reflection", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REFLECTION);
+ RNA_def_property_ui_text(prop, "Reflection", "Causes the texture to affect the reflected light's brightness");
RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "coloremission_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_float_sdna(prop, NULL, "colemitfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Emission Color Factor", "Amount texture affects emission color.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "colorabsorption_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ prop= RNA_def_property(srna, "colorreflection_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "colreflfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Absorpion Color Factor", "Amount texture affects diffuse color.");
+ RNA_def_property_ui_text(prop, "Reflection Color Factor", "Amount texture affects color of out-scattered light");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
+ prop= RNA_def_property(srna, "colortransmission_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "coltransfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Transmission Color Factor", "Amount texture affects result color after light has been scattered/absorbed.");
RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "density_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "densfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Density Factor", "Amount texture affects density.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "emission_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "emitfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Emission Factor", "Amount texture affects emission.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- prop= RNA_def_property(srna, "absorption_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
- RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Absorption Factor", "Amount texture affects absorption.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "scattering_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "scatterfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Scattering Factor", "Amount texture affects scattering.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
+ prop= RNA_def_property(srna, "reflection_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "reflfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Reflection Factor", "Amount texture affects brightness of out-scattered light.");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
/* end volume material */
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_MaterialTextureSlot_enabled_get", "rna_MaterialTextureSlot_enabled_set");
RNA_def_property_ui_text(prop, "Enabled", "Enable this material texture slot.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "new_bump", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_NEW_BUMP);
RNA_def_property_ui_text(prop, "New Bump", "Use new, corrected bump mapping code (backwards compatibility option).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
static void rna_def_material_colors(StructRNA *srna)
@@ -631,77 +661,79 @@ static void rna_def_material_colors(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "r");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Diffuse Color", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop= RNA_def_property(srna, "specular_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "specr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Specular Color", "Specular color of the material.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop= RNA_def_property(srna, "mirror_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "mirr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Mirror Color", "Mirror color of the material.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Alpha", "Alpha transparency of the material.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
- prop= RNA_def_property(srna, "specular_alpha", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "specular_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "spectra");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Specular Alpha", "Alpha transparency for specular areas.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
/* Color bands */
prop= RNA_def_property(srna, "use_diffuse_ramp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAMP_COL);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_diffuse_ramp_set");
RNA_def_property_ui_text(prop, "Use Diffuse Ramp", "Toggle diffuse ramp operations.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_ramp", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ramp_col");
RNA_def_property_struct_type(prop, "ColorRamp");
RNA_def_property_ui_text(prop, "Diffuse Ramp", "Color ramp used to affect diffuse shading.");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "use_specular_ramp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAMP_SPEC);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_specular_ramp_set");
RNA_def_property_ui_text(prop, "Use Specular Ramp", "Toggle specular ramp operations.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_ramp", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ramp_spec");
RNA_def_property_struct_type(prop, "ColorRamp");
RNA_def_property_ui_text(prop, "Specular Ramp", "Color ramp used to affect specular shading.");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_ramp_blend", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rampblend_col");
RNA_def_property_enum_items(prop, prop_ramp_blend_diffuse_items);
RNA_def_property_ui_text(prop, "Diffuse Ramp Blend", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_ramp_blend", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rampblend_spec");
RNA_def_property_enum_items(prop, prop_ramp_blend_diffuse_items);
RNA_def_property_ui_text(prop, "Diffuse Ramp Blend", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_ramp_input", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rampin_col");
RNA_def_property_enum_items(prop, prop_ramp_input_items);
RNA_def_property_ui_text(prop, "Diffuse Ramp Input", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_ramp_input", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rampin_spec");
RNA_def_property_enum_items(prop, prop_ramp_input_items);
RNA_def_property_ui_text(prop, "Specular Ramp Input", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
@@ -721,47 +753,47 @@ static void rna_def_material_diffuse(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "diff_shader");
RNA_def_property_enum_items(prop, prop_diff_shader_items);
RNA_def_property_ui_text(prop, "Diffuse Shader Model", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "diffuse_intensity", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "diffuse_intensity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "ref");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Diffuse Intensity", "Amount of diffuse reflection.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop= RNA_def_property(srna, "roughness", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 3.14f);
RNA_def_property_ui_text(prop, "Roughness", "Oren-Nayar Roughness");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_toon_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "param[0]");
RNA_def_property_range(prop, 0.0f, 3.14f);
RNA_def_property_ui_text(prop, "Diffuse Toon Size", "Size of diffuse toon area.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "diffuse_toon_smooth", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "diffuse_toon_smooth", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "param[1]");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Diffuse Toon Smooth", "Smoothness of diffuse toon area.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_fresnel", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "param[1]");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_ui_text(prop, "Diffuse Fresnel", "Power of Fresnel.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "diffuse_fresnel_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "param[0]");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_ui_text(prop, "Diffuse Fresnel Factor", "Blending factor of Frensel.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "darkness", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 2.0f);
RNA_def_property_ui_text(prop, "Darkness", "Minnaert darkness.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
static void rna_def_material_raymirror(BlenderRNA *brna)
@@ -782,67 +814,67 @@ static void rna_def_material_raymirror(BlenderRNA *brna)
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAYMIRROR); /* use bitflags */
RNA_def_property_ui_text(prop, "Enabled", "Enable raytraced reflections.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "ray_mirror");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Reflectivity", "Sets the amount mirror reflection for raytrace.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "fresnel", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fresnel_mir");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_ui_text(prop, "Fresnel", "Power of Fresnel for mirror reflection.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "fresnel_mir_i");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "gloss_mir");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Gloss Amount", "The shininess of the reflection. Values < 1.0 give diffuse, blurry reflections.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "gloss_anisotropic", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "gloss_anisotropic", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "aniso_gloss_mir");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Gloss Anisotropy", "The shape of the reflection, from 0.0 (circular) to 1.0 (fully stretched along the tangent.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "gloss_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samp_gloss_mir");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Gloss Samples", "Number of cone samples averaged for blurry reflections.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "adapt_thresh_mir");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Gloss Threshold", "Threshold for adaptive sampling. If a sample contributes less than this amount (as a percentage), sampling is stopped.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "depth", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ray_depth");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Depth", "Maximum allowed number of light inter-reflections.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist_mir");
RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_text(prop, "Maximum Distance", "Maximum distance of reflected rays. Reflections further than this range fade to sky color or material color.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "fade_to", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "fadeto_mir");
RNA_def_property_enum_items(prop, prop_fadeto_mir_items);
RNA_def_property_ui_text(prop, "Fade-out Color", "The color that rays with no intersection within the Max Distance take. Material color can be best for indoor scenes, sky color for outdoor.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
static void rna_def_material_raytra(BlenderRNA *brna)
@@ -859,61 +891,61 @@ static void rna_def_material_raytra(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "ang");
RNA_def_property_range(prop, 1.0f, 3.0f);
RNA_def_property_ui_text(prop, "IOR", "Sets angular index of refraction for raytraced refraction.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "fresnel", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fresnel_tra");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_ui_text(prop, "Fresnel", "Power of Fresnel for transparency (Ray or ZTransp).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "fresnel_tra_i");
RNA_def_property_range(prop, 1.0f, 5.0f);
RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "gloss_tra");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Gloss Amount", "The clarity of the refraction. Values < 1.0 give diffuse, blurry refractions.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "gloss_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samp_gloss_tra");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Gloss Samples", "Number of cone samples averaged for blurry refractions.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "adapt_thresh_tra");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Gloss Threshold", "Threshold for adaptive sampling. If a sample contributes less than this amount (as a percentage), sampling is stopped.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "depth", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ray_depth_tra");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Depth", "Maximum allowed number of light inter-refractions.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "filter", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "filter", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "filter");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Filter", "Amount to blend in the material's diffuse color in raytraced transparency (simulating absorption).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "limit", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "tx_limit");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Limit", "Maximum depth for light to travel through the transparent material before becoming fully filtered (0.0 is disabled).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "tx_falloff");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Falloff", "Falloff power for transmissivity filter effect (1.0 is linear).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
static void rna_def_material_volume(BlenderRNA *brna)
@@ -934,15 +966,6 @@ static void rna_def_material_volume(BlenderRNA *brna)
//{MA_VOL_STEP_ADAPTIVE, "ADAPTIVE", 0, "Adaptive", ""},
{0, NULL, 0, NULL, NULL}};
- static EnumPropertyItem prop_phasefunction_items[] = {
- {MA_VOL_PH_ISOTROPIC, "ISOTROPIC", 0, "Isotropic", ""},
- {MA_VOL_PH_MIEHAZY, "MIE_HAZY", 0, "Mie Hazy", ""},
- {MA_VOL_PH_MIEMURKY, "MIE_MURKY", 0, "Mie Murky", ""},
- {MA_VOL_PH_RAYLEIGH, "RAYLEIGH", 0, "Rayleigh", ""},
- {MA_VOL_PH_HG, "HENYEY-GREENSTEIN", 0, "Henyey-Greenstein", ""},
- {MA_VOL_PH_SCHLICK, "SCHLICK", 0, "Schlick", ""},
- {0, NULL, 0, NULL, NULL}};
-
srna= RNA_def_struct(brna, "MaterialVolume", NULL);
RNA_def_struct_sdna(srna, "VolumeSettings");
RNA_def_struct_nested(brna, srna, "Material");
@@ -952,120 +975,113 @@ static void rna_def_material_volume(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "stepsize_type");
RNA_def_property_enum_items(prop, prop_stepsize_items);
RNA_def_property_ui_text(prop, "Step Calculation", "Method of calculating the steps through the volume");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "step_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stepsize");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
RNA_def_property_ui_text(prop, "Step Size", "Distance between subsequent volume depth samples.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
-
- prop= RNA_def_property(srna, "shading_step_size", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "shade_stepsize");
- RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Shading Step Size", "Distance between subsequent volume shading samples.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "scattering_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shade_type");
RNA_def_property_enum_items(prop, prop_scattering_items);
RNA_def_property_ui_text(prop, "Scattering Mode", "Method of shading, attenuating, and scattering light through the volume");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "light_cache", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shadeflag", MA_VOL_PRECACHESHADING); /* use bitflags */
RNA_def_property_ui_text(prop, "Light Cache", "Pre-calculate the shading information into a voxel grid, speeds up shading at slightly less accuracy");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "cache_resolution", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "precache_resolution");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the voxel grid, low resolutions are faster, high resolutions use more memory.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ms_diffusion", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ms_diff");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Diffusion", "Diffusion factor, the strength of the blurring effect");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ms_spread", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ms_steps");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Spread", "Simulation steps, the effective distance over which the light is diffused");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ms_intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ms_intensity");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Intensity", "Multiplier for multiple scattered light energy");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "depth_cutoff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "depth_cutoff");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Depth Cutoff", "Stop ray marching early if transmission drops below this luminance - higher values give speedups in dense volumes at the expense of accuracy.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "density", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "density", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "density");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Density", "The base density of the volume");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "density_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "density_scale");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
RNA_def_property_ui_text(prop, "Density Scale", "Multiplier for the material's density");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
-
- prop= RNA_def_property(srna, "absorption", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "absorption");
- RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Absorption", "Amount of light that gets absorbed by the volume - higher values mean light travels less distance");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
-
- prop= RNA_def_property(srna, "absorption_color", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_float_sdna(prop, NULL, "absorption_col");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Absorption Color", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "scattering", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "scattering");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1 ,3);
- RNA_def_property_ui_text(prop, "Scattering", "Amount of light that gets scattered by the volume - values > 1.0 are non-physical");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_ui_text(prop, "Scattering", "Amount of light that gets scattered out by the volume - the more out-scattering, the shallower the light will penetrate ");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "emission", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "emission");
+ prop= RNA_def_property(srna, "transmission_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "transmission_col");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Transmission Color", "Result color of the volume, after other light has been scattered/absorbed");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop= RNA_def_property(srna, "reflection_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "reflection_col");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Reflection Color", "Colour of light scattered out of the volume (does not affect transmission)");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop= RNA_def_property(srna, "reflection", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "reflection");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Emission", "Amount of light that gets emitted by the volume");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1 ,3);
+ RNA_def_property_ui_text(prop, "Reflection", "Multiplier to make out-scattered light brighter or darker (non-physically correct)");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "emission_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "emission_col");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Emission Color", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
-
- prop= RNA_def_property(srna, "phase_function", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "phasefunc_type");
- RNA_def_property_enum_items(prop, prop_phasefunction_items);
- RNA_def_property_ui_text(prop, "Phase Function", "Isotropic/Anisotropic scattering");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+ prop= RNA_def_property(srna, "emission", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "emission");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_ui_text(prop, "Emission", "Amount of light that gets emitted by the volume");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
prop= RNA_def_property(srna, "asymmetry", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "phasefunc_g");
+ RNA_def_property_float_sdna(prop, NULL, "asymmetry");
RNA_def_property_range(prop, -1.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Asymmetry", "Continuum between forward scattering and back scattering");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_ui_text(prop, "Asymmetry", "Back scattering (-1.0) to Forward scattering (1.0) and the range in between.");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
@@ -1083,118 +1099,118 @@ static void rna_def_material_halo(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "hasize");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Size", "Sets the dimension of the halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "hardness", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "har");
RNA_def_property_range(prop, 0, 127);
RNA_def_property_ui_text(prop, "Hardness", "Sets the hardness of the halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "add", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "add", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "add");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Add", "Sets the strength of the add effect.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "rings", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ringc");
RNA_def_property_range(prop, 0, 24);
RNA_def_property_ui_text(prop, "Rings", "Sets the number of rings rendered over the halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "line_number", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "linec");
RNA_def_property_range(prop, 0, 250);
RNA_def_property_ui_text(prop, "Line Number", "Sets the number of star shaped lines rendered over the halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "star_tips", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "starc");
RNA_def_property_range(prop, 3, 50);
RNA_def_property_ui_text(prop, "Star Tips", "Sets the number of points on the star shaped halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "seed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "seed1");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_text(prop, "Seed", "Randomizes ring dimension and line location.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "flare_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_FLARE); /* use bitflags */
RNA_def_property_ui_text(prop, "Flare", "Renders halo as a lensflare.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "flare_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "flaresize");
RNA_def_property_range(prop, 0.1f, 25.0f);
RNA_def_property_ui_text(prop, "Flare Size", "Sets the factor by which the flare is larger than the halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "flare_subsize", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "subsize");
RNA_def_property_range(prop, 0.1f, 25.0f);
RNA_def_property_ui_text(prop, "Flare Subsize", "Sets the dimension of the subflares, dots and circles.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "flare_boost", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "flareboost");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Flare Boost", "Gives the flare extra strength.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "flare_seed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "seed2");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_text(prop, "Flare Seed", "Specifies an offset in the flare seed table.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "flares_sub", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "flarec");
RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "Flares Sub", "Sets the number of subflares.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ring", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_RINGS);
RNA_def_property_ui_text(prop, "Rings", "Renders rings over halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "lines", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_LINES);
RNA_def_property_ui_text(prop, "Lines", "Renders star shaped lines over halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "star", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_STAR);
RNA_def_property_ui_text(prop, "Star", "Renders halo as a star.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "texture", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALOTEX);
RNA_def_property_ui_text(prop, "Texture", "Gives halo a texture.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "vertex_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALOPUNO);
RNA_def_property_ui_text(prop, "Vertex Normal", "Uses the vertex normal to specify the dimension of the halo.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "xalpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_XALPHA);
RNA_def_property_ui_text(prop, "Extreme Alpha", "Uses extreme alpha.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "shaded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_SHADE);
RNA_def_property_ui_text(prop, "Shaded", "Lets halo receive light and shadows from external objects.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "soft", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALO_SOFT);
RNA_def_property_ui_text(prop, "Soft", "Softens the edges of halos at intersections with other geometry.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
static void rna_def_material_sss(BlenderRNA *brna)
@@ -1212,62 +1228,62 @@ static void rna_def_material_sss(BlenderRNA *brna)
RNA_def_property_range(prop, 0.001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001, 10000, 1, 3);
RNA_def_property_ui_text(prop, "Radius", "Mean red/green/blue scattering path length.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "sss_col");
RNA_def_property_ui_text(prop, "Color", "Scattering color.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "error_tolerance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sss_error");
RNA_def_property_ui_range(prop, 0.0001, 10, 1, 3);
RNA_def_property_ui_text(prop, "Error Tolerance", "Error tolerance (low values are slower and higher quality).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sss_scale");
RNA_def_property_ui_range(prop, 0.001, 1000, 1, 3);
RNA_def_property_ui_text(prop, "Scale", "Object scale factor.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ior", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sss_ior");
RNA_def_property_ui_range(prop, 0.1, 2, 1, 3);
RNA_def_property_ui_text(prop, "IOR", "Index of refraction (higher values are denser).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "sss_colfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Color Factor", "Blend factor for SSS colors.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "texture_factor", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "texture_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "sss_texfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Texture Factor", "Texture scatting blend factor.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "front", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sss_front");
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Front", "Front scattering weight.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "back", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sss_back");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Back", "Back scattering weight.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sss_flag", MA_DIFF_SSS);
RNA_def_property_ui_text(prop, "Enabled", "Enable diffuse subsurface scatting effects in a material.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
-void rna_def_material_specularity(StructRNA *srna)
+static void rna_def_material_specularity(StructRNA *srna)
{
PropertyRNA *prop;
@@ -1283,13 +1299,13 @@ void rna_def_material_specularity(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "spec_shader");
RNA_def_property_enum_items(prop, prop_specular_shader_items);
RNA_def_property_ui_text(prop, "Specular Shader Model", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "spec");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Specular Intensity", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
/* NOTE: "har", "param", etc are used for multiple purposes depending on
* settings. This should be fixed in DNA once, for RNA we just expose them
@@ -1300,34 +1316,34 @@ void rna_def_material_specularity(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "har");
RNA_def_property_range(prop, 1, 511);
RNA_def_property_ui_text(prop, "Specular Hardness", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_ior", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "refrac");
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_text(prop, "Specular IOR", "");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_toon_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "param[2]");
RNA_def_property_range(prop, 0.0f, 1.53f);
RNA_def_property_ui_text(prop, "Specular Toon Size", "Size of specular toon area.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "specular_toon_smooth", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "specular_toon_smooth", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "param[3]");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Specular Toon Smooth", "Ssmoothness of specular toon area.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "specular_slope", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rms");
RNA_def_property_range(prop, 0, 0.4);
RNA_def_property_ui_text(prop, "Specular Slope", "The standard deviation of surface slope.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
-void rna_def_material_strand(BlenderRNA *brna)
+static void rna_def_material_strand(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -1340,61 +1356,61 @@ void rna_def_material_strand(BlenderRNA *brna)
prop= RNA_def_property(srna, "tangent_shading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TANGENT_STR);
RNA_def_property_ui_text(prop, "Tangent Shading", "Uses direction of strands as normal for tangent-shading.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "surface_diffuse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_STR_SURFDIFF);
RNA_def_property_ui_text(prop, "Surface Diffuse", "Make diffuse shading more similar to shading the surface.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "blend_distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "strand_surfnor");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Blend Distance", "Worldspace distance over which to blend in the surface normal.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "blender_units", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_STR_B_UNITS);
RNA_def_property_ui_text(prop, "Blender Units", "Use Blender units for widths instead of pixels.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "root_size", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "strand_sta");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_MaterialStrand_start_size_range");
RNA_def_property_ui_text(prop, "Root Size", "Start size of strands in pixels Blender units.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "tip_size", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "strand_end");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_MaterialStrand_end_size_range");
RNA_def_property_ui_text(prop, "Tip Size", "Start size of strands in pixels or Blender units.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "min_size", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "strand_min");
RNA_def_property_range(prop, 0.001, 10);
RNA_def_property_ui_text(prop, "Minimum Size", "Minimum size of strands in pixels.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "shape", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "strand_ease");
RNA_def_property_range(prop, -0.9, 0.9);
RNA_def_property_ui_text(prop, "Shape", "Positive values make strands rounder, negative makes strands spiky.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "width_fade", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "strand_widthfade");
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Width Fade", "Transparency along the width of the strand.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "strand_uvname");
RNA_def_property_ui_text(prop, "UV Layer", "Name of UV layer to override.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
}
-void rna_def_material_physics(BlenderRNA *brna)
+static void rna_def_material_physics(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -1459,45 +1475,45 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "Material type defining how the object is rendered.");
RNA_def_property_enum_funcs(prop, NULL, "rna_Material_type_set", NULL);
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop= RNA_def_property(srna, "transparency", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRANSP);
RNA_def_property_ui_text(prop, "Transparency", "Render material as transparent.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "transparency_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, transparency_items);
RNA_def_property_ui_text(prop, "Transparency Method", "Method to use for rendering transparency.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "ambient", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "ambient", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "amb");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Ambient", "Amount of global ambient color the material receives.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "emit", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 2.0f, 10, 2);
RNA_def_property_ui_text(prop, "Emit", "Amount of light to emit.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "translucency", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "translucency", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Translucency", "Amount of diffuse shading on the back side.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "cubic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_CUBIC);
RNA_def_property_ui_text(prop, "Cubic Interpolation", "Use cubic interpolation for diffuse values, for smoother transitions.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "object_color", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_OBCOLOR);
RNA_def_property_ui_text(prop, "Object Color", "Modulate the result with a per-object color.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "shadow_ray_bias", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sbias");
@@ -1509,143 +1525,150 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Factor to multiply shadow buffer bias with (0 is ignore.)");
- prop= RNA_def_property(srna, "shadow_casting_alpha", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "shadow_casting_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "shad_alpha");
RNA_def_property_range(prop, 0.001, 1);
RNA_def_property_ui_text(prop, "Shadow Casting Alpha", "Shadow casting alpha, only in use for Irregular Shadowbuffer.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "light_group", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "group");
RNA_def_property_struct_type(prop, "Group");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Light Group", "Limit lighting to lamps in this Group.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
/* flags */
prop= RNA_def_property(srna, "light_group_exclusive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_GROUP_NOLAY);
RNA_def_property_ui_text(prop, "Light Group Exclusive", "Material uses the light group exclusively - these lamps are excluded from other scene lighting.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "traceable", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRACEBLE);
RNA_def_property_ui_text(prop, "Traceable", "Include this material and geometry that uses it in ray tracing calculations.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADOW);
RNA_def_property_ui_text(prop, "Shadows", "Allows this material to receive shadows.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "shadeless", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHLESS);
RNA_def_property_ui_text(prop, "Shadeless", "Makes this material insensitive to light or shadow.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "vertex_color_light", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_VERTEXCOL);
RNA_def_property_ui_text(prop, "Vertex Color Light", "Add vertex colors as additional lighting.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "vertex_color_paint", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_VERTEXCOLP);
RNA_def_property_ui_text(prop, "Vertex Color Paint", "Replaces object base color with vertex colors (multiplies with 'texture face' face assigned textures).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "invert_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ZINV);
RNA_def_property_ui_text(prop, "Invert Z Depth", "Renders material's faces with an inverted Z buffer (scanline only).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "sky", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ENV);
RNA_def_property_ui_text(prop, "Sky", "Renders this material with zero alpha, with sky background in place (scanline only).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "only_shadow", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYSHADOW);
RNA_def_property_ui_text(prop, "Only Shadow", "Renders shadows as the material's alpha value, making materials transparent except for shadowed areas.");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "face_texture", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE);
RNA_def_property_ui_text(prop, "Face Textures", "Replaces the object's base color with color from face assigned image textures");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "face_texture_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE_ALPHA);
RNA_def_property_ui_text(prop, "Face Textures Alpha", "Replaces the object's base alpha value with alpha from face assigned image textures");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "cast_shadows_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYCAST);
RNA_def_property_ui_text(prop, "Cast Shadows Only", "Makes objects with this material appear invisible, only casting shadows (not rendered).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "exclude_mist", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_NOMIST);
RNA_def_property_ui_text(prop, "Exclude Mist", "Excludes this material from mist effects (in world settings)");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "receive_transparent_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADOW_TRA);
RNA_def_property_ui_text(prop, "Receive Transparent Shadows", "Allow this object to receive transparent shadows casted through other objects");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "ray_shadow_bias", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAYBIAS);
RNA_def_property_ui_text(prop, "Ray Shadow Bias", "Prevents raytraced shadow errors on surfaces with smooth shaded normals (terminator problem)");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "full_oversampling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FULL_OSA);
RNA_def_property_ui_text(prop, "Full Oversampling", "Force this material to render full shading/textures for all anti-aliasing samples");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "cast_buffer_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADBUF);
RNA_def_property_ui_text(prop, "Cast Buffer Shadows", "Allow this material to cast shadows from shadow buffer lamps");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "tangent_shading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TANGENT_V);
RNA_def_property_ui_text(prop, "Tangent Shading", "Use the material's tangent vector instead of the normal for shading - for anisotropic shading effects");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
+ RNA_def_property_update(prop, 0, "rna_Material_update");
/* nested structs */
- prop= RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "MaterialRaytraceMirror");
RNA_def_property_pointer_funcs(prop, "rna_Material_mirror_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Raytrace Mirror", "Raytraced reflection settings for the material.");
- prop= RNA_def_property(srna, "raytrace_transparency", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "raytrace_transparency", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "MaterialRaytraceTransparency");
RNA_def_property_pointer_funcs(prop, "rna_Material_transp_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Raytrace Transparency", "Raytraced reflection settings for the material.");
- prop= RNA_def_property(srna, "volume", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "volume", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "vol");
RNA_def_property_struct_type(prop, "MaterialVolume");
RNA_def_property_ui_text(prop, "Volume", "Volume settings for the material.");
- prop= RNA_def_property(srna, "halo", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "halo", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "MaterialHalo");
RNA_def_property_pointer_funcs(prop, "rna_Material_halo_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Halo", "Halo settings for the material.");
- prop= RNA_def_property(srna, "subsurface_scattering", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "subsurface_scattering", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "MaterialSubsurfaceScattering");
RNA_def_property_pointer_funcs(prop, "rna_Material_sss_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Subsurface Scattering", "Subsurface scattering settings for the material.");
- prop= RNA_def_property(srna, "strand", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "strand", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "MaterialStrand");
RNA_def_property_pointer_funcs(prop, "rna_Material_strand_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Strand", "Strand settings for the material.");
- prop= RNA_def_property(srna, "physics", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "physics", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "MaterialPhysics");
RNA_def_property_pointer_funcs(prop, "rna_Material_physics_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Physics", "Game physics settings.");
@@ -1664,7 +1687,7 @@ void RNA_def_material(BlenderRNA *brna)
/* common */
rna_def_animdata_common(srna);
rna_def_mtex_common(srna, "rna_Material_mtex_begin", "rna_Material_active_texture_get",
- "rna_Material_active_texture_set", "MaterialTextureSlot");
+ "rna_Material_active_texture_set", "MaterialTextureSlot", "rna_Material_update");
rna_def_material_colors(srna);
rna_def_material_diffuse(srna);
@@ -1679,9 +1702,11 @@ void RNA_def_material(BlenderRNA *brna)
rna_def_material_mtex(brna);
rna_def_material_strand(brna);
rna_def_material_physics(brna);
+
+ RNA_api_material(srna);
}
-void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeget, const char *activeset, const char *structname)
+void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeget, const char *activeset, const char *structname, const char *update)
{
PropertyRNA *prop;
@@ -1696,13 +1721,13 @@ void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeg
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_funcs(prop, activeget, activeset, NULL);
RNA_def_property_ui_text(prop, "Active Texture", "Active texture slot being displayed.");
- RNA_def_property_update(prop, NC_TEXTURE|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, update);
prop= RNA_def_property(srna, "active_texture_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "texact");
RNA_def_property_range(prop, 0, MAX_MTEX-1);
RNA_def_property_ui_text(prop, "Active Texture Index", "Index of active texture slot.");
- RNA_def_property_update(prop, NC_TEXTURE|ND_SHADING_DRAW, NULL);
+ RNA_def_property_update(prop, 0, update);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_material_api.c b/source/blender/makesrna/intern/rna_material_api.c
new file mode 100644
index 00000000000..aa28b6b923c
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_material_api.c
@@ -0,0 +1,126 @@
+/**
+ *
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#include "DNA_material_types.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_material.h"
+#include "BKE_texture.h"
+
+/*
+ Adds material to the first free texture slot.
+ If all slots are busy, replaces the first.
+*/
+static void rna_Material_add_texture(Material *ma, Tex *tex, int mapto, int texco)
+{
+ int i;
+ MTex *mtex;
+ int slot= -1;
+
+ for (i= 0; i < MAX_MTEX; i++) {
+ if (!ma->mtex[i]) {
+ slot= i;
+ break;
+ }
+ }
+
+ if (slot == -1)
+ slot= 0;
+
+ if (ma->mtex[slot]) {
+ ma->mtex[slot]->tex->id.us--;
+ }
+ else {
+ ma->mtex[slot]= add_mtex();
+ }
+
+ mtex= ma->mtex[slot];
+
+ mtex->tex= tex;
+ id_us_plus(&tex->id);
+
+ mtex->texco= mapto;
+ mtex->mapto= texco;
+}
+
+#else
+
+void RNA_api_material(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ /* copied from rna_def_material_mtex (rna_material.c) */
+ static EnumPropertyItem prop_texture_coordinates_items[] = {
+ {TEXCO_GLOB, "GLOBAL", 0, "Global", "Uses global coordinates for the texture coordinates."},
+ {TEXCO_OBJECT, "OBJECT", 0, "Object", "Uses linked object's coordinates for texture coordinates."},
+ {TEXCO_UV, "UV", 0, "UV", "Uses UV coordinates for texture coordinates."},
+ {TEXCO_ORCO, "ORCO", 0, "Generated", "Uses the original undeformed coordinates of the object."},
+ {TEXCO_STRAND, "STRAND", 0, "Strand", "Uses normalized strand texture coordinate (1D)."},
+ {TEXCO_STICKY, "STICKY", 0, "Sticky", "Uses mesh's sticky coordinates for the texture coordinates."},
+ {TEXCO_WINDOW, "WINDOW", 0, "Window", "Uses screen coordinates as texture coordinates."},
+ {TEXCO_NORM, "NORMAL", 0, "Normal", "Uses normal vector as texture coordinates."},
+ {TEXCO_REFL, "REFLECTION", 0, "Reflection", "Uses reflection vector as texture coordinates."},
+ {TEXCO_STRESS, "STRESS", 0, "Stress", "Uses the difference of edge lengths compared to original coordinates of the mesh."},
+ {TEXCO_TANGENT, "TANGENT", 0, "Tangent", "Uses the optional tangent vector as texture coordinates."},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem prop_texture_mapto_items[] = {
+ {MAP_COL, "COLOR", 0, "Color", "Causes the texture to affect basic color of the material"},
+ {MAP_NORM, "NORMAL", 0, "Normal", "Causes the texture to affect the rendered normal"},
+ {MAP_COLSPEC, "SPECULAR_COLOR", 0, "Specularity Color", "Causes the texture to affect the specularity color"},
+ {MAP_COLMIR, "MIRROR", 0, "Mirror", "Causes the texture to affect the mirror color"},
+ {MAP_REF, "REFLECTION", 0, "Reflection", "Causes the texture to affect the value of the materials reflectivity"},
+ {MAP_SPEC, "SPECULARITY", 0, "Specularity", "Causes the texture to affect the value of specularity"},
+ {MAP_EMIT, "EMIT", 0, "Emit", "Causes the texture to affect the emit value"},
+ {MAP_ALPHA, "ALPHA", 0, "Alpha", "Causes the texture to affect the alpha value"},
+ {MAP_HAR, "HARDNESS", 0, "Hardness", "Causes the texture to affect the hardness value"},
+ {MAP_RAYMIRR, "RAY_MIRROR", 0, "Ray-Mirror", "Causes the texture to affect the ray-mirror value"},
+ {MAP_TRANSLU, "TRANSLUCENCY", 0, "Translucency", "Causes the texture to affect the translucency value"},
+ {MAP_AMB, "AMBIENT", 0, "Ambient", "Causes the texture to affect the value of ambient"},
+ {MAP_DISPLACE, "DISPLACEMENT", 0, "Displacement", "Let the texture displace the surface"},
+ {MAP_WARP, "WARP", 0, "Warp", "Let the texture warp texture coordinates of next channels"},
+ {0, NULL, 0, NULL, NULL}};
+
+ func= RNA_def_function(srna, "add_texture", "rna_Material_add_texture");
+ RNA_def_function_ui_description(func, "Add a texture to material's free texture slot.");
+ parm= RNA_def_pointer(func, "texture", "Texture", "", "Texture to add.");
+ parm= RNA_def_enum(func, "texture_coordinates", prop_texture_coordinates_items, TEXCO_UV, "", "Source of texture coordinate information."); /* optional */
+ parm= RNA_def_enum(func, "map_to", prop_texture_mapto_items, MAP_COL, "", "Controls which material property the texture affects."); /* optional */
+}
+
+#endif
+
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 78fb8ede3ee..124fd80ce5a 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -953,6 +953,16 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SHARP);
RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+ prop= RNA_def_property(srna, "loose", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_LOOSEEDGE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Loose", "Loose edge");
+
+ prop= RNA_def_property(srna, "fgon", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FGON);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Fgon", "Fgon edge");
}
static void rna_def_mface(BlenderRNA *brna)
@@ -974,6 +984,12 @@ static void rna_def_mface(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, "rna_MeshFace_verts_get", "rna_MeshFace_verts_set", NULL);
RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
+ /* leaving this fixed size array for foreach_set used in import scripts */
+ prop= RNA_def_property(srna, "verts_raw", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "v1");
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Vertices", "Fixed size vertex indices array");
+
prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "mat_nr");
RNA_def_property_ui_text(prop, "Material Index", "");
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 686d91e4fe2..3da0e1e6fd4 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -32,183 +32,15 @@
#include "RNA_define.h"
#include "RNA_types.h"
-#ifdef RNA_RUNTIME
-
-#include "DNA_mesh_types.h"
-#include "DNA_scene_types.h"
-
-#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_main.h"
-#include "BKE_mesh.h"
-
-#include "BLI_edgehash.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-static void rna_Mesh_calc_edges(Mesh *mesh)
-{
- CustomData edata;
- EdgeHashIterator *ehi;
- MFace *mf = mesh->mface;
- MEdge *med;
- EdgeHash *eh = BLI_edgehash_new();
- int i, *index, totedge, totface = mesh->totface;
-
- for (i = 0; i < totface; i++, mf++) {
- if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
- BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
- BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
-
- if (mf->v4) {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
- BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
- BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
- } else {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
- BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
- }
- }
-
- totedge = BLI_edgehash_size(eh);
-
- /* write new edges into a temporary CustomData */
- memset(&edata, 0, sizeof(edata));
- CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
-
- ehi = BLI_edgehashIterator_new(eh);
- med = CustomData_get_layer(&edata, CD_MEDGE);
- for(i = 0; !BLI_edgehashIterator_isDone(ehi);
- BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
- BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
-
- med->flag = ME_EDGEDRAW|ME_EDGERENDER;
- }
- BLI_edgehashIterator_free(ehi);
-
- /* free old CustomData and assign new one */
- CustomData_free(&mesh->edata, mesh->totedge);
- mesh->edata = edata;
- mesh->totedge = totedge;
-
- mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
-
- BLI_edgehash_free(eh, NULL);
-}
-
-static void rna_Mesh_update(Mesh *mesh, bContext *C)
-{
- if(mesh->totface && mesh->totedge == 0)
- rna_Mesh_calc_edges(mesh);
-
- mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
-
- DAG_id_flush_update(&mesh->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
-}
-
-static void rna_Mesh_add_verts(Mesh *mesh, int len)
-{
- CustomData vdata;
- MVert *mvert;
- int i, totvert;
-
- if(len == 0)
- return;
-
- totvert= mesh->totvert + len;
- CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
- CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
-
- if(!CustomData_has_layer(&vdata, CD_MVERT))
- CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
-
- CustomData_free(&mesh->vdata, mesh->totvert);
- mesh->vdata= vdata;
- mesh_update_customdata_pointers(mesh);
-
- /* scan the input list and insert the new vertices */
-
- mvert= &mesh->mvert[mesh->totvert];
- for(i=0; i<len; i++, mvert++)
- mvert->flag |= SELECT;
-
- /* set final vertex list size */
- mesh->totvert= totvert;
-}
-
-static void rna_Mesh_add_edges(Mesh *mesh, int len)
-{
- CustomData edata;
- MEdge *medge;
- int i, totedge;
+#include "BLO_sys_types.h"
- if(len == 0)
- return;
+#include "ED_mesh.h"
- totedge= mesh->totedge+len;
-
- /* update customdata */
- CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
- CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
-
- if(!CustomData_has_layer(&edata, CD_MEDGE))
- CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
-
- CustomData_free(&mesh->edata, mesh->totedge);
- mesh->edata= edata;
- mesh_update_customdata_pointers(mesh);
-
- /* set default flags */
- medge= &mesh->medge[mesh->totedge];
- for(i=0; i<len; i++, medge++)
- medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
-
- mesh->totedge= totedge;
-}
-
-static void rna_Mesh_add_faces(Mesh *mesh, int len)
-{
- CustomData fdata;
- MFace *mface;
- int i, totface;
-
- if(len == 0)
- return;
-
- totface= mesh->totface + len; /* new face count */
-
- /* update customdata */
- CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
- CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
-
- if(!CustomData_has_layer(&fdata, CD_MFACE))
- CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
-
- CustomData_free(&mesh->fdata, mesh->totface);
- mesh->fdata= fdata;
- mesh_update_customdata_pointers(mesh);
-
- /* set default flags */
- mface= &mesh->mface[mesh->totface];
- for(i=0; i<len; i++, mface++)
- mface->flag= SELECT;
-
- mesh->totface= totface;
-}
+#ifdef RNA_RUNTIME
-static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces)
+static void rna_Mesh_uv_texture_add(struct Mesh *me, struct bContext *C)
{
- if(verts)
- rna_Mesh_add_verts(mesh, verts);
- if(edges)
- rna_Mesh_add_edges(mesh, edges);
- if(faces)
- rna_Mesh_add_faces(mesh, faces);
+ ED_mesh_uv_texture_add(C, NULL, NULL, me);
}
#else
@@ -218,7 +50,13 @@ void RNA_api_mesh(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func= RNA_def_function(srna, "add_geometry", "rna_Mesh_add_geometry");
+ func= RNA_def_function(srna, "transform", "ED_mesh_transform");
+ RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix.");
+ parm= RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix.", 0.0f, 0.0f);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "add_geometry", "ED_mesh_geometry_add");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm= RNA_def_int(func, "verts", 0, 0, INT_MAX, "Number", "Number of vertices to add.", 0, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm= RNA_def_int(func, "edges", 0, 0, INT_MAX, "Number", "Number of edges to add.", 0, INT_MAX);
@@ -226,8 +64,20 @@ void RNA_api_mesh(StructRNA *srna)
parm= RNA_def_int(func, "faces", 0, 0, INT_MAX, "Number", "Number of faces to add.", 0, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
- func= RNA_def_function(srna, "update", "rna_Mesh_update");
+ func= RNA_def_function(srna, "add_uv_texture", "rna_Mesh_uv_texture_add");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh.");
+
+ func= RNA_def_function(srna, "calc_normals", "ED_mesh_calc_normals");
+ RNA_def_function_ui_description(func, "Calculate vertex normals.");
+
+ func= RNA_def_function(srna, "update", "ED_mesh_update");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
+ func= RNA_def_function(srna, "add_material", "ED_mesh_material_add");
+ RNA_def_function_ui_description(func, "Add a new material to Mesh.");
+ parm= RNA_def_pointer(func, "material", "Material", "", "Material to add.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index f3160a7bb18..1a4e4da886b 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -67,7 +67,7 @@ static void rna_MetaBall_update_data(bContext *C, PointerRNA *ptr)
#else
-void rna_def_metaelement(BlenderRNA *brna)
+static void rna_def_metaelement(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -143,7 +143,7 @@ void rna_def_metaelement(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
}
-void rna_def_metaball(BlenderRNA *brna)
+static void rna_def_metaball(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 32e34559f1f..480abff19cb 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -930,12 +930,14 @@ static void rna_def_modifier_softbody(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SoftbodyModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_SOFT);
- prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "SoftBodySettings");
RNA_def_property_pointer_funcs(prop, "rna_SoftBodyModifier_settings_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Soft Body Settings", "");
- prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "PointCache");
RNA_def_property_pointer_funcs(prop, "rna_SoftBodyModifier_point_cache_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Soft Body Point Cache", "");
@@ -1551,15 +1553,18 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "ClothModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_CLOTH);
- prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "sim_parms");
RNA_def_property_ui_text(prop, "Cloth Settings", "");
- prop= RNA_def_property(srna, "collision_settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "collision_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "coll_parms");
RNA_def_property_ui_text(prop, "Cloth Collision Settings", "");
- prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Point Cache", "");
}
@@ -1609,16 +1614,11 @@ static void rna_def_modifier_collision(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "CollisionModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_PHYSICS);
- prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "CollisionSettings");
RNA_def_property_pointer_funcs(prop, "rna_CollisionModifier_settings_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Settings", "");
-
- prop= RNA_def_property(srna, "absorption", PROP_INT, PROP_PERCENTAGE);
- RNA_def_property_int_sdna(prop, NULL, "absorption");
- RNA_def_property_ui_range(prop, 0, 100, 1, 2);
- RNA_def_property_ui_text(prop, "Absorption %", "How much of effector force gets lost during collision with this object (in percent).");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_bevel(BlenderRNA *brna)
@@ -1780,7 +1780,8 @@ static void rna_def_modifier_fluidsim(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "FluidsimModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_FLUIDSIM);
- prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "fss");
RNA_def_property_ui_text(prop, "Settings", "Settings for how this object is used in the fluid simulation.");
}
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 690a198f12c..20d1a898303 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -47,7 +47,7 @@
/* temp constant defined for these funcs only... */
#define NLASTRIP_MIN_LEN_THRESH 0.1f
-void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value)
+static void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value)
{
NlaStrip *data= (NlaStrip *)ptr->data;
@@ -280,7 +280,7 @@ EnumPropertyItem nla_mode_extend_items[] = {
{NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."},
{0, NULL, 0, NULL, NULL}};
-void rna_def_nlastrip(BlenderRNA *brna)
+static void rna_def_nlastrip(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -433,7 +433,7 @@ void rna_def_nlastrip(BlenderRNA *brna)
// - sync length
}
-void rna_def_nlatrack(BlenderRNA *brna)
+static void rna_def_nlatrack(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 3fd358a1c16..ebd032bb0b1 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
+#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
@@ -37,9 +38,82 @@
#include "BKE_node.h"
#include "BKE_image.h"
+static EnumPropertyItem node_blend_type_items[] = {
+ { 0, "MIX", 0, "Mix", ""},
+ { 1, "ADD", 0, "Add", ""},
+ { 3, "SUBTRACT", 0, "Subtract", ""},
+ { 2, "MULTIPLY", 0, "Multiply", ""},
+ { 4, "SCREEN", 0, "Screen", ""},
+ { 9, "OVERLAY", 0, "Overlay", ""},
+ { 5, "DIVIDE", 0, "Divide", ""},
+ { 6, "DIFFERENCE", 0, "Difference", ""},
+ { 7, "DARKEN", 0, "Darken", ""},
+ { 8, "LIGHTEN", 0, "Lighten", ""},
+ {10, "DODGE", 0, "Dodge", ""},
+ {11, "BURN", 0, "Burn", ""},
+ {15, "COLOR", 0, "Color", ""},
+ {14, "VALUE", 0, "Value", ""},
+ {13, "SATURATION", 0, "Saturation", ""},
+ {12, "HUE", 0, "Hue", ""},
+ {16, "SOFT_LIGHT", 0, "Soft Light", ""},
+ {17, "LINEAR_LIGHT", 0, "Linear Light",""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem node_flip_items[] = {
+ {0, "X", 0, "Flip X", ""},
+ {1, "Y", 0, "Flip Y", ""},
+ {2, "XY", 0, "Flip X & Y", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem node_math_items[] = {
+ { 0, "ADD", 0, "Add", ""},
+ { 1, "SUBTRACT", 0, "Subtract", ""},
+ { 2, "MULTIPLY", 0, "Multiply", ""},
+ { 3, "DIVIDE", 0, "Divide", ""},
+ { 4, "SINE", 0, "Sine", ""},
+ { 5, "COSINE", 0, "Cosine", ""},
+ { 6, "TANGENT", 0, "Tangent", ""},
+ { 7, "ARCSINE", 0, "Arcsine", ""},
+ { 8, "ARCCOSINE", 0, "Arccosine", ""},
+ { 9, "ARCTANGENT", 0, "Arctangent", ""},
+ {10, "POWER", 0, "Power", ""},
+ {11, "LOGARITHM", 0, "Logarithm", ""},
+ {12, "MINIMUM", 0, "Minimum", ""},
+ {13, "MAXIMUM", 0, "Maximum", ""},
+ {14, "ROUND", 0, "Round", ""},
+ {15, "LESS_THAN", 0, "Less Than", ""},
+ {16, "GREATER_THAN", 0, "Greater Than", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem node_vec_math_items[] = {
+ {0, "ADD", 0, "Add", ""},
+ {1, "SUBTRACT", 0, "Subtract", ""},
+ {2, "AVERAGE", 0, "Average", ""},
+ {3, "DOT_PRODUCT", 0, "Dot Product", ""},
+ {4, "CROSS_PRODUCT", 0, "Cross Product", ""},
+ {5, "NORMALIZE", 0, "Normalize", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem node_filter_items[] = {
+ {0, "SOFTEN", 0, "Soften", ""},
+ {1, "SHARPEN", 0, "Sharpen", ""},
+ {2, "LAPLACE", 0, "Laplace", ""},
+ {3, "SOBEL", 0, "Sobel", ""},
+ {4, "PREWITT", 0, "Prewitt", ""},
+ {5, "KIRSCH", 0, "Kirsch", ""},
+ {6, "SHADOW", 0, "Shadow", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
-StructRNA *rna_Node_refine(struct PointerRNA *ptr)
+#include "ED_node.h"
+
+static StructRNA *rna_Node_refine(struct PointerRNA *ptr)
{
bNode *node = (bNode*)ptr->data;
@@ -66,6 +140,53 @@ static char *rna_Node_path(PointerRNA *ptr)
return BLI_sprintfN("nodes[%d]", index);
}
+static void rna_Node_update(bContext *C, PointerRNA *ptr)
+{
+ bNode *node= (bNode*)ptr->data;
+
+ ED_node_changed_update(C, node);
+}
+
+static void rna_Node_update_name(bContext *C, PointerRNA *ptr)
+{
+ bNode *node= (bNode*)ptr->data;
+ const char *name;
+
+ if(node->id) {
+ BLI_strncpy(node->name, node->id->name+2, NODE_MAXSTR);
+ }
+ else {
+ switch(node->typeinfo->type) {
+ case SH_NODE_MIX_RGB:
+ case CMP_NODE_MIX_RGB:
+ case TEX_NODE_MIX_RGB:
+ if(RNA_enum_name(node_blend_type_items, node->custom1, &name))
+ BLI_strncpy(node->name, name, NODE_MAXSTR);
+ break;
+ case CMP_NODE_FILTER:
+ if(RNA_enum_name(node_filter_items, node->custom1, &name))
+ BLI_strncpy(node->name, name, NODE_MAXSTR);
+ break;
+ case CMP_NODE_FLIP:
+ if(RNA_enum_name(node_flip_items, node->custom1, &name))
+ BLI_strncpy(node->name, name, NODE_MAXSTR);
+ break;
+ case SH_NODE_MATH:
+ case CMP_NODE_MATH:
+ case TEX_NODE_MATH:
+ if(RNA_enum_name(node_math_items, node->custom1, &name))
+ BLI_strncpy(node->name, name, NODE_MAXSTR);
+ break;
+ case SH_NODE_VECT_MATH:
+ if(RNA_enum_name(node_vec_math_items, node->custom1, &name))
+ BLI_strncpy(node->name, name, NODE_MAXSTR);
+ break;
+ }
+ }
+
+ rna_Node_update(C, ptr);
+}
+
#else
#define MaxNodes 1000
@@ -183,53 +304,22 @@ static void def_math(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem items[] = {
- { 0, "ADD", 0, "Add", ""},
- { 1, "SUBTRACT", 0, "Subtract", ""},
- { 2, "MULTIPLY", 0, "Multiply", ""},
- { 3, "DIVIDE", 0, "Divide", ""},
- { 4, "SINE", 0, "Sine", ""},
- { 5, "COSINE", 0, "Cosine", ""},
- { 6, "TANGENT", 0, "Tangent", ""},
- { 7, "ARCSINE", 0, "Arcsine", ""},
- { 8, "ARCCOSINE", 0, "Arccosine", ""},
- { 9, "ARCTANGENT", 0, "Arctangent", ""},
- {10, "POWER", 0, "Power", ""},
- {11, "LOGARITHM", 0, "Logarithm", ""},
- {12, "MINIMUM", 0, "Minimum", ""},
- {13, "MAXIMUM", 0, "Maximum", ""},
- {14, "ROUND", 0, "Round", ""},
- {15, "LESS_THAN", 0, "Less Than", ""},
- {16, "GREATER_THAN", 0, "Greater Than", ""},
-
- {0, NULL, 0, NULL, NULL}
- };
-
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, items);
+ RNA_def_property_enum_items(prop, node_math_items);
RNA_def_property_ui_text(prop, "Operation", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
}
static void def_vector_math(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem items[] = {
- {0, "ADD", 0, "Add", ""},
- {1, "SUBTRACT", 0, "Subtract", ""},
- {2, "AVERAGE", 0, "Average", ""},
- {3, "DOT_PRODUCT", 0, "Dot Product", ""},
- {4, "CROSS_PRODUCT", 0, "Cross Product", ""},
- {5, "NORMALIZE", 0, "Normalize", ""},
-
- {0, NULL, 0, NULL, NULL}
- };
-
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, items);
+ RNA_def_property_enum_items(prop, node_vec_math_items);
RNA_def_property_ui_text(prop, "Operation", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
}
static void def_rgb_curve(StructRNA *srna)
@@ -240,6 +330,7 @@ static void def_rgb_curve(StructRNA *srna)
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_vector_curve(StructRNA *srna)
@@ -250,6 +341,7 @@ static void def_vector_curve(StructRNA *srna)
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_time(StructRNA *srna)
@@ -260,59 +352,44 @@ static void def_time(StructRNA *srna)
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Curve", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_ui_text(prop, "Start Frame", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "end", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
RNA_def_property_ui_text(prop, "End Frame", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_val_to_rgb(StructRNA *srna)
{
- /*PropertyRNA *prop;*/
+ PropertyRNA *prop;
- /* TODO: uncomment when ColorBand is wrapped *//*
- prop = RNA_def_property(srna, "color_band", PROP_POINTER, PROP_NONE);
+ prop = RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "storage");
- RNA_def_property_struct_type(prop, "ColorBand");
- RNA_def_property_ui_text(prop, "Color Band", "");*/
+ RNA_def_property_struct_type(prop, "ColorRamp");
+ RNA_def_property_ui_text(prop, "Color Ramp", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_mix_rgb(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem blend_type_items[] = {
- { 0, "MIX", 0, "Mix", ""},
- { 1, "ADD", 0, "Add", ""},
- { 3, "SUBTRACT", 0, "Subtract", ""},
- { 2, "MULTIPLY", 0, "Multiply", ""},
- { 4, "SCREEN", 0, "Screen", ""},
- { 9, "OVERLAY", 0, "Overlay", ""},
- { 5, "DIVIDE", 0, "Divide", ""},
- { 6, "DIFFERENCE", 0, "Difference", ""},
- { 7, "DARKEN", 0, "Darken", ""},
- { 8, "LIGHTEN", 0, "Lighten", ""},
- {10, "DODGE", 0, "Dodge", ""},
- {11, "BURN", 0, "Burn", ""},
- {15, "COLOR", 0, "Color", ""},
- {14, "VALUE", 0, "Value", ""},
- {13, "SATURATION", 0, "Saturation", ""},
- {12, "HUE", 0, "Hue", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, blend_type_items);
+ RNA_def_property_enum_items(prop, node_blend_type_items);
RNA_def_property_ui_text(prop, "Blend Type", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
prop = RNA_def_property(srna, "alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
- RNA_def_property_ui_text(prop, "Diffuse", "Include alpha of second input in this operation");
+ RNA_def_property_ui_text(prop, "Alpha", "Include alpha of second input in this operation");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_texture(StructRNA *srna)
@@ -324,10 +401,12 @@ static void def_texture(StructRNA *srna)
RNA_def_property_struct_type(prop, "Texture");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Texture", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
prop = RNA_def_property(srna, "node_output", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_ui_text(prop, "Node Output", "For node-based textures, which output node to use");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
@@ -342,18 +421,22 @@ static void def_sh_material(StructRNA *srna)
RNA_def_property_struct_type(prop, "Material");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Material", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
prop = RNA_def_property(srna, "diffuse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_DIFF);
RNA_def_property_ui_text(prop, "Diffuse", "Material Node outputs Diffuse");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "specular", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_SPEC);
RNA_def_property_ui_text(prop, "Specular", "Material Node outputs Specular");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "invert_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_NEG);
RNA_def_property_ui_text(prop, "Invert Normal", "Material Node uses inverted normal");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_sh_mapping(StructRNA *srna)
@@ -364,6 +447,7 @@ static void def_sh_mapping(StructRNA *srna)
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "TexMapping");
RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_sh_geometry(StructRNA *srna)
@@ -375,10 +459,12 @@ static void def_sh_geometry(StructRNA *srna)
prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvname");
RNA_def_property_ui_text(prop, "UV Layer", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "color_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "colname");
RNA_def_property_ui_text(prop, "Vertex Color Layer", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
@@ -387,10 +473,12 @@ static void def_sh_geometry(StructRNA *srna)
static void def_cmp_alpha_over(StructRNA *srna)
{
PropertyRNA *prop;
-
+
+ // XXX: Tooltip
prop = RNA_def_property(srna, "convert_premul", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
- RNA_def_property_ui_text(prop, "convert_premul", "TODO: don't know what this is");
+ RNA_def_property_ui_text(prop, "Convert Premul", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
RNA_def_struct_sdna_from(srna, "NodeTwoFloats", "storage");
@@ -398,6 +486,32 @@ static void def_cmp_alpha_over(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "x");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Premul", "Mix Factor");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+}
+
+static void def_cmp_hue_saturation(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeHueSat", "storage");
+
+ prop = RNA_def_property(srna, "hue", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "hue");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Hue", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "sat", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "sat");
+ RNA_def_property_range(prop, 0.0f, 2.0f);
+ RNA_def_property_ui_text(prop, "Saturation", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "val", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "val");
+ RNA_def_property_range(prop, 0.0f, 2.0f);
+ RNA_def_property_ui_text(prop, "Value", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_blur(StructRNA *srna)
@@ -422,58 +536,70 @@ static void def_cmp_blur(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "sizex");
RNA_def_property_range(prop, 0, 256);
RNA_def_property_ui_text(prop, "Size X", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "sizey", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sizey");
- RNA_def_property_range(prop, 1, 256);
+ RNA_def_property_range(prop, 0, 256);
RNA_def_property_ui_text(prop, "Size Y", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
RNA_def_property_range(prop, 1, 256);
RNA_def_property_ui_text(prop, "Samples", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "max_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxspeed");
RNA_def_property_range(prop, 1, 1024);
RNA_def_property_ui_text(prop, "Max Speed", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "min_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "minspeed");
RNA_def_property_range(prop, 1, 1024);
RNA_def_property_ui_text(prop, "Min Speed", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "relative", 1);
RNA_def_property_ui_text(prop, "Relative", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fac");
RNA_def_property_range(prop, 0.0f, 2.0f);
RNA_def_property_ui_text(prop, "Factor", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "factor_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "percentx");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Relative Size X", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "factor_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "percenty");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Relative Size Y", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "filtertype");
RNA_def_property_enum_items(prop, filter_type_items);
RNA_def_property_ui_text(prop, "Filter Type", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "bokeh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bokeh", 1);
RNA_def_property_ui_text(prop, "Bokeh", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "gamma", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gamma", 1);
RNA_def_property_ui_text(prop, "Gamma", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/*
TODO:
@@ -490,21 +616,11 @@ static void def_cmp_filter(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem type_items[] = {
- {0, "SOFTEN", 0, "Soften", ""},
- {1, "SHARPEN", 0, "Sharpen", ""},
- {2, "LAPLACE", 0, "Laplace", ""},
- {3, "SOBEL", 0, "Sobel", ""},
- {4, "PREWITT", 0, "Prewitt", ""},
- {5, "KIRSCH", 0, "Kirsch", ""},
- {6, "SHADOW", 0, "Shadow", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, type_items);
+ RNA_def_property_enum_items(prop, node_filter_items);
RNA_def_property_ui_text(prop, "Filter Type", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
}
static void def_cmp_map_value(StructRNA *srna)
@@ -515,31 +631,41 @@ static void def_cmp_map_value(StructRNA *srna)
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "loc");
+ RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Offset", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "size");
+ RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Size", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
RNA_def_property_ui_text(prop, "Use Minimum", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
RNA_def_property_ui_text(prop, "Use Maximum", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min");
+ RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Minimum", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
+ RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Maximum", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_vector_blur(StructRNA *srna)
@@ -551,22 +677,47 @@ static void def_cmp_vector_blur(StructRNA *srna)
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
RNA_def_property_ui_text(prop, "Samples", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "min_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "minspeed");
RNA_def_property_ui_text(prop, "Min Speed", "Minimum speed for a pixel to be blurred; used to separate background from foreground");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "max_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxspeed");
- RNA_def_property_ui_text(prop, "Min Speed", "Maximum speed, or zero for none");
+ RNA_def_property_ui_text(prop, "Max Speed", "Maximum speed, or zero for none");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fac");
RNA_def_property_ui_text(prop, "Blur Factor", "Scaling factor for motion vectors; actually 'shutter speed' in frames");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "curved", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "curved", 1);
RNA_def_property_ui_text(prop, "Curved", "Interpolate between frames in a bezier curve, rather than linearly");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+}
+
+static void def_cmp_levels(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem space_items[] = {
+ {1, "COMNINED_RGB", 0, "C", "Combined RGB"},
+ {2, "RED", 0, "R", "Red Channel"},
+ {3, "GREEN", 0, "G", "Green Channel"},
+ {4, "BLUE", 0, "B", "Blue Channel"},
+ {5, "LUMINANCE", 0, "L", "Luminance Channel"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, space_items);
+ RNA_def_property_ui_text(prop, "Color Space", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_image(StructRNA *srna)
@@ -586,6 +737,7 @@ static void def_cmp_image(StructRNA *srna)
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
RNA_def_struct_sdna_from(srna, "ImageUser", "storage");
@@ -595,24 +747,29 @@ static void def_cmp_image(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "frames");
RNA_def_property_range(prop, 1, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Frames", "Number of images used in animation");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sfra");
RNA_def_property_range(prop, 1, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Start Frame", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "offset", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cycl", 1);
RNA_def_property_ui_text(prop, "Cyclic", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "auto_refresh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANIM_ALWAYS);
RNA_def_property_ui_text(prop, "Auto-Refresh", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* } */
@@ -622,6 +779,7 @@ static void def_cmp_image(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "layer");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "Layer", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* } */
@@ -638,16 +796,19 @@ static void def_cmp_render_layers(StructRNA *srna)
RNA_def_property_struct_type(prop, "Scene");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Scene", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
/* TODO: layers in menu */
prop = RNA_def_property(srna, "layer", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_ui_text(prop, "Layer", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO: comments indicate this might be a hack */
prop = RNA_def_property(srna, "re_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
RNA_def_property_ui_text(prop, "Re-render", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_output_file(StructRNA *srna)
@@ -711,11 +872,13 @@ static void def_cmp_output_file(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "sfra");
RNA_def_property_range(prop, 1, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Start Frame", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "end", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "efra");
RNA_def_property_range(prop, 1, MAXFRAMEF);
RNA_def_property_ui_text(prop, "End Frame", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_dilate_erode(StructRNA *srna)
@@ -724,7 +887,9 @@ static void def_cmp_dilate_erode(StructRNA *srna)
prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
+ RNA_def_property_range(prop, -100, 100);
RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_scale(StructRNA *srna)
@@ -742,6 +907,7 @@ static void def_cmp_scale(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, space_items);
RNA_def_property_ui_text(prop, "Space", "Coordinate space to scale relative to");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_diff_matte(StructRNA *srna)
@@ -756,11 +922,13 @@ static void def_cmp_diff_matte(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed.");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed.");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_color_matte(StructRNA *srna)
@@ -775,16 +943,19 @@ static void def_cmp_color_matte(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "H", "Hue tolerance for colors to be considered a keying color");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "s", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "S", "Saturation Tolerance for the color");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "v", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t3");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "V", "Value Tolerance for the color");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_distance_matte(StructRNA *srna)
@@ -799,11 +970,13 @@ static void def_cmp_distance_matte(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed.");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed.");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_color_spill(StructRNA *srna)
@@ -811,9 +984,9 @@ static void def_cmp_color_spill(StructRNA *srna)
PropertyRNA *prop;
static EnumPropertyItem channel_items[] = {
- {1, "R", 0, "Red", ""},
- {2, "G", 0, "Green", ""},
- {3, "B", 0, "Blue", ""},
+ {1, "R", 0, "R", "Red Spill Suppression"},
+ {2, "G", 0, "G", "Green Spill Suppression"},
+ {3, "B", 0, "B", "Blue Spill Suppression"},
{0, NULL, 0, NULL, NULL}
};
@@ -821,6 +994,7 @@ static void def_cmp_color_spill(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, channel_items);
RNA_def_property_ui_text(prop, "Channel", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
@@ -828,6 +1002,7 @@ static void def_cmp_color_spill(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 0.0f, 0.5f);
RNA_def_property_ui_text(prop, "Amount", "How much the selected channel is affected by");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_chroma_matte(StructRNA *srna)
@@ -840,26 +1015,31 @@ static void def_cmp_chroma_matte(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 1.0f, 80.0f);
RNA_def_property_ui_text(prop, "Acceptance", "Tolerance for a color to be considered a keying color");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "cutoff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 30.0f);
RNA_def_property_ui_text(prop, "Cutoff", "Tolerance below which colors will be considered as exact matches");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fsize");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Lift", "Alpha lift");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fstrength");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Gain", "Alpha gain");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "shadow_adjust", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t3");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Shadow Adjust", "Adjusts the brightness of any shadows captured");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO:
if(c->t2 > c->t1)
@@ -883,10 +1063,12 @@ static void def_cmp_channel_matte(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_ui_text(prop, "Color Space", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO: channel must be 1, 2 or 3 */
prop = RNA_def_property(srna, "channel", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
RNA_def_property_ui_text(prop, "Channel", "");
RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
@@ -895,11 +1077,13 @@ static void def_cmp_channel_matte(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "low", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Low", "Values lower than this setting are 100% keyed");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO:
if(c->t2 > c->t1)
@@ -911,17 +1095,11 @@ static void def_cmp_flip(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem axis_items[] = {
- {0, "X", 0, "X", ""},
- {1, "Y", 0, "Y", ""},
- {2, "XY", 0, "X & Y", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, axis_items);
+ RNA_def_property_enum_items(prop, node_flip_items);
RNA_def_property_ui_text(prop, "Axis", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update_name");
}
static void def_cmp_splitviewer(StructRNA *srna)
@@ -938,12 +1116,13 @@ static void def_cmp_splitviewer(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom2");
RNA_def_property_enum_items(prop, axis_items);
RNA_def_property_ui_text(prop, "Axis", "");
-
- /* TODO: percentage */
- prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_PERCENTAGE);
- RNA_def_property_float_sdna(prop, NULL, "custom1");
- RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "factor", PROP_INT, PROP_FACTOR);
+ RNA_def_property_int_sdna(prop, NULL, "custom1");
+ RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Factor", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_id_mask(StructRNA *srna)
@@ -954,17 +1133,18 @@ static void def_cmp_id_mask(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "Index", "Pass index number to convert to alpha");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_map_uv(StructRNA *srna)
{
PropertyRNA *prop;
-
- /* TODO: percentage */
- prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_PERCENTAGE);
+
+ prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_FACTOR);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Alpha", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_defocus(StructRNA *srna)
@@ -988,50 +1168,60 @@ static void def_cmp_defocus(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "bktype");
RNA_def_property_enum_items(prop, bokeh_items);
RNA_def_property_ui_text(prop, "Bokeh Type", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO: angle in degrees */
prop = RNA_def_property(srna, "angle", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rotation");
RNA_def_property_range(prop, 0, 90);
RNA_def_property_ui_text(prop, "Angle", "Bokeh shape rotation offset in degrees");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "gamma_correction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gamco", 1);
RNA_def_property_ui_text(prop, "Gamma Correction", "Enable gamma correction before and after main process");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO */
prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fstop");
RNA_def_property_range(prop, 0.0f, 128.0f);
RNA_def_property_ui_text(prop, "fStop", "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "max_blur", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "maxblur");
RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_text(prop, "Max Blur", "blur limit, maximum CoC radius, 0=no limit");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bthresh");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Threshold", "CoC radius threshold, prevents background bleed on in-focus midground, 0=off");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "preview", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "preview", 1);
RNA_def_property_ui_text(prop, "Preview", "Enable sampling mode, useful for preview when using low samplecounts");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
RNA_def_property_range(prop, 16, 256);
RNA_def_property_ui_text(prop, "Samples", "Number of samples (16=grainy, higher=less noise)");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "use_zbuffer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "no_zbuf", 1);
RNA_def_property_ui_text(prop, "Use Z-Buffer", "Disable when using an image as input instead of actual zbuffer (auto enabled if node not image based, eg. time node)");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "z_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "scale");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Z-Scale", "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_luma_matte(StructRNA *srna)
@@ -1044,11 +1234,13 @@ static void def_cmp_luma_matte(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "low", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Low", "Values lower than this setting are 100% keyed");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO: keep low less than high */
@@ -1061,10 +1253,12 @@ static void def_cmp_invert(StructRNA *srna)
prop = RNA_def_property(srna, "rgb", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_CHAN_RGB);
RNA_def_property_ui_text(prop, "RGB", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_CHAN_A);
RNA_def_property_ui_text(prop, "Alpha", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_crop(StructRNA *srna)
@@ -1074,6 +1268,7 @@ static void def_cmp_crop(StructRNA *srna)
prop = RNA_def_property(srna, "crop_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Crop Image Size", "Whether to crop the size of the input image");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
RNA_def_struct_sdna_from(srna, "NodeTwoXYs", "storage");
@@ -1081,21 +1276,25 @@ static void def_cmp_crop(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "x1");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "X1", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "x2", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "x2");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "X2", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "y1", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "y1");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "Y1", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "y2", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "y2");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "Y2", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_dblur(StructRNA *srna)
@@ -1106,42 +1305,50 @@ static void def_cmp_dblur(StructRNA *srna)
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "iter");
- RNA_def_property_range(prop, 1, 128);
+ RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "Iterations", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "wrap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "wrap", 1);
RNA_def_property_ui_text(prop, "Wrap", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "center_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "center_x");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Center X", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "center_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "center_y");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Center Y", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "distance");
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Distance", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, 0.0f, 360.0f);
RNA_def_property_ui_text(prop, "Angle", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "spin", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spin");
RNA_def_property_range(prop, -360.0f, 360.0f);
RNA_def_property_ui_text(prop, "Spin", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "zoom");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Zoom", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_bilateral_blur(StructRNA *srna)
@@ -1154,16 +1361,19 @@ static void def_cmp_bilateral_blur(StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "iter");
RNA_def_property_range(prop, 1, 128);
RNA_def_property_ui_text(prop, "Iterations", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "sigma_color", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sigma_color");
RNA_def_property_range(prop, 0.01f, 3.0f);
RNA_def_property_ui_text(prop, "Color Sigma", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "sigma_space", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sigma_space");
RNA_def_property_range(prop, 0.01f, 30.0f);
RNA_def_property_ui_text(prop, "Space Sigma", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_premul_key(StructRNA *srna)
@@ -1180,6 +1390,7 @@ static void def_cmp_premul_key(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Mapping", "Conversion between premultiplied alpha and key alpha");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
@@ -1195,12 +1406,12 @@ static void def_cmp_glare(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
- /*static EnumPropertyItem quality_items[] = {
+ static EnumPropertyItem quality_items[] = {
{0, "HIGH", 0, "High", ""},
{1, "MEDIUM", 0, "Medium", ""},
{2, "LOW", 0, "Low", ""},
{0, NULL, 0, NULL, NULL}
- };*/
+ };
RNA_def_struct_sdna_from(srna, "NodeGlare", "storage");
@@ -1208,55 +1419,66 @@ static void def_cmp_glare(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Glare Type", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "quality", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "quality");
- RNA_def_property_enum_items(prop, type_items);
+ RNA_def_property_enum_items(prop, quality_items);
RNA_def_property_ui_text(prop, "Quality", "If not set to high quality, the effect will be applied to a low-res copy of the source image");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "iter");
RNA_def_property_range(prop, 2, 5);
RNA_def_property_ui_text(prop, "Iterations", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "color_modulation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colmod");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Color Modulation", "");
+ RNA_def_property_ui_text(prop, "Color Modulation", "Amount of Color Modulation, modulates colors of streaks and ghosts for a spectral dispersion effect");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "mix", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mix");
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Mix", "-1 is original image only, 0 is exact 50/50 mix, 1 is processed image only");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "threshold");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Threshold", "The glare filter will only be applied to pixels brighter than this value");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "streaks", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, 2, 16);
RNA_def_property_ui_text(prop, "Streaks", "Total number of streaks");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "angle_offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "angle_ofs");
RNA_def_property_range(prop, 0.0f, 180.0f);
RNA_def_property_ui_text(prop, "Angle Offset", "Streak angle offset in degrees");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "fade", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fade");
RNA_def_property_range(prop, 0.75f, 1.0f);
RNA_def_property_ui_text(prop, "Fade", "Streak fade-out factor");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "rotate_45", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "angle", 1);
RNA_def_property_ui_text(prop, "Rotate 45", "Simple star filter: add 45 degree rotation offset");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "size");
RNA_def_property_range(prop, 6, 9);
RNA_def_property_ui_text(prop, "Size", "Glow/glare size (not actual size; relative to initial size of bright area of pixels)");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
/* TODO */
}
@@ -1277,45 +1499,49 @@ static void def_cmp_tonemap(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Tonemap Type", "");
-
- /* TODO: if type==0 { */
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "key", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "key");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Key", "The value the average luminance is mapped to");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, 0.001f, 10.0f);
RNA_def_property_ui_text(prop, "Offset", "Normally always 1, but can be used as an extra control to alter the brightness curve");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "gamma");
RNA_def_property_range(prop, 0.001f, 3.0f);
RNA_def_property_ui_text(prop, "Gamma", "If not used, set to 1");
-
- /* TODO: } else { */
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f");
RNA_def_property_range(prop, -8.0f, 8.0f);
RNA_def_property_ui_text(prop, "Intensity", "If less than zero, darkens image; otherwise, makes it brighter");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "m");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Contrast", "Set to 0 to use estimate from input image");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "adaptation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "a");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Adaptation", "If 0, global; if 1, based on pixel intensity");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "correction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "c");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Color Correction", "If 0, same for all channels; if 1, each independent");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_cmp_lensdist(StructRNA *srna)
@@ -1327,16 +1553,17 @@ static void def_cmp_lensdist(StructRNA *srna)
prop = RNA_def_property(srna, "projector", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "proj", 1);
RNA_def_property_ui_text(prop, "Projector", "Enable/disable projector mode. Effect is applied in horizontal direction only.");
-
- /* TODO: if proj mode is off { */
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "jitter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "jit", 1);
RNA_def_property_ui_text(prop, "Jitter", "Enable/disable jittering; faster, but also noisier");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "fit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "fit", 1);
RNA_def_property_ui_text(prop, "Fit", "For positive distortion factor only: scale image such that black areas are not visible");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
@@ -1352,6 +1579,7 @@ static void def_tex_output(StructRNA *srna)
prop = RNA_def_property(srna, "output_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Output Name", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_tex_image(StructRNA *srna)
@@ -1362,6 +1590,7 @@ static void def_tex_image(StructRNA *srna)
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "ImageUser");
RNA_def_property_ui_text(prop, "Settings", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_tex_bricks(StructRNA *srna)
@@ -1372,21 +1601,25 @@ static void def_tex_bricks(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "custom3");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Offset Amount", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "offset_frequency", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_range(prop, 2, 99);
RNA_def_property_ui_text(prop, "Offset Frequency", "Offset every N rows");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "squash", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "custom4");
RNA_def_property_range(prop, 0.0f, 99.0f);
RNA_def_property_ui_text(prop, "Squash Amount", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "squash_frequency", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
RNA_def_property_range(prop, 2, 99);
RNA_def_property_ui_text(prop, "Squash Frequency", "Squash every N rows");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
}
/* -------------------------------------------------------------------------- */
@@ -1478,6 +1711,8 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Node Tree", "Node tree consisting of linked nodes used for materials, textures and compositing.");
RNA_def_struct_sdna(srna, "bNodeTree");
RNA_def_struct_ui_icon(srna, ICON_NODE);
+
+ rna_def_animdata_common(srna);
prop = RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL);
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index be4f131a6d6..69424649b3b 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -64,7 +64,7 @@ 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, 0, "HUE_SAT", HueSat, "Hue/Saturation", "" )
+DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue/Saturation", "" )
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", "" )
@@ -104,7 +104,7 @@ DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMU
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_VIEW_LEVELS, 0, "LEVELS", Levels, "Levels", "" )
+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", "" )
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 3d43dfdfc2c..3a3842adbf1 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -31,6 +31,7 @@
#include "rna_internal.h"
+#include "DNA_action_types.h"
#include "DNA_customdata_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -82,6 +83,8 @@ EnumPropertyItem object_type_items[] = {
#ifdef RNA_RUNTIME
+#include "BLI_arithb.h"
+
#include "DNA_key_types.h"
#include "BKE_armature.h"
@@ -103,6 +106,12 @@ void rna_Object_update(bContext *C, PointerRNA *ptr)
DAG_id_flush_update(ptr->id.data, OB_RECALC_OB);
}
+void rna_Object_matrix_update(bContext *C, PointerRNA *ptr)
+{
+ ED_object_apply_obmat(ptr->id.data);
+ rna_Object_update(C, ptr);
+}
+
void rna_Object_update_data(bContext *C, PointerRNA *ptr)
{
DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
@@ -440,6 +449,43 @@ static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr,
psys_set_current_num(ob, value);
}
+/* rotation - euler angles */
+static void rna_Object_rotation_euler_get(PointerRNA *ptr, float *value)
+{
+ Object *ob= ptr->data;
+
+ if(ob->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */
+ AxisAngleToEulO(&ob->quat[1], ob->quat[0], value, EULER_ORDER_DEFAULT);
+ else if(ob->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */
+ QuatToEul(ob->quat, value);
+ else
+ VECCOPY(value, ob->rot);
+}
+
+/* rotation - euler angles */
+static void rna_Object_rotation_euler_set(PointerRNA *ptr, const float *value)
+{
+ Object *ob= ptr->data;
+
+ if(ob->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */
+ EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &ob->quat[1], &ob->quat[0]);
+ else if(ob->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */
+ EulToQuat((float*)value, ob->quat);
+ else
+ VECCOPY(ob->rot, value);
+}
+
+static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value)
+{
+ Object *ob= ptr->data;
+
+ /* use API Method for conversions... */
+ BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotmode, (short)value);
+
+ /* finally, set the new rotation type */
+ ob->rotmode= value;
+}
+
static PointerRNA rna_MaterialSlot_material_get(PointerRNA *ptr)
{
Object *ob= (Object*)ptr->id.data;
@@ -695,7 +741,7 @@ static PointerRNA rna_Object_field_get(PointerRNA *ptr)
/* weak */
if(!ob->pd)
- ob->pd= object_add_collision_fields();
+ ob->pd= object_add_collision_fields(0);
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, ob->pd);
}
@@ -706,7 +752,7 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr)
/* weak */
if(!ob->pd)
- ob->pd= object_add_collision_fields();
+ ob->pd= object_add_collision_fields(0);
return rna_pointer_inherit_refine(ptr, &RNA_CollisionSettings, ob->pd);
}
@@ -1045,6 +1091,18 @@ static void rna_def_object(BlenderRNA *brna)
{OB_DUPLIFACES, "FACES", 0, "Faces", "Duplicate child objects on all faces."},
{OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing."},
{0, NULL, 0, NULL, NULL}};
+
+ // XXX: this RNA enum define is currently duplicated for objects, since there is some text here which is not applicable
+ static EnumPropertyItem prop_rotmode_items[] = {
+ {ROT_MODE_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock."},
+ {ROT_MODE_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock. (Default)"},
+ {ROT_MODE_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."},
+ {0, NULL, 0, NULL, NULL}};
int matrix_dimsize[]= {4, 4};
@@ -1161,57 +1219,105 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, NULL);
/* transform */
-
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "Location of the object.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
-
- prop= RNA_def_property(srna, "delta_location", PROP_FLOAT, PROP_TRANSLATION);
- RNA_def_property_float_sdna(prop, NULL, "dloc");
- RNA_def_property_ui_text(prop, "Delta Location", "Extra added translation to object location.");
+
+ prop= RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
+ RNA_def_property_float_sdna(prop, NULL, "quat");
+ RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
- prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
+ /* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but
+ * having a single one is better for Keyframing and other property-management situations...
+ */
+ prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "quat");
+ // TODO: we may need some validation funcs
+ RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
+
+ prop= RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "rot");
- RNA_def_property_ui_text(prop, "Rotation", "Rotation of the object.");
+ RNA_def_property_float_funcs(prop, "rna_Object_rotation_euler_get", "rna_Object_rotation_euler_set", NULL);
+ RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
-
- prop= RNA_def_property(srna, "delta_rotation", PROP_FLOAT, PROP_EULER);
- RNA_def_property_float_sdna(prop, NULL, "drot");
- RNA_def_property_ui_text(prop, "Delta Rotation", "Extra added rotation to the rotation of the object.");
+
+ prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "rotmode");
+ RNA_def_property_enum_items(prop, prop_rotmode_items); // XXX move to using a single define of this someday
+ RNA_def_property_enum_funcs(prop, NULL, "rna_Object_rotation_mode_set", NULL);
+ RNA_def_property_ui_text(prop, "Rotation Mode", "");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_ui_text(prop, "Scale", "Scaling of the object.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
-
+
+ /* delta transforms */
+ prop= RNA_def_property(srna, "delta_location", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "dloc");
+ RNA_def_property_ui_text(prop, "Delta Location", "Extra added translation to object location.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
+
+ prop= RNA_def_property(srna, "delta_rotation_euler", PROP_FLOAT, PROP_EULER);
+ RNA_def_property_float_sdna(prop, NULL, "drot");
+ RNA_def_property_ui_text(prop, "Delta Rotation (Euler)", "Extra added rotation to the rotation of the object (when using Euler rotations).");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
+
+ prop= RNA_def_property(srna, "delta_rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
+ RNA_def_property_float_sdna(prop, NULL, "dquat");
+ RNA_def_property_ui_text(prop, "Delta Rotation (Quaternion)", "Extra added rotation to the rotation of the object (when using Quaternion rotations).");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
+
+#if 0 // XXX not supported well yet...
+ prop= RNA_def_property(srna, "delta_rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "dquat");
+ RNA_def_property_ui_text(prop, "Delta Rotation (Axis Angle)", "Extra added rotation to the rotation of the object (when using Axis-Angle rotations).");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
+#endif
+
prop= RNA_def_property(srna, "delta_scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "dsize");
RNA_def_property_ui_text(prop, "Delta Scale", "Extra added scaling to the scale of the object.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
-
+
+ /* transform locks */
prop= RNA_def_property(srna, "lock_location", PROP_BOOLEAN, PROP_XYZ);
RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_LOCX);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Lock Location", "Lock editing of location in the interface.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_XYZ);
RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
+
+ // XXX this is sub-optimal - it really should be included above, but due to technical reasons we can't do this!
+ prop= RNA_def_property(srna, "lock_rotation_w", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTW);
+ RNA_def_property_ui_text(prop, "Lock Rotation (4D Angle)", "Lock editing of 'angle' component of four-component rotations in the interface.");
+ // XXX this needs a better name
+ prop= RNA_def_property(srna, "lock_rotations_4d", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROT4D);
+ RNA_def_property_ui_text(prop, "Lock Rotations (4D)", "Lock editing of four component rotations by components (instead of as Eulers).");
prop= RNA_def_property(srna, "lock_scale", PROP_BOOLEAN, PROP_XYZ);
RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_SCALEX);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Lock Scale", "Lock editing of scale in the interface.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
/* matrix */
prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "obmat");
RNA_def_property_multi_array(prop, 2, matrix_dimsize);
RNA_def_property_ui_text(prop, "Matrix", "Transformation matrix.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_matrix_update");
/* collections */
prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
@@ -1223,14 +1329,13 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the Object.");
/* game engine */
-
- prop= RNA_def_property(srna, "game", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "game", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "GameObjectSettings");
RNA_def_property_pointer_funcs(prop, "rna_Object_game_settings_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Game Settings", "Game engine related settings for the object.");
/* vertex groups */
-
prop= RNA_def_property(srna, "vertex_groups", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "defbase", NULL);
RNA_def_property_struct_type(prop, "VertexGroup");
@@ -1249,7 +1354,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Object_update_data");
/* empty */
-
prop= RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype");
RNA_def_property_enum_items(prop, empty_drawtype_items);
@@ -1263,7 +1367,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* render */
-
prop= RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "index");
RNA_def_property_ui_text(prop, "Pass Index", "Index # for the IndexOB render pass.");
@@ -1274,7 +1377,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* physics */
-
prop= RNA_def_property(srna, "field", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "pd");
RNA_def_property_struct_type(prop, "FieldSettings");
@@ -1308,7 +1410,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* restrict */
-
prop= RNA_def_property(srna, "restrict_view", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEW);
RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport.");
@@ -1325,20 +1426,9 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* anim */
-
rna_def_animdata_common(srna);
- prop= RNA_def_property(srna, "draw_keys", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_DRAWKEY);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); // update ipo flag indirect
- RNA_def_property_ui_text(prop, "Draw Keys", "Draw object as key positions.");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update");
-
- prop= RNA_def_property(srna, "draw_keys_selected", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_DRAWKEYSEL);
- RNA_def_property_ui_text(prop, "Draw Keys Selected", "Limit the drawing of object keys to selected.");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
-
+ /* duplicates */
prop= RNA_def_property(srna, "track_override_parent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_POWERTRACK);
RNA_def_property_ui_text(prop, "Track Override Parent", "Override rotation from parenting.");
@@ -1406,8 +1496,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Dupli Frames Off", "Recurring frames to exclude from the Dupliframes.");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update");
- /* time offset */
+ prop= RNA_def_property(srna, "dupli_list", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "duplilist", NULL);
+ RNA_def_property_struct_type(prop, "DupliObject");
+ RNA_def_property_ui_text(prop, "Dupli list", "Object duplis.");
+ /* time offset */
prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE|PROP_UNIT_TIME);
RNA_def_property_float_sdna(prop, NULL, "sf");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
@@ -1434,7 +1528,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
/* drawing */
-
prop= RNA_def_property(srna, "max_draw_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "dt");
RNA_def_property_enum_items(prop, drawtype_items);
@@ -1501,7 +1594,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pose", "Current pose for armatures.");
/* shape keys */
-
prop= RNA_def_property(srna, "shape_key_lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_LOCK);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_shape_key_lock_set");
@@ -1523,12 +1615,43 @@ static void rna_def_object(BlenderRNA *brna)
RNA_api_object(srna);
}
+static void rna_def_dupli_object(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "DupliObject", NULL);
+ RNA_def_struct_sdna(srna, "DupliObject");
+ RNA_def_struct_ui_text(srna, "Dupli Object", "Dupli Object data.");
+ /* RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA); */
+
+ prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ /* RNA_def_property_struct_type(prop, "Object"); */
+ RNA_def_property_pointer_sdna(prop, NULL, "ob");
+ /* RNA_def_property_pointer_funcs(prop, "rna_DupliObject_object_get", NULL, NULL); */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Object", "Object this DupliObject represents.");
+
+ prop= RNA_def_property(srna, "ob_matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "omat");
+ RNA_def_property_array(prop, 16);
+ RNA_def_property_ui_text(prop, "Object Matrix", "Object transformation matrix.");
+
+ prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "mat");
+ RNA_def_property_array(prop, 16);
+ RNA_def_property_ui_text(prop, "DupliObject Matrix", "DupliObject transformation matrix.");
+
+ /* TODO: DupliObject has more properties that can be wrapped */
+}
+
void RNA_def_object(BlenderRNA *brna)
{
rna_def_object(brna);
rna_def_object_game_settings(brna);
rna_def_vertex_group(brna);
rna_def_material_slot(brna);
+ rna_def_dupli_object(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 3541bc2b1b0..098604c1eab 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -28,76 +28,402 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <time.h>
#include "RNA_define.h"
#include "RNA_types.h"
+#include "DNA_object_types.h"
+
+#include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */
+
+#include "ED_mesh.h"
+
#ifdef RNA_RUNTIME
-#include "MEM_guardedalloc.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_customdata.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_anim.h"
+#include "BKE_depsgraph.h"
+#include "BKE_displist.h"
+#include "BKE_font.h"
+#include "BKE_mball.h"
+
+#include "BLI_arithb.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 "MEM_guardedalloc.h"
-/* copied from init_render_mesh (render code) */
-Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene)
+/* copied from Mesh_getFromObject and adapted to RNA interface */
+/* settings: 0 - preview, 1 - render */
+static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports, int apply_modifiers, int settings)
{
- CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL;
- DerivedMesh *dm;
- Mesh *me;
+ Mesh *tmpmesh;
+ Curve *tmpcu = NULL;
+ Object *tmpobj = NULL;
+ int render = settings, i;
+ int cage = !apply_modifiers;
+ Scene *sce = CTX_data_scene(C);
+
+ /* perform the mesh extraction based on type */
+ switch (ob->type) {
+ case OB_FONT:
+ case OB_CURVE:
+ case OB_SURF:
+
+ /* copies object and modifiers (but not the data) */
+ tmpobj= copy_object(ob);
+ tmpcu = (Curve *)tmpobj->data;
+ tmpcu->id.us--;
+
+ /* if getting the original caged mesh, delete object modifiers */
+ if( cage )
+ object_free_modifiers(tmpobj);
+
+ /* copies the data */
+ tmpobj->data = copy_curve( (Curve *) ob->data );
+
+#if 0
+ /* copy_curve() sets disp.first null, so currently not need */
+ {
+ Curve *cu;
+ cu = (Curve *)tmpobj->data;
+ if( cu->disp.first )
+ MEM_freeN( cu->disp.first );
+ cu->disp.first = NULL;
+ }
- /* TODO: other types */
- if(ob->type != OB_MESH)
- return NULL;
+#endif
+
+ /* get updated display list, and convert to a mesh */
+ makeDispListCurveTypes( sce, tmpobj, 0 );
+ nurbs_to_mesh( tmpobj );
+
+ /* nurbs_to_mesh changes the type to a mesh, check it worked */
+ if (tmpobj->type != OB_MESH) {
+ free_libblock_us( &(CTX_data_main(C)->object), tmpobj );
+ BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?");
+ return NULL;
+ }
+ tmpmesh = tmpobj->data;
+ free_libblock_us( &G.main->object, tmpobj );
+ break;
+
+ case OB_MBALL:
+ /* metaballs don't have modifiers, so just convert to mesh */
+ ob = find_basis_mball( sce, ob );
+ /* todo, re-generatre for render-res */
+ /* metaball_polygonize(scene, ob) */
+
+ tmpmesh = add_mesh("Mesh");
+ mball_to_mesh( &ob->disp, tmpmesh );
+ break;
+
+ case OB_MESH:
+ /* copies object and modifiers (but not the data) */
+ if (cage) {
+ /* copies the data */
+ tmpmesh = copy_mesh( ob->data );
+ /* if not getting the original caged mesh, get final derived mesh */
+ } else {
+ /* Make a dummy mesh, saves copying */
+ DerivedMesh *dm;
+ /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
+ CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
+ for example, needs CD_MASK_MDEFORMVERT */
+
+ /* Write the display mesh into the dummy mesh */
+ if (render)
+ dm = mesh_create_derived_render( sce, ob, mask );
+ else
+ dm = mesh_create_derived_view( sce, ob, mask );
+
+ tmpmesh = add_mesh( "Mesh" );
+ DM_to_mesh( dm, tmpmesh );
+ dm->release( dm );
+ }
+
+ break;
+ default:
+ BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
+ return NULL;
+ }
+
+ /* Copy materials to new mesh */
+ switch (ob->type) {
+ case OB_SURF:
+ tmpmesh->totcol = tmpcu->totcol;
+
+ /* free old material list (if it exists) and adjust user counts */
+ if( tmpcu->mat ) {
+ for( i = tmpcu->totcol; i-- > 0; ) {
+ /* are we an object material or data based? */
+ if (ob->colbits & 1<<i)
+ tmpmesh->mat[i] = ob->mat[i];
+ else
+ tmpmesh->mat[i] = tmpcu->mat[i];
+
+ if (tmpmesh->mat[i])
+ tmpmesh->mat[i]->id.us++;
+ }
+ }
+ break;
+
+#if 0
+ /* Crashes when assigning the new material, not sure why */
+ case OB_MBALL:
+ tmpmb = (MetaBall *)ob->data;
+ tmpmesh->totcol = tmpmb->totcol;
+
+ /* free old material list (if it exists) and adjust user counts */
+ if( tmpmb->mat ) {
+ for( i = tmpmb->totcol; i-- > 0; ) {
+ tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
+ if (tmpmesh->mat[i]) {
+ tmpmb->mat[i]->id.us++;
+ }
+ }
+ }
+ break;
+#endif
+
+ case OB_MESH:
+ if (!cage) {
+ Mesh *origmesh= ob->data;
+ tmpmesh->flag= origmesh->flag;
+ tmpmesh->mat = MEM_dupallocN(origmesh->mat);
+ tmpmesh->totcol = origmesh->totcol;
+ tmpmesh->smoothresh= origmesh->smoothresh;
+ if( origmesh->mat ) {
+ for( i = origmesh->totcol; i-- > 0; ) {
+ /* are we an object material or data based? */
+ if (ob->colbits & 1<<i)
+ tmpmesh->mat[i] = ob->mat[i];
+ else
+ tmpmesh->mat[i] = origmesh->mat[i];
+ if (tmpmesh->mat[i])
+ tmpmesh->mat[i]->id.us++;
+ }
+ }
+ }
+ break;
+ } /* end copy materials */
+
+ /* we don't assign it to anything */
+ tmpmesh->id.us--;
- dm= mesh_create_derived_render(scene, ob, mask);
+ /* make sure materials get updated in objects */
+ test_object_materials( ( ID * ) tmpmesh );
+
+ return tmpmesh;
+}
+
+/* When no longer needed, duplilist should be freed with Object.free_duplilist */
+static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports)
+{
+ if (!(ob->transflag & OB_DUPLI)) {
+ BKE_report(reports, RPT_ERROR, "Object does not have duplis.");
+ return;
+ }
+
+ /* free duplilist if a user forgets to */
+ if (ob->duplilist) {
+ BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed.");
+
+ free_object_duplilist(ob->duplilist);
+ ob->duplilist= NULL;
+ }
+
+ ob->duplilist= object_duplilist(CTX_data_scene(C), ob);
- if(!dm)
- return NULL;
+ /* ob->duplilist should now be freed with Object.free_duplilist */
+}
+
+static void rna_Object_free_duplilist(Object *ob, ReportList *reports)
+{
+ if (ob->duplilist) {
+ free_object_duplilist(ob->duplilist);
+ ob->duplilist= NULL;
+ }
+}
+
+static bDeformGroup *rna_Object_add_vertex_group(Object *ob, char *group_name)
+{
+ return ED_vgroup_add_name(ob, group_name);
+}
+
+static void rna_Object_add_vertex_to_group(Object *ob, int vertex_index, bDeformGroup *def, float weight, int assignmode)
+{
+ /* creates dverts if needed */
+ ED_vgroup_vert_add(ob, def, vertex_index, weight, assignmode);
+}
- me= add_mesh("tmp_render_mesh");
- me->id.us--; /* we don't assign it to anything */
- DM_to_mesh(dm, me);
- dm->release(dm);
+/* copied from old API Object.makeDisplayList (Object.c) */
+static void rna_Object_make_display_list(Object *ob, bContext *C)
+{
+ Scene *sce= CTX_data_scene(C);
+ if (ob->type == OB_FONT) {
+ Curve *cu = ob->data;
+ freedisplist(&cu->disp);
+ BKE_text_to_curve(sce, ob, CU_LEFT);
+ }
- { /* update the material */
- short i, *totcol =give_totcolp(ob);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+}
- /* free the current material list */
- if(me->mat)
- MEM_freeN((void *)me->mat);
+static Object *rna_Object_find_armature(Object *ob)
+{
+ Object *ob_arm = NULL;
- me->mat= (Material **)MEM_callocN(sizeof(void *)*(*totcol), "matarray");
+ if (ob->type != OB_MESH) return NULL;
- for(i=0; i<*totcol; i++) {
- Material *mat= give_current_material(ob, i+1);
- if(mat) {
- me->mat[i]= mat;
- mat->id.us++;
+ if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
+ ob_arm = ob->parent;
+ }
+ else {
+ ModifierData *mod = (ModifierData*)ob->modifiers.first;
+ while (mod) {
+ if (mod->type == eModifierType_Armature) {
+ ob_arm = ((ArmatureModifierData*)mod)->object;
}
+
+ mod = mod->next;
}
}
- return me;
+ return ob_arm;
}
+int rna_Object_is_visible(Object *ob, bContext *C)
+{
+ return ob->lay & CTX_data_scene(C)->lay;
+}
+
+/*
+static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int *indices, int totindex, float weight, int assignmode)
+{
+ if (ob->type != OB_MESH) {
+ BKE_report(reports, RPT_ERROR, "Object should be of MESH type.");
+ return;
+ }
+
+ Mesh *me = (Mesh*)ob->data;
+ int group_index = get_defgroup_num(ob, group);
+ if (group_index == -1) {
+ BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh.");
+ return;
+ }
+
+ if (assignmode != WEIGHT_REPLACE && assignmode != WEIGHT_ADD && assignmode != WEIGHT_SUBTRACT) {
+ BKE_report(reports, RPT_ERROR, "Bad assignment mode." );
+ return;
+ }
+
+ // makes a set of dVerts corresponding to the mVerts
+ if (!me->dvert)
+ create_dverts(&me->id);
+
+ // loop list adding verts to group
+ for (i= 0; i < totindex; i++) {
+ if(i < 0 || i >= me->totvert) {
+ BKE_report(reports, RPT_ERROR, "Bad vertex index in list.");
+ return;
+ }
+
+ add_vert_defnr(ob, group_index, i, weight, assignmode);
+ }
+}
+*/
+
#else
void RNA_api_object(StructRNA *srna)
{
FunctionRNA *func;
- PropertyRNA *prop;
-
- func= RNA_def_function(srna, "create_render_mesh", "rna_Object_create_render_mesh");
- RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied.");
- prop= RNA_def_pointer(func, "scene", "Scene", "", "");
- RNA_def_property_flag(prop, PROP_REQUIRED);
- prop= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export.");
- RNA_def_function_return(func, prop);
+ PropertyRNA *parm;
+
+ static EnumPropertyItem mesh_type_items[] = {
+ {0, "PREVIEW", 0, "Preview", "Apply modifier preview settings."},
+ {1, "RENDER", 0, "Render", "Apply modifier render settings."},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem assign_mode_items[] = {
+ {WEIGHT_REPLACE, "REPLACE", 0, "Replace", "Replace."}, /* TODO: more meaningful descriptions */
+ {WEIGHT_ADD, "ADD", 0, "Add", "Add."},
+ {WEIGHT_SUBTRACT, "SUBTRACT", 0, "Subtract", "Subtract."},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* mesh */
+ func= RNA_def_function(srna, "create_mesh", "rna_Object_create_mesh");
+ RNA_def_function_ui_description(func, "Create a Mesh datablock with modifiers applied.");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+ parm= RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export.");
+ RNA_def_function_return(func, parm);
+
+ /* duplis */
+ func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist");
+ RNA_def_function_ui_description(func, "Create a list of dupli objects for this object, needs to be freed manually with free_dupli_list.");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
+
+ func= RNA_def_function(srna, "free_dupli_list", "rna_Object_free_duplilist");
+ RNA_def_function_ui_description(func, "Free the list of dupli objects.");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+
+ /* vertex groups */
+ func= RNA_def_function(srna, "add_vertex_group", "rna_Object_add_vertex_group");
+ RNA_def_function_ui_description(func, "Add vertex group to object.");
+ parm= RNA_def_string(func, "name", "Group", 0, "", "Vertex group name."); /* optional */
+ parm= RNA_def_pointer(func, "group", "VertexGroup", "", "New vertex group.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "add_vertex_to_group", "rna_Object_add_vertex_to_group");
+ RNA_def_function_ui_description(func, "Add vertex to a vertex group.");
+ parm= RNA_def_int(func, "vertex_index", 0, 0, 0, "", "Vertex index.", 0, 0);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "group", "VertexGroup", "", "Vertex group to add vertex to.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_float(func, "weight", 0, 0.0f, 1.0f, "", "Vertex weight.", 0.0f, 1.0f);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "type", assign_mode_items, 0, "", "Vertex assign mode.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ /* Armature */
+ func= RNA_def_function(srna, "find_armature", "rna_Object_find_armature");
+ RNA_def_function_ui_description(func, "Find armature influencing this object as a parent or via a modifier.");
+ parm= RNA_def_pointer(func, "ob_arm", "Object", "", "Armature object influencing this object or NULL.");
+ RNA_def_function_return(func, parm);
+
+ /* DAG */
+ func= RNA_def_function(srna, "make_display_list", "rna_Object_make_display_list");
+ RNA_def_function_ui_description(func, "Update object's display data."); /* XXX describe better */
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
+ /* View */
+ func= RNA_def_function(srna, "is_visible", "rna_Object_is_visible");
+ RNA_def_function_ui_description(func, "Determine if object is visible in active scene.");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ parm= RNA_def_boolean(func, "is_visible", 0, "", "Object visibility.");
+ RNA_def_function_return(func, parm);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 3dfbfcccacf..652a80a24eb 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -31,11 +31,40 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "WM_api.h"
#include "WM_types.h"
+EnumPropertyItem effector_shape_items[] = {
+ {PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""},
+ {PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""},
+ {PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Surface", ""},
+ {PFIELD_SHAPE_POINTS, "POINTS", 0, "Every Point", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem empty_shape_items[] = {
+ {PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""},
+ {PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem vortex_shape_items[] = {
+ {PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""},
+ {PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""},
+ {PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Surface falloff (New)", ""},
+ {PFIELD_SHAPE_POINTS, "POINTS", 0, "Every Point (New)", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem empty_vortex_shape_items[] = {
+ {PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""},
+ {PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@@ -358,65 +387,115 @@ static void rna_SoftBodySettings_goal_vgroup_set(PointerRNA *ptr, const char *va
rna_object_vgroup_name_index_set(ptr, value, &sb->vertgroup);
}
+static int particle_field_check(PointerRNA *ptr)
+{
+ ID *id= ptr->id.data;
+
+ return (GS(id->name) == ID_PA);
+}
static void rna_FieldSettings_update(bContext *C, PointerRNA *ptr)
{
- Object *ob= (Object*)ptr->id.data;
+ if(particle_field_check(ptr)) {
+ ParticleSettings *part = (ParticleSettings*)ptr->id.data;
+
+ if(part->pd->forcefield != PFIELD_TEXTURE && part->pd->tex) {
+ part->pd->tex->id.us--;
+ part->pd->tex= 0;
+ }
+
+ if(part->pd2->forcefield != PFIELD_TEXTURE && part->pd2->tex) {
+ part->pd2->tex->id.us--;
+ part->pd2->tex= 0;
+ }
+
+ DAG_id_flush_update(&part->id, OB_RECALC|PSYS_RECALC_RESET);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
- if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex) {
- ob->pd->tex->id.us--;
- ob->pd->tex= 0;
}
+ else {
+ Object *ob = (Object*)ptr->id.data;
- DAG_id_flush_update(&ob->id, OB_RECALC_OB);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex) {
+ ob->pd->tex->id.us--;
+ ob->pd->tex= 0;
+ }
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_OB);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ }
}
-static void rna_FieldSettings_surface_update(bContext *C, PointerRNA *ptr)
+static void rna_FieldSettings_shape_update(bContext *C, PointerRNA *ptr)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= (Object*)ptr->id.data;
- PartDeflect *pd= ob->pd;
- ModifierData *md= modifiers_findByType(ob, eModifierType_Surface);
- /* add/remove modifier as needed */
- if(!md) {
- if(pd && (pd->flag & PFIELD_SURFACE))
- if(ELEM6(pd->forcefield,PFIELD_HARMONIC,PFIELD_FORCE,PFIELD_HARMONIC,PFIELD_CHARGE,PFIELD_LENNARDJ,PFIELD_BOID))
+ if(!particle_field_check(ptr)) {
+ Object *ob= (Object*)ptr->id.data;
+ PartDeflect *pd= ob->pd;
+ ModifierData *md= modifiers_findByType(ob, eModifierType_Surface);
+
+ /* add/remove modifier as needed */
+ if(!md) {
+ if(pd && (pd->shape == PFIELD_SHAPE_SURFACE) && ELEM(pd->forcefield,PFIELD_GUIDE,PFIELD_TEXTURE)==0)
if(ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE))
ED_object_modifier_add(NULL, scene, ob, eModifierType_Surface);
- }
- else {
- if(!pd || !(pd->flag & PFIELD_SURFACE))
- ED_object_modifier_remove(NULL, scene, ob, md);
- }
+ }
+ else {
+ if(!pd || pd->shape != PFIELD_SHAPE_SURFACE)
+ ED_object_modifier_remove(NULL, scene, ob, md);
+ }
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ }
}
static void rna_FieldSettings_dependency_update(bContext *C, PointerRNA *ptr)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= (Object*)ptr->id.data;
- /* do this before scene sort, that one checks for CU_PATH */
- /* XXX if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) {
- Curve *cu= ob->data;
- cu->flag |= (CU_PATH|CU_3D);
- do_curvebuts(B_CU3D); // all curves too
- }*/
+ if(particle_field_check(ptr)) {
+ DAG_id_flush_update((ID*)ptr->id.data, OB_RECALC|PSYS_RECALC_RESET);
+ }
+ else {
+ Object *ob= (Object*)ptr->id.data;
+
+ /* do this before scene sort, that one checks for CU_PATH */
+ /* XXX if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) {
+ Curve *cu= ob->data;
+ cu->flag |= (CU_PATH|CU_3D);
+ do_curvebuts(B_CU3D); // all curves too
+ }*/
- rna_FieldSettings_surface_update(C, ptr);
+ rna_FieldSettings_shape_update(C, ptr);
- DAG_scene_sort(scene);
+ DAG_scene_sort(scene);
- if(ob->type == OB_CURVE && ob->pd->forcefield == PFIELD_GUIDE)
- DAG_id_flush_update(&ob->id, OB_RECALC);
- else
- DAG_id_flush_update(&ob->id, OB_RECALC_OB);
+ if(ob->type == OB_CURVE && ob->pd->forcefield == PFIELD_GUIDE)
+ DAG_id_flush_update(&ob->id, OB_RECALC);
+ else
+ DAG_id_flush_update(&ob->id, OB_RECALC_OB);
- WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ }
+}
+
+static void rna_EffectorWeight_update(bContext *C, PointerRNA *ptr)
+{
+ DAG_id_flush_update((ID*)ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
}
+static void rna_EffectorWeight_dependency_update(bContext *C, PointerRNA *ptr)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ DAG_scene_sort(scene);
+
+ DAG_id_flush_update((ID*)ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
+}
static void rna_CollisionSettings_dependency_update(bContext *C, PointerRNA *ptr)
{
Scene *scene= CTX_data_scene(C);
@@ -448,6 +527,47 @@ static void rna_softbody_update(bContext *C, PointerRNA *ptr)
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
}
+
+static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ Object *ob= NULL;
+
+ if(C==NULL) {
+ EnumPropertyItem *item= NULL;
+ int totitem= 0;
+
+ /* needed for doc generation */
+ RNA_enum_items_add(&item, &totitem, effector_shape_items);
+ RNA_enum_items_add(&item, &totitem, empty_shape_items);
+ RNA_enum_items_add(&item, &totitem, vortex_shape_items);
+ RNA_enum_items_add(&item, &totitem, empty_shape_items);
+ RNA_enum_item_end(&item, &totitem);
+
+ *free= 1;
+
+ return item;
+ }
+
+ if(particle_field_check(ptr))
+ return empty_shape_items;
+
+ ob= (Object*)ptr->id.data;
+
+ if(ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
+ if(ob->pd->forcefield == PFIELD_VORTEX)
+ return vortex_shape_items;
+
+ return effector_shape_items;
+ }
+ else {
+ if(ob->pd->forcefield == PFIELD_VORTEX)
+ return empty_vortex_shape_items;
+
+ return empty_shape_items;
+ }
+}
+
+
#else
static void rna_def_pointcache(BlenderRNA *brna)
@@ -617,6 +737,135 @@ static void rna_def_collision(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Collision from Stack", "Pick collision object from modifier stack (softbody only)");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
*/
+
+ prop= RNA_def_property(srna, "absorption", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 2);
+ RNA_def_property_ui_text(prop, "Absorption", "How much of effector force gets lost during collision with this object (in percent).");
+ RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
+}
+
+static void rna_def_effector_weight(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "EffectorWeights", NULL);
+ RNA_def_struct_ui_text(srna, "Effector Weights", "Effector weights for physics simulation.");
+ RNA_def_struct_ui_icon(srna, ICON_PHYSICS);
+
+ /* Flags */
+ prop= RNA_def_property(srna, "do_growing_hair", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", EFF_WEIGHT_DO_HAIR);
+ RNA_def_property_ui_text(prop, "Use For Growing Hair", "Use force fields when growing hair.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ /* General */
+ prop= RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "group");
+ RNA_def_property_struct_type(prop, "Group");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this Group.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_dependency_update");
+
+ prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "global_gravity");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Gravity", "Global gravity weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ /* Effector weights */
+ prop= RNA_def_property(srna, "all", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[0]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "All", "All effector's weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "spherical", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[1]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "vortex", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[2]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Vortex", "Vortex effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "magnetic", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[3]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Magnetic", "Magnetic effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "wind", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[4]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Wind", "Wind effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "curveguide", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[5]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Curve Guide", "Curve guide effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "texture", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[6]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Texture", "Texture effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "harmonic", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[7]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Harmonic", "Harmonic effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "charge", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[8]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Charge", "Charge effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "lennardjones", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[9]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Lennard-Jones", "Lennard-Jones effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "boid", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[10]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Boid", "Boid effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[11]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Turbulence", "Turbulence effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
+
+ prop= RNA_def_property(srna, "drag", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "weight[12]");
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Drag", "Drag effector weight.");
+ RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
}
static void rna_def_field(BlenderRNA *brna)
@@ -626,18 +875,20 @@ static void rna_def_field(BlenderRNA *brna)
static EnumPropertyItem field_type_items[] = {
{0, "NONE", 0, "None", ""},
- {PFIELD_FORCE, "SPHERICAL", 0, "Spherical", ""},
+ {PFIELD_FORCE, "FORCE", 0, "Force", ""},
+ {PFIELD_WIND, "WIND", 0, "Wind", ""},
{PFIELD_VORTEX, "VORTEX", 0, "Vortex", ""},
{PFIELD_MAGNET, "MAGNET", 0, "Magnetic", ""},
- {PFIELD_WIND, "WIND", 0, "Wind", ""},
- {PFIELD_GUIDE, "GUIDE", 0, "Curve Guide", ""},
- {PFIELD_TEXTURE, "TEXTURE", 0, "Texture", ""},
{PFIELD_HARMONIC, "HARMONIC", 0, "Harmonic", ""},
{PFIELD_CHARGE, "CHARGE", 0, "Charge", ""},
{PFIELD_LENNARDJ, "LENNARDJ", 0, "Lennard-Jones", ""},
+ {PFIELD_TEXTURE, "TEXTURE", 0, "Texture", ""},
+ {PFIELD_GUIDE, "GUIDE", 0, "Curve Guide", ""},
{PFIELD_BOID, "BOID", 0, "Boid", ""},
+ {PFIELD_TURBULENCE, "TURBULENCE", 0, "Turbulence", ""},
+ {PFIELD_DRAG, "DRAG", 0, "Drag", ""},
{0, NULL, 0, NULL, NULL}};
-
+
static EnumPropertyItem falloff_items[] = {
{PFIELD_FALL_SPHERE, "SPHERE", 0, "Sphere", ""},
{PFIELD_FALL_TUBE, "TUBE", 0, "Tube", ""},
@@ -650,6 +901,12 @@ static void rna_def_field(BlenderRNA *brna)
{PFIELD_TEX_CURL, "CURL", 0, "Curl", ""},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem zdirection_items[] = {
+ {PFIELD_Z_BOTH, "BOTH", 0, "Both Z", ""},
+ {PFIELD_Z_POS, "POSITIVE", 0, "+Z", ""},
+ {PFIELD_Z_NEG, "NEGATIVE", 0, "-Z", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "FieldSettings", NULL);
RNA_def_struct_sdna(srna, "PartDeflect");
RNA_def_struct_ui_text(srna, "Field Settings", "Field settings for an object in physics simulation.");
@@ -662,6 +919,12 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_enum_items(prop, field_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of field.");
RNA_def_property_update(prop, 0, "rna_FieldSettings_dependency_update");
+
+ prop= RNA_def_property(srna, "shape", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, effector_shape_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Effector_shape_itemf");
+ RNA_def_property_ui_text(prop, "Shape", "Which direction is used to calculate the effector force.");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_shape_update");
prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "falloff");
@@ -674,6 +937,12 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_enum_items(prop, texture_items);
RNA_def_property_ui_text(prop, "Texture Mode", "How the texture effect is calculated (RGB & Curl need a RGB texture else Gradient will be used instead)");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "z_direction", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "zdir");
+ RNA_def_property_enum_items(prop, zdirection_items);
+ RNA_def_property_ui_text(prop, "Z Direction", "Effect in full or only positive/negative Z direction.");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
/* Float */
@@ -682,18 +951,51 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Strength", "Strength of force field");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
- prop= RNA_def_property(srna, "falloff_power", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "f_power");
- RNA_def_property_range(prop, 0.0f, 10.0f);
- RNA_def_property_ui_text(prop, "Falloff Power", "Falloff power (real gravitational falloff = 2)");
+
+ /* different ui range to above */
+ prop= RNA_def_property(srna, "linear_drag", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f_strength");
+ RNA_def_property_range(prop, -2.0f, 2.0f);
+ RNA_def_property_ui_text(prop, "Linear Drag", "Drag component proportional to velocity.");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop= RNA_def_property(srna, "harmonic_damping", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_damp");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Harmonic Damping", "Damping of the harmonic force");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ /* different ui range to above */
+ prop= RNA_def_property(srna, "quadratic_drag", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f_damp");
+ RNA_def_property_range(prop, -2.0f, 2.0f);
+ RNA_def_property_ui_text(prop, "Quadratic Drag", "Drag component proportional to the square of velocity.");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "flow", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f_flow");
+ RNA_def_property_range(prop, 0.0f, 10.0f);
+ RNA_def_property_ui_text(prop, "Flow", "Convert effector force into air flow velocity");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ /* different ui range to above */
+ prop= RNA_def_property(srna, "inflow", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f_flow");
+ RNA_def_property_range(prop, -10.0f, 10.0f);
+ RNA_def_property_ui_text(prop, "Inflow", "Inwards component of the vortex force");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f_size");
+ RNA_def_property_range(prop, 0.0f, 10.0f);
+ RNA_def_property_ui_text(prop, "Size", "Size of the noise");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "falloff_power", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f_power");
+ RNA_def_property_range(prop, 0.0f, 10.0f);
+ RNA_def_property_ui_text(prop, "Falloff Power", "Falloff power (real gravitational falloff = 2)");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
prop= RNA_def_property(srna, "minimum_distance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mindist");
@@ -770,26 +1072,16 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_ADD);
RNA_def_property_ui_text(prop, "Additive", "Based on distance/falloff it adds a portion of the entire path");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
- prop= RNA_def_property(srna, "planar", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_PLANAR);
- RNA_def_property_ui_text(prop, "Planar", "Create planar field");
- RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
- prop= RNA_def_property(srna, "surface", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_SURFACE);
- RNA_def_property_ui_text(prop, "Surface", "Use closest point on surface");
- RNA_def_property_update(prop, 0, "rna_FieldSettings_surface_update");
-
- prop= RNA_def_property(srna, "positive_z", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_POSZ);
- RNA_def_property_ui_text(prop, "Positive", "Effect only in direction of positive Z axis");
- RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop= RNA_def_property(srna, "use_coordinates", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_OBJECT);
RNA_def_property_ui_text(prop, "Use Coordinates", "Use object/global coordinates for texture");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "global_coordinates", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GLOBAL_CO);
+ RNA_def_property_ui_text(prop, "Use Global Coordinates", "Use effector/global coordinates for turbulence");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
prop= RNA_def_property(srna, "force_2d", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_2D);
@@ -800,6 +1092,16 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_ROOTCO);
RNA_def_property_ui_text(prop, "Root Texture Coordinates", "Texture coordinates from root particle locations");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "do_location", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_LOCATION);
+ RNA_def_property_ui_text(prop, "Location", "Effect particles' location");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+ prop= RNA_def_property(srna, "do_rotation", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_ROTATION);
+ RNA_def_property_ui_text(prop, "Rotation", "Effect particles' dynamic rotation");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
/* Pointer */
@@ -1109,12 +1411,18 @@ static void rna_def_softbody(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get", "rna_SoftBodySettings_self_collision_set");
RNA_def_property_ui_text(prop, "Self Collision", "Enable naive vertex ball self collision.");
RNA_def_property_update(prop, 0, "rna_softbody_update");
+
+ prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "EffectorWeights");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Effector Weights", "");
}
void RNA_def_object_force(BlenderRNA *brna)
{
rna_def_pointcache(brna);
rna_def_collision(brna);
+ rna_def_effector_weight(brna);
rna_def_field(brna);
rna_def_game_softbody(brna);
rna_def_softbody(brna);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index e6f0a462f03..453b5f9f91a 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -99,6 +99,7 @@ EnumPropertyItem part_hair_ren_as_items[] = {
#include "BKE_context.h"
#include "BKE_cloth.h"
#include "BKE_depsgraph.h"
+#include "BKE_effect.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -106,48 +107,43 @@ EnumPropertyItem part_hair_ren_as_items[] = {
#include "BLI_arithb.h"
/* property update functions */
-static void rna_Particle_redo(bContext *C, PointerRNA *ptr)
+static void particle_recalc(bContext *C, PointerRNA *ptr, short flag)
{
- Scene *scene = CTX_data_scene(C);
- ParticleSettings *part;
if(ptr->type==&RNA_ParticleSystem) {
ParticleSystem *psys = (ParticleSystem*)ptr->data;
- Object *ob = psys_find_object(scene, psys);
- psys->recalc = PSYS_RECALC_REDO;
+ psys->recalc = flag;
- if(ob)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
- else {
- part = ptr->id.data;
- psys_flush_particle_settings(scene, part, PSYS_RECALC_REDO);
+ DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
}
+ else
+ DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA|flag);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
}
+static void rna_Particle_redo(bContext *C, PointerRNA *ptr)
+{
+ particle_recalc(C, ptr, PSYS_RECALC_REDO);
+}
static void rna_Particle_reset(bContext *C, PointerRNA *ptr)
{
- Scene *scene = CTX_data_scene(C);
- ParticleSettings *part;
+ particle_recalc(C, ptr, PSYS_RECALC_RESET);
+}
- if(ptr->type==&RNA_ParticleSystem) {
- ParticleSystem *psys = (ParticleSystem*)ptr->data;
- Object *ob = psys_find_object(scene, psys);
-
- psys->recalc = PSYS_RECALC_RESET;
+static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
+{
+ particle_recalc(C, ptr, PSYS_RECALC_RESET|PSYS_RECALC_TYPE);
+}
- if(ob) {
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
- }
- else {
- part = ptr->id.data;
- psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
- }
+static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr)
+{
+ particle_recalc(C, ptr, PSYS_RECALC_RESET|PSYS_RECALC_PHYS);
+}
- WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
+static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
+{
+ particle_recalc(C, ptr, PSYS_RECALC_CHILD);
}
static void rna_Particle_target_reset(bContext *C, PointerRNA *ptr)
@@ -199,62 +195,9 @@ static void rna_Particle_target_redo(bContext *C, PointerRNA *ptr)
}
}
-static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
-{
- Scene *scene = CTX_data_scene(C);
- ParticleSettings *part;
-
- if(ptr->type==&RNA_ParticleSystem) {
- ParticleSystem *psys = (ParticleSystem*)ptr->data;
- Object *ob = psys_find_object(scene, psys);
-
- psys->recalc = PSYS_RECALC_RESET|PSYS_RECALC_TYPE;
-
- if(ob) {
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
- }
- else {
- part = ptr->id.data;
- psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE);
- }
-
- WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
-}
-
-static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr)
-{
- Scene *scene = CTX_data_scene(C);
- ParticleSettings *part = ptr->id.data;
- psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_PHYS);
- WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
-}
-
-static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
-{
- Scene *scene = CTX_data_scene(C);
- ParticleSettings *part;
-
- if(ptr->type==&RNA_ParticleSystem) {
- ParticleSystem *psys = (ParticleSystem*)ptr->data;
- Object *ob = psys_find_object(scene, psys);
-
- psys->recalc = PSYS_RECALC_CHILD;
-
- if(ob)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- }
- else {
- part = ptr->id.data;
-
- psys_flush_particle_settings(scene, part, PSYS_RECALC_CHILD);
- }
-
- WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL);
-}
static void rna_Particle_hair_dynamics(bContext *C, PointerRNA *ptr)
{
- Scene *scene = CTX_data_scene(C);
+ /* Scene *scene = CTX_data_scene(C); */
ParticleSystem *psys = (ParticleSystem*)ptr->data;
if(psys && !psys->clmd) {
@@ -312,9 +255,10 @@ static void rna_PartSettings_start_set(struct PointerRNA *ptr, float value)
if(value > settings->end)
value = settings->end;
- if(settings->type==PART_REACTOR && value < 1.0)
- value = 1.0;
- else if (value < MINAFRAMEF)
+ //if(settings->type==PART_REACTOR && value < 1.0)
+ // value = 1.0;
+ //else
+ if (value < MINAFRAMEF)
value = MINAFRAMEF;
settings->sta = value;
@@ -506,7 +450,7 @@ EnumPropertyItem reactor_from_items[] = {
static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, int *free)
{
- ParticleSettings *part = ptr->id.data;
+ /* ParticleSettings *part = ptr->id.data; */
if(C==NULL) {
EnumPropertyItem *item= NULL;
@@ -522,9 +466,9 @@ static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, i
return item;
}
- if(part->type==PART_REACTOR)
- return part_reactor_from_items;
- else
+ //if(part->type==PART_REACTOR)
+ // return part_reactor_from_items;
+ //else
return part_from_items;
}
@@ -576,6 +520,28 @@ static EnumPropertyItem *rna_Particle_ren_as_itemf(bContext *C, PointerRNA *ptr,
return part_ren_as_items;
}
+static PointerRNA rna_Particle_field1_get(PointerRNA *ptr)
+{
+ ParticleSettings *part= (ParticleSettings*)ptr->id.data;
+
+ /* weak */
+ if(!part->pd)
+ part->pd= object_add_collision_fields(0);
+
+ return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd);
+}
+
+static PointerRNA rna_Particle_field2_get(PointerRNA *ptr)
+{
+ ParticleSettings *part= (ParticleSettings*)ptr->id.data;
+
+ /* weak */
+ if(!part->pd2)
+ part->pd2= object_add_collision_fields(0);
+
+ return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd2);
+}
+
#else
@@ -649,7 +615,7 @@ static void rna_def_particle(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem alive_items[] = {
- {PARS_KILLED, "KILLED", 0, "Killed", ""},
+ //{PARS_KILLED, "KILLED", 0, "Killed", ""},
{PARS_DEAD, "DEAD", 0, "Dead", ""},
{PARS_UNBORN, "UNBORN", 0, "Unborn", ""},
{PARS_ALIVE, "ALIVE", 0, "Alive", ""},
@@ -767,7 +733,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
static EnumPropertyItem type_items[] = {
{PART_EMITTER, "EMITTER", 0, "Emitter", ""},
- {PART_REACTOR, "REACTOR", 0, "Reactor", ""},
+ //{PART_REACTOR, "REACTOR", 0, "Reactor", ""},
{PART_HAIR, "HAIR", 0, "Hair", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -986,10 +952,10 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Children", "Apply effectors to children.");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
- prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS);
- RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents");
- RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+ //prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE);
+ //RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS);
+ //RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents");
+ //RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
/* TODO: used somewhere? */
prop= RNA_def_property(srna, "child_render", PROP_BOOLEAN, PROP_NONE);
@@ -1713,89 +1679,25 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Billboard Object", "Billboards face this object (default is active camera)");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
- /* effectors */
- prop= RNA_def_property(srna, "effector_group", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "eff_group");
- RNA_def_property_struct_type(prop, "Group");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this Group.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_all", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[0]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "All", "All effector's weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_spherical", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[1]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_vortex", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[2]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Vortex", "Vortex effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_magnetic", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[3]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Magnetic", "Magnetic effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_wind", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[4]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Wind", "Wind effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_curveguide", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[5]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Curve Guide", "Curve guide effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_texture", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[6]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Texture", "Texture effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_harmonic", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[7]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Harmonic", "Harmonic effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_charge", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[8]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Charge", "Charge effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
- prop= RNA_def_property(srna, "eweight_lennardjones", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "effector_weight[9]");
- RNA_def_property_range(prop, -200.0f, 200.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Lennard-Jones", "Lennard-Jones effector weight.");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
+ prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "EffectorWeights");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Effector Weights", "");
/* animation here? */
rna_def_animdata_common(srna);
-// struct PartDeflect *pd;
-// struct PartDeflect *pd2;
+ prop= RNA_def_property(srna, "force_field_1", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "pd");
+ RNA_def_property_struct_type(prop, "FieldSettings");
+ RNA_def_property_pointer_funcs(prop, "rna_Particle_field1_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Force Field 1", "");
+
+ prop= RNA_def_property(srna, "force_field_2", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "pd2");
+ RNA_def_property_struct_type(prop, "FieldSettings");
+ RNA_def_property_pointer_funcs(prop, "rna_Particle_field2_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Force Field 2", "");
}
static void rna_def_particle_target(BlenderRNA *brna)
@@ -1871,10 +1773,10 @@ static void rna_def_particle_system(BlenderRNA *brna)
/* access to particle settings is redirected through functions */
/* to allow proper id-buttons functionality */
- prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
//RNA_def_property_pointer_sdna(prop, NULL, "part");
RNA_def_property_struct_type(prop, "ParticleSettings");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL);
RNA_def_property_pointer_funcs(prop, "rna_particle_settings_get", "rna_particle_settings_set", NULL);
RNA_def_property_ui_text(prop, "Settings", "Particle system settings.");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -1904,9 +1806,10 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Hair Dynamics", "Enable hair dynamics using cloth simulation.");
RNA_def_property_update(prop, 0, "rna_Particle_hair_dynamics");
- prop= RNA_def_property(srna, "cloth", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "cloth", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "clmd");
RNA_def_property_struct_type(prop, "ClothModifier");
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Cloth", "Cloth dynamics for hair");
@@ -2082,7 +1985,8 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Particle_reset");
/* pointcache */
- prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "pointcache");
RNA_def_property_struct_type(prop, "PointCache");
RNA_def_property_ui_text(prop, "Point Cache", "");
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 3a03e7a624d..03ced839ebe 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -23,6 +23,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "RNA_define.h"
#include "RNA_types.h"
@@ -39,8 +40,9 @@
#ifdef RNA_RUNTIME
-#include <string.h>
-
+#include "BIK_api.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
#include "BLI_arithb.h"
#include "DNA_userdef_types.h"
@@ -49,8 +51,11 @@
#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
+#include "ED_object.h"
#include "ED_armature.h"
+#include "MEM_guardedalloc.h"
+
static void rna_Pose_update(bContext *C, PointerRNA *ptr)
{
// XXX when to use this? ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
@@ -58,6 +63,15 @@ static void rna_Pose_update(bContext *C, PointerRNA *ptr)
DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
}
+static void rna_Pose_IK_update(bContext *C, PointerRNA *ptr)
+{
+ // XXX when to use this? ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
+ Object *ob= ptr->id.data;
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ BIK_clear_data(ob->pose);
+}
+
static char *rna_PoseChannel_path(PointerRNA *ptr)
{
return BLI_sprintfN("pose.pose_channels[\"%s\"]", ((bPoseChannel*)ptr->data)->name);
@@ -98,7 +112,7 @@ static void rna_BoneGroup_color_set_set(PointerRNA *ptr, int value)
}
}
-IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create)
+static IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create)
{
bPoseChannel *pchan= ptr->data;
@@ -110,106 +124,70 @@ IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create)
return pchan->prop;
}
+static void rna_Pose_ik_solver_set(struct PointerRNA *ptr, int value)
+{
+ bPose *pose= (bPose*)ptr->data;
+
+ if (pose->iksolver != value) {
+ // the solver has changed, must clean any temporary structures
+ BIK_clear_data(pose);
+ if (pose->ikparam) {
+ MEM_freeN(pose->ikparam);
+ pose->ikparam = NULL;
+ }
+ pose->iksolver = value;
+ init_pose_ikparam(pose);
+ }
+}
+
+static void rna_Pose_ik_solver_update(bContext *C, PointerRNA *ptr)
+{
+ Object *ob= ptr->id.data;
+ bPose *pose = ptr->data;
+ Scene *scene = CTX_data_scene(C);
+
+ pose->flag |= POSE_RECALC; // checks & sorts pose channels
+ DAG_scene_sort(scene);
+
+ update_pose_constraint_flags(pose);
+
+ object_test_constraints(ob);
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB);
+}
+
/* rotation - euler angles */
-static void rna_PoseChannel_euler_rotation_get(PointerRNA *ptr, float *value)
+static void rna_PoseChannel_rotation_euler_get(PointerRNA *ptr, float *value)
{
bPoseChannel *pchan= ptr->data;
- if(pchan->rotmode == PCHAN_ROT_AXISANGLE) /* default XYZ eulers */
+ if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */
AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], value, EULER_ORDER_DEFAULT);
- else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers */
+ else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */
QuatToEul(pchan->quat, value);
else
VECCOPY(value, pchan->eul);
}
/* rotation - euler angles */
-static void rna_PoseChannel_euler_rotation_set(PointerRNA *ptr, const float *value)
+static void rna_PoseChannel_rotation_euler_set(PointerRNA *ptr, const float *value)
{
bPoseChannel *pchan= ptr->data;
- if(pchan->rotmode == PCHAN_ROT_AXISANGLE) /* default XYZ eulers */
+ if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */
EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]);
- else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers */
+ else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */
EulToQuat((float*)value, pchan->quat);
else
VECCOPY(pchan->eul, value);
}
-/* rotation - axis angle only */
-static void rna_PoseChannel_rotation_axis_get(PointerRNA *ptr, float *value)
-{
- bPoseChannel *pchan= ptr->data;
-
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
- /* axis is stord in quat for now */
- VecCopyf(value, &pchan->quat[1]);
- }
-}
-
-/* rotation - axis angle only */
-static void rna_PoseChannel_rotation_axis_set(PointerRNA *ptr, const float *value)
-{
- bPoseChannel *pchan= ptr->data;
-
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
- /* axis is stored in quat for now */
- VecCopyf(&pchan->quat[1], (float *)value);
- }
-}
-
static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value)
{
bPoseChannel *pchan= ptr->data;
- /* check if any change - if so, need to convert data */
- // TODO: this needs to be generalised at some point to work for objects too...
- if (value > 0) { /* to euler */
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
- /* axis-angle to euler */
- AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], pchan->eul, value);
- }
- else if (pchan->rotmode == PCHAN_ROT_QUAT) {
- /* quat to euler */
- QuatToEulO(pchan->quat, pchan->eul, value);
- }
- /* else { no conversion needed } */
- }
- else if (value == PCHAN_ROT_QUAT) { /* to quat */
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
- /* axis angle to quat */
- float q[4];
-
- /* copy to temp var first, since quats and axis-angle are stored in same place */
- QuatCopy(q, pchan->quat);
- AxisAngleToQuat(q, &pchan->quat[1], pchan->quat[0]);
- }
- else if (pchan->rotmode > 0) {
- /* euler to quat */
- EulOToQuat(pchan->eul, pchan->rotmode, pchan->quat);
- }
- /* else { no conversion needed } */
- }
- else { /* to axis-angle */
- if (pchan->rotmode > 0) {
- /* euler to axis angle */
- EulOToAxisAngle(pchan->eul, pchan->rotmode, &pchan->quat[1], &pchan->quat[0]);
- }
- else if (pchan->rotmode == PCHAN_ROT_QUAT) {
- /* quat to axis angle */
- float q[4];
-
- /* copy to temp var first, since quats and axis-angle are stored in same place */
- QuatCopy(q, pchan->quat);
- QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]);
- }
-
- /* when converting to axis-angle, we need a special exception for the case when there is no axis */
- if (IS_EQ(pchan->quat[1], pchan->quat[2]) && IS_EQ(pchan->quat[2], pchan->quat[3])) {
- /* for now, rotate around y-axis then (so that it simply becomes the roll) */
- pchan->quat[2]= 1.0f;
- }
- }
+ /* use API Method for conversions... */
+ BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotmode, (short)value);
/* finally, set the new rotation type */
pchan->rotmode= value;
@@ -236,6 +214,70 @@ static int rna_PoseChannel_has_ik_get(PointerRNA *ptr)
return ED_pose_channel_in_IK_chain(ob, pchan);
}
+StructRNA *rna_IKParam_refine(PointerRNA *ptr)
+{
+ bIKParam *param = (bIKParam *)ptr->data;
+
+ switch (param->iksolver) {
+ case IKSOLVER_ITASC:
+ return &RNA_Itasc;
+ default:
+ return &RNA_IKParam;
+ }
+}
+
+PointerRNA rna_Pose_ikparam_get(struct PointerRNA *ptr)
+{
+ bPose *pose= (bPose*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_IKParam, pose->ikparam);
+}
+
+static StructRNA *rna_Pose_ikparam_typef(PointerRNA *ptr)
+{
+ bPose *pose= (bPose*)ptr->data;
+
+ switch (pose->iksolver) {
+ case IKSOLVER_ITASC:
+ return &RNA_Itasc;
+ default:
+ return &RNA_IKParam;
+ }
+}
+
+static void rna_Itasc_update(bContext *C, PointerRNA *ptr)
+{
+ Object *ob = ptr->id.data;
+ bItasc *itasc = ptr->data;
+
+ /* verify values */
+ if (itasc->precision < 0.0001f)
+ itasc->precision = 0.0001f;
+ if (itasc->minstep < 0.001f)
+ itasc->minstep = 0.001f;
+ if (itasc->maxstep < itasc->minstep)
+ itasc->maxstep = itasc->minstep;
+ if (itasc->feedback < 0.01f)
+ itasc->feedback = 0.01f;
+ if (itasc->feedback > 100.f)
+ itasc->feedback = 100.f;
+ if (itasc->maxvel < 0.01f)
+ itasc->maxvel = 0.01f;
+ if (itasc->maxvel > 100.f)
+ itasc->maxvel = 100.f;
+ BIK_update_param(ob->pose);
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+}
+
+static void rna_Itasc_update_rebuild(bContext *C, PointerRNA *ptr)
+{
+ Object *ob= ptr->id.data;
+ bPose *pose = ob->pose;
+
+ pose->flag |= POSE_RECALC; // checks & sorts pose channels
+ rna_Itasc_update(C, ptr);
+}
+
static PointerRNA rna_PoseChannel_bone_group_get(PointerRNA *ptr)
{
Object *ob= (Object*)ptr->id.data;
@@ -323,7 +365,8 @@ static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, in
*max= MAX2(0, *max);
}
-void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index)
+#if 0
+static void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index)
{
bPose *pose= (bPose*)ptr->data;
bActionGroup *grp;
@@ -334,7 +377,7 @@ void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index)
else BLI_strncpy(value, "", sizeof(grp->name)); // XXX if invalid pointer, won't this crash?
}
-int rna_pose_bgroup_name_index_length(PointerRNA *ptr, int index)
+static int rna_pose_bgroup_name_index_length(PointerRNA *ptr, int index)
{
bPose *pose= (bPose*)ptr->data;
bActionGroup *grp;
@@ -343,7 +386,7 @@ int rna_pose_bgroup_name_index_length(PointerRNA *ptr, int index)
return (grp)? strlen(grp->name): 0;
}
-void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, short *index)
+static void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, short *index)
{
bPose *pose= (bPose*)ptr->data;
bActionGroup *grp;
@@ -359,7 +402,7 @@ void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, short *i
*index= 0;
}
-void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen)
+static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen)
{
bPose *pose= (bPose*)ptr->data;
bActionGroup *grp;
@@ -373,6 +416,7 @@ void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result,
BLI_strncpy(result, "", maxlen);
}
+#endif
#else
@@ -428,24 +472,36 @@ static void rna_def_bone_group(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
// TODO: editing the colors for this should result in changes to the color type...
- prop= RNA_def_property(srna, "colors", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "colors", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "ThemeBoneColorSet");
RNA_def_property_pointer_sdna(prop, NULL, "cs"); /* NOTE: the DNA data is not really a pointer, but this code works :) */
RNA_def_property_ui_text(prop, "Colors", "Copy of the colors associated with the group's color set.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
}
+static EnumPropertyItem prop_iksolver_items[] = {
+ {IKSOLVER_LEGACY, "LEGACY", 0, "Legacy", "Original IK solver."},
+ {IKSOLVER_ITASC, "ITASC", 0, "iTaSC", "Multi constraint, stateful IK solver."},
+ {0, NULL, 0, NULL, NULL}};
+
+static EnumPropertyItem prop_solver_items[] = {
+ {ITASC_SOLVER_SDLS, "SDLS", 0, "SDLS", "Selective Damped Least Square"},
+ {ITASC_SOLVER_DLS, "DLS", 0, "DLS", "Damped Least Square with Numerical Filtering"},
+ {0, NULL, 0, NULL, NULL}};
+
static void rna_def_pose_channel(BlenderRNA *brna)
{
+ // XXX: this RNA enum define is currently duplicated for objects, since there is some text here which is not applicable
static EnumPropertyItem prop_rotmode_items[] = {
- {PCHAN_ROT_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock (default)"},
- {PCHAN_ROT_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock"},
- {PCHAN_ROT_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"},
- {PCHAN_ROT_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"},
- {PCHAN_ROT_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"},
- {PCHAN_ROT_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"},
- {PCHAN_ROT_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"},
- {PCHAN_ROT_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."},
+ {ROT_MODE_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock (default)"},
+ {ROT_MODE_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"},
+ {ROT_MODE_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."},
{0, NULL, 0, NULL, NULL}};
StructRNA *srna;
@@ -467,7 +523,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_PoseChannel_name_set");
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
-
+
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "selectflag", BONE_SELECTED);
RNA_def_property_ui_text(prop, "Selected", "");
@@ -477,16 +533,17 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "pathsf");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone Paths Calculation Start Frame", "Starting frame of range of frames to use for Bone Path calculations.");
- RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
prop= RNA_def_property(srna, "path_end_frame", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "pathef");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone Paths Calculation End Frame", "End frame of range of frames to use for Bone Path calculations.");
- RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
/* Relationships to other bones */
- prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "Bone");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone", "Bone associated with this Pose Channel.");
@@ -512,52 +569,53 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Scale", "");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update");
- prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_QUATERNION);
+ prop= RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
RNA_def_property_float_sdna(prop, NULL, "quat");
- RNA_def_property_ui_text(prop, "Rotation", "Rotation in Quaternions.");
- RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update");
-
- prop= RNA_def_property(srna, "rotation_angle", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "quat[0]");
- RNA_def_property_ui_text(prop, "Rotation Angle", "Angle of Rotation for Axis-Angle rotation representation.");
+ RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update");
- prop= RNA_def_property(srna, "rotation_axis", PROP_FLOAT, PROP_XYZ);
+ /* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but
+ * having a single one is better for Keyframing and other property-management situations...
+ */
+ prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE);
RNA_def_property_float_sdna(prop, NULL, "quat");
- RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_axis_get", "rna_PoseChannel_rotation_axis_set", NULL);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Rotation Axis", "Axis for Axis-Angle rotation representation.");
+ // TODO: we may need some validation funcs
+ RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update");
- prop= RNA_def_property(srna, "euler_rotation", PROP_FLOAT, PROP_EULER);
+ prop= RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "eul");
- RNA_def_property_float_funcs(prop, "rna_PoseChannel_euler_rotation_get", "rna_PoseChannel_euler_rotation_set", NULL);
- RNA_def_property_ui_text(prop, "Rotation (Euler)", "Rotation in Eulers.");
+ RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_euler_get", "rna_PoseChannel_rotation_euler_set", NULL);
+ RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers.");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update");
prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rotmode");
- RNA_def_property_enum_items(prop, prop_rotmode_items);
+ RNA_def_property_enum_items(prop, prop_rotmode_items); // XXX move to using a single define of this someday
RNA_def_property_enum_funcs(prop, NULL, "rna_PoseChannel_rotation_mode_set", NULL);
RNA_def_property_ui_text(prop, "Rotation Mode", "");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
/* These three matrix properties await an implementation of the PROP_MATRIX subtype, which currently doesn't exist. */
-/* prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_struct_type(prop, "chan_mat");
+ prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "chan_mat");
+ RNA_def_property_array(prop, 16);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");*/
+ RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");
/* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */
-/* prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_struct_type(prop, "pose_mat");
+ prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "pose_mat");
+ RNA_def_property_array(prop, 16);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Matrix", "Final 4x4 matrix for this channel.");
+ /*
prop= RNA_def_property(srna, "constraint_inverse_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "constinv");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position."); */
+ RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position.");
+ */
/* Head/Tail Coordinates (in Pose Space) - Automatically calculated... */
prop= RNA_def_property(srna, "pose_head", PROP_FLOAT, PROP_TRANSLATION);
@@ -573,96 +631,118 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_PoseChannel_has_ik_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Has IK", "Is part of an IK chain.");
- 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, "ik_dof_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "ikflag", BONE_IK_NO_XDOF);
RNA_def_property_ui_text(prop, "IK X DoF", "Allow movement around the X axis.");
- 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, "ik_dof_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "ikflag", BONE_IK_NO_YDOF);
RNA_def_property_ui_text(prop, "IK Y DoF", "Allow movement around the Y axis.");
- RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_IK_update");
prop= RNA_def_property(srna, "ik_dof_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "ikflag", BONE_IK_NO_ZDOF);
RNA_def_property_ui_text(prop, "IK Z DoF", "Allow movement around the Z axis.");
- 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, "ik_limit_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_XLIMIT);
RNA_def_property_ui_text(prop, "IK X Limit", "Limit movement around the X axis.");
- 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, "ik_limit_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_YLIMIT);
RNA_def_property_ui_text(prop, "IK Y Limit", "Limit movement around the Y axis.");
- 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, "ik_limit_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_ZLIMIT);
RNA_def_property_ui_text(prop, "IK Z Limit", "Limit movement around the Z axis.");
- 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, "ik_rot_control", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_ROTCTL);
+ RNA_def_property_ui_text(prop, "IK rot control", "Apply channel rotation as IK constraint");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
+
+ prop= RNA_def_property(srna, "ik_lin_control", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_LINCTL);
+ RNA_def_property_ui_text(prop, "IK rot control", "Apply channel size as IK constraint if stretching is enabled");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
prop= RNA_def_property(srna, "ik_min_x", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmin[0]");
RNA_def_property_range(prop, -180.0f, 0.0f);
RNA_def_property_ui_text(prop, "IK X Minimum", "Minimum angles for IK Limit");
- 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, "ik_max_x", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmax[0]");
RNA_def_property_range(prop, 0.0f, 180.0f);
RNA_def_property_ui_text(prop, "IK X Maximum", "Maximum angles for IK Limit");
- 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, "ik_min_y", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmin[1]");
RNA_def_property_range(prop, -180.0f, 0.0f);
RNA_def_property_ui_text(prop, "IK Y Minimum", "Minimum angles for IK Limit");
- 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, "ik_max_y", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmax[1]");
RNA_def_property_range(prop, 0.0f, 180.0f);
RNA_def_property_ui_text(prop, "IK Y Maximum", "Maximum angles for IK Limit");
- 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, "ik_min_z", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmin[2]");
RNA_def_property_range(prop, -180.0f, 0.0f);
RNA_def_property_ui_text(prop, "IK Z Minimum", "Minimum angles for IK Limit");
- 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, "ik_max_z", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmax[2]");
RNA_def_property_range(prop, 0.0f, 180.0f);
RNA_def_property_ui_text(prop, "IK Z Maximum", "Maximum angles for IK Limit");
- 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, "ik_stiffness_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness[0]");
RNA_def_property_range(prop, 0.0f, 0.99f);
RNA_def_property_ui_text(prop, "IK X Stiffness", "IK stiffness around the X axis.");
- 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, "ik_stiffness_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness[1]");
RNA_def_property_range(prop, 0.0f, 0.99f);
RNA_def_property_ui_text(prop, "IK Y Stiffness", "IK stiffness around the Y axis.");
- 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, "ik_stiffness_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness[2]");
RNA_def_property_range(prop, 0.0f, 0.99f);
RNA_def_property_ui_text(prop, "IK Z Stiffness", "IK stiffness around the Z axis.");
- 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, "ik_stretch", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ikstretch");
RNA_def_property_range(prop, 0.0f,1.0f);
RNA_def_property_ui_text(prop, "IK Stretch", "Allow scaling of the bone for IK.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
+
+ prop= RNA_def_property(srna, "ik_rot_weight", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "ikrotweight");
+ RNA_def_property_range(prop, 0.0f,1.0f);
+ RNA_def_property_ui_text(prop, "IK Rot Weight", "Weight of rotation constraint for IK.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
+
+ prop= RNA_def_property(srna, "ik_lin_weight", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "iklinweight");
+ RNA_def_property_range(prop, 0.0f,1.0f);
+ RNA_def_property_ui_text(prop, "IK Lin Weight", "Weight of scale constraint for IK.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
/* custom bone shapes */
@@ -719,6 +799,113 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
}
+static void rna_def_pose_itasc(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "Itasc", "IKParam");
+ RNA_def_struct_sdna(srna, "bItasc");
+ RNA_def_struct_ui_text(srna, "bItasc", "Parameters for the iTaSC IK solver.");
+
+ prop= RNA_def_property(srna, "precision", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "precision");
+ RNA_def_property_range(prop, 0.0f,0.1f);
+ RNA_def_property_ui_text(prop, "Precision", "Precision of convergence in case of reiteration.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "num_iter", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "numiter");
+ RNA_def_property_range(prop, 1.f,1000.f);
+ RNA_def_property_ui_text(prop, "Iterations", "Maximum number of iterations for convergence in case of reiteration.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "num_step", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "numstep");
+ RNA_def_property_range(prop, 1.f, 50.f);
+ RNA_def_property_ui_text(prop, "Num steps", "Divides the frame interval into this many steps.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "simulation", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_SIMULATION);
+ RNA_def_property_ui_text(prop, "Simulation", "Simulation mode: solver is statefull, runs in real-time context and ignores actions and non-IK constraints (i.e. solver is in full charge of the IK chain).");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update_rebuild");
+
+ prop= RNA_def_property(srna, "initial_reiteration", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_INITIAL_REITERATION);
+ RNA_def_property_ui_text(prop, "Initial Reiteration", "Allow reiteration for initial frame.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "reiteration", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_REITERATION);
+ RNA_def_property_ui_text(prop, "Reiteration", "Allow reiteration for all frames.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_AUTO_STEP);
+ RNA_def_property_ui_text(prop, "Auto step", "Automatically determine the optimal number of steps for best performance/accurary trade off.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "min_step", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "minstep");
+ RNA_def_property_range(prop, 0.0f,0.1f);
+ RNA_def_property_ui_text(prop, "Min step", "Lower bound for timestep in second in case of automatic substeps.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "max_step", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "maxstep");
+ RNA_def_property_range(prop, 0.0f,1.0f);
+ RNA_def_property_ui_text(prop, "Max step", "Higher bound for timestep in second in case of automatic substeps.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "feedback", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "feedback");
+ RNA_def_property_range(prop, 0.0f,100.0f);
+ RNA_def_property_ui_text(prop, "Feedback", "Feedback coefficient for error correction. Average response time=1/feedback. Default=20.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "max_velocity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "maxvel");
+ RNA_def_property_range(prop, 0.0f,100.0f);
+ RNA_def_property_ui_text(prop, "Max Velocity", "Maximum joint velocity in rad/s. Default=50.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "solver");
+ RNA_def_property_enum_items(prop, prop_solver_items);
+ RNA_def_property_ui_text(prop, "Solver", "Solving method selection: Automatic damping or manual damping");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update_rebuild");
+
+ prop= RNA_def_property(srna, "dampmax", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "dampmax");
+ RNA_def_property_range(prop, 0.0f,1.0f);
+ RNA_def_property_ui_text(prop, "Damp", "Maximum damping coefficient when singular value is nearly 0. Higher values=more stability, less reactivity. Default=0.5");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+
+ prop= RNA_def_property(srna, "dampeps", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "dampeps");
+ RNA_def_property_range(prop, 0.0f,1.0f);
+ RNA_def_property_ui_text(prop, "Epsilon", "Singular value under which damping is progressively applied. Higher values=more stability, less reactivity. Default=0.1");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
+}
+
+static void rna_def_pose_ikparam(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "IKParam", NULL);
+ RNA_def_struct_sdna(srna, "bIKParam");
+ RNA_def_struct_ui_text(srna, "IKParam", "Base type for IK solver parameters.");
+ RNA_def_struct_refine_func(srna, "rna_IKParam_refine");
+
+ prop= RNA_def_property(srna, "ik_solver", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "iksolver");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_items(prop, prop_iksolver_items);
+ RNA_def_property_ui_text(prop, "IK Solver", "IK solver for which these parameters are defined, 0 for Legacy, 1 for iTaSC.");
+}
+
static void rna_def_pose(BlenderRNA *brna)
{
StructRNA *srna;
@@ -753,13 +940,29 @@ static void rna_def_pose(BlenderRNA *brna)
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");
RNA_def_property_ui_text(prop, "Active Bone Group Index", "Active index in bone groups array.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
+
+ prop= RNA_def_property(srna, "ik_solver", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "iksolver");
+ RNA_def_property_enum_funcs(prop, NULL, "rna_Pose_ik_solver_set", NULL);
+ RNA_def_property_enum_items(prop, prop_iksolver_items);
+ RNA_def_property_ui_text(prop, "IK Solver", "Selection of IK solver for IK chain, current choice is 0 for Legacy, 1 for iTaSC.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_ik_solver_update");
+
+ prop= RNA_def_property(srna, "ik_param", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "IKParam");
+ RNA_def_property_pointer_funcs(prop, "rna_Pose_ikparam_get", NULL, "rna_Pose_ikparam_typef");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "IK Param", "Parameters for IK solver.");
+
+ /* RNA_api_pose(srna); */
}
void RNA_def_pose(BlenderRNA *brna)
{
rna_def_pose(brna);
rna_def_pose_channel(brna);
-
+ rna_def_pose_ikparam(brna);
+ rna_def_pose_itasc(brna);
rna_def_bone_group(brna);
}
diff --git a/source/blender/editors/preview/previewrender_intern.h b/source/blender/makesrna/intern/rna_pose_api.c
index 74a3aeee754..40bb131b3f9 100644
--- a/source/blender/editors/preview/previewrender_intern.h
+++ b/source/blender/makesrna/intern/rna_pose_api.c
@@ -1,6 +1,6 @@
/**
- * $Id:
- *
+ * $Id$
+ *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
*
@@ -26,12 +26,31 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef PREVIEWRENDER_INTERN_H
-#define PREVIEWRENDER_INTERN_H
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#include "DNA_object_types.h"
+
+/* #include "BLO_sys_types.h" */
+
+#ifdef RNA_RUNTIME
+
+/* #include "DNA_anim_types.h" */
+#include "DNA_action_types.h" /* bPose */
-/* internal exports only */
+#else
+void RNA_api_pose(StructRNA *srna)
+{
+ /* FunctionRNA *func; */
+ /* PropertyRNA *parm; */
+}
-#endif /* PREVIEWRENDER_INTERN_H */
+#endif
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 8df6398f1f4..8dd751cd26a 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -458,6 +458,62 @@ static int rna_IntProperty_default_get(PointerRNA *ptr)
rna_idproperty_check(&prop, ptr);
return ((IntPropertyRNA*)prop)->defaultvalue;
}
+/* int/float/bool */
+static int rna_NumberProperty_default_array_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
+{
+ PropertyRNA *prop= (PropertyRNA*)ptr->data;
+ rna_idproperty_check(&prop, ptr);
+
+ length[0]= prop->totarraylength;
+
+ return length[0];
+}
+static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values)
+{
+ PropertyRNA *prop= (PropertyRNA*)ptr->data;
+ IntPropertyRNA *nprop= (IntPropertyRNA*)prop;
+ rna_idproperty_check(&prop, ptr);
+
+ if(nprop->defaultarray) {
+ memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int));
+ }
+ else {
+ int i;
+ for(i=0; i < prop->totarraylength; i++)
+ values[i]= nprop->defaultvalue;
+ }
+}
+static void rna_BoolProperty_default_array_get(PointerRNA *ptr, int *values)
+{
+ PropertyRNA *prop= (PropertyRNA*)ptr->data;
+ BooleanPropertyRNA *nprop= (BooleanPropertyRNA*)prop;
+ rna_idproperty_check(&prop, ptr);
+
+ if(nprop->defaultarray) {
+ memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int));
+ }
+ else {
+ int i;
+ for(i=0; i < prop->totarraylength; i++)
+ values[i]= nprop->defaultvalue;
+ }
+}
+static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
+{
+ PropertyRNA *prop= (PropertyRNA*)ptr->data;
+ FloatPropertyRNA *nprop= (FloatPropertyRNA*)prop;
+ rna_idproperty_check(&prop, ptr);
+
+ if(nprop->defaultarray) {
+ memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(float));
+ }
+ else {
+ int i;
+ for(i=0; i < prop->totarraylength; i++)
+ values[i]= nprop->defaultvalue;
+ }
+}
+
static int rna_IntProperty_hard_min_get(PointerRNA *ptr)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
@@ -786,6 +842,7 @@ static void rna_def_property(BlenderRNA *brna)
{PROP_DIRPATH, "DIRECTORY_PATH", 0, "Directory Path", ""},
{PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned Number", ""},
{PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
+ {PROP_FACTOR, "FACTOR", 0, "Factor", ""},
{PROP_ANGLE, "ANGLE", 0, "Angle", ""},
{PROP_TIME, "TIME", 0, "Time", ""},
{PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
@@ -797,7 +854,6 @@ static void rna_def_property(BlenderRNA *brna)
{PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
{PROP_XYZ, "XYZ", 0, "XYZ", ""},
{PROP_RGB, "RGB", 0, "RGB", ""},
- {PROP_NEVER_NULL, "NEVER_NULL", 0, "Never Null", ""},
{PROP_LAYER, "LAYER", 0, "Layer", ""},
{PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""},
{0, NULL, 0, NULL, NULL}};
@@ -932,13 +988,27 @@ static void rna_def_number_property(StructRNA *srna, PropertyType type)
}
-#if 0 // XXX - Variable length arrays
prop= RNA_def_property(srna, "default_array", type, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL);
- else RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL);
- RNA_def_property_ui_text(prop, "Default", "Default value for this number");
-#endif
+ RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION); /* no fixed default length, important its not 0 though */
+ RNA_def_property_flag(prop, PROP_DYNAMIC);
+ RNA_def_property_dynamic_array_funcs(prop, "rna_NumberProperty_default_array_get_length"); /* same for all types */
+
+ switch(type) {
+ case PROP_BOOLEAN:
+ RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_array_get", NULL);
+ break;
+ case PROP_INT:
+ RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL);
+ break;
+ case PROP_FLOAT:
+ RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL);
+ break;
+ default:
+ break;
+ }
+ RNA_def_property_ui_text(prop, "Default Array", "Default value for this array");
+
prop= RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 965796c6d5b..d6cd81aced2 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -62,6 +62,7 @@ EnumPropertyItem prop_mode_items[] ={
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_node.h"
+#include "BKE_pointcache.h"
#include "BLI_threads.h"
@@ -70,7 +71,7 @@ EnumPropertyItem prop_mode_items[] ={
#include "RE_pipeline.h"
-PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter)
+static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter)
{
ListBaseIterator *internal= iter->internal;
@@ -257,6 +258,41 @@ static void rna_SceneRenderData_file_format_set(PointerRNA *ptr, int value)
#endif
}
+void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd)
+{
+ rd->subimtype &= ~(R_JPEG2K_12BIT|R_JPEG2K_16BIT | R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS);
+
+ switch(rd->jp2_depth) {
+ case 8: break;
+ case 12: rd->subimtype |= R_JPEG2K_12BIT; break;
+ case 16: rd->subimtype |= R_JPEG2K_16BIT; break;
+ }
+
+ switch(rd->jp2_preset) {
+ case 1: rd->subimtype |= R_JPEG2K_CINE_PRESET; break;
+ case 2: rd->subimtype |= R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS; break;
+ case 3: rd->subimtype |= R_JPEG2K_CINE_PRESET; break;
+ case 4: rd->subimtype |= R_JPEG2K_CINE_PRESET; break;
+ case 5: rd->subimtype |= R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS; break;
+ case 6: rd->subimtype |= R_JPEG2K_CINE_PRESET; break;
+ case 7: rd->subimtype |= R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS; break;
+ }
+}
+
+static void rna_SceneRenderData_jpeg2k_preset_set(PointerRNA *ptr, int value)
+{
+ RenderData *rd= (RenderData*)ptr->data;
+ rd->jp2_preset= value;
+ rna_SceneRenderData_jpeg2k_preset_update(rd);
+}
+
+static void rna_SceneRenderData_jpeg2k_depth_set(PointerRNA *ptr, int value)
+{
+ RenderData *rd= (RenderData*)ptr->data;
+ rd->jp2_depth= value;
+ rna_SceneRenderData_jpeg2k_preset_update(rd);
+}
+
static int rna_SceneRenderData_active_layer_index_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -371,7 +407,7 @@ static void rna_SceneRenderLayer_pass_update(bContext *C, PointerRNA *ptr)
ntreeCompositForceHidden(scene->nodetree, scene);
}
-void rna_Scene_use_nodes_set(PointerRNA *ptr, int value)
+static void rna_Scene_use_nodes_set(PointerRNA *ptr, int value)
{
Scene *scene= (Scene*)ptr->data;
@@ -380,6 +416,14 @@ void rna_Scene_use_nodes_set(PointerRNA *ptr, int value)
ED_node_composit_default(scene);
}
+static void rna_Physics_update(bContext *C, PointerRNA *ptr)
+{
+ Scene *scene= (Scene*)ptr->id.data;
+ Base *base;
+
+ for(base = scene->base.first; base; base=base->next)
+ BKE_ptcache_object_reset(scene, base->object, PTCACHE_RESET_DEPSGRAPH);
+}
#else
static void rna_def_tool_settings(BlenderRNA *brna)
@@ -523,7 +567,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, mesh_select_mode_items);
RNA_def_property_ui_text(prop, "Mesh Selection Mode", "Mesh selection and display mode.");
- prop= RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "vgroup_weight");
RNA_def_property_ui_text(prop, "Vertex Group Weight", "Weight to assign in vertex groups.");
}
@@ -561,7 +605,6 @@ static void rna_def_unit_settings(BlenderRNA *brna)
RNA_def_property_update(prop, NC_WINDOW, NULL);
}
-
void rna_def_render_layer_common(StructRNA *srna, int scene)
{
PropertyRNA *prop;
@@ -784,7 +827,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
-void rna_def_scene_game_data(BlenderRNA *brna)
+static void rna_def_scene_game_data(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -1229,19 +1272,19 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
#ifdef WITH_OPENJPEG
static EnumPropertyItem jp2_preset_items[] = {
{0, "NO_PRESET", 0, "No Preset", ""},
- {1, "R_JPEG2K_CINE_PRESET", 0, "Cinema 24fps 2048x1080", ""},
- {2, "R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS", 0, "Cinema 48fps 2048x1080", ""},
- {3, "R_JPEG2K_CINE_PRESET", 0, "Cinema 24fps 4096x2160", ""},
- {4, "R_JPEG2K_CINE_PRESET", 0, "Cine-Scope 24fps 2048x858", ""},
- {5, "R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS", 0, "Cine-Scope 48fps 2048x858", ""},
- {6, "R_JPEG2K_CINE_PRESET", 0, "Cine-Flat 24fps 1998x1080", ""},
- {7, "R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS", 0, "Cine-Flat 48fps 1998x1080", ""},
+ {1, "CINE_24FPS", 0, "Cinema 24fps 2048x1080", ""},
+ {2, "CINE_48FPS", 0, "Cinema 48fps 2048x1080", ""},
+ {3, "CINE_24FPS_4K", 0, "Cinema 24fps 4096x2160", ""},
+ {4, "CINE_SCOPE_48FPS", 0, "Cine-Scope 24fps 2048x858", ""},
+ {5, "CINE_SCOPE_48FPS", 0, "Cine-Scope 48fps 2048x858", ""},
+ {6, "CINE_FLAT_24FPS", 0, "Cine-Flat 24fps 1998x1080", ""},
+ {7, "CINE_FLAT_48FPS", 0, "Cine-Flat 48fps 1998x1080", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem jp2_depth_items[] = {
- {0, "8", 0, "8", ""},
- {R_JPEG2K_12BIT, "16", 0, "16", ""},
- {R_JPEG2K_16BIT, "32", 0, "32", ""},
+ {8, "8", 0, "8", "8 bit color channels"},
+ {12, "12", 0, "12", "12 bit color channels"},
+ {16, "16", 0, "16", "16 bit color channels"},
{0, NULL, 0, NULL, NULL}};
#endif
@@ -1302,23 +1345,25 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "planes");
RNA_def_property_enum_items(prop, color_mode_items);
RNA_def_property_ui_text(prop, "Color Mode", "Choose BW for saving greyscale images, RGB for saving red, green and blue channels, AND RGBA for saving red, green, blue + alpha channels");
-
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
prop= RNA_def_property(srna, "resolution_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "xsch");
RNA_def_property_range(prop, 4, 10000);
RNA_def_property_ui_text(prop, "Resolution X", "Number of horizontal pixels in the rendered image.");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL);
prop= RNA_def_property(srna, "resolution_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ysch");
RNA_def_property_range(prop, 4, 10000);
RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image.");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL);
prop= RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "size");
RNA_def_property_ui_range(prop, 1, 100, 10, 1);
RNA_def_property_ui_text(prop, "Resolution %", "Percentage scale for render resolution");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "parts_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "xparts");
@@ -1336,13 +1381,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "xasp");
RNA_def_property_range(prop, 1.0f, 200.0f);
RNA_def_property_ui_text(prop, "Pixel Aspect X", "Horizontal aspect ratio - for anamorphic or non-square pixel output");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL);
prop= RNA_def_property(srna, "pixel_aspect_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yasp");
RNA_def_property_range(prop, 1.0f, 200.0f);
RNA_def_property_ui_text(prop, "Pixel Aspect Y", "Vertical aspect ratio - for anamorphic or non-square pixel output");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL);
/* JPEG and AVI JPEG */
@@ -1412,19 +1457,21 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
#ifdef WITH_OPENJPEG
/* Jpeg 2000 */
- prop= RNA_def_property(srna, "jpeg_preset", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "jp2_preset");
+ prop= RNA_def_property(srna, "jpeg2k_preset", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "jp2_preset");
RNA_def_property_enum_items(prop, jp2_preset_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_jpeg2k_preset_set", NULL);
RNA_def_property_ui_text(prop, "Preset", "Use a DCI Standard preset for saving jpeg2000");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
- prop= RNA_def_property(srna, "jpeg_depth", PROP_ENUM, PROP_NONE);
+ prop= RNA_def_property(srna, "jpeg2k_depth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "jp2_depth");
RNA_def_property_enum_items(prop, jp2_depth_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_jpeg2k_depth_set", NULL);
RNA_def_property_ui_text(prop, "Depth", "Bit depth per channel");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
- prop= RNA_def_property(srna, "jpeg_ycc", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "jpeg2k_ycc", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "subimtype", R_JPEG2K_YCC);
RNA_def_property_ui_text(prop, "YCC", "Save luminance-chrominance-chrominance channels instead of RGB colors");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -1510,6 +1557,19 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "ffcodecdata.flags", FFMPEG_MULTIPLEX_AUDIO);
RNA_def_property_ui_text(prop, "Multiplex Audio", "Interleave audio with the output video");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "ffmpeg_audio_mixrate", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.audio_mixrate");
+ RNA_def_property_range(prop, 8000, 192000);
+ RNA_def_property_ui_text(prop, "Samplerate", "Audio samplerate(samples/s)");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "ffmpeg_audio_volume", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "ffcodecdata.audio_volume");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Volume", "Audio volume");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
#endif
prop= RNA_def_property(srna, "fps", PROP_INT, PROP_NONE);
@@ -1574,17 +1634,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, field_order_items);
RNA_def_property_ui_text(prop, "Field Order", "Order of video fields. Select which lines get rendered first, to create smooth motion for TV output");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "fields_still", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_FIELDSTILL);
RNA_def_property_ui_text(prop, "Fields Still", "Disable the time difference between fields.");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
- prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC);
- RNA_def_property_ui_text(prop, "Sync Audio", "Play back and sync with audio from Sequence Editor");
- RNA_def_property_update(prop, NC_SCENE, NULL);
-
prop= RNA_def_property(srna, "render_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SHADOW);
RNA_def_property_ui_text(prop, "Render Shadows", "Calculate shadows while rendering.");
@@ -1643,6 +1699,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, threads_mode_items);
RNA_def_property_ui_text(prop, "Threads Mode", "Determine the amount of render threads used");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "motion_blur", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR);
@@ -1653,6 +1710,30 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER);
RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size.");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "border_min_x", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "border.xmin");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Border Minimum X", "Sets minimum X value to for the render border.");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "border_min_y", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "border.ymin");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Border Minimum Y", "Sets minimum Y value for the render border");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "border_max_x", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "border.xmax");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Border Maximum X", "Sets maximum X value for the render border");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "border_max_y", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "border.ymax");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Border Maximum Y", "Sets maximum Y value for the render border");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "crop_to_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_CROP);
@@ -1726,6 +1807,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "displaymode");
RNA_def_property_enum_items(prop, display_mode_items);
RNA_def_property_ui_text(prop, "Display", "Select where rendered images will be displayed");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "output_path", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "pic");
@@ -1902,6 +1984,16 @@ void RNA_def_scene(BlenderRNA *brna)
PropertyRNA *prop;
FunctionRNA *func;
+ static EnumPropertyItem audio_distance_model_items[] = {
+ {0, "NONE", 0, "None", "No distance attenuation."},
+ {1, "INVERSE", 0, "Inverse", "Inverse distance model."},
+ {2, "INVERSE_CLAMPED", 0, "Inverse Clamped", "Inverse distance model with clamping."},
+ {3, "LINEAR", 0, "Linear", "Linear distance model."},
+ {4, "LINEAR_CLAMPED", 0, "Linear Clamped", "Linear distance model with clamping."},
+ {5, "EXPONENT", 0, "Exponent", "Exponent distance model."},
+ {6, "EXPONENT_CLAMPED", 0, "Exponent Clamped", "Exponent distance model with clamping."},
+ {0, NULL, 0, NULL, NULL}};
+
/* Struct definition */
srna= RNA_def_struct(brna, "Scene", "ID");
RNA_def_struct_ui_text(srna, "Scene", "Scene consisting objects and defining time and render related settings.");
@@ -1994,6 +2086,9 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Stamp Note", "User define note for the render stamping.");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ /* Animation Data (for Scene) */
+ rna_def_animdata_common(srna);
+
/* Nodes (Compositing) */
prop= RNA_def_property(srna, "nodetree", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Node Tree", "Compositing node tree.");
@@ -2032,19 +2127,35 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE|ND_KEYINGSET, NULL);
/* Tool Settings */
- prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "toolsettings");
RNA_def_property_struct_type(prop, "ToolSettings");
RNA_def_property_ui_text(prop, "Tool Settings", "");
/* Unit Settings */
- prop= RNA_def_property(srna, "unit_settings", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "unit_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "unit");
RNA_def_property_struct_type(prop, "UnitSettings");
RNA_def_property_ui_text(prop, "Unit Settings", "Unit editing settings");
+
+ /* Physics Settings */
+ prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION);
+ RNA_def_property_float_sdna(prop, NULL, "physics_settings.gravity");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, -200.0f, 200.0f);
+ RNA_def_property_ui_text(prop, "Gravity", "Constant acceleration in a given direction");
+ RNA_def_property_update(prop, 0, "rna_Physics_update");
+
+ prop= RNA_def_property(srna, "use_gravity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "physics_settings.flag", PHYS_GLOBAL_GRAVITY);
+ RNA_def_property_ui_text(prop, "Global Gravity", "Use global gravity for all dynamics.");
+ RNA_def_property_update(prop, 0, "rna_Physics_update");
/* Render Data */
- prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "r");
RNA_def_property_struct_type(prop, "SceneRenderData");
RNA_def_property_ui_text(prop, "Render Data", "");
@@ -2055,8 +2166,43 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "TimelineMarker");
RNA_def_property_ui_text(prop, "Timeline Markers", "Markers used in all timelines for the current scene.");
+ /* Audio Settings */
+ prop= RNA_def_property(srna, "mute_audio", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_MUTE);
+ RNA_def_property_ui_text(prop, "Audio Muted", "Play back of audio from Sequence Editor will be muted.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC);
+ RNA_def_property_ui_text(prop, "Audio Sync", "Play back and sync with audio from Sequence Editor.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "scrub_audio", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SCRUB);
+ RNA_def_property_ui_text(prop, "Audio Scrubbing", "Play audio from Sequence Editor while scrubbing.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "speed_of_sound", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "audio.speed_of_sound");
+ RNA_def_property_range(prop, 0.01f, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Speed of Sound", "Speed of sound for doppler effect calculation.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "doppler_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "audio.doppler_factor");
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Doppler Factor", "Pitch factor for doppler effect calculation.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "distance_model", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "audio.distance_model");
+ RNA_def_property_enum_items(prop, audio_distance_model_items);
+ RNA_def_property_ui_text(prop, "Distance Model", "Distance model for distance attenuation calculation.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
/* Game Settings */
- prop= RNA_def_property(srna, "game_data", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "game_data", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "gm");
RNA_def_property_struct_type(prop, "SceneGameData");
RNA_def_property_ui_text(prop, "Game Data", "");
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 26047ab5dc3..40f2db6d4a4 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -1,5 +1,5 @@
/**
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -21,7 +21,7 @@
* All rights reserved.
*
*
- * Contributor(s): Joshua Leung
+ * Contributor(s): Joshua Leung, Arystanbek Dyussenov
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -40,9 +40,49 @@
#ifdef RNA_RUNTIME
#include "BKE_animsys.h"
+#include "BKE_scene.h"
+#include "BKE_depsgraph.h"
-// Scene API stuff from kazanbas branch here...
+#include "ED_object.h"
+#include "WM_api.h"
+
+static void rna_Scene_add_object(Scene *sce, ReportList *reports, Object *ob)
+{
+ Base *base= object_in_scene(ob, sce);
+ if (base) {
+ BKE_report(reports, RPT_ERROR, "Object is already in this scene.");
+ return;
+ }
+ base= scene_add_base(sce, ob);
+ ob->id.us++;
+
+ /* this is similar to what object_add_type and add_object do */
+ ob->lay= base->lay= sce->lay;
+ ob->recalc |= OB_RECALC;
+
+ DAG_scene_sort(sce);
+}
+
+static void rna_Scene_remove_object(Scene *sce, ReportList *reports, Object *ob)
+{
+ Base *base= object_in_scene(ob, sce);
+ if (!base) {
+ BKE_report(reports, RPT_ERROR, "Object is not in this scene.");
+ return;
+ }
+ /* as long as ED_base_object_free_and_unlink calls free_libblock_us, we don't have to decrement ob->id.us */
+ ED_base_object_free_and_unlink(sce, base);
+}
+
+static void rna_Scene_set_frame(Scene *sce, bContext *C, int frame)
+{
+ sce->r.cfra= frame;
+ CLAMP(sce->r.cfra, MINAFRAME, MAXFRAME);
+ scene_update_for_newframe(sce, (1<<20) - 1);
+
+ WM_event_add_notifier(C, NC_SCENE|ND_FRAME, sce);
+}
static KeyingSet *rna_Scene_add_keying_set(Scene *sce, ReportList *reports,
char name[], int absolute, int insertkey_needed, int insertkey_visual)
@@ -77,21 +117,37 @@ void RNA_api_scene(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
-
- // Scene API stuff from kazanbas branch here...
-
+
+ func= RNA_def_function(srna, "add_object", "rna_Scene_add_object");
+ RNA_def_function_ui_description(func, "Add object to scene.");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_pointer(func, "object", "Object", "", "Object to add to scene.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "remove_object", "rna_Scene_remove_object");
+ RNA_def_function_ui_description(func, "Remove object from scene.");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove from scene.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "set_frame", "rna_Scene_set_frame");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Set scene frame updating all objects immediately.");
+ parm= RNA_def_int(func, "frame", 0, MINAFRAME, MAXFRAME, "", "Frame number to set.", MINAFRAME, MAXFRAME);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
/* Add Keying Set */
func= RNA_def_function(srna, "add_keying_set", "rna_Scene_add_keying_set");
RNA_def_function_ui_description(func, "Add a new Keying Set to Scene.");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
- /* returns the new KeyingSet */
+ /* returns the new KeyingSet */
parm= RNA_def_pointer(func, "keyingset", "KeyingSet", "", "Newly created Keying Set.");
- RNA_def_function_return(func, parm);
- /* name */
+ RNA_def_function_return(func, parm);
+ /* name */
RNA_def_string(func, "name", "KeyingSet", 64, "Name", "Name of Keying Set");
- /* flags */
+ /* flags */
RNA_def_boolean(func, "absolute", 1, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)");
- /* keying flags */
+ /* keying flags */
RNA_def_boolean(func, "insertkey_needed", 0, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves.");
RNA_def_boolean(func, "insertkey_visual", 0, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'.");
}
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 7a243327bd1..2a72845dd42 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -135,10 +135,10 @@ static void rna_def_screen(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Screen", "Screen datablock, defining the layout of areas in a window.");
RNA_def_struct_ui_icon(srna, ICON_SPLITSCREEN);
- prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NEVER_NULL);
- RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen.");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL);
RNA_def_property_pointer_funcs(prop, NULL, "rna_Screen_scene_set", NULL);
+ RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen.");
RNA_def_property_update(prop, 0, "rna_Screen_scene_update");
prop= RNA_def_property(srna, "areas", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index 53bd230870f..1003af6d4d1 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -48,6 +48,8 @@ static StructRNA* rna_Sensor_refine(struct PointerRNA *ptr)
return &RNA_KeyboardSensor;
case SENS_PROPERTY:
return &RNA_PropertySensor;
+ case SENS_ARMATURE:
+ return &RNA_ArmatureSensor;
case SENS_MOUSE:
return &RNA_MouseSensor;
case SENS_COLLISION:
@@ -73,7 +75,7 @@ static StructRNA* rna_Sensor_refine(struct PointerRNA *ptr)
#else
-void rna_def_sensor(BlenderRNA *brna)
+static void rna_def_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -92,6 +94,7 @@ void rna_def_sensor(BlenderRNA *brna)
{SENS_JOYSTICK, "JOYSTICK", 0, "joystick", ""},
{SENS_ACTUATOR, "ACTUATOR", 0, "Actuator", ""},
{SENS_DELAY, "DELAY", 0, "Delay", ""},
+ {SENS_ARMATURE, "ARMATURE", 0, "Armature", ""},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Sensor", NULL);
@@ -129,14 +132,14 @@ void rna_def_sensor(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 10000);
}
-void rna_def_always_sensor(BlenderRNA *brna)
+static void rna_def_always_sensor(BlenderRNA *brna)
{
StructRNA *srna;
srna= RNA_def_struct(brna, "AlwaysSensor", "Sensor");
RNA_def_struct_ui_text(srna, "Always Sensor", "Sensor to generate continuous pulses.");
}
-void rna_def_near_sensor(BlenderRNA *brna)
+static void rna_def_near_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -160,7 +163,7 @@ void rna_def_near_sensor(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 10000.0f);
}
-void rna_def_mouse_sensor(BlenderRNA *brna)
+static void rna_def_mouse_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -186,7 +189,7 @@ void rna_def_mouse_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mouse Event", "Specify the type of event this mouse sensor should trigger on.");
}
-void rna_def_touch_sensor(BlenderRNA *brna)
+static void rna_def_touch_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -201,7 +204,7 @@ void rna_def_touch_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Material", "Only look for floors with this material.");
}
-void rna_def_keyboard_sensor(BlenderRNA *brna)
+static void rna_def_keyboard_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -240,7 +243,7 @@ void rna_def_keyboard_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "All Keys", "Trigger this sensor on any keystroke.");
}
-void rna_def_property_sensor(BlenderRNA *brna)
+static void rna_def_property_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -278,7 +281,41 @@ void rna_def_property_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Maximum Value", "Specify maximum value in Interval type.");
}
-void rna_def_actuator_sensor(BlenderRNA *brna)
+static void rna_def_armature_sensor(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ static EnumPropertyItem prop_type_items[] ={
+ {SENS_ARM_STATE_CHANGED, "STATECHG", 0, "State Changed", ""},
+ {SENS_ARM_LIN_ERROR_BELOW, "LINERRORBELOW", 0, "Lin error below", ""},
+ {SENS_ARM_LIN_ERROR_ABOVE, "LINERRORABOVE", 0, "Lin error above", ""},
+ {SENS_ARM_ROT_ERROR_BELOW, "ROTERRORBELOW", 0, "Rot error below", ""},
+ {SENS_ARM_ROT_ERROR_ABOVE, "ROTERRORBELOW", 0, "Rot error above", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "ArmatureSensor", "Sensor");
+ RNA_def_struct_ui_text(srna, "Armature Sensor", "Sensor to detect values and changes in values of IK solver.");
+ RNA_def_struct_sdna_from(srna, "bArmatureSensor", "data");
+
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, prop_type_items);
+ RNA_def_property_ui_text(prop, "Test Type", "Type of value and test.");
+
+ prop= RNA_def_property(srna, "channel_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "posechannel");
+ RNA_def_property_ui_text(prop, "Bone name", "Identify the bone to check value from");
+
+ prop= RNA_def_property(srna, "constraint_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "constraint");
+ RNA_def_property_ui_text(prop, "Constraint name", "Identify the bone constraint to check value from.");
+
+ prop= RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "value");
+ RNA_def_property_ui_text(prop, "Compare Value", "Specify value to be used in comparison.");
+}
+
+static void rna_def_actuator_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -292,7 +329,7 @@ void rna_def_actuator_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Actuator", "Actuator name, actuator active state modifications will be detected.");
}
-void rna_def_delay_sensor(BlenderRNA *brna)
+static void rna_def_delay_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -314,7 +351,7 @@ void rna_def_delay_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Repeat", "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics.");
}
-void rna_def_collision_sensor(BlenderRNA *brna)
+static void rna_def_collision_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -341,7 +378,7 @@ void rna_def_collision_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Collision Type", "Toggle collision on material or property.");
}
-void rna_def_radar_sensor(BlenderRNA *brna)
+static void rna_def_radar_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -376,7 +413,7 @@ void rna_def_radar_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Distance", "Depth of the radar cone.");
}
-void rna_def_random_sensor(BlenderRNA *brna)
+static void rna_def_random_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -390,7 +427,7 @@ void rna_def_random_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Seed", "Initial seed of the generator. (Choose 0 for not random).");
}
-void rna_def_ray_sensor(BlenderRNA *brna)
+static void rna_def_ray_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -438,7 +475,7 @@ void rna_def_ray_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Axis", "Specify along which axis the ray is cast.");
}
-void rna_def_message_sensor(BlenderRNA *brna)
+static void rna_def_message_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -451,7 +488,7 @@ void rna_def_message_sensor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Subject", "Optional subject filter: only accept messages with this subject, or empty for all.");
}
-void rna_def_joystick_sensor(BlenderRNA *brna)
+static void rna_def_joystick_sensor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -531,6 +568,7 @@ void RNA_def_sensor(BlenderRNA *brna)
rna_def_touch_sensor(brna);
rna_def_keyboard_sensor(brna);
rna_def_property_sensor(brna);
+ rna_def_armature_sensor(brna);
rna_def_actuator_sensor(brna);
rna_def_delay_sensor(brna);
rna_def_collision_sensor(brna);
diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c
index 9f016f73694..9404fb775c3 100644
--- a/source/blender/makesrna/intern/rna_sequence.c
+++ b/source/blender/makesrna/intern/rna_sequence.c
@@ -228,7 +228,15 @@ static char *rna_Sequence_path(PointerRNA *ptr)
/* sequencer data comes from scene...
* TODO: would be nice to make SequenceEditor data a datablock of its own (for shorter paths)
*/
- return BLI_sprintfN("sequence_editor.sequences[\"%s\"]", seq->name+2);
+ if (seq->name+2)
+ return BLI_sprintfN("sequence_editor.sequences[\"%s\"]", seq->name+2);
+ else {
+ /* compromise for the frequent sitation when strips don't have names... */
+ Scene *sce= (Scene*)ptr->id.data;
+ Editing *ed= seq_give_editing(sce, FALSE);
+
+ return BLI_sprintfN("sequence_editor.sequences[%d]", BLI_findindex(&ed->seqbase, seq));
+ }
}
static PointerRNA rna_SequenceEdtior_meta_stack_get(CollectionPropertyIterator *iter)
@@ -239,6 +247,35 @@ static PointerRNA rna_SequenceEdtior_meta_stack_get(CollectionPropertyIterator *
return rna_pointer_inherit_refine(&iter->parent, &RNA_Sequence, ms->parseq);
}
+static void rna_MovieSequence_filename_set(PointerRNA *ptr, const char *value)
+{
+ Sequence *seq= (Sequence*)(ptr->data);
+ char dir[FILE_MAX], name[FILE_MAX];
+
+ BLI_split_dirfile_basic(value, dir, name);
+ BLI_strncpy(seq->strip->dir, dir, sizeof(seq->strip->dir));
+ BLI_strncpy(seq->strip->stripdata->name, name, sizeof(seq->strip->stripdata->name));
+}
+
+static void rna_SoundSequence_filename_set(PointerRNA *ptr, const char *value)
+{
+ Sequence *seq= (Sequence*)(ptr->data);
+ char dir[FILE_MAX], name[FILE_MAX];
+
+ BLI_split_dirfile_basic(value, dir, name);
+ BLI_strncpy(seq->strip->dir, dir, sizeof(seq->strip->dir));
+ BLI_strncpy(seq->strip->stripdata->name, name, sizeof(seq->strip->stripdata->name));
+}
+
+static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value)
+{
+ StripElem *elem= (StripElem*)(ptr->data);
+ char name[FILE_MAX];
+
+ BLI_split_dirfile_basic(value, NULL, name);
+ BLI_strncpy(elem->name, name, sizeof(elem->name));
+}
+
#else
static void rna_def_strip_element(BlenderRNA *brna)
@@ -253,6 +290,7 @@ static void rna_def_strip_element(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Filename", "");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SequenceElement_filename_set");
}
static void rna_def_strip_crop(BlenderRNA *brna)
@@ -490,6 +528,7 @@ static void rna_def_sequence(BlenderRNA *brna)
prop= RNA_def_property(srna, "channel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "machine");
+ RNA_def_property_range(prop, 0, MAXSEQ-1);
RNA_def_property_ui_text(prop, "Channel", "Y position of the sequence strip.");
RNA_def_property_int_funcs(prop, NULL, "rna_SequenceEditor_channel_set",NULL); // overlap test
RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, NULL);
@@ -514,7 +553,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_function_return(func, RNA_def_pointer(func, "elem", "SequenceElement", "", "strip element of the current frame"));
}
-void rna_def_editor(BlenderRNA *brna)
+static void rna_def_editor(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -736,6 +775,7 @@ static void rna_def_movie(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "strip->stripdata->name");
RNA_def_property_ui_text(prop, "Filename", "");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MovieSequence_filename_set");
prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "strip->dir");
@@ -762,6 +802,7 @@ static void rna_def_sound(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "strip->stripdata->name");
RNA_def_property_ui_text(prop, "Filename", "");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SoundSequence_filename_set");
prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "strip->dir");
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 943129c7169..7bccd685c1d 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -211,11 +211,13 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x ");
RNA_def_property_update(prop, 0, NULL);
- prop= RNA_def_property(srna, "point_cache_low", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "point_cache_low", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "point_cache[0]");
RNA_def_property_ui_text(prop, "Point Cache", "");
- prop= RNA_def_property(srna, "point_cache_high", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "point_cache_high", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]");
RNA_def_property_ui_text(prop, "Point Cache", "");
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 542f6e2aeda..422283c940f 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -38,8 +38,7 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
-#include "BKE_paint.h"
-
+#include "WM_api.h"
#include "WM_types.h"
EnumPropertyItem space_type_items[] = {
@@ -80,11 +79,15 @@ static EnumPropertyItem dc_all_items[] = {DC_RGB, DC_RGBA, DC_ALPHA, DC_Z, DC_LC
#ifdef RNA_RUNTIME
+#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "BKE_animsys.h"
#include "BKE_brush.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
+#include "BKE_paint.h"
#include "ED_image.h"
#include "ED_screen.h"
@@ -188,7 +191,8 @@ static EnumPropertyItem dc_z_items[] = {DC_RGB, DC_Z, DC_LCMS, DC_ZERO};
static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, PointerRNA *ptr, int *free)
{
SpaceImage *sima= (SpaceImage*)ptr->data;
- ImBuf *ibuf= ED_space_image_buffer(sima);
+ ImBuf *ibuf;
+ void *lock;
int zbuf, alpha;
if(C==NULL) {
@@ -196,9 +200,13 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, P
return dc_all_items;
}
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+
alpha= ibuf && (ibuf->channels == 4);
zbuf= ibuf && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1));
+ ED_space_image_release_buffer(sima, lock);
+
if(alpha && zbuf)
return dc_all_items;
else if(alpha)
@@ -209,9 +217,23 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, P
return dc_rgb_items;
}
+static void rna_SpaceImageEditor_curves_update(bContext *C, PointerRNA *ptr)
+{
+ SpaceImage *sima= (SpaceImage*)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+ curvemapping_do_ibuf(sima->cumap, ibuf);
+ ED_space_image_release_buffer(sima, lock);
+
+ WM_event_add_notifier(C, NC_IMAGE, sima->image);
+}
+
+
/* Space Text Editor */
-void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
+static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
{
SpaceText *st= (SpaceText*)(ptr->data);
@@ -219,7 +241,7 @@ void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
st->left= 0;
}
-void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value)
+static void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value)
{
SpaceText *st= (SpaceText*)(ptr->data);
@@ -227,16 +249,9 @@ void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value)
st->top= 0;
}
-void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value)
-{
- SpaceFile *sfile= (SpaceFile*)(ptr->data);
-
- sfile->params= value.data;
-}
-
/* Space Properties */
-StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr)
+static StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr)
{
SpaceButs *sbuts= (SpaceButs*)(ptr->data);
@@ -246,7 +261,7 @@ StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr)
return &RNA_ID;
}
-void rna_SpaceProperties_align_set(PointerRNA *ptr, int value)
+static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value)
{
SpaceButs *sbuts= (SpaceButs*)(ptr->data);
@@ -311,12 +326,36 @@ static void rna_View3D_display_background_image_set(PointerRNA *ptr, int value)
}
/* Space Time */
+
static void rna_SpaceTime_redraw_update(bContext *C, PointerRNA *ptr)
{
SpaceTime *st= (SpaceTime*)ptr->data;
ED_screen_animation_timer_update(C, st->redraws);
}
+/* Space Dopesheet */
+
+static void rna_SpaceDopeSheetEditor_action_set(PointerRNA *ptr, PointerRNA value)
+{
+ SpaceAction *saction= (SpaceAction*)(ptr->data);
+ saction->action= value.data;
+}
+
+static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr)
+{
+ SpaceAction *saction= (SpaceAction*)(ptr->data);
+ Object *obact= CTX_data_active_object(C);
+
+ /* we must set this action to be the one used by active object (if not pinned) */
+ if(obact && saction->pin == 0) {
+ AnimData *adt= BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */
+
+ /* set action */
+ adt->action= saction->action;
+ id_us_plus(&adt->action->id);
+ }
+}
+
#else
static void rna_def_space(BlenderRNA *brna)
@@ -491,7 +530,8 @@ static void rna_def_background_image(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
- prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "iuser");
RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed.");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
@@ -572,11 +612,9 @@ static void rna_def_space_3dview(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Viewport Shading", "Method to display/shade objects in the 3D View.");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
- prop= RNA_def_property(srna, "localview", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "localview", 0);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ prop= RNA_def_property(srna, "local_view", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "localvd");
RNA_def_property_ui_text(prop, "Local View", "Display an isolated sub-set of objects, apart from the scene visibility.");
- RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
prop= RNA_def_property(srna, "lens", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "lens");
@@ -717,10 +755,11 @@ static void rna_def_space_buttons(BlenderRNA *brna)
{BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
{BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
{BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
- {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraint", "Constraint"},
- {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifier", "Modifier"},
+ {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"},
+ {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"},
{BCONTEXT_DATA, "DATA", 0, "Data", "Data"},
{BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
+ {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone Constraints"},
{BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
{BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
{BCONTEXT_PARTICLE, "PARTICLE", ICON_PARTICLES, "Particle", "Particle"},
@@ -779,7 +818,8 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL);
- prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "iuser");
RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed.");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL);
@@ -787,7 +827,7 @@ static void rna_def_space_image(BlenderRNA *brna)
prop= RNA_def_property(srna, "curves", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "cumap");
RNA_def_property_ui_text(prop, "Curves", "Color curve mapping to use for displaying the image.");
- RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_curves_update");
prop= RNA_def_property(srna, "image_pin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "pin", 0);
@@ -808,7 +848,8 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL);
/* uv */
- prop= RNA_def_property(srna, "uv_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "uv_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "SpaceUVEditor");
RNA_def_property_pointer_funcs(prop, "rna_SpaceImageEditor_uvedit_get", NULL, NULL);
RNA_def_property_ui_text(prop, "UV Editor", "UV editor settings.");
@@ -1036,6 +1077,13 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
srna= RNA_def_struct(brna, "SpaceDopeSheetEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceAction");
RNA_def_struct_ui_text(srna, "Space DopeSheet Editor", "DopeSheet space data.");
+
+ /* data */
+ prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceDopeSheetEditor_action_set", NULL);
+ RNA_def_property_ui_text(prop, "Action", "Action displayed and edited in this space.");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, "rna_SpaceDopeSheetEditor_action_update");
/* mode */
prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
@@ -1199,6 +1247,11 @@ static void rna_def_space_time(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Sequencer Windows", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
+ prop= RNA_def_property(srna, "play_nodes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_NODES);
+ RNA_def_property_ui_text(prop, "Node Windows", "");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update");
+
/* Other options */
prop= RNA_def_property(srna, "continue_physics", PROP_BOOLEAN, PROP_NONE);
@@ -1422,7 +1475,6 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
prop= RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "params");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceFileBrowser_params_set", NULL);
RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser.");
}
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index cd39c317bc5..8c9b2b58887 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -198,7 +198,8 @@ static void rna_def_text(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "TextLine");
RNA_def_property_ui_text(prop, "Lines", "Lines of text.");
- prop= RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "curl");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "TextLine");
@@ -209,7 +210,8 @@ static void rna_def_text(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Current Character", "Index of current character in current line, and also start index of character in selection if one exists.");
- prop= RNA_def_property(srna, "selection_end_line", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "selection_end_line", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "sell");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "TextLine");
@@ -223,6 +225,8 @@ static void rna_def_text(BlenderRNA *brna)
prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "TextMarker");
RNA_def_property_ui_text(prop, "Markers", "Text markers highlighting part of the text.");
+
+ RNA_api_text(srna);
}
void RNA_def_text(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_text_api.c b/source/blender/makesrna/intern/rna_text_api.c
new file mode 100644
index 00000000000..b048a6b59d0
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_text_api.c
@@ -0,0 +1,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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#ifdef RNA_RUNTIME
+
+#else
+
+void RNA_api_text(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *prop;
+
+ func= RNA_def_function(srna, "clear", "clear_text");
+ RNA_def_function_ui_description(func, "clear the text block.");
+
+ func= RNA_def_function(srna, "write", "write_text");
+ RNA_def_function_ui_description(func, "write text at the cursor location and advance to the end of the text block.");
+ prop= RNA_def_string(func, "text", "Text", 0, "", "New text for this datablock.");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index f6835f3e7b5..5c7a097a54d 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -40,8 +40,6 @@
#include "BKE_node.h"
-#include "WM_types.h"
-
static EnumPropertyItem texture_filter_items[] = {
{TXF_BOX, "BOX", 0, "Box", ""},
{TXF_EWA, "EWA", 0, "EWA", ""},
@@ -52,10 +50,16 @@ static EnumPropertyItem texture_filter_items[] = {
#ifdef RNA_RUNTIME
+#include "BKE_depsgraph.h"
#include "BKE_texture.h"
+#include "BKE_main.h"
+
#include "ED_node.h"
-StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
+#include "WM_api.h"
+#include "WM_types.h"
+
+static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
{
Tex *tex= (Tex*)ptr->data;
@@ -95,6 +99,14 @@ StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
}
}
+static void rna_Texture_update(bContext *C, PointerRNA *ptr)
+{
+ Tex *tex= ptr->id.data;
+
+ DAG_id_flush_update(&tex->id, 0);
+ WM_event_add_notifier(C, NC_TEXTURE, tex);
+}
+
static void rna_Texture_type_set(PointerRNA *ptr, int value)
{
Tex *tex= (Tex*)ptr->data;
@@ -112,6 +124,28 @@ static void rna_Texture_type_set(PointerRNA *ptr, int value)
tex->type = value;
}
+void rna_TextureSlot_update(bContext *C, PointerRNA *ptr)
+{
+ ID *id= ptr->id.data;
+
+ DAG_id_flush_update(id, 0);
+
+ switch(GS(id->name)) {
+ case ID_MA:
+ WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, id);
+ break;
+ case ID_WO:
+ WM_event_add_notifier(C, NC_WORLD, id);
+ break;
+ case ID_LA:
+ WM_event_add_notifier(C, NC_LAMP|ND_LIGHTING, id);
+ break;
+ case ID_BR:
+ WM_event_add_notifier(C, NC_BRUSH, id);
+ break;
+ }
+}
+
static int rna_TextureSlot_name_length(PointerRNA *ptr)
{
MTex *mtex= ptr->data;
@@ -202,7 +236,7 @@ static void rna_Texture_use_color_ramp_set(PointerRNA *ptr, int value)
tex->coba= add_colorband(0);
}
-void rna_Texture_use_nodes_set(PointerRNA *ptr, int v)
+static void rna_Texture_use_nodes_set(PointerRNA *ptr, int v)
{
Tex *tex= (Tex*)ptr->data;
@@ -242,20 +276,6 @@ static EnumPropertyItem *rna_ImageTexture_filter_itemf(bContext *C, PointerRNA *
return item;
}
-static float rna_TextureSlot_angle_get(PointerRNA *ptr)
-{
- MTex *tex= (MTex*)ptr->data;
- const float conv = 57.295779506;
- return tex->rot * conv;
-}
-
-static void rna_TextureSlot_angle_set(PointerRNA *ptr, float v)
-{
- MTex *tex= (MTex*)ptr->data;
- const float conv = 0.017453293;
- tex->rot = v * conv;
-}
-
#else
static void rna_def_color_ramp_element(BlenderRNA *brna)
@@ -271,13 +291,13 @@ static void rna_def_color_ramp_element(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "r");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Color", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "position", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "pos");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Position", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_color_ramp(BlenderRNA *brna)
@@ -301,13 +321,13 @@ static void rna_def_color_ramp(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "data", "tot");
RNA_def_property_struct_type(prop, "ColorRampElement");
RNA_def_property_ui_text(prop, "Elements", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ipotype");
RNA_def_property_enum_items(prop, prop_interpolation_items);
RNA_def_property_ui_text(prop, "Interpolation", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texmapping(BlenderRNA *brna)
@@ -321,37 +341,37 @@ static void rna_def_texmapping(BlenderRNA *brna)
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "rot");
RNA_def_property_ui_text(prop, "Rotation", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_ui_text(prop, "Scale", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "minimum", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum", "Minimum value for clipping");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "maximum", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum", "Maximum value for clipping");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "has_minimum", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
RNA_def_property_ui_text(prop, "Has Minimum", "Whether to use minimum clipping value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "has_maximum", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
RNA_def_property_ui_text(prop, "Has Maximum", "Whether to use maximum clipping value");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_mtex(BlenderRNA *brna)
@@ -378,12 +398,6 @@ static void rna_def_mtex(BlenderRNA *brna)
{MTEX_LIN_LIGHT , "LINEAR LIGHT", 0, "Linear Light", ""},
{0, NULL, 0, NULL, NULL}};
- static EnumPropertyItem prop_map_mode_items[] = {
- {MTEX_MAP_MODE_FIXED, "FIXED", 0, "Fixed", ""},
- {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""},
- {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""},
- {0, NULL, 0, NULL, NULL}};
-
static EnumPropertyItem output_node_items[] = {
{0, "DUMMY", 0, "Dummy", ""},
{0, NULL, 0, NULL, NULL}};
@@ -398,89 +412,66 @@ static void rna_def_mtex(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Texture");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Texture", "Texture datablock used by this texture slot.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_TextureSlot_name_get", "rna_TextureSlot_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Texture slot name.");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_struct_name_property(srna, prop);
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
/* mapping */
prop= RNA_def_property(srna, "offset", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "ofs");
RNA_def_property_ui_range(prop, -10, 10, 10, 2);
RNA_def_property_ui_text(prop, "Offset", "Fine tunes texture mapping X, Y and Z locations.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_XYZ);
RNA_def_property_ui_range(prop, -100, 100, 10, 2);
RNA_def_property_ui_text(prop, "Size", "Sets scaling for the texture's X, Y and Z sizes.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "r");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Color", "The default color for textures that don't return RGB.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "blendtype");
RNA_def_property_enum_items(prop, prop_blend_type_items);
RNA_def_property_ui_text(prop, "Blend Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "stencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_STENCIL);
RNA_def_property_ui_text(prop, "Stencil", "Use this texture as a blending value on the next texture.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "negate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_NEGATIVE);
RNA_def_property_ui_text(prop, "Negate", "Inverts the values of the texture to reverse its effect.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "rgb_to_intensity", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_RGBTOINT);
RNA_def_property_ui_text(prop, "RGB to Intensity", "Converts texture RGB values to intensity (gray) values.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_float_sdna(prop, NULL, "rot");
- RNA_def_property_range(prop, 0, 360);
- RNA_def_property_float_funcs(prop, "rna_TextureSlot_angle_get", "rna_TextureSlot_angle_set", NULL);
- RNA_def_property_ui_text(prop, "Angle", "Defines brush texture rotation.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- prop= RNA_def_property(srna, "brush_map_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, prop_map_mode_items);
- RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "def_var");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Default Value", "Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- prop= RNA_def_property(srna, "variable_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
- RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Variable Factor", "Amount texture affects other values.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
-
- prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "norfac");
- RNA_def_property_ui_range(prop, 0, 5, 10, 3);
- RNA_def_property_ui_text(prop, "Normal Factor", "Amount texture affects normal values.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
prop= RNA_def_property(srna, "output_node", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "which_output");
RNA_def_property_enum_items(prop, output_node_items);
RNA_def_property_enum_funcs(prop, "rna_TextureSlot_output_node_get", NULL, "rna_TextureSlot_output_node_itemf");
RNA_def_property_ui_text(prop, "Output Node", "Which output node to use, for node-based textures.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
}
static void rna_def_filter_size_common(StructRNA *srna)
@@ -491,14 +482,14 @@ static void rna_def_filter_size_common(StructRNA *srna)
prop= RNA_def_property(srna, "use_filter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_FILTER_MIN);
RNA_def_property_ui_text(prop, "Use Filter", "Use Filter Size as a minimal filter value in pixels");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "filter_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "filtersize");
RNA_def_property_range(prop, 0.1, 50.0);
RNA_def_property_ui_range(prop, 0.1, 50.0, 1, 0.2);
RNA_def_property_ui_text(prop, "Filter Size", "Multiplies the filter size used by MIP Map and Interpolation");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_environment_map_common(StructRNA *srna)
@@ -515,14 +506,14 @@ static void rna_def_environment_map_common(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_source_items);
RNA_def_property_ui_text(prop, "Source", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* XXX: move this to specific types if needed */
prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ima");
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_ui_text(prop, "Image", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_environment_map(BlenderRNA *brna)
@@ -545,28 +536,28 @@ static void rna_def_environment_map(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clipsta");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_range(prop, 0.01, 50, 100, 2);
RNA_def_property_ui_text(prop, "Clip Start", "Objects nearer than this are not visible to map.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clipend");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_range(prop, 0.10, 20000, 100, 2);
RNA_def_property_ui_text(prop, "Clip End", "Objects further than this are not visible to map.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "viewscale");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_range(prop, 0.5, 5, 100, 2);
RNA_def_property_ui_text(prop, "Zoom", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* XXX: EnvMap.notlay */
@@ -574,12 +565,12 @@ static void rna_def_environment_map(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "cuberes");
RNA_def_property_range(prop, 50, 4096);
RNA_def_property_ui_text(prop, "Resolution", "Pixel resolution of the rendered environment map.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "depth", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 5);
RNA_def_property_ui_text(prop, "Depth", "Number of times a map will be rendered recursively (mirror effects.)");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static EnumPropertyItem prop_noise_basis_items[] = {
@@ -620,38 +611,38 @@ static void rna_def_texture_clouds(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_depth", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "noisedepth");
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_range(prop, 0, 6, 0, 2);
RNA_def_property_ui_text(prop, "Noise Depth", "Sets the depth of the cloud calculation");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisetype");
RNA_def_property_enum_items(prop, prop_noise_type);
RNA_def_property_ui_text(prop, "Noise Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_clouds_stype);
RNA_def_property_ui_text(prop, "Color", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.001, 0.1);
RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_wood(BlenderRNA *brna)
@@ -681,44 +672,44 @@ static void rna_def_texture_wood(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "turbul");
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisetype");
RNA_def_property_enum_items(prop, prop_noise_type);
RNA_def_property_ui_text(prop, "Noise Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_wood_stype);
RNA_def_property_ui_text(prop, "Pattern", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noisebasis2", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis2");
RNA_def_property_enum_items(prop, prop_wood_noisebasis2);
RNA_def_property_ui_text(prop, "Noise Basis 2", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.001, 0.1);
RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
@@ -748,51 +739,51 @@ static void rna_def_texture_marble(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "turbul");
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_depth", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "noisedepth");
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_range(prop, 0, 6, 0, 2);
RNA_def_property_ui_text(prop, "Noise Depth", "Sets the depth of the cloud calculation");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisetype");
RNA_def_property_enum_items(prop, prop_noise_type);
RNA_def_property_ui_text(prop, "Noise Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_marble_stype);
RNA_def_property_ui_text(prop, "Pattern", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noisebasis2", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis2");
RNA_def_property_enum_items(prop, prop_marble_noisebasis2);
RNA_def_property_ui_text(prop, "Noise Basis 2", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.001, 0.1);
RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
@@ -810,14 +801,14 @@ static void rna_def_texture_magic(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_depth", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "noisedepth");
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_range(prop, 0, 6, 0, 2);
RNA_def_property_ui_text(prop, "Noise Depth", "Sets the depth of the cloud calculation");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_blend(BlenderRNA *brna)
@@ -835,6 +826,11 @@ static void rna_def_texture_blend(BlenderRNA *brna)
{TEX_RAD, "RADIAL", 0, "Radial", "Creates a radial progression"},
{0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem prop_flip_axis_items[]= {
+ {0, "HORIZONTAL", 0, "Horizontal", "Flips the texture's X and Y axis"},
+ {TEX_FLIPBLEND, "VERTICAL", 0, "Vertical", "Flips the texture's X and Y axis"},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "BlendTexture", "Texture");
RNA_def_struct_ui_text(srna, "Blend Texture", "Procedural color blending texture.");
RNA_def_struct_sdna(srna, "Tex");
@@ -843,12 +839,14 @@ static void rna_def_texture_blend(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_blend_progression);
RNA_def_property_ui_text(prop, "Progression", "Sets the style of the color blending");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
- prop= RNA_def_property(srna, "flip_axis", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_FLIPBLEND);
+ prop= RNA_def_property(srna, "flip_axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, prop_flip_axis_items);
RNA_def_property_ui_text(prop, "Flip Axis", "Flips the texture's X and Y axis");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
}
static void rna_def_texture_stucci(BlenderRNA *brna)
@@ -871,32 +869,32 @@ static void rna_def_texture_stucci(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "noisesize");
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisetype");
RNA_def_property_enum_items(prop, prop_noise_type);
RNA_def_property_ui_text(prop, "Noise Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_stucci_stype);
RNA_def_property_ui_text(prop, "Pattern", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_noise(BlenderRNA *brna)
@@ -914,11 +912,11 @@ static void rna_def_texture_image(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem prop_image_extension[] = {
- {1, "EXTEND", 0, "Extend", "Extends by repeating edge pixels of the image"},
- {2, "CLIP", 0, "Clip", "Clips to image size and sets exterior pixels as transparent"},
- {4, "CLIP_CUBE", 0, "Clip Cube", "Clips to cubic-shaped area around the image and sets exterior pixels as transparent"},
- {3, "REPEAT", 0, "Repeat", "Causes the image to repeat horizontally and vertically"},
- {5, "CHECKER", 0, "Checker", "Causes the image to repeat in checker board pattern"},
+ {TEX_EXTEND, "EXTEND", 0, "Extend", "Extends by repeating edge pixels of the image"},
+ {TEX_CLIP, "CLIP", 0, "Clip", "Clips to image size and sets exterior pixels as transparent"},
+ {TEX_CLIPCUBE, "CLIP_CUBE", 0, "Clip Cube", "Clips to cubic-shaped area around the image and sets exterior pixels as transparent"},
+ {TEX_REPEAT, "REPEAT", 0, "Repeat", "Causes the image to repeat horizontally and vertically"},
+ {TEX_CHECKER, "CHECKER", 0, "Checker", "Causes the image to repeat in checker board pattern"},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "ImageTexture", "Texture");
@@ -929,45 +927,45 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_MIPMAP);
RNA_def_property_boolean_funcs(prop, NULL, "rna_ImageTexture_mipmap_set");
RNA_def_property_ui_text(prop, "MIP Map", "Uses auto-generated MIP maps for the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "mipmap_gauss", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_GAUSS_MIP);
RNA_def_property_ui_text(prop, "MIP Map Gauss", "Uses Gauss filter to sample down MIP maps");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "interpolation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_INTERPOL);
RNA_def_property_ui_text(prop, "Interpolation", "Interpolates pixels using Area filter");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* XXX: I think flip_axis should be a generic Texture property, enabled for all the texture types */
prop= RNA_def_property(srna, "flip_axis", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_IMAROT);
RNA_def_property_ui_text(prop, "Flip Axis", "Flips the texture's X and Y axis");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ 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", "Uses the alpha channel information in the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "calculate_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_CALCALPHA);
RNA_def_property_ui_text(prop, "Calculate Alpha", "Calculates an alpha channel based on RGB values in the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "invert_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_NEGALPHA);
RNA_def_property_ui_text(prop, "Invert Alpha", "Inverts all the alpha values in the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
rna_def_filter_size_common(srna);
prop= RNA_def_property(srna, "normal_map", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_NORMALMAP);
RNA_def_property_ui_text(prop, "Normal Map", "Uses image RGB values for normal mapping");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* XXX: mtex->normapspace "Sets space of normal map image" "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3"
* not sure why this goes in mtex instead of texture directly? */
@@ -975,47 +973,47 @@ static void rna_def_texture_image(BlenderRNA *brna)
prop= RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "extend");
RNA_def_property_enum_items(prop, prop_image_extension);
- RNA_def_property_ui_text(prop, "Extension", "Sets how the image is stretched in the texture");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_ui_text(prop, "Extension", "Sets how the image is extrapolated past its original bounds");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "repeat_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "xrepeat");
RNA_def_property_range(prop, 1, 512);
RNA_def_property_ui_text(prop, "Repeat X", "Sets a repetition multiplier in the X direction");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "repeat_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "yrepeat");
RNA_def_property_range(prop, 1, 512);
RNA_def_property_ui_text(prop, "Repeat Y", "Sets a repetition multiplier in the Y direction");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "mirror_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_REPEAT_XMIR);
RNA_def_property_ui_text(prop, "Mirror X", "Mirrors the image repetition on the X direction");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "mirror_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_REPEAT_YMIR);
RNA_def_property_ui_text(prop, "Mirror Y", "Mirrors the image repetition on the Y direction");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "checker_odd", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_CHECKER_ODD);
RNA_def_property_ui_text(prop, "Checker Odd", "Sets odd checker tiles");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "checker_even", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_CHECKER_EVEN);
RNA_def_property_ui_text(prop, "Checker Even", "Sets even checker tiles");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "checker_distance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "checkerdist");
RNA_def_property_range(prop, 0.0, 0.99);
RNA_def_property_ui_range(prop, 0.0, 0.99, 0.1, 0.01);
RNA_def_property_ui_text(prop, "Checker Distance", "Sets distance between checker tiles");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
#if 0
@@ -1027,7 +1025,7 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, -10, 10);
RNA_def_property_ui_text(prop, "Crop Rectangle", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
#endif
@@ -1036,35 +1034,40 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_range(prop, -10.0, 10.0);
RNA_def_property_ui_range(prop, -10.0, 10.0, 1, 0.2);
RNA_def_property_ui_text(prop, "Crop Minimum X", "Sets minimum X value to crop the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "crop_min_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cropymin");
RNA_def_property_range(prop, -10.0, 10.0);
RNA_def_property_ui_range(prop, -10.0, 10.0, 1, 0.2);
RNA_def_property_ui_text(prop, "Crop Minimum Y", "Sets minimum Y value to crop the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "crop_max_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cropxmax");
RNA_def_property_range(prop, -10.0, 10.0);
RNA_def_property_ui_range(prop, -10.0, 10.0, 1, 0.2);
RNA_def_property_ui_text(prop, "Crop Maximum X", "Sets maximum X value to crop the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "crop_max_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cropymax");
RNA_def_property_range(prop, -10.0, 10.0);
RNA_def_property_ui_range(prop, -10.0, 10.0, 1, 0.2);
RNA_def_property_ui_text(prop, "Crop Maximum Y", "Sets maximum Y value to crop the image");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ima");
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+ prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "iuser");
+ RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed.");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* filtering */
prop= RNA_def_property(srna, "filter", PROP_ENUM, PROP_NONE);
@@ -1072,19 +1075,19 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_enum_items(prop, texture_filter_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_ImageTexture_filter_itemf");
RNA_def_property_ui_text(prop, "Filter", "Texture filter to use for sampling image.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "filter_probes", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "afmax");
RNA_def_property_range(prop, 1, 256);
RNA_def_property_ui_text(prop, "Filter Probes", "Maximum number of samples. Higher gives less blur at distant/oblique angles, but is also slower.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "filter_eccentricity", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "afmax");
RNA_def_property_range(prop, 1, 256);
RNA_def_property_ui_text(prop, "Filter Eccentricity", "Maximum eccentricity. Higher gives less blur at distant/oblique angles, but is also slower.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_plugin(BlenderRNA *brna)
@@ -1109,11 +1112,16 @@ static void rna_def_texture_environment_map(BlenderRNA *brna)
rna_def_environment_map_common(srna);
+ prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "iuser");
+ RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed.");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
prop= RNA_def_property(srna, "environment_map", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "env");
RNA_def_property_struct_type(prop, "EnvironmentMap");
RNA_def_property_ui_text(prop, "Environment Map", "Gets the environment map associated with this texture");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
rna_def_filter_size_common(srna);
}
@@ -1139,62 +1147,62 @@ static void rna_def_texture_musgrave(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_musgrave_type);
RNA_def_property_ui_text(prop, "Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "highest_dimension", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mg_H");
RNA_def_property_range(prop, 0.0001, 2);
RNA_def_property_ui_text(prop, "Highest Dimension", "Highest fractal dimension");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "lacunarity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mg_lacunarity");
RNA_def_property_range(prop, 0, 6);
RNA_def_property_ui_text(prop, "Lacunarity", "Gap between succesive frequencies");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "octaves", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mg_octaves");
RNA_def_property_range(prop, 0, 8);
RNA_def_property_ui_text(prop, "Octaves", "Number of frequencies used");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mg_offset");
RNA_def_property_range(prop, 0, 6);
RNA_def_property_ui_text(prop, "Offset", "The fractal offset");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mg_gain");
RNA_def_property_range(prop, 0, 6);
RNA_def_property_ui_text(prop, "Gain", "The gain multiplier");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ns_outscale");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Noise Intensity", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "noisesize");
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.001, 0.1);
RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_voronoi(BlenderRNA *brna)
@@ -1228,62 +1236,62 @@ static void rna_def_texture_voronoi(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "vn_w1");
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 1", "Voronoi feature weight 1");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "weight_2", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_w2");
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 2", "Voronoi feature weight 2");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "weight_3", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_w3");
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 3", "Voronoi feature weight 3");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "weight_4", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_w4");
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 4", "Voronoi feature weight 4");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "minkovsky_exponent", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_mexp");
RNA_def_property_range(prop, 0.01, 10);
RNA_def_property_ui_text(prop, "Minkovsky Exponent", "Minkovsky exponent");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "distance_metric", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "vn_distm");
RNA_def_property_enum_items(prop, prop_distance_metric_items);
RNA_def_property_ui_text(prop, "Distance Metric", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "coloring", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "vn_coltype");
RNA_def_property_enum_items(prop, prop_coloring_items);
RNA_def_property_ui_text(prop, "Coloring", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ns_outscale");
RNA_def_property_range(prop, 0.01, 10);
RNA_def_property_ui_text(prop, "Noise Intensity", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "noisesize");
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.001, 0.1);
RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_distorted_noise(BlenderRNA *brna)
@@ -1299,32 +1307,32 @@ static void rna_def_texture_distorted_noise(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "dist_amount");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Distortion Amount", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "noisesize");
RNA_def_property_range(prop, 0.0001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis2");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_distortion", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Distortion", "Sets the noise basis for the distortion");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.001, 0.1);
RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_pointdensity(BlenderRNA *brna)
@@ -1380,104 +1388,104 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "source");
RNA_def_property_enum_items(prop, point_source_items);
RNA_def_property_ui_text(prop, "Point Source", "Point data to use as renderable point density");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object");
RNA_def_property_ui_text(prop, "Object", "Object to take point data from");
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "psys");
RNA_def_property_ui_text(prop, "Particle System", "Particle System to render as points");
RNA_def_property_struct_type(prop, "ParticleSystem");
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "particle_cache", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "psys_cache_space");
RNA_def_property_enum_items(prop, particle_cache_items);
RNA_def_property_ui_text(prop, "Particle Cache", "Co-ordinate system to cache particles in");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "vertices_cache", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ob_cache_space");
RNA_def_property_enum_items(prop, vertice_cache_items);
RNA_def_property_ui_text(prop, "Vertices Cache", "Co-ordinate system to cache vertices in");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "radius");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_text(prop, "Radius", "Radius from the shaded sample to look for points within");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "falloff_type");
RNA_def_property_enum_items(prop, falloff_items);
RNA_def_property_ui_text(prop, "Falloff", "Method of attenuating density by distance from the point");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "falloff_softness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "falloff_softness");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_text(prop, "Softness", "Softness of the 'soft' falloff option");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "color_source", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "color_source");
RNA_def_property_enum_items(prop, color_source_items);
RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "speed_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "speed_scale");
RNA_def_property_range(prop, 0.001, 100.0);
RNA_def_property_ui_text(prop, "Scale", "Multipler to bring particle speed within an acceptable range");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "coba");
RNA_def_property_struct_type(prop, "ColorRamp");
RNA_def_property_ui_text(prop, "Color Ramp", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* Turbulence */
prop= RNA_def_property(srna, "turbulence", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_PD_TURBULENCE);
RNA_def_property_ui_text(prop, "Turbulence", "Add directed noise to the density at render-time");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "turbulence_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "noise_size");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_text(prop, "Size", "Scale of the added turbulent noise");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "turbulence_strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "noise_fac");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_text(prop, "Strength", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "turbulence_depth", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "noise_depth");
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_text(prop, "Depth", "Level of detail in the added turbulent noise");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "turbulence_influence", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noise_influence");
RNA_def_property_enum_items(prop, turbulence_influence_items);
RNA_def_property_ui_text(prop, "Turbulence Influence", "Method for driving added turbulent noise");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noise_basis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
RNA_def_property_ui_text(prop, "Noise Basis", "Noise formula used for tubulence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
srna= RNA_def_struct(brna, "PointDensityTexture", "Texture");
@@ -1488,7 +1496,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "pd");
RNA_def_property_struct_type(prop, "PointDensity");
RNA_def_property_ui_text(prop, "Point Density", "The point density settings associated with this texture");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture_voxeldata(BlenderRNA *brna)
@@ -1511,6 +1519,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
{TEX_VD_IMAGE_SEQUENCE, "IMAGE_SEQUENCE", 0, "Image Sequence", "Generate voxels from a sequence of image slices"},
{TEX_VD_SMOKE, "SMOKE", 0, "Smoke", "Render voxels from a Blender smoke simulation"},
{0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem voxeldata_extension[] = {
+ {TEX_EXTEND, "EXTEND", 0, "Extend", "Extends by repeating edge pixels of the image"},
+ {TEX_CLIP, "CLIP", 0, "Clip", "Clips to image size and sets exterior pixels as transparent"},
+ {TEX_REPEAT, "REPEAT", 0, "Repeat", "Causes the image to repeat horizontally and vertically"},
+ {0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "VoxelData", NULL);
RNA_def_struct_sdna(srna, "VoxelData");
@@ -1520,46 +1534,52 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "interp_type");
RNA_def_property_enum_items(prop, interpolation_type_items);
RNA_def_property_ui_text(prop, "Interpolation", "Method to interpolate/smooth values between voxel cells");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+ prop= RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "extend");
+ RNA_def_property_enum_items(prop, voxeldata_extension);
+ RNA_def_property_ui_text(prop, "Extension", "Sets how the texture is extrapolated past its original bounds");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "int_multiplier");
RNA_def_property_range(prop, 0.01, FLT_MAX);
RNA_def_property_ui_text(prop, "Intensity", "Multiplier for intensity values");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "file_format", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "file_format");
RNA_def_property_enum_items(prop, file_format_items);
RNA_def_property_ui_text(prop, "File Format", "Format of the source data set to render ");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "source_path", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "source_path");
RNA_def_property_ui_text(prop, "Source Path", "The external source data file to use");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resol");
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the voxel grid.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "still", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_VD_STILL);
RNA_def_property_ui_text(prop, "Still Frame Only", "Always render a still frame from the voxel data sequence");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "still_frame_number", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "still_frame");
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_text(prop, "Still Frame Number", "The frame number to always use");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "domain_object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object");
RNA_def_property_ui_text(prop, "Domain Object", "Object used as the smoke simulation domain");
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
srna= RNA_def_struct(brna, "VoxelDataTexture", "Texture");
@@ -1570,7 +1590,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "vd");
RNA_def_property_struct_type(prop, "VoxelData");
RNA_def_property_ui_text(prop, "Voxel Data", "The voxel data associated with this texture");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
}
static void rna_def_texture(BlenderRNA *brna)
@@ -1609,51 +1629,49 @@ static void rna_def_texture(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_enum_funcs(prop, NULL, "rna_Texture_type_set", NULL);
RNA_def_property_ui_text(prop, "Type", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "use_color_ramp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_COLORBAND);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_color_ramp_set");
RNA_def_property_ui_text(prop, "Use Color Ramp", "Toggle color ramp operations.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "coba");
RNA_def_property_struct_type(prop, "ColorRamp");
RNA_def_property_ui_text(prop, "Color Ramp", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "brightness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bright");
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Brightness", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.01, 5);
RNA_def_property_ui_text(prop, "Contrast", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
- /* XXX: would be nicer to have this as a color selector?
- but the values can go past [0,1]. */
- prop= RNA_def_property(srna, "rgb_factor", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "rgb_factor", PROP_FLOAT, PROP_RGB);
RNA_def_property_float_sdna(prop, NULL, "rfac");
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "RGB Factor", "");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
/* nodetree */
prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_nodes_set");
RNA_def_property_ui_text(prop, "Use Nodes", "Make this a node-based texture");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node-based textures");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
rna_def_animdata_common(srna);
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 20948843f8a..17846651c3b 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -37,14 +37,15 @@
#ifdef RNA_RUNTIME
-static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle)
+static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle, int icon_only)
{
int flag= 0;
flag |= (slider)? UI_ITEM_R_SLIDER: 0;
flag |= (expand)? UI_ITEM_R_EXPAND: 0;
flag |= (toggle)? UI_ITEM_R_TOGGLE: 0;
-
+ flag |= (icon_only)? UI_ITEM_R_ICON_ONLY: 0;
+
uiItemR(layout, name, icon, ptr, propname, flag);
}
@@ -88,7 +89,7 @@ static void api_ui_item_rna_common(FunctionRNA *func)
PropertyRNA *parm;
parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property.");
- RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data.");
RNA_def_property_flag(parm, PROP_REQUIRED);
}
@@ -145,6 +146,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail.");
RNA_def_boolean(func, "slider", 0, "", "Use slider widget for numeric values.");
RNA_def_boolean(func, "toggle", 0, "", "Use toggle widget for boolean values.");
+ RNA_def_boolean(func, "icon_only", 0, "", "Draw only icons in buttons, no text.");
func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR");
api_ui_item_rna_common(func);
@@ -163,7 +165,7 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_common(func);
api_ui_item_rna_common(func);
parm= RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in.");
- RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
parm= RNA_def_string(func, "search_property", "", 0, "", "Identifier of search collection property.");
RNA_def_property_flag(parm, PROP_REQUIRED);
@@ -252,31 +254,29 @@ void RNA_api_ui_layout(StructRNA *srna)
func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
parm= RNA_def_pointer(func, "data", "Modifier", "", "Modifier data.");
- RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in.");
RNA_def_function_return(func, parm);
func= RNA_def_function(srna, "template_constraint", "uiTemplateConstraint");
parm= RNA_def_pointer(func, "data", "Constraint", "", "Constraint data.");
- RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in.");
RNA_def_function_return(func, parm);
func= RNA_def_function(srna, "template_preview", "uiTemplatePreview");
parm= RNA_def_pointer(func, "id", "ID", "", "ID datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "parent", "ID", "", "ID datablock.");
- parm= RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot.");
+ RNA_def_pointer(func, "parent", "ID", "", "ID datablock.");
+ RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot.");
func= RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping");
- parm= RNA_def_pointer(func, "curvemap", "CurveMapping", "", "Curve mapping pointer.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
+ api_ui_item_rna_common(func);
RNA_def_enum(func, "type", curve_type_items, 0, "Type", "Type of curves to display.");
- RNA_def_boolean(func, "compact", 0, "", "Use more compact curve mapping.");
+ RNA_def_boolean(func, "levels", 0, "", "Show black/white levels.");
func= RNA_def_function(srna, "template_color_ramp", "uiTemplateColorRamp");
- parm= RNA_def_pointer(func, "ramp", "ColorRamp", "", "Color ramp pointer.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
+ api_ui_item_rna_common(func);
RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail.");
func= RNA_def_function(srna, "template_layers", "uiTemplateLayers");
@@ -292,11 +292,21 @@ void RNA_api_ui_layout(StructRNA *srna)
parm= RNA_def_pointer(func, "image_user", "ImageUser", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- func= RNA_def_function(srna, "template_list", "uiTemplateList");
+ func= RNA_def_function(srna, "template_image", "uiTemplateImage");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
- parm= RNA_def_pointer(func, "active_data", "AnyType", "", "Data from which to take property for the active element.");
+ parm= RNA_def_pointer(func, "image_user", "ImageUser", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ RNA_def_boolean(func, "compact", 0, "", "Use more compact layout.");
+
+ func= RNA_def_function(srna, "template_list", "uiTemplateList");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property.");
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ parm= RNA_def_string(func, "property", "", 0, "", "Identifier of 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.");
+ 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.");
RNA_def_property_flag(parm, PROP_REQUIRED);
parm= RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display.", 0, INT_MAX);
@@ -314,11 +324,6 @@ void RNA_api_ui_layout(StructRNA *srna)
func= RNA_def_function(srna, "view3d_select_faceselmenu", "uiTemplate_view3d_select_faceselmenu");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
-
- func= RNA_def_function(srna, "template_texture_image", "uiTemplateTextureImage");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
- parm= RNA_def_pointer(func, "texture", "Texture", "", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 4825076528f..25448d0c2de 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -109,11 +109,6 @@ static PointerRNA rna_UserDef_edit_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesEdit, ptr->data);
}
-static PointerRNA rna_UserDef_language_get(PointerRNA *ptr)
-{
- return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesLanguage, ptr->data);
-}
-
static PointerRNA rna_UserDef_filepaths_get(PointerRNA *ptr)
{
return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesFilePaths, ptr->data);
@@ -197,25 +192,29 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna)
RNA_def_property_range(prop, 0.5, 2.0);
RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas.");
- prop= RNA_def_property(srna, "paneltitle", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "paneltitle", 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 Font", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "grouplabel", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "grouplabel", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "grouplabel");
RNA_def_property_struct_type(prop, "ThemeFontStyle");
RNA_def_property_ui_text(prop, "Group Label Font", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "widgetlabel", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "widgetlabel", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "widgetlabel");
RNA_def_property_struct_type(prop, "ThemeFontStyle");
RNA_def_property_ui_text(prop, "Widget Label Font", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "widget", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "widget", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "widget");
RNA_def_property_struct_type(prop, "ThemeFontStyle");
RNA_def_property_ui_text(prop, "Widget Font", "");
@@ -317,7 +316,7 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Driven Selected", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "blend", PROP_FLOAT, PROP_PERCENTAGE);
+ prop= RNA_def_property(srna, "blend", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_text(prop, "Blend", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
@@ -334,97 +333,113 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "ThemeUI");
RNA_def_struct_ui_text(srna, "Theme User Interface", "Theme settings for user interface elements.");
- prop= RNA_def_property(srna, "wcol_regular", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_regular", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_regular");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Regular Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_tool", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_tool", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_tool");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Tool Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_radio", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_radio", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_radio");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Radio Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_text", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_text", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_text");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Text Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_option", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_option", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_option");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Option Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_toggle");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Toggle Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_num");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Number Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_numslider", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_numslider", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_numslider");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Slider Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_box", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_box", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_box");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Box Backdrop Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_menu", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_menu", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Menu Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_pulldown", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_pulldown", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_pulldown");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Pulldown Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_menu_back", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_menu_back", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu_back");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Menu Backdrop Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_menu_item", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_menu_item", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu_item");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Menu Item Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_scroll");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "Scroll Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_list_item", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_list_item", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_list_item");
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
RNA_def_property_ui_text(prop, "List Item Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop= RNA_def_property(srna, "wcol_state", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "wcol_state", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "wcol_state");
RNA_def_property_struct_type(prop, "ThemeWidgetStateColors");
RNA_def_property_ui_text(prop, "State Colors", "");
@@ -1380,87 +1395,104 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "Name of the theme.");
RNA_def_struct_name_property(srna, prop);
- prop= RNA_def_property(srna, "user_interface", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "user_interface", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tui");
RNA_def_property_struct_type(prop, "ThemeUserInterface");
RNA_def_property_ui_text(prop, "User Interface", "");
- prop= RNA_def_property(srna, "view_3d", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "view_3d", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tv3d");
RNA_def_property_struct_type(prop, "ThemeView3D");
RNA_def_property_ui_text(prop, "3D View", "");
- prop= RNA_def_property(srna, "graph_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "graph_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tipo");
RNA_def_property_struct_type(prop, "ThemeGraphEditor");
RNA_def_property_ui_text(prop, "Graph Editor", "");
- prop= RNA_def_property(srna, "file_browser", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "file_browser", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tfile");
RNA_def_property_struct_type(prop, "ThemeFileBrowser");
RNA_def_property_ui_text(prop, "File Browser", "");
- prop= RNA_def_property(srna, "nla_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "nla_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tnla");
RNA_def_property_struct_type(prop, "ThemeNLAEditor");
RNA_def_property_ui_text(prop, "NLA Editor", "");
- prop= RNA_def_property(srna, "dopesheet_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "dopesheet_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tact");
RNA_def_property_struct_type(prop, "ThemeDopeSheet");
RNA_def_property_ui_text(prop, "DopeSheet", "");
- prop= RNA_def_property(srna, "image_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "image_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tima");
RNA_def_property_struct_type(prop, "ThemeImageEditor");
RNA_def_property_ui_text(prop, "Image Editor", "");
- prop= RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tseq");
RNA_def_property_struct_type(prop, "ThemeSequenceEditor");
RNA_def_property_ui_text(prop, "Sequence Editor", "");
- prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tbuts");
RNA_def_property_struct_type(prop, "ThemeProperties");
RNA_def_property_ui_text(prop, "Properties", "");
- prop= RNA_def_property(srna, "text_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "text_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "text");
RNA_def_property_struct_type(prop, "ThemeTextEditor");
RNA_def_property_ui_text(prop, "Text Editor", "");
- prop= RNA_def_property(srna, "timeline", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "timeline", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "ttime");
RNA_def_property_struct_type(prop, "ThemeTimeline");
RNA_def_property_ui_text(prop, "Timeline", "");
- prop= RNA_def_property(srna, "node_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "node_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tnode");
RNA_def_property_struct_type(prop, "ThemeNodeEditor");
RNA_def_property_ui_text(prop, "Node Editor", "");
- prop= RNA_def_property(srna, "logic_editor", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "logic_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tlogic");
RNA_def_property_struct_type(prop, "ThemeLogicEditor");
RNA_def_property_ui_text(prop, "Logic Editor", "");
- prop= RNA_def_property(srna, "outliner", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "outliner", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "toops");
RNA_def_property_struct_type(prop, "ThemeOutliner");
RNA_def_property_ui_text(prop, "Outliner", "");
- prop= RNA_def_property(srna, "info", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "info", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tinfo");
RNA_def_property_struct_type(prop, "ThemeInfo");
RNA_def_property_ui_text(prop, "Info", "");
- prop= RNA_def_property(srna, "user_preferences", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "user_preferences", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tuserpref");
RNA_def_property_struct_type(prop, "ThemeUserPreferences");
RNA_def_property_ui_text(prop, "User Preferences", "");
- prop= RNA_def_property(srna, "bone_color_sets", PROP_COLLECTION, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "bone_color_sets", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_collection_sdna(prop, NULL, "tarm", "");
RNA_def_property_struct_type(prop, "ThemeBoneColorSet");
RNA_def_property_ui_text(prop, "Bone Color Sets", "");
@@ -1531,6 +1563,16 @@ static void rna_def_userdef_view(BlenderRNA *brna)
{USER_ZOOM_DOLLY, "DOLLY", 0, "Dolly", "Zooms in and out based on vertical mouse movement."},
{USER_ZOOM_SCALE, "SCALE", 0, "Scale", "Zooms in and out like scaling the view, mouse movements relative to center."},
{0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem select_mouse_items[] = {
+ {USER_LMOUSESELECT, "LEFT", 0, "Left", "Use left Mouse Button for selection."},
+ {0, "RIGHT", 0, "Right", "Use Right Mouse Button for selection."},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem middle_mouse_mouse_items[] = {
+ {0, "PAN", 0, "Pan", "Use the middle mouse button for panning the viewport."},
+ {USER_VIEWMOVE, "ROTATE", 0, "Rotate", "Use the middle mouse button for rotation the viewport."},
+ {0, NULL, 0, NULL, NULL}};
static EnumPropertyItem view_rotation_items[] = {
{0, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport."},
@@ -1646,15 +1688,11 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Rotate Around Selection", "Use selection as the orbiting center.");
/* select with */
- prop= RNA_def_property(srna, "left_mouse_button_select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_LMOUSESELECT);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_userdef_lmb_select_set");
- RNA_def_property_ui_text(prop, "Left Mouse Button Select", "Use left Mouse Button for selection.");
- prop= RNA_def_property(srna, "right_mouse_button_select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_LMOUSESELECT);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_userdef_rmb_select_set");
- RNA_def_property_ui_text(prop, "Right Mouse Button Select", "Use Right Mouse Button for selection.");
+ prop= RNA_def_property(srna, "select_mouse", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, select_mouse_items);
+ RNA_def_property_ui_text(prop, "Select Mouse", "The mouse button used for selection.");
prop= RNA_def_property(srna, "emulate_3_button_mouse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_TWOBUTTONMOUSE);
@@ -1683,13 +1721,11 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
/* middle mouse button */
- prop= RNA_def_property(srna, "middle_mouse_rotate", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_VIEWMOVE);
- RNA_def_property_ui_text(prop, "Middle Mouse Rotate", "Use the middle mouse button for rotation the viewport.");
-
- prop= RNA_def_property(srna, "middle_mouse_pan", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_VIEWMOVE);
- RNA_def_property_ui_text(prop, "Middle Mouse Pan", "Use the middle mouse button for panning the viewport.");
+
+ prop= RNA_def_property(srna, "middle_mouse", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, middle_mouse_mouse_items);
+ RNA_def_property_ui_text(prop, "Middle Mouse", "Use the middle mouse button to pan or zoom the view.");
prop= RNA_def_property(srna, "wheel_invert_zoom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_WHEELZOOMDIR);
@@ -1766,28 +1802,38 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
{BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
{0, NULL, 0, NULL, NULL}};
+ static const EnumPropertyItem material_link_items[]= {
+ {0, "OBDATA", 0, "ObData", "Toggle whether the material is linked to object data or the object block."},
+ {USER_MAT_ON_OB, "OBJECT", 0, "Object", "Toggle whether the material is linked to object data or the object block."},
+ {0, NULL, 0, NULL, NULL}};
+
+ static const EnumPropertyItem object_align_items[]= {
+ {0, "WORLD", 0, "World", "Align newly added objects facing the 3D View direction"},
+ {USER_ADD_VIEWALIGNED, "VIEW", 0, "View", "Align newly added objects to the world coordinates"},
+ {0, NULL, 0, NULL, NULL}};
+
+
srna= RNA_def_struct(brna, "UserPreferencesEdit", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
RNA_def_struct_ui_text(srna, "Edit Methods", "Settings for interacting with Blender data.");
/* Edit Methods */
- prop= RNA_def_property(srna, "material_linked_object", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_MAT_ON_OB);
- RNA_def_property_ui_text(prop, "Material Linked Object", "Toggle whether the material is linked to object data or the object block.");
-
- prop= RNA_def_property(srna, "material_linked_obdata", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_MAT_ON_OB);
- RNA_def_property_ui_text(prop, "Material Linked ObData", "Toggle whether the material is linked to object data or the object block.");
+
+ prop= RNA_def_property(srna, "material_link", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, material_link_items);
+ RNA_def_property_ui_text(prop, "Material Link To", "Toggle whether the material is linked to object data or the object block");
+
+ prop= RNA_def_property(srna, "object_align", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, object_align_items);
+ RNA_def_property_ui_text(prop, "Align Object To", "Align newly added objects facing the 3D View direction or the world coordinates");
prop= RNA_def_property(srna, "enter_edit_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_ADD_EDITMODE);
RNA_def_property_ui_text(prop, "Enter Edit Mode", "Enter Edit Mode automatically after adding a new object.");
- prop= RNA_def_property(srna, "align_to_view", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_ADD_VIEWALIGNED);
- RNA_def_property_ui_text(prop, "Align To View", "Align newly added objects facing the 3D View direction.");
-
prop= RNA_def_property(srna, "drag_immediately", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_DRAGIMMEDIATE);
RNA_def_property_ui_text(prop, "Drag Immediately", "Moving things with a mouse drag doesn't require a click to confirm (Best for tablet users).");
@@ -1917,87 +1963,6 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Duplicate Particle", "Causes particle systems to be duplicated with the object.");
}
-static void rna_def_userdef_language(BlenderRNA *brna)
-{
- PropertyRNA *prop;
- StructRNA *srna;
-
- /* hardcoded here, could become dynamic somehow */
- static EnumPropertyItem language_items[] = {
- {0, "ENGLISH", 0, "English", ""},
- {1, "JAPANESE", 0, "Japanese", ""},
- {2, "DUTCH", 0, "Dutch", ""},
- {3, "ITALIAN", 0, "Italian", ""},
- {4, "GERMAN", 0, "German", ""},
- {5, "FINNISH", 0, "Finnish", ""},
- {6, "SWEDISH", 0, "Swedish", ""},
- {7, "FRENCH", 0, "French", ""},
- {8, "SPANISH", 0, "Spanish", ""},
- {9, "CATALAN", 0, "Catalan", ""},
- {10, "CZECH", 0, "Czech", ""},
- {11, "BRAZILIAN_PORTUGUESE", 0, "Brazilian Portuguese", ""},
- {12, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese", ""},
- {13, "RUSSIAN", 0, "Russian", ""},
- {14, "CROATIAN", 0, "Croatian", ""},
- {15, "SERBIAN", 0, "Serbian", ""},
- {16, "UKRAINIAN", 0, "Ukrainian", ""},
- {17, "POLISH", 0, "Polish", ""},
- {18, "ROMANIAN", 0, "Romanian", ""},
- {19, "ARABIC", 0, "Arabic", ""},
- {20, "BULGARIAN", 0, "Bulgarian", ""},
- {21, "GREEK", 0, "Greek", ""},
- {22, "KOREAN", 0, "Korean", ""},
- {0, NULL, 0, NULL, NULL}};
-
- srna= RNA_def_struct(brna, "UserPreferencesLanguage", NULL);
- RNA_def_struct_sdna(srna, "UserDef");
- RNA_def_struct_nested(brna, srna, "UserPreferences");
- RNA_def_struct_ui_text(srna, "Language & Font", "User interface translation settings.");
-
- prop= RNA_def_property(srna, "international_fonts", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE);
- RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
- prop= RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "dpi");
- RNA_def_property_range(prop, 48, 128);
- RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
- prop= RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "scrollback");
- RNA_def_property_range(prop, 32, 32768);
- RNA_def_property_ui_text(prop, "Scrollback", "Maximum number of lines to store for the console buffer.");
-
- /* Language Selection */
-
- prop= RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, language_items);
- RNA_def_property_ui_text(prop, "Language", "Language use for translation.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
- prop= RNA_def_property(srna, "translate_tooltips", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS);
- RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate Tooltips.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
- prop= RNA_def_property(srna, "translate_buttons", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_BUTTONS);
- RNA_def_property_ui_text(prop, "Translate Buttons", "Translate button labels.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
- prop= RNA_def_property(srna, "translate_toolbox", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_MENUS);
- RNA_def_property_ui_text(prop, "Translate Toolbox", "Translate toolbox menu.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
- prop= RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT);
- RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts.");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-}
-
static void rna_def_userdef_system(BlenderRNA *brna)
{
PropertyRNA *prop;
@@ -2073,12 +2038,84 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{USER_DRAW_OVERLAP, "OVERLAP", 0, "Overlap", "Redraw all overlapping regions, minimal memory usage but more redraws."},
{USER_DRAW_FULL, "FULL", 0, "Full", "Do a full redraw each time, slow, only use for reference or when all else fails."},
{0, NULL, 0, NULL, NULL}};
+
+ /* hardcoded here, could become dynamic somehow */
+ static EnumPropertyItem language_items[] = {
+ {0, "ENGLISH", 0, "English", ""},
+ {1, "JAPANESE", 0, "Japanese", ""},
+ {2, "DUTCH", 0, "Dutch", ""},
+ {3, "ITALIAN", 0, "Italian", ""},
+ {4, "GERMAN", 0, "German", ""},
+ {5, "FINNISH", 0, "Finnish", ""},
+ {6, "SWEDISH", 0, "Swedish", ""},
+ {7, "FRENCH", 0, "French", ""},
+ {8, "SPANISH", 0, "Spanish", ""},
+ {9, "CATALAN", 0, "Catalan", ""},
+ {10, "CZECH", 0, "Czech", ""},
+ {11, "BRAZILIAN_PORTUGUESE", 0, "Brazilian Portuguese", ""},
+ {12, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese", ""},
+ {13, "RUSSIAN", 0, "Russian", ""},
+ {14, "CROATIAN", 0, "Croatian", ""},
+ {15, "SERBIAN", 0, "Serbian", ""},
+ {16, "UKRAINIAN", 0, "Ukrainian", ""},
+ {17, "POLISH", 0, "Polish", ""},
+ {18, "ROMANIAN", 0, "Romanian", ""},
+ {19, "ARABIC", 0, "Arabic", ""},
+ {20, "BULGARIAN", 0, "Bulgarian", ""},
+ {21, "GREEK", 0, "Greek", ""},
+ {22, "KOREAN", 0, "Korean", ""},
+ {0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "UserPreferencesSystem", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
RNA_def_struct_ui_text(srna, "System & OpenGL", "Graphics driver and operating system settings.");
+ /* Language */
+
+ prop= RNA_def_property(srna, "international_fonts", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE);
+ RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "dpi");
+ RNA_def_property_range(prop, 48, 128);
+ RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "scrollback");
+ RNA_def_property_range(prop, 32, 32768);
+ RNA_def_property_ui_text(prop, "Scrollback", "Maximum number of lines to store for the console buffer.");
+
+ /* Language Selection */
+
+ prop= RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, language_items);
+ RNA_def_property_ui_text(prop, "Language", "Language use for translation.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "translate_tooltips", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS);
+ RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate Tooltips.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "translate_buttons", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_BUTTONS);
+ RNA_def_property_ui_text(prop, "Translate Buttons", "Translate button labels.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "translate_toolbox", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_MENUS);
+ RNA_def_property_ui_text(prop, "Translate Toolbox", "Translate toolbox menu.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT);
+ RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts.");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
/* System & OpenGL */
prop= RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE);
@@ -2090,7 +2127,8 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_CUSTOM_RANGE);
RNA_def_property_ui_text(prop, "Use Weight Color Range", "Enable color range used for weight visualization in weight painting mode.");
- prop= RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "coba_weight");
RNA_def_property_struct_type(prop, "ColorRamp");
RNA_def_property_ui_text(prop, "Weight Color Range", "Color range used for weight visualization in weight painting mode.");
@@ -2126,14 +2164,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_SOUND);
RNA_def_property_ui_text(prop, "Game Sound", "Enables sounds to be played in games.");
- prop= RNA_def_property(srna, "filter_file_extensions", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_FILTERFILEEXTS);
- RNA_def_property_ui_text(prop, "Filter File Extensions", "Display only files with extensions in the image select window.");
-
- prop= RNA_def_property(srna, "hide_dot_files_datablocks", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_HIDE_DOT);
- RNA_def_property_ui_text(prop, "Hide Dot Files/Datablocks", "Hide files/datablocks that start with a dot(.*)");
-
prop= RNA_def_property(srna, "clip_alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "glalphaclip");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -2217,7 +2247,15 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
RNA_def_struct_ui_text(srna, "File Paths", "Default paths for external files.");
-
+
+ prop= RNA_def_property(srna, "hide_dot_files_datablocks", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_HIDE_DOT);
+ RNA_def_property_ui_text(prop, "Hide Dot Files/Datablocks", "Hide files/datablocks that start with a dot(.*)");
+
+ prop= RNA_def_property(srna, "filter_file_extensions", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_FILTERFILEEXTS);
+ RNA_def_property_ui_text(prop, "Filter File Extensions", "Display only files with extensions in the image select window.");
+
prop= RNA_def_property(srna, "use_relative_paths", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_RELPATHS);
RNA_def_property_ui_text(prop, "Relative Paths", "Default relative path option for the file selector.");
@@ -2296,10 +2334,9 @@ void RNA_def_userdef(BlenderRNA *brna)
static EnumPropertyItem user_pref_sections[] = {
{0, "VIEW_CONTROLS", 0, "View", ""},
{1, "EDIT_METHODS", 0, "Editing", ""},
- {2, "LANGUAGE_COLORS", 0, "Language", ""},
+ {2, "FILE_PATHS", 0, "File", ""},
{3, "SYSTEM_OPENGL", 0, "System", ""},
- {4, "FILE_PATHS", 0, "File", ""},
- {5, "THEMES", 0, "Themes", ""},
+// {4, "THEMES", 0, "Themes", ""}, // Leave this out until we figure out a way to manage themes in the prefs.
{0, NULL, 0, NULL, NULL}};
rna_def_userdef_dothemes(brna);
@@ -2325,34 +2362,32 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Styles", "");
/* nested structs */
- prop= RNA_def_property(srna, "view", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "view", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesView");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_view_get", NULL, NULL);
RNA_def_property_ui_text(prop, "View & Controls", "Preferences related to viewing data.");
- prop= RNA_def_property(srna, "edit", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "edit", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesEdit");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_edit_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Edit Methods", "Settings for interacting with Blender data.");
- prop= RNA_def_property(srna, "language", PROP_POINTER, PROP_NEVER_NULL);
- RNA_def_property_struct_type(prop, "UserPreferencesLanguage");
- RNA_def_property_pointer_funcs(prop, "rna_UserDef_language_get", NULL, NULL);
- RNA_def_property_ui_text(prop, "Language & Font", "User interface translation settings.");
-
- prop= RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesFilePaths");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_filepaths_get", NULL, NULL);
RNA_def_property_ui_text(prop, "File Paths", "Default paths for external files.");
- prop= RNA_def_property(srna, "system", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "system", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesSystem");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_system_get", NULL, NULL);
RNA_def_property_ui_text(prop, "System & OpenGL", "Graphics driver and operating system settings.");
rna_def_userdef_view(brna);
rna_def_userdef_edit(brna);
- rna_def_userdef_language(brna);
rna_def_userdef_filepaths(brna);
rna_def_userdef_system(brna);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index af3ac4a0a82..0dd9e3aed42 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -46,6 +46,8 @@ EnumPropertyItem event_type_items[] = {
{LEFTMOUSE, "LEFTMOUSE", 0, "Left Mouse", ""},
{MIDDLEMOUSE, "MIDDLEMOUSE", 0, "Middle Mouse", ""},
{RIGHTMOUSE, "RIGHTMOUSE", 0, "Right Mouse", ""},
+ {BUTTON4MOUSE, "BUTTON4MOUSE", 0, "Button4 Mouse", ""},
+ {BUTTON5MOUSE, "BUTTON5MOUSE", 0, "Button5 Mouse", ""},
{ACTIONMOUSE, "ACTIONMOUSE", 0, "Action Mouse", ""},
{SELECTMOUSE, "SELECTMOUSE", 0, "Select Mouse", ""},
@@ -197,7 +199,7 @@ static StructRNA *rna_OperatorProperties_refine(PointerRNA *ptr)
return ptr->type;
}
-IDProperty *rna_OperatorProperties_idproperties(PointerRNA *ptr, int create)
+static IDProperty *rna_OperatorProperties_idproperties(PointerRNA *ptr, int create)
{
if(create && !ptr->data) {
IDPropertyTemplate val = {0};
@@ -278,7 +280,8 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
- prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "OperatorProperties");
RNA_def_property_ui_text(prop, "Properties", "");
RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL);
@@ -404,7 +407,8 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Window", "Open window.");
RNA_def_struct_sdna(srna, "wmWindow");
- prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "Screen");
RNA_def_property_ui_text(prop, "Screen", "Active screen showing in the window.");
RNA_def_property_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 0ed5016ccd2..b2ed90eef03 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -34,14 +34,17 @@
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
-#include "WM_types.h"
-
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
+#include "BKE_depsgraph.h"
+#include "BKE_main.h"
#include "BKE_texture.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
static PointerRNA rna_World_ambient_occlusion_get(PointerRNA *ptr)
{
return rna_pointer_inherit_refine(ptr, &RNA_WorldAmbientOcclusion, ptr->id.data);
@@ -95,6 +98,22 @@ static void rna_World_active_texture_set(PointerRNA *ptr, PointerRNA value)
}
}
+static void rna_World_update(bContext *C, PointerRNA *ptr)
+{
+ World *wo= ptr->id.data;
+
+ DAG_id_flush_update(&wo->id, 0);
+ WM_event_add_notifier(C, NC_WORLD, wo);
+}
+
+static void rna_World_draw_update(bContext *C, PointerRNA *ptr)
+{
+ World *wo= ptr->id.data;
+
+ DAG_id_flush_update(&wo->id, 0);
+ WM_event_add_notifier(C, NC_WORLD|ND_WORLD_DRAW, wo);
+}
+
#else
static void rna_def_world_mtex(BlenderRNA *brna)
@@ -119,22 +138,22 @@ static void rna_def_world_mtex(BlenderRNA *brna)
prop= RNA_def_property(srna, "map_blend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_BLEND);
RNA_def_property_ui_text(prop, "Blend", "Affect the color progression of the background.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "map_horizon", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_HORIZ);
RNA_def_property_ui_text(prop, "Horizon", "Affect the color of the horizon.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "map_zenith_up", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_ZENUP);
RNA_def_property_ui_text(prop, "Zenith Up", "Affect the color of the zenith above.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "map_zenith_down", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_ZENDOWN);
RNA_def_property_ui_text(prop, "Zenith Down", "Affect the color of the zenith below.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
/* unused
prop= RNA_def_property(srna, "map_mist", PROP_BOOLEAN, PROP_NONE);
@@ -145,38 +164,38 @@ static void rna_def_world_mtex(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "texco");
RNA_def_property_enum_items(prop, texco_items);
RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used to map the texture onto the background.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object");
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "blend_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "varfac");
+ RNA_def_property_float_sdna(prop, NULL, "blendfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Blend Factor", "Amount texture affects color progression of the background.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "horizon_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Horizon Factor", "Amount texture affects color of the horizon.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "zenith_up_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_float_sdna(prop, NULL, "zenupfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Zenith Up Factor", "Amount texture affects color of the zenith above.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "zenith_down_factor", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_float_sdna(prop, NULL, "zendownfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Zenith Down Factor", "Amount texture affects color of the zenith below.");
- RNA_def_property_update(prop, NC_TEXTURE, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
}
static void rna_def_ambient_occlusion(BlenderRNA *brna)
@@ -215,83 +234,100 @@ static void rna_def_ambient_occlusion(BlenderRNA *brna)
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_AMB_OCC);
RNA_def_property_ui_text(prop, "Enabled", "Use Ambient Occlusion to add light based on distance between elements, creating the illusion of omnipresent light");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "aodist");
RNA_def_property_ui_text(prop, "Distance", "Length of rays, defines how far away other faces give occlusion effect.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "falloff_strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "aodistfac");
RNA_def_property_ui_text(prop, "Strength", "Distance attenuation factor, the higher, the 'shorter' the shadows.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "aoenergy");
RNA_def_property_ui_range(prop, 0, 10, 0.1, 3);
RNA_def_property_ui_text(prop, "Energy", "Amount of enerygy generated by ambient occlusion.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "bias", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "aobias");
RNA_def_property_range(prop, 0, 0.5);
RNA_def_property_ui_text(prop, "Bias", "Bias (in radians) to prevent smoothed faces from showing banding (for Raytrace Constant Jittered).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ao_adapt_thresh");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Threshold", "Samples below this threshold will be considered fully shadowed/unshadowed and skipped (for Raytrace Adaptive QMC).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "adapt_to_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ao_adapt_speed_fac");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Adapt To Speed", "Use the speed vector pass to reduce AO samples in fast moving pixels. Higher values result in more aggressive sample reduction. Requires Vec pass enabled (for Raytrace Adaptive QMC).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "error_tolerance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ao_approx_error");
RNA_def_property_range(prop, 0.0001, 10);
RNA_def_property_ui_text(prop, "Error Tolerance", "Low values are slower and higher quality (for Approximate).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "correction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ao_approx_correction");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_range(prop, 0, 1, 0.1, 2);
RNA_def_property_ui_text(prop, "Correction", "Ad-hoc correction for over-occlusion due to the approximation (for Approximate).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "falloff", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "aomode", WO_AODIST);
RNA_def_property_ui_text(prop, "Falloff", "");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "pixel_cache", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "aomode", WO_AOCACHE);
RNA_def_property_ui_text(prop, "Pixel Cache", "Cache AO results in pixels and interpolate over neighbouring pixels for speedup (for Approximate).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "aosamp");
RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "Samples", "Amount of ray samples. Higher values give smoother results and longer rendering times");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "blend_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "aomix");
RNA_def_property_enum_items(prop, blend_mode_items);
RNA_def_property_ui_text(prop, "Blend Mode", "Defines how AO mixes with material shading.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "color", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "aocolor");
RNA_def_property_enum_items(prop, prop_color_items);
RNA_def_property_ui_text(prop, "Color", "Defines the color of the AO light");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "sample_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ao_samp_method");
RNA_def_property_enum_items(prop, prop_sample_method_items);
RNA_def_property_ui_text(prop, "Sample Method", "Method for generating shadow samples (for Raytrace).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "gather_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ao_gather_method");
RNA_def_property_enum_items(prop, prop_gather_method_items);
RNA_def_property_ui_text(prop, "Gather Method", "");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "passes", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ao_approx_passes");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Passes", "Number of preprocessing passes to reduce overocclusion (for Approximate).");
+ RNA_def_property_update(prop, 0, "rna_World_update");
}
static void rna_def_world_mist(BlenderRNA *brna)
@@ -313,35 +349,39 @@ static void rna_def_world_mist(BlenderRNA *brna)
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_MIST);
RNA_def_property_ui_text(prop, "Enabled", "Occlude objects with the environment color as they are further away.");
+ RNA_def_property_update(prop, 0, "rna_World_draw_update");
prop= RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "misi");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Intensity", "Intensity of the mist effect.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "miststa");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 10000, 10, 2);
RNA_def_property_ui_text(prop, "Start", "Starting distance of the mist, measured from the camera");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_draw_update");
prop= RNA_def_property(srna, "depth", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "mistdist");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 10000, 10, 2);
RNA_def_property_ui_text(prop, "Depth", "The distance over which the mist effect fades in");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_draw_update");
prop= RNA_def_property(srna, "height", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "misthi");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Height", "Control how much mist density decreases with height");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mistype");
RNA_def_property_enum_items(prop, falloff_items);
RNA_def_property_ui_text(prop, "Falloff", "Type of transition used to fade mist");
+ RNA_def_property_update(prop, 0, "rna_World_update");
}
static void rna_def_world_stars(BlenderRNA *brna)
@@ -357,37 +397,38 @@ static void rna_def_world_stars(BlenderRNA *brna)
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_STARS);
RNA_def_property_ui_text(prop, "Enabled", "Enable starfield generation.");
- RNA_def_property_update(prop, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "starsize");
RNA_def_property_range(prop, 0, 10);
RNA_def_property_ui_text(prop, "Size", "Average screen dimension of stars.");
- RNA_def_property_update(prop, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "min_distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "starmindist");
RNA_def_property_range(prop, 0, 1000);
RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance to the camera for stars.");
- RNA_def_property_update(prop, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "average_separation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stardist");
RNA_def_property_range(prop, 2, 1000);
RNA_def_property_ui_text(prop, "Average Separation", "Average distance between any two stars.");
- RNA_def_property_update(prop, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "color_randomization", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "starcolnoise");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Color Randomization", "Randomize star colors.");
- RNA_def_property_update(prop, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
/* unused
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "starr");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Color", "Stars color.");*/
+ RNA_def_property_ui_text(prop, "Color", "Stars color.");
+ RNA_def_property_update(prop, 0, "rna_World_update");*/
}
void RNA_def_world(BlenderRNA *brna)
@@ -412,65 +453,71 @@ void RNA_def_world(BlenderRNA *brna)
rna_def_animdata_common(srna);
rna_def_mtex_common(srna, "rna_World_mtex_begin", "rna_World_active_texture_get",
- "rna_World_active_texture_set", "WorldTextureSlot");
+ "rna_World_active_texture_set", "WorldTextureSlot", "rna_World_update");
/* colors */
prop= RNA_def_property(srna, "horizon_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "horr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Horizon Color", "Color at the horizon.");
- RNA_def_property_update(prop, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "zenith_color", PROP_FLOAT, PROP_COLOR);
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, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "ambr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Ambient Color", "");
+ RNA_def_property_update(prop, 0, "rna_World_update");
/* exp, range */
prop= RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "exp");
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_ui_text(prop, "Exposure", "Amount of exponential color correction for light.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "range", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "range");
RNA_def_property_range(prop, 0.2, 5.0);
RNA_def_property_ui_text(prop, "Range", "The color range that will be mapped to 0-1.");
+ RNA_def_property_update(prop, 0, "rna_World_update");
/* sky type */
prop= RNA_def_property(srna, "blend_sky", 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, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "paper_sky", 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, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
prop= RNA_def_property(srna, "real_sky", 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, NC_WORLD, NULL);
+ RNA_def_property_update(prop, 0, "rna_World_update");
/* nested structs */
- prop= RNA_def_property(srna, "ambient_occlusion", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "ambient_occlusion", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "WorldAmbientOcclusion");
RNA_def_property_pointer_funcs(prop, "rna_World_ambient_occlusion_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Ambient Occlusion", "World ambient occlusion settings.");
- prop= RNA_def_property(srna, "mist", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "mist", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "WorldMistSettings");
RNA_def_property_pointer_funcs(prop, "rna_World_mist_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Mist", "World mist settings.");
- prop= RNA_def_property(srna, "stars", PROP_POINTER, PROP_NEVER_NULL);
+ prop= RNA_def_property(srna, "stars", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "WorldStarsSettings");
RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Stars", "World stars settings.");
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index df2567142ca..58bee7e3acf 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -34,6 +34,10 @@ SET(INC
${ZLIB_INC}
)
+IF(WIN32)
+ SET(INC ${INC} ${PTHREADS_INC})
+ENDIF(WIN32)
+
IF(WITH_OPENEXR)
ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript
index 771ce42e1dc..01319dc1eb4 100644
--- a/source/blender/nodes/SConscript
+++ b/source/blender/nodes/SConscript
@@ -38,6 +38,13 @@ if env['WITH_BF_QUICKTIME']:
defs.append('WITH_QUICKTIME')
incs += ' ' + env['BF_QUICKTIME_INC']
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [190,105] )
env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] )
env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] )
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c
index ee9545c3196..800cccc2bfc 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c
@@ -50,7 +50,8 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
RenderData *rd= data;
if(scene && (rd->scemode & R_DOCOMP)) {
- RenderResult *rr= RE_GetResult(RE_GetRender(scene->id.name));
+ Render *re= RE_GetRender(scene->id.name);
+ RenderResult *rr= RE_AcquireResultWrite(re);
if(rr) {
CompBuf *outbuf, *zbuf=NULL;
@@ -78,11 +79,15 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
rr->rectf= outbuf->rect;
outbuf->malloc= 0;
free_compbuf(outbuf);
+
+ RE_ReleaseResult(re);
/* signal for imageviewer to refresh (it converts to byte rects...) */
BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
return;
}
+ else
+ RE_ReleaseResult(re);
}
}
if(in[0]->data)
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c
index 5f444357776..00be52a81aa 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c
@@ -350,11 +350,12 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out
static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
Scene *sce= (Scene *)node->id;
+ Render *re= (sce)? RE_GetRender(sce->id.name): NULL;
RenderData *rd= data;
RenderResult *rr= NULL;
- if(sce)
- rr= RE_GetResult(RE_GetRender(sce->id.name));
+ if(re)
+ rr= RE_AcquireResultRead(re);
if(rr) {
SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
@@ -389,7 +390,10 @@ static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in,
}
}
}
- }
+ }
+
+ if(re)
+ RE_ReleaseResult(re);
};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c
index 28b769a8a97..6056e9a28f4 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c
@@ -329,8 +329,8 @@ bNodeType cmp_node_view_levels= {
/* execfunc */ node_composit_exec_view_levels,
/* butfunc */ NULL,
/* initfunc */ node_composit_init_view_levels,
- /* freestoragefunc */ node_free_standard_storage,
- /* copystoragefunc */ node_copy_standard_storage,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
/* id */ NULL
};
diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c
index b396d5549d7..075eefb4368 100644
--- a/source/blender/nodes/intern/CMP_util.c
+++ b/source/blender/nodes/intern/CMP_util.c
@@ -614,7 +614,9 @@ void generate_preview(bNode *node, CompBuf *stackbuf)
if(stackbuf->rect==NULL && stackbuf->rect_procedural==NULL) return;
stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA);
-
+
+ BLI_lock_thread(LOCK_PREVIEW);
+
if(stackbuf->x > stackbuf->y) {
preview->xsize= 140;
preview->ysize= (140*stackbuf->y)/stackbuf->x;
@@ -628,14 +630,15 @@ void generate_preview(bNode *node, CompBuf *stackbuf)
cbuf= generate_procedural_preview(stackbuf_use, preview->xsize, preview->ysize);
else
cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize);
-
+
/* this ensures free-compbuf does the right stuff */
SWAP(float *, cbuf->rect, node->preview->rect);
+
+ BLI_unlock_thread(LOCK_PREVIEW);
free_compbuf(cbuf);
if(stackbuf_use!=stackbuf)
free_compbuf(stackbuf_use);
-
}
}
diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c
index 2c21627dad9..f2333ffcf2e 100644
--- a/source/blender/nodes/intern/TEX_util.c
+++ b/source/blender/nodes/intern/TEX_util.c
@@ -47,8 +47,6 @@
#define PREV_RES 128 /* default preview resolution */
-int preview_flag = 0;
-
void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
{
if(dg->node->need_exec)
@@ -217,7 +215,8 @@ void ntreeTexExecTree(
short thread,
Tex *tex,
short which_output,
- int cfra
+ int cfra,
+ int preview
){
TexResult dummy_texres;
TexCallData data;
@@ -231,21 +230,14 @@ void ntreeTexExecTree(
data.dxt = dxt;
data.dyt = dyt;
data.target = texres;
- data.do_preview = preview_flag;
+ data.do_preview = preview;
data.thread = thread;
data.which_output = which_output;
data.cfra= cfra;
- preview_flag = 0;
-
ntreeExecTree(nodes, &data, thread);
}
-void ntreeTexSetPreviewFlag(int doit)
-{
- preview_flag = doit;
-}
-
char* ntreeTexOutputMenu(bNodeTree *ntree)
{
bNode *node;
diff --git a/source/blender/nodes/intern/TEX_util.h b/source/blender/nodes/intern/TEX_util.h
index 87a9cf288d6..fd3d47f4729 100644
--- a/source/blender/nodes/intern/TEX_util.h
+++ b/source/blender/nodes/intern/TEX_util.h
@@ -102,8 +102,6 @@ float tex_input_value(bNodeStack *in, TexParams *params, short thread);
void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn);
void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata);
-void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, float *dxt, float *dyt, short thread, struct Tex *tex, short which_output, int cfra);
-
void params_from_cdata(TexParams *out, TexCallData *in);
#endif
diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py
index c2ef6bbc0d0..4ff5c8102e2 100644
--- a/source/blender/python/epy_doc_gen.py
+++ b/source/blender/python/epy_doc_gen.py
@@ -225,7 +225,7 @@ def write_func(rna, ident, out, func_type):
elif rna_prop_type=='float':
if length==0:
val_str= '%g' % val
- if '.' not in val_str:
+ if '.' not in val_str and '-' not in val_str: # value could be 1e-05
val_str += '.0'
else:
# array
diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c
index 32262276d0a..431f1987383 100644
--- a/source/blender/python/generic/Mathutils.c
+++ b/source/blender/python/generic/Mathutils.c
@@ -437,7 +437,7 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
mat[8] = 1.0f;
} else if((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) {
//arbitrary rotation
- AxisAngleToMat3(vec->vec, angle, (float *)mat);
+ AxisAngleToMat3(vec->vec, angle, (float (*)[3])mat);
} else {
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n");
@@ -912,7 +912,7 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
return NULL;
}
- if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) {
+ if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
return NULL;
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index a85bcd011a6..d0829acd6cc 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -147,6 +147,17 @@ void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate)
}
}
+static void bpy_import_test(char *modname)
+{
+ PyObject *mod= PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
+ if(mod) {
+ Py_DECREF(mod);
+ }
+ else {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+}
void BPY_free_compiled_text( struct Text *text )
{
@@ -176,7 +187,21 @@ static void bpy_init_modules( void )
PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
Py_DECREF(mod);
-
+ /* add our own modules dir */
+ {
+ char *modpath= BLI_gethome_folder("scripts/modules", BLI_GETHOME_ALL);
+
+ if(modpath) {
+ PyObject *sys_path= PySys_GetObject("path"); /* borrow */
+ PyObject *py_modpath= PyUnicode_FromString(modpath);
+ PyList_Insert(sys_path, 0, py_modpath); /* add first */
+ Py_DECREF(py_modpath);
+ }
+
+ bpy_import_test("bpy_ops"); /* adds its self to bpy.ops */
+ bpy_import_test("bpy_sys"); /* adds its self to bpy.sys */
+ }
+
/* stand alone utility modules not related to blender directly */
Geometry_Init();
Mathutils_Init();
@@ -232,26 +257,10 @@ static PyObject *CreateGlobalDictionary( bContext *C )
return dict;
}
-/* Use this so we can include our own python bundle */
-#if 0
-wchar_t* Py_GetPath(void)
-{
- int i;
- static wchar_t py_path[FILE_MAXDIR] = L"";
- char *dirname= BLI_gethome_folder("python");
- if(dirname) {
- i= mbstowcs(py_path, dirname, FILE_MAXDIR);
- printf("py path %s, %d\n", dirname, i);
- }
- return py_path;
-}
-#endif
-
-
/* must be called before Py_Initialize */
void BPY_start_python_path(void)
{
- char *py_path_bundle= BLI_gethome_folder("python");
+ char *py_path_bundle= BLI_gethome_folder("python", BLI_GETHOME_ALL);
if(py_path_bundle==NULL)
return;
@@ -259,8 +268,17 @@ void BPY_start_python_path(void)
/* set the environment path */
printf("found bundled python: %s\n", py_path_bundle);
+#if 0
BLI_setenv("PYTHONHOME", py_path_bundle);
BLI_setenv("PYTHONPATH", py_path_bundle);
+#endif
+
+ {
+ static wchar_t py_path_bundle_wchar[FILE_MAXDIR];
+
+ mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR);
+ Py_SetPythonHome(py_path_bundle_wchar);
+ }
}
@@ -299,6 +317,11 @@ void BPY_start_python( int argc, char **argv )
PyObject *d = PyEval_GetBuiltins( );
PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item);
+
+ /* a bit nasty but this prevents help() and input() from locking blender
+ * Ideally we could have some way for the console to replace sys.stdin but
+ * python would lock blender while waiting for a return value, not easy :| */
+ PySys_SetObject("stdin", Py_None);
}
pyrna_alloc_types();
@@ -579,8 +602,9 @@ void BPY_run_ui_scripts(bContext *C, int reload)
char *file_extension;
char *dirname;
char path[FILE_MAX];
- char *dirs[] = {"ui", "io", NULL};
- int a, err;
+ char *dirs[] = {"scripts/ui", "scripts/io", NULL};
+ int path_flags[] = {BLI_GETHOME_LOCAL|BLI_GETHOME_SYSTEM, BLI_GETHOME_USER}; /* SYSTEM / NON-SYSTEM */
+ int a, err, flag_iter;
PyGILState_STATE gilstate;
PyObject *sys_path;
@@ -590,56 +614,60 @@ void BPY_run_ui_scripts(bContext *C, int reload)
sys_path= PySys_GetObject("path"); /* borrow */
PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
- for(a=0; dirs[a]; a++) {
- dirname= BLI_gethome_folder(dirs[a]);
+ /* Scan system scripts first, then local/user */
+ for(flag_iter=0; flag_iter < sizeof(path_flags)/sizeof(int); flag_iter++) {
+
+ for(a=0; dirs[a]; a++) {
+ dirname= BLI_gethome_folder(dirs[a], path_flags[flag_iter]);
- if(!dirname)
- continue;
+ if(!dirname)
+ continue;
- dir = opendir(dirname);
+ dir = opendir(dirname);
- if(!dir)
- continue;
-
- /* set the first dir in the sys.path for fast importing of modules */
- PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */
+ if(!dir)
+ continue;
- while((de = readdir(dir)) != NULL) {
- /* We could stat the file but easier just to let python
- * import it and complain if theres a problem */
- err = 0;
-
- if (de->d_name[0] == '.') {
- /* do nothing, probably .svn */
- }
- else if ((file_extension = strstr(de->d_name, ".py"))) {
- /* normal py files? */
- if(file_extension && file_extension[3] == '\0') {
- de->d_name[(file_extension - de->d_name)] = '\0';
- err= bpy_import_module(de->d_name, reload);
+ /* set the first dir in the sys.path for fast importing of modules */
+ PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */
+
+ while((de = readdir(dir)) != NULL) {
+ /* We could stat the file but easier just to let python
+ * import it and complain if theres a problem */
+ err = 0;
+
+ if (de->d_name[0] == '.') {
+ /* do nothing, probably .svn */
+ }
+ else if ((file_extension = strstr(de->d_name, ".py"))) {
+ /* normal py files? */
+ if(file_extension && file_extension[3] == '\0') {
+ de->d_name[(file_extension - de->d_name)] = '\0';
+ err= bpy_import_module(de->d_name, reload);
+ }
}
- }
#ifndef __linux__
- else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) {
+ else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) {
#else
- else if(de->d_type==DT_DIR) {
- BLI_join_dirfile(path, dirname, de->d_name);
+ else if(de->d_type==DT_DIR) {
+ BLI_join_dirfile(path, dirname, de->d_name);
#endif
- /* support packages */
- BLI_join_dirfile(path, path, "__init__.py");
+ /* support packages */
+ BLI_join_dirfile(path, path, "__init__.py");
- if(BLI_exists(path)) {
- err= bpy_import_module(de->d_name, reload);
+ if(BLI_exists(path)) {
+ err= bpy_import_module(de->d_name, reload);
+ }
}
- }
- if(err==-1) {
- BPy_errors_to_report(NULL);
- fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name);
+ if(err==-1) {
+ BPy_errors_to_report(NULL);
+ fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name);
+ }
}
- }
- closedir(dir);
+ closedir(dir);
+ }
}
PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 062db42e0e9..301204d3e2b 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -65,7 +65,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
return NULL;
}
- if(ot->poll && (ot->poll(C) == FALSE)) {
+ if(WM_operator_poll((bContext*)C, ot) == FALSE) {
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
return NULL;
}
@@ -79,16 +79,31 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
if (error_val==0) {
- ReportList reports;
+ ReportList *reports;
- BKE_reports_init(&reports, RPT_STORE);
+ reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
+ BKE_reports_init(reports, RPT_STORE);
- WM_operator_call_py(C, ot, context, &ptr, &reports);
+ WM_operator_call_py(C, ot, context, &ptr, reports);
- if(BPy_reports_to_error(&reports))
+ if(BPy_reports_to_error(reports))
error_val = -1;
- BKE_reports_clear(&reports);
+ /* operator output is nice to have in the terminal/console too */
+ if(reports->list.first) {
+ char *report_str= BKE_reports_string(reports, 0); /* all reports */
+
+ if(report_str) {
+ PySys_WriteStdout(report_str);
+ MEM_freeN(report_str);
+ }
+ }
+
+ BKE_reports_clear(reports);
+ if ((reports->flag & RPT_FREE) == 0)
+ {
+ MEM_freeN(reports);
+ }
}
WM_operator_properties_free(&ptr);
@@ -113,6 +128,58 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
Py_RETURN_NONE;
}
+static PyObject *pyop_as_string( PyObject * self, PyObject * args)
+{
+ wmOperatorType *ot;
+ PointerRNA ptr;
+
+ char *opname;
+ PyObject *kw= NULL; /* optional args */
+ int all_args = 1;
+ int error_val= 0;
+
+ char *buf;
+ PyObject *pybuf;
+
+ bContext *C = BPy_GetContext();
+
+ 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);
+
+ if (ot == NULL) {
+ PyErr_Format( PyExc_SystemError, "bpy.__ops__.as_string: operator \"%s\"could not be found", opname);
+ return NULL;
+ }
+
+ /* WM_operator_properties_create(&ptr, opname); */
+ /* Save another lookup */
+ RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
+
+ if(kw && PyDict_Size(kw))
+ error_val= pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");
+
+ if (error_val==0)
+ buf= WM_operator_pystring(C, ot, &ptr, all_args);
+
+ WM_operator_properties_free(&ptr);
+
+ if (error_val==-1) {
+ return NULL;
+ }
+
+ if(buf) {
+ pybuf= PyUnicode_FromString(buf);
+ MEM_freeN(buf);
+ }
+ else {
+ pybuf= PyUnicode_FromString("");
+ }
+
+ return pybuf;
+}
+
static PyObject *pyop_dir(PyObject *self)
{
PyObject *list = PyList_New(0), *name;
@@ -157,6 +224,7 @@ static PyObject *pyop_getrna(PyObject *self, PyObject *value)
PyObject *BPY_operator_module( void )
{
static PyMethodDef pyop_call_meth = {"call", (PyCFunction) pyop_call, METH_VARARGS, NULL};
+ static PyMethodDef pyop_as_string_meth ={"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL};
static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL};
static PyMethodDef pyop_getrna_meth = {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL};
static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL};
@@ -166,6 +234,7 @@ PyObject *BPY_operator_module( void )
PyDict_SetItemString(PySys_GetObject("modules"), "bpy.__ops__", submodule);
PyModule_AddObject( submodule, "call", PyCFunction_New(&pyop_call_meth, NULL) );
+ PyModule_AddObject( submodule, "as_string",PyCFunction_New(&pyop_as_string_meth,NULL) );
PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) );
PyModule_AddObject( submodule, "get_rna", PyCFunction_New(&pyop_getrna_meth, NULL) );
PyModule_AddObject( submodule, "add", PyCFunction_New(&pyop_add_meth, NULL) );
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 0a487a8dbe8..bbf657d8ce0 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -81,9 +81,9 @@ static struct BPY_flag_def pyop_ret_flags[] = {
extern void BPY_update_modules( void ); //XXX temp solution
-static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
+static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event)
{
- PyObject *py_class = op->type->pyop_data;
+ PyObject *py_class = ot->pyop_data;
PyObject *args;
PyObject *ret= NULL, *py_class_instance, *item= NULL;
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
@@ -105,7 +105,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
/* Assign instance attributes from operator properties */
- {
+ if(op) {
const char *arg_name;
RNA_STRUCT_BEGIN(op->ptr, prop) {
@@ -121,10 +121,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
}
/* set operator pointer RNA as instance "__operator__" attribute */
- RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
- py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
- PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
- Py_DECREF(py_operator);
+ if(op) {
+ RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
+ py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
+ PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
+ Py_DECREF(py_operator);
+ }
RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
@@ -148,8 +150,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
else if (mode==PYOP_POLL) {
item= PyObject_GetAttrString(py_class, "poll");
args = PyTuple_New(2);
- //XXX Todo - wrap context in a useful way, None for now.
- PyTuple_SET_ITEM(args, 1, Py_None);
+ PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
}
PyTuple_SET_ITEM(args, 0, py_class_instance);
@@ -160,21 +161,24 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
}
if (ret == NULL) { /* covers py_class_instance failing too */
- BPy_errors_to_report(op->reports);
+ if(op)
+ BPy_errors_to_report(op->reports);
}
else {
if (mode==PYOP_POLL) {
if (PyBool_Check(ret) == 0) {
PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
- BPy_errors_to_report(op->reports);
+ if(op)
+ BPy_errors_to_report(op->reports);
}
else {
ret_flag= ret==Py_True ? 1:0;
}
} else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
- /* the returned value could not be converted into a flag */
- BPy_errors_to_report(op->reports);
+ /* the returned value could not be converted into a flag */
+ if(op)
+ BPy_errors_to_report(op->reports);
ret_flag = OPERATOR_CANCELLED;
}
@@ -225,19 +229,17 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);
+ return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event);
}
static int PYTHON_OT_execute(bContext *C, wmOperator *op)
{
- return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
+ return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL);
}
-static int PYTHON_OT_poll(bContext *C)
+static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
{
- // XXX TODO - no way to get the operator type (and therefor class) from the poll function.
- //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL);
- return 1;
+ return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL);
}
void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
@@ -270,7 +272,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
if (PyObject_HasAttrString(py_class, "execute"))
ot->exec= PYTHON_OT_execute;
if (PyObject_HasAttrString(py_class, "poll"))
- ot->poll= PYTHON_OT_poll;
+ ot->pyop_poll= PYTHON_OT_poll;
ot->pyop_data= userdata;
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index dd6bc35fc0a..1f800be266b 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -345,13 +345,33 @@ static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
return result;
}
+static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
+{
+ char *param= _PyUnicode_AsString(item);
+
+ if (param==NULL) {
+ char *enum_str= pyrna_enum_as_string(ptr, prop);
+ PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
+ MEM_freeN(enum_str);
+ return 0;
+ } else {
+ if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
+ char *enum_str= pyrna_enum_as_string(ptr, prop);
+ PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
+ MEM_freeN(enum_str);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
{
PyObject *ret;
int type = RNA_property_type(prop);
- int len = RNA_property_array_length(ptr, prop);
- if (len > 0) {
+ if (RNA_property_array_check(ptr, prop)) {
return pyrna_py_from_array(ptr, prop);
}
@@ -521,9 +541,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
{
/* XXX hard limits should be checked here */
int type = RNA_property_type(prop);
- int len = RNA_property_array_length(ptr, prop);
- if (len > 0) {
+
+ if (RNA_property_array_check(ptr, prop)) {
+
/* char error_str[512]; */
int ok= 1;
@@ -603,42 +624,52 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
}
case PROP_ENUM:
{
- char *param = _PyUnicode_AsString(value);
-
- if (param==NULL) {
+ int val, i;
+
+ if (PyUnicode_Check(value)) {
+ if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix))
+ return -1;
+ }
+ else if (PyTuple_Check(value)) {
+ /* tuple of enum items, concatenate all values with OR */
+ val= 0;
+ for (i= 0; i < PyTuple_Size(value); i++) {
+ int tmpval;
+
+ /* PyTuple_GET_ITEM returns a borrowed reference */
+ if (!pyrna_string_to_enum(PyTuple_GET_ITEM(value, i), ptr, prop, &tmpval, error_prefix))
+ return -1;
+
+ val |= tmpval;
+ }
+ }
+ else {
char *enum_str= pyrna_enum_as_string(ptr, prop);
- PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
+ PyErr_Format(PyExc_TypeError, "%.200s expected a string enum or a tuple of strings in (%.200s)", error_prefix, enum_str);
MEM_freeN(enum_str);
return -1;
- } else {
- int val;
- if (RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, &val)) {
- if(data) *((int*)data)= val;
- else RNA_property_enum_set(ptr, prop, val);
- } else {
- char *enum_str= pyrna_enum_as_string(ptr, prop);
- PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
- MEM_freeN(enum_str);
- return -1;
- }
}
+
+ if(data) *((int*)data)= val;
+ else RNA_property_enum_set(ptr, prop, val);
break;
}
case PROP_POINTER:
{
StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
+ int flag = RNA_property_flag(prop);
if(!BPy_StructRNA_Check(value) && value != Py_None) {
- PointerRNA tmp;
- RNA_pointer_create(NULL, ptype, NULL, &tmp);
- PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(tmp.type));
+ PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptype));
+ return -1;
+ } else if((flag & PROP_NEVER_NULL) && value == Py_None) {
+ PyErr_Format(PyExc_TypeError, "property can't be assigned a None value");
return -1;
} else {
BPy_StructRNA *param= (BPy_StructRNA*)value;
int raise_error= FALSE;
if(data) {
- int flag = RNA_property_flag(prop);
if(flag & PROP_RNAPTR) {
if(value == Py_None)
@@ -819,13 +850,11 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
len = RNA_property_collection_length(&self->ptr, self->prop);
- } else {
+ } else if (RNA_property_array_check(&self->ptr, self->prop)) {
len = pyrna_prop_array_length(self);
-
- if (len==0) { /* not an array*/
- PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
- return -1;
- }
+ } else {
+ PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
+ len = -1; /* error value */
}
return len;
@@ -979,7 +1008,7 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
{
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
return prop_subscript_collection(self, key);
- } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */
+ } else if (RNA_property_array_check(&self->ptr, self->prop)) {
return prop_subscript_array(self, key);
}
@@ -1681,32 +1710,32 @@ static PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
{
/* Try get values from a collection */
- PyObject *ret = pyrna_prop_values(self);
+ PyObject *ret;
+ PyObject *iter;
- if (ret==NULL) {
- /* collection did not work, try array */
+ if(RNA_property_array_check(&self->ptr, self->prop)) {
int len = pyrna_prop_array_length(self);
+ int i;
+ PyErr_Clear();
+ ret = PyList_New(len);
- if (len) {
- int i;
- PyErr_Clear();
- ret = PyList_New(len);
-
- for (i=0; i < len; i++) {
- PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
- }
+ for (i=0; i < len; i++) {
+ PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
}
}
-
- if (ret) {
- /* we know this is a list so no need to PyIter_Check */
- PyObject *iter = PyObject_GetIter(ret);
- Py_DECREF(ret);
- return iter;
+ else if ((ret = pyrna_prop_values(self))) {
+ /* do nothing */
+ }
+ else {
+ PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
+ return NULL;
}
- PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
- return NULL;
+
+ /* we know this is a list so no need to PyIter_Check */
+ iter = PyObject_GetIter(ret);
+ Py_DECREF(ret);
+ return iter;
}
static struct PyMethodDef pyrna_struct_methods[] = {
@@ -1776,11 +1805,12 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PyObject *ret;
int type = RNA_property_type(prop);
- int len = RNA_property_array_length(ptr, prop);
int a;
- if(len > 0) {
+ if(RNA_property_array_check(ptr, prop)) {
+ int len = RNA_property_array_length(ptr, prop);
+
/* resolve the array from a new pytype */
ret = PyTuple_New(len);
@@ -1994,8 +2024,10 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
/* Check if we gave args that dont exist in the function
* printing the error is slow but it should only happen when developing.
- * the if below is quick, checking if it passed less keyword args then we gave */
- if(kw && (PyDict_Size(kw) > kw_tot)) {
+ * the if below is quick, checking if it passed less keyword args then we gave.
+ * (Dont overwrite the error if we have one, otherwise can skip important messages and confuse with args)
+ */
+ if(err == 0 && kw && (PyDict_Size(kw) > kw_tot)) {
PyObject *key, *value;
Py_ssize_t pos = 0;
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 3284f7ea79a..b30bc4936a5 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -34,6 +34,10 @@ SET(INC
../makesrna
)
+IF(WIN32)
+ SET(INC ${INC} ${PTHREADS_INC})
+ENDIF(WIN32)
+
IF(WITH_OPENEXR)
ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index db151775b96..f6193c29eba 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -23,4 +23,12 @@ if env['WITH_BF_OPENEXR']:
if env['OURPLATFORM']=='linux2':
cflags='-pthread'
+
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( libname = 'bf_render', sources = sources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags )
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index bf02af6ac36..56a81ac6b43 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -157,8 +157,11 @@ void RE_FreeAllRender (void);
/* get results and statistics */
void RE_FreeRenderResult(struct RenderResult *rr);
-struct RenderResult *RE_GetResult(struct Render *re);
-void RE_GetResultImage(struct Render *re, struct RenderResult *rr);
+struct RenderResult *RE_AcquireResultRead(struct Render *re);
+struct RenderResult *RE_AcquireResultWrite(struct Render *re);
+void RE_ReleaseResult(struct Render *re);
+void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr);
+void RE_ReleaseResultImage(struct Render *re);
struct RenderStats *RE_GetStats(struct Render *re);
void RE_ResultGet32(struct Render *re, unsigned int *rect);
struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name);
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index 15b59f2c8cc..069861df992 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -55,7 +55,7 @@ int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, f
/* particle.c */
void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype);
-float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip);
+float texture_value_blend(float tex, float out, float fact, float facg, int blendtype);
/* node_composite.c */
void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 435e3ddc07f..134be189e8f 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -128,7 +128,6 @@ typedef struct ShadeInput
/* individual copies: */
int har; /* hardness */
- float layerfac;
/* texture coordinates */
float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[4];
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index e50e498228d..96306be31c8 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -121,6 +121,10 @@ struct Render
RenderResult *pushedresult;
/* a list of RenderResults, for fullsample */
ListBase fullresult;
+ /* read/write mutex, all internal code that writes to re->result must use a
+ write lock, all external code must use a read lock. internal code is assumed
+ to not conflict with writes, so no lock used for that */
+ ThreadRWMutex resultmutex;
/* window size, display rect, viewplane */
int winx, winy;
diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h
index 9d87a219c82..368d60ee7f0 100644
--- a/source/blender/render/intern/include/volume_precache.h
+++ b/source/blender/render/intern/include/volume_precache.h
@@ -30,4 +30,4 @@ void volume_precache(Render *re);
void free_volume_precache(Render *re);
int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co);
-#define VOL_MS_TIMESTEP 0.1f \ No newline at end of file
+#define VOL_MS_TIMESTEP 0.1f
diff --git a/source/blender/render/intern/include/volumetric.h b/source/blender/render/intern/include/volumetric.h
index 026b4840ea3..97e7e022fa0 100644
--- a/source/blender/render/intern/include/volumetric.h
+++ b/source/blender/render/intern/include/volumetric.h
@@ -26,9 +26,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
-float vol_get_stepsize(struct ShadeInput *shi, int context);
float vol_get_density(struct ShadeInput *shi, float *co);
-void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float stepsize, float density);
+void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co_);
void shade_volume_outside(ShadeInput *shi, ShadeResult *shr);
void shade_volume_inside(ShadeInput *shi, ShadeResult *shr);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 99825c0c2ff..b3784f26048 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -889,6 +889,28 @@ static void free_mesh_orco_hash(Render *re)
}
}
+static void check_material_mapto(Material *ma)
+{
+ int a;
+ ma->mapto_textured = 0;
+
+ /* cache which inputs are actually textured.
+ * this can avoid a bit of time spent iterating through all the texture slots, map inputs and map tos
+ * every time a property which may or may not be textured is accessed */
+
+ for(a=0; a<MAX_MTEX; a++) {
+ if(ma->mtex[a] && ma->mtex[a]->tex) {
+ /* currently used only in volume render, so we'll check for those flags */
+ if(ma->mtex[a]->mapto & MAP_DENSITY) ma->mapto_textured |= MAP_DENSITY;
+ if(ma->mtex[a]->mapto & MAP_EMISSION) ma->mapto_textured |= MAP_EMISSION;
+ if(ma->mtex[a]->mapto & MAP_EMISSION_COL) ma->mapto_textured |= MAP_EMISSION_COL;
+ if(ma->mtex[a]->mapto & MAP_SCATTERING) ma->mapto_textured |= MAP_SCATTERING;
+ if(ma->mtex[a]->mapto & MAP_TRANSMISSION_COL) ma->mapto_textured |= MAP_TRANSMISSION_COL;
+ if(ma->mtex[a]->mapto & MAP_REFLECTION) ma->mapto_textured |= MAP_REFLECTION;
+ if(ma->mtex[a]->mapto & MAP_REFLECTION_COL) ma->mapto_textured |= MAP_REFLECTION_COL;
+ }
+ }
+}
static void flag_render_node_material(Render *re, bNodeTree *ntree)
{
bNode *node;
@@ -930,6 +952,8 @@ static Material *give_render_material(Render *re, Object *ob, int nr)
if(ma->nodetree && ma->use_nodes)
flag_render_node_material(re, ma->nodetree);
+ check_material_mapto(ma);
+
return ma;
}
@@ -1474,7 +1498,7 @@ static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int
static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset)
{
Object *ob= obr->ob;
- Object *tob=0;
+// Object *tob=0;
Material *ma=0;
ParticleSystemModifierData *psmd;
ParticleSystem *tpsys=0;
@@ -1484,6 +1508,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
ParticleKey state;
ParticleCacheKey *cache=0;
ParticleBillboardData bb;
+ ParticleSimulationData sim = {re->scene, ob, psys, NULL};
ParticleStrandData sd;
StrandBuffer *strandbuf=0;
StrandVert *svert=0;
@@ -1517,14 +1542,16 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
return 1;
/* 2. start initialising things */
- if(part->phystype==PART_PHYS_KEYED)
- psys_count_keyed_targets(ob,psys);
/* last possibility to bail out! */
- psmd= psys_get_modifier(ob,psys);
+ sim.psmd = psmd = psys_get_modifier(ob,psys);
if(!(psmd->modifier.mode & eModifierMode_Render))
return 0;
+ if(part->phystype==PART_PHYS_KEYED)
+ psys_count_keyed_targets(&sim);
+
+
if(G.rendering == 0) { /* preview render */
totchild = (int)((float)totchild * (float)part->disp / 100.0f);
}
@@ -1611,14 +1638,14 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
#endif // XXX old animation system
cfra = bsystem_time(re->scene, 0, (float)re->scene->r.cfra, 0.0);
-/* 2.4 setup reactors */
- if(part->type == PART_REACTOR){
- psys_get_reactor_target(ob, psys, &tob, &tpsys);
- if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
- psmd = psys_get_modifier(tob,tpsys);
- tpart = tpsys->part;
- }
- }
+///* 2.4 setup reactors */
+// if(part->type == PART_REACTOR){
+// psys_get_reactor_target(ob, psys, &tob, &tpsys);
+// if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
+// psmd = psys_get_modifier(tob,tpsys);
+// tpart = tpsys->part;
+// }
+// }
/* 2.5 setup matrices */
Mat4MulMat4(mat, ob->obmat, re->viewmat);
@@ -1695,7 +1722,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
if(path_nbr == 0)
- psys->lattice = psys_get_lattice(re->scene, ob, psys);
+ psys->lattice = psys_get_lattice(&sim);
/* 3. start creating renderable things */
for(a=0,pa=pars; a<totpart+totchild; a++, pa++, seed++) {
@@ -1786,8 +1813,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
- r_tilt = 2.0f * cpa->rand[2];
- r_length = cpa->rand[1];
+ r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
+ r_length = PSYS_FRAND(a + 22);
num = cpa->num;
@@ -1952,7 +1979,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
continue;
state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : ct;
- psys_get_particle_on_path(re->scene,ob,psys,a,&state,1);
+ psys_get_particle_on_path(&sim,a,&state,1);
if(psys->parent)
Mat4MulVecfl(psys->parent->obmat, state.co);
@@ -1971,7 +1998,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
else {
time=0.0f;
state.time=cfra;
- if(psys_get_particle_state(re->scene,ob,psys,a,&state,0)==0)
+ if(psys_get_particle_state(&sim,a,&state,0)==0)
continue;
if(psys->parent)
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index a6b089c6029..077f826b1ef 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -213,11 +213,15 @@ static void free_render_result(ListBase *lb, RenderResult *rr)
/* all layers except the active one get temporally pushed away */
static void push_render_result(Render *re)
{
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
/* officially pushed result should be NULL... error can happen with do_seq */
RE_FreeRenderResult(re->pushedresult);
re->pushedresult= re->result;
re->result= NULL;
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
@@ -229,6 +233,8 @@ static void pop_render_result(Render *re)
return;
}
if(re->pushedresult) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) {
/* find which layer in pushedresult should be replaced */
SceneRenderLayer *srl;
@@ -255,6 +261,8 @@ static void pop_render_result(Render *re)
RE_FreeRenderResult(re->pushedresult);
re->pushedresult= NULL;
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
}
@@ -406,7 +414,7 @@ static int passtype_from_name(char *str)
static void render_unique_exr_name(Render *re, char *str, int sample)
{
- char di[FILE_MAX], name[FILE_MAXFILE], fi[FILE_MAXFILE];
+ char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE];
BLI_strncpy(di, G.sce, FILE_MAX);
BLI_splitdirstring(di, fi);
@@ -920,6 +928,8 @@ static void read_render_result(Render *re, int sample)
{
char str[FILE_MAX];
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
@@ -928,6 +938,8 @@ static void read_render_result(Render *re, int sample)
if(!read_render_result_from_file(str, re->result))
printf("cannot read: %s\n", str);
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
/* *************************************************** */
@@ -946,13 +958,32 @@ Render *RE_GetRender(const char *name)
}
/* if you want to know exactly what has been done */
-RenderResult *RE_GetResult(Render *re)
+RenderResult *RE_AcquireResultRead(Render *re)
{
- if(re)
+ if(re) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_READ);
return re->result;
+ }
+
return NULL;
}
+RenderResult *RE_AcquireResultWrite(Render *re)
+{
+ if(re) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ return re->result;
+ }
+
+ return NULL;
+}
+
+void RE_ReleaseResult(Render *re)
+{
+ if(re)
+ BLI_rw_mutex_unlock(&re->resultmutex);
+}
+
/* displist.c util.... */
Scene *RE_GetScene(Render *re)
{
@@ -973,38 +1004,49 @@ RenderLayer *render_get_active_layer(Render *re, RenderResult *rr)
/* fill provided result struct with what's currently active or done */
-void RE_GetResultImage(Render *re, RenderResult *rr)
+void RE_AcquireResultImage(Render *re, RenderResult *rr)
{
memset(rr, 0, sizeof(RenderResult));
- if(re && re->result) {
- RenderLayer *rl;
-
- rr->rectx= re->result->rectx;
- rr->recty= re->result->recty;
-
- rr->rectf= re->result->rectf;
- rr->rectz= re->result->rectz;
- rr->rect32= re->result->rect32;
-
- /* active layer */
- rl= render_get_active_layer(re, re->result);
+ if(re) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_READ);
- if(rl) {
- if(rr->rectf==NULL)
- rr->rectf= rl->rectf;
- if(rr->rectz==NULL)
- rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z);
+ if(re->result) {
+ RenderLayer *rl;
+
+ rr->rectx= re->result->rectx;
+ rr->recty= re->result->recty;
+
+ rr->rectf= re->result->rectf;
+ rr->rectz= re->result->rectz;
+ rr->rect32= re->result->rect32;
+
+ /* active layer */
+ rl= render_get_active_layer(re, re->result);
+
+ if(rl) {
+ if(rr->rectf==NULL)
+ rr->rectf= rl->rectf;
+ if(rr->rectz==NULL)
+ rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z);
+ }
}
}
}
+void RE_ReleaseResultImage(Render *re)
+{
+ if(re)
+ BLI_rw_mutex_unlock(&re->resultmutex);
+}
+
/* caller is responsible for allocating rect in correct size! */
void RE_ResultGet32(Render *re, unsigned int *rect)
{
RenderResult rres;
- RE_GetResultImage(re, &rres);
+ RE_AcquireResultImage(re, &rres);
+
if(rres.rect32)
memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
else if(rres.rectf) {
@@ -1022,6 +1064,8 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
else
/* else fill with black */
memset(rect, 0, sizeof(int)*re->rectx*re->recty);
+
+ RE_ReleaseResultImage(re);
}
@@ -1042,12 +1086,15 @@ Render *RE_NewRender(const char *name)
re= MEM_callocN(sizeof(Render), "new render");
BLI_addtail(&RenderList, re);
strncpy(re->name, name, RE_MAXNAME);
+ BLI_rw_mutex_init(&re->resultmutex);
}
/* prevent UI to draw old results */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
RE_FreeRenderResult(re->result);
re->result= NULL;
re->result_ok= 0;
+ BLI_rw_mutex_unlock(&re->resultmutex);
/* set default empty callbacks */
re->display_init= result_nothing;
@@ -1072,6 +1119,7 @@ Render *RE_NewRender(const char *name)
/* only call this while you know it will remove the link too */
void RE_FreeRender(Render *re)
{
+ BLI_rw_mutex_end(&re->resultmutex);
free_renderdata_tables(re);
free_sample_tables(re);
@@ -1153,6 +1201,8 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy
make_sample_tables(re);
/* if preview render, we try to keep old result */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
if(re->r.scemode & R_PREVIEWBUTS) {
if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty);
else {
@@ -1168,6 +1218,8 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy
re->result->rectx= re->rectx;
re->result->recty= re->recty;
}
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
/* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */
re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx);
@@ -1184,8 +1236,12 @@ void RE_SetDispRect (struct Render *re, rcti *disprect)
re->recty= disprect->ymax-disprect->ymin;
/* initialize render result */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
@@ -1345,11 +1401,15 @@ static void render_tile_processor(Render *re, int firsttile)
if(re->test_break(re->tbh))
return;
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
/* hrmf... exception, this is used for preview render, re-entrant, so render result has to be re-used */
if(re->result==NULL || re->result->layers.first==NULL) {
if(re->result) RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
}
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
re->stats_draw(re->sdh, &re->i);
@@ -1357,7 +1417,7 @@ static void render_tile_processor(Render *re, int firsttile)
return;
initparts(re);
-
+
/* assuming no new data gets added to dbase... */
R= *re;
@@ -1384,7 +1444,7 @@ static void render_tile_processor(Render *re, int firsttile)
break;
}
}
-
+
freeparts(re);
}
@@ -1522,17 +1582,21 @@ static void threaded_tile_processor(Render *re)
rctf viewplane= re->viewplane;
int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
/* first step; free the entire render result, make new, and/or prepare exr buffer saving */
if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
RE_FreeRenderResult(re->result);
- if(re->sss_points)
+ if(re->sss_points && render_display_draw_enabled(re))
re->result= new_render_result(re, &re->disprect, 0, 0);
else if(re->r.scemode & R_FULL_SAMPLE)
re->result= new_full_sample_buffers_exr(re);
else
re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE));
}
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
if(re->result==NULL)
return;
@@ -1540,7 +1604,7 @@ static void threaded_tile_processor(Render *re)
/* warning; no return here without closing exr file */
initparts(re);
-
+
if(re->result->exrhandle) {
RenderResult *rr;
char str[FILE_MAX];
@@ -1629,6 +1693,8 @@ static void threaded_tile_processor(Render *re)
}
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
if(re->result->exrhandle) {
RenderResult *rr;
@@ -1644,6 +1710,8 @@ static void threaded_tile_processor(Render *re)
read_render_result(re, 0);
}
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
/* unset threadsafety */
g_break= 0;
@@ -1823,8 +1891,10 @@ static void do_render_blur_3d(Render *re)
}
/* swap results */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
RE_FreeRenderResult(re->result);
re->result= rres;
+ BLI_rw_mutex_unlock(&re->resultmutex);
set_mblur_offs(0.0f);
re->i.curblur= 0; /* stats */
@@ -1894,8 +1964,11 @@ static void do_render_fields_3d(Render *re)
do_render_blur_3d(re);
else
do_render_3d(re);
+
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
rr1= re->result;
re->result= NULL;
+ BLI_rw_mutex_unlock(&re->resultmutex);
/* second field */
if(!re->test_break(re->tbh)) {
@@ -1921,8 +1994,11 @@ static void do_render_fields_3d(Render *re)
re->recty *= 2;
re->disprect.ymin *= 2;
re->disprect.ymax *= 2;
+
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
-
+ RE_FreeRenderResult(rr1);
+
if(rr2) {
if(re->r.mode & R_ODDFIELD)
merge_renderresult_fields(re->result, rr2, rr1);
@@ -1931,12 +2007,14 @@ static void do_render_fields_3d(Render *re)
RE_FreeRenderResult(rr2);
}
- RE_FreeRenderResult(rr1);
re->i.curfield= 0; /* stats */
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
re->display_draw(re->ddh, re->result, NULL);
}
@@ -2000,6 +2078,8 @@ static void do_render_fields_blur_3d(Render *re)
if((re->r.mode & R_CROP)==0) {
RenderResult *rres;
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
/* sub-rect for merge call later on */
re->result->tilerect= re->disprect;
@@ -2020,6 +2100,8 @@ static void do_render_fields_blur_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
re->display_init(re->dih, re->result);
re->display_draw(re->ddh, re->result, NULL);
}
@@ -2176,7 +2258,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
}
/* ensure we get either composited result or the active layer */
- RE_GetResultImage(re, &rres);
+ RE_AcquireResultImage(re, &rres);
/* accumulate with filter, and clip */
mask= (1<<sample);
@@ -2195,6 +2277,8 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
}
}
+ RE_ReleaseResultImage(re);
+
/* show stuff */
if(sample!=re->osa-1) {
/* weak... the display callback wants an active renderlayer pointer... */
@@ -2206,9 +2290,11 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
break;
}
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result->rectf)
MEM_freeN(re->result->rectf);
re->result->rectf= rectf;
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
void RE_MergeFullSample(Render *re, Scene *sce, bNodeTree *ntree)
@@ -2309,9 +2395,12 @@ static void do_render_composite_fields_blur_3d(Render *re)
static void renderresult_stampinfo(Scene *scene)
{
RenderResult rres;
+ Render *re= RE_GetRender(scene->id.name);
+
/* this is the basic trick to get the displayed float or char rect from render result */
- RE_GetResultImage(RE_GetRender(scene->id.name), &rres);
+ RE_AcquireResultImage(re, &rres);
BKE_stamp_buf(scene, (unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4);
+ RE_ReleaseResultImage(re);
}
static void do_render_seq(Render * re)
@@ -2327,6 +2416,8 @@ static void do_render_seq(Render * re)
recurs_depth--;
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+
if(ibuf) {
if(ibuf->rect_float) {
if (!rr->rectf)
@@ -2369,6 +2460,8 @@ static void do_render_seq(Render * re)
else
rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
}
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -2388,14 +2481,15 @@ static void do_render_all_options(Render *re)
re->stats_draw(re->sdh, &re->i);
re->display_draw(re->ddh, re->result, NULL);
-
}
else {
do_render_composite_fields_blur_3d(re);
}
/* for UI only */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
renderresult_add_names(re->result);
+ BLI_rw_mutex_unlock(&re->resultmutex);
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
@@ -2622,7 +2716,7 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
char name[FILE_MAX];
RenderResult rres;
- RE_GetResultImage(re, &rres);
+ RE_AcquireResultImage(re, &rres);
/* write movie or image */
if(BKE_imtype_is_movie(scene->r.imtype)) {
@@ -2686,6 +2780,8 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
}
}
+ RE_ReleaseResultImage(re);
+
BLI_timestr(re->i.lastframetime, name);
printf(" Time: %s\n", name);
fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
@@ -2723,7 +2819,8 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
do_write_image_or_movie(re, scene, mh);
}
} else {
- re->test_break(re->tbh);
+ if(re->test_break(re->tbh))
+ G.afbreek= 1;
}
}
} else {
@@ -2769,9 +2866,10 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
do_render_all_options(re);
- if(re->test_break(re->tbh) == 0) {
+ if(re->test_break(re->tbh) == 0)
do_write_image_or_movie(re, scene, mh);
- }
+ else
+ G.afbreek= 1;
if(G.afbreek==1) {
/* remove touched file */
@@ -3006,6 +3104,7 @@ static void external_render_3d(Render *re, RenderEngineType *type)
{
RenderEngine engine;
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
RE_FreeRenderResult(re->result);
@@ -3014,6 +3113,7 @@ static void external_render_3d(Render *re, RenderEngineType *type)
else
re->result= new_render_result(re, &re->disprect, 0, 0); // XXX re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE));
}
+ BLI_rw_mutex_unlock(&re->resultmutex);
if(re->result==NULL)
return;
@@ -3027,6 +3127,7 @@ static void external_render_3d(Render *re, RenderEngineType *type)
free_render_result(&engine.fullresult, engine.fullresult.first);
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result->exrhandle) {
RenderResult *rr;
@@ -3042,5 +3143,6 @@ static void external_render_3d(Render *re, RenderEngineType *type)
read_render_result(re, 0);
}
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 5f8cf5504fa..b7832e74cd1 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -92,6 +92,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
{
DerivedMesh* dm;
ParticleKey state;
+ ParticleSimulationData sim = {re->scene, ob, psys, NULL};
ParticleData *pa=NULL;
float cfra = bsystem_time(re->scene, ob, (float)re->scene->r.cfra, 0.0);
int i, childexists;
@@ -120,7 +121,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
Mat4Invert(ob->imat, ob->obmat);
total_particles = psys->totpart+psys->totchild;
- psys->lattice=psys_get_lattice(re->scene,ob,psys);
+ psys->lattice=psys_get_lattice(&sim);
pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
alloc_point_data(pd, total_particles, data_used);
@@ -133,7 +134,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
for (i=0, pa=psys->particles; i < total_particles; i++, pa++) {
state.time = cfra;
- if(psys_get_particle_state(re->scene, ob, psys, i, &state, 0)) {
+ if(psys_get_particle_state(&sim, i, &state, 0)) {
VECCOPY(partco, state.co);
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index d2599f6050c..cce99d64b39 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -1343,7 +1343,8 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
/* mix colors based on shadfac (rgb + amount of light factor) */
addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
} else if (shi.mat->material_type == MA_TYPE_VOLUME) {
- addAlphaLight(is->col, shr.combined, shr.alpha, 1.0f);
+ QUATCOPY(is->col, shr.combined);
+ is->col[3] = 1.f;
}
if(depth>0 && is->col[3]>0.0f) {
@@ -1900,7 +1901,8 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
else max_samples = 1;
} else {
if (do_soft) max_samples = lar->ray_totsamp;
- else max_samples = (R.osa > 4)?R.osa:5;
+ else if (shi->depth == 0) max_samples = (R.osa > 4)?R.osa:5;
+ else max_samples = 1;
}
ray_shadow_jittered_coords(shi, max_samples, jitco, &totjitco);
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 621831fb341..30832db5c7d 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -1024,7 +1024,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f
externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
yn= tin*mtex->colfac;
- zn= tin*mtex->varfac;
+ zn= tin*mtex->alphafac;
if(mtex->mapto & MAP_COL) {
zn= 1.0-yn;
@@ -1156,7 +1156,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
//yn= tin*mtex->colfac;
- //zn= tin*mtex->varfac;
+ //zn= tin*mtex->alphafac;
if(mtex->mapto & MAP_COL) {
tex[0]=tr;
tex[1]=tg;
@@ -1175,11 +1175,11 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
har->b= in[2];
}
if(mtex->mapto & MAP_ALPHA)
- har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_ALPHA);
+ har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->alphafac,mtex->blendtype);
if(mtex->mapto & MAP_HAR)
- har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_HAR);
+ har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->hardfac,mtex->blendtype);
if(mtex->mapto & MAP_RAYMIRR)
- har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_RAYMIRR);
+ har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->raymirrfac,mtex->blendtype);
/* now what on earth is this good for?? */
//if(mtex->texco & 16) {
// har->alfa= tin;
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index bd022e768f8..a416c2d2764 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -862,6 +862,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
setting them back, maybe we need to create our own Render? */
/* do SSS preprocessing render */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
rr= re->result;
osa= re->osa;
osaflag= re->r.mode & R_OSA;
@@ -872,12 +873,20 @@ static void sss_create_tree_mat(Render *re, Material *mat)
re->sss_points= &points;
re->sss_mat= mat;
re->i.partsdone= 0;
- re->result= NULL;
- RE_TileProcessor(re, 0, !(re->r.mode & R_PREVIEWBUTS));
- RE_FreeRenderResult(re->result);
+ if(!(re->r.scemode & R_PREVIEWBUTS))
+ re->result= NULL;
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
+ RE_TileProcessor(re, 0, 1);
+
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ if(!(re->r.scemode & R_PREVIEWBUTS)) {
+ RE_FreeRenderResult(re->result);
+ re->result= rr;
+ }
+ BLI_rw_mutex_unlock(&re->resultmutex);
- re->result= rr;
re->i.partsdone= partsdone;
re->sss_mat= NULL;
re->sss_points= NULL;
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 2d2c01e0bf1..7b0e5d8abbc 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -721,7 +721,7 @@ static int evalnodes(Tex *tex, float *texvec, float *dxt, float *dyt, TexResult
short rv = TEX_INT;
bNodeTree *nodes = tex->nodetree;
- ntreeTexExecTree(nodes, texres, texvec, dxt, dyt, thread, tex, which_output, R.r.cfra);
+ ntreeTexExecTree(nodes, texres, texvec, dxt, dyt, thread, tex, which_output, R.r.cfra, (R.r.scemode & R_NODE_PREVIEW));
if(texres->nor) rv |= TEX_NOR;
rv |= TEX_RGB;
@@ -1468,9 +1468,12 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg
}
}
-float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip)
+float texture_value_blend(float tex, float out, float fact, float facg, int blendtype)
{
float in=0.0, facm, col, scf;
+ int flip= (facg < 0.0f);
+
+ facg= fabsf(facg);
fact*= facg;
facm= 1.0-fact;
@@ -1631,7 +1634,7 @@ void do_material_tex(ShadeInput *shi)
float fact, facm, factt, facmm, stencilTin=1.0;
float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
int tex_nr, rgbnor= 0, warpdone=0;
- float nu[3], nv[3], nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping
+ float nu[3] = {0,0,0}, nv[3] = {0,0,0}, nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping
int nunvdone= 0;
if (R.r.scemode & R_NO_TEX) return;
@@ -1813,7 +1816,7 @@ void do_material_tex(ShadeInput *shi)
TexResult ttexr = {0, 0, 0, 0, 0, texres.talpha, NULL}; // temp TexResult
float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
- const float bf = 0.04f*Tnor*((mtex->maptoneg & MAP_NORM) ? -mtex->norfac : mtex->norfac);
+ const float bf = 0.04f*Tnor*mtex->norfac;
// disable internal bump eval
float* nvec = texres.nor;
texres.nor = NULL;
@@ -2020,10 +2023,9 @@ void do_material_tex(ShadeInput *shi)
/* mapping */
if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
- float tcol[3], colfac;
+ float tcol[3];
/* stencil maps on the texture control slider, not texture intensity value */
- colfac= mtex->colfac*stencilTin;
tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb;
@@ -2043,15 +2045,19 @@ void do_material_tex(ShadeInput *shi)
}
if(mtex->mapto & MAP_COL) {
+ float colfac= mtex->colfac*stencilTin;
texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype);
}
if(mtex->mapto & MAP_COLSPEC) {
- texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colfac, mtex->blendtype);
+ float colspecfac= mtex->colspecfac*stencilTin;
+ texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype);
}
if(mtex->mapto & MAP_COLMIR) {
+ float mirrfac= mtex->mirrfac*stencilTin;
+
// exception for envmap only
if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) {
- fact= texres.tin*colfac;
+ fact= texres.tin*mirrfac;
facm= 1.0- fact;
shi->refcol[0]= fact + facm*shi->refcol[0];
shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1];
@@ -2059,14 +2065,13 @@ void do_material_tex(ShadeInput *shi)
shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3];
}
else {
- texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, colfac, mtex->blendtype);
+ texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype);
}
}
}
if( (mtex->mapto & MAP_NORM) ) {
if(texres.nor) {
- if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
- else tex->norfac= mtex->norfac;
+ tex->norfac= mtex->norfac;
/* we need to code blending modes for normals too once.. now 1 exception hardcoded */
@@ -2074,7 +2079,7 @@ void do_material_tex(ShadeInput *shi)
/* qdn: for normalmaps, to invert the normalmap vector,
it is better to negate x & y instead of subtracting the vector as was done before */
tex->norfac = mtex->norfac;
- if (mtex->maptoneg & MAP_NORM) {
+ if (tex->norfac < 0.0f) {
texres.nor[0] = -texres.nor[0];
texres.nor[1] = -texres.nor[1];
}
@@ -2159,8 +2164,7 @@ void do_material_tex(ShadeInput *shi)
/* Now that most textures offer both Nor and Intensity, allow */
/* both to work, and let user select with slider. */
if(texres.nor) {
- if(mtex->maptoneg & MAP_DISPLACE) tex->norfac= -mtex->norfac;
- else tex->norfac= mtex->norfac;
+ tex->norfac= mtex->norfac;
shi->displace[0]+= 0.2f*Tnor*tex->norfac*texres.nor[0];
shi->displace[1]+= 0.2f*Tnor*tex->norfac*texres.nor[1];
@@ -2172,12 +2176,7 @@ void do_material_tex(ShadeInput *shi)
else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
}
- if(mtex->maptoneg & MAP_DISPLACE) {
- factt= (texres.tin-0.5f)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
- }
- else {
- factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
- }
+ factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
if(mtex->blendtype==MTEX_BLEND) {
shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0];
@@ -2200,7 +2199,6 @@ void do_material_tex(ShadeInput *shi)
if(mtex->mapto & MAP_VARS) {
/* stencil maps on the texture control slider, not texture intensity value */
- float varfac= mtex->varfac*stencilTin;
if(rgbnor & TEX_RGB) {
if(texres.talpha) texres.tin= texres.ta;
@@ -2208,66 +2206,59 @@ void do_material_tex(ShadeInput *shi)
}
if(mtex->mapto & MAP_REF) {
- int flip= mtex->maptoneg & MAP_REF;
+ float difffac= mtex->difffac*stencilTin;
- shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, varfac, mtex->blendtype, flip);
+ shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype);
if(shi->refl<0.0) shi->refl= 0.0;
}
if(mtex->mapto & MAP_SPEC) {
- int flip= mtex->maptoneg & MAP_SPEC;
+ float specfac= mtex->specfac*stencilTin;
- shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, varfac, mtex->blendtype, flip);
+ shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype);
if(shi->spec<0.0) shi->spec= 0.0;
}
if(mtex->mapto & MAP_EMIT) {
- int flip= mtex->maptoneg & MAP_EMIT;
+ float emitfac= mtex->emitfac*stencilTin;
- shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, varfac, mtex->blendtype, flip);
+ shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype);
if(shi->emit<0.0) shi->emit= 0.0;
}
if(mtex->mapto & MAP_ALPHA) {
- int flip= mtex->maptoneg & MAP_ALPHA;
+ float alphafac= mtex->alphafac*stencilTin;
- shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, varfac, mtex->blendtype, flip);
+ shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype);
if(shi->alpha<0.0) shi->alpha= 0.0;
else if(shi->alpha>1.0) shi->alpha= 1.0;
}
if(mtex->mapto & MAP_HAR) {
- int flip= mtex->maptoneg & MAP_HAR;
float har; // have to map to 0-1
+ float hardfac= mtex->hardfac*stencilTin;
har= ((float)shi->har)/128.0;
- har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, varfac, mtex->blendtype, flip);
+ har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype);
if(har<1.0) shi->har= 1;
else if(har>511.0) shi->har= 511;
else shi->har= (int)har;
}
if(mtex->mapto & MAP_RAYMIRR) {
- int flip= mtex->maptoneg & MAP_RAYMIRR;
+ float raymirrfac= mtex->raymirrfac*stencilTin;
- shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, varfac, mtex->blendtype, flip);
+ shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype);
if(shi->ray_mirror<0.0) shi->ray_mirror= 0.0;
else if(shi->ray_mirror>1.0) shi->ray_mirror= 1.0;
}
if(mtex->mapto & MAP_TRANSLU) {
- int flip= mtex->maptoneg & MAP_TRANSLU;
+ float translfac= mtex->translfac*stencilTin;
- shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, varfac, mtex->blendtype, flip);
+ shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype);
if(shi->translucency<0.0) shi->translucency= 0.0;
else if(shi->translucency>1.0) shi->translucency= 1.0;
}
- if(mtex->mapto & MAP_LAYER) {
- int flip= mtex->maptoneg & MAP_LAYER;
-
- shi->layerfac= texture_value_blend(mtex->def_var, shi->layerfac, texres.tin, varfac, mtex->blendtype, flip);
- if(shi->layerfac<0.0) shi->layerfac= 0.0;
- else if(shi->layerfac>1.0) shi->layerfac= 1.0;
- }
if(mtex->mapto & MAP_AMB) {
- int flip= mtex->maptoneg & MAP_AMB;
+ float ambfac= mtex->ambfac*stencilTin;
- shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, varfac, mtex->blendtype, flip);
+ shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype);
if(shi->amb<0.0) shi->amb= 0.0;
else if(shi->amb>1.0) shi->amb= 1.0;
@@ -2385,11 +2376,10 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
}
- if((mapto_flag & (MAP_EMISSION_COL+MAP_ABSORPTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_ABSORPTION_COL))) {
- float tcol[3], colfac;
+ if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) {
+ float tcol[3];
/* stencil maps on the texture control slider, not texture intensity value */
- colfac= mtex->colfac*stencilTin;
if((rgbnor & TEX_RGB)==0) {
tcol[0]= mtex->r;
@@ -2410,18 +2400,23 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
/* used for emit */
if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) {
- texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype);
+ float colemitfac= mtex->colemitfac*stencilTin;
+ texture_rgb_blend(col, tcol, col, texres.tin, colemitfac, mtex->blendtype);
+ }
+
+ if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) {
+ float colreflfac= mtex->colreflfac*stencilTin;
+ texture_rgb_blend(col, tcol, col, texres.tin, colreflfac, mtex->blendtype);
}
- /* MAP_COLMIR is abused for absorption colour at the moment */
- if((mapto_flag & MAP_ABSORPTION_COL) && (mtex->mapto & MAP_ABSORPTION_COL)) {
- texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype);
+ if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) {
+ float coltransfac= mtex->coltransfac*stencilTin;
+ texture_rgb_blend(col, tcol, col, texres.tin, coltransfac, mtex->blendtype);
}
}
if((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) {
/* stencil maps on the texture control slider, not texture intensity value */
- float varfac= mtex->varfac*stencilTin;
/* convert RGB to intensity if intensity info isn't provided */
if (!(rgbnor & TEX_INT)) {
@@ -2432,27 +2427,27 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
}
if((mapto_flag & MAP_EMISSION) && (mtex->mapto & MAP_EMISSION)) {
- int flip= mtex->maptoneg & MAP_EMISSION;
+ float emitfac= mtex->emitfac*stencilTin;
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
+ *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype);
if(*val<0.0) *val= 0.0;
}
if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) {
- int flip= mtex->maptoneg & MAP_DENSITY;
+ float densfac= mtex->densfac*stencilTin;
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
+ *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype);
CLAMP(*val, 0.0, 1.0);
}
- if((mapto_flag & MAP_ABSORPTION) && (mtex->mapto & MAP_ABSORPTION)) {
- int flip= mtex->maptoneg & MAP_ABSORPTION;
+ if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) {
+ float scatterfac= mtex->scatterfac*stencilTin;
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
+ *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype);
CLAMP(*val, 0.0, 1.0);
}
- if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) {
- int flip= mtex->maptoneg & MAP_SCATTERING;
+ if((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) {
+ float reflfac= mtex->reflfac*stencilTin;
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
+ *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype);
CLAMP(*val, 0.0, 1.0);
}
}
@@ -2767,7 +2762,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
if(mtex->mapto & WOMAP_BLEND) {
if(rgb) texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
- *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->varfac, mtex->blendtype, 0);
+ *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype);
}
}
}
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 15d8643fea4..7ecaf83ae27 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -185,9 +185,9 @@ static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz)
}
}
- tot /= added;
+ if (added > 0) tot /= added;
- return ((added>0)?tot:0.0f);
+ return tot;
}
/* function to filter the edges of the light cache, where there was no volume originally.
@@ -202,17 +202,54 @@ static void lightcache_filter(VolumePrecache *vp)
for (y=0; y < vp->res[1]; y++) {
for (x=0; x < vp->res[0]; x++) {
/* trigger for outside mesh */
- if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.5f)
+ if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
vp->data_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
- if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.5f)
+ if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
vp->data_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
- if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.5f)
+ if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
vp->data_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
}
}
}
}
+static void lightcache_filter2(VolumePrecache *vp)
+{
+ int x, y, z;
+ float *new_r, *new_g, *new_b;
+ int field_size = vp->res[0]*vp->res[1]*vp->res[2]*sizeof(float);
+
+ new_r = MEM_mallocN(field_size, "temp buffer for light cache filter r channel");
+ new_g = MEM_mallocN(field_size, "temp buffer for light cache filter g channel");
+ new_b = MEM_mallocN(field_size, "temp buffer for light cache filter b channel");
+
+ memcpy(new_r, vp->data_r, field_size);
+ memcpy(new_g, vp->data_g, field_size);
+ memcpy(new_b, vp->data_b, field_size);
+
+ for (z=0; z < vp->res[2]; z++) {
+ for (y=0; y < vp->res[1]; y++) {
+ for (x=0; x < vp->res[0]; x++) {
+ /* trigger for outside mesh */
+ if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
+ new_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+ if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
+ new_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+ if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
+ new_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+ }
+ }
+ }
+
+ SWAP(float *, vp->data_r, new_r);
+ SWAP(float *, vp->data_g, new_g);
+ SWAP(float *, vp->data_b, new_b);
+
+ if (new_r) { MEM_freeN(new_r); new_r=NULL; }
+ if (new_g) { MEM_freeN(new_g); new_g=NULL; }
+ if (new_b) { MEM_freeN(new_b); new_b=NULL; }
+}
+
static inline int ms_I(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
{
return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
@@ -423,11 +460,10 @@ static void *vol_precache_part(void *data)
ObjectInstanceRen *obi = pa->obi;
RayTree *tree = pa->tree;
ShadeInput *shi = pa->shi;
- float density, scatter_col[3] = {0.f, 0.f, 0.f};
+ float scatter_col[3] = {0.f, 0.f, 0.f};
float co[3];
int x, y, z;
const int res[3]= {pa->res[0], pa->res[1], pa->res[2]};
- const float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW);
for (z= pa->minz; z < pa->maxz; z++) {
co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
@@ -448,8 +484,7 @@ static void *vol_precache_part(void *data)
VecCopyf(shi->view, co);
Normalize(shi->view);
- density = vol_get_density(shi, co);
- vol_get_scattering(shi, scatter_col, co, stepsize, density);
+ vol_get_scattering(shi, scatter_col, co);
obi->volume_precache->data_r[ V_I(x, y, z, res) ] = scatter_col[0];
obi->volume_precache->data_g[ V_I(x, y, z, res) ] = scatter_col[1];
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index bc425c8a1a3..381a32de027 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -170,29 +170,6 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *co
}
}
-/* input shader data */
-
-float vol_get_stepsize(struct ShadeInput *shi, int context)
-{
- if (shi->mat->vol.stepsize_type == MA_VOL_STEP_RANDOMIZED) {
- /* range between 0.75 and 1.25 */
- const float rnd = 0.5f * BLI_thread_frand(shi->thread) + 0.75f;
-
- if (context == STEPSIZE_VIEW)
- return shi->mat->vol.stepsize * rnd;
- else if (context == STEPSIZE_SHADE)
- return shi->mat->vol.shade_stepsize * rnd;
- }
- else { // MA_VOL_STEP_CONSTANT
-
- if (context == STEPSIZE_VIEW)
- return shi->mat->vol.stepsize;
- else if (context == STEPSIZE_SHADE)
- return shi->mat->vol.shade_stepsize;
- }
-
- return shi->mat->vol.stepsize;
-}
/* trilinear interpolation */
static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, float *co)
@@ -212,9 +189,9 @@ static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, fl
sample_co[1] = ((co[1] - bbmin[1]) / dim[1]);
sample_co[2] = ((co[2] - bbmin[2]) / dim[2]);
- scatter_col[0] = voxel_sample_trilinear(vp->data_r, vp->res, sample_co);
- scatter_col[1] = voxel_sample_trilinear(vp->data_g, vp->res, sample_co);
- scatter_col[2] = voxel_sample_trilinear(vp->data_b, vp->res, sample_co);
+ scatter_col[0] = voxel_sample_triquadratic(vp->data_r, vp->res, sample_co);
+ scatter_col[1] = voxel_sample_triquadratic(vp->data_g, vp->res, sample_co);
+ scatter_col[2] = voxel_sample_triquadratic(vp->data_b, vp->res, sample_co);
}
/* Meta object density, brute force for now
@@ -270,7 +247,8 @@ float vol_get_density(struct ShadeInput *shi, float *co)
float density = shi->mat->vol.density;
float density_scale = shi->mat->vol.density_scale;
- do_volume_tex(shi, co, MAP_DENSITY, NULL, &density);
+ if (shi->mat->mapto_textured & MAP_DENSITY)
+ do_volume_tex(shi, co, MAP_DENSITY, NULL, &density);
// if meta-object, modulate by metadensity without increasing it
if (shi->obi->obr->ob->type == OB_MBALL) {
@@ -281,79 +259,110 @@ float vol_get_density(struct ShadeInput *shi, float *co)
return density * density_scale;
}
-/* scattering multiplier, values above 1.0 are non-physical,
- * but can be useful to tweak lighting */
-float vol_get_scattering_fac(ShadeInput *shi, float *co)
+
+/* Color of light that gets scattered out by the volume */
+/* Uses same physically based scattering parameter as in transmission calculations,
+ * along with artificial reflection scale/reflection color tint */
+void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co)
{
float scatter = shi->mat->vol.scattering;
- float col[3] = {0.0, 0.0, 0.0};
+ float reflection= shi->mat->vol.reflection;
+ VECCOPY(ref_col, shi->mat->vol.reflection_col);
+
+ if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_REFLECTION_COL))
+ do_volume_tex(shi, co, MAP_SCATTERING+MAP_REFLECTION_COL, ref_col, &scatter);
- do_volume_tex(shi, co, MAP_SCATTERING, col, &scatter);
+ /* only one single float parameter at a time... :s */
+ if (shi->mat->mapto_textured & (MAP_REFLECTION))
+ do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection);
- return scatter;
+ ref_col[0] = reflection * ref_col[0] * scatter;
+ ref_col[1] = reflection * ref_col[1] * scatter;
+ ref_col[2] = reflection * ref_col[2] * scatter;
}
/* compute emission component, amount of radiance to add per segment
* can be textured with 'emit' */
-void vol_get_emission(ShadeInput *shi, float *emission_col, float *co, float density)
+void vol_get_emission(ShadeInput *shi, float *emission_col, float *co)
{
float emission = shi->mat->vol.emission;
VECCOPY(emission_col, shi->mat->vol.emission_col);
- do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission);
+ if (shi->mat->mapto_textured & (MAP_EMISSION+MAP_EMISSION_COL))
+ do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission);
- emission_col[0] = emission_col[0] * emission * density;
- emission_col[1] = emission_col[1] * emission * density;
- emission_col[2] = emission_col[2] * emission * density;
+ emission_col[0] = emission_col[0] * emission;
+ emission_col[1] = emission_col[1] * emission;
+ emission_col[2] = emission_col[2] * emission;
}
-void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co)
+
+/* A combination of scattering and absorption -> known as sigma T.
+ * This can possibly use a specific scattering colour,
+ * and absorption multiplier factor too, but these parameters are left out for simplicity.
+ * It's easy enough to get a good wide range of results with just these two parameters. */
+void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co)
{
- float absorption = shi->mat->vol.absorption;
- VECCOPY(absorb_col, shi->mat->vol.absorption_col);
+ /* technically absorption, but named transmission color
+ * since it describes the effect of the coloring *after* absorption */
+ float transmission_col[3] = {shi->mat->vol.transmission_col[0], shi->mat->vol.transmission_col[1], shi->mat->vol.transmission_col[2]};
+ float scattering = shi->mat->vol.scattering;
- do_volume_tex(shi, co, MAP_ABSORPTION+MAP_ABSORPTION_COL, absorb_col, &absorption);
+ if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_TRANSMISSION_COL))
+ do_volume_tex(shi, co, MAP_SCATTERING+MAP_TRANSMISSION_COL, transmission_col, &scattering);
- absorb_col[0] = (1.0f - absorb_col[0]) * absorption;
- absorb_col[1] = (1.0f - absorb_col[1]) * absorption;
- absorb_col[2] = (1.0f - absorb_col[2]) * absorption;
+ sigma_t[0] = (1.0f - transmission_col[0]) + scattering;
+ sigma_t[1] = (1.0f - transmission_col[1]) + scattering;
+ sigma_t[2] = (1.0f - transmission_col[2]) + scattering;
}
/* phase function - determines in which directions the light
* is scattered in the volume relative to incoming direction
* and view direction */
-float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w, float *wp)
+float vol_get_phasefunc(ShadeInput *shi, float g, float *w, float *wp)
{
- const float costheta = Inpf(w, wp);
- const float scale = M_PI;
-
- /*
- * Scale constant is required, since Blender's shading system doesn't normalise for
- * energy conservation - eg. scaling by 1/pi for a lambert shader.
- * This makes volumes darker than other solid objects, for the same lighting intensity.
- * To correct this, scale up the phase function values
+ const float normalize = 0.25f; // = 1.f/4.f = M_PI/(4.f*M_PI)
+
+ /* normalization constant is 1/4 rather than 1/4pi, since
+ * Blender's shading system doesn't normalise for
+ * energy conservation - eg. multiplying by pdf ( 1/pi for a lambert brdf ).
+ * This means that lambert surfaces in Blender are pi times brighter than they 'should be'
+ * and therefore, with correct energy conservation, volumes will darker than other solid objects,
+ * for the same lighting intensity.
+ * To correct this, scale up the phase function values by pi
* until Blender's shading system supports this better. --matt
*/
+ if (g == 0.f) { /* isotropic */
+ return normalize * 1.f;
+ } else { /* schlick */
+ const float k = 1.55f * g - .55f * g * g * g;
+ const float kcostheta = k * Inpf(w, wp);
+ return normalize * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta));
+ }
+
+ /*
+ * not used, but here for reference:
switch (phasefunc_type) {
case MA_VOL_PH_MIEHAZY:
- return scale * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f)) / (4.f*M_PI);
+ return normalize * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f));
case MA_VOL_PH_MIEMURKY:
- return scale * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)) / (4.f*M_PI);
+ return normalize * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f));
case MA_VOL_PH_RAYLEIGH:
- return scale * 3.f/(16.f*M_PI) * (1 + costheta * costheta);
+ return normalize * 3.f/4.f * (1 + costheta * costheta);
case MA_VOL_PH_HG:
- return scale * (1.f / (4.f * M_PI) * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f));
+ return normalize * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f));
case MA_VOL_PH_SCHLICK:
{
const float k = 1.55f * g - .55f * g * g * g;
const float kcostheta = k * costheta;
- return scale * (1.f / (4.f * M_PI) * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta)));
+ return normalize * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta));
}
case MA_VOL_PH_ISOTROPIC:
default:
- return scale * (1.f / (4.f * M_PI));
+ return normalize * 1.f;
}
+ */
}
/* Compute transmittance = e^(-attenuation) */
@@ -361,15 +370,15 @@ void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float
{
/* input density = density at co */
float tau[3] = {0.f, 0.f, 0.f};
- float absorb[3];
- const float scatter_dens = vol_get_scattering_fac(shi, co) * density * stepsize;
-
- vol_get_absorption(shi, absorb, co);
+ const float stepd = density * stepsize;
+ float sigma_t[3];
+
+ vol_get_sigma_t(shi, sigma_t, co);
/* homogenous volume within the sampled distance */
- tau[0] += scatter_dens * absorb[0];
- tau[1] += scatter_dens * absorb[1];
- tau[2] += scatter_dens * absorb[2];
+ tau[0] += stepd * sigma_t[0];
+ tau[1] += stepd * sigma_t[1];
+ tau[2] += stepd * sigma_t[2];
tr[0] *= exp(-tau[0]);
tr[1] *= exp(-tau[1]);
@@ -381,31 +390,29 @@ static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float *
{
float p[3] = {co[0], co[1], co[2]};
float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
- //const float ambtau = -logf(shi->mat->vol.depth_cutoff); // never zero
float tau[3] = {0.f, 0.f, 0.f};
float t0 = 0.f;
float t1 = Normalize(step_vec);
float pt0 = t0;
- t0 += shi->mat->vol.shade_stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+ t0 += shi->mat->vol.stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
p[0] += t0 * step_vec[0];
p[1] += t0 * step_vec[1];
p[2] += t0 * step_vec[2];
- VecMulf(step_vec, shi->mat->vol.shade_stepsize);
+ VecMulf(step_vec, shi->mat->vol.stepsize);
- for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.shade_stepsize) {
- float absorb[3];
+ for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.stepsize) {
const float d = vol_get_density(shi, p);
const float stepd = (t0 - pt0) * d;
- const float scatter_dens = vol_get_scattering_fac(shi, p) * stepd;
- vol_get_absorption(shi, absorb, p);
+ float sigma_t[3];
+
+ vol_get_sigma_t(shi, sigma_t, co);
- tau[0] += scatter_dens * absorb[0];
- tau[1] += scatter_dens * absorb[1];
- tau[2] += scatter_dens * absorb[2];
+ tau[0] += stepd * sigma_t[0];
+ tau[1] += stepd * sigma_t[1];
+ tau[2] += stepd * sigma_t[2];
- //if (luminance(tau) >= ambtau) break;
VecAddf(p, p, step_vec);
}
@@ -420,9 +427,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
float visifac, lv[3], lampdist;
float tr[3]={1.0,1.0,1.0};
float hitco[3], *atten_co;
- float p;
- float scatter_fac;
- float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE);
+ float p, ref_col[3];
if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return;
if ((lar->lay & shi->lay)==0) return;
@@ -476,15 +481,20 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
}
}
- p = vol_get_phasefunc(shi, shi->mat->vol.phasefunc_type, shi->mat->vol.phasefunc_g, shi->view, lv);
- VecMulf(lacol, p);
+ if (luminance(lacol) < 0.001f) return;
+
+ p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, shi->view, lv);
+
+ /* physically based scattering with non-physically based RGB gain */
+ vol_get_reflection_color(shi, ref_col, co);
- scatter_fac = vol_get_scattering_fac(shi, co);
- VecMulf(lacol, scatter_fac);
+ lacol[0] *= p * ref_col[0];
+ lacol[1] *= p * ref_col[1];
+ lacol[2] *= p * ref_col[2];
}
/* single scattering only for now */
-void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float stepsize, float density)
+void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co)
{
ListBase *lights;
GroupObject *go;
@@ -516,71 +526,69 @@ outgoing radiance from behind surface * beam transmittance/attenuation
--> radiance for each segment =
(radiance added by scattering + radiance added by emission) * beam transmittance/attenuation
*/
+
+/* For ease of use, I've also introduced a 'reflection' and 'reflection color' parameter, which isn't
+ * physically correct. This works as an RGB tint/gain on out-scattered light, but doesn't affect the light
+ * that is transmitted through the volume. While having wavelength dependent absorption/scattering is more correct,
+ * it also makes it harder to control the overall look of the volume since colouring the outscattered light results
+ * in the inverse colour being transmitted through the rest of the volume.
+ */
static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco)
{
- float tr[3] = {1.0f, 1.0f, 1.0f};
- float radiance[3] = {0.f, 0.f, 0.f}, d_radiance[3] = {0.f, 0.f, 0.f};
- float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW);
- int nsteps, s;
- float emit_col[3], scatter_col[3] = {0.0, 0.0, 0.0};
- float stepvec[3], step_sta[3], step_end[3], step_mid[3];
- float density;
- const float depth_cutoff = shi->mat->vol.depth_cutoff;
-
- /* ray marching */
- nsteps = (int)((VecLenf(co, endco) / stepsize) + 0.5);
-
- VecSubf(stepvec, endco, co);
- VecMulf(stepvec, 1.0f / nsteps);
- VecCopyf(step_sta, co);
- VecAddf(step_end, step_sta, stepvec);
-
- /* get radiance from all points along the ray due to participating media */
- for (s = 0; s < nsteps; s++) {
-
- density = vol_get_density(shi, step_sta);
+ float radiance[3] = {0.f, 0.f, 0.f};
+ float tr[3] = {1.f, 1.f, 1.f};
+ float p[3] = {co[0], co[1], co[2]};
+ float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
+ const float stepsize = shi->mat->vol.stepsize;
+
+ float t0 = 0.f;
+ float pt0 = t0;
+ float t1 = Normalize(step_vec); /* returns vector length */
+
+ t0 += stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+ p[0] += t0 * step_vec[0];
+ p[1] += t0 * step_vec[1];
+ p[2] += t0 * step_vec[2];
+ VecMulf(step_vec, stepsize);
+
+ for (; t0 < t1; pt0 = t0, t0 += stepsize) {
+ const float density = vol_get_density(shi, p);
- /* there's only any use in shading here if there's actually some density to shade! */
if (density > 0.01f) {
-
+ float scatter_col[3], emit_col[3];
+ const float stepd = (t0 - pt0) * density;
+
/* transmittance component (alpha) */
vol_get_transmittance_seg(shi, tr, stepsize, co, density);
-
- step_mid[0] = step_sta[0] + (stepvec[0] * 0.5);
- step_mid[1] = step_sta[1] + (stepvec[1] * 0.5);
- step_mid[2] = step_sta[2] + (stepvec[2] * 0.5);
-
- /* incoming light via emission or scattering (additive) */
- vol_get_emission(shi, emit_col, step_mid, density);
- if (shi->obi->volume_precache)
- vol_get_precached_scattering(shi, scatter_col, step_mid);
- else
- vol_get_scattering(shi, scatter_col, step_mid, stepsize, density);
+ if (luminance(tr) < shi->mat->vol.depth_cutoff) break;
- VecMulf(scatter_col, density);
- VecAddf(d_radiance, emit_col, scatter_col);
+ vol_get_emission(shi, emit_col, p);
- /* Lv += Tr * (Lve() + Ld) */
- VecMulVecf(d_radiance, tr, d_radiance);
- VecMulf(d_radiance, stepsize);
+ if (shi->obi->volume_precache) {
+ float p2[3];
+
+ p2[0] = p[0] + (step_vec[0] * 0.5);
+ p2[1] = p[1] + (step_vec[1] * 0.5);
+ p2[2] = p[2] + (step_vec[2] * 0.5);
+
+ vol_get_precached_scattering(shi, scatter_col, p2);
+ } else
+ vol_get_scattering(shi, scatter_col, p);
- VecAddf(radiance, radiance, d_radiance);
+ radiance[0] += stepd * tr[0] * (emit_col[0] + scatter_col[0]);
+ radiance[1] += stepd * tr[1] * (emit_col[1] + scatter_col[1]);
+ radiance[2] += stepd * tr[2] * (emit_col[2] + scatter_col[2]);
}
-
- VecCopyf(step_sta, step_end);
- VecAddf(step_end, step_end, stepvec);
-
- /* luminance rec. 709 */
- if ((0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]) < depth_cutoff) break;
+ VecAddf(p, p, step_vec);
}
- /* multiply original color (behind volume) with beam transmittance over entire distance */
- VecMulVecf(col, tr, col);
+ /* multiply original color (from behind volume) with transmittance over entire distance */
+ VecMulVecf(col, tr, col);
VecAddf(col, col, radiance);
/* alpha <-- transmission luminance */
- col[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]);
+ col[3] = 1.0f - luminance(tr);
}
/* the main entry point for volume shading */
@@ -607,7 +615,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in
/* don't render the backfaces of ztransp volume materials.
* volume shading renders the internal volume from between the
- * near view intersection of the solid volume to the
+ * ' view intersection of the solid volume to the
* intersection on the other side, as part of the shading of
* the front face.
@@ -683,7 +691,6 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct
float hitco[3];
float tr[3] = {1.0,1.0,1.0};
Isect is;
- float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE);
float *startco, *endco;
float density=0.f;
@@ -711,8 +718,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct
vol_get_transmittance(shi, tr, startco, endco);
VecCopyf(shr->combined, tr);
- shr->combined[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]);
- shr->alpha = shr->combined[3];
+ shr->combined[3] = 1.0f - luminance(tr);
}
@@ -749,4 +755,4 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr)
shi->mat = mat_backup;
shi->obi = obi_backup;
shi->obr = obi_backup->obr;
-} \ No newline at end of file
+}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 17858e55e3d..479f33c9ff2 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -167,12 +167,10 @@ void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex)
SmokeModifierData *smd = (SmokeModifierData *)md;
if(smd->domain && smd->domain->fluid) {
- //int big = (smd->domain->flags & MOD_SMOKE_HIGHRES);
- int big=0;
- if (big) {
- //smoke_turbulence_get_res(smd->domain->wt, vd->resol);
- //vd->dataset = smoke_turbulence_get_density(smd->domain->wt);
+ if (smd->domain->flags & MOD_SMOKE_HIGHRES) {
+ smoke_turbulence_get_res(smd->domain->wt, vd->resol);
+ vd->dataset = smoke_turbulence_get_density(smd->domain->wt);
} else {
VECCOPY(vd->resol, smd->domain->res);
vd->dataset = smoke_get_density(smd->domain->fluid);
@@ -228,9 +226,6 @@ void make_voxeldata(struct Render *re)
{
Tex *tex;
- if(re->scene->r.scemode & R_PREVIEWBUTS)
- return;
-
re->i.infostr= "Loading voxel datasets";
re->stats_draw(re->sdh, &re->i);
@@ -261,9 +256,6 @@ void free_voxeldata(Render *re)
{
Tex *tex;
- if(re->scene->r.scemode & R_PREVIEWBUTS)
- return;
-
for (tex= G.main->tex.first; tex; tex= tex->id.next) {
if(tex->id.us && tex->type==TEX_VOXELDATA) {
free_voxeldata_one(re, tex);
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript
index 91635904524..08a291871f1 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -19,4 +19,11 @@ defs = []
if not env['WITH_BF_PYTHON']:
defs.append('DISABLE_PYTHON')
+if env['OURPLATFORM'] == 'linux2':
+ cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
env.BlenderLib ( 'bf_windowmanager', sources, Split(incs), defs, libtype=['core'], priority=[5] )
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 544804b26d6..489f27990cd 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -83,12 +83,12 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle);
/* keymap */
void WM_keymap_init (struct bContext *C);
-wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type,
+wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type,
short val, int modifier, short keymodifier);
-wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type,
+wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type,
short val, int modifier, short keymodifier);
-void WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short keymodifier);
-ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid,
+void WM_keymap_tweak (wmKeyMap *keymap, short type, short val, int modifier, short keymodifier);
+wmKeyMap *WM_keymap_find (struct wmWindowManager *wm, const char *nameid,
short spaceid, short regionid);
wmKeyMap *WM_modalkeymap_add(struct wmWindowManager *wm, const char *nameid, struct EnumPropertyItem *items);
@@ -104,13 +104,13 @@ void WM_key_event_operator_change(const struct bContext *C, const char *opname,
/* handlers */
-struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap);
+struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap);
/* boundbox, optional subwindow boundbox for offset */
-struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bb, rcti *swinbb);
+struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, rcti *bb, rcti *swinbb);
/* priority not implemented, it adds in begin */
-struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority);
+struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int priority);
-void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap);
+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),
@@ -119,7 +119,7 @@ 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);
-struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, ListBase *handlers, struct wmOperator *op);
+struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
void WM_event_remove_handlers(struct bContext *C, ListBase *handlers);
void WM_event_add_mousemove(struct bContext *C);
@@ -139,7 +139,7 @@ void WM_event_window_timer_sleep(struct wmWindow *win, struct wmTimer *timer, i
int WM_menu_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
/* invoke callback, confirm menu + exec */
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
- /* invoke callback, file selector "filename" unset + exec */
+ /* invoke callback, file selector "path" unset + exec */
int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
@@ -162,6 +162,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag)
wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname);
+int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot);
int WM_operator_call (struct bContext *C, struct wmOperator *op);
int WM_operator_repeat (struct bContext *C, struct wmOperator *op);
int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
@@ -169,7 +170,7 @@ int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int con
void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring);
void WM_operator_properties_free(struct PointerRNA *ptr);
-void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter);
+void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type);
/* operator as a python command (resultuing string must be free'd) */
char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args);
@@ -225,8 +226,10 @@ void WM_set_framebuffer_index_color(int index);
int WM_framebuffer_to_index(unsigned int col);
/* threaded Jobs Manager */
+#define WM_JOB_PRIORITY 1
+#define WM_JOB_EXCL_RENDER 2
-struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner);
+struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner, int flag);
int WM_jobs_test(struct wmWindowManager *wm, void *owner);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 806f5409b0a..d746df01421 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -183,9 +183,12 @@ typedef struct wmNotifier {
#define ND_SHADING_DRAW (31<<16)
/* NC_LAMP Lamp */
-#define ND_LIGHTING (44<<16)
-#define ND_LIGHTING_DRAW (45<<16)
-#define ND_SKY (46<<16)
+#define ND_LIGHTING (40<<16)
+#define ND_LIGHTING_DRAW (41<<16)
+#define ND_SKY (42<<16)
+
+ /* NC_WORLD World */
+#define ND_WORLD_DRAW (45<<16)
/* NC_TEXT Text */
#define ND_CURSOR (50<<16)
@@ -276,12 +279,8 @@ typedef struct wmGesture {
} wmGesture;
/* ************** custom wmEvent data ************** */
-
-#define DEV_STYLUS 1
-#define DEV_ERASER 2
-
typedef struct wmTabletData {
- int Active; /* 0=None, 1=Stylus, 2=Eraser */
+ int Active; /* 0=EVT_TABLET_NONE, 1=EVT_TABLET_STYLUS, 2=EVT_TABLET_ERASER */
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */
float Ytilt; /* as above */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 38cf39c2081..4405b52888d 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -69,15 +69,17 @@ void WM_operator_free(wmOperator *op)
MEM_freeN(op->properties);
}
- if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) {
+ if(op->reports && (op->reports->flag & RPT_FREE)) {
BKE_reports_clear(op->reports);
MEM_freeN(op->reports);
}
if(op->macro.first) {
- wmOperator *opm;
- for(opm= op->macro.first; opm; opm= opm->next)
+ wmOperator *opm, *opmnext;
+ for(opm= op->macro.first; opm; opm= opmnext) {
+ opmnext = opm->next;
WM_operator_free(opm);
+ }
}
MEM_freeN(op);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 3c03d24ca93..b7156a17383 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -239,7 +239,7 @@ void wm_event_do_notifiers(bContext *C)
if(G.rendering==0) { // XXX make lock in future, or separated derivedmesh users in scene
- /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual,
+ /* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual,
no layer check here, gets correct flushed */
/* sets first, we allow per definition current scene to have dependencies on sets */
if(scene->set) {
@@ -259,20 +259,23 @@ void wm_event_do_notifiers(bContext *C)
/* ********************* operators ******************* */
-static int wm_operator_poll(bContext *C, wmOperatorType *ot)
+int WM_operator_poll(bContext *C, wmOperatorType *ot)
{
wmOperatorTypeMacro *otmacro;
for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) {
wmOperatorType *ot= WM_operatortype_find(otmacro->idname, 0);
- if(0==wm_operator_poll(C, ot))
+ if(0==WM_operator_poll(C, ot))
return 0;
}
- if(ot->poll)
+ /* python needs operator type, so we added exception for it */
+ if(ot->pyop_poll)
+ return ot->pyop_poll(C, ot);
+ else if(ot->poll)
return ot->poll(C);
-
+
return 1;
}
@@ -284,7 +287,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
if(op==NULL || op->type==NULL)
return retval;
- if(0==wm_operator_poll(C, op->type))
+ if(0==WM_operator_poll(C, op->type))
return retval;
if(op->type->exec)
@@ -349,8 +352,7 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P
}
else {
op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
- BKE_reports_init(op->reports, RPT_STORE);
- op->flag |= OPERATOR_REPORT_FREE;
+ BKE_reports_init(op->reports, RPT_STORE|RPT_FREE);
}
/* recursive filling of operator macro list */
@@ -398,7 +400,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
wmWindowManager *wm= CTX_wm_manager(C);
int retval= OPERATOR_PASS_THROUGH;
- if(wm_operator_poll(C, ot)) {
+ if(WM_operator_poll(C, ot)) {
wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */
if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE)
@@ -413,7 +415,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
else
printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */
- if(!(retval & OPERATOR_RUNNING_MODAL)) {
+ /* Note, if the report is given as an argument then assume the caller will deal with displaying them
+ * currently python only uses this */
+ if(!(retval & OPERATOR_RUNNING_MODAL) && reports==NULL) {
if(op->reports->list.first) /* only show the report if the report list was not given in the function */
uiPupMenuReports(C, op->reports);
@@ -555,6 +559,12 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
retval= wm_operator_call_internal(C, ot, context, properties, reports);
+ /* keep the reports around if needed later */
+ if (retval & OPERATOR_RUNNING_MODAL || ot->flag & OPTYPE_REGISTER)
+ {
+ reports->flag |= RPT_FREE;
+ }
+
return retval;
}
@@ -710,7 +720,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
/* the matching rules */
if(kmitype==KM_TEXTINPUT)
- if(ISKEYBOARD(winevent->type)) return 1;
+ if(ISTEXTINPUT(winevent->type) && winevent->ascii) return 1;
if(kmitype!=KM_ANY)
if(winevent->type!=kmitype) return 0;
@@ -733,7 +743,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
/* key modifiers always check when event has it */
/* otherwise regular keypresses with keymodifier still work */
if(winevent->keymodifier)
- if(ISKEYBOARD(winevent->type))
+ if(ISTEXTINPUT(winevent->type))
if(winevent->keymodifier!=kmi->keymodifier) return 0;
return 1;
@@ -895,9 +905,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
switch(event->val) {
case EVT_FILESELECT_OPEN:
case EVT_FILESELECT_FULL_OPEN:
- {
- char *dir= NULL; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0);
-
+ {
if(event->val==EVT_FILESELECT_OPEN)
ED_area_newspace(C, handler->op_area, SPACE_FILE);
else
@@ -908,8 +916,6 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
sfile->op= handler->op;
ED_fileselect_set_params(sfile);
- dir = NULL;
- MEM_freeN(path);
action= WM_HANDLER_BREAK;
}
@@ -920,7 +926,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
{
/* XXX validate area and region? */
bScreen *screen= CTX_wm_screen(C);
- char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0);
+ char *path= RNA_string_get_alloc(handler->op->ptr, "path", NULL, 0);
if(screen != handler->filescreen)
ED_screen_full_prevspace(C);
@@ -937,7 +943,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
/* XXX also extension code in image-save doesnt work for this yet */
if(strncmp(handler->op->type->name, "Save", 4)==0) {
/* this gives ownership to pupmenu */
- uiPupMenuSaveOver(C, handler->op, path);
+ uiPupMenuSaveOver(C, handler->op, (path)? path: "");
}
else {
int retval= handler->op->type->exec(C, handler->op);
@@ -955,7 +961,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
WM_operator_free(handler->op);
wm_event_free_handler(handler);
- MEM_freeN(path);
+ if(path)
+ MEM_freeN(path);
action= WM_HANDLER_BREAK;
}
@@ -998,7 +1005,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
int always_pass;
if(handlers==NULL) return action;
-
+
/* modal handlers can get removed in this loop, we keep the loop this way */
for(handler= handlers->first; handler; handler= nexthandler) {
nexthandler= handler->next;
@@ -1013,16 +1020,19 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
action= WM_HANDLER_BREAK;
if(handler->keymap) {
+ wmKeyMap *keymap= handler->keymap;
wmKeymapItem *kmi;
- for(kmi= handler->keymap->first; kmi; kmi= kmi->next) {
- if(wm_eventmatch(event, kmi)) {
-
- event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */
-
- action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
- if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */
- break;
+ if(!keymap->poll || keymap->poll(C)) {
+ for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) {
+ if(wm_eventmatch(event, kmi)) {
+
+ event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */
+
+ action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
+ if(action==WM_HANDLER_BREAK) /* not always_pass here, it denotes removed handler */
+ break;
+ }
}
}
}
@@ -1038,8 +1048,12 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
action= wm_handler_operator_call(C, handlers, handler, event, NULL);
}
- if(!always_pass && action==WM_HANDLER_BREAK)
- break;
+ if(action==WM_HANDLER_BREAK) {
+ if(always_pass)
+ action= WM_HANDLER_CONTINUE;
+ else
+ break;
+ }
}
/* fileread case */
@@ -1051,6 +1065,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
static int wm_event_inside_i(wmEvent *event, rcti *rect)
{
+ if(wm_event_always_pass(event))
+ return 1;
if(BLI_in_rcti(rect, event->x, event->y))
return 1;
if(event->type==MOUSEMOVE) {
@@ -1142,7 +1158,7 @@ void wm_event_do_handlers(bContext *C)
while( (event= win->queue.first) ) {
int action;
-
+
CTX_wm_window_set(C, win);
/* we let modal handlers get active area/region, also wm_paintcursor_test needs it */
@@ -1152,61 +1168,73 @@ void wm_event_do_handlers(bContext *C)
/* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */
wm_window_make_drawable(C, win);
- action= wm_handlers_do(C, event, &win->handlers);
+ /* first we do priority handlers, modal + some limited keymaps */
+ action= wm_handlers_do(C, event, &win->modalhandlers);
/* fileread case */
- if(CTX_wm_window(C)==NULL) {
+ if(CTX_wm_window(C)==NULL)
return;
- }
/* builtin tweak, if action is break it removes tweak */
- if(!wm_event_always_pass(event))
- wm_tweakevent_test(C, event, action);
-
- if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
+ wm_tweakevent_test(C, event, action);
+
+ if(action==WM_HANDLER_CONTINUE) {
ScrArea *sa;
ARegion *ar;
int doit= 0;
/* XXX to solve, here screen handlers? */
- if(!wm_event_always_pass(event)) {
- if(event->type==MOUSEMOVE) {
- /* state variables in screen, cursors */
- ED_screen_set_subwinactive(win, event);
- /* for regions having custom cursors */
- wm_paintcursor_test(C, event);
- }
+ if(event->type==MOUSEMOVE) {
+ /* state variables in screen, cursors */
+ ED_screen_set_subwinactive(win, event);
+ /* for regions having custom cursors */
+ wm_paintcursor_test(C, event);
}
-
+
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
- if(wm_event_always_pass(event) || wm_event_inside_i(event, &sa->totrct)) {
-
+ if(wm_event_inside_i(event, &sa->totrct)) {
CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, NULL);
- action= wm_handlers_do(C, event, &sa->handlers);
- if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
+ if(action==WM_HANDLER_CONTINUE) {
for(ar=sa->regionbase.first; ar; ar= ar->next) {
- if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct)) {
+ if(wm_event_inside_i(event, &ar->winrct)) {
CTX_wm_region_set(C, ar);
action= wm_handlers_do(C, event, &ar->handlers);
doit |= (BLI_in_rcti(&ar->winrct, event->x, event->y));
- if(!wm_event_always_pass(event)) {
- if(action==WM_HANDLER_BREAK)
- break;
- }
+ if(action==WM_HANDLER_BREAK)
+ break;
}
}
}
+
+ CTX_wm_region_set(C, NULL);
+
+ if(action==WM_HANDLER_CONTINUE)
+ action= wm_handlers_do(C, event, &sa->handlers);
+
+ CTX_wm_area_set(C, NULL);
+
/* NOTE: do not escape on WM_HANDLER_BREAK, mousemove needs handled for previous area */
}
}
+ if(action==WM_HANDLER_CONTINUE) {
+ /* also some non-modal handlers need active area/region */
+ CTX_wm_area_set(C, area_event_inside(C, event->x, event->y));
+ CTX_wm_region_set(C, region_event_inside(C, event->x, event->y));
+
+ action= wm_handlers_do(C, event, &win->handlers);
+
+ /* fileread case */
+ if(CTX_wm_window(C)==NULL)
+ return;
+ }
+
/* XXX hrmf, this gives reliable previous mouse coord for area change, feels bad?
doing it on ghost queue gives errors when mousemoves go over area borders */
- if(doit && win->screen->subwinactive != win->screen->mainwin) {
+ if(doit && win->screen && win->screen->subwinactive != win->screen->mainwin) {
win->eventstate->prevx= event->x;
win->eventstate->prevy= event->y;
}
@@ -1219,7 +1247,7 @@ void wm_event_do_handlers(bContext *C)
}
/* only add mousemove when queue was read entirely */
- if(win->addmousemove) {
+ if(win->addmousemove && win->eventstate) {
wmEvent event= *(win->eventstate);
event.type= MOUSEMOVE;
event.prevx= event.x;
@@ -1250,7 +1278,7 @@ void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval)
}
}
-/* operator is supposed to have a filled "filename" property */
+/* operator is supposed to have a filled "path" property */
/* optional property: filetype (XXX enum?) */
/* Idea is to keep a handler alive on window queue, owning the operator.
@@ -1270,7 +1298,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
handler->op_region= CTX_wm_region(C);
handler->filescreen= CTX_wm_screen(C);
- BLI_addhead(&win->handlers, handler);
+ BLI_addhead(&win->modalhandlers, handler);
WM_event_fileselect_event(C, op, full?EVT_FILESELECT_FULL_OPEN:EVT_FILESELECT_OPEN);
}
@@ -1281,9 +1309,10 @@ void WM_event_set_handler_flag(wmEventHandler *handler, int flag)
handler->flag= flag;
}
-wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op)
+wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
{
wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event modal handler");
+ wmWindow *win= CTX_wm_window(C);
/* operator was part of macro */
if(op->opm) {
@@ -1298,15 +1327,20 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOp
handler->op_area= CTX_wm_area(C); /* means frozen screen context for modal handlers! */
handler->op_region= CTX_wm_region(C);
- BLI_addhead(handlers, handler);
+ BLI_addhead(&win->modalhandlers, handler);
return handler;
}
-wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap)
+wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
{
wmEventHandler *handler;
+ if(!keymap) {
+ printf("WM_event_add_keymap_handler called with NULL keymap\n");
+ return NULL;
+ }
+
/* only allow same keymap once */
for(handler= handlers->first; handler; handler= handler->next)
if(handler->keymap==keymap)
@@ -1320,7 +1354,7 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap
}
/* priorities not implemented yet, for time being just insert in begin of list */
-wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority)
+wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int priority)
{
wmEventHandler *handler;
@@ -1333,7 +1367,7 @@ wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBas
return handler;
}
-wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bblocal, rcti *bbwin)
+wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, rcti *bblocal, rcti *bbwin)
{
wmEventHandler *handler= WM_event_add_keymap_handler(handlers, keymap);
@@ -1344,7 +1378,7 @@ wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *key
return handler;
}
-void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap)
+void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
{
wmEventHandler *handler;
@@ -1497,10 +1531,10 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
const GHOST_TabletData *td= GHOST_GetTabletData(win->ghostwin);
/* if there's tablet data from an active tablet device then add it */
- if ((td != NULL) && td->Active) {
+ if ((td != NULL) && td->Active != GHOST_kTabletModeNone) {
struct wmTabletData *wmtab= MEM_mallocN(sizeof(wmTabletData), "customdata tablet");
- wmtab->Active = td->Active;
+ wmtab->Active = (int)td->Active;
wmtab->Pressure = td->Pressure;
wmtab->Xtilt = td->Xtilt;
wmtab->Ytilt = td->Ytilt;
@@ -1542,12 +1576,16 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
case GHOST_kEventButtonDown:
case GHOST_kEventButtonUp: {
GHOST_TEventButtonData *bd= customdata;
- event.val= (type==GHOST_kEventButtonDown);
+ event.val= (type==GHOST_kEventButtonDown) ? KM_PRESS:KM_RELEASE; /* Note!, this starts as 0/1 but later is converted to KM_PRESS/KM_RELEASE by tweak */
if (bd->button == GHOST_kButtonMaskLeft)
event.type= LEFTMOUSE;
else if (bd->button == GHOST_kButtonMaskRight)
event.type= RIGHTMOUSE;
+ else if (bd->button == GHOST_kButtonMaskButton4)
+ event.type= BUTTON4MOUSE;
+ else if (bd->button == GHOST_kButtonMaskButton5)
+ event.type= BUTTON5MOUSE;
else
event.type= MIDDLEMOUSE;
@@ -1565,7 +1603,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
event.val= (type==GHOST_kEventKeyDown)?KM_PRESS:KM_RELEASE;
/* exclude arrow keys, esc, etc from text input */
- if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>14))
+ if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>0))
event.ascii= '\0';
/* modifiers */
@@ -1595,6 +1633,13 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
else if(event.val==KM_RELEASE && event.keymodifier==event.type)
event.keymodifier= evt->keymodifier= 0;
}
+
+ /* this case happens on some systems that on holding a key pressed,
+ generate press events without release, we still want to keep the
+ modifier in win->eventstate, but for the press event of the same
+ key we don't want the key modifier */
+ if(event.keymodifier == event.type)
+ event.keymodifier= 0;
/* if test_break set, it catches this. XXX Keep global for now? */
if(event.type==ESCKEY)
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 9694a8fa1c6..1aca9a66e57 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -195,6 +195,7 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
/* ensure making new keymaps and set space types */
wm->initialized= 0;
+ wm->winactive= NULL;
/* only first wm in list has ghostwins */
for(win= wm->windows.first; win; win= win->next) {
@@ -202,6 +203,10 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
if(oldwin->winid == win->winid ) {
win->ghostwin= oldwin->ghostwin;
+ win->active= oldwin->active;
+ if(win->active)
+ wm->winactive= win;
+
GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */
oldwin->ghostwin= NULL;
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index b2cdddf5b63..b4328d12e81 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -78,7 +78,7 @@
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "ED_node.h"
-#include "ED_previewrender.h"
+#include "ED_render.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_util.h"
@@ -90,6 +90,7 @@
#include "GPU_extensions.h"
#include "GPU_draw.h"
+#include "BKE_depsgraph.h"
#include "BKE_sound.h"
static void wm_init_reports(bContext *C)
@@ -113,6 +114,7 @@ void WM_init(bContext *C)
set_free_windowmanager_cb(wm_close_and_free); /* library.c */
set_blender_test_break_cb(wm_window_testbreak); /* blender.c */
+ DAG_editors_update_cb(ED_render_id_flush_update); /* depsgraph.c */
ED_spacetypes_init(); /* editors/space_api/spacetype.c */
@@ -129,6 +131,8 @@ void WM_init(bContext *C)
wm_init_reports(C); /* reports cant be initialized before the wm */
+ GPU_extensions_init();
+
UI_init();
// clear_matcopybuf(); /* XXX */
@@ -139,8 +143,6 @@ void WM_init(bContext *C)
ED_preview_init_dbase();
- GPU_extensions_init();
-
G.ndofdevice = -1; /* XXX bad initializer, needs set otherwise buttons show! */
read_Blog();
@@ -167,6 +169,7 @@ extern wchar_t *copybufinfo;
// XXX copy/paste buffer stuff...
extern void free_anim_copybuf();
+extern void free_anim_drivers_copybuf();
extern void free_posebuf();
/* called in creator.c even... tsk, split this! */
@@ -187,6 +190,7 @@ void WM_exit(bContext *C)
CTX_wm_window_set(C, win); /* needed by operator close callbacks */
WM_event_remove_handlers(C, &win->handlers);
+ WM_event_remove_handlers(C, &win->modalhandlers);
ED_screen_exit(C, win, win->screen);
}
}
@@ -213,6 +217,7 @@ void WM_exit(bContext *C)
free_blender(); /* blender.c, does entire library and spacetypes */
// free_matcopybuf();
free_anim_copybuf();
+ free_anim_drivers_copybuf();
free_posebuf();
// free_vertexpaint();
// free_imagepaint();
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index bef3268920d..9e16ce4082f 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -107,6 +107,7 @@ struct wmJob {
/* internal */
void *owner;
+ int flag;
short suspended, running, ready, do_update, stop;
/* once running, we store this separately */
@@ -123,7 +124,7 @@ struct wmJob {
/* returns current or adds new job, but doesnt run it */
/* every owner only gets a single job, adding a new one will stop running stop and
when stopped it starts the new one */
-wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner)
+wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, int flag)
{
wmJob *steve;
@@ -137,6 +138,7 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner)
BLI_addtail(&wm->jobs, steve);
steve->win= win;
steve->owner= owner;
+ steve->flag= flag;
}
return steve;
@@ -198,20 +200,25 @@ static void *do_job_thread(void *job_v)
}
/* dont allow same startjob to be executed twice */
-static void wm_jobs_test_suspend(wmWindowManager *wm, wmJob *test)
+static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
{
wmJob *steve;
+ int suspend= 0;
- for(steve= wm->jobs.first; steve; steve= steve->next)
- if(steve!=test)
- if(steve->running)
- if(steve->startjob==test->startjob)
- break;
-
- if(steve)
- test->suspended= 1;
- else
- test->suspended= 0;
+ for(steve= wm->jobs.first; steve; steve= steve->next) {
+ if(steve==test || !steve->running) continue;
+ if(steve->startjob!=test->startjob && !(test->flag & WM_JOB_EXCL_RENDER)) continue;
+ if((test->flag & WM_JOB_EXCL_RENDER) && !(steve->flag & WM_JOB_EXCL_RENDER)) continue;
+
+ suspend= 1;
+
+ /* if this job has higher priority, stop others */
+ if(test->flag & WM_JOB_PRIORITY)
+ steve->stop= 1;
+ }
+
+ /* possible suspend ourselfs, waiting for other jobs, or de-suspend */
+ test->suspended= suspend;
}
/* if job running, the same owner gave it a new job */
@@ -225,7 +232,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
else {
if(steve->customdata && steve->startjob) {
- wm_jobs_test_suspend(wm, steve);
+ wm_jobs_test_suspend_stop(wm, steve);
if(steve->suspended==0) {
/* copy to ensure proper free in end */
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 5566aeba260..7d25fb8172e 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -96,17 +96,17 @@ static void keymap_properties_set(wmKeymapItem *kmi)
}
/* if item was added, then bail out */
-wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
+wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier)
{
wmKeymapItem *kmi;
- for(kmi= lb->first; kmi; kmi= kmi->next)
+ for(kmi= keymap->keymap.first; kmi; kmi= kmi->next)
if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0)
break;
if(kmi==NULL) {
kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry");
- BLI_addtail(lb, kmi);
+ BLI_addtail(&keymap->keymap, kmi);
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
keymap_event_set(kmi, type, val, modifier, keymodifier);
@@ -116,11 +116,11 @@ wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, shor
}
/* always add item */
-wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
+wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier)
{
wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry");
- BLI_addtail(lb, kmi);
+ BLI_addtail(&keymap->keymap, kmi);
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
keymap_event_set(kmi, type, val, modifier, keymodifier);
@@ -134,14 +134,14 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short v
space/region ids are same as DNA_space_types.h */
/* gets free'd in wm.c */
-static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short spaceid, short regionid)
+wmKeyMap *WM_keymap_find(wmWindowManager *wm, const char *nameid, short spaceid, short regionid)
{
wmKeyMap *km;
for(km= wm->keymaps.first; km; km= km->next)
if(km->spaceid==spaceid && km->regionid==regionid)
if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME))
- break;
+ return km;
if(km==NULL) {
km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
@@ -154,19 +154,13 @@ static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short sp
return km;
}
-ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, short spaceid, short regionid)
-{
- wmKeyMap *km= wm_keymap_add(wm, nameid, spaceid, regionid);
- return &km->keymap;
-}
-
/* ****************** modal keymaps ************ */
/* modal maps get linked to a running operator, and filter the keys before sending to modal() callback */
wmKeyMap *WM_modalkeymap_add(wmWindowManager *wm, const char *nameid, EnumPropertyItem *items)
{
- wmKeyMap *km= wm_keymap_add(wm, nameid, 0, 0);
+ wmKeyMap *km= WM_keymap_find(wm, nameid, 0, 0);
km->is_modal= 1;
km->items= items;
@@ -242,15 +236,18 @@ static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len)
return str;
}
-static wmKeymapItem *wm_keymap_item_find_handlers(ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props)
+static wmKeymapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props)
{
wmEventHandler *handler;
+ wmKeyMap *keymap;
wmKeymapItem *kmi;
/* find keymap item in handlers */
for(handler=handlers->first; handler; handler=handler->next) {
- if(handler->keymap) {
- for(kmi=handler->keymap->first; kmi; kmi=kmi->next) {
+ keymap= handler->keymap;
+
+ if(keymap && (!keymap->poll || keymap->poll((bContext*)C))) {
+ for(kmi=keymap->keymap.first; kmi; kmi=kmi->next) {
if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) {
if(compare_props) {
if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data))
@@ -272,11 +269,11 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname,
/* look into multiple handler lists to find the item */
if(CTX_wm_window(C))
- found= wm_keymap_item_find_handlers(&CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props);
+ found= wm_keymap_item_find_handlers(C, &CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props);
if(CTX_wm_area(C) && found==NULL)
- found= wm_keymap_item_find_handlers(&CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props);
+ found= wm_keymap_item_find_handlers(C, &CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props);
if(found==NULL) {
if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) {
@@ -287,12 +284,12 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname,
break;
if(ar)
- found= wm_keymap_item_find_handlers(&ar->handlers, opname, opcontext, properties, compare_props);
+ found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props);
}
}
else {
if(CTX_wm_region(C))
- found= wm_keymap_item_find_handlers(&CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props);
+ found= wm_keymap_item_find_handlers(C, &CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props);
}
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 37cd424ac18..2c124437eb2 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include "DNA_ID.h"
+#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
@@ -46,12 +47,16 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
+#include "BLO_readfile.h"
+
#include "BKE_blender.h"
#include "BKE_context.h"
+#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_utildefines.h"
@@ -242,7 +247,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag)
ot->idname= idname;
ot->name= name;
- ot->flag= OPTYPE_MACRO | flag;
+ ot->flag= OPTYPE_MACRO|flag;
ot->exec= wm_macro_exec;
ot->invoke= wm_macro_invoke;
@@ -496,10 +501,10 @@ int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
}
-/* op->invoke, opens fileselect if filename property not set, otherwise executes */
+/* op->invoke, opens fileselect if path property not set, otherwise executes */
int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event)
{
- if (RNA_property_is_set(op->ptr, "filename")) {
+ if (RNA_property_is_set(op->ptr, "path")) {
return WM_operator_call(C, op);
}
else {
@@ -509,9 +514,11 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event)
}
/* default properties for fileselect */
-void WM_operator_properties_filesel(wmOperatorType *ot, int filter)
+void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type)
{
- RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "Path to file.");
+ RNA_def_string_file_path(ot->srna, "path", "", FILE_MAX, "FilePath", "Path to file.");
+ RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "FileName", "Name of the file.");
+ RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Directory of the file.");
RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", "");
RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", "");
@@ -521,6 +528,10 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter)
RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", "");
RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", "");
RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", "");
+
+ RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL,
+ "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file.",
+ FILE_LOADLIB, FILE_SPECIAL);
}
/* op->poll */
@@ -531,7 +542,7 @@ int WM_operator_winactive(bContext *C)
}
/* op->invoke */
-static void redo_cb(bContext *C, void *arg_op, void *arg2)
+static void redo_cb(bContext *C, void *arg_op, int event)
{
wmOperator *lastop= arg_op;
@@ -553,7 +564,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS);
uiBlockClearFlag(block, UI_BLOCK_LOOP);
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1);
- uiBlockSetFunc(block, redo_cb, arg_op, NULL);
+ uiBlockSetHandleFunc(block, redo_cb, arg_op);
if(!op->properties) {
IDPropertyTemplate val = {0};
@@ -671,7 +682,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u
for(; ot; ot= ot->next) {
if(BLI_strcasestr(ot->name, str)) {
- if(ot->poll==NULL || ot->poll((bContext *)C)) {
+ if(WM_operator_poll((bContext*)C, ot)) {
char name[256];
int len= strlen(ot->name);
@@ -736,11 +747,12 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* op->poll */
-int wm_search_menu_poll(bContext *C)
+static int wm_search_menu_poll(bContext *C)
{
if(CTX_wm_window(C)==NULL) return 0;
if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_CONSOLE) return 0; // XXX - so we can use the shortcut in the console
if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_TEXT) return 0; // XXX - so we can use the spacebar in the text editor
+ if(CTX_data_edit_object(C) && CTX_data_edit_object(C)->type==OB_CURVE) return 0; // XXX - so we can use the spacebar for entering text
return 1;
}
@@ -869,21 +881,9 @@ static void WM_OT_open_recentfile(wmOperatorType *ot)
RNA_def_enum_funcs(prop, open_recentfile_itemf);
}
-/* ********* main file *********** */
+/* *************** open file **************** */
-static void untitled(char *name)
-{
- if (G.save_over == 0 && strlen(name) < FILE_MAX-16) {
- char *c= BLI_last_slash(name);
-
- if (c)
- strcpy(&c[1], "untitled.blend");
- else
- strcpy(name, "untitled.blend");
- }
-}
-
-static void load_set_load_ui(wmOperator *op)
+static void open_set_load_ui(wmOperator *op)
{
if(!RNA_property_is_set(op->ptr, "load_ui"))
RNA_boolean_set(op->ptr, "load_ui", !(U.flag & USER_FILENOUI));
@@ -891,8 +891,8 @@ static void load_set_load_ui(wmOperator *op)
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- RNA_string_set(op->ptr, "filename", G.sce);
- load_set_load_ui(op);
+ RNA_string_set(op->ptr, "path", G.sce);
+ open_set_load_ui(op);
WM_event_add_fileselect(C, op);
@@ -901,10 +901,10 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
{
- char filename[FILE_MAX];
+ char path[FILE_MAX];
- RNA_string_get(op->ptr, "filename", filename);
- load_set_load_ui(op);
+ RNA_string_get(op->ptr, "path", path);
+ open_set_load_ui(op);
if(RNA_boolean_get(op->ptr, "load_ui"))
G.fileflags &= ~G_FILE_NO_UI;
@@ -915,7 +915,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
// do it before for now, but is this correct with multiple windows?
WM_event_add_notifier(C, NC_WINDOW, NULL);
- WM_read_file(C, filename, op->reports);
+ WM_read_file(C, path, op->reports);
return 0;
}
@@ -930,11 +930,171 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->exec= wm_open_mainfile_exec;
ot->poll= WM_operator_winactive;
- WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file.");
}
+/* **************** link/append *************** */
+
+static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if(RNA_property_is_set(op->ptr, "path")) {
+ return WM_operator_call(C, op);
+ }
+ else {
+ /* XXX TODO solve where to get last linked library from */
+ RNA_string_set(op->ptr, "path", G.lib);
+ WM_event_add_fileselect(C, op);
+ return OPERATOR_RUNNING_MODAL;
+ }
+}
+
+static short wm_link_append_flag(wmOperator *op)
+{
+ short flag= 0;
+
+ if(RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT;
+ if(RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY;
+ if(RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE;
+ if(RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK;
+
+ return flag;
+}
+
+static void wm_link_make_library_local(Main *main, const char *libname)
+{
+ Library *lib;
+
+ /* and now find the latest append lib file */
+ for(lib= main->library.first; lib; lib=lib->id.next)
+ if(BLI_streq(libname, lib->filename))
+ break;
+
+ /* make local */
+ if(lib) {
+ all_local(lib, 1);
+ /* important we unset, otherwise these object wont
+ * link into other scenes from this blend file */
+ flag_all_listbases_ids(LIB_APPEND_TAG, 0);
+ }
+}
+
+static int wm_link_append_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain= CTX_data_main(C);
+ Scene *scene= CTX_data_scene(C);
+ Main *mainl= 0;
+ BlendHandle *bh;
+ PropertyRNA *prop;
+ char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX];
+ int idcode, totfiles=0;
+ short flag;
+
+ name[0] = '\0';
+ RNA_string_get(op->ptr, "filename", name);
+ RNA_string_get(op->ptr, "directory", dir);
+
+ /* test if we have a valid data */
+ if(BLO_is_a_library(dir, libname, group) == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Not a library");
+ return OPERATOR_CANCELLED;
+ }
+ else if(group[0] == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+ return OPERATOR_CANCELLED;
+ }
+ else if(BLI_streq(bmain->name, libname)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* check if something is indicated for append/link */
+ prop = RNA_struct_find_property(op->ptr, "files");
+ if(prop) {
+ totfiles= RNA_property_collection_length(op->ptr, prop);
+ if(totfiles == 0) {
+ if(name[0] == '\0') {
+ BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+ return OPERATOR_CANCELLED;
+ }
+ }
+ }
+ else if(name[0] == '\0') {
+ BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* now we have or selected, or an indicated file */
+ if(RNA_boolean_get(op->ptr, "autoselect"))
+ scene_deselect_all(scene);
+
+ bh = BLO_blendhandle_from_file(libname);
+ idcode = BLO_idcode_from_name(group);
+
+ flag = wm_link_append_flag(op);
+
+ /* tag everything, all untagged data can be made local */
+ if((flag & FILE_LINK)==0)
+ flag_all_listbases_ids(LIB_APPEND_TAG, 1);
+
+ /* here appending/linking starts */
+ mainl = BLO_library_append_begin(C, &bh, libname);
+ if(totfiles == 0) {
+ BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag);
+ }
+ else {
+ RNA_BEGIN(op->ptr, itemptr, "files") {
+ RNA_string_get(&itemptr, "name", name);
+ BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag);
+ }
+ RNA_END;
+ }
+ BLO_library_append_end(C, mainl, &bh, idcode, flag);
+
+ /* mark all library linked objects to be updated */
+ recalc_all_library_objects(bmain);
+
+ /* append, rather than linking */
+ if((flag & FILE_LINK)==0)
+ wm_link_make_library_local(bmain, libname);
+
+ /* recreate dependency graph to include new objects */
+ DAG_scene_sort(scene);
+ DAG_ids_flush_update(0);
+
+ BLO_blendhandle_close(bh);
+
+ /* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */
+ BLI_strncpy(G.lib, dir, FILE_MAX);
+
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_link_append(wmOperatorType *ot)
+{
+ ot->name= "Link/Append from Library";
+ ot->idname= "WM_OT_link_append";
+ ot->description= "Link or Append from a Library .blend file";
+
+ ot->invoke= wm_link_append_invoke;
+ ot->exec= wm_link_append_exec;
+ ot->poll= WM_operator_winactive;
+
+ WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB);
+
+ RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending.");
+ RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects.");
+ RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer.");
+ RNA_def_boolean(ot->srna, "relative_paths", 1, "Relative Paths", "Store the library path as a relative path to current .blend file.");
+
+ RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
+}
+
+/* *************** recover last session **************** */
+
static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
{
char scestr[FILE_MAX], filename[FILE_MAX];
@@ -969,6 +1129,20 @@ static void WM_OT_recover_last_session(wmOperatorType *ot)
ot->poll= WM_operator_winactive;
}
+/* *************** save file as **************** */
+
+static void untitled(char *name)
+{
+ if(G.save_over == 0 && strlen(name) < FILE_MAX-16) {
+ char *c= BLI_last_slash(name);
+
+ if(c)
+ strcpy(&c[1], "untitled.blend");
+ else
+ strcpy(name, "untitled.blend");
+ }
+}
+
static void save_set_compress(wmOperator *op)
{
if(!RNA_property_is_set(op->ptr, "compress")) {
@@ -987,7 +1161,7 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even
BLI_strncpy(name, G.sce, FILE_MAX);
untitled(name);
- RNA_string_set(op->ptr, "filename", name);
+ RNA_string_set(op->ptr, "path", name);
WM_event_add_fileselect(C, op);
@@ -997,20 +1171,20 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even
/* function used for WM_OT_save_mainfile too */
static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
{
- char filename[FILE_MAX];
+ char path[FILE_MAX];
int compress;
save_set_compress(op);
compress= RNA_boolean_get(op->ptr, "compress");
- if(RNA_property_is_set(op->ptr, "filename"))
- RNA_string_get(op->ptr, "filename", filename);
+ if(RNA_property_is_set(op->ptr, "path"))
+ RNA_string_get(op->ptr, "path", path);
else {
- BLI_strncpy(filename, G.sce, FILE_MAX);
- untitled(filename);
+ BLI_strncpy(path, G.sce, FILE_MAX);
+ untitled(path);
}
- WM_write_file(C, filename, compress, op->reports);
+ WM_write_file(C, path, compress, op->reports);
WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL);
@@ -1027,11 +1201,11 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
ot->exec= wm_save_as_mainfile_exec;
ot->poll= WM_operator_winactive;
- WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
}
-/* *************** Save file directly ******** */
+/* *************** save file directly ******** */
static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
@@ -1041,7 +1215,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
BLI_strncpy(name, G.sce, FILE_MAX);
untitled(name);
- RNA_string_set(op->ptr, "filename", name);
+ RNA_string_set(op->ptr, "path", name);
uiPupMenuSaveOver(C, op, name);
return OPERATOR_RUNNING_MODAL;
@@ -1057,7 +1231,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
ot->exec= wm_save_as_mainfile_exec;
ot->poll= WM_operator_winactive;
- WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE);
+ WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
}
@@ -1194,7 +1368,7 @@ int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
wm_gesture_tag_redraw(C);
@@ -1258,7 +1432,7 @@ int WM_gesture_circle_invoke(bContext *C, wmOperator *op, wmEvent *event)
op->customdata= WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
wm_gesture_tag_redraw(C);
@@ -1311,7 +1485,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
- if(event->val==0) { /* key release */
+ if(event->val==KM_RELEASE) { /* key release */
wm_gesture_end(C, op);
return OPERATOR_FINISHED;
}
@@ -1394,7 +1568,7 @@ static void tweak_gesture_modal(bContext *C, wmEvent *event)
if(gesture->event_type==event->type) {
WM_gesture_end(C, gesture);
window->tweak= NULL;
-
+
/* when tweak fails we should give the other keymap entries a chance */
event->val= KM_RELEASE;
}
@@ -1412,7 +1586,7 @@ void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
if(win->tweak==NULL) {
if(CTX_wm_region(C)) {
- if(event->val) { // pressed
+ if(event->val==KM_PRESS) { // pressed
if( ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) )
win->tweak= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
}
@@ -1435,7 +1609,7 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event)
op->customdata= WM_gesture_new(C, event, WM_GESTURE_LASSO);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
wm_gesture_tag_redraw(C);
@@ -1450,7 +1624,7 @@ int WM_gesture_lines_invoke(bContext *C, wmOperator *op, wmEvent *event)
op->customdata= WM_gesture_new(C, event, WM_GESTURE_LINES);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
wm_gesture_tag_redraw(C);
@@ -1512,7 +1686,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
- if(event->val==0) { /* key release */
+ if(event->val==KM_RELEASE) { /* key release */
gesture_lasso_apply(C, op, event->type);
return OPERATOR_FINISHED;
}
@@ -1757,7 +1931,7 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
wm_radial_control_paint, op->customdata);
/* add modal handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
WM_radial_control_modal(C, op, event);
@@ -1805,17 +1979,19 @@ void WM_OT_radial_control_partial(wmOperatorType *ot)
/* uses no type defines, fully local testing function anyway... ;) */
-static int ten_timer_exec(bContext *C, wmOperator *op)
+static int redraw_timer_exec(bContext *C, wmOperator *op)
{
ARegion *ar= CTX_wm_region(C);
double stime= PIL_check_seconds_timer();
int type = RNA_int_get(op->ptr, "type");
- int a, time;
- char tmpstr[128];
+ int iter = RNA_int_get(op->ptr, "iterations");
+ int a;
+ float time;
+ char *infostr= "";
WM_cursor_wait(1);
-
- for(a=0; a<10; a++) {
+
+ for(a=0; a<iter; a++) {
if (type==0) {
ED_region_do_draw(C, ar);
}
@@ -1831,13 +2007,35 @@ static int ten_timer_exec(bContext *C, wmOperator *op)
wmWindow *win= CTX_wm_window(C);
ScrArea *sa;
+ ScrArea *sa_back= CTX_wm_area(C);
+ ARegion *ar_back= CTX_wm_region(C);
+
+ for(sa= CTX_wm_screen(C)->areabase.first; sa; sa= sa->next) {
+ ARegion *ar_iter;
+ CTX_wm_area_set(C, sa);
+
+ for(ar_iter= sa->regionbase.first; ar_iter; ar_iter= ar_iter->next) {
+ CTX_wm_region_set(C, ar_iter);
+ ED_region_do_draw(C, ar_iter);
+ }
+ }
+
+ CTX_wm_window_set(C, win); /* XXX context manipulation warning! */
+
+ CTX_wm_area_set(C, sa_back);
+ CTX_wm_region_set(C, ar_back);
+ }
+ else if (type==3) {
+ wmWindow *win= CTX_wm_window(C);
+ ScrArea *sa;
+
for(sa= CTX_wm_screen(C)->areabase.first; sa; sa= sa->next)
ED_area_tag_redraw(sa);
wm_draw_update(C);
CTX_wm_window_set(C, win); /* XXX context manipulation warning! */
}
- else if (type==3) {
+ else if (type==4) {
Scene *scene= CTX_data_scene(C);
if(a & 1) scene->r.cfra--;
@@ -1850,40 +2048,44 @@ static int ten_timer_exec(bContext *C, wmOperator *op)
}
}
- time= (int) ((PIL_check_seconds_timer()-stime)*1000);
+ time= ((PIL_check_seconds_timer()-stime)*1000);
- if(type==0) sprintf(tmpstr, "10 x Draw Region: %d ms", time);
- if(type==1) sprintf(tmpstr, "10 x Draw Region and Swap: %d ms", time);
- if(type==2) sprintf(tmpstr, "10 x Draw Window and Swap: %d ms", time);
- if(type==3) sprintf(tmpstr, "Anim Step: %d ms", time);
- if(type==4) sprintf(tmpstr, "10 x Undo/Redo: %d ms", time);
+ if(type==0) infostr= "Draw Region";
+ if(type==1) infostr= "Draw Region and Swap";
+ if(type==2) infostr= "Draw Window";
+ if(type==3) infostr= "Draw Window and Swap";
+ if(type==4) infostr= "Animation Steps";
+ if(type==5) infostr= "Undo/Redo";
WM_cursor_wait(0);
- uiPupMenuNotice(C, tmpstr);
+ BKE_reportf(op->reports, RPT_INFO, "%d x %s: %.2f ms, average: %.4f", iter, infostr, time, time/iter);
return OPERATOR_FINISHED;
}
-static void WM_OT_ten_timer(wmOperatorType *ot)
+static void WM_OT_redraw_timer(wmOperatorType *ot)
{
static EnumPropertyItem prop_type_items[] = {
{0, "DRAW", 0, "Draw Region", ""},
- {1, "DRAWSWAP", 0, "Draw Region + Swap", ""},
- {2, "DRAWWINSWAP", 0, "Draw Window + Swap", ""},
- {3, "ANIMSTEP", 0, "Anim Step", ""},
- {4, "UNDO", 0, "Undo/Redo", ""},
+ {1, "DRAW_SWAP", 0, "Draw Region + Swap", ""},
+ {2, "DRAW_WIN", 0, "Draw Window", ""},
+ {3, "DRAW_WIN_SWAP", 0, "Draw Window + Swap", ""},
+ {4, "ANIM_STEP", 0, "Anim Step", ""},
+ {5, "UNDO", 0, "Undo/Redo", ""},
{0, NULL, 0, NULL, NULL}};
- ot->name= "Ten Timer";
- ot->idname= "WM_OT_ten_timer";
+ ot->name= "Redraw Timer";
+ ot->idname= "WM_OT_redraw_timer";
+ ot->description="Simple redraw timer to test the speed of updating the interface.";
ot->description="Ten Timer operator.";
ot->invoke= WM_menu_invoke;
- ot->exec= ten_timer_exec;
+ ot->exec= redraw_timer_exec;
ot->poll= WM_operator_winactive;
RNA_def_enum(ot->srna, "type", prop_type_items, 0, "Type", "");
+ RNA_def_int(ot->srna, "iterations", 10, 1,INT_MAX, "Iterations", "Number of times to redraw", 1,1000);
}
@@ -1913,11 +2115,12 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_exit_blender);
WM_operatortype_append(WM_OT_open_recentfile);
WM_operatortype_append(WM_OT_open_mainfile);
+ WM_operatortype_append(WM_OT_link_append);
WM_operatortype_append(WM_OT_recover_last_session);
WM_operatortype_append(WM_OT_jobs_timer);
WM_operatortype_append(WM_OT_save_as_mainfile);
WM_operatortype_append(WM_OT_save_mainfile);
- WM_operatortype_append(WM_OT_ten_timer);
+ WM_operatortype_append(WM_OT_redraw_timer);
WM_operatortype_append(WM_OT_debug_menu);
WM_operatortype_append(WM_OT_search_menu);
}
@@ -1925,7 +2128,7 @@ void wm_operatortype_init(void)
/* default keymap for windows and screens, only call once per WM */
void wm_window_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Window", 0, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm, "Window", 0, 0);
/* items to make WM work */
WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0);
@@ -1944,6 +2147,7 @@ void wm_window_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
@@ -1951,7 +2155,7 @@ void wm_window_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
/* debug/testing */
- WM_keymap_verify_item(keymap, "WM_OT_ten_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "WM_OT_redraw_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index d70516ef02e..c853afe4507 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -146,6 +146,7 @@ void wm_window_free(bContext *C, wmWindow *win)
CTX_wm_window_set(C, NULL);
WM_event_remove_handlers(C, &win->handlers);
+ WM_event_remove_handlers(C, &win->modalhandlers);
/* end running jobs, a job end also removes its timer */
for(wt= win->timers.first; wt; wt= wtnext) {
@@ -331,7 +332,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow
/* called in wm_check, also inits stuff after file read */
void wm_window_add_ghostwindows(wmWindowManager *wm)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
wmWindow *win;
/* no commandline prefsize? then we set this */
@@ -367,11 +368,14 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state");
/* add keymap handlers (1 handler for all keys in map!) */
- keymap= WM_keymap_listbase(wm, "Window", 0, 0);
+ keymap= WM_keymap_find(wm, "Window", 0, 0);
WM_event_add_keymap_handler(&win->handlers, keymap);
- keymap= WM_keymap_listbase(wm, "Screen", 0, 0);
+ keymap= WM_keymap_find(wm, "Screen", 0, 0);
WM_event_add_keymap_handler(&win->handlers, keymap);
+
+ keymap= WM_keymap_find(wm, "Screen Editing", 0, 0);
+ WM_event_add_keymap_handler(&win->modalhandlers, keymap);
wm_window_title(wm, win);
}
@@ -623,6 +627,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
if(state!=GHOST_kWindowStateMinimized) {
GHOST_RectangleHandle client_rect;
int l, t, r, b, scr_w, scr_h;
+ int sizex, sizey, posx, posy;
client_rect= GHOST_GetClientBounds(win->ghostwin);
GHOST_GetRectangle(client_rect, &l, &t, &r, &b);
@@ -630,37 +635,56 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
GHOST_DisposeRectangle(client_rect);
wm_get_screensize(&scr_w, &scr_h);
- win->sizex= r-l;
- win->sizey= b-t;
- win->posx= l;
- win->posy= scr_h - t - win->sizey;
-
- /* debug prints */
- if(0) {
- state = GHOST_GetWindowState(win->ghostwin);
-
- if(state==GHOST_kWindowStateNormal) {
- if(G.f & G_DEBUG) printf("window state: normal\n");
- }
- else if(state==GHOST_kWindowStateMinimized) {
- if(G.f & G_DEBUG) printf("window state: minimized\n");
- }
- else if(state==GHOST_kWindowStateMaximized) {
- if(G.f & G_DEBUG) printf("window state: maximized\n");
+ sizex= r-l;
+ sizey= b-t;
+ posx= l;
+ posy= scr_h - t - win->sizey;
+
+ /*
+ * Ghost sometimes send size or move events when the window hasn't changed.
+ * One case of this is using compiz on linux. To alleviate the problem
+ * we ignore all such event here.
+ *
+ * It might be good to eventually do that at Ghost level, but that is for
+ * another time.
+ */
+ if (win->sizex != sizex ||
+ win->sizey != sizey ||
+ win->posx != posx ||
+ win->posy != posy)
+ {
+ win->sizex= sizex;
+ win->sizey= sizey;
+ win->posx= posx;
+ win->posy= posy;
+
+ /* debug prints */
+ if(0) {
+ state = GHOST_GetWindowState(win->ghostwin);
+
+ if(state==GHOST_kWindowStateNormal) {
+ if(G.f & G_DEBUG) printf("window state: normal\n");
+ }
+ else if(state==GHOST_kWindowStateMinimized) {
+ if(G.f & G_DEBUG) printf("window state: minimized\n");
+ }
+ else if(state==GHOST_kWindowStateMaximized) {
+ if(G.f & G_DEBUG) printf("window state: maximized\n");
+ }
+ else if(state==GHOST_kWindowStateFullScreen) {
+ if(G.f & G_DEBUG) printf("window state: fullscreen\n");
+ }
+
+ if(type!=GHOST_kEventWindowSize) {
+ if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey);
+ }
+
}
- else if(state==GHOST_kWindowStateFullScreen) {
- if(G.f & G_DEBUG) printf("window state: fullscreen\n");
- }
-
- if(type!=GHOST_kEventWindowSize) {
- if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey);
- }
-
+
+ wm_window_make_drawable(C, win);
+ wm_draw_window_clear(win);
+ WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
}
-
- wm_window_make_drawable(C, win);
- wm_draw_window_clear(win);
- WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
}
break;
}
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 9a3bba9af1d..4360e49e371 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -43,7 +43,7 @@ typedef struct wmEventHandler {
int type, flag; /* type default=0, rest is custom */
/* keymap handler */
- ListBase *keymap; /* pointer to builtin/custom keymaps */
+ wmKeyMap *keymap; /* pointer to builtin/custom keymaps */
rcti *bblocal, *bbwin; /* optional local and windowspace bb */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 3da621bda85..cc6041ce529 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -40,7 +40,7 @@
#define EVT_DATA_GESTURE 2
#define EVT_DATA_TIMER 3
-/* tablet active */
+/* tablet active, matches GHOST_TTabletMode */
#define EVT_TABLET_NONE 0
#define EVT_TABLET_STYLUS 1
#define EVT_TABLET_ERASER 2
@@ -56,6 +56,9 @@
/* only use if you want user option switch possible */
#define ACTIONMOUSE 0x005
#define SELECTMOUSE 0x006
+/* Extra mouse buttons */
+#define BUTTON4MOUSE 0x007
+#define BUTTON5MOUSE 0x008
/* defaults from ghost */
#define WHEELUPMOUSE 0x00a
#define WHEELDOWNMOUSE 0x00b
@@ -191,10 +194,13 @@
/* for event checks */
/* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */
-#define ISKEYBOARD(event) (event >=' ' && event <=255)
+#define ISTEXTINPUT(event) (event >=' ' && event <=255)
+
+ /* test wether the event is a key on the keyboard */
+#define ISKEYBOARD(event) (event >=' ' && event <=320)
/* test whether event type is acceptable as hotkey, excluding modifiers */
-#define ISHOTKEY(event) (event >=' ' && event <=320 && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY))
+#define ISHOTKEY(event) (ISKEYBOARD(event) && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY))
/* **************** BLENDER GESTURE EVENTS ********************* */
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index c1585a71ac1..8b6143467b9 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -95,6 +95,7 @@ char *ED_info_stats_string(struct Scene *scene){return NULL;}
void ED_area_tag_redraw(struct ScrArea *sa){}
void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op){}
void ED_node_texture_default(struct Tex *tx){}
+void ED_node_changed_update(struct bContext *C, struct bNode *node){}
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){}
@@ -112,6 +113,18 @@ void uiLayoutSetEnabled(struct uiLayout *layout, int enabled){}
void uiLayoutSetAlignment(struct uiLayout *layout, int alignment){}
void uiLayoutSetScaleX(struct uiLayout *layout, float scale){}
void uiLayoutSetScaleY(struct uiLayout *layout, float scale){}
+void ED_base_object_free_and_unlink(struct Scene *scene, struct Base *base){}
+void ED_mesh_calc_normals(struct Mesh *me){}
+void ED_mesh_geometry_add(struct Mesh *mesh, struct ReportList *reports, int verts, int edges, int faces){}
+void ED_mesh_material_add(struct Mesh *me, struct Material *ma){}
+void ED_mesh_transform(struct Mesh *me, float *mat){}
+void ED_mesh_update(struct Mesh *mesh, struct bContext *C){}
+int ED_mesh_uv_texture_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me){return 0;}
+void ED_object_apply_obmat(struct Object *ob){}
+void ED_object_constraint_dependency_update(struct Scene *scene, struct Object *ob){}
+void ED_object_constraint_update(struct Object *ob){}
+struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, char *name){return (struct bDeformGroup *) NULL;}
+void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode){}
void uiItemR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int flag){}
@@ -154,6 +167,7 @@ void uiTemplateOperatorSearch(struct uiLayout *layout){}
void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C){}
void uiTemplate_view3d_select_faceselmenu(struct uiLayout *layout, struct bContext *C){}
void uiTemplateTextureImage(struct uiLayout *layout, struct bContext *C, struct Tex *tex){}
+void uiTemplateImage(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *userptr, int compact){}
/* rna render */
struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;}
@@ -170,11 +184,13 @@ struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *)
struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;}
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;}
int WM_operatortype_remove(const char *idname){return 0;}
+int WM_operator_poll(struct bContext *C, struct wmOperatorType *ot){return 0;}
void WM_operator_properties_free(struct PointerRNA *ptr){}
void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){}
void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){}
void WM_operator_bl_idname(char *to, const char *from){}
short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;}
+char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args){return NULL;}
/* smoke */
void lzo1x_1_compress(void) {return;}
@@ -198,3 +214,5 @@ void smoke_get_velocity_z(void) {return;}
void smoke_get_obstacle(void) {return;}
void smoke_get_index(void) {return;}
void smoke_step(void) {return;}
+
+char blender_path(){return NULL;} \ No newline at end of file
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 1256881182b..bef41983bab 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -24,6 +24,9 @@
#
# ***** END GPL LICENSE BLOCK *****
+# So BUILDINFO and BLENDERPATH strings are automatically quoted
+CMAKE_POLICY(SET CMP0005 NEW)
+
SETUP_LIBDIRS()
INCLUDE_DIRECTORIES(../../intern/guardedalloc
@@ -66,19 +69,37 @@ IF(NOT WITH_SDL)
ADD_DEFINITIONS(-DDISABLE_SDL)
ENDIF(NOT WITH_SDL)
+IF(UNIX AND NOT APPLE)
+ SET(BLENDERPATH ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION})
+ # blender_path in creator.c
+ ADD_DEFINITIONS(-DBLENDERPATH="${BLENDERPATH}")
+ENDIF(UNIX AND NOT APPLE)
+
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
ADD_DEFINITIONS(-DWITH_BINRELOC)
INCLUDE_DIRECTORIES(${BINRELOC_INC})
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
-MESSAGE(STATUS "Configuring blender")
+# Setup the exe sources and buildinfo
+SET(EXESRC creator.c)
IF(WIN32)
- ADD_EXECUTABLE(blender ${EXETYPE} creator.c ../icons/winblender.rc)
-ELSE(WIN32)
- ADD_EXECUTABLE(blender ${EXETYPE} creator.c)
+ SET(EXESRC ${EXESRC} ../icons/winblender.rc)
ENDIF(WIN32)
+IF(WITH_BUILDINFO)
+ ADD_DEFINITIONS(-DBUILD_DATE="${BUILD_DATE}")
+ ADD_DEFINITIONS(-DBUILD_TIME="${BUILD_TIME}")
+ ADD_DEFINITIONS(-DBUILD_REV="${BUILD_REV}")
+ ADD_DEFINITIONS(-DBUILD_PLATFORM="${CMAKE_SYSTEM_NAME}")
+ ADD_DEFINITIONS(-DBUILD_TYPE="${CMAKE_BUILD_TYPE}")
+
+ SET(EXESRC ${EXESRC} buildinfo.c)
+ENDIF(WITH_BUILDINFO)
+
+MESSAGE(STATUS "Configuring blender")
+
+ADD_EXECUTABLE(blender ${EXETYPE} ${EXESRC})
# Post build steps for bundling/packaging.
@@ -96,6 +117,9 @@ IF(WITH_INSTALL)
ENDIF(UNIX)
IF(UNIX AND NOT APPLE)
+
+ # Local installation, "make install" can be done after this optionally
+
ADD_CUSTOM_COMMAND(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
COMMAND rm -Rf ${TARGETDIR}/.blender
@@ -115,8 +139,7 @@ IF(WITH_INSTALL)
ADD_CUSTOM_COMMAND(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
COMMENT "copying blender scripts..."
- COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/ui ${TARGETDIR}/.blender/
- COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/io ${TARGETDIR}/.blender/
+ COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/scripts ${TARGETDIR}/.blender/
COMMAND find ${TARGETDIR} -name "*.py?" -prune -exec rm -rf {} "\;"
)
@@ -152,6 +175,27 @@ IF(WITH_INSTALL)
COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;"
)
+
+ # Above we bundle a portable distrobution in ./bin
+ # This is an optional "make install" which installs blender on the system.
+ INSTALL(
+ PROGRAMS ${TARGETDIR}/blender
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
+ )
+
+ IF(WITH_GAMEENGINE AND WITH_PLAYER)
+ INSTALL(
+ PROGRAMS ${TARGETDIR}/blenderplayer
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
+ )
+ ENDIF(WITH_GAMEENGINE AND WITH_PLAYER)
+
+ INSTALL(
+ DIRECTORY ${TARGETDIR}/.blender/
+ DESTINATION ${BLENDERPATH}
+ )
+ # end "make install"
+
ENDIF(UNIX AND NOT APPLE)
IF(APPLE)
@@ -161,9 +205,9 @@ IF(WITH_INSTALL)
ADD_CUSTOM_COMMAND(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMAND cp -R ${SOURCEINFO} ${TARGETDIR}/blender.app/Contents/
- COMMAND cp -R ${SOURCEDIR}/Contents/PkgInfo ${TARGETDIR}/blender.app/Contents/
- COMMAND cp -R ${SOURCEDIR}/Contents/Resources ${TARGETDIR}/blender.app/Contents/
+ COMMAND cp -Rf ${SOURCEINFO} ${TARGETDIR}/blender.app/Contents/
+ COMMAND cp -Rf ${SOURCEDIR}/Contents/PkgInfo ${TARGETDIR}/blender.app/Contents/
+ COMMAND cp -Rf ${SOURCEDIR}/Contents/Resources ${TARGETDIR}/blender.app/Contents/
COMMAND cat ${SOURCEINFO} | sed s/VERSION/`cat ${CMAKE_SOURCE_DIR}/release/VERSION`/ | sed s/DATE/`date +'%Y-%b-%d'`/ > ${TARGETINFO}
COMMAND rm -Rf ${TARGETDIR}/blender.app/Contents/MacOS/.blender
COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
@@ -174,8 +218,8 @@ IF(WITH_INSTALL)
ADD_CUSTOM_COMMAND(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
- COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/Resources/
- COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
+ COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/Resources/
+ COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/blender.app/Contents/Resources/
)
ENDIF(WITH_INTERNATIONAL)
@@ -183,8 +227,7 @@ IF(WITH_INSTALL)
IF(WITH_PYTHON)
ADD_CUSTOM_COMMAND(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/ui ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
- COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/io ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
+ COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/scripts ${TARGETDIR}/blender.app/Contents/MacOS/.blender/
COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/
COMMAND unzip -q ${LIBDIR}/release/python.zip -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/
COMMAND find ${TARGETDIR}/blender.app -name "*.py?" -prune -exec rm -rf {} "\;"
@@ -206,18 +249,16 @@ IF(WITH_INSTALL)
MAIN_DEPENDENCY blender
COMMAND if not exist \"${TARGETDIR}\\.blender\" mkdir \"${TARGETDIR}\\.blender\"
COMMAND if not exist \"${TARGETDIR}\\.blender\\locale\" mkdir \"${TARGETDIR}\\.blender\\locale\"
- COMMAND if not exist \"${TARGETDIR}\\.blender\\ui\" mkdir \"${TARGETDIR}\\.blender\\ui\"
- COMMAND if not exist \"${TARGETDIR}\\.blender\\io\" mkdir \"${TARGETDIR}\\.blender\\io\"
+ COMMAND if not exist \"${TARGETDIR}\\.blender\\scripts\" mkdir \"${TARGETDIR}\\.blender\\scripts\"
COMMAND if not exist \"${TARGETDIR}\\plugins\" mkdir \"${TARGETDIR}\\plugins\"
COMMAND copy /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\.Blanguages\" \"${TARGETDIR}\\.blender\\\"
COMMAND copy /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\.bfont.ttf\" \"${TARGETDIR}\\.blender\\\"
COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\locale\\*.*\" \"${TARGETDIR}\\.blender\\locale\"
COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\scripts\\*.*\" \"${TARGETDIR}\\.blender\\scripts\"
- COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\ui\\*.*\" \"${TARGETDIR}\\.blender\\ui\"
- COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\io\\*.*\" \"${TARGETDIR}\\.blender\\io\"
COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\"
COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\"
- COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python26.zip\" \"${TARGETDIR}\\\"
+ # TODO, copy python bundle
+ # COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python31.zip\" \"${TARGETDIR}\\\"
)
FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR)
@@ -319,6 +360,7 @@ IF(UNIX)
blender_ONL
bf_python
bf_gen_python
+ bf_ikplugin
bf_blenkernel
bf_nodes
bf_gpu
@@ -363,6 +405,7 @@ IF(UNIX)
bf_ngnetwork
extern_bullet
bf_loopbacknetwork
+ bf_ITASC
bf_common
bf_moto
bf_python
diff --git a/source/creator/SConscript b/source/creator/SConscript
index 75e7494ebb5..7b3d1493ed2 100644
--- a/source/creator/SConscript
+++ b/source/creator/SConscript
@@ -1,5 +1,6 @@
#!/usr/bin/python
Import ('env')
+import os
sources = 'creator.c'
@@ -32,4 +33,8 @@ if env['WITH_BF_PYTHON']:
else:
defs.append('DISABLE_PYTHON')
+if env['WITH_BF_FHS']: # /usr -> /usr/share/blender/2.5
+ defs.append('BLENDERPATH=\\"' + os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) + '\\"')
+
+
env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 )
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 41b27b1c915..6f64628b467 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -101,6 +101,7 @@
#ifdef BUILD_DATE
extern char * build_date;
extern char * build_time;
+extern char * build_rev;
extern char * build_platform;
extern char * build_type;
#endif
@@ -116,6 +117,14 @@ extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */
char bprogname[FILE_MAXDIR+FILE_MAXFILE]; /* from blenpluginapi:pluginapi.c */
char btempdir[FILE_MAXDIR+FILE_MAXFILE];
+/* unix path support.
+ * defined by the compiler. eg "/usr/share/blender/2.5" "/opt/blender/2.5" */
+#ifndef BLENDERPATH
+#define BLENDERPATH ""
+#endif
+
+char blender_path[FILE_MAXDIR+FILE_MAXFILE] = BLENDERPATH;
+
/* Initialise callbacks for the modules that need them */
static void setCallbacks(void);
@@ -221,6 +230,10 @@ static void print_help(void)
printf (" \t\t passed unchanged. Access via Python's sys.argv\n");
printf ("\nEnvironment Variables:\n");
printf (" $HOME\t\t\tStore files such as .blender/ .B.blend .Bfs .Blog here.\n");
+ printf (" $BLENDERPATH\tSystem directory to use for data files and scripts.\n");
+ printf (" \tFor this build of blender the default BLENDERPATH is...\n");
+ printf (" \t\"%s\"\n", blender_path);
+ printf (" \tseting the $BLENDERPATH will override this\n");
#ifdef WIN32
printf (" $TEMP\t\tStore temporary files here.\n");
#else
@@ -305,6 +318,12 @@ int main(int argc, char **argv)
BLI_where_am_i(bprogname, argv[0]);
+ { /* override the hard coded blender path */
+ char *blender_path_env = getenv("BLENDERPATH");
+ if(blender_path_env)
+ BLI_strncpy(blender_path, blender_path_env, sizeof(blender_path));
+ }
+
RNA_init();
RE_engines_init();
diff --git a/source/darwin/Makefile b/source/darwin/Makefile
index 35842b43eae..1431ab817ff 100644
--- a/source/darwin/Makefile
+++ b/source/darwin/Makefile
@@ -49,8 +49,6 @@ ifeq ($(APPLICATION), blender)
@echo "---> copying .blender/ scripts"
@cp -R $(NANBLENDERHOME)/bin/.blender $(DIR)/bin/$(APPLICATION).app/Contents/MacOS
@cp -R $(NANBLENDERHOME)/release/scripts $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/
- @echo "---> copying ui scripts"
- @cp -R $(NANBLENDERHOME)/release/ui $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/
@echo "---> copying python modules"
@mkdir $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/python
@unzip -q $(LCGDIR)/release/python.zip -d $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/python/
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index ae46f880711..df7f35d7773 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -34,6 +34,7 @@
#include <signal.h>
#include <stdlib.h>
+#include <stdio.h>
#ifdef WIN32
// don't show stl-warnings
@@ -89,6 +90,8 @@ extern "C" {
#include "DNA_scene_types.h"
/***/
+#include "AUD_C-API.h"
+
//XXX #include "BSE_headerbuttons.h"
#include "BKE_context.h"
#include "../../blender/windowmanager/WM_types.h"
@@ -135,6 +138,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
BLI_strncpy(oldsce, G.sce, sizeof(oldsce));
+#ifndef DISABLE_PYTHON
resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path
setGamePythonPath(G.sce);
@@ -143,6 +147,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
+#endif
bgl::InitExtensions(true);
@@ -204,8 +209,9 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
ketsjiengine->SetUseFixedTime(usefixed);
ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
+#ifndef DISABLE_PYTHON
CValue::SetDeprecationWarnings(nodepwarnings);
-
+#endif
//lock frame and camera enabled - storing global values
int tmp_lay= scene->lay;
@@ -286,7 +292,9 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
if(blenderdata) {
BLI_strncpy(G.sce, blenderdata->name, sizeof(G.sce));
BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
+#ifndef DISABLE_PYTHON
setGamePythonPath(G.sce);
+#endif
}
}
// else forget it, we can't find it
@@ -363,10 +371,11 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
networkdevice,
startscenename,
blscene);
-
+
+#ifndef DISABLE_PYTHON
// some python things
PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
- ketsjiengine->SetPythonDictionary(dictionaryobject);
+ ketsjiengine->SetPyNamespace(dictionaryobject);
initRasterizer(rasterizer, canvas);
PyObject *gameLogic = initGameLogic(ketsjiengine, startscene);
PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
@@ -381,17 +390,22 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
#ifdef WITH_FFMPEG
initVideoTexture();
#endif
+#endif // DISABLE_PYTHON
//initialize Dome Settings
if(blscene->gm.stereoflag == STEREO_DOME)
ketsjiengine->InitDome(blscene->gm.dome.res, blscene->gm.dome.mode, blscene->gm.dome.angle, blscene->gm.dome.resbuf, blscene->gm.dome.tilt, blscene->gm.dome.warptext);
+ // initialize 3D Audio Settings
+ AUD_set3DSetting(AUD_3DS_SPEED_OF_SOUND, blscene->audio.speed_of_sound);
+ AUD_set3DSetting(AUD_3DS_DOPPLER_FACTOR, blscene->audio.doppler_factor);
+ AUD_set3DSetting(AUD_3DS_DISTANCE_MODEL, blscene->audio.distance_model);
+
if (sceneconverter)
{
// convert and add scene
sceneconverter->ConvertScene(
startscene,
- dictionaryobject,
rendertools,
canvas);
ketsjiengine->AddScene(startscene);
@@ -461,7 +475,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
// when exiting the mainloop
-
+#ifndef DISABLE_PYTHON
// Clears the dictionary by hand:
// This prevents, extra references to global variables
// inside the GameLogic dictionary when the python interpreter is finalized.
@@ -481,9 +495,11 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
}
Py_DECREF(gameLogic_keys_new);
gameLogic_keys_new = NULL;
-
+#endif
ketsjiengine->StopEngine();
+#ifndef DISABLE_PYTHON
exitGamePythonScripting();
+#endif
networkdevice->Disconnect();
}
if (sceneconverter)
@@ -491,9 +507,11 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
delete sceneconverter;
sceneconverter = NULL;
}
-
+
+#ifndef DISABLE_PYTHON
Py_DECREF(gameLogic_keys);
gameLogic_keys = NULL;
+#endif
}
//lock frame and camera enabled - restoring global values
if (v3d->scenelock==0){
@@ -548,14 +566,17 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
- Py_DECREF(pyGlobalDict);
-
if (bfd) BLO_blendfiledata_free(bfd);
BLI_strncpy(G.sce, oldsce, sizeof(G.sce));
+#ifndef DISABLE_PYTHON
+ Py_DECREF(pyGlobalDict);
+
// Release Python's GIL
PyGILState_Release(gilstate);
+#endif
+
}
extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
@@ -574,9 +595,11 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
+#ifndef DISABLE_PYTHON
// Acquire Python's GIL (global interpreter lock)
// so we can safely run Python code and API calls
PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
bgl::InitExtensions(true);
@@ -673,9 +696,10 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
startscenename,
blscene);
+#ifndef DISABLE_PYTHON
// some python things
PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
- ketsjiengine->SetPythonDictionary(dictionaryobject);
+ ketsjiengine->SetPyNamespace(dictionaryobject);
initRasterizer(rasterizer, canvas);
PyObject *gameLogic = initGameLogic(ketsjiengine, startscene);
PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module
@@ -687,13 +711,13 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
#ifdef WITH_FFMPEG
initVideoTexture();
#endif
+#endif // DISABLE_PYTHON
if (sceneconverter)
{
// convert and add scene
sceneconverter->ConvertScene(
startscene,
- dictionaryobject,
rendertools,
canvas);
ketsjiengine->AddScene(startscene);
@@ -771,6 +795,8 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
+#ifndef DISABLE_PYTHON
// Release Python's GIL
PyGILState_Release(gilstate);
+#endif
}
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index ee15fd99ed5..f2d6528d797 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -6,6 +6,7 @@ SET(INC
../../../source/kernel/gen_system
../../../intern/string
../../../intern/guardedalloc
+ ../../../intern/audaspace/intern
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
../../../source/gameengine/Converter
../../../source/blender/imbuf
@@ -34,12 +35,17 @@ SET(INC
../../../source/blender/gpu
../../../extern/bullet2/src
../../../extern/glew/include
- ${PYTHON_INC}
)
IF(WITH_FFMPEG)
ADD_DEFINITIONS(-DWITH_FFMPEG)
ENDIF(WITH_FFMPEG)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(bf_blroutines "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_bloutines', sources, Split(incs), [], libtype=['game', 'game2', 'player'], priority=[0, 0, 55] , compileflags=cxxflags)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index dba6d1113c9..bb02f3b372e 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -44,6 +44,7 @@ extern "C" {
* This little block needed for linking to Blender...
*/
#ifdef WIN32
+#include <vector>
#include "BLI_winstuff.h"
#endif
diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile
index 4b65da667ef..4a437aff97d 100644
--- a/source/gameengine/BlenderRoutines/Makefile
+++ b/source/gameengine/BlenderRoutines/Makefile
@@ -40,6 +40,7 @@ CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_AUDASPACE)/include
# because of kernel dependency on makesdna
CPPFLAGS += -I../../blender/makesdna
CPPFLAGS += -I../../blender/editors/include
diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript
index ad6f9f23fce..f076612e231 100644
--- a/source/gameengine/BlenderRoutines/SConscript
+++ b/source/gameengine/BlenderRoutines/SConscript
@@ -8,6 +8,7 @@ incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
incs += ' #source/gameengine/Converter #source/blender/imbuf'
incs += ' #intern/ghost/include'
+incs += ' #intern/audaspace/intern'
incs += ' #intern/moto/include #source/gameengine/Ketsji #source/blender/blenlib'
incs += ' #source/blender/blenkernel #source/blender'
incs += ' #source/blender/blenfont #source/blender/editors/include'
@@ -24,7 +25,11 @@ incs += ' #source/blender/windowmanager'
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
-incs += ' ' + env['BF_PYTHON_INC']
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
incs += ' ' + env['BF_BULLET_INC']
incs += ' ' + env['BF_OPENGL_INC']
diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt
index 5a1887bd6c3..518e6a2bd58 100644
--- a/source/gameengine/CMakeLists.txt
+++ b/source/gameengine/CMakeLists.txt
@@ -38,7 +38,10 @@ ADD_SUBDIRECTORY(Rasterizer)
ADD_SUBDIRECTORY(Rasterizer/RAS_OpenGLRasterizer)
ADD_SUBDIRECTORY(SceneGraph)
ADD_SUBDIRECTORY(Physics/Bullet)
-ADD_SUBDIRECTORY(VideoTexture)
+
+IF(WITH_PYTHON)
+ ADD_SUBDIRECTORY(VideoTexture)
+ENDIF(WITH_PYTHON)
IF(WITH_PLAYER)
ADD_SUBDIRECTORY(GamePlayer)
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index ca4290703e1..6f3036d8e09 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -432,6 +432,8 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
return keepgoing;
};
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -526,12 +528,11 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
mat.setValue((const float *)matrix);
BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
- obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
if (!m_userpose) {
if(!m_pose)
obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
- game_copy_pose(&m_userpose, m_pose);
+ game_copy_pose(&m_userpose, m_pose, 0);
}
// pchan= verify_pose_channel(m_userpose, string); // adds the channel if its not there.
pchan= get_pose_channel(m_userpose, string); // adds the channel if its not there.
@@ -554,7 +555,7 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
if (!m_userpose) {
if(!m_pose)
obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
- game_copy_pose(&m_userpose, m_pose);
+ game_copy_pose(&m_userpose, m_pose, 0);
}
// pchan= verify_pose_channel(m_userpose, string);
pchan= get_pose_channel(m_userpose, string); // adds the channel if its not there.
@@ -572,7 +573,6 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
return NULL;
}
- pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE;
Py_RETURN_NONE;
}
@@ -677,3 +677,5 @@ PyObject* BL_ActionActuator::pyattr_get_channel_names(void *self_v, const KX_PYA
return ret;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index a6b4c4a055d..3f3cd5f496d 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -50,7 +50,7 @@ public:
short priority,
short end_reset,
float stride)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_ACTION),
m_lastpos(0, 0, 0),
m_blendframe(0),
@@ -84,6 +84,8 @@ public:
bAction* GetAction() { return m_action; }
void SetAction(bAction* act) { m_action= act; }
+#ifndef DISABLE_PYTHON
+
KX_PYMETHOD_O(BL_ActionActuator,GetChannel);
KX_PYMETHOD_DOC(BL_ActionActuator,setChannel);
@@ -129,6 +131,7 @@ public:
return 1;
}
}
+#endif // DISABLE_PYTHON
protected:
diff --git a/source/gameengine/Converter/BL_ArmatureActuator.cpp b/source/gameengine/Converter/BL_ArmatureActuator.cpp
new file mode 100644
index 00000000000..a018f0f938d
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureActuator.cpp
@@ -0,0 +1,267 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "DNA_action_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_actuator_types.h"
+#include "BKE_constraint.h"
+#include "BLI_arithb.h"
+#include "BL_ArmatureActuator.h"
+#include "BL_ArmatureObject.h"
+
+/**
+ * This class is the conversion of the Pose channel constraint.
+ * It makes a link between the pose constraint and the KX scene.
+ * The main purpose is to give access to the constraint target
+ * to link it to a game object.
+ * It also allows to activate/deactivate constraints during the game.
+ * Later it will also be possible to create constraint on the fly
+ */
+
+BL_ArmatureActuator::BL_ArmatureActuator(SCA_IObject* obj,
+ int type,
+ const char *posechannel,
+ const char *constraintname,
+ KX_GameObject* targetobj,
+ KX_GameObject* subtargetobj,
+ float weight) :
+ SCA_IActuator(obj, KX_ACT_ARMATURE),
+ m_constraint(NULL),
+ m_gametarget(targetobj),
+ m_gamesubtarget(subtargetobj),
+ m_posechannel(posechannel),
+ m_constraintname(constraintname),
+ m_weight(weight),
+ m_type(type)
+{
+ if (m_gametarget)
+ m_gametarget->RegisterActuator(this);
+ if (m_gamesubtarget)
+ m_gamesubtarget->RegisterActuator(this);
+ FindConstraint();
+}
+
+BL_ArmatureActuator::~BL_ArmatureActuator()
+{
+ if (m_gametarget)
+ m_gametarget->UnregisterActuator(this);
+ if (m_gamesubtarget)
+ m_gamesubtarget->UnregisterActuator(this);
+}
+
+void BL_ArmatureActuator::ProcessReplica()
+{
+ // the replica is tracking the same object => register it (this may be changed in Relnk())
+ if (m_gametarget)
+ m_gametarget->RegisterActuator(this);
+ if (m_gamesubtarget)
+ m_gamesubtarget->UnregisterActuator(this);
+ SCA_IActuator::ProcessReplica();
+}
+
+void BL_ArmatureActuator::ReParent(SCA_IObject* parent)
+{
+ SCA_IActuator::ReParent(parent);
+ // must remap the constraint
+ FindConstraint();
+}
+
+bool BL_ArmatureActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ bool res=false;
+ if (clientobj == m_gametarget)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_gametarget = NULL;
+ res = true;
+ }
+ if (clientobj == m_gamesubtarget)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_gamesubtarget = NULL;
+ res = true;
+ }
+ return res;
+}
+
+void BL_ArmatureActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_gametarget];
+ if (h_obj) {
+ if (m_gametarget)
+ m_gametarget->UnregisterActuator(this);
+ m_gametarget = (KX_GameObject*)(*h_obj);
+ m_gametarget->RegisterActuator(this);
+ }
+ h_obj = (*obj_map)[m_gamesubtarget];
+ if (h_obj) {
+ if (m_gamesubtarget)
+ m_gamesubtarget->UnregisterActuator(this);
+ m_gamesubtarget = (KX_GameObject*)(*h_obj);
+ m_gamesubtarget->RegisterActuator(this);
+ }
+}
+
+void BL_ArmatureActuator::FindConstraint()
+{
+ m_constraint = NULL;
+
+ if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
+ BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
+ m_constraint = armobj->GetConstraint(m_posechannel, m_constraintname);
+ }
+}
+
+bool BL_ArmatureActuator::Update(double curtime, bool frame)
+{
+ // the only role of this actuator is to ensure that the armature pose will be evaluated
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (!bNegativeEvent) {
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
+ switch (m_type) {
+ case ACT_ARM_RUN:
+ result = true;
+ obj->SetActiveAction(NULL, 0, curtime);
+ break;
+ case ACT_ARM_ENABLE:
+ if (m_constraint)
+ m_constraint->ClrConstraintFlag(CONSTRAINT_OFF);
+ break;
+ case ACT_ARM_DISABLE:
+ if (m_constraint)
+ m_constraint->SetConstraintFlag(CONSTRAINT_OFF);
+ break;
+ case ACT_ARM_SETTARGET:
+ if (m_constraint) {
+ m_constraint->SetTarget(m_gametarget);
+ m_constraint->SetSubtarget(m_gamesubtarget);
+ }
+ break;
+ case ACT_ARM_SETWEIGHT:
+ if (m_constraint)
+ m_constraint->SetWeight(m_weight);
+ break;
+ }
+ }
+ return result;
+}
+
+#ifndef DISABLE_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python Integration Hooks */
+/* ------------------------------------------------------------------------- */
+
+PyTypeObject BL_ArmatureActuator::Type = {
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
+ "BL_ArmatureActuator",
+ 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,
+ &SCA_IActuator::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+
+PyMethodDef BL_ArmatureActuator::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef BL_ArmatureActuator::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("constraint", BL_ArmatureActuator, pyattr_get_constraint),
+ KX_PYATTRIBUTE_RW_FUNCTION("target", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
+ KX_PYATTRIBUTE_RW_FUNCTION("subtarget", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
+ KX_PYATTRIBUTE_FLOAT_RW("weight",0.0f,1.0f,BL_ArmatureActuator,m_weight),
+ KX_PYATTRIBUTE_INT_RW("type",0,ACT_ARM_MAXTYPE,false,BL_ArmatureActuator,m_type),
+ { NULL } //Sentinel
+};
+
+PyObject* BL_ArmatureActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
+ KX_GameObject *target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
+ if (!target)
+ Py_RETURN_NONE;
+ else
+ return target->GetProxy();
+}
+
+int BL_ArmatureActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
+ KX_GameObject* &target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: BL_ArmatureActuator"))
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
+
+ if (target != NULL)
+ target->UnregisterActuator(actuator);
+
+ target = gameobj;
+
+ if (target)
+ target->RegisterActuator(actuator);
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject* BL_ArmatureActuator::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
+ BL_ArmatureConstraint* constraint = actuator->m_constraint;
+ if (!constraint)
+ Py_RETURN_NONE;
+ else
+ return constraint->GetProxy();
+}
+
+#endif // DISABLE_PYTHON
+
diff --git a/source/gameengine/Converter/BL_ArmatureActuator.h b/source/gameengine/Converter/BL_ArmatureActuator.h
new file mode 100644
index 00000000000..e7e12bc2e4e
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureActuator.h
@@ -0,0 +1,93 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 BL_ARMATUREACTUATOR
+#define BL_ARMATUREACTUATOR
+
+#include "SCA_IActuator.h"
+#include "BL_ArmatureConstraint.h"
+
+/**
+ * This class is the conversion of the Pose channel constraint.
+ * It makes a link between the pose constraint and the KX scene.
+ * The main purpose is to give access to the constraint target
+ * to link it to a game object.
+ * It also allows to activate/deactivate constraints during the game.
+ * Later it will also be possible to create constraint on the fly
+ */
+
+class BL_ArmatureActuator : public SCA_IActuator
+{
+ Py_Header;
+public:
+ BL_ArmatureActuator(SCA_IObject* gameobj,
+ int type,
+ const char *posechannel,
+ const char *constraintname,
+ KX_GameObject* targetobj,
+ KX_GameObject* subtargetobj,
+ float weight);
+
+ virtual ~BL_ArmatureActuator();
+
+ virtual CValue* GetReplica() {
+ BL_ArmatureActuator* replica = new BL_ArmatureActuator(*this);
+ replica->ProcessReplica();
+ return replica;
+ };
+ virtual void ProcessReplica();
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+ virtual bool Update(double curtime, bool frame);
+ virtual void ReParent(SCA_IObject* parent);
+
+#ifndef DISABLE_PYTHON
+
+ /* These are used to get and set m_target */
+ static PyObject* pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+#endif // DISABLE_PYTHON
+
+private:
+ // identify the constraint that this actuator controls
+ void FindConstraint();
+
+ BL_ArmatureConstraint* m_constraint;
+ KX_GameObject* m_gametarget;
+ KX_GameObject* m_gamesubtarget;
+ STR_String m_posechannel;
+ STR_String m_constraintname;
+ float m_weight;
+ int m_type;
+};
+
+#endif //BL_ARMATUREACTUATOR
+
+
diff --git a/source/gameengine/Converter/BL_ArmatureChannel.cpp b/source/gameengine/Converter/BL_ArmatureChannel.cpp
new file mode 100644
index 00000000000..9a9161b080f
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureChannel.cpp
@@ -0,0 +1,469 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DNA_armature_types.h"
+#include "BL_ArmatureChannel.h"
+#include "BL_ArmatureObject.h"
+#include "BL_ArmatureConstraint.h"
+#include "BLI_arithb.h"
+#include "BLI_string.h"
+
+#ifndef DISABLE_PYTHON
+
+PyTypeObject BL_ArmatureChannel::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "BL_ArmatureChannel",
+ 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,
+ &CValue::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyObject* BL_ArmatureChannel::py_repr(void)
+{
+ return PyUnicode_FromString(m_posechannel->name);
+}
+
+PyObject *BL_ArmatureChannel::GetProxy()
+{
+ return GetProxyPlus_Ext(this, &Type, m_posechannel);
+}
+
+PyObject *BL_ArmatureChannel::NewProxy(bool py_owns)
+{
+ return NewProxyPlus_Ext(this, &Type, m_posechannel, py_owns);
+}
+
+#endif // DISABLE_PYTHON
+
+BL_ArmatureChannel::BL_ArmatureChannel(
+ BL_ArmatureObject *armature,
+ bPoseChannel *posechannel)
+ : PyObjectPlus(), m_posechannel(posechannel), m_armature(armature)
+{
+}
+
+BL_ArmatureChannel::~BL_ArmatureChannel()
+{
+}
+
+#ifndef DISABLE_PYTHON
+
+// PYTHON
+
+PyMethodDef BL_ArmatureChannel::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+// order of definition of attributes, must match Attributes[] array
+#define BCA_BONE 0
+#define BCA_PARENT 1
+
+PyAttributeDef BL_ArmatureChannel::Attributes[] = {
+ // Keep these attributes in order of BCA_ defines!!! used by py_attr_getattr and py_attr_setattr
+ KX_PYATTRIBUTE_RO_FUNCTION("bone",BL_ArmatureChannel,py_attr_getattr),
+ KX_PYATTRIBUTE_RO_FUNCTION("parent",BL_ArmatureChannel,py_attr_getattr),
+
+ { NULL } //Sentinel
+};
+
+/* attributes directly taken from bPoseChannel */
+PyAttributeDef BL_ArmatureChannel::AttributesPtr[] = {
+ KX_PYATTRIBUTE_CHAR_RO("name",bPoseChannel,name),
+ KX_PYATTRIBUTE_FLAG_RO("has_ik",bPoseChannel,flag, POSE_CHAIN),
+ KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("ik_dof_x",bPoseChannel,ikflag, BONE_IK_NO_XDOF),
+ KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("ik_dof_y",bPoseChannel,ikflag, BONE_IK_NO_YDOF),
+ KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("ik_dof_z",bPoseChannel,ikflag, BONE_IK_NO_ZDOF),
+ KX_PYATTRIBUTE_FLAG_RO("ik_limit_x",bPoseChannel,ikflag, BONE_IK_XLIMIT),
+ KX_PYATTRIBUTE_FLAG_RO("ik_limit_y",bPoseChannel,ikflag, BONE_IK_YLIMIT),
+ KX_PYATTRIBUTE_FLAG_RO("ik_limit_z",bPoseChannel,ikflag, BONE_IK_ZLIMIT),
+ KX_PYATTRIBUTE_FLAG_RO("ik_rot_control",bPoseChannel,ikflag, BONE_IK_ROTCTL),
+ KX_PYATTRIBUTE_FLAG_RO("ik_lin_control",bPoseChannel,ikflag, BONE_IK_LINCTL),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RW("location",-FLT_MAX,FLT_MAX,bPoseChannel,loc,3),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RW("scale",-FLT_MAX,FLT_MAX,bPoseChannel,size,3),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RW("rotation_quaternion",-1.0f,1.0f,bPoseChannel,quat,4),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RW("rotaion_euler",-10.f,10.f,bPoseChannel,eul,3),
+ KX_PYATTRIBUTE_SHORT_RW("rotation_mode",0,ROT_MODE_MAX-1,false,bPoseChannel,rotmode),
+ KX_PYATTRIBUTE_FLOAT_MATRIX_RO("channel_matrix",bPoseChannel,chan_mat,4),
+ KX_PYATTRIBUTE_FLOAT_MATRIX_RO("pose_matrix",bPoseChannel,pose_mat,4),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RO("pose_head",bPoseChannel,pose_head,3),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RO("pose_tail",bPoseChannel,pose_tail,3),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_min_x",bPoseChannel,limitmin[0]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_max_x",bPoseChannel,limitmax[0]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_min_y",bPoseChannel,limitmin[1]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_max_y",bPoseChannel,limitmax[1]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_min_z",bPoseChannel,limitmin[2]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_max_z",bPoseChannel,limitmax[2]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_stiffness_x",bPoseChannel,stiffness[0]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_stiffness_y",bPoseChannel,stiffness[1]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_stiffness_z",bPoseChannel,stiffness[2]),
+ KX_PYATTRIBUTE_FLOAT_RO("ik_stretch",bPoseChannel,ikstretch),
+ KX_PYATTRIBUTE_FLOAT_RW("ik_rot_weight",0,1.0f,bPoseChannel,ikrotweight),
+ KX_PYATTRIBUTE_FLOAT_RW("ik_lin_weight",0,1.0f,bPoseChannel,iklinweight),
+ KX_PYATTRIBUTE_RW_FUNCTION("joint_rotation",BL_ArmatureChannel,py_attr_get_joint_rotation,py_attr_set_joint_rotation),
+ { NULL } //Sentinel
+};
+
+PyObject* BL_ArmatureChannel::py_attr_getattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
+ bPoseChannel* channel = self->m_posechannel;
+ int attr_order = attrdef-Attributes;
+
+ if (!channel) {
+ PyErr_SetString(PyExc_AttributeError, "channel is NULL");
+ return NULL;
+ }
+
+ switch (attr_order) {
+ case BCA_BONE:
+ // bones are standalone proxy
+ return NewProxyPlus_Ext(NULL,&BL_ArmatureBone::Type,channel->bone,false);
+ case BCA_PARENT:
+ {
+ BL_ArmatureChannel* parent = self->m_armature->GetChannel(channel->parent);
+ if (parent)
+ return parent->GetProxy();
+ else
+ Py_RETURN_NONE;
+ }
+ }
+ PyErr_SetString(PyExc_AttributeError, "channel unknown attribute");
+ return NULL;
+}
+
+int BL_ArmatureChannel::py_attr_setattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
+ bPoseChannel* channel = self->m_posechannel;
+ int attr_order = attrdef-Attributes;
+
+ int ival;
+ double dval;
+ char* sval;
+ KX_GameObject *oval;
+
+ if (!channel) {
+ PyErr_SetString(PyExc_AttributeError, "channel is NULL");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ switch (attr_order) {
+ default:
+ break;
+ }
+
+ PyErr_SetString(PyExc_AttributeError, "channel unknown attribute");
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject* BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
+ bPoseChannel* pchan = self->m_posechannel;
+ // decompose the pose matrix in euler rotation
+ float rest_mat[3][3];
+ float pose_mat[3][3];
+ float joint_mat[3][3];
+ float joints[3];
+ float norm;
+ double sa, ca;
+ // get rotation in armature space
+ Mat3CpyMat4(pose_mat, pchan->pose_mat);
+ Mat3Ortho(pose_mat);
+ if (pchan->parent) {
+ // bone has a parent, compute the rest pose of the bone taking actual pose of parent
+ Mat3IsMat3MulMat4(rest_mat, pchan->bone->bone_mat, pchan->parent->pose_mat);
+ Mat3Ortho(rest_mat);
+ } else {
+ // otherwise, the bone matrix in armature space is the rest pose
+ Mat3CpyMat4(rest_mat, pchan->bone->arm_mat);
+ }
+ // remove the rest pose to get the joint movement
+ Mat3Transp(rest_mat);
+ Mat3MulMat3(joint_mat, rest_mat, pose_mat);
+ joints[0] = joints[1] = joints[2] = 0.f;
+ // returns a 3 element list that gives corresponding joint
+ int flag = 0;
+ if (!(pchan->ikflag & BONE_IK_NO_XDOF))
+ flag |= 1;
+ if (!(pchan->ikflag & BONE_IK_NO_YDOF))
+ flag |= 2;
+ if (!(pchan->ikflag & BONE_IK_NO_ZDOF))
+ flag |= 4;
+ switch (flag) {
+ case 0: // fixed joint
+ break;
+ case 1: // X only
+ Mat3ToEulO(joint_mat, joints, EULER_ORDER_XYZ);
+ joints[1] = joints[2] = 0.f;
+ break;
+ case 2: // Y only
+ Mat3ToEulO(joint_mat, joints, EULER_ORDER_XYZ);
+ joints[0] = joints[2] = 0.f;
+ break;
+ case 3: // X+Y
+ Mat3ToEulO(joint_mat, joints, EULER_ORDER_ZYX);
+ joints[2] = 0.f;
+ break;
+ case 4: // Z only
+ Mat3ToEulO(joint_mat, joints, EULER_ORDER_XYZ);
+ joints[0] = joints[1] = 0.f;
+ break;
+ case 5: // X+Z
+ // decompose this as an equivalent rotation vector in X/Z plane
+ joints[0] = joint_mat[1][2];
+ joints[2] = -joint_mat[1][0];
+ norm = Normalize(joints);
+ if (norm < FLT_EPSILON) {
+ norm = (joint_mat[1][1] < 0.f) ? M_PI : 0.f;
+ } else {
+ norm = acos(joint_mat[1][1]);
+ }
+ VecMulf(joints, norm);
+ break;
+ case 6: // Y+Z
+ Mat3ToEulO(joint_mat, joints, EULER_ORDER_XYZ);
+ joints[0] = 0.f;
+ break;
+ case 7: // X+Y+Z
+ // equivalent axis
+ joints[0] = (joint_mat[1][2]-joint_mat[2][1])*0.5f;
+ joints[1] = (joint_mat[2][0]-joint_mat[0][2])*0.5f;
+ joints[2] = (joint_mat[0][1]-joint_mat[1][0])*0.5f;
+ sa = VecLength(joints);
+ ca = (joint_mat[0][0]+joint_mat[1][1]+joint_mat[1][1]-1.0f)*0.5f;
+ if (sa > FLT_EPSILON) {
+ norm = atan2(sa,ca)/sa;
+ } else {
+ if (ca < 0.0) {
+ norm = M_PI;
+ VecMulf(joints,0.f);
+ if (joint_mat[0][0] > 0.f) {
+ joints[0] = 1.0f;
+ } else if (joint_mat[1][1] > 0.f) {
+ joints[1] = 1.0f;
+ } else {
+ joints[2] = 1.0f;
+ }
+ } else {
+ norm = 0.0;
+ }
+ }
+ VecMulf(joints,norm);
+ break;
+ }
+ return newVectorObject(joints, 3, Py_NEW, NULL);
+}
+
+int BL_ArmatureChannel::py_attr_set_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
+ bPoseChannel* pchan = self->m_posechannel;
+ PyObject *item;
+ float joints[3];
+ float quat[4];
+
+ if (!PySequence_Check(value) || PySequence_Size(value) != 3) {
+ PyErr_SetString(PyExc_AttributeError, "expected a sequence of [3] floats");
+ return PY_SET_ATTR_FAIL;
+ }
+ for (int i=0; i<3; i++) {
+ item = PySequence_GetItem(value, i); /* new ref */
+ joints[i] = PyFloat_AsDouble(item);
+ Py_DECREF(item);
+ if (joints[i] == -1.0f && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_AttributeError, "expected a sequence of [3] floats");
+ return PY_SET_ATTR_FAIL;
+ }
+ }
+
+ int flag = 0;
+ if (!(pchan->ikflag & BONE_IK_NO_XDOF))
+ flag |= 1;
+ if (!(pchan->ikflag & BONE_IK_NO_YDOF))
+ flag |= 2;
+ if (!(pchan->ikflag & BONE_IK_NO_ZDOF))
+ flag |= 4;
+ QuatOne(quat);
+ switch (flag) {
+ case 0: // fixed joint
+ break;
+ case 1: // X only
+ joints[1] = joints[2] = 0.f;
+ EulOToQuat(joints, EULER_ORDER_XYZ, quat);
+ break;
+ case 2: // Y only
+ joints[0] = joints[2] = 0.f;
+ EulOToQuat(joints, EULER_ORDER_XYZ, quat);
+ break;
+ case 3: // X+Y
+ joints[2] = 0.f;
+ EulOToQuat(joints, EULER_ORDER_ZYX, quat);
+ break;
+ case 4: // Z only
+ joints[0] = joints[1] = 0.f;
+ EulOToQuat(joints, EULER_ORDER_XYZ, quat);
+ break;
+ case 5: // X+Z
+ // X and Z are components of an equivalent rotation axis
+ joints[1] = 0;
+ VecRotToQuat(joints, VecLength(joints), quat);
+ break;
+ case 6: // Y+Z
+ joints[0] = 0.f;
+ EulOToQuat(joints, EULER_ORDER_XYZ, quat);
+ break;
+ case 7: // X+Y+Z
+ // equivalent axis
+ VecRotToQuat(joints, VecLength(joints), quat);
+ break;
+ }
+ if (pchan->rotmode > 0) {
+ QuatToEulO(quat, joints, pchan->rotmode);
+ VecCopyf(pchan->eul, joints);
+ } else
+ QuatCopy(pchan->quat, quat);
+ return PY_SET_ATTR_SUCCESS;
+}
+
+// *************************
+// BL_ArmatureBone
+//
+// Access to Bone structure
+PyTypeObject BL_ArmatureBone::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "BL_ArmatureBone",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_bone_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,
+ &CValue::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+// not used since this class is never instantiated
+PyObject *BL_ArmatureBone::GetProxy()
+{
+ return NULL;
+}
+PyObject *BL_ArmatureBone::NewProxy(bool py_owns)
+{
+ return NULL;
+}
+
+PyObject *BL_ArmatureBone::py_bone_repr(PyObject *self)
+{
+ Bone* bone = static_cast<Bone*>BGE_PROXY_PTR(self);
+ return PyUnicode_FromString(bone->name);
+}
+
+PyMethodDef BL_ArmatureBone::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+/* no attributes on C++ class since it is never instantiated */
+PyAttributeDef BL_ArmatureBone::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+// attributes that work on proxy ptr (points to a Bone structure)
+PyAttributeDef BL_ArmatureBone::AttributesPtr[] = {
+ KX_PYATTRIBUTE_CHAR_RO("name",Bone,name),
+ KX_PYATTRIBUTE_FLAG_RO("connected",Bone,flag, BONE_CONNECTED),
+ KX_PYATTRIBUTE_FLAG_RO("hinge",Bone,flag, BONE_HINGE),
+ KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("inherit_scale",Bone,flag, BONE_NO_SCALE),
+ KX_PYATTRIBUTE_SHORT_RO("bbone_segments",Bone,segments),
+ KX_PYATTRIBUTE_FLOAT_RO("roll",Bone,roll),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RO("head",Bone,head,3),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RO("tail",Bone,tail,3),
+ KX_PYATTRIBUTE_FLOAT_RO("length",Bone,length),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RO("arm_head",Bone,arm_head,3),
+ KX_PYATTRIBUTE_FLOAT_VECTOR_RO("arm_tail",Bone,arm_tail,3),
+ KX_PYATTRIBUTE_FLOAT_MATRIX_RO("arm_mat",Bone,arm_mat,4),
+ KX_PYATTRIBUTE_FLOAT_MATRIX_RO("bone_mat",Bone,bone_mat,4),
+ KX_PYATTRIBUTE_RO_FUNCTION("parent",BL_ArmatureBone,py_bone_get_parent),
+ KX_PYATTRIBUTE_RO_FUNCTION("children",BL_ArmatureBone,py_bone_get_parent),
+ { NULL } //Sentinel
+};
+
+PyObject *BL_ArmatureBone::py_bone_get_parent(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ Bone* bone = reinterpret_cast<Bone*>BGE_PROXY_PTR(self);
+ if (bone->parent) {
+ // create a proxy unconnected to any GE object
+ return NewProxyPlus_Ext(NULL,&Type,bone->parent,false);
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *BL_ArmatureBone::py_bone_get_children(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ Bone* bone = reinterpret_cast<Bone*>BGE_PROXY_PTR(self);
+ Bone* child;
+ int count = 0;
+ for (child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next)
+ count++;
+
+ PyObject* childrenlist = PyList_New(count);
+
+ for (count = 0, child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next, ++count)
+ PyList_SET_ITEM(childrenlist,count,NewProxyPlus_Ext(NULL,&Type,child,false));
+
+ return childrenlist;
+}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Converter/BL_ArmatureChannel.h b/source/gameengine/Converter/BL_ArmatureChannel.h
new file mode 100644
index 00000000000..64b03835d83
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureChannel.h
@@ -0,0 +1,95 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 __BL_ARMATURECHANNEL
+#define __BL_ARMATURECHANNEL
+
+#include "DNA_action_types.h"
+#include "GEN_HashedPtr.h"
+#include "GEN_Map.h"
+#include "PyObjectPlus.h"
+
+class SCA_IObject;
+class KX_GameObject;
+class BL_ArmatureObject;
+struct bConstraint;
+struct bPoseChannel;
+struct Object;
+struct bPose;
+
+class BL_ArmatureChannel : public PyObjectPlus
+{
+ // use Py_HeaderPtr since we use generic pointer in proxy
+ Py_HeaderPtr;
+
+private:
+ friend class BL_ArmatureObject;
+ struct bPoseChannel* m_posechannel;
+ BL_ArmatureObject* m_armature;
+
+public:
+ BL_ArmatureChannel(class BL_ArmatureObject *armature,
+ struct bPoseChannel *posechannel);
+ virtual ~BL_ArmatureChannel();
+
+#ifndef DISABLE_PYTHON
+ // Python access
+ virtual PyObject* py_repr(void);
+
+ static PyObject* py_attr_getattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* py_attr_get_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int py_attr_set_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif // DISABLE_PYTHON
+};
+
+/* this is a factory class to access bBone data field in the GE.
+ It's not supposed to be instantiated, we only need it for the Attributes and Method array.
+ The actual proxy object will be manually created using NewProxyPtr */
+class BL_ArmatureBone : public PyObjectPlus
+{
+ // use Py_HeaderPtr since we use generic pointer in proxy
+ Py_HeaderPtr;
+private:
+ // make constructor private to make sure no one tries to instantiate this class
+ BL_ArmatureBone() {}
+ virtual ~BL_ArmatureBone() {}
+
+public:
+
+#ifndef DISABLE_PYTHON
+ static PyObject *py_bone_repr(PyObject *self);
+ static PyObject *py_bone_get_parent(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject *py_bone_get_children(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+#endif
+
+};
+
+
+#endif //__BL_ARMATURECHANNEL
+
diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.cpp b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
new file mode 100644
index 00000000000..42581b63ec4
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
@@ -0,0 +1,454 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DNA_constraint_types.h"
+#include "DNA_action_types.h"
+#include "BL_ArmatureConstraint.h"
+#include "BL_ArmatureObject.h"
+#include "BLI_arithb.h"
+#include "BLI_string.h"
+
+#ifndef DISABLE_PYTHON
+
+PyTypeObject BL_ArmatureConstraint::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "BL_ArmatureConstraint",
+ 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,
+ &CValue::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyObject* BL_ArmatureConstraint::py_repr(void)
+{
+ return PyUnicode_FromString(m_name);
+}
+
+#endif // DISABLE_PYTHON
+
+BL_ArmatureConstraint::BL_ArmatureConstraint(
+ BL_ArmatureObject *armature,
+ bPoseChannel *posechannel,
+ bConstraint *constraint,
+ KX_GameObject* target,
+ KX_GameObject* subtarget)
+ : PyObjectPlus(), m_armature(armature), m_constraint(constraint), m_posechannel(posechannel)
+{
+ m_target = target;
+ m_blendtarget = (target) ? target->GetBlenderObject() : NULL;
+ m_subtarget = subtarget;
+ m_blendsubtarget = (subtarget) ? subtarget->GetBlenderObject() : NULL;
+ m_pose = m_subpose = NULL;
+ if (m_blendtarget) {
+ Mat4CpyMat4(m_blendmat, m_blendtarget->obmat);
+ if (m_blendtarget->type == OB_ARMATURE)
+ m_pose = m_blendtarget->pose;
+ }
+ if (m_blendsubtarget) {
+ Mat4CpyMat4(m_blendsubmat, m_blendsubtarget->obmat);
+ if (m_blendsubtarget->type == OB_ARMATURE)
+ m_subpose = m_blendsubtarget->pose;
+ }
+ if (m_target)
+ m_target->RegisterObject(m_armature);
+ if (m_subtarget)
+ m_subtarget->RegisterObject(m_armature);
+ BLI_snprintf(m_name, sizeof(m_name), "%s:%s", m_posechannel->name, m_constraint->name);
+}
+
+BL_ArmatureConstraint::~BL_ArmatureConstraint()
+{
+ if (m_target)
+ m_target->UnregisterObject(m_armature);
+ if (m_subtarget)
+ m_subtarget->UnregisterObject(m_armature);
+}
+
+BL_ArmatureConstraint* BL_ArmatureConstraint::GetReplica() const
+{
+ BL_ArmatureConstraint* replica = new BL_ArmatureConstraint(*this);
+ replica->ProcessReplica();
+ return replica;
+}
+
+void BL_ArmatureConstraint::ReParent(BL_ArmatureObject* armature)
+{
+ m_armature = armature;
+ if (m_target)
+ m_target->RegisterObject(armature);
+ if (m_subtarget)
+ m_subtarget->RegisterObject(armature);
+ // find the corresponding constraint in the new armature object
+ if (m_constraint) {
+ bPose* newpose = armature->GetOrigPose();
+ char* constraint = m_constraint->name;
+ char* posechannel = m_posechannel->name;
+ bPoseChannel* pchan;
+ bConstraint* pcon;
+ m_constraint = NULL;
+ m_posechannel = NULL;
+ // and locate the constraint
+ for (pchan = (bPoseChannel*)newpose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
+ if (!strcmp(pchan->name, posechannel)) {
+ // now locate the constraint
+ for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) {
+ if (!strcmp(pcon->name, constraint)) {
+ m_constraint = pcon;
+ m_posechannel = pchan;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+void BL_ArmatureConstraint::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_target];
+ if (h_obj) {
+ m_target->UnregisterObject(m_armature);
+ m_target = (KX_GameObject*)(*h_obj);
+ m_target->RegisterObject(m_armature);
+ }
+ h_obj = (*obj_map)[m_subtarget];
+ if (h_obj) {
+ m_subtarget->UnregisterObject(m_armature);
+ m_subtarget = (KX_GameObject*)(*h_obj);
+ m_subtarget->RegisterObject(m_armature);
+ }
+}
+
+bool BL_ArmatureConstraint::UnlinkObject(SCA_IObject* clientobj)
+{
+ bool res=false;
+ if (clientobj == m_target) {
+ m_target = NULL;
+ res = true;
+ }
+ if (clientobj == m_subtarget) {
+ m_subtarget = NULL;
+ res = true;
+ }
+ return res;
+}
+
+void BL_ArmatureConstraint::UpdateTarget()
+{
+ if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
+ if (m_blendtarget) {
+ // external target, must be updated
+ m_target->UpdateBlenderObjectMatrix(m_blendtarget);
+ if (m_pose && m_target->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ // update the pose in case a bone is specified in the constraint target
+ m_blendtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose();
+ }
+ if (m_blendsubtarget && m_subtarget) {
+ m_subtarget->UpdateBlenderObjectMatrix(m_blendsubtarget);
+ if (m_subpose && m_subtarget->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ m_blendsubtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose();
+ }
+ }
+}
+
+void BL_ArmatureConstraint::RestoreTarget()
+{
+ if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
+ if (m_blendtarget) {
+ Mat4CpyMat4(m_blendtarget->obmat, m_blendmat);
+ if (m_pose)
+ m_blendtarget->pose = m_pose;
+ }
+ if (m_blendsubtarget && m_subtarget) {
+ Mat4CpyMat4(m_blendsubtarget->obmat, m_blendsubmat);
+ if (m_subpose)
+ m_blendsubtarget->pose = m_subpose;
+ }
+ }
+}
+
+bool BL_ArmatureConstraint::Match(const char* posechannel, const char* constraint)
+{
+ return (!strcmp(m_posechannel->name, posechannel) && !strcmp(m_constraint->name, constraint));
+}
+
+void BL_ArmatureConstraint::SetTarget(KX_GameObject* target)
+{
+ if (m_blendtarget) {
+ if (target != m_target) {
+ m_target->UnregisterObject(m_armature);
+ m_target = target;
+ if (m_target)
+ m_target->RegisterObject(m_armature);
+ }
+ }
+
+}
+
+void BL_ArmatureConstraint::SetSubtarget(KX_GameObject* subtarget)
+{
+ if (m_blendsubtarget) {
+ if (subtarget != m_subtarget) {
+ m_subtarget->UnregisterObject(m_armature);
+ m_subtarget = subtarget;
+ if (m_subtarget)
+ m_subtarget->RegisterObject(m_armature);
+ }
+ }
+
+}
+
+#ifndef DISABLE_PYTHON
+
+// PYTHON
+
+PyMethodDef BL_ArmatureConstraint::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+// order of definition of attributes, must match Attributes[] array
+#define BCA_TYPE 0
+#define BCA_NAME 1
+#define BCA_ENFORCE 2
+#define BCA_HEADTAIL 3
+#define BCA_LINERROR 4
+#define BCA_ROTERROR 5
+#define BCA_TARGET 6
+#define BCA_SUBTARGET 7
+#define BCA_ACTIVE 8
+#define BCA_IKWEIGHT 9
+#define BCA_IKTYPE 10
+#define BCA_IKFLAG 11
+#define BCA_IKDIST 12
+#define BCA_IKMODE 13
+
+PyAttributeDef BL_ArmatureConstraint::Attributes[] = {
+ // Keep these attributes in order of BCA_ defines!!! used by py_attr_getattr and py_attr_setattr
+ KX_PYATTRIBUTE_RO_FUNCTION("type",BL_ArmatureConstraint,py_attr_getattr),
+ KX_PYATTRIBUTE_RO_FUNCTION("name",BL_ArmatureConstraint,py_attr_getattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("enforce",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("headtail",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RO_FUNCTION("lin_error",BL_ArmatureConstraint,py_attr_getattr),
+ KX_PYATTRIBUTE_RO_FUNCTION("rot_error",BL_ArmatureConstraint,py_attr_getattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("target",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("subtarget",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("active",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("ik_weight",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RO_FUNCTION("ik_type",BL_ArmatureConstraint,py_attr_getattr),
+ KX_PYATTRIBUTE_RO_FUNCTION("ik_flag",BL_ArmatureConstraint,py_attr_getattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("ik_dist",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+ KX_PYATTRIBUTE_RW_FUNCTION("ik_mode",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
+
+ { NULL } //Sentinel
+};
+
+
+PyObject* BL_ArmatureConstraint::py_attr_getattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ BL_ArmatureConstraint* self= static_cast<BL_ArmatureConstraint*>(self_v);
+ bConstraint* constraint = self->m_constraint;
+ bKinematicConstraint* ikconstraint = (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) ? (bKinematicConstraint*)constraint->data : NULL;
+ int attr_order = attrdef-Attributes;
+
+ if (!constraint) {
+ PyErr_SetString(PyExc_AttributeError, "constraint is NULL");
+ return NULL;
+ }
+
+ switch (attr_order) {
+ case BCA_TYPE:
+ return PyLong_FromLong(constraint->type);
+ case BCA_NAME:
+ return PyUnicode_FromString(constraint->name);
+ case BCA_ENFORCE:
+ return PyFloat_FromDouble(constraint->enforce);
+ case BCA_HEADTAIL:
+ return PyFloat_FromDouble(constraint->headtail);
+ case BCA_LINERROR:
+ return PyFloat_FromDouble(constraint->lin_error);
+ case BCA_ROTERROR:
+ return PyFloat_FromDouble(constraint->rot_error);
+ case BCA_TARGET:
+ if (!self->m_target)
+ Py_RETURN_NONE;
+ else
+ return self->m_target->GetProxy();
+ case BCA_SUBTARGET:
+ if (!self->m_subtarget)
+ Py_RETURN_NONE;
+ else
+ return self->m_subtarget->GetProxy();
+ case BCA_ACTIVE:
+ return PyBool_FromLong(constraint->flag & CONSTRAINT_OFF);
+ case BCA_IKWEIGHT:
+ case BCA_IKTYPE:
+ case BCA_IKFLAG:
+ case BCA_IKDIST:
+ case BCA_IKMODE:
+ if (!ikconstraint) {
+ PyErr_SetString(PyExc_AttributeError, "constraint is not of IK type");
+ return NULL;
+ }
+ switch (attr_order) {
+ case BCA_IKWEIGHT:
+ return PyFloat_FromDouble((ikconstraint)?ikconstraint->weight:0.0);
+ case BCA_IKTYPE:
+ return PyLong_FromLong(ikconstraint->type);
+ case BCA_IKFLAG:
+ return PyLong_FromLong(ikconstraint->flag);
+ case BCA_IKDIST:
+ return PyFloat_FromDouble(ikconstraint->dist);
+ case BCA_IKMODE:
+ return PyLong_FromLong(ikconstraint->mode);
+ }
+ // should not come here
+ break;
+ }
+ PyErr_SetString(PyExc_AttributeError, "constraint unknown attribute");
+ return NULL;
+}
+
+int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ BL_ArmatureConstraint* self= static_cast<BL_ArmatureConstraint*>(self_v);
+ bConstraint* constraint = self->m_constraint;
+ bKinematicConstraint* ikconstraint = (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) ? (bKinematicConstraint*)constraint->data : NULL;
+ int attr_order = attrdef-Attributes;
+ int ival;
+ double dval;
+ char* sval;
+ KX_GameObject *oval;
+
+ if (!constraint) {
+ PyErr_SetString(PyExc_AttributeError, "constraint is NULL");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ switch (attr_order) {
+ case BCA_ENFORCE:
+ dval = PyFloat_AsDouble(value);
+ if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "constraint.enforce = float: BL_ArmatureConstraint, expected a float between 0 and 1");
+ return PY_SET_ATTR_FAIL;
+ }
+ constraint->enforce = dval;
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_HEADTAIL:
+ dval = PyFloat_AsDouble(value);
+ if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "constraint.headtail = float: BL_ArmatureConstraint, expected a float between 0 and 1");
+ return PY_SET_ATTR_FAIL;
+ }
+ constraint->headtail = dval;
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_TARGET:
+ if (!ConvertPythonToGameObject(value, &oval, true, "constraint.target = value: BL_ArmatureConstraint"))
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
+ self->SetTarget(oval);
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_SUBTARGET:
+ if (!ConvertPythonToGameObject(value, &oval, true, "constraint.subtarget = value: BL_ArmatureConstraint"))
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
+ self->SetSubtarget(oval);
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_ACTIVE:
+ ival = PyObject_IsTrue( value );
+ if (ival == -1) {
+ PyErr_SetString(PyExc_AttributeError, "constraint.active = bool: BL_ArmatureConstraint, expected True or False");
+ return PY_SET_ATTR_FAIL;
+ }
+ self->m_constraint->flag = (self->m_constraint->flag & ~CONSTRAINT_OFF) | ((ival)?0:CONSTRAINT_OFF);
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_IKWEIGHT:
+ case BCA_IKDIST:
+ case BCA_IKMODE:
+ if (!ikconstraint) {
+ PyErr_SetString(PyExc_AttributeError, "constraint is not of IK type");
+ return PY_SET_ATTR_FAIL;
+ }
+ switch (attr_order) {
+ case BCA_IKWEIGHT:
+ dval = PyFloat_AsDouble(value);
+ if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "constraint.weight = float: BL_ArmatureConstraint, expected a float between 0 and 1");
+ return PY_SET_ATTR_FAIL;
+ }
+ ikconstraint->weight = dval;
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_IKDIST:
+ dval = PyFloat_AsDouble(value);
+ if (dval < 0.0f) { /* also accounts for non float */
+ PyErr_SetString(PyExc_AttributeError, "constraint.ik_dist = float: BL_ArmatureConstraint, expected a positive float");
+ return PY_SET_ATTR_FAIL;
+ }
+ ikconstraint->dist = dval;
+ return PY_SET_ATTR_SUCCESS;
+
+ case BCA_IKMODE:
+ ival = PyLong_AsLong(value);
+ if (ival < 0) {
+ PyErr_SetString(PyExc_AttributeError, "constraint.ik_mode = integer: BL_ArmatureConstraint, expected a positive integer");
+ return PY_SET_ATTR_FAIL;
+ }
+ ikconstraint->mode = ival;
+ return PY_SET_ATTR_SUCCESS;
+ }
+ // should not come here
+ break;
+
+ }
+
+ PyErr_SetString(PyExc_AttributeError, "constraint unknown attribute");
+ return PY_SET_ATTR_FAIL;
+}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.h b/source/gameengine/Converter/BL_ArmatureConstraint.h
new file mode 100644
index 00000000000..2a202dfe62e
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureConstraint.h
@@ -0,0 +1,118 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 __BL_ARMATURECONSTRAINT
+#define __BL_ARMATURECONSTRAINT
+
+#include "DNA_constraint_types.h"
+#include "GEN_HashedPtr.h"
+#include "GEN_Map.h"
+#include "PyObjectPlus.h"
+
+class SCA_IObject;
+class KX_GameObject;
+class BL_ArmatureObject;
+struct bConstraint;
+struct bPoseChannel;
+struct Object;
+struct bPose;
+
+/**
+ * SG_DList : element of controlled constraint list
+ * head = BL_ArmatureObject::m_controlledConstraints
+ * SG_QList : not used
+ */
+class BL_ArmatureConstraint : public PyObjectPlus
+{
+ Py_Header;
+
+private:
+ struct bConstraint* m_constraint;
+ struct bPoseChannel* m_posechannel;
+ class BL_ArmatureObject* m_armature;
+ char m_name[64];
+ KX_GameObject* m_target;
+ KX_GameObject* m_subtarget;
+ struct Object* m_blendtarget;
+ struct Object* m_blendsubtarget;
+ float m_blendmat[4][4];
+ float m_blendsubmat[4][4];
+ struct bPose* m_pose;
+ struct bPose* m_subpose;
+
+public:
+ BL_ArmatureConstraint(class BL_ArmatureObject *armature,
+ struct bPoseChannel *posechannel,
+ struct bConstraint *constraint,
+ KX_GameObject* target,
+ KX_GameObject* subtarget);
+ virtual ~BL_ArmatureConstraint();
+
+ BL_ArmatureConstraint* GetReplica() const;
+ void ReParent(BL_ArmatureObject* armature);
+ void Relink(GEN_Map<GEN_HashedPtr, void*> *map);
+ bool UnlinkObject(SCA_IObject* clientobj);
+
+ void UpdateTarget();
+ void RestoreTarget();
+
+ bool Match(const char* posechannel, const char* constraint);
+ const char* GetName() { return m_name; }
+
+ void SetConstraintFlag(int flag)
+ {
+ if (m_constraint)
+ m_constraint->flag |= flag;
+ }
+ void ClrConstraintFlag(int flag)
+ {
+ if (m_constraint)
+ m_constraint->flag &= ~flag;
+ }
+ void SetWeight(float weight)
+ {
+ if (m_constraint && m_constraint->type == CONSTRAINT_TYPE_KINEMATIC && m_constraint->data) {
+ bKinematicConstraint* con = (bKinematicConstraint*)m_constraint->data;
+ con->weight = weight;
+ }
+ }
+ void SetTarget(KX_GameObject* target);
+ void SetSubtarget(KX_GameObject* subtarget);
+
+#ifndef DISABLE_PYTHON
+
+ // Python access
+ virtual PyObject* py_repr(void);
+
+ static PyObject* py_attr_getattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif // DISABLE_PYTHON
+};
+
+#endif //__BL_ARMATURECONSTRAINT
+
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index cfd90813a16..a6066adc03e 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -29,9 +29,15 @@
#include "BL_ArmatureObject.h"
#include "BL_ActionActuator.h"
+#include "KX_BlenderSceneConverter.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_arithb.h"
+#include "BIK_api.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_utildefines.h"
+#include "BKE_constraint.h"
#include "GEN_Map.h"
#include "GEN_HashedPtr.h"
#include "MEM_guardedalloc.h"
@@ -39,6 +45,11 @@
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_nla_types.h"
+#include "DNA_constraint_types.h"
+#include "KX_PythonSeq.h"
+#include "KX_PythonInit.h"
+#include "KX_KetsjiEngine.h"
#include "MT_Matrix4x4.h"
@@ -46,6 +57,153 @@
#include <config.h>
#endif
+/**
+ * Move here pose function for game engine so that we can mix with GE objects
+ * Principle is as follow:
+ * Use Blender structures so that where_is_pose can be used unchanged
+ * Copy the constraint so that they can be enabled/disabled/added/removed at runtime
+ * Don't copy the constraints for the pose used by the Action actuator, it does not need them.
+ * Scan the constraint structures so that the KX equivalent of target objects are identified and
+ * stored in separate list.
+ * When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
+ * Blender objects and restore after the evaluation.
+ */
+void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
+{
+ bPose *out;
+ bPoseChannel *pchan, *outpchan;
+ GHash *ghash;
+
+ /* the game engine copies the current armature pose and then swaps
+ * the object pose pointer. this makes it possible to change poses
+ * without affecting the original blender data. */
+
+ if (!src) {
+ *dst=NULL;
+ return;
+ }
+ else if (*dst==src) {
+ printf("copy_pose source and target are the same\n");
+ *dst=NULL;
+ return;
+ }
+
+ out= (bPose*)MEM_dupallocN(src);
+ out->agroups.first= out->agroups.last= NULL;
+ out->ikdata = NULL;
+ out->ikparam = MEM_dupallocN(out->ikparam);
+ out->flag |= POSE_GAME_ENGINE;
+ BLI_duplicatelist(&out->chanbase, &src->chanbase);
+
+ /* remap pointers */
+ ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ pchan= (bPoseChannel*)src->chanbase.first;
+ outpchan= (bPoseChannel*)out->chanbase.first;
+ for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
+ BLI_ghash_insert(ghash, pchan, outpchan);
+
+ for (pchan=(bPoseChannel*)out->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
+ pchan->parent= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->parent);
+ pchan->child= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->child);
+ pchan->path= NULL;
+
+ if (copy_constraint) {
+ ListBase listb;
+ // copy all constraint for backward compatibility
+ copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
+ pchan->constraints= listb;
+ } else {
+ pchan->constraints.first = NULL;
+ pchan->constraints.last = NULL;
+ }
+ }
+
+ BLI_ghash_free(ghash, NULL, NULL);
+
+ *dst=out;
+}
+
+
+
+/* Only allowed for Poses with identical channels */
+void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/)
+{
+ short mode= ACTSTRIPMODE_BLEND;
+
+ bPoseChannel *dchan;
+ const bPoseChannel *schan;
+ bConstraint *dcon, *scon;
+ float dstweight;
+ int i;
+
+ switch (mode){
+ case ACTSTRIPMODE_BLEND:
+ dstweight = 1.0F - srcweight;
+ break;
+ case ACTSTRIPMODE_ADD:
+ dstweight = 1.0F;
+ break;
+ default :
+ dstweight = 1.0F;
+ }
+
+ schan= (bPoseChannel*)src->chanbase.first;
+ for (dchan = (bPoseChannel*)dst->chanbase.first; dchan; dchan=(bPoseChannel*)dchan->next, schan= (bPoseChannel*)schan->next){
+ // always blend on all channels since we don't know which one has been set
+ /* quat interpolation done separate */
+ if (schan->rotmode == ROT_MODE_QUAT) {
+ float dquat[4], squat[4];
+
+ QUATCOPY(dquat, dchan->quat);
+ QUATCOPY(squat, schan->quat);
+ if (mode==ACTSTRIPMODE_BLEND)
+ QuatInterpol(dchan->quat, dquat, squat, srcweight);
+ else {
+ QuatMulFac(squat, srcweight);
+ QuatMul(dchan->quat, dquat, squat);
+ }
+
+ NormalQuat(dchan->quat);
+ }
+
+ for (i=0; i<3; i++) {
+ /* blending for loc and scale are pretty self-explanatory... */
+ dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
+ dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
+
+ /* euler-rotation interpolation done here instead... */
+ // FIXME: are these results decent?
+ if (schan->rotmode)
+ dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
+ }
+ for(dcon= (bConstraint*)dchan->constraints.first, scon= (bConstraint*)schan->constraints.first; dcon && scon; dcon= (bConstraint*)dcon->next, scon= (bConstraint*)scon->next) {
+ /* no 'add' option for constraint blending */
+ dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
+ }
+ }
+
+ /* this pose is now in src time */
+ dst->ctime= src->ctime;
+}
+
+void game_free_pose(bPose *pose)
+{
+ if (pose) {
+ /* free pose-channels and constraints */
+ free_pose_channels(pose);
+
+ /* free IK solver state */
+ BIK_clear_data(pose);
+
+ /* free IK solver param */
+ if (pose->ikparam)
+ MEM_freeN(pose->ikparam);
+
+ MEM_freeN(pose);
+ }
+}
+
BL_ArmatureObject::BL_ArmatureObject(
void* sgReplicationInfo,
SG_Callbacks callbacks,
@@ -53,12 +211,17 @@ BL_ArmatureObject::BL_ArmatureObject(
Scene *scene)
: KX_GameObject(sgReplicationInfo,callbacks),
+ m_controlledConstraints(),
+ m_poseChannels(),
m_objArma(armature),
m_framePose(NULL),
m_scene(scene), // maybe remove later. needed for where_is_pose
m_lastframe(0.0),
+ m_timestep(0.040),
m_activeAct(NULL),
m_activePriority(999),
+ m_constraintNumber(0),
+ m_channelNumber(0),
m_lastapplyframe(0.0)
{
m_armature = (bArmature *)armature->data;
@@ -67,7 +230,177 @@ BL_ArmatureObject::BL_ArmatureObject(
* the original pose before calling into blender functions, to deal with
* replica's or other objects using the same blender object */
m_pose = NULL;
- game_copy_pose(&m_pose, m_objArma->pose);
+ game_copy_pose(&m_pose, m_objArma->pose, 1);
+ // store the original armature object matrix
+ memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat));
+}
+
+BL_ArmatureObject::~BL_ArmatureObject()
+{
+ BL_ArmatureConstraint* constraint;
+ while ((constraint = m_controlledConstraints.Remove()) != NULL) {
+ delete constraint;
+ }
+ BL_ArmatureChannel* channel;
+ while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) {
+ delete channel;
+ }
+ if (m_pose)
+ game_free_pose(m_pose);
+ if (m_framePose)
+ game_free_pose(m_framePose);
+}
+
+
+void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
+{
+ // first delete any existing constraint (should not have any)
+ while (!m_controlledConstraints.Empty()) {
+ BL_ArmatureConstraint* constraint = m_controlledConstraints.Remove();
+ delete constraint;
+ }
+ m_constraintNumber = 0;
+
+ // list all the constraint and convert them to BL_ArmatureConstraint
+ // get the persistent pose structure
+ bPoseChannel* pchan;
+ bConstraint* pcon;
+ bConstraintTypeInfo* cti;
+ Object* blendtarget;
+ KX_GameObject* gametarget;
+ KX_GameObject* gamesubtarget;
+
+ // and locate the constraint
+ for (pchan = (bPoseChannel*)m_pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
+ for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) {
+ if (pcon->flag & CONSTRAINT_DISABLE)
+ continue;
+ // which constraint should we support?
+ switch (pcon->type) {
+ case CONSTRAINT_TYPE_TRACKTO:
+ case CONSTRAINT_TYPE_KINEMATIC:
+ case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_MINMAX:
+ case CONSTRAINT_TYPE_SIZELIKE:
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ case CONSTRAINT_TYPE_STRETCHTO:
+ case CONSTRAINT_TYPE_CLAMPTO:
+ case CONSTRAINT_TYPE_TRANSFORM:
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ cti = constraint_get_typeinfo(pcon);
+ gametarget = gamesubtarget = NULL;
+ if (cti && cti->get_constraint_targets) {
+ ListBase listb = { NULL, NULL };
+ cti->get_constraint_targets(pcon, &listb);
+ if (listb.first) {
+ bConstraintTarget* target = (bConstraintTarget*)listb.first;
+ if (target->tar && target->tar != m_objArma) {
+ // only remember external objects, self target is handled automatically
+ blendtarget = target->tar;
+ gametarget = converter->FindGameObject(blendtarget);
+ }
+ if (target->next != NULL) {
+ // secondary target
+ target = (bConstraintTarget*)target->next;
+ if (target->tar && target->tar != m_objArma) {
+ // only track external object
+ blendtarget = target->tar;
+ gamesubtarget = converter->FindGameObject(blendtarget);
+ }
+ }
+ }
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(pcon, &listb, 1);
+ }
+ BL_ArmatureConstraint* constraint = new BL_ArmatureConstraint(this, pchan, pcon, gametarget, gamesubtarget);
+ m_controlledConstraints.AddBack(constraint);
+ m_constraintNumber++;
+ }
+ }
+ }
+}
+
+BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(const char* posechannel, const char* constraintname)
+{
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end(); ++cit) {
+ BL_ArmatureConstraint* constraint = *cit;
+ if (constraint->Match(posechannel, constraintname))
+ return constraint;
+ }
+ return NULL;
+}
+
+BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(const char* posechannelconstraint)
+{
+ // performance: use hash string instead of plain string compare
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end(); ++cit) {
+ BL_ArmatureConstraint* constraint = *cit;
+ if (!strcmp(constraint->GetName(), posechannelconstraint))
+ return constraint;
+ }
+ return NULL;
+}
+
+BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(int index)
+{
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end() && index; ++cit, --index);
+ return (cit.end()) ? NULL : *cit;
+}
+
+/* this function is called to populate the m_poseChannels list */
+void BL_ArmatureObject::LoadChannels()
+{
+ if (m_poseChannels.Empty()) {
+ bPoseChannel* pchan;
+ BL_ArmatureChannel* proxy;
+
+ m_channelNumber = 0;
+ for (pchan = (bPoseChannel*)m_pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
+ proxy = new BL_ArmatureChannel(this, pchan);
+ m_poseChannels.AddBack(proxy);
+ m_channelNumber++;
+ }
+ }
+}
+
+BL_ArmatureChannel* BL_ArmatureObject::GetChannel(bPoseChannel* pchan)
+{
+ LoadChannels();
+ SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
+ for (cit.begin(); !cit.end(); ++cit)
+ {
+ BL_ArmatureChannel* channel = *cit;
+ if (channel->m_posechannel == pchan)
+ return channel;
+ }
+ return NULL;
+}
+
+BL_ArmatureChannel* BL_ArmatureObject::GetChannel(const char* str)
+{
+ LoadChannels();
+ SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
+ for (cit.begin(); !cit.end(); ++cit)
+ {
+ BL_ArmatureChannel* channel = *cit;
+ if (!strcmp(channel->m_posechannel->name, str))
+ return channel;
+ }
+ return NULL;
+}
+
+BL_ArmatureChannel* BL_ArmatureObject::GetChannel(int index)
+{
+ LoadChannels();
+ if (index < 0 || index >= m_channelNumber)
+ return NULL;
+ SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
+ for (cit.begin(); !cit.end() && index; ++cit, --index);
+ return (cit.end()) ? NULL : *cit;
}
CValue* BL_ArmatureObject::GetReplica()
@@ -83,22 +416,61 @@ void BL_ArmatureObject::ProcessReplica()
KX_GameObject::ProcessReplica();
m_pose = NULL;
- game_copy_pose(&m_pose, pose);
+ m_framePose = NULL;
+ game_copy_pose(&m_pose, pose, 1);
}
-BL_ArmatureObject::~BL_ArmatureObject()
+void BL_ArmatureObject::ReParentLogic()
{
- if (m_pose)
- game_free_pose(m_pose);
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end(); ++cit) {
+ (*cit)->ReParent(this);
+ }
+ KX_GameObject::ReParentLogic();
+}
+
+void BL_ArmatureObject::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end(); ++cit) {
+ (*cit)->Relink(obj_map);
+ }
+ KX_GameObject::Relink(obj_map);
+}
+
+bool BL_ArmatureObject::UnlinkObject(SCA_IObject* clientobj)
+{
+ // clientobj is being deleted, make sure we don't hold any reference to it
+ bool res = false;
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end(); ++cit) {
+ res |= (*cit)->UnlinkObject(clientobj);
+ }
+ return res;
}
void BL_ArmatureObject::ApplyPose()
{
m_armpose = m_objArma->pose;
m_objArma->pose = m_pose;
+ // in the GE, we use ctime to store the timestep
+ m_pose->ctime = (float)m_timestep;
//m_scene->r.cfra++;
if(m_lastapplyframe != m_lastframe) {
+ // update the constraint if any, first put them all off so that only the active ones will be updated
+ SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
+ for (cit.begin(); !cit.end(); ++cit) {
+ (*cit)->UpdateTarget();
+ }
+ // update ourself
+ UpdateBlenderObjectMatrix(m_objArma);
where_is_pose(m_scene, m_objArma); // XXX
+ // restore ourself
+ memcpy(m_objArma->obmat, m_obmat, sizeof(m_obmat));
+ // restore active targets
+ for (cit.begin(); !cit.end(); ++cit) {
+ (*cit)->RestoreTarget();
+ }
m_lastapplyframe = m_lastframe;
}
}
@@ -119,30 +491,37 @@ bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority,
{
if (curtime != m_lastframe){
m_activePriority = 9999;
+ // compute the timestep for the underlying IK algorithm
+ m_timestep = curtime-m_lastframe;
m_lastframe= curtime;
m_activeAct = NULL;
// remember the pose at the start of the frame
- m_framePose = m_pose;
+ GetPose(&m_framePose);
}
- if (priority<=m_activePriority)
+ if (act)
{
- if (priority<m_activePriority)
- // this action overwrites the previous ones, start from initial pose to cancel their effects
- m_pose = m_framePose;
- if (m_activeAct && (m_activeAct!=act))
- m_activeAct->SetBlendTime(0.0); /* Reset the blend timer */
- m_activeAct = act;
- m_activePriority = priority;
- m_lastframe = curtime;
-
- return true;
- }
- else{
- act->SetBlendTime(0.0);
- return false;
+ if (priority<=m_activePriority)
+ {
+ if (priority<m_activePriority) {
+ // this action overwrites the previous ones, start from initial pose to cancel their effects
+ SetPose(m_framePose);
+ if (m_activeAct && (m_activeAct!=act))
+ /* Reset the blend timer since this new action cancels the old one */
+ m_activeAct->SetBlendTime(0.0);
+ }
+ m_activeAct = act;
+ m_activePriority = priority;
+ m_lastframe = curtime;
+
+ return true;
+ }
+ else{
+ act->SetBlendTime(0.0);
+ return false;
+ }
}
-
+ return false;
}
BL_ActionActuator * BL_ArmatureObject::GetActiveAction()
@@ -161,7 +540,7 @@ void BL_ArmatureObject::GetPose(bPose **pose)
a crash and memory leakage when
&BL_ActionActuator::m_pose is freed
*/
- game_copy_pose(pose, m_pose);
+ game_copy_pose(pose, m_pose, 0);
}
else {
if (*pose == m_pose)
@@ -178,7 +557,7 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose)
/* Otherwise, copy the armature's pose channels into the caller-supplied pose */
if (!*pose)
- game_copy_pose(pose, m_pose);
+ game_copy_pose(pose, m_pose, 0);
else
extract_pose_from_pose(*pose, m_pose);
}
@@ -210,3 +589,72 @@ float BL_ArmatureObject::GetBoneLength(Bone* bone) const
{
return (float)(MT_Point3(bone->head) - MT_Point3(bone->tail)).length();
}
+
+#ifndef DISABLE_PYTHON
+
+// PYTHON
+
+PyTypeObject BL_ArmatureObject::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "BL_ArmatureObject",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,
+ &KX_GameObject::Sequence,
+ &KX_GameObject::Mapping,
+ 0,0,0,
+ NULL,
+ NULL,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &KX_GameObject::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef BL_ArmatureObject::Methods[] = {
+
+ KX_PYMETHODTABLE_NOARGS(BL_ArmatureObject, update),
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef BL_ArmatureObject::Attributes[] = {
+
+ KX_PYATTRIBUTE_RO_FUNCTION("constraints", BL_ArmatureObject, pyattr_get_constraints),
+ KX_PYATTRIBUTE_RO_FUNCTION("channels", BL_ArmatureObject, pyattr_get_channels),
+ {NULL} //Sentinel
+};
+
+PyObject* BL_ArmatureObject::pyattr_get_constraints(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ return KX_PythonSeq_CreatePyObject((static_cast<BL_ArmatureObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CONSTRAINTS);
+}
+
+PyObject* BL_ArmatureObject::pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ BL_ArmatureObject* self = static_cast<BL_ArmatureObject*>(self_v);
+ self->LoadChannels(); // make sure we have the channels
+ return KX_PythonSeq_CreatePyObject((static_cast<BL_ArmatureObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CHANNELS);
+}
+
+KX_PYMETHODDEF_DOC_NOARGS(BL_ArmatureObject, update,
+ "update()\n"
+ "Make sure that the armature will be updated on next graphic frame.\n"
+ "This is automatically done if a KX_ArmatureActuator with mode run is active\n"
+ "or if an action is playing. This function is usefull in other cases.\n")
+{
+ SetActiveAction(NULL, 0, KX_GetActiveEngine()->GetFrameTime());
+ Py_RETURN_NONE;
+}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h
index af0b7dc201c..b7ef38468bb 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.h
+++ b/source/gameengine/Converter/BL_ArmatureObject.h
@@ -31,21 +31,34 @@
#define BL_ARMATUREOBJECT
#include "KX_GameObject.h"
+#include "BL_ArmatureConstraint.h"
+#include "BL_ArmatureChannel.h"
#include "SG_IObject.h"
+#include <vector>
+#include <algorithm>
struct bArmature;
struct Bone;
+struct bConstraint;
class BL_ActionActuator;
+class BL_ArmatureActuator;
class MT_Matrix4x4;
struct Object;
+class KX_BlenderSceneConverter;
class BL_ArmatureObject : public KX_GameObject
{
+ Py_Header;
public:
+
double GetLastFrame ();
short GetActivePriority();
virtual void ProcessReplica();
+ virtual void ReParentLogic();
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+
class BL_ActionActuator * GetActiveAction();
BL_ArmatureObject(
@@ -73,6 +86,19 @@ public:
Object* GetArmatureObject() {return m_objArma;}
+ // for constraint python API
+ void LoadConstraints(KX_BlenderSceneConverter* converter);
+ size_t GetConstraintNumber() const { return m_constraintNumber; }
+ BL_ArmatureConstraint* GetConstraint(const char* posechannel, const char* constraint);
+ BL_ArmatureConstraint* GetConstraint(const char* posechannelconstraint);
+ BL_ArmatureConstraint* GetConstraint(int index);
+ // for pose channel python API
+ void LoadChannels();
+ size_t GetChannelNumber() const { return m_constraintNumber; }
+ BL_ArmatureChannel* GetChannel(bPoseChannel* channel);
+ BL_ArmatureChannel* GetChannel(const char* channel);
+ BL_ArmatureChannel* GetChannel(int index);
+
/// Retrieve the pose matrix for the specified bone.
/// Returns true on success.
bool GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix);
@@ -81,7 +107,21 @@ public:
float GetBoneLength(Bone* bone) const;
virtual int GetGameObjectType() { return OBJ_ARMATURE; }
+
+#ifndef DISABLE_PYTHON
+
+ // PYTHON
+ static PyObject* pyattr_get_constraints(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ KX_PYMETHOD_DOC_NOARGS(BL_ArmatureObject, update);
+
+#endif // DISABLE_PYTHON
+
protected:
+ /* list element: BL_ArmatureConstraint. Use SG_DListHead to have automatic list replication */
+ SG_DListHead<BL_ArmatureConstraint> m_controlledConstraints;
+ /* list element: BL_ArmatureChannel. Use SG_DList to avoid list replication */
+ SG_DList m_poseChannels;
Object *m_objArma;
struct bArmature *m_armature;
struct bPose *m_pose;
@@ -89,18 +129,23 @@ protected:
struct bPose *m_framePose;
struct Scene *m_scene; // need for where_is_pose
double m_lastframe;
+ double m_timestep; // delta since last pose evaluation.
class BL_ActionActuator *m_activeAct;
short m_activePriority;
+ size_t m_constraintNumber;
+ size_t m_channelNumber;
+ // store the original armature object matrix
+ float m_obmat[4][4];
double m_lastapplyframe;
+};
+/* Pose function specific to the game engine */
+void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, short mode*/); /* was blend_poses */
+//void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
+void game_copy_pose(struct bPose **dst, struct bPose *src, int copy_con);
+void game_free_pose(struct bPose *pose);
-#ifdef WITH_CXX_GUARDEDALLOC
-public:
- void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ArmatureObject"); }
- void operator delete( void *mem ) { MEM_freeN(mem); }
-#endif
-};
#endif
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 230820719aa..db32f18f63b 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -838,8 +838,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
if (mface->v4)
tan3 = tangent[f*4 + 3];
}
-
- ma = give_current_material(blenderobj, mface->mat_nr+1);
+ if(blenderobj)
+ ma = give_current_material(blenderobj, mface->mat_nr+1);
+ else
+ ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL;
{
bool visible = true;
@@ -1895,7 +1897,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
KX_Scene* kxscene,
KX_KetsjiEngine* ketsjiEngine,
e_PhysicsEngine physics_engine,
- PyObject* pythondictionary,
RAS_IRenderTools* rendertools,
RAS_ICanvas* canvas,
KX_BlenderSceneConverter* converter,
@@ -2501,6 +2502,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->GetDeformer()->UpdateBuckets();
}
+ // Set up armature constraints
+ for (i=0;i<sumolist->GetCount();++i)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+ if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ ((BL_ArmatureObject*)gameobj)->LoadConstraints(converter);
+ }
+
bool processCompoundChildren = false;
// create physics information
@@ -2643,7 +2652,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
struct Object* blenderobj = gameobj->GetBlenderObject();
int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
- BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,layerMask,isInActiveLayer,converter);
+ BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
index b8f9d1ec4e6..218b296b47b 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.h
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.h
@@ -40,7 +40,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
class KX_Scene* kxscene,
class KX_KetsjiEngine* ketsjiEngine,
e_PhysicsEngine physics_engine,
- PyObject* pythondictionary,
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas,
class KX_BlenderSceneConverter* sceneconverter,
diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp
index 81ce9ff6154..0af6556f285 100644
--- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp
@@ -412,6 +412,8 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame)
return keepgoing;
};
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -492,3 +494,5 @@ int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE
return PY_SET_ATTR_SUCCESS;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h
index 28a6d90abdf..efb1293a5eb 100644
--- a/source/gameengine/Converter/BL_ShapeActionActuator.h
+++ b/source/gameengine/Converter/BL_ShapeActionActuator.h
@@ -51,7 +51,7 @@ public:
short blendin,
short priority,
float stride)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_SHAPEACTION),
m_lastpos(0, 0, 0),
m_blendframe(0),
@@ -82,6 +82,8 @@ public:
bAction* GetAction() { return m_action; }
void SetAction(bAction* act) { m_action= act; }
+#ifndef DISABLE_PYTHON
+
static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
@@ -123,6 +125,8 @@ public:
}
+#endif // DISABLE_PYTHON
+
protected:
void SetStartTime(float curtime);
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index 257ca856b2c..f9af2c23629 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -59,9 +59,15 @@ SET(INC
../../../source/blender/misc
../../../source/blender/blenloader
../../../source/blender/gpu
+ ../../../source/blender/ikplugin
../../../extern/bullet2/src
- ${PYTHON_INC}
)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(bf_converter "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_converter', sources, Split(incs), [], libtype=['game','player'], priority=[5,70] )
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 151564391f3..26b4514061c 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -243,7 +243,6 @@ struct BlenderDebugDraw : public btIDebugDraw
#endif
void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
- PyObject* dictobj,
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas)
{
@@ -328,7 +327,6 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
destinationscene,
m_ketsjiEngine,
physics_engine,
- dictobj,
rendertools,
canvas,
this,
@@ -920,3 +918,10 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
}
+
+#ifndef DISABLE_PYTHON
+PyObject *KX_BlenderSceneConverter::GetPyNamespace()
+{
+ return m_ketsjiEngine->GetPyNamespace();
+}
+#endif
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index bb87a21a683..f74944d3552 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -89,7 +89,6 @@ public:
*/
virtual void ConvertScene(
class KX_Scene* destinationscene,
- PyObject* dictobj,
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas
);
@@ -143,6 +142,9 @@ public:
struct Main* GetMain() { return m_maggie; };
+#ifndef DISABLE_PYTHON
+ PyObject *GetPyNamespace();
+#endif
#ifdef WITH_CXX_GUARDEDALLOC
public:
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 91a39bd7686..1cb16acf148 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -88,6 +88,7 @@
#include "DNA_packedFile_types.h"
#include "BL_ActionActuator.h"
#include "BL_ShapeActionActuator.h"
+#include "BL_ArmatureActuator.h"
/* end of blender include block */
#include "BL_BlenderDataConversion.h"
@@ -1021,6 +1022,15 @@ void BL_ConvertActuators(char* maggiename,
break;
}
+ case ACT_ARMATURE:
+ {
+ bArmatureActuator* armAct = (bArmatureActuator*) bact->data;
+ KX_GameObject *tmpgob = converter->FindGameObject(armAct->target);
+ KX_GameObject *subgob = converter->FindGameObject(armAct->subtarget);
+ BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator(gameobj, armAct->type, armAct->posechannel, armAct->constraint, tmpgob, subgob, armAct->weight);
+ baseact = tmparmact;
+ break;
+ }
default:
; /* generate some error */
}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index 85ab8e4f8b8..faef0feaf48 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -91,8 +91,7 @@ LinkControllerToActuators(
void BL_ConvertControllers(
struct Object* blenderobject,
class KX_GameObject* gameobj,
- SCA_LogicManager* logicmgr,
- PyObject* pythondictionary,
+ SCA_LogicManager* logicmgr,
int activeLayerBitInfo,
bool isInActiveLayer,
KX_BlenderSceneConverter* converter
@@ -158,8 +157,9 @@ void BL_ConvertControllers(
bPythonCont* pycont = (bPythonCont*) bcontr->data;
SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
gamecontroller = pyctrl;
-
- pyctrl->SetDictionary(pythondictionary);
+#ifndef DISABLE_PYTHON
+
+ pyctrl->SetNamespace(converter->GetPyNamespace());
if(pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
if (pycont->text)
@@ -187,6 +187,8 @@ void BL_ConvertControllers(
pyctrl->SetDebug(true);
}
+#endif // DISABLE_PYTHON
+
break;
}
default:
@@ -211,7 +213,8 @@ void BL_ConvertControllers(
gameobj->AddController(gamecontroller);
converter->RegisterGameController(gamecontroller, bcontr);
-
+
+#ifndef DISABLE_PYTHON
if (bcontr->type==CONT_PYTHON) {
SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
/* not strictly needed but gives syntax errors early on and
@@ -226,7 +229,8 @@ void BL_ConvertControllers(
// pyctrl->Import();
}
}
-
+#endif // DISABLE_PYTHON
+
//done with gamecontroller
gamecontroller->Release();
}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h
index d340778290c..2689ad446bd 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.h
+++ b/source/gameengine/Converter/KX_ConvertControllers.h
@@ -34,8 +34,7 @@
void BL_ConvertControllers(
struct Object* blenderobject,
class KX_GameObject* gameobj,
- class SCA_LogicManager* logicmgr,
- PyObject* pythondictionary,
+ class SCA_LogicManager* logicmgr,
int activeLayerBitInfo,
bool isInActiveLayer,
class KX_BlenderSceneConverter* converter
diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp
index 1c22d2a0600..7ecdb6c5db6 100644
--- a/source/gameengine/Converter/KX_ConvertProperties.cpp
+++ b/source/gameengine/Converter/KX_ConvertProperties.cpp
@@ -130,7 +130,7 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
propval->Release();
}
-
+#ifndef DISABLE_PYTHON
/* Warn if we double up on attributes, this isnt quite right since it wont find inherited attributes however there arnt many */
for(PyAttributeDef *attrdef = KX_GameObject::Attributes; attrdef->m_name; attrdef++) {
if(strcmp(prop->name, attrdef->m_name)==0) {
@@ -145,6 +145,7 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
}
}
/* end warning check */
+#endif // DISABLE_PYTHON
prop = prop->next;
}
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 09027f18844..692cc91f340 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -28,6 +28,7 @@
* Conversion of Blender data blocks to KX sensor system
*/
+#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -64,6 +65,7 @@ probably misplaced */
#include "KX_NearSensor.h"
#include "KX_RadarSensor.h"
#include "KX_MouseFocusSensor.h"
+#include "KX_ArmatureSensor.h"
#include "SCA_JoystickSensor.h"
#include "KX_NetworkMessageSensor.h"
#include "SCA_ActuatorSensor.h"
@@ -302,7 +304,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
case SENS_ALWAYS:
{
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
@@ -314,7 +316,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
case SENS_DELAY:
{
// we can reuse the Always event manager for the delay sensor
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
@@ -550,7 +552,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
{
bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
SCA_EventManager* eventmgr
- = logicmgr->FindEventManager(SCA_EventManager::PROPERTY_EVENTMGR);
+ = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
STR_String propname=blenderpropsensor->name;
@@ -601,6 +603,21 @@ void BL_ConvertSensors(struct Object* blenderobject,
break;
}
+ case SENS_ARMATURE:
+ {
+ bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
+ // we will reuse the property event manager, there is nothing special with this sensor
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String bonename=blenderarmsensor->posechannel;
+ STR_String constraintname=blenderarmsensor->constraint;
+ gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
+ }
+ break;
+ }
+
case SENS_RADAR:
{
@@ -659,7 +676,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
//blenderradarsensor->angle;
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RAY_EVENTMGR);
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
@@ -691,7 +708,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
// some files didn't write randomsensor, avoid crash now for NULL ptr's
if (blenderrndsensor)
{
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RANDOM_EVENTMGR);
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
int randomSeed = blenderrndsensor->seed;
diff --git a/source/gameengine/Converter/Makefile b/source/gameengine/Converter/Makefile
index e261f9350e9..d41cc705087 100644
--- a/source/gameengine/Converter/Makefile
+++ b/source/gameengine/Converter/Makefile
@@ -53,6 +53,7 @@ CPPFLAGS += -I../../blender/blenlib
CPPFLAGS += -I../../blender/blenkernel
CPPFLAGS += -I../../blender/render/extern/include
CPPFLAGS += -I../../blender/gpu
+CPPFLAGS += -I../../blender/ikplugin
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I../Expressions -I../Rasterizer -I../GameLogic
CPPFLAGS += -I../Ketsji -I../BlenderRoutines -I../SceneGraph
diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript
index 2d126310475..616c205732c 100644
--- a/source/gameengine/Converter/SConscript
+++ b/source/gameengine/Converter/SConscript
@@ -13,14 +13,23 @@ incs += ' #source/blender/blenlib #source/blender/blenkernel #source/blender'
incs += ' #source/blender/editors/include #source/blender/makesdna #source/gameengine/Rasterizer'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #source/gameengine/GameLogic'
incs += ' #source/gameengine/Expressions #source/gameengine/Network #source/gameengine/SceneGraph'
-incs += ' #source/gameengine/Physics/common #source/gameengine/Physics/Bullet #source/gameengine/Physics/BlOde'
+incs += ' #source/gameengine/Physics/common #source/gameengine/Physics/Bullet'
incs += ' #source/gameengine/Physics/Dummy'
incs += ' #source/gameengine/Network/LoopBackNetwork'
incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu'
incs += ' #source/blender/windowmanager'
incs += ' #source/blender/makesrna'
+incs += ' #source/blender/ikplugin'
-incs += ' ' + env['BF_PYTHON_INC']
incs += ' ' + env['BF_BULLET_INC']
+if env['BF_DEBUG']:
+ if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc', 'win64-vc'):
+ defs.append('_DEBUG')
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,40], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp
index 6779c2ea780..62e43da335b 100644
--- a/source/gameengine/Expressions/BoolValue.cpp
+++ b/source/gameengine/Expressions/BoolValue.cpp
@@ -205,9 +205,9 @@ CValue* CBoolValue::GetReplica()
return replica;
}
-
-
+#ifndef DISABLE_PYTHON
PyObject* CBoolValue::ConvertValueToPython()
{
return PyBool_FromLong(m_bool != 0);
}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Expressions/BoolValue.h b/source/gameengine/Expressions/BoolValue.h
index 4d0103ec1dd..baec6bdee69 100644
--- a/source/gameengine/Expressions/BoolValue.h
+++ b/source/gameengine/Expressions/BoolValue.h
@@ -45,7 +45,9 @@ public:
void Configure(CValue* menuvalue);
virtual CValue* GetReplica();
+#ifndef DISABLE_PYTHON
virtual PyObject* ConvertValueToPython();
+#endif
private:
bool m_bool;
diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt
index 439a50852a7..db7d12f313d 100644
--- a/source/gameengine/Expressions/CMakeLists.txt
+++ b/source/gameengine/Expressions/CMakeLists.txt
@@ -30,11 +30,17 @@ SET(INC
.
../../../source/kernel/gen_system
../../../intern/string
+ ../../../intern/guardedalloc
../../../intern/moto/include
../../../source/gameengine/SceneGraph
../../../source/blender/blenloader
- ${PYTHON_INC}
)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(bf_expressions "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['game','player'], priority = [45,125] )
diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp
index 4de685a82c1..b1ac0e1ea9a 100644
--- a/source/gameengine/Expressions/FloatValue.cpp
+++ b/source/gameengine/Expressions/FloatValue.cpp
@@ -314,9 +314,9 @@ CValue* CFloatValue::GetReplica()
}
-
+#ifndef DISABLE_PYTHON
PyObject* CFloatValue::ConvertValueToPython()
{
return PyFloat_FromDouble(m_float);
}
-
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Expressions/FloatValue.h b/source/gameengine/Expressions/FloatValue.h
index 442f0eb6cf8..f1469734a1f 100644
--- a/source/gameengine/Expressions/FloatValue.h
+++ b/source/gameengine/Expressions/FloatValue.h
@@ -36,7 +36,9 @@ public:
virtual CValue* GetReplica();
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+#ifndef DISABLE_PYTHON
virtual PyObject* ConvertValueToPython();
+#endif
protected:
float m_float;
diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp
index b782de4bef6..badba8ead63 100644
--- a/source/gameengine/Expressions/IntValue.cpp
+++ b/source/gameengine/Expressions/IntValue.cpp
@@ -326,7 +326,7 @@ void CIntValue::SetValue(CValue* newval)
}
-
+#ifndef DISABLE_PYTHON
PyObject* CIntValue::ConvertValueToPython()
{
if((m_int > INT_MIN) && (m_int < INT_MAX))
@@ -334,3 +334,4 @@ PyObject* CIntValue::ConvertValueToPython()
else
return PyLong_FromLongLong(m_int);
}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Expressions/IntValue.h b/source/gameengine/Expressions/IntValue.h
index 0513026c4cf..26150674c93 100644
--- a/source/gameengine/Expressions/IntValue.h
+++ b/source/gameengine/Expressions/IntValue.h
@@ -47,7 +47,10 @@ public:
void Configure(CValue* menuvalue);
void AddConfigurationData(CValue* menuvalue);
virtual CValue* GetReplica();
+
+#ifndef DISABLE_PYTHON
virtual PyObject* ConvertValueToPython();
+#endif
protected:
virtual ~CIntValue();
diff --git a/source/gameengine/Expressions/KX_Python.h b/source/gameengine/Expressions/KX_Python.h
index f41accec730..ecbd1b9b6b0 100644
--- a/source/gameengine/Expressions/KX_Python.h
+++ b/source/gameengine/Expressions/KX_Python.h
@@ -40,11 +40,13 @@
#undef _POSIX_C_SOURCE
#endif
-
+#ifndef DISABLE_PYTHON
#include "Python.h"
#define USE_MATHUTILS // Blender 2.5x api will use mathutils, for a while we might want to test without it
+#endif
+
#ifdef __FreeBSD__
#include <osreldate.h>
#if __FreeBSD_version > 500039
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp
index 002674450d1..6e47ed913db 100644
--- a/source/gameengine/Expressions/ListValue.cpp
+++ b/source/gameengine/Expressions/ListValue.cpp
@@ -14,6 +14,8 @@
*
*/
+#include <stdio.h>
+
#include "ListValue.h"
#include "StringValue.h"
#include "VoidValue.h"
@@ -26,9 +28,255 @@
#include <config.h>
#endif
-#if ((PY_MAJOR_VERSION == 2) &&(PY_MINOR_VERSION < 5))
-#define Py_ssize_t int
-#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CListValue::CListValue()
+: CPropValue()
+{
+ m_bReleaseContents=true;
+}
+
+
+
+CListValue::~CListValue()
+{
+
+ if (m_bReleaseContents) {
+ for (unsigned int i=0;i<m_pValueArray.size();i++) {
+ m_pValueArray[i]->Release();
+ }
+ }
+}
+
+
+static STR_String gstrListRep=STR_String("List");
+
+const STR_String & CListValue::GetText()
+{
+ gstrListRep = "[";
+ STR_String commastr = "";
+
+ for (int i=0;i<GetCount();i++)
+ {
+ gstrListRep += commastr;
+ gstrListRep += GetValue(i)->GetText();
+ commastr = ",";
+ }
+ gstrListRep += "]";
+
+ return gstrListRep;
+}
+
+
+
+CValue* CListValue::GetReplica() {
+ CListValue* replica = new CListValue(*this);
+
+ replica->ProcessReplica();
+
+ replica->m_bReleaseContents=true; // for copy, complete array is copied for now...
+ // copy all values
+ int numelements = m_pValueArray.size();
+ unsigned int i=0;
+ replica->m_pValueArray.resize(numelements);
+ for (i=0;i<m_pValueArray.size();i++)
+ replica->m_pValueArray[i] = m_pValueArray[i]->GetReplica();
+
+
+ return replica;
+};
+
+
+
+void CListValue::SetValue(int i, CValue *val)
+{
+ assertd(i < m_pValueArray.size());
+ m_pValueArray[i]=val;
+}
+
+
+
+void CListValue::Resize(int num)
+{
+ m_pValueArray.resize(num);
+}
+
+
+
+void CListValue::Remove(int i)
+{
+ assertd(i<m_pValueArray.size());
+ m_pValueArray.erase(m_pValueArray.begin()+i);
+}
+
+
+
+void CListValue::ReleaseAndRemoveAll()
+{
+ for (unsigned int i=0;i<m_pValueArray.size();i++)
+ m_pValueArray[i]->Release();
+ m_pValueArray.clear();//.Clear();
+}
+
+
+
+CValue* CListValue::FindValue(const STR_String & name)
+{
+ for (int i=0; i < GetCount(); i++)
+ if (GetValue(i)->GetName() == name)
+ return GetValue(i);
+
+ return NULL;
+}
+
+CValue* CListValue::FindValue(const char * name)
+{
+ for (int i=0; i < GetCount(); i++)
+ if (GetValue(i)->GetName() == name)
+ return GetValue(i);
+
+ return NULL;
+}
+
+bool CListValue::SearchValue(CValue *val)
+{
+ for (int i=0;i<GetCount();i++)
+ if (val == GetValue(i))
+ return true;
+ return false;
+}
+
+
+
+void CListValue::SetReleaseOnDestruct(bool bReleaseContents)
+{
+ m_bReleaseContents = bReleaseContents;
+}
+
+
+
+bool CListValue::RemoveValue(CValue *val)
+{
+ bool result=false;
+
+ for (int i=GetCount()-1;i>=0;i--)
+ if (val == GetValue(i))
+ {
+ Remove(i);
+ result=true;
+ }
+ return result;
+}
+
+
+
+void CListValue::MergeList(CListValue *otherlist)
+{
+
+ int numelements = this->GetCount();
+ int numotherelements = otherlist->GetCount();
+
+
+ Resize(numelements+numotherelements);
+
+ for (int i=0;i<numotherelements;i++)
+ {
+ SetValue(i+numelements,otherlist->GetValue(i)->AddRef());
+ }
+}
+
+bool CListValue::CheckEqual(CValue* first,CValue* second)
+{
+ bool result = false;
+
+ CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second);
+
+ if (eqval==NULL)
+ return false;
+ const STR_String& text = eqval->GetText();
+ if (&text==&CBoolValue::sTrueString)
+ {
+ result = true;
+ }
+ eqval->Release();
+ return result;
+
+}
+
+
+/* ---------------------------------------------------------------------
+ * Some stuff taken from the header
+ * --------------------------------------------------------------------- */
+CValue* CListValue::Calc(VALUE_OPERATOR op,CValue *val)
+{
+ //assert(false); // todo: implement me!
+ static int error_printed = 0;
+ if (error_printed==0) {
+ fprintf(stderr, "CValueList::Calc not yet implimented\n");
+ error_printed = 1;
+ }
+ return NULL;
+}
+
+CValue* CListValue::CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue* val)
+{
+ //assert(false); // todo: implement me!
+ static int error_printed = 0;
+ if (error_printed==0) {
+ fprintf(stderr, "CValueList::CalcFinal not yet implimented\n");
+ error_printed = 1;
+ }
+ return NULL;
+}
+
+
+
+void CListValue::Add(CValue* value)
+{
+ m_pValueArray.push_back(value);
+}
+
+
+
+double CListValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+void CListValue::SetModified(bool bModified)
+{
+ CValue::SetModified(bModified);
+ int numels = GetCount();
+
+ for (int i=0;i<numels;i++)
+ GetValue(i)->SetModified(bModified);
+}
+
+
+
+bool CListValue::IsModified()
+{
+ bool bmod = CValue::IsModified(); //normal own flag
+ int numels = GetCount();
+
+ for (int i=0;i<numels;i++)
+ bmod = bmod || GetValue(i)->IsModified();
+
+ return bmod;
+}
+
+#ifndef DISABLE_PYTHON
+
+/* --------------------------------------------------------------------- */
+/* Python interface ---------------------------------------------------- */
+/* --------------------------------------------------------------------- */
Py_ssize_t listvalue_bufferlen(PyObject* self)
{
@@ -297,13 +545,13 @@ PyMethodDef CListValue::Methods[] = {
{"reverse", (PyCFunction)CListValue::sPyreverse,METH_NOARGS},
{"index", (PyCFunction)CListValue::sPyindex,METH_O},
{"count", (PyCFunction)CListValue::sPycount,METH_O},
-
+
/* Dict style access */
{"get", (PyCFunction)CListValue::sPyget,METH_VARARGS},
-
+
/* Own cvalue funcs */
{"from_id", (PyCFunction)CListValue::sPyfrom_id,METH_O},
-
+
{NULL,NULL} //Sentinel
};
@@ -311,213 +559,29 @@ PyAttributeDef CListValue::Attributes[] = {
{ NULL } //Sentinel
};
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CListValue::CListValue()
-: CPropValue()
-{
- m_bReleaseContents=true;
-}
-
-
-
-CListValue::~CListValue()
-{
-
- if (m_bReleaseContents) {
- for (unsigned int i=0;i<m_pValueArray.size();i++) {
- m_pValueArray[i]->Release();
- }
- }
-}
-
-
-static STR_String gstrListRep=STR_String("List");
-
-const STR_String & CListValue::GetText()
-{
- gstrListRep = "[";
- STR_String commastr = "";
-
- for (int i=0;i<GetCount();i++)
- {
- gstrListRep += commastr;
- gstrListRep += GetValue(i)->GetText();
- commastr = ",";
- }
- gstrListRep += "]";
-
- return gstrListRep;
-}
-
-
-
-CValue* CListValue::GetReplica() {
- CListValue* replica = new CListValue(*this);
-
- replica->ProcessReplica();
-
- replica->m_bReleaseContents=true; // for copy, complete array is copied for now...
- // copy all values
- int numelements = m_pValueArray.size();
- unsigned int i=0;
- replica->m_pValueArray.resize(numelements);
- for (i=0;i<m_pValueArray.size();i++)
- replica->m_pValueArray[i] = m_pValueArray[i]->GetReplica();
-
-
- return replica;
-};
-
-
-
-void CListValue::SetValue(int i, CValue *val)
-{
- assertd(i < m_pValueArray.size());
- m_pValueArray[i]=val;
-}
-
-
-
-void CListValue::Resize(int num)
-{
- m_pValueArray.resize(num);
-}
-
-
-
-void CListValue::Remove(int i)
-{
- assertd(i<m_pValueArray.size());
- m_pValueArray.erase(m_pValueArray.begin()+i);
-}
-
-
-
-void CListValue::ReleaseAndRemoveAll()
-{
- for (unsigned int i=0;i<m_pValueArray.size();i++)
- m_pValueArray[i]->Release();
- m_pValueArray.clear();//.Clear();
-}
-
-
-
-CValue* CListValue::FindValue(const STR_String & name)
-{
- for (int i=0; i < GetCount(); i++)
- if (GetValue(i)->GetName() == name)
- return GetValue(i);
-
- return NULL;
-}
-
-CValue* CListValue::FindValue(const char * name)
-{
- for (int i=0; i < GetCount(); i++)
- if (GetValue(i)->GetName() == name)
- return GetValue(i);
-
- return NULL;
-}
-
-bool CListValue::SearchValue(CValue *val)
-{
- for (int i=0;i<GetCount();i++)
- if (val == GetValue(i))
- return true;
- return false;
-}
-
-
-
-void CListValue::SetReleaseOnDestruct(bool bReleaseContents)
-{
- m_bReleaseContents = bReleaseContents;
-}
-
-
-
-bool CListValue::RemoveValue(CValue *val)
-{
- bool result=false;
-
- for (int i=GetCount()-1;i>=0;i--)
- if (val == GetValue(i))
- {
- Remove(i);
- result=true;
- }
- return result;
-}
-
-
-
-void CListValue::MergeList(CListValue *otherlist)
-{
-
- int numelements = this->GetCount();
- int numotherelements = otherlist->GetCount();
-
-
- Resize(numelements+numotherelements);
-
- for (int i=0;i<numotherelements;i++)
- {
- SetValue(i+numelements,otherlist->GetValue(i)->AddRef());
- }
-}
-
-
PyObject* CListValue::Pyappend(PyObject* value)
{
CValue* objval = ConvertPythonToValue(value, "CList.append(i): CValueList, ");
if (!objval) /* ConvertPythonToValue sets the error */
return NULL;
-
+
if (!BGE_PROXY_PYOWNS(m_proxy)) {
PyErr_SetString(PyExc_TypeError, "CList.append(i): this CValueList is used internally for the game engine and can't be modified");
return NULL;
}
-
+
Add(objval);
-
+
Py_RETURN_NONE;
}
-
-
PyObject* CListValue::Pyreverse()
{
std::reverse(m_pValueArray.begin(),m_pValueArray.end());
Py_RETURN_NONE;
}
-
-
-bool CListValue::CheckEqual(CValue* first,CValue* second)
-{
- bool result = false;
-
- CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second);
-
- if (eqval==NULL)
- return false;
- const STR_String& text = eqval->GetText();
- if (&text==&CBoolValue::sTrueString)
- {
- result = true;
- }
- eqval->Release();
- return result;
-
-}
-
-
-
PyObject* CListValue::Pyindex(PyObject *value)
{
PyObject* result = NULL;
@@ -542,7 +606,7 @@ PyObject* CListValue::Pyindex(PyObject *value)
PyErr_SetString(PyExc_ValueError, "CList.index(x): x not in CListValue");
}
return result;
-
+
}
@@ -552,7 +616,7 @@ PyObject* CListValue::Pycount(PyObject* value)
int numfound = 0;
CValue* checkobj = ConvertPythonToValue(value, ""); /* error ignored */
-
+
if (checkobj==NULL) { /* in this case just return that there are no items in the list */
PyErr_Clear();
return PyLong_FromSsize_t(0);
@@ -580,9 +644,9 @@ PyObject* CListValue::Pyget(PyObject *args)
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
return NULL;
-
+
CValue *item = FindValue((const char *)key);
- if (item) {
+ if (item) {
PyObject* pyobj = item->ConvertValueToPython();
if (pyobj)
return pyobj;
@@ -597,7 +661,7 @@ PyObject* CListValue::Pyget(PyObject *args)
PyObject* CListValue::Pyfrom_id(PyObject* value)
{
uintptr_t id= (uintptr_t)PyLong_AsVoidPtr(value);
-
+
if (PyErr_Occurred())
return NULL;
@@ -608,72 +672,8 @@ PyObject* CListValue::Pyfrom_id(PyObject* value)
return GetValue(i)->GetProxy();
}
PyErr_SetString(PyExc_IndexError, "from_id(#): id not found in CValueList");
- return NULL;
-
-}
-
-
-/* ---------------------------------------------------------------------
- * Some stuff taken from the header
- * --------------------------------------------------------------------- */
-CValue* CListValue::Calc(VALUE_OPERATOR op,CValue *val)
-{
- //assert(false); // todo: implement me!
- static int error_printed = 0;
- if (error_printed==0) {
- fprintf(stderr, "CValueList::Calc not yet implimented\n");
- error_printed = 1;
- }
return NULL;
-}
-
-CValue* CListValue::CalcFinal(VALUE_DATA_TYPE dtype,
- VALUE_OPERATOR op,
- CValue* val)
-{
- //assert(false); // todo: implement me!
- static int error_printed = 0;
- if (error_printed==0) {
- fprintf(stderr, "CValueList::CalcFinal not yet implimented\n");
- error_printed = 1;
- }
- return NULL;
-}
-
-
-
-void CListValue::Add(CValue* value)
-{
- m_pValueArray.push_back(value);
-}
-
-
-double CListValue::GetNumber()
-{
- return -1;
}
-
-
-void CListValue::SetModified(bool bModified)
-{
- CValue::SetModified(bModified);
- int numels = GetCount();
-
- for (int i=0;i<numels;i++)
- GetValue(i)->SetModified(bModified);
-}
-
-
-
-bool CListValue::IsModified()
-{
- bool bmod = CValue::IsModified(); //normal own flag
- int numels = GetCount();
-
- for (int i=0;i<numels;i++)
- bmod = bmod || GetValue(i)->IsModified();
-
- return bmod;
-}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h
index 2dc458e0148..8f3b9dcda0b 100644
--- a/source/gameengine/Expressions/ListValue.h
+++ b/source/gameengine/Expressions/ListValue.h
@@ -60,6 +60,7 @@ public:
bool CheckEqual(CValue* first,CValue* second);
+#ifndef DISABLE_PYTHON
virtual PyObject* py_repr(void) {
PyObject *py_proxy= this->GetProxy();
PyObject *py_list= PySequence_List(py_proxy);
@@ -75,7 +76,7 @@ public:
KX_PYMETHOD_O(CListValue,count);
KX_PYMETHOD_VARARGS(CListValue,get);
KX_PYMETHOD_O(CListValue,from_id);
-
+#endif
private:
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 1d1d9e6103b..54a33b76efd 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -30,8 +30,6 @@
#include <config.h>
#endif
-#ifndef NO_EXP_PYTHON_EMBEDDING
-
/*------------------------------
* PyObjectPlus cpp
*
@@ -51,6 +49,57 @@
#include "PyObjectPlus.h"
#include "STR_String.h"
#include "MT_Vector3.h"
+#include "MEM_guardedalloc.h"
+
+PyObjectPlus::~PyObjectPlus()
+{
+#ifndef DISABLE_PYTHON
+ if(m_proxy) {
+ BGE_PROXY_REF(m_proxy)= NULL;
+ Py_DECREF(m_proxy); /* Remove own reference, python may still have 1 */
+ }
+// assert(ob_refcnt==0);
+#endif
+}
+
+PyObjectPlus::PyObjectPlus() : SG_QList() // constructor
+{
+#ifndef DISABLE_PYTHON
+ m_proxy= NULL;
+#endif
+};
+
+void PyObjectPlus::ProcessReplica()
+{
+#ifndef DISABLE_PYTHON
+ /* Clear the proxy, will be created again if needed with GetProxy()
+ * otherwise the PyObject will point to the wrong reference */
+ m_proxy= NULL;
+#endif
+}
+
+/* Sometimes we might want to manually invalidate a BGE type even if
+ * it hasnt been released by the BGE, say for example when an object
+ * is removed from a scene, accessing it may cause problems.
+ *
+ * In this case the current proxy is made invalid, disowned,
+ * and will raise an error on access. However if python can get access
+ * to this class again it will make a new proxy and work as expected.
+ */
+void PyObjectPlus::InvalidateProxy() // check typename of each parent
+{
+#ifndef DISABLE_PYTHON
+ if(m_proxy) {
+ BGE_PROXY_REF(m_proxy)=NULL;
+ Py_DECREF(m_proxy);
+ m_proxy= NULL;
+ }
+#endif
+}
+
+
+#ifndef DISABLE_PYTHON
+
/*------------------------------
* PyObjectPlus Type -- Every class, even the abstract one should have a Type
------------------------------*/
@@ -77,17 +126,6 @@ PyTypeObject PyObjectPlus::Type = {
NULL // no subtype
};
-
-PyObjectPlus::~PyObjectPlus()
-{
- if(m_proxy) {
- BGE_PROXY_REF(m_proxy)= NULL;
- Py_DECREF(m_proxy); /* Remove own reference, python may still have 1 */
- }
-// assert(ob_refcnt==0);
-}
-
-
PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the entry in Type.
{
PyObjectPlus *self_plus= BGE_PROXY_REF(self);
@@ -95,7 +133,6 @@ PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the ent
PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
return NULL;
}
-
return self_plus->py_repr();
}
@@ -145,42 +182,55 @@ PyObject * PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObjec
PyObjectPlus_Proxy *ret = (PyObjectPlus_Proxy *) type->tp_alloc(type, 0); /* starts with 1 ref, used for the return ref' */
ret->ref= base->ref;
- base->ref= NULL; /* invalidate! disallow further access */
-
+ ret->ptr= base->ptr;
ret->py_owns= base->py_owns;
+ ret->py_ref = base->py_ref;
- ret->ref->m_proxy= NULL;
-
- /* 'base' may be free'd after this func finished but not necessarily
- * there is no reference to the BGE data now so it will throw an error on access */
- Py_DECREF(base);
-
- ret->ref->m_proxy= (PyObject *)ret; /* no need to add a ref because one is added when creating. */
- Py_INCREF(ret); /* we return a new ref but m_proxy holds a ref so we need to add one */
-
-
- /* 'ret' will have 2 references.
- * - One ref is needed because ret->ref->m_proxy holds a refcount to the current proxy.
- * - Another is needed for returning the value.
- *
- * So we should be ok with 2 refs, but for some reason this crashes. so adding a new ref...
- * */
+ if (ret->py_ref) {
+ base->ref= NULL; /* invalidate! disallow further access */
+ base->ptr = NULL;
+ if (ret->ref)
+ ret->ref->m_proxy= NULL;
+ /* 'base' may be free'd after this func finished but not necessarily
+ * there is no reference to the BGE data now so it will throw an error on access */
+ Py_DECREF(base);
+ if (ret->ref) {
+ ret->ref->m_proxy= (PyObject *)ret; /* no need to add a ref because one is added when creating. */
+ Py_INCREF(ret); /* we return a new ref but m_proxy holds a ref so we need to add one */
+ }
+ } else {
+ // generic structures don't hold a reference to this proxy, so don't increment ref count
+ if (ret->py_owns)
+ // but if the proxy owns the structure, there can be only one owner
+ base->ptr= NULL;
+ }
return (PyObject *)ret;
}
void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper
{
- PyObjectPlus *self_plus= BGE_PROXY_REF(self);
- if(self_plus) {
- if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */
- self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */
- delete self_plus;
+ if (BGE_PROXY_PYREF(self)) {
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self);
+ if(self_plus) {
+ if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */
+ self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */
+ delete self_plus;
+ }
+ BGE_PROXY_REF(self)= NULL; // not really needed
+ }
+ // the generic pointer is not deleted directly, only through self_plus
+ BGE_PROXY_PTR(self)= NULL; // not really needed
+ } else {
+ void *ptr= BGE_PROXY_PTR(self);
+ if(ptr) {
+ if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */
+ // generic structure owned by python MUST be created though MEM_alloc
+ MEM_freeN(ptr);
+ }
+ BGE_PROXY_PTR(self)= NULL; // not really needed
}
-
- BGE_PROXY_REF(self)= NULL; // not really needed
}
-
#if 0
/* is ok normally but not for subtyping, use tp_free instead. */
PyObject_DEL( self );
@@ -189,11 +239,6 @@ void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper
#endif
};
-PyObjectPlus::PyObjectPlus() : SG_QList() // constructor
-{
- m_proxy= NULL;
-};
-
/*------------------------------
* PyObjectPlus Methods -- Every class, even the abstract one should have a Methods
------------------------------*/
@@ -217,8 +262,9 @@ PyObject* PyObjectPlus::pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DE
/* note, this is called as a python 'getset, where the PyAttributeDef is the closure */
PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef)
{
- void *self= (void *)(BGE_PROXY_REF(self_py));
- if(self==NULL) {
+ PyObjectPlus *ref= (BGE_PROXY_REF(self_py));
+ char* ptr = (attrdef->m_usePtr) ? (char*)BGE_PROXY_PTR(self_py) : (char*)ref;
+ if(ptr == NULL || (BGE_PROXY_PYREF(self_py) && (ref==NULL || !ref->py_is_valid()))) {
if(attrdef == attr_invalid)
Py_RETURN_TRUE; // dont bother running the function
@@ -226,7 +272,6 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
return NULL;
}
-
if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
{
// fake attribute, ignore
@@ -237,9 +282,9 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
// the attribute has no field correspondance, handover processing to function.
if (attrdef->m_getFunction == NULL)
return NULL;
- return (*attrdef->m_getFunction)(self, attrdef);
+ return (*attrdef->m_getFunction)(ref, attrdef);
}
- char *ptr = reinterpret_cast<char*>(self)+attrdef->m_offset;
+ ptr += attrdef->m_offset;
if (attrdef->m_length > 1)
{
PyObject* resultlist = PyList_New(attrdef->m_length);
@@ -293,6 +338,35 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
else
{
switch (attrdef->m_type) {
+ case KX_PYATTRIBUTE_TYPE_FLAG:
+ {
+ bool bval;
+ switch (attrdef->m_size) {
+ case 1:
+ {
+ unsigned char *val = reinterpret_cast<unsigned char*>(ptr);
+ bval = (*val & attrdef->m_imin);
+ break;
+ }
+ case 2:
+ {
+ unsigned short *val = reinterpret_cast<unsigned short*>(ptr);
+ bval = (*val & attrdef->m_imin);
+ break;
+ }
+ case 4:
+ {
+ unsigned int *val = reinterpret_cast<unsigned int*>(ptr);
+ bval = (*val & attrdef->m_imin);
+ break;
+ }
+ default:
+ return NULL;
+ }
+ if (attrdef->m_imax)
+ bval = !bval;
+ return PyLong_FromSsize_t(bval);
+ }
case KX_PYATTRIBUTE_TYPE_BOOL:
{
bool *val = reinterpret_cast<bool*>(ptr);
@@ -318,7 +392,49 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
case KX_PYATTRIBUTE_TYPE_FLOAT:
{
float *val = reinterpret_cast<float*>(ptr);
- return PyFloat_FromDouble(*val);
+ if (attrdef->m_imin == 0) {
+ if (attrdef->m_imax == 0) {
+ return PyFloat_FromDouble(*val);
+ } else {
+ // vector, verify size
+ if (attrdef->m_size != attrdef->m_imax*sizeof(float))
+ {
+ return NULL;
+ }
+#ifdef USE_MATHUTILS
+ return newVectorObject(val, attrdef->m_imax, Py_NEW, NULL);
+#else
+ 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]));
+ }
+ return resultlist;
+#endif
+ }
+ } else {
+ // matrix case
+ if (attrdef->m_size != attrdef->m_imax*attrdef->m_imin*sizeof(float))
+ {
+ return NULL;
+ }
+#ifdef USE_MATHUTILS
+ return newMatrixObject(val, attrdef->m_imin, attrdef->m_imax, Py_WRAP, NULL);
+#else
+ PyObject* rowlist = PyList_New(attrdef->m_imin);
+ for (unsigned int i=0; i<attrdef->m_imin; i++)
+ {
+ PyObject* collist = PyList_New(attrdef->m_imax);
+ for (unsigned int j=0; j<attrdef->m_imax; j++)
+ {
+ PyList_SET_ITEM(collist,j,PyFloat_FromDouble(val[j]));
+ }
+ PyList_SET_ITEM(rowlist,i,collist);
+ val += attrdef->m_imax;
+ }
+ return rowlist;
+#endif
+ }
}
case KX_PYATTRIBUTE_TYPE_VECTOR:
{
@@ -340,17 +456,47 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
STR_String *val = reinterpret_cast<STR_String*>(ptr);
return PyUnicode_FromString(*val);
}
+ case KX_PYATTRIBUTE_TYPE_CHAR:
+ {
+ return PyUnicode_FromString(ptr);
+ }
default:
return NULL;
}
}
}
+
+static bool py_check_attr_float(float *var, PyObject *value, const PyAttributeDef *attrdef)
+{
+ double val = PyFloat_AsDouble(value);
+ if (val == -1.0 && PyErr_Occurred())
+ {
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return false;
+ }
+ if (attrdef->m_clamp)
+ {
+ if (val < attrdef->m_fmin)
+ val = attrdef->m_fmin;
+ else if (val > attrdef->m_fmax)
+ val = attrdef->m_fmax;
+ }
+ else if (val < attrdef->m_fmin || val > attrdef->m_fmax)
+ {
+ PyErr_Format(PyExc_ValueError, "value out of range for attribute \"%s\"", attrdef->m_name);
+ return false;
+ }
+ *var = (float)val;
+ return true;
+}
+
/* note, this is called as a python getset */
int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef)
{
- void *self= (void *)(BGE_PROXY_REF(self_py));
- if(self==NULL) {
+ PyObjectPlus *ref= (BGE_PROXY_REF(self_py));
+ char* ptr = (attrdef->m_usePtr) ? (char*)BGE_PROXY_PTR(self_py) : (char*)ref;
+ if(ref==NULL || !ref->py_is_valid() || ptr==NULL) {
PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
return PY_SET_ATTR_FAIL;
}
@@ -358,8 +504,10 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
void *undoBuffer = NULL;
void *sourceBuffer = NULL;
size_t bufferSize = 0;
+ PyObject *item = NULL; // to store object that must be dereferenced in case of error
+ PyObject *list = NULL; // to store object that must be dereferenced in case of error
- char *ptr = reinterpret_cast<char*>(self)+attrdef->m_offset;
+ ptr += attrdef->m_offset;
if (attrdef->m_length > 1)
{
if (!PySequence_Check(value))
@@ -380,7 +528,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
PyErr_Format(PyExc_AttributeError, "function attribute without function for attribute \"%s\", report to blender.org", attrdef->m_name);
return PY_SET_ATTR_FAIL;
}
- return (*attrdef->m_setFunction)(self, attrdef, value);
+ return (*attrdef->m_setFunction)(ref, attrdef, value);
case KX_PYATTRIBUTE_TYPE_BOOL:
bufferSize = sizeof(bool);
break;
@@ -409,10 +557,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
}
for (int i=0; i<attrdef->m_length; i++)
{
- PyObject *item = PySequence_GetItem(value, i); /* new ref */
- // we can decrement the reference immediately, the reference count
- // is at least 1 because the item is part of an array
- Py_DECREF(item);
+ item = PySequence_GetItem(value, i); /* new ref */
switch (attrdef->m_type)
{
case KX_PYATTRIBUTE_TYPE_BOOL:
@@ -528,11 +673,14 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
PyErr_Format(PyExc_AttributeError, "type check error for attribute \"%s\", report to blender.org", attrdef->m_name);
goto UNDO_AND_ERROR;
}
+ // finished using item, release
+ Py_DECREF(item);
+ item = NULL;
}
// no error, call check function if any
if (attrdef->m_checkFunction != NULL)
{
- if ((*attrdef->m_checkFunction)(self, attrdef) != 0)
+ if ((*attrdef->m_checkFunction)(ref, attrdef) != 0)
{
// if the checing function didnt set an error then set a generic one here so we dont set an error with no exception
if (PyErr_Occurred()==0)
@@ -545,6 +693,8 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
memcpy(sourceBuffer, undoBuffer, bufferSize);
free(undoBuffer);
}
+ if (item)
+ Py_DECREF(item);
return PY_SET_ATTR_FAIL;
}
}
@@ -561,7 +711,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
PyErr_Format(PyExc_AttributeError, "function attribute without function \"%s\", report to blender.org", attrdef->m_name);
return PY_SET_ATTR_FAIL;
}
- return (*attrdef->m_setFunction)(self, attrdef, value);
+ return (*attrdef->m_setFunction)(ref, attrdef, value);
}
if (attrdef->m_checkFunction != NULL || attrdef->m_type == KX_PYATTRIBUTE_TYPE_VECTOR)
{
@@ -576,11 +726,19 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
bufferSize = sizeof(short);
break;
case KX_PYATTRIBUTE_TYPE_ENUM:
+ case KX_PYATTRIBUTE_TYPE_FLAG:
+ case KX_PYATTRIBUTE_TYPE_CHAR:
+ bufferSize = attrdef->m_size;
+ break;
case KX_PYATTRIBUTE_TYPE_INT:
bufferSize = sizeof(int);
break;
case KX_PYATTRIBUTE_TYPE_FLOAT:
bufferSize = sizeof(float);
+ if (attrdef->m_imax)
+ bufferSize *= attrdef->m_imax;
+ if (attrdef->m_imin)
+ bufferSize *= attrdef->m_imin;
break;
case KX_PYATTRIBUTE_TYPE_STRING:
sourceBuffer = reinterpret_cast<STR_String*>(ptr)->Ptr();
@@ -624,6 +782,49 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
}
break;
}
+ case KX_PYATTRIBUTE_TYPE_FLAG:
+ {
+ bool bval;
+ if (PyLong_Check(value))
+ {
+ bval = (PyLong_AsSsize_t(value) != 0);
+ }
+ else if (PyBool_Check(value))
+ {
+ bval = (value == Py_True);
+ }
+ else
+ {
+ PyErr_Format(PyExc_TypeError, "expected an integer or a bool for attribute \"%s\"", attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ if (attrdef->m_imax)
+ bval = !bval;
+ switch (attrdef->m_size) {
+ case 1:
+ {
+ unsigned char *val = reinterpret_cast<unsigned char*>(ptr);
+ *val = (*val & ~attrdef->m_imin) | ((bval)?attrdef->m_imin:0);
+ break;
+ }
+ case 2:
+ {
+ unsigned short *val = reinterpret_cast<unsigned short*>(ptr);
+ *val = (*val & ~attrdef->m_imin) | ((bval)?attrdef->m_imin:0);
+ break;
+ }
+ case 4:
+ {
+ unsigned int *val = reinterpret_cast<unsigned int*>(ptr);
+ *val = (*val & ~attrdef->m_imin) | ((bval)?attrdef->m_imin:0);
+ break;
+ }
+ default:
+ PyErr_Format(PyExc_TypeError, "internal error: unsupported flag field \"%s\"", attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ break;
+ }
case KX_PYATTRIBUTE_TYPE_SHORT:
{
short int *var = reinterpret_cast<short int*>(ptr);
@@ -689,25 +890,71 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
case KX_PYATTRIBUTE_TYPE_FLOAT:
{
float *var = reinterpret_cast<float*>(ptr);
- double val = PyFloat_AsDouble(value);
- if (val == -1.0 && PyErr_Occurred())
+ if (attrdef->m_imin != 0)
{
- PyErr_Format(PyExc_TypeError, "expected a float for attribute \"%s\"", attrdef->m_name);
- goto FREE_AND_ERROR;
- }
- else if (attrdef->m_clamp)
+ if (attrdef->m_size != attrdef->m_imin*attrdef->m_imax*sizeof(float))
+ {
+ PyErr_Format(PyExc_TypeError, "internal error: incorrect field size for attribute \"%s\"", attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ if (!PySequence_Check(value) || PySequence_Size(value) != attrdef->m_imin)
+ {
+ PyErr_Format(PyExc_TypeError, "expected a sequence of [%d][%d] floats for attribute \"%s\"", attrdef->m_imin, attrdef->m_imax, attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ for (int i=0; i<attrdef->m_imin; i++)
+ {
+ PyObject *list = PySequence_GetItem(value, i); /* new ref */
+ if (!PySequence_Check(list) || PySequence_Size(list) != attrdef->m_imax)
+ {
+ PyErr_Format(PyExc_TypeError, "expected a sequence of [%d][%d] floats for attribute \"%s\"", attrdef->m_imin, attrdef->m_imax, attrdef->m_name);
+ goto RESTORE_AND_ERROR;
+ }
+ for (int j=0; j<attrdef->m_imax; j++)
+ {
+ item = PySequence_GetItem(list, j); /* new ref */
+ if (!py_check_attr_float(var, item, attrdef))
+ {
+ PyErr_Format(PyExc_TypeError, "expected a sequence of [%d][%d] floats for attribute \"%s\"", attrdef->m_imin, attrdef->m_imax, attrdef->m_name);
+ goto RESTORE_AND_ERROR;
+ }
+ Py_DECREF(item);
+ item = NULL;
+ ++var;
+ }
+ Py_DECREF(list);
+ list = NULL;
+ }
+ }
+ else if (attrdef->m_imax != 0)
{
- if (val < attrdef->m_fmin)
- val = attrdef->m_fmin;
- else if (val > attrdef->m_fmax)
- val = attrdef->m_fmax;
- }
- else if (val < attrdef->m_fmin || val > attrdef->m_fmax)
+ if (attrdef->m_size != attrdef->m_imax*sizeof(float))
+ {
+ PyErr_Format(PyExc_TypeError, "internal error: incorrect field size for attribute \"%s\"", attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ if (!PySequence_Check(value) || PySequence_Size(value) != attrdef->m_imax)
+ {
+ PyErr_Format(PyExc_TypeError, "expected a sequence of [%d] floats for attribute \"%s\"", attrdef->m_imax, attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ for (int i=0; i<attrdef->m_imax; i++)
+ {
+ item = PySequence_GetItem(value, i); /* new ref */
+ if (!py_check_attr_float(var, item, attrdef))
+ {
+ goto RESTORE_AND_ERROR;
+ }
+ Py_DECREF(item);
+ item = NULL;
+ ++var;
+ }
+ }
+ else
{
- PyErr_Format(PyExc_ValueError, "value out of range for attribute \"%s\"", attrdef->m_name);
- goto FREE_AND_ERROR;
+ if (!py_check_attr_float(var, value, attrdef))
+ goto FREE_AND_ERROR;
}
- *var = (float)val;
break;
}
case KX_PYATTRIBUTE_TYPE_VECTOR:
@@ -715,16 +962,15 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
if (!PySequence_Check(value) || PySequence_Size(value) != 3)
{
PyErr_Format(PyExc_TypeError, "expected a sequence of 3 floats for attribute \"%s\"", attrdef->m_name);
- return PY_SET_ATTR_FAIL;
+ goto FREE_AND_ERROR;
}
MT_Vector3 *var = reinterpret_cast<MT_Vector3*>(ptr);
for (int i=0; i<3; i++)
{
- PyObject *item = PySequence_GetItem(value, i); /* new ref */
- // we can decrement the reference immediately, the reference count
- // is at least 1 because the item is part of an array
- Py_DECREF(item);
+ item = PySequence_GetItem(value, i); /* new ref */
double val = PyFloat_AsDouble(item);
+ Py_DECREF(item);
+ item = NULL;
if (val == -1.0 && PyErr_Occurred())
{
PyErr_Format(PyExc_TypeError, "expected a sequence of 3 floats for attribute \"%s\"", attrdef->m_name);
@@ -746,6 +992,22 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
}
break;
}
+ case KX_PYATTRIBUTE_TYPE_CHAR:
+ {
+ if (PyUnicode_Check(value))
+ {
+ Py_ssize_t val_len;
+ char *val = _PyUnicode_AsStringAndSize(value, &val_len);
+ strncpy(ptr, val, attrdef->m_size);
+ ptr[attrdef->m_size-1] = 0;
+ }
+ else
+ {
+ PyErr_Format(PyExc_TypeError, "expected a string for attribute \"%s\"", attrdef->m_name);
+ goto FREE_AND_ERROR;
+ }
+ break;
+ }
case KX_PYATTRIBUTE_TYPE_STRING:
{
STR_String *var = reinterpret_cast<STR_String*>(ptr);
@@ -793,7 +1055,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
// check if post processing is needed
if (attrdef->m_checkFunction != NULL)
{
- if ((*attrdef->m_checkFunction)(self, attrdef) != 0)
+ if ((*attrdef->m_checkFunction)(ref, attrdef) != 0)
{
// restore value
RESTORE_AND_ERROR:
@@ -814,6 +1076,10 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
FREE_AND_ERROR:
if (undoBuffer)
free(undoBuffer);
+ if (list)
+ Py_DECREF(list);
+ if (item)
+ Py_DECREF(item);
return 1;
}
}
@@ -833,47 +1099,35 @@ PyObject *PyObjectPlus::py_repr(void)
return NULL;
}
-void PyObjectPlus::ProcessReplica()
-{
- /* Clear the proxy, will be created again if needed with GetProxy()
- * otherwise the PyObject will point to the wrong reference */
- m_proxy= NULL;
-}
-
-/* Sometimes we might want to manually invalidate a BGE type even if
- * it hasnt been released by the BGE, say for example when an object
- * is removed from a scene, accessing it may cause problems.
- *
- * In this case the current proxy is made invalid, disowned,
- * and will raise an error on access. However if python can get access
- * to this class again it will make a new proxy and work as expected.
- */
-void PyObjectPlus::InvalidateProxy() // check typename of each parent
-{
- if(m_proxy) {
- BGE_PROXY_REF(m_proxy)=NULL;
- Py_DECREF(m_proxy);
- m_proxy= NULL;
- }
-}
-
-PyObject *PyObjectPlus::GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp)
+PyObject *PyObjectPlus::GetProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr)
{
if (self->m_proxy==NULL)
{
self->m_proxy = reinterpret_cast<PyObject *>PyObject_NEW( PyObjectPlus_Proxy, tp);
BGE_PROXY_PYOWNS(self->m_proxy) = false;
+ BGE_PROXY_PYREF(self->m_proxy) = true;
}
//PyObject_Print(self->m_proxy, stdout, 0);
//printf("ref %d\n", self->m_proxy->ob_refcnt);
BGE_PROXY_REF(self->m_proxy) = self; /* Its possible this was set to NULL, so set it back here */
+ BGE_PROXY_PTR(self->m_proxy) = ptr;
Py_INCREF(self->m_proxy); /* we own one, thos ones fore the return */
return self->m_proxy;
}
-PyObject *PyObjectPlus::NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns)
+PyObject *PyObjectPlus::NewProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr, bool py_owns)
{
+ if (!self)
+ {
+ // in case of proxy without reference to game object
+ PyObject* proxy = reinterpret_cast<PyObject *>PyObject_NEW( PyObjectPlus_Proxy, tp);
+ BGE_PROXY_PYREF(proxy) = false;
+ BGE_PROXY_PYOWNS(proxy) = py_owns;
+ BGE_PROXY_REF(proxy) = NULL;
+ BGE_PROXY_PTR(proxy) = ptr;
+ return proxy;
+ }
if (self->m_proxy)
{
if(py_owns)
@@ -889,7 +1143,7 @@ PyObject *PyObjectPlus::NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool
}
- GetProxy_Ext(self, tp);
+ GetProxyPlus_Ext(self, tp, ptr);
if(py_owns) {
BGE_PROXY_PYOWNS(self->m_proxy) = py_owns;
Py_DECREF(self->m_proxy); /* could avoid thrashing here but for now its ok */
@@ -974,5 +1228,4 @@ void PyObjectPlus::SetDeprecationWarningFirst(WarnLink* wlink) {m_base_wlink_f
void PyObjectPlus::SetDeprecationWarningLinkLast(WarnLink* wlink) {m_base_wlink_last= wlink;}
void PyObjectPlus::NullDeprecationWarning() {m_base_wlink_first= m_base_wlink_last= NULL;}
-#endif //NO_EXP_PYTHON_EMBEDDING
-
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index f9edb7877b0..971f9296912 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -27,8 +27,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef NO_EXP_PYTHON_EMBEDDING
-
#ifndef _adr_py_lib_h_ // only process once,
#define _adr_py_lib_h_ // even if multiply included
@@ -45,6 +43,7 @@
* Python defines
------------------------------*/
+#ifndef DISABLE_PYTHON
#ifdef USE_MATHUTILS
extern "C" {
#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */
@@ -88,13 +87,17 @@ typedef struct {
typedef struct PyObjectPlus_Proxy {
PyObject_HEAD /* required python macro */
- class PyObjectPlus *ref;
- bool py_owns;
+ class PyObjectPlus *ref; // pointer to GE object, it holds a reference to this proxy
+ void *ptr; // optional pointer to generic structure, the structure holds no reference to this proxy
+ bool py_owns; // true if the object pointed by ref should be deleted when the proxy is deleted
+ bool py_ref; // true if proxy is connected to a GE object (ref is used)
} PyObjectPlus_Proxy;
#define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
#define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
+#define BGE_PROXY_PTR(_self) (((PyObjectPlus_Proxy *)_self)->ptr)
#define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
+#define BGE_PROXY_PYREF(_self) (((PyObjectPlus_Proxy *)_self)->py_ref)
/* Note, sometimes we dont care what BGE type this is as long as its a proxy */
#define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc)
@@ -103,18 +106,33 @@ typedef struct PyObjectPlus_Proxy {
#define BGE_PROXY_FROM_REF(_self) (((PyObjectPlus *)_self)->GetProxy())
- // This must be the first line of each
- // PyC++ class
+// This must be the first line of each
+// PyC++ class
+// AttributesPtr correspond to attributes of proxy generic pointer
+// each PyC++ class must be registered in KX_PythonInitTypes.cpp
#define __Py_Header \
public: \
static PyTypeObject Type; \
static PyMethodDef Methods[]; \
static PyAttributeDef Attributes[]; \
virtual PyTypeObject *GetType(void) {return &Type;}; \
- virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \
- virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \
+ virtual PyObject *GetProxy() {return GetProxyPlus_Ext(this, &Type, NULL);}; \
+ virtual PyObject *NewProxy(bool py_owns) {return NewProxyPlus_Ext(this, &Type, NULL, py_owns);}; \
+// leave above line empty (macro)!
+// use this macro for class that use generic pointer in proxy
+// GetProxy() and NewProxy() must be defined to set the correct pointer in the proxy
+#define __Py_HeaderPtr \
+ public: \
+ static PyTypeObject Type; \
+ static PyMethodDef Methods[]; \
+ static PyAttributeDef Attributes[]; \
+ static PyAttributeDef AttributesPtr[]; \
+ virtual PyTypeObject *GetType(void) {return &Type;}; \
+ virtual PyObject *GetProxy(); \
+ virtual PyObject *NewProxy(bool py_owns); \
+// leave above line empty (macro)!
#ifdef WITH_CXX_GUARDEDALLOC
#define Py_Header __Py_Header \
void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \
@@ -124,6 +142,15 @@ typedef struct PyObjectPlus_Proxy {
#define Py_Header __Py_Header
#endif
+#ifdef WITH_CXX_GUARDEDALLOC
+#define Py_HeaderPtr __Py_HeaderPtr \
+ void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \
+ void operator delete( void *mem ) { MEM_freeN(mem); } \
+
+#else
+#define Py_HeaderPtr __Py_HeaderPtr
+#endif
+
/*
* nonzero values are an error for setattr
* however because of the nested lookups we need to know if the errors
@@ -245,6 +272,8 @@ enum KX_PYATTRIBUTE_TYPE {
KX_PYATTRIBUTE_TYPE_DUMMY,
KX_PYATTRIBUTE_TYPE_FUNCTION,
KX_PYATTRIBUTE_TYPE_VECTOR,
+ KX_PYATTRIBUTE_TYPE_FLAG,
+ KX_PYATTRIBUTE_TYPE_CHAR,
};
enum KX_PYATTRIBUTE_ACCESS {
@@ -261,11 +290,14 @@ typedef struct KX_PYATTRIBUTE_DEF {
const char *m_name; // name of the python attribute
KX_PYATTRIBUTE_TYPE m_type; // type of value
KX_PYATTRIBUTE_ACCESS m_access; // read/write access or read-only
- int m_imin; // minimum value in case of integer attributes (for string: minimum string length)
- int m_imax; // maximum value in case of integer attributes (for string: maximum string length)
+ int m_imin; // minimum value in case of integer attributes
+ // (for string: minimum string length, for flag: mask value, for float: matrix row size)
+ int m_imax; // maximum value in case of integer attributes
+ // (for string: maximum string length, for flag: 1 if flag is negative, float: vector/matrix col size)
float m_fmin; // minimum value in case of float attributes
float m_fmax; // maximum value in case of float attributes
bool m_clamp; // enforce min/max value by clamping
+ bool m_usePtr; // the attribute uses the proxy generic pointer, set at runtime
size_t m_offset; // position of field in structure
size_t m_size; // size of field for runtime verification (enum only)
size_t m_length; // length of array, 1=simple attribute
@@ -283,104 +315,146 @@ typedef struct KX_PYATTRIBUTE_DEF {
float *m_floatPtr;
STR_String *m_stringPtr;
MT_Vector3 *m_vectorPtr;
+ char *m_charPtr;
} m_typeCheck;
} PyAttributeDef;
#define KX_PYATTRIBUTE_DUMMY(name) \
- { name, KX_PYATTRIBUTE_TYPE_DUMMY, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_DUMMY, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, NULL, NULL, {NULL, 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+ { 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} }
+
+/* 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} }
// 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, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+ { 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} }
+ { 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, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} }
-
+ { 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} }
+// 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} }
+
+// 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+ { 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, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+ { 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, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+ { 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} }
+// 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, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->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, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} }
+ { 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, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->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, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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) \
- { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
+ { 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} }
/*------------------------------
@@ -388,6 +462,20 @@ typedef struct KX_PYATTRIBUTE_DEF {
------------------------------*/
typedef PyTypeObject * PyParentObject; // Define the PyParent Object
+#else // DISABLE_PYTHON
+
+#define Py_Header \
+ public: \
+
+
+#define Py_HeaderPtr \
+ public: \
+
+
+#endif
+
+
+
// By making SG_QList the ultimate parent for PyObjectPlus objects, it
// allows to put them in 2 different dynamic lists at the same time
// The use of these links is interesting because they free of memory allocation
@@ -405,11 +493,12 @@ class PyObjectPlus : public SG_QList
public:
PyObjectPlus();
-
- PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
virtual ~PyObjectPlus(); // destructor
+#ifndef DISABLE_PYTHON
+ PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
+
/* These static functions are referenced by ALL PyObjectPlus_Proxy types
* they take the C++ reference from the PyObjectPlus_Proxy and call
* its own virtual py_repr, py_base_dealloc ,etc. functions.
@@ -422,26 +511,23 @@ public:
/* These are all virtual python methods that are defined in each class
* Our own fake subclassing calls these on each class, then calls the parent */
virtual PyObject* py_repr(void);
+ /* subclass may overwrite this function to implement more sophisticated method of validating a proxy */
+ virtual bool py_is_valid(void) { return true; }
static PyObject* py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef);
static int py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef);
/* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
static PyObject* pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
- static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp);
- static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns);
-
- void InvalidateProxy();
-
- /**
- * Makes sure any internal data owned by this class is deep copied.
- */
- virtual void ProcessReplica();
-
-
- static bool m_ignore_deprecation_warnings;
-
+
+ static PyObject *GetProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr);
+ /* self=NULL => proxy to generic pointer detached from GE object
+ if py_owns is true, the memory pointed by ptr will be deleted automatially with MEM_freeN
+ self!=NULL=> proxy attached to GE object, ptr is optional and point to a struct from which attributes can be defined
+ if py_owns is true, the object will be deleted automatically, ptr will NOT be deleted
+ (assume object destructor takes care of it) */
+ static PyObject *NewProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr, bool py_owns);
+
static WarnLink* GetDeprecationWarningLinkFirst(void);
static WarnLink* GetDeprecationWarningLinkLast(void);
static void SetDeprecationWarningFirst(WarnLink* wlink);
@@ -454,12 +540,20 @@ public:
static void ShowDeprecationWarning_func(const char* method,const char* prop);
static void ClearDeprecationWarning();
-};
+#endif
+ void InvalidateProxy();
-PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
+ /**
+ * Makes sure any internal data owned by this class is deep copied.
+ */
+ virtual void ProcessReplica();
-#endif // _adr_py_lib_h_
+ static bool m_ignore_deprecation_warnings;
+};
-#endif //NO_EXP_PYTHON_EMBEDDING
+#ifndef DISABLE_PYTHON
+PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
+#endif
+#endif // _adr_py_lib_h_
diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript
index c819bfb0d3e..94af9dcfec8 100644
--- a/source/gameengine/Expressions/SConscript
+++ b/source/gameengine/Expressions/SConscript
@@ -3,7 +3,13 @@ Import ('env')
sources = env.Glob('*.cpp')
-incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader'
-incs += ' ' + env['BF_PYTHON_INC']
+incs ='. #source/kernel/gen_system #intern/guardedalloc #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader'
-env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,80], cxx_compileflags=env['BGE_CXXFLAGS'])
+defs = []
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
+env.BlenderLib ( 'bf_expressions', sources, Split(incs), defs, libtype=['core','player'], priority = [360,80], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h
index 069eb8d9c24..a23bb4ec3e2 100644
--- a/source/gameengine/Expressions/StringValue.h
+++ b/source/gameengine/Expressions/StringValue.h
@@ -39,9 +39,11 @@ public:
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); };
virtual CValue* GetReplica();
+#ifndef DISABLE_PYTHON
virtual PyObject* ConvertValueToPython() {
return PyUnicode_FromString(m_strString.Ptr());
}
+#endif // DISABLE_PYTHON
private:
// data member
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index 130317d77e2..6d2dfe2a6e3 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -33,7 +33,7 @@
double CValue::m_sZeroVec[3] = {0.0,0.0,0.0};
-#ifndef NO_EXP_PYTHON_EMBEDDING
+#ifndef DISABLE_PYTHON
PyTypeObject CValue::Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -64,6 +64,8 @@ PyTypeObject CValue::Type = {
PyMethodDef CValue::Methods[] = {
{NULL,NULL} //Sentinel
};
+#endif // DISABLE_PYTHON
+
/*#define CVALUE_DEBUG*/
#ifdef CVALUE_DEBUG
@@ -90,10 +92,6 @@ std::vector<SmartCValueRef> gRefList;
CValue::CValue()
: PyObjectPlus(),
-#else
-CValue::CValue()
-:
-#endif //NO_EXP_PYTHON_EMBEDDING
m_pNamedPropertyArray(NULL),
m_refcount(1)
@@ -526,8 +524,7 @@ CValue* CValue::FindIdentifier(const STR_String& identifiername)
return result;
}
-
-#ifndef NO_EXP_PYTHON_EMBEDDING
+#ifndef DISABLE_PYTHON
PyAttributeDef CValue::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("name", CValue, pyattr_get_name),
@@ -618,7 +615,8 @@ PyObject* CValue::ConvertKeysToPython( void )
return pylist;
}
-#endif //NO_EXP_PYTHON_EMBEDDING
+#endif // DISABLE_PYTHON
+
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index 7d4adcdb64f..f639ae5af78 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -197,19 +197,14 @@ public:
-#ifndef NO_EXP_PYTHON_EMBEDDING
#include "PyObjectPlus.h"
+#ifndef DISABLE_PYTHON
#include "object.h"
+#endif
class CValue : public PyObjectPlus
-#else
-class CValue
-#endif //NO_EXP_PYTHON_EMBEDDING
-
{
-#ifndef NO_EXP_PYTHON_EMBEDDING
Py_Header;
-#endif //NO_EXP_PYTHON_EMBEDDING
public:
enum AllocationTYPE {
STACKVALUE = 0,
@@ -224,9 +219,9 @@ public:
// Construction / Destruction
-#ifndef NO_EXP_PYTHON_EMBEDDING
-
CValue();
+
+#ifndef DISABLE_PYTHON
//static PyObject* PyMake(PyObject*,PyObject*);
virtual PyObject *py_repr(void)
{
@@ -242,10 +237,7 @@ public:
static PyObject * pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef);
virtual PyObject* ConvertKeysToPython( void );
-
-#else
- CValue();
-#endif //NO_EXP_PYTHON_EMBEDDING
+#endif // DISABLE_PYTHON
@@ -416,12 +408,8 @@ public: \
class CPropValue : public CValue
{
public:
-#ifndef NO_EXP_PYTHON_EMBEDDING
CPropValue() :
CValue(),
-#else
- CPropValue() :
-#endif //NO_EXP_PYTHON_EMBEDDING
m_strNewName()
{
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index 601585f79d6..819af4b56f8 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -34,7 +34,6 @@ SET(INC
../../../source/gameengine/SceneGraph
../../../intern/moto/include
../../../source/gameengine/Rasterizer
- ${PYTHON_INC}
)
IF(WITH_SDL)
@@ -43,5 +42,11 @@ ELSE(WITH_SDL)
ADD_DEFINITIONS(-DDISABLE_SDL)
ENDIF(WITH_SDL)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(bf_logic "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_logic', sources, Split(incs), [], libtype=['game','player'], priority=[30, 110] )
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 9dfb5ddc38f..bd1e5fa7105 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -43,7 +43,7 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
int int_arg,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_2DFILTER),
m_type(type),
m_disableMotionBlur(flag),
m_float_arg(float_arg),
@@ -99,12 +99,12 @@ void SCA_2DFilterActuator::SetShaderText(const char *text)
m_shaderText = text;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
-
-
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_2DFilterActuator::Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -141,3 +141,5 @@ PyAttributeDef SCA_2DFilterActuator::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_RW("value", 0.0, 100.0, SCA_2DFilterActuator, m_float_arg),
{ NULL } //Sentinel
};
+
+#endif
diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp
index ac9e238bd64..21380caf6a0 100644
--- a/source/gameengine/GameLogic/SCA_ANDController.cpp
+++ b/source/gameengine/GameLogic/SCA_ANDController.cpp
@@ -91,7 +91,7 @@ CValue* SCA_ANDController::GetReplica()
return replica;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -127,5 +127,5 @@ PyMethodDef SCA_ANDController::Methods[] = {
PyAttributeDef SCA_ANDController::Attributes[] = {
{ NULL } //Sentinel
};
-
+#endif // DISABLE_PYTHON
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
index a80b2af55c8..e4dfe4e0bff 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
@@ -36,8 +36,7 @@
SCA_ActuatorEventManager::SCA_ActuatorEventManager(class SCA_LogicManager* logicmgr)
- : SCA_EventManager(ACTUATOR_EVENTMGR),
- m_logicmgr(logicmgr)
+ : SCA_EventManager(logicmgr, ACTUATOR_EVENTMGR)
{
}
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
index f3884c87a75..8c86d0dd422 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
@@ -37,8 +37,6 @@ using namespace std;
class SCA_ActuatorEventManager : public SCA_EventManager
{
- class SCA_LogicManager* m_logicmgr;
-
public:
SCA_ActuatorEventManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_ActuatorEventManager();
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
index 428362a0a24..c5ba95e2c2c 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
@@ -114,6 +114,7 @@ void SCA_ActuatorSensor::Update()
}
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -163,4 +164,6 @@ int SCA_ActuatorSensor::CheckActuator(void *self, const PyAttributeDef*)
return 1;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
index 1a095148500..299684fc955 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
@@ -56,11 +56,15 @@ public:
virtual void ReParent(SCA_IObject* parent);
void Update();
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
-
+
static int CheckActuator(void *self, const PyAttributeDef*);
+
+#endif // DISABLE_PYTHON
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
index dd3b55abcc9..aee01606974 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
@@ -42,8 +42,7 @@
using namespace std;
SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
- : SCA_EventManager(ALWAYS_EVENTMGR),
- m_logicmgr(logicmgr)
+ : SCA_EventManager(logicmgr, ALWAYS_EVENTMGR)
{
}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
index 9540e3b71f6..f7fb3b9714e 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
@@ -34,8 +34,6 @@
using namespace std;
class SCA_AlwaysEventManager : public SCA_EventManager
{
-
- class SCA_LogicManager* m_logicmgr;
public:
SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
index 35b035f6466..898d0f4bb34 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -98,6 +98,8 @@ bool SCA_AlwaysSensor::Evaluate()
return result;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -133,4 +135,6 @@ PyAttributeDef SCA_AlwaysSensor::Attributes[] = {
{ NULL } //Sentinel
};
+#endif
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_BasicEventManager.cpp b/source/gameengine/GameLogic/SCA_BasicEventManager.cpp
new file mode 100644
index 00000000000..a2a7e535b5c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_BasicEventManager.cpp
@@ -0,0 +1,61 @@
+/**
+ * Manager for 'always' events. Since always sensors can operate in pulse
+ * mode, they need to be activated.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "SCA_BasicEventManager.h"
+#include "SCA_LogicManager.h"
+#include <vector>
+#include "SCA_ISensor.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using namespace std;
+
+SCA_BasicEventManager::SCA_BasicEventManager(class SCA_LogicManager* logicmgr)
+ : SCA_EventManager(logicmgr, BASIC_EVENTMGR)
+{
+}
+
+SCA_BasicEventManager::~SCA_BasicEventManager()
+{
+}
+
+void SCA_BasicEventManager::NextFrame()
+{
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
+ {
+ (*it)->Activate(m_logicmgr);
+ }
+}
+
diff --git a/source/gameengine/GameLogic/SCA_BasicEventManager.h b/source/gameengine/GameLogic/SCA_BasicEventManager.h
new file mode 100644
index 00000000000..3bd2df08c07
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_BasicEventManager.h
@@ -0,0 +1,57 @@
+/**
+ * Manager for sensor that only need to call Update
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 __SCA_BASICEVENTMGR
+#define __SCA_BASICEVENTMGR
+
+#include "SCA_EventManager.h"
+#include <vector>
+
+using namespace std;
+
+class SCA_BasicEventManager : public SCA_EventManager
+{
+public:
+ SCA_BasicEventManager(class SCA_LogicManager* logicmgr);
+ ~SCA_BasicEventManager();
+
+ virtual void NextFrame();
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "GE:SCA_BasicEventManager"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__SCA_BASICEVENTMGR
+
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
index 0f67ddd56a5..2c2b588abd3 100644
--- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
@@ -124,6 +124,8 @@ bool SCA_DelaySensor::Evaluate()
return trigger;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -162,4 +164,6 @@ PyAttributeDef SCA_DelaySensor::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
index d1301541a0a..5b6f3c46022 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -35,8 +35,9 @@
#endif
-SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype)
- :m_mgrtype(mgrtype)
+SCA_EventManager::SCA_EventManager(SCA_LogicManager* logicmgr, EVENT_MANAGER_TYPE mgrtype)
+ :m_logicmgr(logicmgr),
+ m_mgrtype(mgrtype)
{
}
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index 424150ffa63..debefcc45b0 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -38,6 +38,8 @@
class SCA_EventManager
{
protected:
+ class SCA_LogicManager* m_logicmgr; /* all event manager subclasses use this (other then TimeEventManager) */
+
// use a set to speed-up insertion/removal
//std::set <class SCA_ISensor*> m_sensors;
SG_DList m_sensors;
@@ -52,13 +54,13 @@ public:
TIME_EVENTMGR,
RANDOM_EVENTMGR,
RAY_EVENTMGR,
- RADAR_EVENTMGR,
NETWORK_EVENTMGR,
JOY_EVENTMGR,
- ACTUATOR_EVENTMGR
+ ACTUATOR_EVENTMGR,
+ BASIC_EVENTMGR
};
- SCA_EventManager(EVENT_MANAGER_TYPE mgrtype);
+ SCA_EventManager(SCA_LogicManager* logicmgr, EVENT_MANAGER_TYPE mgrtype);
virtual ~SCA_EventManager();
virtual void RemoveSensor(class SCA_ISensor* sensor);
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
index 60969300474..91135079fe6 100644
--- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
@@ -36,6 +36,8 @@
#include "InputParser.h"
#include "MT_Transform.h" // for fuzzyZero
+#include <stdio.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
index 0fda75590c1..13deed12dd1 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -27,6 +27,7 @@
*/
#include "SCA_IActuator.h"
+#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -34,8 +35,9 @@
using namespace std;
-SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj) :
+SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, KX_ACTUATOR_TYPE type) :
SCA_ILogicBrick(gameobj),
+ m_type(type),
m_links(0),
m_posevent(false),
m_negevent(false)
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index 00ba8c9ce4e..2f1c04192ab 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -41,6 +41,7 @@ class SCA_IActuator : public SCA_ILogicBrick
{
friend class SCA_LogicManager;
protected:
+ int m_type;
int m_links; // number of active links to controllers
// when 0, the actuator is automatically stopped
//std::vector<CValue*> m_events;
@@ -60,8 +61,33 @@ public:
/**
* This class also inherits the default copy constructors
*/
-
- SCA_IActuator(SCA_IObject* gameobj);
+ enum KX_ACTUATOR_TYPE {
+ KX_ACT_OBJECT,
+ KX_ACT_IPO,
+ KX_ACT_CAMERA,
+ KX_ACT_SOUND,
+ KX_ACT_PROPERTY,
+ KX_ACT_ADD_OBJECT,
+ KX_ACT_END_OBJECT,
+ KX_ACT_DYNAMIC,
+ KX_ACT_REPLACE_MESH,
+ KX_ACT_TRACKTO,
+ KX_ACT_CONSTRAINT,
+ KX_ACT_SCENE,
+ KX_ACT_RANDOM,
+ KX_ACT_MESSAGE,
+ KX_ACT_ACTION,
+ KX_ACT_CD,
+ KX_ACT_GAME,
+ KX_ACT_VISIBILITY,
+ KX_ACT_2DFILTER,
+ KX_ACT_PARENT,
+ KX_ACT_SHAPEACTION,
+ KX_ACT_STATE,
+ KX_ACT_ARMATURE,
+ };
+
+ SCA_IActuator(SCA_IObject* gameobj, KX_ACTUATOR_TYPE type);
/**
* UnlinkObject(...)
@@ -127,7 +153,7 @@ public:
void IncLink() { m_links++; }
void DecLink();
bool IsNoLink() const { return !m_links; }
-
+ bool IsType(KX_ACTUATOR_TYPE type) { return m_type == type; }
#ifdef WITH_CXX_GUARDEDALLOC
public:
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 7cfd2adc1d0..65c9c4d0f57 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -33,6 +33,8 @@
#include "PyObjectPlus.h"
#include "../Ketsji/KX_PythonSeq.h" /* not nice, only need for KX_PythonSeq_CreatePyObject */
+#include <stdio.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -196,6 +198,8 @@ void SCA_IController::ApplyState(unsigned int state)
}
}
+#ifndef DISABLE_PYTHON
+
/* Python api */
PyTypeObject SCA_IController::Type = {
@@ -247,3 +251,4 @@ PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBU
{
return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_ACTUATORS);
}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
index 202921c6986..48514121661 100644
--- a/source/gameengine/GameLogic/SCA_IController.h
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -98,10 +98,12 @@ public:
}
}
+
+#ifndef DISABLE_PYTHON
static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
+#endif // DISABLE_PYTHON
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index f679d0ee487..6502fc6de41 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -173,6 +173,7 @@ CValue* SCA_ILogicBrick::GetEvent()
+#ifndef DISABLE_PYTHON
/* python stuff */
@@ -255,3 +256,5 @@ PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg)
{
return PyLong_FromSsize_t(boolarg? KX_TRUE: KX_FALSE);
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index ac533335f0b..11885f988f3 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -125,6 +125,7 @@ public:
static class SCA_LogicManager* m_sCurrentLogicManager;
+#ifndef DISABLE_PYTHON
// python methods
static PyObject* pyattr_get_owner(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -147,8 +148,9 @@ protected:
/** Convert a a c++ value to KX_TRUE, KX_FALSE in Python. */
PyObject* BoolToPyArg(bool);
-
+#endif // DISABLE_PYTHON
+
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 2bffd029bd4..e63b616cab0 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -26,6 +26,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
#include <iostream>
+#include <algorithm>
#include "SCA_IObject.h"
#include "SCA_ISensor.h"
@@ -76,6 +77,12 @@ SCA_IObject::~SCA_IObject()
(*ita)->Delete();
}
+ SCA_ObjectList::iterator ito;
+ for (ito = m_registeredObjects.begin(); !(ito==m_registeredObjects.end()); ++ito)
+ {
+ (*ito)->UnlinkObject(this);
+ }
+
//T_InterpolatorList::iterator i;
//for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
// delete *i;
@@ -123,6 +130,26 @@ void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
}
}
+void SCA_IObject::RegisterObject(SCA_IObject* obj)
+{
+ // one object may be registered multiple times via constraint target
+ // store multiple reference, this will serve as registration counter
+ m_registeredObjects.push_back(obj);
+}
+
+void SCA_IObject::UnregisterObject(SCA_IObject* obj)
+{
+ SCA_ObjectList::iterator ito;
+ for (ito = m_registeredObjects.begin(); ito != m_registeredObjects.end(); ++ito)
+ {
+ if ((*ito) == obj) {
+ (*ito) = m_registeredObjects.back();
+ m_registeredObjects.pop_back();
+ break;
+ }
+ }
+}
+
void SCA_IObject::ReParentLogic()
{
SCA_ActuatorList& oldactuators = GetActuators();
@@ -165,7 +192,7 @@ void SCA_IObject::ReParentLogic()
// a new object cannot be client of any actuator
m_registeredActuators.clear();
-
+ m_registeredObjects.clear();
}
@@ -280,7 +307,7 @@ void SCA_IObject::SetState(unsigned int state)
}
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -318,3 +345,5 @@ PyMethodDef SCA_IObject::Methods[] = {
PyAttributeDef SCA_IObject::Attributes[] = {
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 3060410dc6b..f078e129378 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -36,15 +36,19 @@
#include "Value.h"
#include <vector>
+class SCA_IObject;
class SCA_ISensor;
class SCA_IController;
class SCA_IActuator;
+#ifndef DISABLE_PYTHON
template<class T> T PyVecTo(PyObject*);
+#endif
typedef std::vector<SCA_ISensor *> SCA_SensorList;
typedef std::vector<SCA_IController *> SCA_ControllerList;
typedef std::vector<SCA_IActuator *> SCA_ActuatorList;
+typedef std::vector<SCA_IObject *> SCA_ObjectList;
class SCA_IObject : public CValue
{
@@ -59,6 +63,7 @@ protected:
SCA_ControllerList m_controllers;
SCA_ActuatorList m_actuators;
SCA_ActuatorList m_registeredActuators; // actuators that use a pointer to this object
+ SCA_ObjectList m_registeredObjects; // objects that hold reference to this object
// SG_Dlist: element of objects with active actuators
// Head: SCA_LogicManager::m_activeActuators
@@ -143,13 +148,22 @@ public:
void RegisterActuator(SCA_IActuator* act);
void UnregisterActuator(SCA_IActuator* act);
+ void RegisterObject(SCA_IObject* objs);
+ void UnregisterObject(SCA_IObject* objs);
+ /**
+ * UnlinkObject(...)
+ * this object is informed that one of the object to which it holds a reference is deleted
+ * returns true if there was indeed a reference.
+ */
+ virtual bool UnlinkObject(SCA_IObject* clientobj) { return false; }
+
SCA_ISensor* FindSensor(const STR_String& sensorname);
SCA_IActuator* FindActuator(const STR_String& actuatorname);
SCA_IController* FindController(const STR_String& controllername);
void SetCurrentTime(float currentTime) {}
- void ReParentLogic();
+ virtual void ReParentLogic();
/**
* Set whether or not to ignore activity culling requests
@@ -205,6 +219,7 @@ public:
typedef enum ObjectTypes {
OBJ_ARMATURE=0,
OBJ_CAMERA=1,
+ OBJ_LIGHT=2,
}ObjectTypes;
};
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 497a5d1095a..877563e3161 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -35,6 +35,8 @@
// needed for IsTriggered()
#include "SCA_PythonController.h"
+#include <stdio.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -288,6 +290,9 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr)
}
}
}
+
+#ifndef DISABLE_PYTHON
+
/* ----------------------------------------------- */
/* Python Functions */
/* ----------------------------------------------- */
@@ -379,5 +384,6 @@ int SCA_ISensor::pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrde
self->m_level = false;
return 0;
}
+#endif // DISABLE_PYTHON
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 742b05bd88b..fce5f340be1 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -171,6 +171,7 @@ public:
bool IsNoLink() const
{ return !m_links; }
+#ifndef DISABLE_PYTHON
/* Python functions: */
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,reset);
@@ -178,6 +179,7 @@ public:
static PyObject* pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif // DISABLE_PYTHON
};
#endif //__SCA_ISENSOR
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index ff8f3b1c81f..480292774da 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -37,8 +37,7 @@
SCA_JoystickManager::SCA_JoystickManager(class SCA_LogicManager* logicmgr)
- : SCA_EventManager(JOY_EVENTMGR),
- m_logicmgr(logicmgr)
+ : SCA_EventManager(logicmgr, JOY_EVENTMGR)
{
int i;
for (i=0; i<JOYINDEX_MAX; i++) {
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.h b/source/gameengine/GameLogic/SCA_JoystickManager.h
index be55e95b033..cd0e22cc367 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.h
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.h
@@ -35,8 +35,6 @@
using namespace std;
class SCA_JoystickManager : public SCA_EventManager
{
-
- class SCA_LogicManager* m_logicmgr;
/**
* SDL Joystick Class Instance
*/
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index 4936b380352..9ac64b7f31e 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -32,6 +32,7 @@
#include "PyObjectPlus.h"
+#include <stdio.h>
#include <iostream>
@@ -244,6 +245,7 @@ bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m)
return res;
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -413,3 +415,5 @@ PyObject* SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTR
SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
return PyBool_FromLong( joy ? joy->Connected() : 0 );
}
+
+#endif
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h
index b793c591ac1..49ca58ee14f 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.h
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h
@@ -117,6 +117,8 @@ public:
return m_joyindex;
}
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -155,6 +157,8 @@ public:
return 0;
}
+#endif // DISABLE_PYTHON
+
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
index 279adab94d8..3d010f57055 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
@@ -37,9 +37,8 @@
SCA_KeyboardManager::SCA_KeyboardManager(SCA_LogicManager* logicmgr,
SCA_IInputDevice* inputdev)
- : SCA_EventManager(KEYBOARD_EVENTMGR),
- m_inputDevice(inputdev),
- m_logicmanager(logicmgr)
+ : SCA_EventManager(logicmgr, KEYBOARD_EVENTMGR),
+ m_inputDevice(inputdev)
{
}
@@ -65,7 +64,7 @@ void SCA_KeyboardManager::NextFrame()
SG_DList::iterator<SCA_ISensor> it(m_sensors);
for (it.begin();!it.end();++it)
{
- (*it)->Activate(m_logicmanager);
+ (*it)->Activate(m_logicmgr);
}
}
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h
index c5553a74aef..8155283a274 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h
@@ -45,8 +45,6 @@ using namespace std;
class SCA_KeyboardManager : public SCA_EventManager
{
class SCA_IInputDevice* m_inputDevice;
- class SCA_LogicManager* m_logicmanager;
-
public:
SCA_KeyboardManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* inputdev);
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index d2e3871fec2..dcad65e6459 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -403,6 +403,7 @@ void SCA_KeyboardSensor::LogKeystrokes(void)
}
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python Functions */
@@ -495,6 +496,7 @@ PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBU
return resultlist;
}
+#endif // DISABLE_PYTHON
/* Accessed from python */
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index d7e0f301a9d..0ce08b3e408 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -103,6 +103,7 @@ public:
virtual bool IsPositiveTrigger();
bool TriggerOnAllKeys();
+#ifndef DISABLE_PYTHON
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -113,6 +114,7 @@ public:
KX_PYMETHOD_DOC_O(SCA_KeyboardSensor,getKeyStatus);
static PyObject* pyattr_get_events(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
};
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index b782c6dfb93..d93f2e70e36 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -305,6 +305,9 @@ void SCA_LogicManager::EndFrame()
void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
{
controller->Activate(m_triggeredControllerSet);
+
+#ifndef DISABLE_PYTHON
+
// so that the controller knows which sensor has activited it
// only needed for python controller
// Note that this is safe even if the controller is subclassed.
@@ -313,6 +316,7 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I
SCA_PythonController* pythonController = (SCA_PythonController*)controller;
pythonController->AddTriggeredSensor(sensor);
}
+#endif
}
SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp
index d407647cec3..c752701e785 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp
@@ -48,9 +48,8 @@
SCA_MouseManager::SCA_MouseManager(SCA_LogicManager* logicmgr,
SCA_IInputDevice* mousedev)
- : SCA_EventManager(MOUSE_EVENTMGR),
- m_mousedevice (mousedev),
- m_logicmanager(logicmgr)
+ : SCA_EventManager(logicmgr, MOUSE_EVENTMGR),
+ m_mousedevice (mousedev)
{
m_xpos = 0;
m_ypos = 0;
@@ -93,7 +92,7 @@ void SCA_MouseManager::NextFrame()
mousesensor->setX(mx);
mousesensor->setY(my);
- mousesensor->Activate(m_logicmanager);
+ mousesensor->Activate(m_logicmgr);
}
}
}
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h
index ef1533c636b..00bbab66aa6 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.h
+++ b/source/gameengine/GameLogic/SCA_MouseManager.h
@@ -47,7 +47,6 @@ class SCA_MouseManager : public SCA_EventManager
{
class SCA_IInputDevice* m_mousedevice;
- class SCA_LogicManager* m_logicmanager;
unsigned short m_xpos; // Cached location of the mouse pointer
unsigned short m_ypos;
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index 9d32682eaa9..466b8f7e741 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -57,7 +57,7 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
m_mousemode = mousemode;
m_triggermode = true;
- UpdateHotkey(this, NULL);
+ UpdateHotkey(this);
Init();
}
@@ -72,7 +72,7 @@ SCA_MouseSensor::~SCA_MouseSensor()
/* Nothing to be done here. */
}
-int SCA_MouseSensor::UpdateHotkey(void *self, const PyAttributeDef*)
+void SCA_MouseSensor::UpdateHotkey(void *self)
{
// gosh, this function is so damn stupid
// its here because of a design mistake in the mouse sensor, it should only
@@ -100,9 +100,6 @@ int SCA_MouseSensor::UpdateHotkey(void *self, const PyAttributeDef*)
default:
; /* ignore, no hotkey */
}
- // return value is used in py_setattro(),
- // 0=attribute checked ok (see Attributes array definition)
- return 0;
}
CValue* SCA_MouseSensor::GetReplica()
@@ -239,6 +236,8 @@ bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
return ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -296,10 +295,20 @@ PyMethodDef SCA_MouseSensor::Methods[] = {
{NULL,NULL} //Sentinel
};
+int SCA_MouseSensor::UpdateHotkeyPy(void *self, const PyAttributeDef*)
+{
+ UpdateHotkey(self);
+ // return value is used in py_setattro(),
+ // 0=attribute checked ok (see Attributes array definition)
+ return 0;
+}
+
PyAttributeDef SCA_MouseSensor::Attributes[] = {
- KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkey),
+ KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkeyPy),
KX_PYATTRIBUTE_SHORT_LIST_RO("position",SCA_MouseSensor,m_x,2),
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
index a679e605428..25b3a6c2e6e 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.h
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -86,8 +86,6 @@ class SCA_MouseSensor : public SCA_ISensor
bool isValid(KX_MOUSESENSORMODE);
- static int UpdateHotkey(void *self, const PyAttributeDef*);
-
SCA_MouseSensor(class SCA_MouseManager* keybdmgr,
int startx,int starty,
short int mousemode,
@@ -102,14 +100,20 @@ class SCA_MouseSensor : public SCA_ISensor
SCA_IInputDevice::KX_EnumInputs GetHotKey();
void setX(short x);
void setY(short y);
-
+
+ static void UpdateHotkey(void *self);
+
+
+#ifndef DISABLE_PYTHON
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
+ static int UpdateHotkeyPy(void *self, const PyAttributeDef *);
+
// get button status
KX_PYMETHOD_DOC_O(SCA_MouseSensor,getButtonStatus);
-
+#endif
};
#endif //__KX_MOUSESENSOR
diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp
index c971c06fadd..99c74e6d737 100644
--- a/source/gameengine/GameLogic/SCA_NANDController.cpp
+++ b/source/gameengine/GameLogic/SCA_NANDController.cpp
@@ -91,7 +91,7 @@ CValue* SCA_NANDController::GetReplica()
return replica;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -128,4 +128,6 @@ PyAttributeDef SCA_NANDController::Attributes[] = {
{ NULL } //Sentinel
};
+#endif
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp
index 7a8b09e4bec..a84453de977 100644
--- a/source/gameengine/GameLogic/SCA_NORController.cpp
+++ b/source/gameengine/GameLogic/SCA_NORController.cpp
@@ -91,7 +91,7 @@ CValue* SCA_NORController::GetReplica()
return replica;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -128,4 +128,6 @@ PyAttributeDef SCA_NORController::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp
index 12e2f610986..0f750eedf77 100644
--- a/source/gameengine/GameLogic/SCA_ORController.cpp
+++ b/source/gameengine/GameLogic/SCA_ORController.cpp
@@ -87,6 +87,8 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr)
}
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -122,4 +124,6 @@ PyAttributeDef SCA_ORController::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
index 9446487cdb7..2b480a8e8cb 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -43,7 +43,7 @@
/* ------------------------------------------------------------------------- */
SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_PROPERTY),
m_type(acttype),
m_propname(propname),
m_exprtxt(expr),
@@ -221,6 +221,7 @@ void SCA_PropertyActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
}
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -260,4 +261,6 @@ PyAttributeDef SCA_PropertyActuator::Attributes[] = {
{ NULL } //Sentinel
};
+#endif
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
index 764465309df..e01ce74e0a9 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
@@ -35,8 +35,7 @@
SCA_PropertyEventManager::SCA_PropertyEventManager(class SCA_LogicManager* logicmgr)
- : SCA_EventManager(PROPERTY_EVENTMGR),
- m_logicmgr(logicmgr)
+ : SCA_EventManager(logicmgr, PROPERTY_EVENTMGR)
{
}
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
index a9692377df8..5a036abb8b7 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.h
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
@@ -37,8 +37,6 @@ using namespace std;
class SCA_PropertyEventManager : public SCA_EventManager
{
- class SCA_LogicManager* m_logicmgr;
-
public:
SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_PropertyEventManager();
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index 9c09c8410fb..2a4222af355 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -38,6 +38,7 @@
#include "SCA_EventManager.h"
#include "SCA_LogicManager.h"
#include "BoolValue.h"
+#include "FloatValue.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -190,6 +191,22 @@ bool SCA_PropertySensor::CheckPropertyCondition()
m_checkpropval.Upper();
}
result = (testprop == m_checkpropval);
+
+ /* Patch: floating point values cant use strings usefully since you can have "0.0" == "0.0000"
+ * this could be made into a generic Value class function for comparing values with a string.
+ */
+ if(result==false && dynamic_cast<CFloatValue *>(orgprop) != NULL) {
+ float f;
+
+ if(EOF == sscanf(m_checkpropval.ReadPtr(), "%f", &f))
+ {
+ //error
+ }
+ else {
+ result = (f == ((CFloatValue *)orgprop)->GetFloat());
+ }
+ }
+ /* end patch */
}
orgprop->Release();
@@ -290,16 +307,18 @@ CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername)
return GetParent()->FindIdentifier(identifiername);
}
+#ifndef DISABLE_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*)
{
/* There is no type checking at this moment, unfortunately... */
return 0;
}
-/* ------------------------------------------------------------------------- */
-/* Python functions */
-/* ------------------------------------------------------------------------- */
-
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_PropertySensor::Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -334,4 +353,6 @@ PyAttributeDef SCA_PropertySensor::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index a5bbfc8438b..cd8a6713148 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -84,6 +84,8 @@ public:
virtual bool IsPositiveTrigger();
virtual CValue* FindIdentifier(const STR_String& identifiername);
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -92,6 +94,8 @@ public:
* Test whether this is a sensible value (type check)
*/
static int validValueForProperty(void* self, const PyAttributeDef*);
+
+#endif
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index ecaa8c508db..ac3e0434d20 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -34,8 +34,12 @@
#include "SCA_ISensor.h"
#include "SCA_IActuator.h"
#include "PyObjectPlus.h"
+
+#ifndef DISABLE_PYTHON
#include "compile.h"
#include "eval.h"
+#endif // DISABLE_PYTHON
+
#include <algorithm>
@@ -49,13 +53,18 @@ SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, int mode)
: SCA_IController(gameobj),
+#ifndef DISABLE_PYTHON
m_bytecode(NULL),
m_function(NULL),
+#endif
m_function_argc(0),
m_bModified(true),
m_debug(false),
- m_mode(mode),
- m_pythondictionary(NULL)
+ m_mode(mode)
+#ifndef DISABLE_PYTHON
+ , m_pythondictionary(NULL)
+#endif
+
{
}
@@ -78,6 +87,8 @@ int SCA_PythonController::Release()
SCA_PythonController::~SCA_PythonController()
{
+
+#ifndef DISABLE_PYTHON
//printf("released python byte script\n");
Py_XDECREF(m_bytecode);
@@ -88,6 +99,7 @@ SCA_PythonController::~SCA_PythonController()
PyDict_Clear(m_pythondictionary);
Py_DECREF(m_pythondictionary);
}
+#endif
}
@@ -95,7 +107,8 @@ SCA_PythonController::~SCA_PythonController()
CValue* SCA_PythonController::GetReplica()
{
SCA_PythonController* replica = new SCA_PythonController(*this);
-
+
+#ifndef DISABLE_PYTHON
/* why is this needed at all??? - m_bytecode is NULL'd below so this doesnt make sense
* but removing it crashes blender (with YoFrankie). so leave in for now - Campbell */
Py_XINCREF(replica->m_bytecode);
@@ -113,6 +126,7 @@ CValue* SCA_PythonController::GetReplica()
if (m_pythondictionary)
Py_INCREF(replica->m_pythondictionary);
*/
+#endif
// this will copy properties and so on...
replica->ProcessReplica();
@@ -136,8 +150,8 @@ void SCA_PythonController::SetScriptName(const STR_String& name)
}
-
-void SCA_PythonController::SetDictionary(PyObject* pythondictionary)
+#ifndef DISABLE_PYTHON
+void SCA_PythonController::SetNamespace(PyObject* pythondictionary)
{
if (m_pythondictionary)
{
@@ -151,6 +165,7 @@ void SCA_PythonController::SetDictionary(PyObject* pythondictionary)
PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_FromString(m_scriptName.Ptr()));
}
+#endif
int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
{
@@ -160,6 +175,8 @@ int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
return 0;
}
+#ifndef DISABLE_PYTHON
+
/* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self)
{
@@ -360,6 +377,7 @@ bool SCA_PythonController::Import()
return true;
}
+
void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
{
m_sCurrentController = this;
@@ -514,5 +532,13 @@ int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_D
return PY_SET_ATTR_SUCCESS;
}
+#else // DISABLE_PYTHON
+
+void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
+{
+ /* intentionally blank */
+}
+
+#endif // DISABLE_PYTHON
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index 9311b3f355e..eeac710c6ea 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -42,8 +42,10 @@ class SCA_IObject;
class SCA_PythonController : public SCA_IController
{
Py_Header;
+#ifndef DISABLE_PYTHON
struct _object * m_bytecode; /* SCA_PYEXEC_SCRIPT only */
PyObject* m_function; /* SCA_PYEXEC_MODULE only */
+#endif
int m_function_argc;
bool m_bModified;
bool m_debug; /* use with SCA_PYEXEC_MODULE for reloading every logic run */
@@ -53,9 +55,10 @@ class SCA_PythonController : public SCA_IController
protected:
STR_String m_scriptText;
STR_String m_scriptName;
+#ifndef DISABLE_PYTHON
PyObject* m_pythondictionary; /* for SCA_PYEXEC_SCRIPT only */
PyObject* m_pythonfunction; /* for SCA_PYEXEC_MODULE only */
-
+#endif
std::vector<class SCA_ISensor*> m_triggeredSensors;
public:
@@ -80,7 +83,9 @@ class SCA_PythonController : public SCA_IController
void SetScriptText(const STR_String& text);
void SetScriptName(const STR_String& name);
- void SetDictionary(PyObject* pythondictionary);
+#ifndef DISABLE_PYTHON
+ void SetNamespace(PyObject* pythondictionary);
+#endif
void SetDebug(bool debug) { m_debug = debug; }
void AddTriggeredSensor(class SCA_ISensor* sensor)
{ m_triggeredSensors.push_back(sensor); }
@@ -89,7 +94,7 @@ class SCA_PythonController : public SCA_IController
bool Import();
void ErrorPrint(const char *error_msg);
-
+#ifndef DISABLE_PYTHON
static const char* sPyGetCurrentController__doc__;
static PyObject* sPyGetCurrentController(PyObject* self);
static const char* sPyAddActiveActuator__doc__;
@@ -106,8 +111,7 @@ class SCA_PythonController : public SCA_IController
static PyObject* pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
-
-
+#endif
};
#endif //KX_PYTHONCONTROLLER_H
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
index a3a5cc2303e..fa85bdd768e 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -51,7 +51,7 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
float para1,
float para2,
const STR_String &propName)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_RANDOM),
m_propname(propName),
m_parameter1(para1),
m_parameter2(para2),
@@ -309,6 +309,8 @@ void SCA_RandomActuator::enforceConstraints() {
}
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -546,5 +548,7 @@ KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setFloatNegativeExponential,
enforceConstraints();
Py_RETURN_NONE;
}
-
+
+#endif
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h
index f84c44b43c9..2eb9b8d5d14 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.h
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.h
@@ -91,6 +91,8 @@ class SCA_RandomActuator : public SCA_IActuator
virtual CValue* GetReplica();
virtual void ProcessReplica();
+
+#ifndef DISABLE_PYTHON
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
@@ -109,6 +111,9 @@ class SCA_RandomActuator : public SCA_IActuator
KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatUniform);
KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatNormal);
KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatNegativeExponential);
+
+#endif // DISABLE_PYTHON
+
}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */
#endif
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
index 976597aa812..780f8d10857 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
@@ -42,8 +42,7 @@ using namespace std;
#endif
SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
- : SCA_EventManager(RANDOM_EVENTMGR),
- m_logicmgr(logicmgr)
+ : SCA_EventManager(logicmgr, RANDOM_EVENTMGR)
{
}
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h
index c8b511b87b7..81896709551 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.h
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h
@@ -39,8 +39,6 @@ using namespace std;
class SCA_RandomEventManager : public SCA_EventManager
{
- class SCA_LogicManager* m_logicmgr;
-
public:
SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 890875e61c6..922e44b1c1d 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -124,6 +124,8 @@ bool SCA_RandomSensor::Evaluate()
return evaluateResult;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -178,4 +180,6 @@ int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *at
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index f93cf57370e..8126824c3dd 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -56,13 +56,15 @@ public:
virtual bool IsPositiveTrigger();
virtual void Init();
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
static PyObject* pyattr_get_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
-
+#endif
};
#endif //__KX_RANDOMSENSOR
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
index 911ea772bef..1b49906b8de 100644
--- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
@@ -43,7 +43,7 @@
#include "FloatValue.h"
SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr)
-: SCA_EventManager(TIME_EVENTMGR)
+: SCA_EventManager(NULL, TIME_EVENTMGR)
{
}
diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp
index 17350feb98b..e726a49347c 100644
--- a/source/gameengine/GameLogic/SCA_XNORController.cpp
+++ b/source/gameengine/GameLogic/SCA_XNORController.cpp
@@ -95,7 +95,7 @@ CValue* SCA_XNORController::GetReplica()
return replica;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -132,4 +132,6 @@ PyAttributeDef SCA_XNORController::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp
index a6a7cc25897..71cc4374e95 100644
--- a/source/gameengine/GameLogic/SCA_XORController.cpp
+++ b/source/gameengine/GameLogic/SCA_XORController.cpp
@@ -95,7 +95,7 @@ CValue* SCA_XORController::GetReplica()
return replica;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -131,5 +131,6 @@ PyMethodDef SCA_XORController::Methods[] = {
PyAttributeDef SCA_XORController::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
/* eof */
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index 1530c71c7f3..3840754ed06 100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -7,9 +7,6 @@ incs = '. #/source/kernel/gen_system #/intern/string'
incs += ' #/source/gameengine/Expressions #/intern/moto/include'
incs += ' #/source/gameengine/Rasterizer #/source/gameengine/SceneGraph'
-incs += ' ' + env['BF_PYTHON_INC']
-
-
defs = []
if env['WITH_BF_SDL']:
@@ -17,6 +14,11 @@ if env['WITH_BF_SDL']:
else:
defs.append('DISABLE_SDL')
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
if env['BF_DEBUG']:
defs.append('_DEBUG')
diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript
index dd5a48c2b55..99eda4cb592 100644
--- a/source/gameengine/GamePlayer/common/SConscript
+++ b/source/gameengine/GamePlayer/common/SConscript
@@ -58,8 +58,14 @@ incs = ['.',
# 'unix/GPU_System.cpp']
# gp_common_env.Append ( CPPPATH = ['unix'])
-incs += Split(env['BF_PYTHON_INC'])
+defs = []
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
incs += Split(env['BF_PNG_INC'])
incs += Split(env['BF_ZLIB_INC'])
-env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype=['player'], priority=[5], cxx_compileflags=env['BGE_CXXFLAGS'])
+env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = defs, libtype=['player'], priority=[5], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 8ec41968042..3c989293c94 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -679,7 +679,7 @@ bool GPG_Application::startEngine(void)
// some python things
PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest, m_maggie, m_argc, m_argv);
- m_ketsjiengine->SetPythonDictionary(dictionaryobject);
+ m_ketsjiengine->SetPyNamespace(dictionaryobject);
initRasterizer(m_rasterizer, m_canvas);
PyObject *gameLogic = initGameLogic(m_ketsjiengine, startscene);
PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module
@@ -702,7 +702,6 @@ bool GPG_Application::startEngine(void)
m_sceneconverter->ConvertScene(
startscene,
- dictionaryobject,
m_rendertools,
m_canvas);
m_ketsjiengine->AddScene(startscene);
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index fdd7792b72a..cfb827cf8c3 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -40,9 +40,13 @@ incs = ['.',
'#source/blender/gpu',
'#extern/glew/include']
-incs += Split(env['BF_PYTHON_INC'])
-
defs = []
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index f548bcdaae1..35eb5dc124a 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -728,6 +728,8 @@ void BL_Shader::SetUniform(int uniform, const int* val, int len)
}
}
+#ifndef DISABLE_PYTHON
+
PyMethodDef BL_Shader::Methods[] =
{
// creation
@@ -1409,4 +1411,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
return NULL;
}
+#endif // DISABLE_PYTHON
+
// eof
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index b2610d7762a..ebd2e491f35 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -222,6 +222,7 @@ public:
void SetUniform(int uniform, const int val);
// Python interface
+#ifndef DISABLE_PYTHON
virtual PyObject* py_repr(void) { return PyUnicode_FromFormat("BL_Shader\n\tvertex shader:%s\n\n\tfragment shader%s\n\n", vertProg, fragProg); }
// -----------------------------------
@@ -249,6 +250,7 @@ public:
KX_PYMETHOD_DOC( BL_Shader, setUniformDef );
KX_PYMETHOD_DOC( BL_Shader, setAttrib );
KX_PYMETHOD_DOC( BL_Shader, setSampler);
+#endif
};
#endif//__BL_SHADER_H__
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 01d369bc7a9..857be4bd827 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -59,7 +59,6 @@ SET(INC
../../../source/blender/gpu
../../../extern/bullet2/src
../../../extern/glew/include
- ${PYTHON_INC}
)
IF(WITH_SDL)
@@ -68,5 +67,11 @@ ELSE(WITH_SDL)
ADD_DEFINITIONS(-DDISABLE_SDL)
ENDIF(WITH_SDL)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(bf_ketsji "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_ketsji', sources, Split(incs), [], libtype=['game','player'], priority=[25, 72], compileflags = cflags )
diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
index b89b0dcff9f..1a608713c51 100644
--- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
+++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
@@ -36,8 +36,13 @@ SET(INC
../../../../source/gameengine/Expressions
../../../../source/gameengine/SceneGraph
../../../../source/gameengine/Network
- ${PYTHON_INC}
)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(kx_network "${SRC}" "${INC}")
#env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['game2', 'player'], priority=[5, 155] )
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
index 738f64713b0..65f7d98253c 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
@@ -45,7 +45,7 @@
KX_NetworkEventManager::KX_NetworkEventManager(class SCA_LogicManager*
logicmgr, class NG_NetworkDeviceInterface *ndi) :
-SCA_EventManager(NETWORK_EVENTMGR), m_logicmgr(logicmgr), m_ndi(ndi)
+SCA_EventManager(logicmgr, NETWORK_EVENTMGR), m_ndi(ndi)
{
//printf("KX_NetworkEventManager constructor\n");
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
index ae88f1d4987..fd776640bcf 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
@@ -34,7 +34,6 @@
class KX_NetworkEventManager : public SCA_EventManager
{
- class SCA_LogicManager* m_logicmgr;
class NG_NetworkDeviceInterface* m_ndi;
public:
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
index 3af8f765251..04a7f2b3603 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
@@ -42,7 +42,7 @@ KX_NetworkMessageActuator::KX_NetworkMessageActuator(
const STR_String &subject,
int bodyType,
const STR_String &body) :
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_MESSAGE),
m_networkscene(networkscene),
m_toPropName(toPropName),
m_subject(subject),
@@ -95,6 +95,8 @@ CValue* KX_NetworkMessageActuator::GetReplica()
return replica;
}
+#ifndef DISABLE_PYTHON
+
/* -------------------------------------------------------------------- */
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
@@ -133,3 +135,5 @@ PyAttributeDef KX_NetworkMessageActuator::Attributes[] = {
KX_PYATTRIBUTE_STRING_RW("body", 0, 16384, false, KX_NetworkMessageActuator, m_body),
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index 392e9dd9d1b..18dc416cc1b 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -158,6 +158,8 @@ bool KX_NetworkMessageSensor::IsPositiveTrigger()
return m_IsUp;
}
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -216,3 +218,5 @@ PyObject* KX_NetworkMessageSensor::pyattr_get_subjects(void *self_v, const KX_PY
return (new CListValue())->NewProxy(true);
}
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index d8a0651d2f1..3a8fe760bb9 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -66,6 +66,8 @@ public:
virtual void Init();
void EndFrame();
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------- */
/* Python interface -------------------------------------------- */
/* ------------------------------------------------------------- */
@@ -74,6 +76,8 @@ public:
static PyObject* pyattr_get_bodies(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_subjects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif // DISABLE_PYTHON
+
};
#endif //__KX_NETWORKMESSAGE_SENSOR_H
diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript
index 8f88511acca..64d00489c89 100644
--- a/source/gameengine/Ketsji/KXNetwork/SConscript
+++ b/source/gameengine/Ketsji/KXNetwork/SConscript
@@ -7,6 +7,11 @@ incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/
incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions'
incs += ' #source/gameengine/Network #source/gameengine/SceneGraph'
-incs += ' ' + env['BF_PYTHON_INC']
+defs = []
-env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=[],libtype=['core','player'], priority=[400,125], cxx_compileflags=env['BGE_CXXFLAGS'])
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
+env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=defs,libtype=['core','player'], priority=[400,125], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Ketsji/KX_ArmatureSensor.cpp b/source/gameengine/Ketsji/KX_ArmatureSensor.cpp
new file mode 100644
index 00000000000..40e16744d71
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ArmatureSensor.cpp
@@ -0,0 +1,208 @@
+/**
+ * Armature sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "DNA_action_types.h"
+#include "DNA_constraint_types.h"
+#include "BKE_constraint.h"
+#include "DNA_sensor_types.h"
+
+#include "BL_ArmatureObject.h"
+#include "KX_ArmatureSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+KX_ArmatureSensor::KX_ArmatureSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const char *posechannel,
+ const char *constraintname,
+ int type,
+ float value)
+ : SCA_ISensor(gameobj,eventmgr),
+ m_constraint(NULL),
+ m_posechannel(posechannel),
+ m_constraintname(constraintname),
+ m_type(type),
+ m_value(value)
+{
+ FindConstraint();
+}
+
+void KX_ArmatureSensor::Init()
+{
+ m_lastresult = m_invert?true:false;
+ m_result = false;
+ m_reset = true;
+}
+
+void KX_ArmatureSensor::FindConstraint()
+{
+ m_constraint = NULL;
+
+ if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
+ BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
+ // get the persistent pose structure
+ bPose* pose = armobj->GetOrigPose();
+ bPoseChannel* pchan;
+ bConstraint* pcon;
+ // and locate the constraint
+ for (pchan = (bPoseChannel*)pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
+ if (!strcmp(pchan->name, m_posechannel)) {
+ // now locate the constraint
+ for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) {
+ if (!strcmp(pcon->name, m_constraintname)) {
+ if (pcon->flag & CONSTRAINT_DISABLE)
+ /* this constraint is not valid, can't use it */
+ break;
+ m_constraint = pcon;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+CValue* KX_ArmatureSensor::GetReplica()
+{
+ KX_ArmatureSensor* replica = new KX_ArmatureSensor(*this);
+ // m_range_expr must be recalculated on replica!
+ replica->ProcessReplica();
+ return replica;
+}
+
+void KX_ArmatureSensor::ReParent(SCA_IObject* parent)
+{
+ SCA_ISensor::ReParent(parent);
+ // must remap the constraint
+ FindConstraint();
+}
+
+bool KX_ArmatureSensor::IsPositiveTrigger()
+{
+ return (m_invert) ? !m_result : m_result;
+}
+
+
+KX_ArmatureSensor::~KX_ArmatureSensor()
+{
+}
+
+bool KX_ArmatureSensor::Evaluate()
+{
+ bool reset = m_reset && m_level;
+
+ m_reset = false;
+ if (!m_constraint)
+ return false;
+ switch (m_type) {
+ case SENS_ARM_STATE_CHANGED:
+ m_result = !(m_constraint->flag & CONSTRAINT_OFF);
+ break;
+ case SENS_ARM_LIN_ERROR_BELOW:
+ m_result = (m_constraint->lin_error < m_value);
+ break;
+ case SENS_ARM_LIN_ERROR_ABOVE:
+ m_result = (m_constraint->lin_error > m_value);
+ break;
+ case SENS_ARM_ROT_ERROR_BELOW:
+ m_result = (m_constraint->rot_error < m_value);
+ break;
+ case SENS_ARM_ROT_ERROR_ABOVE:
+ m_result = (m_constraint->rot_error > m_value);
+ break;
+ }
+ if (m_lastresult!=m_result)
+ {
+ m_lastresult = m_result;
+ return true;
+ }
+ return (reset) ? true : false;
+}
+
+#ifndef DISABLE_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_ArmatureSensor::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "KX_ArmatureSensor",
+ 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,
+ &SCA_ISensor::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef KX_ArmatureSensor::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef KX_ArmatureSensor::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("constraint", KX_ArmatureSensor, pyattr_get_constraint),
+ KX_PYATTRIBUTE_FLOAT_RW("value",-FLT_MAX,FLT_MAX,KX_ArmatureSensor,m_value),
+ KX_PYATTRIBUTE_INT_RW("type",0,SENS_ARM_MAXTYPE,false,KX_ArmatureSensor,m_type),
+ { NULL } //Sentinel
+};
+
+PyObject* KX_ArmatureSensor::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ArmatureSensor* sensor = static_cast<KX_ArmatureSensor*>(self);
+ if (sensor->m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
+ BL_ArmatureObject* armobj = (BL_ArmatureObject*)sensor->m_gameobj;
+ BL_ArmatureConstraint* constraint = armobj->GetConstraint(sensor->m_posechannel, sensor->m_constraintname);
+ if (constraint)
+ return constraint->GetProxy();
+ }
+ Py_RETURN_NONE;
+}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_ArmatureSensor.h b/source/gameengine/Ketsji/KX_ArmatureSensor.h
new file mode 100644
index 00000000000..6dc6991873a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ArmatureSensor.h
@@ -0,0 +1,89 @@
+/**
+ * Property sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_ARMATURESENSOR
+#define __KX_ARMATURESENSOR
+
+struct bConstraint;
+
+#include "SCA_ISensor.h"
+#include "DNA_sensor_types.h"
+
+class KX_ArmatureSensor : public SCA_ISensor
+{
+ Py_Header;
+ //class CExpression* m_rightexpr;
+
+protected:
+
+public:
+ KX_ArmatureSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const char *posechannel,
+ const char *constraintname,
+ int type,
+ float value);
+
+ /**
+ * For property sensor, it is used to release the pre-calculated expression
+ * so that self references are removed before the sensor itself is released
+ */
+ virtual ~KX_ArmatureSensor();
+ virtual CValue* GetReplica();
+ virtual void ReParent(SCA_IObject* parent);
+ virtual void Init();
+ virtual bool Evaluate();
+ virtual bool IsPositiveTrigger();
+
+ // identify the constraint that this actuator controls
+ void FindConstraint();
+
+#ifndef DISABLE_PYTHON
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+ static PyObject* pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+
+#endif // DISABLE_PYTHON
+
+private:
+ struct bConstraint* m_constraint;
+ STR_String m_posechannel;
+ STR_String m_constraintname;
+ int m_type;
+ float m_value;
+ bool m_result;
+ bool m_lastresult;
+};
+
+#endif
+
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index be3d4906761..f5086ca89ac 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -777,6 +777,18 @@ void KX_BlenderMaterial::UpdateIPO(
mMaterial->ref = (float)(ref);
}
+void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
+{
+ if(!mBlenderShader)
+ mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
+
+ if(!mBlenderShader->Ok()) {
+ delete mBlenderShader;
+ mBlenderShader = 0;
+ }
+}
+
+#ifndef DISABLE_PYTHON
PyMethodDef KX_BlenderMaterial::Methods[] =
{
@@ -870,18 +882,6 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
return NULL;
}
-
-void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
-{
- if(!mBlenderShader)
- mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
-
- if(!mBlenderShader->Ok()) {
- delete mBlenderShader;
- mBlenderShader = 0;
- }
-}
-
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
{
return PyLong_FromSsize_t( GetMaterialIndex() );
@@ -941,3 +941,4 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.sr
return NULL;
}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index cdbdc4bd429..0946cd320c5 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -83,6 +83,7 @@ public:
MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
);
+#ifndef DISABLE_PYTHON
// --------------------------------
virtual PyObject* py_repr(void) { return PyUnicode_FromString(mMaterial->matname.ReadPtr()); }
@@ -92,6 +93,7 @@ public:
KX_PYMETHOD_DOC( KX_BlenderMaterial, setTexture );
KX_PYMETHOD_DOC( KX_BlenderMaterial, setBlending );
+#endif // DISABLE_PYTHON
// --------------------------------
// pre calculate to avoid pops/lag at startup
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 0832809772d..384125119a9 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -481,6 +481,7 @@ int KX_Camera::GetViewportTop() const
return m_camdata.m_viewporttop;
}
+#ifndef DISABLE_PYTHON
//----------------------------------------------------------------------------
//Python
@@ -1030,4 +1031,4 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay,
return NULL;
}
-
+#endif
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index bf7a39d93c8..71c66efaa87 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -41,8 +41,10 @@
#include "IntValue.h"
#include "RAS_CameraData.h"
+#ifndef DISABLE_PYTHON
/* utility conversion function */
bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix);
+#endif
class KX_Camera : public KX_GameObject
{
@@ -267,6 +269,7 @@ public:
virtual int GetGameObjectType() { return OBJ_CAMERA; }
+#ifndef DISABLE_PYTHON
KX_PYMETHOD_DOC_VARARGS(KX_Camera, sphereInsideFrustum);
KX_PYMETHOD_DOC_O(KX_Camera, boxInsideFrustum);
KX_PYMETHOD_DOC_O(KX_Camera, pointInsideFrustum);
@@ -304,6 +307,7 @@ public:
static PyObject* pyattr_get_INSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
};
#endif //__KX_CAMERA
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 9c00b5991af..3b02227451c 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -55,7 +55,7 @@ KX_CameraActuator::KX_CameraActuator(
float maxhght,
bool xytog
):
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_CAMERA),
m_ob (obj),
m_height (hght),
m_minHeight (minhght),
@@ -350,6 +350,8 @@ CValue *KX_CameraActuator::findObject(char *obName)
return NULL;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -416,4 +418,6 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
index e047e3724ea..875922b36e7 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.h
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -114,6 +114,8 @@ private :
/** Methods inherited from SCA_ILogicBrick */
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -122,6 +124,8 @@ private :
static PyObject* pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif // DISABLE_PYTHON
+
};
#endif //__KX_CAMERAACTUATOR
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index 7f1d2c7d53c..7bbc53211b6 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -38,6 +38,8 @@
#include "KX_RayCast.h"
#include "KX_PythonInit.h" // KX_GetActiveScene
+#include <stdio.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -56,7 +58,7 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
int time,
int option,
char *property) :
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_CONSTRAINT),
m_refDirVector(refDir),
m_currentTime(0)
{
@@ -559,6 +561,8 @@ bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE
return res;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -618,4 +622,6 @@ int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PY
return 0;
}
+#endif
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
index 54e083b48f0..aee7b3cc44c 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
@@ -26,7 +26,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-#include <Python.h>
+
#include "PyObjectPlus.h"
#include "KX_ConstraintWrapper.h"
#include "PHY_IPhysicsEnvironment.h"
@@ -49,6 +49,8 @@ KX_ConstraintWrapper::~KX_ConstraintWrapper()
{
}
+#ifndef DISABLE_PYTHON
+
PyObject* KX_ConstraintWrapper::PyGetConstraintId()
{
return PyLong_FromSsize_t(m_constraintId);
@@ -115,3 +117,5 @@ PyAttributeDef KX_ConstraintWrapper::Attributes[] = {
//KX_PYATTRIBUTE_TODO("constraintId"),
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
index 74670944415..300455aef6b 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
@@ -40,9 +40,11 @@ public:
virtual ~KX_ConstraintWrapper ();
int getConstraintId() { return m_constraintId;};
+#ifndef DISABLE_PYTHON
KX_PYMETHOD_NOARGS(KX_ConstraintWrapper,GetConstraintId);
KX_PYMETHOD(KX_ConstraintWrapper,SetParam);
KX_PYMETHOD(KX_ConstraintWrapper,GetParam);
+#endif
private:
int m_constraintId;
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
index daa31379985..c0d7b639077 100644
--- a/source/gameengine/Ketsji/KX_Dome.cpp
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -18,13 +18,16 @@ http://www.gnu.org/copyleft/lesser.txt.
Contributor(s): Dalai Felinto
This code is originally inspired on some of the ideas and codes from Paul Bourke.
-Developed as part of a Research and Development project for SAT - La Société des arts technologiques.
+Developed as part of a Research and Development project for SAT - La Soci�t� des arts technologiques.
-----------------------------------------------------------------------------
*/
#include "KX_Dome.h"
+#ifndef DISABLE_PYTHON
#include <structmember.h>
+#endif
+
#include <float.h>
#include <math.h>
@@ -558,7 +561,7 @@ void KX_Dome::CreateMeshDome180(void)
m_radangle = m_angle * M_PI/180.0;//calculates the radians angle, used for flattening
- //creating faces for the env mapcube 180º Dome
+ //creating faces for the env mapcube 180� Dome
// Top Face - just a triangle
cubetop[0].verts[0][0] = -sqrt_2 / 2.0;
cubetop[0].verts[0][1] = 0.0;
@@ -743,7 +746,7 @@ void KX_Dome::CreateMeshDome250(void)
m_radangle = m_angle * M_PI/180.0;//calculates the radians angle, used for flattening
/*
verts_height is the exactly needed height of the cube faces (not always 1.0).
-When we want some horizontal information (e.g. for horizontal 220º domes) we don't need to create and tesselate the whole cube.
+When we want some horizontal information (e.g. for horizontal 220� domes) we don't need to create and tesselate the whole cube.
Therefore the lateral cube faces could be small, and the tesselate mesh would be completely used.
(if we always worked with verts_height = 1.0, we would be discarding a lot of the calculated and tesselated geometry).
@@ -760,7 +763,7 @@ Then we need to multiply it by sqrt(2.0) to get the coordinate of the verts on t
uv_height = uv_ratio * ((verts_height/2) + 0.5);
uv_base = uv_ratio * (1.0 - ((verts_height/2) + 0.5));
- //creating faces for the env mapcube 180º Dome
+ //creating faces for the env mapcube 180� Dome
// Front Face - 2 triangles
cubefront[0].verts[0][0] =-1.0;
cubefront[0].verts[0][1] = 1.0;
@@ -1101,7 +1104,7 @@ void KX_Dome::CreateMeshPanorama(void)
nfacesbottom = 2;
- /* Left Back (135º) face - two triangles */
+ /* Left Back (135�) face - two triangles */
cubeleftback[0].verts[0][0] = 0;
cubeleftback[0].verts[0][1] = -sqrt_2;
@@ -1223,7 +1226,7 @@ void KX_Dome::CreateMeshPanorama(void)
nfacesright = 2;
- /* Right Back (-135º) face - two triangles */
+ /* Right Back (-135�) face - two triangles */
cuberightback[0].verts[0][0] = sqrt_2;
cuberightback[0].verts[0][1] = 0;
cuberightback[0].verts[0][2] = -1.0;
@@ -1352,7 +1355,7 @@ void KX_Dome::FlattenDome(MT_Vector3 verts[3])
void KX_Dome::FlattenPanorama(MT_Vector3 verts[3])
{
-// it creates a full spherical panoramic (360º)
+// it creates a full spherical panoramic (360�)
int i;
double phi;
bool edge=false;
@@ -1445,7 +1448,7 @@ void KX_Dome::SplitFace(vector <DomeFace>& face, int *nfaces)
void KX_Dome::CalculateFrustum(KX_Camera * cam)
{
/*
- // manually creating a 90º Field of View Frustum
+ // manually creating a 90� Field of View Frustum
the original formula:
top = tan(fov*3.14159/360.0) * near [for fov in degrees]
@@ -1466,7 +1469,7 @@ void KX_Dome::CalculateFrustum(KX_Camera * cam)
m_frustrum.camfar = cam->GetCameraFar();
// float top = tan(90.0*MT_PI/360.0) * m_frustrum.camnear;
- float top = m_frustrum.camnear; // for deg = 90º, tan = 1
+ float top = m_frustrum.camnear; // for deg = 90�, tan = 1
m_frustrum.x1 = -top;
m_frustrum.x2 = top;
@@ -1481,9 +1484,9 @@ void KX_Dome::CalculateFrustum(KX_Camera * cam)
void KX_Dome::CalculateCameraOrientation()
{
/*
-Uses 4 cameras for angles up to 180º
-Uses 5 cameras for angles up to 250º
-Uses 6 cameras for angles up to 360º
+Uses 4 cameras for angles up to 180�
+Uses 5 cameras for angles up to 250�
+Uses 6 cameras for angles up to 360�
*/
int i;
float deg45 = MT_PI / 4;
@@ -1494,22 +1497,22 @@ Uses 6 cameras for angles up to 360º
|| m_mode == DOME_TRUNCATED_FRONT
|| m_mode == DOME_TRUNCATED_REAR)){
- m_locRot[0] = MT_Matrix3x3( // 90º - Top
+ m_locRot[0] = MT_Matrix3x3( // 90� - Top
c, -s, 0.0,
0.0,0.0, -1.0,
s, c, 0.0);
- m_locRot[1] = MT_Matrix3x3( // 90º - Bottom
+ m_locRot[1] = MT_Matrix3x3( // 90� - Bottom
-s, c, 0.0,
0.0,0.0, 1.0,
s, c, 0.0);
- m_locRot[2] = MT_Matrix3x3( // 45º - Left
+ m_locRot[2] = MT_Matrix3x3( // 45� - Left
c, 0.0, s,
0, 1.0, 0.0,
-s, 0.0, c);
- m_locRot[3] = MT_Matrix3x3( // 45º - Right
+ m_locRot[3] = MT_Matrix3x3( // 45� - Right
c, 0.0, -s,
0.0, 1.0, 0.0,
s, 0.0, c);
@@ -1518,32 +1521,32 @@ Uses 6 cameras for angles up to 360º
|| m_mode == DOME_TRUNCATED_FRONT
|| m_mode == DOME_TRUNCATED_REAR))){
- m_locRot[0] = MT_Matrix3x3( // 90º - Top
+ m_locRot[0] = MT_Matrix3x3( // 90� - Top
1.0, 0.0, 0.0,
0.0, 0.0,-1.0,
0.0, 1.0, 0.0);
- m_locRot[1] = MT_Matrix3x3( // 90º - Bottom
+ m_locRot[1] = MT_Matrix3x3( // 90� - Bottom
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
0.0,-1.0, 0.0);
- m_locRot[2] = MT_Matrix3x3( // -90º - Left
+ m_locRot[2] = MT_Matrix3x3( // -90� - Left
0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
-1.0, 0.0, 0.0);
- m_locRot[3] = MT_Matrix3x3( // 90º - Right
+ m_locRot[3] = MT_Matrix3x3( // 90� - Right
0.0, 0.0,-1.0,
0.0, 1.0, 0.0,
1.0, 0.0, 0.0);
- m_locRot[4] = MT_Matrix3x3( // 0º - Front
+ m_locRot[4] = MT_Matrix3x3( // 0� - Front
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0);
- m_locRot[5] = MT_Matrix3x3( // 180º - Back - USED for ENVMAP only
+ m_locRot[5] = MT_Matrix3x3( // 180� - Back - USED for ENVMAP only
-1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0,-1.0);
@@ -1560,22 +1563,22 @@ Uses 6 cameras for angles up to 360º
0.0 ,0.0, 1.0,
s, -c, 0.0);
- m_locRot[2] = MT_Matrix3x3( // 45º - Left
+ m_locRot[2] = MT_Matrix3x3( // 45� - Left
-s, 0.0, c,
0, 1.0, 0.0,
-c, 0.0, -s);
- m_locRot[3] = MT_Matrix3x3( // 45º - Right
+ m_locRot[3] = MT_Matrix3x3( // 45� - Right
c, 0.0, s,
0, 1.0, 0.0,
-s, 0.0, c);
- m_locRot[4] = MT_Matrix3x3( // 135º - LeftBack
+ m_locRot[4] = MT_Matrix3x3( // 135� - LeftBack
-s, 0.0, -c,
0.0, 1.0, 0.0,
c, 0.0, -s);
- m_locRot[5] = MT_Matrix3x3( // 135º - RightBack
+ m_locRot[5] = MT_Matrix3x3( // 135� - RightBack
c, 0.0, -s,
0.0, 1.0, 0.0,
s, 0.0, c);
@@ -1734,7 +1737,7 @@ void KX_Dome::DrawEnvMap(void)
glVertex3f(-onebythree,-2 * onebythree, 3.0f);
glEnd();
- // domefacesId[2] => -90º (left)
+ // domefacesId[2] => -90� (left)
glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
glBegin(GL_QUADS);
glTexCoord2f(uv_ratio,uv_ratio);
@@ -1747,7 +1750,7 @@ void KX_Dome::DrawEnvMap(void)
glVertex3f(-onebythree, 0.0f, 3.0f);
glEnd();
- // domefacesId[3] => 90º (right)
+ // domefacesId[3] => 90� (right)
glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
glBegin(GL_QUADS);
glTexCoord2f(uv_ratio,uv_ratio);
@@ -1760,7 +1763,7 @@ void KX_Dome::DrawEnvMap(void)
glVertex3f(1.0f, 0.0f, 3.0f);
glEnd();
- // domefacesId[4] => 0º (front)
+ // domefacesId[4] => 0� (front)
glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
glBegin(GL_QUADS);
glTexCoord2f(uv_ratio,uv_ratio);
@@ -1773,7 +1776,7 @@ void KX_Dome::DrawEnvMap(void)
glVertex3f(1.0f, -2 * onebythree, 3.0f);
glEnd();
- // domefacesId[5] => 180º (back)
+ // domefacesId[5] => 180� (back)
glBindTexture(GL_TEXTURE_2D, domefacesId[5]);
glBegin(GL_QUADS);
glTexCoord2f(uv_ratio,uv_ratio);
@@ -1950,19 +1953,19 @@ void KX_Dome::DrawPanorama(void)
glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
GLDrawTriangles(cubebottom, nfacesbottom);
- // domefacesId[1] => -45º (left)
+ // domefacesId[1] => -45� (left)
glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
GLDrawTriangles(cubeleft, nfacesleft);
- // domefacesId[2] => 45º (right)
+ // domefacesId[2] => 45� (right)
glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
GLDrawTriangles(cuberight, nfacesright);
- // domefacesId[0] => -135º (leftback)
+ // domefacesId[0] => -135� (leftback)
glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
GLDrawTriangles(cubeleftback, nfacesleftback);
- // domefacesId[3] => 135º (rightback)
+ // domefacesId[3] => 135� (rightback)
glBindTexture(GL_TEXTURE_2D, domefacesId[5]);
GLDrawTriangles(cuberightback, nfacesrightback);
}
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index 42dc4d8fd24..bc0f875bca6 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -36,6 +36,9 @@
#include "KX_KetsjiEngine.h"
#include "KX_PythonInit.h" /* for config load/saving */
+#include <stdio.h>
+#include <stdlib.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -50,7 +53,7 @@ KX_GameActuator::KX_GameActuator(SCA_IObject *gameobj,
const STR_String& loadinganimationname,
KX_Scene* scene,
KX_KetsjiEngine* ketsjiengine)
- : SCA_IActuator(gameobj)
+ : SCA_IActuator(gameobj, KX_ACT_GAME)
{
m_mode = mode;
m_filename = filename;
@@ -125,6 +128,7 @@ bool KX_GameActuator::Update()
}
case KX_GAME_SAVECFG:
{
+#ifndef DISABLE_PYTHON
if (m_ketsjiengine)
{
char mashal_path[512];
@@ -152,9 +156,11 @@ bool KX_GameActuator::Update()
delete [] marshal_buffer;
}
break;
+#endif // DISABLE_PYTHON
}
case KX_GAME_LOADCFG:
{
+#ifndef DISABLE_PYTHON
if (m_ketsjiengine)
{
char mashal_path[512];
@@ -189,6 +195,7 @@ bool KX_GameActuator::Update()
}
}
break;
+#endif // DISABLE_PYTHON
}
default:
; /* do nothing? this is an internal error !!! */
@@ -198,8 +205,7 @@ bool KX_GameActuator::Update()
}
-
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -238,3 +244,5 @@ PyAttributeDef KX_GameActuator::Attributes[] = {
KX_PYATTRIBUTE_INT_RW("mode", KX_GAME_NODEF+1, KX_GAME_MAX-1, true, KX_GameActuator, m_mode),
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 8193aa8c37b..9bb261fcba9 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -46,6 +46,7 @@ typedef unsigned long uint_ptr;
#define KX_INERTIA_INFINITE 10000
+#include "BLI_arithb.h"
#include "RAS_IPolygonMaterial.h"
#include "KX_BlenderMaterial.h"
#include "KX_GameObject.h"
@@ -103,8 +104,10 @@ KX_GameObject::KX_GameObject(
m_pGraphicController(NULL),
m_xray(false),
m_pHitObject(NULL),
- m_isDeformable(false),
- m_attr_dict(NULL)
+ m_isDeformable(false)
+#ifndef DISABLE_PYTHON
+ , m_attr_dict(NULL)
+#endif
{
m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
@@ -141,16 +144,19 @@ KX_GameObject::~KX_GameObject()
(*contit)->ClearObject();
}
m_pSGNode->SetSGClientObject(NULL);
+
+ /* m_pSGNode is freed in KX_Scene::RemoveNodeDestructObject */
}
if (m_pGraphicController)
{
delete m_pGraphicController;
}
-
+#ifndef DISABLE_PYTHON
if (m_attr_dict) {
PyDict_Clear(m_attr_dict); /* incase of circular refs or other weired cases */
Py_DECREF(m_attr_dict);
}
+#endif // DISABLE_PYTHON
}
KX_GameObject* KX_GameObject::GetClientObject(KX_ClientObjectInfo* info)
@@ -339,8 +345,11 @@ void KX_GameObject::ProcessReplica()
m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
m_pClient_info->m_gameobject = this;
m_state = 0;
+
+#ifndef DISABLE_PYTHON
if(m_attr_dict)
m_attr_dict= PyDict_Copy(m_attr_dict);
+#endif
}
@@ -454,6 +463,22 @@ double* KX_GameObject::GetOpenGLMatrix()
return fl;
}
+void KX_GameObject::UpdateBlenderObjectMatrix(Object* blendobj)
+{
+ if (!blendobj)
+ blendobj = m_pBlenderObject;
+ if (blendobj) {
+ const MT_Matrix3x3& rot = NodeGetWorldOrientation();
+ const MT_Vector3& scale = NodeGetWorldScaling();
+ const MT_Vector3& pos = NodeGetWorldPosition();
+ rot.getValue(blendobj->obmat[0]);
+ pos.getValue(blendobj->obmat[3]);
+ VecMulf(blendobj->obmat[0], scale[0]);
+ VecMulf(blendobj->obmat[1], scale[1]);
+ VecMulf(blendobj->obmat[2], scale[2]);
+ }
+}
+
void KX_GameObject::AddMeshUser()
{
for (size_t i=0;i<m_meshes.size();i++)
@@ -1182,6 +1207,28 @@ CListValue* KX_GameObject::GetChildrenRecursive()
return list;
}
+/* ---------------------------------------------------------------------
+ * Some stuff taken from the header
+ * --------------------------------------------------------------------- */
+void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
+{
+ // we will relink the sensors and actuators that use object references
+ // if the object is part of the replicated hierarchy, use the new
+ // object reference instead
+ SCA_SensorList& sensorlist = GetSensors();
+ SCA_SensorList::iterator sit;
+ for (sit=sensorlist.begin(); sit != sensorlist.end(); sit++)
+ {
+ (*sit)->Relink(map_parameter);
+ }
+ SCA_ActuatorList& actuatorlist = GetActuators();
+ SCA_ActuatorList::iterator ait;
+ for (ait=actuatorlist.begin(); ait != actuatorlist.end(); ait++)
+ {
+ (*ait)->Relink(map_parameter);
+ }
+}
+
#ifdef USE_MATHUTILS
/* These require an SGNode */
@@ -1358,8 +1405,8 @@ void KX_GameObject_Mathutils_Callback_Init(void)
#endif // USE_MATHUTILS
+#ifndef DISABLE_PYTHON
/* ------- python stuff ---------------------------------------------------*/
-
PyMethodDef KX_GameObject::Methods[] = {
{"applyForce", (PyCFunction) KX_GameObject::sPyApplyForce, METH_VARARGS},
{"applyTorque", (PyCFunction) KX_GameObject::sPyApplyTorque, METH_VARARGS},
@@ -1435,23 +1482,6 @@ PyAttributeDef KX_GameObject::Attributes[] = {
{NULL} //Sentinel
};
-
-/*
-bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
- MT_Vector3& pos,
- MT_Vector3& pos2)
-{
- PyObject* pylist;
- PyObject* pylist2;
- bool error = (PyArg_ParseTuple(args,"OO",&pylist,&pylist2)) != 0;
-
- pos = ConvertPythonPylist(pylist);
- pos2 = ConvertPythonPylist(pylist2);
-
- return error;
-}
-*/
-
PyObject* KX_GameObject::PyReplaceMesh(PyObject* args)
{
KX_Scene *scene = KX_GetActiveScene();
@@ -2757,29 +2787,6 @@ PyObject* KX_GameObject::Pyget(PyObject *args)
return def;
}
-/* ---------------------------------------------------------------------
- * Some stuff taken from the header
- * --------------------------------------------------------------------- */
-void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
-{
- // we will relink the sensors and actuators that use object references
- // if the object is part of the replicated hierarchy, use the new
- // object reference instead
- SCA_SensorList& sensorlist = GetSensors();
- SCA_SensorList::iterator sit;
- for (sit=sensorlist.begin(); sit != sensorlist.end(); sit++)
- {
- (*sit)->Relink(map_parameter);
- }
- SCA_ActuatorList& actuatorlist = GetActuators();
- SCA_ActuatorList::iterator ait;
- for (ait=actuatorlist.begin(); ait != actuatorlist.end(); ait++)
- {
- (*ait)->Relink(map_parameter);
- }
-}
-
-
bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix)
{
if (value==NULL) {
@@ -2835,3 +2842,4 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
return false;
}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 845cead1cdb..41e04eef91c 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -60,8 +60,10 @@ class PHY_IGraphicController;
class PHY_IPhysicsEnvironment;
struct Object;
+#ifndef DISABLE_PYTHON
/* utility conversion function */
bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix);
+#endif
#ifdef USE_MATHUTILS
void KX_GameObject_Mathutils_Callback_Init(void);
@@ -114,6 +116,7 @@ public:
*/
static KX_GameObject* GetClientObject(KX_ClientObjectInfo* info);
+#ifndef DISABLE_PYTHON
// Python attributes that wont convert into CValue
//
// there are 2 places attributes can be stored, in the CValue,
@@ -130,6 +133,7 @@ public:
// * when assigning a value, first see if it can be a CValue, if it can remove the "m_attr_dict" and set the CValue
//
PyObject* m_attr_dict;
+#endif
virtual void /* This function should be virtual - derived classed override it */
Relink(
@@ -158,6 +162,15 @@ public:
return &m_OpenGL_4x4Matrix;
};
+ /**
+ * Update the blender object obmat field from the object world position
+ * if blendobj is NULL, update the object pointed by m_pBlenderObject
+ * The user must take action to restore the matrix before leaving the GE.
+ * Used in Armature evaluation
+ */
+ void
+ UpdateBlenderObjectMatrix(Object* blendobj=NULL);
+
/**
* Get a pointer to the game object that is the parent of
* this object. Or NULL if there is no parent. The returned
@@ -736,14 +749,6 @@ public:
) { return m_bIsNegativeScaling; }
/**
- * Is this a light?
- */
- virtual bool
- IsLight(
- void
- ) { return false; }
-
- /**
* @section Logic bubbling methods.
*/
@@ -787,7 +792,8 @@ public:
CListValue* GetChildren();
CListValue* GetChildrenRecursive();
-
+
+#ifndef DISABLE_PYTHON
/**
* @section Python interface functions.
*/
@@ -885,22 +891,7 @@ public:
/* getitem/setitem */
static PyMappingMethods Mapping;
static PySequenceMethods Sequence;
-
-private :
-
- /**
- * Random internal function to convert python function arguments
- * to 2 vectors.
- * @return true if conversion was possible.
- */
-
- bool
- ConvertPythonVectorArgs(
- PyObject* args,
- MT_Vector3& pos,
- MT_Vector3& pos2
- );
-
+#endif
};
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
index f098b0bebf5..e5b7c777fb4 100644
--- a/source/gameengine/Ketsji/KX_ISceneConverter.h
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -53,7 +53,6 @@ public:
*/
virtual void ConvertScene(
class KX_Scene* destinationscene,
- PyObject* dictobj,
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas)=0;
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index b71907be961..58769b94d9b 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -71,7 +71,7 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
bool ipo_as_force,
bool ipo_add,
bool ipo_local)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_IPO),
m_bNegativeEvent(false),
m_startframe (starttime),
m_endframe(endtime),
@@ -404,12 +404,13 @@ int KX_IpoActuator::string2mode(char* modename) {
return res;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
-
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_IpoActuator::Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -451,4 +452,6 @@ PyAttributeDef KX_IpoActuator::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 4117e493322..9f4fa9a7c02 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -112,7 +112,9 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_rendertools(NULL),
m_sceneconverter(NULL),
m_networkdevice(NULL),
+#ifndef DISABLE_PYTHON
m_pythondictionary(NULL),
+#endif
m_keyboarddevice(NULL),
m_mousedevice(NULL),
@@ -231,17 +233,17 @@ void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer)
m_rasterizer = rasterizer;
}
-
+#ifndef DISABLE_PYTHON
/*
* At the moment the GameLogic module is imported into 'pythondictionary' after this function is called.
* if this function ever changes to assign a copy, make sure the game logic module is imported into this dictionary before hand.
*/
-void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary)
+void KX_KetsjiEngine::SetPyNamespace(PyObject* pythondictionary)
{
MT_assert(pythondictionary);
m_pythondictionary = pythondictionary;
}
-
+#endif
void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter)
@@ -604,7 +606,9 @@ else
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_PHYSICS1);
// set Python hooks for each scene
+#ifndef DISABLE_PYTHON
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
+#endif
KX_SetActiveScene(scene);
scene->GetPhysicsEnvironment()->endFrame();
@@ -706,7 +710,9 @@ else
m_suspendeddelta = scene->getSuspendedDelta();
// set Python hooks for each scene
+#ifndef DISABLE_PYTHON
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
+#endif
KX_SetActiveScene(scene);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
@@ -1612,7 +1618,6 @@ KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
scene);
m_sceneconverter->ConvertScene(tmpscene,
- m_pythondictionary,
m_rendertools,
m_canvas);
@@ -1783,6 +1788,11 @@ double KX_KetsjiEngine::GetClockTime(void) const
return m_clockTime;
}
+double KX_KetsjiEngine::GetFrameTime(void) const
+{
+ return m_frameTime;
+}
+
double KX_KetsjiEngine::GetRealTime(void) const
{
return m_kxsystem->GetTimeInSeconds();
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index acb9e53df8a..74d683fbad6 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -70,7 +70,9 @@ private:
class RAS_IRenderTools* m_rendertools;
class KX_ISceneConverter* m_sceneconverter;
class NG_NetworkDeviceInterface* m_networkdevice;
+#ifndef DISABLE_PYTHON
PyObject* m_pythondictionary;
+#endif
class SCA_IInputDevice* m_keyboarddevice;
class SCA_IInputDevice* m_mousedevice;
class KX_Dome* m_dome; // dome stereo mode
@@ -201,7 +203,10 @@ public:
void SetCanvas(RAS_ICanvas* canvas);
void SetRenderTools(RAS_IRenderTools* rendertools);
void SetRasterizer(RAS_IRasterizer* rasterizer);
- void SetPythonDictionary(PyObject* pythondictionary);
+#ifndef DISABLE_PYTHON
+ void SetPyNamespace(PyObject* pythondictionary);
+ PyObject* GetPyNamespace(){return m_pythondictionary;};
+#endif
void SetSceneConverter(KX_ISceneConverter* sceneconverter);
void SetGame2IpoMode(bool game2ipo,int startFrame);
@@ -269,6 +274,10 @@ public:
* Returns current render frame clock time
*/
double GetClockTime(void) const;
+ /**
+ * Returns current logic frame clock time
+ */
+ double GetFrameTime(void) const;
double GetRealTime(void) const;
/**
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 85c495bc2bd..a0ecac178b3 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -264,6 +264,7 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
GPU_lamp_shadow_buffer_unbind(lamp);
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python Integration Hooks */
/* ------------------------------------------------------------------------- */
@@ -384,3 +385,4 @@ int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attr
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 0b7ccbe81ab..0e8484a4fe5 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -64,15 +64,17 @@ public:
void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
void Update();
+
+ virtual int GetGameObjectType() { return OBJ_LIGHT; }
+#ifndef DISABLE_PYTHON
/* attributes */
static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value);
static PyObject* pyattr_get_typeconst(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value);
-
- virtual bool IsLight(void) { return true; }
+#endif
};
#endif //__KX_LIGHT
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index 744fdb75796..a4815c5bd20 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -26,6 +26,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef DISABLE_PYTHON
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -309,3 +311,5 @@ bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **object, bool py_none
return false;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h
index 55684aa5ee9..12174f158f1 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.h
+++ b/source/gameengine/Ketsji/KX_MeshProxy.h
@@ -29,6 +29,8 @@
#ifndef __KX_MESHPROXY
#define __KX_MESHPROXY
+#ifndef DISABLE_PYTHON
+
#include "SCA_IObject.h"
/* utility conversion function */
@@ -72,5 +74,7 @@ public:
static PyObject * pyattr_get_numPolygons(void * self, const KX_PYATTRIBUTE_DEF * attrdef);
};
+#endif // DISABLE_PYTHON
+
#endif //__KX_MESHPROXY
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 8abc4f6b897..2dbaf3c9081 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -340,6 +340,8 @@ const MT_Vector3& KX_MouseFocusSensor::HitNormal() const
return m_hitNormal;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -426,7 +428,7 @@ PyObject* KX_MouseFocusSensor::pyattr_get_hit_normal(void *self_v, const KX_PYAT
return PyObjectFrom(self->HitNormal());
}
-
+#endif // DISABLE_PYTHON
/* eof */
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 7b53557467f..d4063ef1d16 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -86,6 +86,8 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
const MT_Point3& HitPosition() const;
const MT_Vector3& HitNormal() const;
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -98,6 +100,8 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
static PyObject* pyattr_get_hit_position(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_hit_normal(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif // DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
SCA_IObject* m_hitObject;
void* m_hitObject_Last; /* only use for comparison, never access */
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index f7baacdfa61..9cb0faab046 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -142,6 +142,22 @@ KX_NearSensor::~KX_NearSensor()
delete m_client_info;
}
+void KX_NearSensor::SetPhysCtrlRadius()
+{
+ if (m_bTriggered)
+ {
+ if (m_physCtrl)
+ {
+ m_physCtrl->SetRadius(m_ResetMargin);
+ }
+ } else
+ {
+ if (m_physCtrl)
+ {
+ m_physCtrl->SetRadius(m_Margin);
+ }
+ }
+}
bool KX_NearSensor::Evaluate()
{
@@ -151,20 +167,9 @@ bool KX_NearSensor::Evaluate()
if (m_bTriggered != m_bLastTriggered)
{
m_bLastTriggered = m_bTriggered;
- if (m_bTriggered)
- {
- if (m_physCtrl)
- {
- m_physCtrl->SetRadius(m_ResetMargin);
- }
- } else
- {
- if (m_physCtrl)
- {
- m_physCtrl->SetRadius(m_Margin);
- }
-
- }
+
+ SetPhysCtrlRadius();
+
result = true;
}
@@ -240,13 +245,12 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData
return false; // was DT_CONTINUE; but this was defined in Sumo as false
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python Functions */
/* ------------------------------------------------------------------------- */
-//No methods
-
/* ------------------------------------------------------------------------- */
/* Python Integration Hooks */
/* ------------------------------------------------------------------------- */
@@ -283,3 +287,5 @@ PyAttributeDef KX_NearSensor::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 100, KX_NearSensor, m_ResetMargin, CheckResetDistance),
{NULL} //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
index 03d6f830579..4bc4a7d1524 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.h
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -68,6 +68,7 @@ public:
virtual void SynchronizeTransform();
virtual CValue* GetReplica();
virtual void ProcessReplica();
+ virtual void SetPhysCtrlRadius();
virtual bool Evaluate();
virtual void ReParent(SCA_IObject* parent);
@@ -77,6 +78,8 @@ public:
virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2) { return false; };
virtual sensortype GetSensorType() { return ST_NEAR; }
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -91,9 +94,13 @@ public:
if (sensor->m_Margin > sensor->m_ResetMargin)
sensor->m_ResetMargin = sensor->m_Margin;
+ sensor->SetPhysCtrlRadius();
+
return 0;
}
+#endif // DISABLE_PYTHON
+
};
#endif //KX_NEARSENSOR_H
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index 2601ced9c38..03a80fdbc28 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -55,7 +55,7 @@ KX_ObjectActuator(
const short damping,
const KX_LocalFlags& flag
) :
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_OBJECT),
m_force(force),
m_torque(torque),
m_dloc(dloc),
@@ -317,7 +317,7 @@ bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
return res;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -641,4 +641,6 @@ int KX_ObjectActuator::pyattr_set_reference(void *self, const struct KX_PYATTRIB
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index 7a8c7de16b1..900408a30ab 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -157,7 +157,7 @@ public:
}
virtual bool Update();
-
+#ifndef DISABLE_PYTHON
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
@@ -216,6 +216,9 @@ public:
return 0;
}
+
+#endif // DISABLE_PYTHON
+
};
#endif //__KX_OBJECTACTUATOR
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 20e982f03e0..b70aa43ae9f 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -51,7 +51,7 @@ KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj,
bool addToCompound,
bool ghost,
SCA_IObject *ob)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_PARENT),
m_mode(mode),
m_addToCompound(addToCompound),
m_ghost(ghost),
@@ -134,6 +134,8 @@ bool KX_ParentActuator::Update()
return false;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -201,4 +203,6 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h
index f750affc8a1..501533486cf 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.h
+++ b/source/gameengine/Ketsji/KX_ParentActuator.h
@@ -77,6 +77,8 @@ class KX_ParentActuator : public SCA_IActuator
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool UnlinkObject(SCA_IObject* clientobj);
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -85,6 +87,8 @@ class KX_ParentActuator : public SCA_IActuator
static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif // DISABLE_PYTHON
+
}; /* end of class KX_ParentActuator : public SCA_PropertyActuator */
#endif
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
index edb19002671..0e149783338 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
@@ -26,7 +26,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-#include <Python.h>
+
#include "PyObjectPlus.h"
#include "KX_PhysicsObjectWrapper.h"
@@ -50,6 +50,7 @@ KX_PhysicsObjectWrapper::~KX_PhysicsObjectWrapper()
{
}
+#ifndef DISABLE_PYTHON
PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* args)
{
@@ -141,3 +142,5 @@ PyMethodDef KX_PhysicsObjectWrapper::Methods[] = {
{"setActive",(PyCFunction) KX_PhysicsObjectWrapper::sPySetActive, METH_VARARGS},
{NULL,NULL} //Sentinel
};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
index fa6fd1d1f2a..6fba1d0d95f 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
@@ -39,11 +39,15 @@ public:
KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv);
virtual ~KX_PhysicsObjectWrapper();
+#ifndef DISABLE_PYTHON
+
KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetPosition);
KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetLinearVelocity);
KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetAngularVelocity);
KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetActive);
+#endif // DISABLE_PYTHON
+
private:
class PHY_IPhysicsController* m_ctrl;
PHY_IPhysicsEnvironment* m_physenv;
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp
index af8e0510a11..3a9052bd95e 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.cpp
+++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp
@@ -26,6 +26,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef DISABLE_PYTHON
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -271,3 +273,5 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial,
return mat->GetProxy();
}
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h
index e619617d312..e7584727a77 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.h
+++ b/source/gameengine/Ketsji/KX_PolyProxy.h
@@ -29,6 +29,8 @@
#ifndef __KX_POLYROXY
#define __KX_POLYPROXY
+#ifndef DISABLE_PYTHON
+
#include "SCA_IObject.h"
class KX_PolyProxy : public CValue
@@ -65,5 +67,7 @@ public:
};
+#endif // DISABLE_PYTHON
+
#endif //__KX_POLYPROXY
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index 5b4322ae4cd..54a0f51aa7c 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -58,7 +58,9 @@ KX_PolygonMaterial::KX_PolygonMaterial()
m_tface(NULL),
m_mcol(NULL),
m_material(NULL),
+#ifndef DISABLE_PYTHON
m_pymaterial(NULL),
+#endif
m_pass(0)
{
}
@@ -92,21 +94,27 @@ void KX_PolygonMaterial::Initialize(
m_tface = tface;
m_mcol = mcol;
m_material = ma;
+#ifndef DISABLE_PYTHON
m_pymaterial = 0;
+#endif
m_pass = 0;
}
KX_PolygonMaterial::~KX_PolygonMaterial()
{
+#ifndef DISABLE_PYTHON
if (m_pymaterial)
{
Py_DECREF(m_pymaterial);
}
+#endif // DISABLE_PYTHON
}
bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const
{
bool dopass = false;
+
+#ifndef DISABLE_PYTHON
if (m_pymaterial)
{
PyObject *pyRasty = PyCObject_FromVoidPtr((void*)rasty, NULL); /* new reference */
@@ -126,6 +134,7 @@ bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingI
}
}
else
+#endif // DISABLE_PYTHON
{
switch (m_pass++)
{
@@ -196,6 +205,7 @@ void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
}
+#ifndef DISABLE_PYTHON
//----------------------------------------------------------------------------
//Python
@@ -386,3 +396,5 @@ int KX_PolygonMaterial::pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_D
self->m_specular= vec;
return PY_SET_ATTR_SUCCESS;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index dc42bd2f81b..dba12acee7f 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -57,7 +57,10 @@ private:
MTFace* m_tface;
unsigned int* m_mcol;
Material* m_material;
+
+#ifndef DISABLE_PYTHON
PyObject* m_pymaterial;
+#endif
mutable int m_pass;
public:
@@ -114,6 +117,7 @@ public:
}
virtual void GetMaterialRGBAColor(unsigned char *rgba) const;
+#ifndef DISABLE_PYTHON
KX_PYMETHOD_DOC(KX_PolygonMaterial, updateTexture);
KX_PYMETHOD_DOC(KX_PolygonMaterial, setTexture);
KX_PYMETHOD_DOC(KX_PolygonMaterial, activate);
@@ -133,6 +137,7 @@ public:
static int pyattr_set_diffuse(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_specular(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif
};
#endif // __KX_POLYGONMATERIAL_H__
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 04cec3c9106..05513d85fc6 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -41,6 +41,8 @@
#include <config.h>
#endif
+#ifndef DISABLE_PYTHON
+
// nasty glob variable to connect scripting language
// if there is a better way (without global), please do so!
static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL;
@@ -661,3 +663,5 @@ PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment()
return g_CurrentActivePhysicsEnvironment;
}
+#endif // DISABLE_PYTHON
+
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h
index b898cba3796..7eb2fe8909c 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.h
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h
@@ -29,13 +29,15 @@
#ifndef PHY_PYTHON_CONSTRAINTBINDING
#define PHY_PYTHON_CONSTRAINTBINDING
+#ifndef DISABLE_PYTHON
+
#include <Python.h>
PyObject* initPythonConstraintBinding();
void PHY_RemovePythonConstraintBinding();
void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env);
PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment();
-
+#endif // DISABLE_PYTHON
#endif //PHY_PYTHON_CONSTRAINTBINDING
diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp
index a41dab194dd..aef29286f4e 100644
--- a/source/gameengine/Ketsji/KX_PyMath.cpp
+++ b/source/gameengine/Ketsji/KX_PyMath.cpp
@@ -36,6 +36,8 @@
#pragma warning (disable : 4786)
#endif //WIN32
+#ifndef DISABLE_PYTHON
+
#include "MT_Vector3.h"
#include "MT_Vector4.h"
#include "MT_Matrix4x4.h"
@@ -191,3 +193,5 @@ PyObject* PyObjectFrom(const MT_Tuple2 &vec)
return list;
#endif
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h
index 17102905607..0ad91799983 100644
--- a/source/gameengine/Ketsji/KX_PyMath.h
+++ b/source/gameengine/Ketsji/KX_PyMath.h
@@ -42,6 +42,7 @@
#include "KX_Python.h"
#include "PyObjectPlus.h"
+#ifndef DISABLE_PYTHON
#ifdef USE_MATHUTILS
extern "C" {
#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */
@@ -157,7 +158,7 @@ bool PyVecTo(PyObject* pyval, T& vec)
return true;
}
- else if (PyObject_TypeCheck(pyval, &PyObjectPlus::Type))
+ else if (PyObject_TypeCheck(pyval, (PyTypeObject *)&PyObjectPlus::Type))
{ /* note, include this check because PySequence_Check does too much introspection
* on the PyObject (like getting its __class__, on a BGE type this means searching up
* the parent list each time only to discover its not a sequence.
@@ -237,3 +238,5 @@ PyObject* PyObjectFrom(const MT_Quaternion &qrot);
PyObject* PyObjectFrom(const MT_Tuple4 &pos);
#endif
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 298d485aaaf..f09cdd7d720 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -37,12 +37,17 @@
#pragma warning (disable : 4786)
#endif //WIN32
+#ifndef DISABLE_PYTHON
+
extern "C" {
#include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */
#include "Mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use.
#include "Geometry.h" // Blender.Geometry module copied here so the blenderlayer can use.
#include "BGL.h"
+
+ #include "marshal.h" /* python header for loading/saving dicts */
}
+#endif
#include "KX_PythonInit.h"
//python physics binding
@@ -51,6 +56,7 @@ extern "C" {
#include "KX_KetsjiEngine.h"
#include "KX_RadarSensor.h"
#include "KX_RaySensor.h"
+#include "KX_ArmatureSensor.h"
#include "KX_SceneActuator.h"
#include "KX_GameActuator.h"
#include "KX_ParentActuator.h"
@@ -65,6 +71,7 @@ extern "C" {
#include "KX_SoundActuator.h"
#include "KX_StateActuator.h"
#include "BL_ActionActuator.h"
+#include "BL_ArmatureObject.h"
#include "RAS_IRasterizer.h"
#include "RAS_ICanvas.h"
#include "RAS_BucketManager.h"
@@ -87,17 +94,7 @@ extern "C" {
#include "DNA_ID.h"
#include "DNA_scene_types.h"
-
-#include "marshal.h" /* python header for loading/saving dicts */
-
#include "PHY_IPhysicsEnvironment.h"
-// FIXME: Enable for access to blender python modules. This is disabled because
-// python has dependencies on a lot of other modules and is a pain to link.
-//#define USE_BLENDER_PYTHON
-#ifdef USE_BLENDER_PYTHON
-//#include "BPY_extern.h"
-#endif
-
#include "BKE_main.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
@@ -120,15 +117,34 @@ static KX_KetsjiEngine* gp_KetsjiEngine = NULL;
static RAS_IRasterizer* gp_Rasterizer = NULL;
static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = "";
static char gp_GamePythonPathOrig[FILE_MAXDIR + FILE_MAXFILE] = ""; // not super happy about this, but we need to remember the first loaded file for the global/dict load save
-static PyObject *gp_OrigPythonSysPath= NULL;
-static PyObject *gp_OrigPythonSysModules= NULL;
+void KX_SetActiveScene(class KX_Scene* scene)
+{
+ gp_KetsjiScene = scene;
+}
+
+class KX_Scene* KX_GetActiveScene()
+{
+ return gp_KetsjiScene;
+}
+
+class KX_KetsjiEngine* KX_GetActiveEngine()
+{
+ return gp_KetsjiEngine;
+}
+
+/* why is this in python? */
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
{
if (gp_Rasterizer)
gp_Rasterizer->DrawDebugLine(from,to,color);
}
+#ifndef DISABLE_PYTHON
+
+static PyObject *gp_OrigPythonSysPath= NULL;
+static PyObject *gp_OrigPythonSysModules= NULL;
+
/* Macro for building the keyboard translation */
//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromSsize_t(SCA_IInputDevice::KX_##name))
#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name)); Py_DECREF(item)
@@ -1218,6 +1234,53 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_PARENT_SET, KX_ParentActuator::KX_PARENT_SET);
KX_MACRO_addTypesToDict(d, KX_PARENT_REMOVE, KX_ParentActuator::KX_PARENT_REMOVE);
+ /* BL_ArmatureConstraint type */
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_TRACKTO);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_KINEMATIC);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_ROTLIKE, CONSTRAINT_TYPE_ROTLIKE);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_LOCLIKE, CONSTRAINT_TYPE_LOCLIKE);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_MINMAX, CONSTRAINT_TYPE_MINMAX);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_SIZELIKE, CONSTRAINT_TYPE_SIZELIKE);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_LOCKTRACK);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_STRETCHTO, CONSTRAINT_TYPE_STRETCHTO);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_CLAMPTO);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_TRANSFORM, CONSTRAINT_TYPE_TRANSFORM);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_DISTLIMIT, CONSTRAINT_TYPE_DISTLIMIT);
+ /* BL_ArmatureConstraint ik_type */
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_COPYPOSE, CONSTRAINT_IK_COPYPOSE);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_DISTANCE, CONSTRAINT_IK_DISTANCE);
+ /* BL_ArmatureConstraint ik_mode */
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_MODE_INSIDE, LIMITDIST_INSIDE);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_MODE_OUTSIDE, LIMITDIST_OUTSIDE);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_MODE_ONSURFACE, LIMITDIST_ONSURFACE);
+ /* BL_ArmatureConstraint ik_flag */
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_TIP, CONSTRAINT_IK_TIP);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_ROT, CONSTRAINT_IK_ROT);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_STRETCH, CONSTRAINT_IK_STRETCH);
+ KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_POS, CONSTRAINT_IK_POS);
+ /* KX_ArmatureSensor type */
+ KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_STATE_CHANGED, SENS_ARM_STATE_CHANGED);
+ KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_LIN_ERROR_BELOW, SENS_ARM_LIN_ERROR_BELOW);
+ KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_LIN_ERROR_ABOVE, SENS_ARM_LIN_ERROR_ABOVE);
+ KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_ROT_ERROR_BELOW, SENS_ARM_ROT_ERROR_BELOW);
+ KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_ROT_ERROR_ABOVE, SENS_ARM_ROT_ERROR_ABOVE);
+
+ /* BL_ArmatureActuator type */
+ KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_RUN, ACT_ARM_RUN);
+ KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_ENABLE, ACT_ARM_ENABLE);
+ KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_DISABLE, ACT_ARM_DISABLE);
+ KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_SETTARGET, ACT_ARM_SETTARGET);
+ KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_SETWEIGHT, ACT_ARM_SETWEIGHT);
+
+ /* BL_Armature Channel rotation_mode */
+ KX_MACRO_addTypesToDict(d, ROT_MODE_QUAT, ROT_MODE_QUAT);
+ KX_MACRO_addTypesToDict(d, ROT_MODE_XYZ, ROT_MODE_XYZ);
+ KX_MACRO_addTypesToDict(d, ROT_MODE_XZY, ROT_MODE_XZY);
+ KX_MACRO_addTypesToDict(d, ROT_MODE_YXZ, ROT_MODE_YXZ);
+ KX_MACRO_addTypesToDict(d, ROT_MODE_YZX, ROT_MODE_YZX);
+ KX_MACRO_addTypesToDict(d, ROT_MODE_ZXY, ROT_MODE_ZXY);
+ KX_MACRO_addTypesToDict(d, ROT_MODE_ZYX, ROT_MODE_ZYX);
+
// Check for errors
if (PyErr_Occurred())
{
@@ -1901,21 +1964,6 @@ PyObject* initBGL()
return BGL_Init();
}
-void KX_SetActiveScene(class KX_Scene* scene)
-{
- gp_KetsjiScene = scene;
-}
-
-class KX_Scene* KX_GetActiveScene()
-{
- return gp_KetsjiScene;
-}
-
-class KX_KetsjiEngine* KX_GetActiveEngine()
-{
- return gp_KetsjiEngine;
-}
-
// utility function for loading and saving the globalDict
int saveGamePythonConfig( char **marshal_buffer)
{
@@ -2016,3 +2064,5 @@ void resetGamePythonPath()
{
gp_GamePythonPathOrig[0] = '\0';
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index 8f102d13a18..ad3cd15ab4a 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -39,7 +39,7 @@ typedef enum {
extern bool gUseVisibilityTemp;
-
+#ifndef DISABLE_PYTHON
PyObject* initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene* ketsjiscene);
PyObject* initGameKeys();
PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
@@ -57,6 +57,7 @@ void resetGamePythonPath();
void pathGamePythonConfig( char *path );
int saveGamePythonConfig( char **marshal_buffer);
int loadGamePythonConfig(char *marshal_buffer, int marshal_length);
+#endif
class KX_KetsjiEngine;
class KX_Scene;
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index 61e563791c3..dd63163c663 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -32,9 +32,15 @@
#ifndef _adr_py_init_types_h_ // only process once,
#define _adr_py_init_types_h_ // even if multiply included
+#ifndef DISABLE_PYTHON
+
/* Only for Class::Parents */
#include "BL_BlenderShader.h"
#include "BL_ShapeActionActuator.h"
+#include "BL_ArmatureActuator.h"
+#include "BL_ArmatureConstraint.h"
+#include "BL_ArmatureObject.h"
+#include "BL_ArmatureChannel.h"
#include "KX_BlenderMaterial.h"
#include "KX_CameraActuator.h"
#include "KX_ConstraintActuator.h"
@@ -86,7 +92,22 @@
#include "SCA_RandomActuator.h"
#include "SCA_IController.h"
-static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes, int init_getset)
+static void PyType_Attr_Set(PyGetSetDef *attr_getset, PyAttributeDef *attr)
+{
+ attr_getset->name= (char *)attr->m_name;
+ attr_getset->doc= NULL;
+
+ attr_getset->get= reinterpret_cast<getter>(PyObjectPlus::py_get_attrdef);
+
+ if(attr->m_access==KX_PYATTRIBUTE_RO)
+ attr_getset->set= NULL;
+ else
+ attr_getset->set= reinterpret_cast<setter>(PyObjectPlus::py_set_attrdef);
+
+ attr_getset->closure= reinterpret_cast<void *>(attr);
+}
+
+static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes, PyAttributeDef *attributesPtr, int init_getset)
{
PyAttributeDef *attr;
@@ -97,29 +118,31 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a
//if(tp->tp_base==NULL)
// printf("Debug: No Parents - '%s'\n" , tp->tp_name);
- if(tp->tp_getset==NULL && attributes->m_name) {
+ if(tp->tp_getset==NULL && ((attributes && attributes->m_name) || (attributesPtr && attributesPtr->m_name))) {
PyGetSetDef *attr_getset;
int attr_tot= 0;
- for(attr= attributes; attr->m_name; attr++, attr_tot++) {};
+ if (attributes) {
+ for(attr= attributes; attr->m_name; attr++, attr_tot++)
+ attr->m_usePtr = false;
+ }
+ if (attributesPtr) {
+ for(attr= attributesPtr; attr->m_name; attr++, attr_tot++)
+ attr->m_usePtr = true;
+ }
tp->tp_getset = attr_getset = reinterpret_cast<PyGetSetDef *>(PyMem_Malloc((attr_tot+1) * sizeof(PyGetSetDef))); // XXX - Todo, free
-
- for(attr= attributes; attr->m_name; attr++, attr_getset++) {
- attr_getset->name= (char *)attr->m_name;
- attr_getset->doc= NULL;
-
- attr_getset->get= reinterpret_cast<getter>(PyObjectPlus::py_get_attrdef);
-
- if(attr->m_access==KX_PYATTRIBUTE_RO)
- attr_getset->set= NULL;
- else
- attr_getset->set= reinterpret_cast<setter>(PyObjectPlus::py_set_attrdef);
-
- attr_getset->closure= reinterpret_cast<void *>(attr);
+ if (attributes) {
+ for(attr= attributes; attr->m_name; attr++, attr_getset++) {
+ PyType_Attr_Set(attr_getset, attr);
+ }
+ }
+ if (attributesPtr) {
+ for(attr= attributesPtr; attr->m_name; attr++, attr_getset++) {
+ PyType_Attr_Set(attr_getset, attr);
+ }
}
-
memset(attr_getset, 0, sizeof(PyGetSetDef));
}
} else {
@@ -130,7 +153,8 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a
}
-#define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, i)
+#define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, NULL, i)
+#define PyType_Ready_AttrPtr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, n::AttributesPtr, i)
void initPyTypes(void)
{
@@ -151,6 +175,11 @@ void initPyTypes(void)
PyType_Ready_Attr(dict, BL_ActionActuator, init_getset);
PyType_Ready_Attr(dict, BL_Shader, init_getset);
PyType_Ready_Attr(dict, BL_ShapeActionActuator, init_getset);
+ PyType_Ready_Attr(dict, BL_ArmatureObject, init_getset);
+ PyType_Ready_Attr(dict, BL_ArmatureActuator, init_getset);
+ PyType_Ready_Attr(dict, BL_ArmatureConstraint, init_getset);
+ PyType_Ready_AttrPtr(dict, BL_ArmatureBone, init_getset);
+ PyType_Ready_AttrPtr(dict, BL_ArmatureChannel, init_getset);
PyType_Ready_Attr(dict, CListValue, init_getset);
PyType_Ready_Attr(dict, CValue, init_getset);
PyType_Ready_Attr(dict, KX_BlenderMaterial, init_getset);
@@ -223,4 +252,6 @@ void initPyTypes(void)
#endif
}
+#endif // DISABLE_PYTHON
+
#endif
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.h b/source/gameengine/Ketsji/KX_PythonInitTypes.h
index 6da79be9301..5b368d240f1 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.h
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.h
@@ -30,6 +30,8 @@
#ifndef _adr_py_init_types_h_ // only process once,
#define _adr_py_init_types_h_ // even if multiply included
+#ifndef DISABLE_PYTHON
void initPyTypes(void);
+#endif
#endif
diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp
index 75a7c9b8aeb..5b7e770f4e6 100644
--- a/source/gameengine/Ketsji/KX_PythonSeq.cpp
+++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp
@@ -28,9 +28,11 @@
* Readonly sequence wrapper for lookups on logic bricks
*/
+#ifndef DISABLE_PYTHON
#include "KX_PythonSeq.h"
#include "KX_GameObject.h"
+#include "BL_ArmatureObject.h"
#include "SCA_ISensor.h"
#include "SCA_IController.h"
#include "SCA_IActuator.h"
@@ -72,6 +74,10 @@ static Py_ssize_t KX_PythonSeq_len( PyObject * self )
return ((KX_GameObject *)self_plus)->GetControllers().size();
case KX_PYGENSEQ_OB_TYPE_ACTUATORS:
return ((KX_GameObject *)self_plus)->GetActuators().size();
+ case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS:
+ return ((BL_ArmatureObject *)self_plus)->GetConstraintNumber();
+ case KX_PYGENSEQ_OB_TYPE_CHANNELS:
+ return ((BL_ArmatureObject *)self_plus)->GetChannelNumber();
default:
/* Should never happen */
PyErr_SetString(PyExc_SystemError, "invalid type, internal error");
@@ -139,6 +145,29 @@ static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index)
}
return linkedactuators[index]->GetProxy();
}
+ case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS:
+ {
+ int nb_constraint = ((BL_ArmatureObject *)self_plus)->GetConstraintNumber();
+ if(index<0)
+ index += nb_constraint;
+ if(index<0 || index>= nb_constraint) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return ((BL_ArmatureObject *)self_plus)->GetConstraint(index)->GetProxy();
+ }
+ case KX_PYGENSEQ_OB_TYPE_CHANNELS:
+ {
+ int nb_channel = ((BL_ArmatureObject *)self_plus)->GetChannelNumber();
+ if(index<0)
+ index += nb_channel;
+ if(index<0 || index>= nb_channel) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return ((BL_ArmatureObject *)self_plus)->GetChannel(index)->GetProxy();
+ }
+
}
PyErr_SetString(PyExc_SystemError, "invalid sequence type, this is a bug");
@@ -206,6 +235,14 @@ static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, char *key
}
break;
}
+ case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS:
+ {
+ return ((BL_ArmatureObject*)self_plus)->GetConstraint(key);
+ }
+ case KX_PYGENSEQ_OB_TYPE_CHANNELS:
+ {
+ return ((BL_ArmatureObject*)self_plus)->GetChannel(key);
+ }
}
return NULL;
@@ -472,3 +509,5 @@ PyTypeObject KX_PythonSeq_Type = {
NULL, /* PyObject *tp_weaklist; */
NULL
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h
index 15a016224a9..22b968e9362 100644
--- a/source/gameengine/Ketsji/KX_PythonSeq.h
+++ b/source/gameengine/Ketsji/KX_PythonSeq.h
@@ -31,6 +31,8 @@
#ifndef _adr_py_seq_h_ // only process once,
#define _adr_py_seq_h_ // even if multiply included
+#ifndef DISABLE_PYTHON
+
#include "PyObjectPlus.h"
// -------------------------
@@ -39,7 +41,9 @@ enum KX_PYGENSEQ_TYPE {
KX_PYGENSEQ_CONT_TYPE_ACTUATORS,
KX_PYGENSEQ_OB_TYPE_SENSORS,
KX_PYGENSEQ_OB_TYPE_CONTROLLERS,
- KX_PYGENSEQ_OB_TYPE_ACTUATORS
+ KX_PYGENSEQ_OB_TYPE_ACTUATORS,
+ KX_PYGENSEQ_OB_TYPE_CONSTRAINTS,
+ KX_PYGENSEQ_OB_TYPE_CHANNELS,
};
/* The Main PyType Object defined in Main.c */
@@ -57,4 +61,6 @@ typedef struct {
PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type);
+#endif // DISABLE_PYTHON
+
#endif // _adr_py_seq_h_
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index eb127be8044..de5c0533ad3 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -176,7 +176,7 @@ void KX_RadarSensor::SynchronizeTransform()
/* Python Functions */
/* ------------------------------------------------------------------------- */
-/* none */
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python Integration Hooks */
@@ -216,3 +216,4 @@ PyAttributeDef KX_RadarSensor::Attributes[] = {
{NULL} //Sentinel
};
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h
index 27c9be14d1f..589a3f37d50 100644
--- a/source/gameengine/Ketsji/KX_RayEventManager.h
+++ b/source/gameengine/Ketsji/KX_RayEventManager.h
@@ -37,12 +37,9 @@ using namespace std;
class KX_RayEventManager : public SCA_EventManager
{
-
- class SCA_LogicManager* m_logicmgr;
public:
KX_RayEventManager(class SCA_LogicManager* logicmgr)
- : SCA_EventManager(RAY_EVENTMGR),
- m_logicmgr(logicmgr)
+ : SCA_EventManager(logicmgr, RAY_EVENTMGR)
{}
virtual void NextFrame();
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index 1f36945ccaa..4902315fd47 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -43,6 +43,8 @@
#include "KX_IPhysicsController.h"
#include "PHY_IPhysicsController.h"
+#include <stdio.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -311,7 +313,7 @@ bool KX_RaySensor::Evaluate()
return result;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -366,3 +368,5 @@ PyObject* KX_RaySensor::pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_
Py_RETURN_NONE;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index d3e92a14214..39b447b5657 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -84,10 +84,13 @@ public:
KX_RAY_AXIS_NEG_Z
};
+#ifndef DISABLE_PYTHON
/* Attributes */
static PyObject* pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif // DISABLE_PYTHON
+
};
#endif //__KX_RAYSENSOR_H
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 099403fc28d..fb96834c836 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -57,7 +57,7 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
const float *angvel,
bool angv_local)
:
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_ADD_OBJECT),
m_OriginalObject(original),
m_scene(scene),
@@ -163,6 +163,7 @@ void KX_SCA_AddObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
}
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -242,6 +243,14 @@ PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, con
return actuator->m_lastCreatedObject->GetProxy();
}
+PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject()
+{
+ InstantAddObject();
+
+ Py_RETURN_NONE;
+}
+
+#endif // DISABLE_PYTHON
void KX_SCA_AddObjectActuator::InstantAddObject()
{
@@ -277,10 +286,3 @@ void KX_SCA_AddObjectActuator::InstantAddObject()
replica->Release();
}
}
-
-PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject()
-{
- InstantAddObject();
-
- Py_RETURN_NONE;
-}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 7137ba5209e..4cccc406b58 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -115,12 +115,16 @@ public:
void InstantAddObject();
+#ifndef DISABLE_PYTHON
+
KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,InstantAddObject);
static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+#endif // DISABLE_PYTHON
+
}; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */
#endif
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
index 646cfb7219f..07a0df8bf77 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
@@ -41,6 +41,8 @@
#include <config.h>
#endif
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -79,6 +81,8 @@ PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Native functions */
/* ------------------------------------------------------------------------- */
@@ -87,7 +91,7 @@ KX_SCA_DynamicActuator::KX_SCA_DynamicActuator(SCA_IObject *gameobj,
short dyn_operation,
float setmass) :
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_DYNAMIC),
m_dyn_operation(dyn_operation),
m_setmass(setmass)
{
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
index dd9d8015724..b37ea4d57c0 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
@@ -44,7 +44,7 @@
KX_SCA_EndObjectActuator::KX_SCA_EndObjectActuator(SCA_IObject *gameobj,
SCA_IScene* scene):
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_END_OBJECT),
m_scene(scene)
{
// intentionally empty
@@ -84,7 +84,7 @@ CValue* KX_SCA_EndObjectActuator::GetReplica()
return replica;
};
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions : integration hooks */
@@ -120,4 +120,6 @@ PyAttributeDef KX_SCA_EndObjectActuator::Attributes[] = {
{ NULL } //Sentinel
};
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
index e85b8a32798..967bbfcdf1d 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
@@ -44,6 +44,8 @@
#include <config.h>
#endif
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -112,6 +114,8 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, instantReplaceMesh,
Py_RETURN_NONE;
}
+#endif // DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Native functions */
/* ------------------------------------------------------------------------- */
@@ -122,7 +126,7 @@ KX_SCA_ReplaceMeshActuator::KX_SCA_ReplaceMeshActuator(SCA_IObject *gameobj,
bool use_gfx,
bool use_phys) :
- SCA_IActuator(gameobj),
+ SCA_IActuator(gameobj, KX_ACT_REPLACE_MESH),
m_mesh(mesh),
m_scene(scene),
m_use_gfx(use_gfx),
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
index e5482c29aa7..47c823afa9f 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -74,6 +74,8 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
void InstantReplaceMesh();
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -83,6 +85,8 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,instantReplaceMesh);
+#endif // DISABLE_PYTHON
+
};
#endif
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 3483496c3a6..c93ead74182 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -40,14 +40,15 @@
#include "ListValue.h"
#include "SCA_LogicManager.h"
#include "SCA_TimeEventManager.h"
-#include "SCA_AlwaysEventManager.h"
-#include "SCA_RandomEventManager.h"
-#include "KX_RayEventManager.h"
+//#include "SCA_AlwaysEventManager.h"
+//#include "SCA_RandomEventManager.h"
+//#include "KX_RayEventManager.h"
#include "KX_TouchEventManager.h"
#include "SCA_KeyboardManager.h"
#include "SCA_MouseManager.h"
-#include "SCA_PropertyEventManager.h"
+//#include "SCA_PropertyEventManager.h"
#include "SCA_ActuatorEventManager.h"
+#include "SCA_BasicEventManager.h"
#include "KX_Camera.h"
#include "SCA_JoystickManager.h"
@@ -93,6 +94,8 @@
#include "KX_Light.h"
+#include <stdio.h>
+
void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
{
KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
@@ -168,25 +171,27 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
- SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
- SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
+ //SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
+ //SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
SCA_ActuatorEventManager* actmgr = new SCA_ActuatorEventManager(m_logicmgr);
- SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
- KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
+ //SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
+ SCA_BasicEventManager* basicmgr = new SCA_BasicEventManager(m_logicmgr);
+ //KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi);
- m_logicmgr->RegisterEventManager(alwaysmgr);
- m_logicmgr->RegisterEventManager(propmgr);
+ //m_logicmgr->RegisterEventManager(alwaysmgr);
+ //m_logicmgr->RegisterEventManager(propmgr);
m_logicmgr->RegisterEventManager(actmgr);
m_logicmgr->RegisterEventManager(m_keyboardmgr);
m_logicmgr->RegisterEventManager(m_mousemgr);
m_logicmgr->RegisterEventManager(m_timemgr);
- m_logicmgr->RegisterEventManager(rndmgr);
- m_logicmgr->RegisterEventManager(raymgr);
+ //m_logicmgr->RegisterEventManager(rndmgr);
+ //m_logicmgr->RegisterEventManager(raymgr);
m_logicmgr->RegisterEventManager(netmgr);
+ m_logicmgr->RegisterEventManager(basicmgr);
SYS_SystemHandle hSystem = SYS_GetSystem();
@@ -204,7 +209,9 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_bucketmanager=new RAS_BucketManager();
+#ifndef DISABLE_PYTHON
m_attr_dict = PyDict_New(); /* new ref */
+#endif
}
@@ -253,8 +260,11 @@ KX_Scene::~KX_Scene()
{
delete m_bucketmanager;
}
+
+#ifndef DISABLE_PYTHON
PyDict_Clear(m_attr_dict);
Py_DECREF(m_attr_dict);
+#endif
}
RAS_BucketManager* KX_Scene::GetBucketManager()
@@ -467,7 +477,7 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
// this is the list of object that are send to the graphics pipeline
m_objectlist->Add(newobj->AddRef());
- if (newobj->IsLight())
+ if (newobj->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
m_lightlist->Add(newobj->AddRef());
newobj->AddMeshUser();
@@ -743,7 +753,7 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
// add the object in the layer of the parent
(*git)->SetLayer(groupobj->GetLayer());
// If the object was a light, we need to update it's RAS_LightObject as well
- if ((*git)->IsLight())
+ if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
{
KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
lightobj->GetLightData()->m_layer = groupobj->GetLayer();
@@ -851,7 +861,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// add the object in the layer of the parent
(*git)->SetLayer(parentobj->GetLayer());
// If the object was a light, we need to update it's RAS_LightObject as well
- if ((*git)->IsLight())
+ if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
{
KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
lightobj->GetLightData()->m_layer = parentobj->GetLayer();
@@ -972,7 +982,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
newobj->RemoveMeshes();
ret = 1;
- if (newobj->IsLight() && m_lightlist->RemoveValue(newobj))
+ if (newobj->GetGameObjectType()==SCA_IObject::OBJ_LIGHT && m_lightlist->RemoveValue(newobj))
ret = newobj->Release();
if (m_objectlist->RemoveValue(newobj))
ret = newobj->Release();
@@ -1601,6 +1611,8 @@ double KX_Scene::getSuspendedDelta()
return m_suspendeddelta;
}
+#ifndef DISABLE_PYTHON
+
//----------------------------------------------------------------------------
//Python
@@ -1864,3 +1876,5 @@ KX_PYMETHODDEF_DOC(KX_Scene, get, "")
Py_INCREF(def);
return def;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 3e0dc303d72..da72ba2ec98 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -90,7 +90,10 @@ struct KX_ClientObjectInfo;
class KX_Scene : public PyObjectPlus, public SCA_IScene
{
Py_Header;
+
+#ifndef DISABLE_PYTHON
PyObject* m_attr_dict;
+#endif
struct CullingInfo {
int m_layer;
@@ -517,6 +520,7 @@ public:
*/
void SetNodeTree(SG_Tree* root);
+#ifndef DISABLE_PYTHON
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -539,6 +543,8 @@ public:
static PyMappingMethods Mapping;
static PySequenceMethods Sequence;
+#endif
+
/**
* Sets the time the scene was suspended
*/
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp
index ea1be7bca6c..e0b6ab1a34c 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp
@@ -50,7 +50,7 @@ KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj,
KX_KetsjiEngine* ketsjiEngine,
const STR_String& nextSceneName,
KX_Camera* camera)
- : SCA_IActuator(gameobj)
+ : SCA_IActuator(gameobj, KX_ACT_SCENE)
{
m_mode = mode;
m_scene = scene;
@@ -214,7 +214,7 @@ KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -287,4 +287,6 @@ int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index e979a8ce559..e11a94798c9 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -87,6 +87,8 @@ class KX_SceneActuator : public SCA_IActuator
virtual bool Update();
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
@@ -94,6 +96,8 @@ class KX_SceneActuator : public SCA_IActuator
static PyObject* pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif // DISABLE_PYTHON
+
}; /* end of class KXSceneActuator */
#endif
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index e2b4022a312..c97b4618f28 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -49,7 +49,7 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
bool is3d,
KX_3DSoundSettings settings,
KX_SOUNDACT_TYPE type)//,
- : SCA_IActuator(gameobj)
+ : SCA_IActuator(gameobj, KX_ACT_SOUND)
{
m_sound = sound;
m_volume = volume;
@@ -264,7 +264,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -416,3 +416,5 @@ int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATT
return PY_SET_ATTR_SUCCESS;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index 43198f1a253..de862473aac 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -93,6 +93,8 @@ public:
CValue* GetReplica();
void ProcessReplica();
+#ifndef DISABLE_PYTHON
+
/* -------------------------------------------------------------------- */
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
@@ -110,6 +112,9 @@ public:
static PyObject* pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+
+#endif // DISABLE_PYTHON
+
};
#endif //__KX_SOUNDACTUATOR
diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp
index 4159e9c373d..21ed087a3c1 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.cpp
+++ b/source/gameengine/Ketsji/KX_StateActuator.cpp
@@ -40,7 +40,7 @@ KX_StateActuator::KX_StateActuator(
int operation,
unsigned int mask
)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_STATE),
m_operation(operation),
m_mask(mask)
{
@@ -128,6 +128,7 @@ void KX_StateActuator::Activate(SG_DList& head)
}
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -167,3 +168,5 @@ PyAttributeDef KX_StateActuator::Attributes[] = {
KX_PYATTRIBUTE_INT_RW("mask",0,0x3FFFFFFF,false,KX_StateActuator,m_mask),
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 712a512995e..6b454f6a338 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -40,8 +40,7 @@
KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
PHY_IPhysicsEnvironment* physEnv)
- : SCA_EventManager(TOUCH_EVENTMGR),
- m_logicmgr(logicmgr),
+ : SCA_EventManager(logicmgr, TOUCH_EVENTMGR),
m_physEnv(physEnv)
{
//notm_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this);
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index 6da37d615a4..e6414a2e285 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -43,7 +43,6 @@ class PHY_IPhysicsEnvironment;
class KX_TouchEventManager : public SCA_EventManager
{
typedef std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*> NewCollision;
- class SCA_LogicManager* m_logicmgr;
PHY_IPhysicsEnvironment* m_physEnv;
std::set<NewCollision> m_newCollisions;
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index cde67787e2f..2ce5b8d1496 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -287,6 +287,7 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
return false; // was DT_CONTINUE but this was defined in sumo as false.
}
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
@@ -345,5 +346,6 @@ PyObject* KX_TouchSensor::pyattr_get_object_hit_list(void *self_v, const KX_PYAT
return self->m_colliders->GetProxy();
}
+#endif
/* eof */
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index ad1830e05c9..ae5b68da845 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -116,13 +116,16 @@ public:
// todo: put some info for collision maybe
+#ifndef DISABLE_PYTHON
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
static PyObject* pyattr_get_object_hit(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_object_hit_list(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
+
+#endif
};
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index e6c2f86bbce..01c7244b9d0 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -60,7 +60,7 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj,
bool allow3D,
int trackflag,
int upflag)
- : SCA_IActuator(gameobj)
+ : SCA_IActuator(gameobj, KX_ACT_TRACKTO)
{
m_time = time;
m_allow3D = allow3D;
@@ -421,14 +421,12 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
return result;
}
-
+#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
-
-
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_TrackToActuator::Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -492,4 +490,6 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT
return PY_SET_ATTR_SUCCESS;
}
+#endif // DISABLE_PYTHON
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
index bbfc1d17576..880c3712e1f 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.h
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -69,12 +69,16 @@ class KX_TrackToActuator : public SCA_IActuator
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool Update(double curtime, bool frame);
+#ifndef DISABLE_PYTHON
+
/* Python part */
/* These are used to get and set m_ob */
static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif // DISABLE_PYTHON
+
}; /* end of class KX_TrackToActuator : public KX_EditObjectActuator */
#endif
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index 1f46cbf53be..4adeefe32b4 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -1,6 +1,5 @@
-#include <Python.h>
#include "PyObjectPlus.h"
#include "KX_VehicleWrapper.h"
@@ -34,6 +33,7 @@ KX_VehicleWrapper::~KX_VehicleWrapper()
m_motionStates.clear();
}
+#ifndef DISABLE_PYTHON
PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* args)
{
@@ -322,3 +322,5 @@ PyMethodDef KX_VehicleWrapper::Methods[] = {
PyAttributeDef KX_VehicleWrapper::Attributes[] = {
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h
index d7f2da5cd7c..2ca06da18fc 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.h
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h
@@ -20,6 +20,7 @@ public:
virtual ~KX_VehicleWrapper ();
int getConstraintId();
+#ifndef DISABLE_PYTHON
KX_PYMETHOD_VARARGS(KX_VehicleWrapper,AddWheel);
KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetNumWheels);
@@ -46,7 +47,7 @@ public:
KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSuspensionCompression);
KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetRollInfluence);
-
+#endif // DISABLE_PYTHON
private:
PHY_IVehicle* m_vehicle;
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index 6a47dec181b..62ae502cd39 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -26,6 +26,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef DISABLE_PYTHON
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -442,3 +444,5 @@ PyObject* KX_VertexProxy::PySetUV2(PyObject* args)
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index 13c57e9f556..77ca0ad853a 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -29,6 +29,8 @@
#ifndef __KX_VERTEXPROXY
#define __KX_VERTEXPROXY
+#ifndef DISABLE_PYTHON
+
#include "SCA_IObject.h"
class KX_VertexProxy : public CValue
@@ -69,5 +71,7 @@ public:
};
+#endif // DISABLE_PYTHON
+
#endif //__KX_VERTEXPROXY
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
index 184e127209f..8154c87ab42 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
@@ -41,7 +41,7 @@ KX_VisibilityActuator::KX_VisibilityActuator(
bool occlusion,
bool recursive
)
- : SCA_IActuator(gameobj),
+ : SCA_IActuator(gameobj, KX_ACT_VISIBILITY),
m_visible(visible),
m_occlusion(occlusion),
m_recursive(recursive)
@@ -83,6 +83,8 @@ KX_VisibilityActuator::Update()
return false;
}
+#ifndef DISABLE_PYTHON
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -122,3 +124,5 @@ PyAttributeDef KX_VisibilityActuator::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("useRecursion", KX_VisibilityActuator, m_recursive),
{ NULL } //Sentinel
};
+
+#endif // DISABLE_PYTHON
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 5f38020780b..69d146776db 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -20,7 +20,6 @@ incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common #sourc
incs += ' #source/gameengine/Physics/Dummy'
incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include #source/blender/gpu'
-incs += ' ' + env['BF_PYTHON_INC']
incs += ' ' + env['BF_BULLET_INC']
incs += ' ' + env['BF_OPENGL_INC']
@@ -28,8 +27,13 @@ if env['WITH_BF_SDL']:
incs += ' ' + env['BF_SDL_INC']
else:
defs.append('DISABLE_SDL')
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
-if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
if env['BF_DEBUG']:
defs.append('_DEBUG') # for Python
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index df8dc3560ac..b7d0dd2f6e7 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -593,7 +593,7 @@ bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
for(int i= 0; i < obarr.size(); i++) {
ob= obarr[i];
if (ob->getCollisionShape() == newShape); {
- proxy = obarr[i]->getBroadphaseHandle();
+ proxy = ob->getBroadphaseHandle();
if(proxy)
dw->getPairCache()->cleanProxyFromPairs(proxy,dw->getDispatcher());
diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript
index 49f2af1b001..976c6825351 100644
--- a/source/gameengine/Physics/Bullet/SConscript
+++ b/source/gameengine/Physics/Bullet/SConscript
@@ -19,6 +19,12 @@ incs += ' #source/blender/blenlib'
incs += ' #intern/guardedalloc'
incs += ' ' + env['BF_BULLET_INC']
-incs += ' ' + env['BF_PYTHON_INC']
-env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,50], cxx_compileflags=env['BGE_CXXFLAGS'])
+defs = []
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
+env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), defs, libtype=['core','player'], priority=[350,50], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py
index c391d0c3dec..60511f41c2b 100644
--- a/source/gameengine/PyDoc/GameTypes.py
+++ b/source/gameengine/PyDoc/GameTypes.py
@@ -4,15 +4,17 @@ Documentation for the GameTypes Module.
@group Base: PyObjectPlus, CValue, CPropValue, SCA_ILogicBrick, SCA_IObject, SCA_ISensor, SCA_IController, SCA_IActuator
-@group Object: KX_GameObject, KX_LightObject, KX_Camera
+@group Object: KX_GameObject, KX_LightObject, KX_Camera, BL_ArmatureObject
+
+@group Animation: BL_ArmatureConstraint
@group Mesh: KX_MeshProxy, KX_PolyProxy, KX_VertexProxy
@group Shading: KX_PolygonMaterial, KX_BlenderMaterial, BL_Shader
-@group Sensors: SCA_ActuatorSensor, SCA_AlwaysSensor, SCA_DelaySensor, SCA_JoystickSensor, SCA_KeyboardSensor, KX_MouseFocusSensor, SCA_MouseSensor, KX_NearSensor, KX_NetworkMessageSensor, SCA_PropertySensor, KX_RadarSensor, SCA_RandomSensor, KX_RaySensor, KX_TouchSensor
+@group Sensors: SCA_ActuatorSensor, SCA_AlwaysSensor, SCA_DelaySensor, SCA_JoystickSensor, SCA_KeyboardSensor, KX_MouseFocusSensor, SCA_MouseSensor, KX_NearSensor, KX_NetworkMessageSensor, SCA_PropertySensor, KX_RadarSensor, SCA_RandomSensor, KX_RaySensor, KX_TouchSensor, KX_ArmatureSensor
-@group Actuators: SCA_2DFilterActuator, BL_ActionActuator, KX_SCA_AddObjectActuator, KX_CameraActuator, KX_ConstraintActuator, KX_SCA_DynamicActuator, KX_SCA_EndObjectActuator, KX_GameActuator, KX_IpoActuator, KX_NetworkMessageActuator, KX_ObjectActuator, KX_ParentActuator, SCA_PropertyActuator, SCA_RandomActuator, KX_SCA_ReplaceMeshActuator, KX_SceneActuator, BL_ShapeActionActuator, KX_SoundActuator, KX_StateActuator, KX_TrackToActuator, KX_VisibilityActuator
+@group Actuators: SCA_2DFilterActuator, BL_ActionActuator, BL_ArmatureActuator, KX_SCA_AddObjectActuator, KX_CameraActuator, KX_ConstraintActuator, KX_SCA_DynamicActuator, KX_SCA_EndObjectActuator, KX_GameActuator, KX_IpoActuator, KX_NetworkMessageActuator, KX_ObjectActuator, KX_ParentActuator, SCA_PropertyActuator, SCA_RandomActuator, KX_SCA_ReplaceMeshActuator, KX_SceneActuator, BL_ShapeActionActuator, KX_SoundActuator, KX_StateActuator, KX_TrackToActuator, KX_VisibilityActuator
@group Controllers: SCA_ANDController, SCA_NANDController, SCA_NORController, SCA_ORController, SCA_PythonController, SCA_XNORController, SCA_XORController
"""
@@ -5686,6 +5688,332 @@ class KX_Camera(KX_GameObject):
@return: the first object hit or None if no object or object does not match prop
"""
+class BL_ArmatureObject(KX_GameObject):
+ """
+ An armature object.
+
+ @ivar constraints: The list of armature constraint defined on this armature
+ Elements of the list can be accessed by index or string.
+ The key format for string access is '<bone_name>:<constraint_name>'
+ @type constraints: list of L{BL_ArmatureConstraint}
+ @ivar channels: The list of armature channels.
+ Elements of the list can be accessed by index or name the bone.
+ @type channels: list of L{BL_ArmatureChannel}
+ """
+
+ def update():
+ """
+ Ensures that the armature will be updated on next graphic frame.
+
+ This action is unecessary if a KX_ArmatureActuator with mode run is active
+ or if an action is playing. Use this function in other cases. It must be called
+ on each frame to ensure that the armature is updated continously.
+ """
+
+class BL_ArmatureActuator(SCA_IActuator):
+ """
+ Armature Actuators change constraint condition on armatures.
+
+ @group Constants: KX_ACT_ARMATURE_RUN, KX_ACT_ARMATURE_ENABLE, KX_ACT_ARMATURE_DISABLE, KX_ACT_ARMATURE_SETTARGET, KX_ACT_ARMATURE_SETWEIGHT
+ @ivar KX_ACT_ARMATURE_RUN: see type
+ @ivar KX_ACT_ARMATURE_ENABLE: see type
+ @ivar KX_ACT_ARMATURE_DISABLE: see type
+ @ivar KX_ACT_ARMATURE_SETTARGET: see type
+ @ivar KX_ACT_ARMATURE_SETWEIGHT: see type
+ @ivar type: The type of action that the actuator executes when it is active.
+
+ KX_ACT_ARMATURE_RUN(0): just make sure the armature will be updated on the next graphic frame
+ This is the only persistent mode of the actuator: it executes automatically once per frame until stopped by a controller
+
+ KX_ACT_ARMATURE_ENABLE(1): enable the constraint.
+
+ KX_ACT_ARMATURE_DISABLE(2): disable the constraint (runtime constraint values are not updated).
+
+ KX_ACT_ARMATURE_SETTARGET(3): change target and subtarget of constraint
+
+ KX_ACT_ARMATURE_SETWEIGHT(4): change weight of (only for IK constraint)
+ @type type: integer
+ @ivar constraint: The constraint object this actuator is controlling.
+ @type constraint: L{BL_ArmatureConstraint}
+ @ivar target: The object that this actuator will set as primary target to the constraint it controls
+ @type target: L{KX_GameObject}
+ @ivar subtarget: The object that this actuator will set as secondary target to the constraint it controls.
+ Currently, the only secondary target is the pole target for IK constraint.
+ @type subtarget: L{KX_GameObject}
+ @ivar weight: The weight this actuator will set on the constraint it controls.
+ Currently only the IK constraint has a weight. It must be a value between 0 and 1.
+ A weight of 0 disables a constraint while still updating constraint runtime values (see L{BL_ArmatureConstraint})
+ @type weight: float
+ """
+
+class KX_ArmatureSensor(SCA_ISensor):
+ """
+ Armature sensor detect conditions on armatures.
+
+ @group Constants: KX_ARMSENSOR_STATE_CHANGED, KX_ARMSENSOR_LIN_ERROR_BELOW, KX_ARMSENSOR_LIN_ERROR_ABOVE, KX_ARMSENSOR_ROT_ERROR_BELOW, KX_ARMSENSOR_ROT_ERROR_ABOVE
+ @ivar KX_ARMSENSOR_STATE_CHANGED: see type
+ @ivar KX_ARMSENSOR_LIN_ERROR_BELOW: see type
+ @ivar KX_ARMSENSOR_LIN_ERROR_ABOVE: see type
+ @ivar KX_ARMSENSOR_ROT_ERROR_BELOW: see type
+ @ivar KX_ARMSENSOR_ROT_ERROR_ABOVE: see type
+ @ivar type: The type of measurement that the sensor make when it is active.
+
+ KX_ARMSENSOR_STATE_CHANGED(0): detect that the constraint is changing state (active/inactive)
+
+ KX_ARMSENSOR_LIN_ERROR_BELOW(1): detect that the constraint linear error is above a threshold
+
+ KX_ARMSENSOR_LIN_ERROR_ABOVE(2): detect that the constraint linear error is below a threshold
+
+ KX_ARMSENSOR_ROT_ERROR_BELOW(3): detect that the constraint rotation error is above a threshold
+
+ KX_ARMSENSOR_ROT_ERROR_ABOVE(4): detect that the constraint rotation error is below a threshold
+ @type type: integer
+ @ivar constraint: The constraint object this sensor is watching.
+ @type constraint: L{BL_ArmatureConstraint}
+ @ivar value: The threshold used in the comparison with the constraint error
+ The linear error is only updated on CopyPose/Distance IK constraint with iTaSC solver
+ The rotation error is only updated on CopyPose+rotation IK constraint with iTaSC solver
+ The linear error on CopyPose is always >= 0: it is the norm of the distance between the target and the bone
+ The rotation error on CopyPose is always >= 0: it is the norm of the equivalent rotation vector between the bone and the target orientations
+ The linear error on Distance can be positive if the distance between the bone and the target is greater than the desired distance, and negative if the distance is smaller
+ @type value: float
+ """
+
+class BL_ArmatureConstraint(PyObjectPlus):
+ """
+ Proxy to Armature Constraint. Allows to change constraint on the fly.
+ Obtained through L{BL_ArmatureObject}.constraints.
+ Note: not all armature constraints are supported in the GE.
+
+ @group Constants: CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_ROTLIKE, CONSTRAINT_TYPE_LOCLIKE, CONSTRAINT_TYPE_MINMAX, CONSTRAINT_TYPE_SIZELIKE, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_STRETCHTO, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_TRANSFORM, CONSTRAINT_TYPE_DISTLIMIT,CONSTRAINT_IK_COPYPOSE, CONSTRAINT_IK_DISTANCE,CONSTRAINT_IK_MODE_INSIDE, CONSTRAINT_IK_MODE_OUTSIDE,CONSTRAINT_IK_MODE_ONSURFACE,CONSTRAINT_IK_FLAG_TIP,CONSTRAINT_IK_FLAG_ROT, CONSTRAINT_IK_FLAG_STRETCH, CONSTRAINT_IK_FLAG_POS
+ @ivar CONSTRAINT_TYPE_TRACKTO: see type
+ @ivar CONSTRAINT_TYPE_KINEMATIC: see type
+ @ivar CONSTRAINT_TYPE_ROTLIKE: see type
+ @ivar CONSTRAINT_TYPE_LOCLIKE: see type
+ @ivar CONSTRAINT_TYPE_MINMAX: see type
+ @ivar CONSTRAINT_TYPE_SIZELIKE: see type
+ @ivar CONSTRAINT_TYPE_LOCKTRACK: see type
+ @ivar CONSTRAINT_TYPE_STRETCHTO: see type
+ @ivar CONSTRAINT_TYPE_CLAMPTO: see type
+ @ivar CONSTRAINT_TYPE_TRANSFORM: see type
+ @ivar CONSTRAINT_TYPE_DISTLIMIT: see type
+ @ivar CONSTRAINT_IK_COPYPOSE: see ik_type
+ @ivar CONSTRAINT_IK_DISTANCE: see ik_type
+ @ivar CONSTRAINT_IK_MODE_INSIDE: see ik_mode
+ @ivar CONSTRAINT_IK_MODE_OUTSIDE: see ik_mode
+ @ivar CONSTRAINT_IK_MODE_ONSURFACE: see ik_mode
+ @ivar CONSTRAINT_IK_FLAG_TIP: see ik_flag
+ @ivar CONSTRAINT_IK_FLAG_ROT: see ik_flag
+ @ivar CONSTRAINT_IK_FLAG_STRETCH: see ik_flag
+ @ivar CONSTRAINT_IK_FLAG_POS: see ik_flag
+ @ivar type: Type of constraint, read-only
+ @type type: integer, one of CONSTRAINT_TYPE_ constant
+ @ivar name: Name of constraint constructed as <bone_name>:<constraint_name>
+ This name is also the key subscript on L{BL_ArmatureObject}.constraints list
+ @type name: string
+ @ivar enforce: fraction of constraint effect that is enforced. Between 0 and 1.
+ @type enforce: float
+ @ivar headtail: position of target between head and tail of the target bone: 0=head, 1=tail
+ Only used if the target is a bone (i.e target object is an armature)
+ @type headtail: float
+ @ivar lin_error: runtime linear error (in Blender unit) on constraint at the current frame.
+ This is a runtime value updated on each frame by the IK solver. Only available on IK constraint and iTaSC solver.
+ @type lin_error: float
+ @ivar rot_error: runtime rotation error (in radiant) on constraint at the current frame.
+ This is a runtime value updated on each frame by the IK solver. Only available on IK constraint and iTaSC solver.
+ It is only set if the constraint has a rotation part, for example, a CopyPose+Rotation IK constraint.
+ @type rot_error: float
+ @ivar target: Primary target object for the constraint. The position of this object in the GE will be used as target for the constraint.
+ @type target: L{KX_GameObject}
+ @ivar subtarget: Secondary target object for the constraint. The position of this object in the GE will be used as secondary target for the constraint.
+ Currently this is only used for pole target on IK constraint.
+ @type subtarget: L{KX_GameObject}
+ @ivar active: True if the constraint is active.
+ Note: an inactive constraint does not update lin_error and rot_error.
+ @type active: boolean
+ @ivar ik_weight: Weight of the IK constraint between 0 and 1.
+ Only defined for IK constraint.
+ @type ik_weight: float
+ @ivar ik_type: Type of IK constraint, read-only
+
+ CONSTRAINT_IK_COPYPOSE(0): constraint is trying to match the position and eventually the rotation of the target.
+
+ CONSTRAINT_IK_DISTANCE(1): constraint is maintaining a certain distance to target subject to ik_mode
+ @type ik_type: integer
+ @ivar ik_flag: Combination of IK constraint option flags, read-only
+
+ CONSTRAINT_IK_FLAG_TIP(1) : set when the constraint operates on the head of the bone and not the tail
+
+ CONSTRAINT_IK_FLAG_ROT(2) : set when the constraint tries to match the orientation of the target
+
+ CONSTRAINT_IK_FLAG_STRETCH(16) : set when the armature is allowed to stretch (only the bones with stretch factor > 0.0)
+
+ CONSTRAINT_IK_FLAG_POS(32) : set when the constraint tries to match the position of the target
+ @type ik_flag: integer
+ @ivar ik_dist: Distance the constraint is trying to maintain with target, only used when ik_type=CONSTRAINT_IK_DISTANCE
+ @type ik_dist: float
+ @ivar ik_mode: Additional mode for IK constraint. Currently only used for Distance constraint:
+
+ CONSTRAINT_IK_MODE_INSIDE(0) : the constraint tries to keep the bone within ik_dist of target
+
+ CONSTRAINT_IK_MODE_OUTSIDE(1) : the constraint tries to keep the bone outside ik_dist of the target
+
+ CONSTRAINT_IK_MODE_ONSURFACE(2) : the constraint tries to keep the bone exactly at ik_dist of the target
+ @type ik_mode: integer
+ """
+
+class BL_ArmatureChannel(PyObjectPlus):
+ """
+ Proxy to armature pose channel. Allows to read and set armature pose.
+ The attributes are identical to RNA attributes, but mostly in read-only mode.
+
+ @group Constants: PCHAN_ROT_QUAT, PCHAN_ROT_XYZ, PCHAN_ROT_XZY, PCHAN_ROT_YXZ, PCHAN_ROT_YZX, PCHAN_ROT_ZXY, PCHAN_ROT_ZYX
+ @ivar PCHAN_ROT_QUAT: see rotation_mode
+ @ivar PCHAN_ROT_XYZ: see rotation_mode
+ @ivar PCHAN_ROT_XZY: see rotation_mode
+ @ivar PCHAN_ROT_YXZ: see rotation_mode
+ @ivar PCHAN_ROT_YZX: see rotation_mode
+ @ivar PCHAN_ROT_ZXY: see rotation_mode
+ @ivar PCHAN_ROT_ZYX: see rotation_mode
+ @ivar name: channel name (=bone name), read-only.
+ @type name: string
+ @ivar bone: return the bone object corresponding to this pose channel, read-only.
+ @type bone: L{BL_ArmatureBone}
+ @ivar parent: return the parent channel object, None if root channel, read-only.
+ @type parent: L{BL_ArmatureChannel}
+ @ivar has_ik: true if the bone is part of an active IK chain, read-only.
+ This flag is not set when an IK constraint is defined but not enabled (miss target information for example)
+ @type has_ik: boolean
+ @ivar ik_dof_x: true if the bone is free to rotation in the X axis, read-only.
+ @type ik_dof_x: boolean
+ @ivar ik_dof_y: true if the bone is free to rotation in the Y axis, read-only.
+ @type ik_dof_y: boolean
+ @ivar ik_dof_z: true if the bone is free to rotation in the Z axis, read-only.
+ @type ik_dof_z: boolean
+ @ivar ik_limit_x: true if a limit is imposed on X rotation, read-only.
+ @type ik_limit_x: boolean
+ @ivar ik_limit_y: true if a limit is imposed on Y rotation, read-only.
+ @type ik_limit_y: boolean
+ @ivar ik_limit_z: true if a limit is imposed on Z rotation, read-only.
+ @type ik_limit_z: boolean
+ @ivar ik_rot_control: true if channel rotation should applied as IK constraint, read-only.
+ @type ik_rot_control: boolean
+ @ivar ik_lin_control: true if channel size should applied as IK constraint, read-only.
+ @type ik_lin_control: boolean
+ @ivar location: displacement of the bone head in armature local space, read-write.
+ You can only move a bone if it is unconnected to its parent. An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see L{BL_ArmatureObject.update})
+ @type location: vector [X,Y,Z]
+ @ivar scale: scale of the bone relative to its parent, read-write.
+ An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see L{BL_ArmatureObject.update})
+ @type scale: vector [sizeX, sizeY, sizeZ]
+ @ivar rotation: rotation of the bone relative to its parent expressed as a quaternion, read-write.
+ This field is only used if rotation_mode is 0. An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see L{BL_ArmatureObject.update})
+ @type rotation: vector [qr, qi, qj, qk]
+ @ivar euler_rotation: rotation of the bone relative to its parent expressed as a set of euler angles, read-write.
+ This field is only used if rotation_mode is > 0. You must always pass the angles in [X,Y,Z] order; the order of applying the angles to the bone depends on rotation_mode. An action playing on the armature may change this field. An IK chain does not update this value, see joint_rotation.
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see L{BL_ArmatureObject.update})
+ @type euler_rotation: vector [X, Y, Z]
+ @ivar rotation_mode: method of updating the bone rotation, read-write.
+ Use the following constants (euler mode are named as in BLender UI but the actual axis order is reversed):
+ - PCHAN_ROT_QUAT(0) : use quaternioin in rotation attribute to update bone rotation
+ - PCHAN_ROT_XYZ(1) : use euler_rotation and apply angles on bone's Z, Y, X axis successively
+ - PCHAN_ROT_XZY(2) : use euler_rotation and apply angles on bone's Y, Z, X axis successively
+ - PCHAN_ROT_YXZ(3) : use euler_rotation and apply angles on bone's Z, X, Y axis successively
+ - PCHAN_ROT_YZX(4) : use euler_rotation and apply angles on bone's X, Z, Y axis successively
+ - PCHAN_ROT_ZXY(5) : use euler_rotation and apply angles on bone's Y, X, Z axis successively
+ - PCHAN_ROT_ZYX(6) : use euler_rotation and apply angles on bone's X, Y, Z axis successively
+ @type rotation_mode: integer
+ @ivar channel_matrix: pose matrix in bone space (deformation of the bone due to action, constraint, etc), Read-only.
+ This field is updated after the graphic render, it represents the current pose.
+ @type channel_matrix: matrix [4][4]
+ @ivar pose_matrix: pose matrix in armature space, read-only,
+ This field is updated after the graphic render, it represents the current pose.
+ @type pose_matrix: matrix [4][4]
+ @ivar pose_head: position of bone head in armature space, read-only.
+ @type pose_head: vector [x, y, z]
+ @ivar pose_tail: position of bone tail in armature space, read-only.
+ @type pose_tail: vector [x, y, z]
+ @ivar ik_min_x: minimum value of X rotation in degree (<= 0) when X rotation is limited (see ik_limit_x), read-only.
+ @type ik_min_x: float
+ @ivar ik_max_x: maximum value of X rotation in degree (>= 0) when X rotation is limited (see ik_limit_x), read-only.
+ @type ik_max_x: float
+ @ivar ik_min_y: minimum value of Y rotation in degree (<= 0) when Y rotation is limited (see ik_limit_y), read-only.
+ @type ik_min_y: float
+ @ivar ik_max_y: maximum value of Y rotation in degree (>= 0) when Y rotation is limited (see ik_limit_y), read-only.
+ @type ik_max_y: float
+ @ivar ik_min_z: minimum value of Z rotation in degree (<= 0) when Z rotation is limited (see ik_limit_z), read-only.
+ @type ik_min_z: float
+ @ivar ik_max_z: maximum value of Z rotation in degree (>= 0) when Z rotation is limited (see ik_limit_z), read-only.
+ @type ik_max_z: float
+ @ivar ik_stiffness_x: bone rotation stiffness in X axis, read-only
+ @type ik_stiffness_x: float between 0 and 1
+ @ivar ik_stiffness_y: bone rotation stiffness in Y axis, read-only
+ @type ik_stiffness_y: float between 0 and 1
+ @ivar ik_stiffness_z: bone rotation stiffness in Z axis, read-only
+ @type ik_stiffness_z: float between 0 and 1
+ @ivar ik_stretch: ratio of scale change that is allowed, 0=bone can't change size, read-only.
+ @type ik_stretch: float
+ @ivar ik_rot_weight: weight of rotation constraint when ik_rot_control is set, read-write.
+ @type ik_rot_weight: float between 0 and 1
+ @ivar ik_lin_weight: weight of size constraint when ik_lin_control is set, read-write.
+ @type ik_lin_weight: float between 0 and 1
+ @ivar joint_rotation: control bone rotation in term of joint angle (for robotic applications), read-write.
+ When writing to this attribute, you pass a [x, y, z] vector and an appropriate set of euler angles or quaternion is calculated according to the rotation_mode.
+ When you read this attribute, the current pose matrix is converted into a [x, y, z] vector representing the joint angles.
+ The value and the meaning of the x, y, z depends on the ik_dof_ attributes:
+ - 1DoF joint X, Y or Z: the corresponding x, y, or z value is used an a joint angle in radiant
+ - 2DoF joint X+Y or Z+Y: treated as 2 successive 1DoF joints: first X or Z, then Y. The x or z value is used as a joint angle in radiant along the X or Z axis, followed by a rotation along the new Y axis of y radiants.
+ - 2DoF joint X+Z: treated as a 2DoF joint with rotation axis on the X/Z plane. The x and z values are used as the coordinates of the rotation vector in the X/Z plane.
+ - 3DoF joint X+Y+Z: treated as a revolute joint. The [x,y,z] vector represents the equivalent rotation vector to bring the joint from the rest pose to the new pose.
+
+ Notes:
+ - The bone must be part of an IK chain if you want to set the ik_dof_ attributes via the UI, but this will interfere with this attribute since the IK solver will overwrite the pose. You can stay in control of the armature if you create an IK constraint but do not finalize it (e.g. don't set a target): the IK solver will not run but the IK panel will show up on the UI for each bone in the chain.
+ - [0,0,0] always corresponds to the rest pose.
+ - You must request the armature pose to update and wait for the next graphic frame to see the effect of setting this attribute (see L{BL_ArmatureObject.update}).
+ - You can read the result of the calculation in rotation or euler_rotation attributes after setting this attribute.
+ @type joint_rotation: vector [x, y, z]
+ """
+
+class BL_ArmatureBone(PyObjectPlus):
+ """
+ Proxy to Blender bone structure. All fields are read-only and comply to RNA names.
+ All space attribute correspond to the rest pose.
+
+ @ivar name: bone name
+ @type name: string
+ @ivar connected: true when the bone head is struck to the parent's tail
+ @type connected: boolean
+ @ivar hinge: true when bone doesn't inherit rotation or scale from parent bone
+ @type hinge: boolean
+ @ivar inherit_scale: true when bone inherits scaling from parent bone
+ @type inherit_scale: boolean
+ @ivar bbone_segments: number of B-bone segments
+ @type bbone_segments: integer
+ @ivar roll: bone rotation around head-tail axis
+ @type roll: float
+ @ivar head: location of head end of the bone in parent bone space
+ @type head: vector [x, y, z]
+ @ivar tail: location of head end of the bone in parent bone space
+ @type tail: vector [x, y, z]
+ @ivar length: bone length
+ @type length: float
+ @ivar arm_head: location of head end of the bone in armature space
+ @type arm_head: vector [x, y, z]
+ @ivar arm_tail: location of tail end of the bone in armature space
+ @type arm_tail: vector [x, y, z]
+ @ivar arm_mat: matrix of the bone head in armature space
+ This matrix has no scale part.
+ @type arm_mat: matrix [4][4]
+ @ivar bone_mat: rotation matrix of the bone in parent bone space.
+ @type bone_mat: matrix [3][3]
+ @ivar parent: parent bone, or None for root bone
+ @type parent: L{BL_ArmatureBone}
+ @ivar children: list of bone's children
+ @type children: list of L{BL_ArmatureBone}
+ """
# Util func to extract all attrs
"""
import types
diff --git a/source/gameengine/PyDoc/SConscript b/source/gameengine/PyDoc/SConscript
index ed9712ba273..dabe004ae6a 100644
--- a/source/gameengine/PyDoc/SConscript
+++ b/source/gameengine/PyDoc/SConscript
@@ -1,6 +1,11 @@
#!/usr/bin/python
Import ('env')
+import os
+if env['WITH_BF_FHS']:
+ BLENDERPATH = os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION'])
+else:
+ BLENDERPATH = env['BF_INSTALLDIR']
from optparse import OptionParser
import epydoc
@@ -14,7 +19,7 @@ optvalues["quiet"] = 0
optvalues["include_source_code"] = 0
optvalues["inheritance"] = "included"
optvalues["show_private"] = 0
-optvalues["target"] = env["BF_DOCDIR"]+"/BGE_API/"
+optvalues["target"] = os.path.join(BLENDERPATH, 'doc')
optvalues["url"] = "http://www.blender.org"
optvalues["top"] = "Game Engine API"
optvalues["name"] = "Blender"
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index 239031866ca..75d80f4b3d5 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -49,6 +49,8 @@
#include "GL/glew.h"
+#include <stdio.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript
index dbec2d92e31..ea99fa966d8 100644
--- a/source/gameengine/Rasterizer/SConscript
+++ b/source/gameengine/Rasterizer/SConscript
@@ -5,6 +5,12 @@ sources = env.Glob('*.cpp')
incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna'
-incs += ' ' + env['BF_PYTHON_INC']
-env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,70], cxx_compileflags=env['BGE_CXXFLAGS'])
+defs = []
+
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
+
+env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), defs, libtype=['core','player'], priority=[350,70], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript
index 592b138583f..e7c9328688f 100644
--- a/source/gameengine/SConscript
+++ b/source/gameengine/SConscript
@@ -14,9 +14,11 @@ SConscript(['BlenderRoutines/SConscript',
'Rasterizer/SConscript',
'Rasterizer/RAS_OpenGLRasterizer/SConscript',
'SceneGraph/SConscript',
- 'Physics/Bullet/SConscript',
- 'VideoTexture/SConscript'
+ 'Physics/Bullet/SConscript'
])
+if env['WITH_BF_PYTHON']:
+ SConscript(['VideoTexture/SConscript'])
+
if env['WITH_BF_PLAYER']:
SConscript(['GamePlayer/SConscript'])
diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h
index 3e17fb55dc0..97951792ab5 100644
--- a/source/gameengine/SceneGraph/SG_DList.h
+++ b/source/gameengine/SceneGraph/SG_DList.h
@@ -89,6 +89,46 @@ public:
}
};
+ template<typename T> class const_iterator
+ {
+ private:
+ const SG_DList& m_head;
+ const T* m_current;
+ public:
+ typedef const_iterator<T> _myT;
+ const_iterator(const SG_DList& head) : m_head(head), m_current(NULL) {}
+ ~const_iterator() {}
+
+ void begin()
+ {
+ m_current = (const T*)m_head.Peek();
+ }
+ void back()
+ {
+ m_current = (const T*)m_head.Back();
+ }
+ bool end()
+ {
+ return (m_current == (const T*)m_head.Self());
+ }
+ const T* operator*()
+ {
+ return m_current;
+ }
+ _myT& operator++()
+ {
+ // no check of NULL! make sure you don't try to increment beyond end
+ m_current = (const T*)m_current->Peek();
+ return *this;
+ }
+ _myT& operator--()
+ {
+ // no check of NULL! make sure you don't try to increment beyond end
+ m_current = (const T*)m_current->Back();
+ return *this;
+ }
+ };
+
SG_DList()
{
m_flink = m_blink = this;
@@ -159,6 +199,18 @@ public:
{
return this;
}
+ inline const SG_DList *Peek() const // Look at front without removing
+ {
+ return (const SG_DList*)m_flink;
+ }
+ inline const SG_DList *Back() const // Look at front without removing
+ {
+ return (const SG_DList*)m_blink;
+ }
+ inline const SG_DList *Self() const
+ {
+ return this;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
@@ -168,5 +220,32 @@ public:
#endif
};
+/**
+ * SG_DListHead : Template class that implements copy constructor to duplicate list automatically
+ * The elements of the list must have themselves a copy constructor.
+ */
+template<typename T> class SG_DListHead : public SG_DList
+{
+public:
+ typedef SG_DListHead<T> _myT;
+ SG_DListHead() : SG_DList() {}
+ SG_DListHead(const _myT& other) : SG_DList()
+ {
+ // copy the list, assuming objects of type T
+ const_iterator<T> eit(other);
+ T* elem;
+ for (eit.begin(); !eit.end(); ++eit) {
+ elem = (*eit)->GetReplica();
+ AddBack(elem);
+ }
+ }
+ virtual ~SG_DListHead() {}
+ T* Remove()
+ {
+ return static_cast<T*>(SG_DList::Remove());
+ }
+
+};
+
#endif //__SG_DLIST
diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt
index 935c5a2c292..d914783cff3 100644
--- a/source/gameengine/VideoTexture/CMakeLists.txt
+++ b/source/gameengine/VideoTexture/CMakeLists.txt
@@ -48,7 +48,6 @@ SET(INC
../../../intern/moto/include
../../../intern/guardedalloc
../../../extern/glew/include
- ${PYTHON_INC}
)
IF(WITH_FFMPEG)
@@ -57,5 +56,11 @@ IF(WITH_FFMPEG)
ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS)
ENDIF(WITH_FFMPEG)
+IF(WITH_PYTHON)
+ SET(INC ${INC} ${PYTHON_INC})
+ELSE(WITH_PYTHON)
+ ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
BLENDERLIB(bf_videotex "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_videotex', sources, Split(incs), [], libtype=['game','player'], priority=[25, 72], compileflags = cflags )
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
index 119bd1c9954..b6b60c593ed 100644
--- a/source/gameengine/VideoTexture/SConscript
+++ b/source/gameengine/VideoTexture/SConscript
@@ -15,12 +15,14 @@ incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/m
incs += ' #intern/guardedalloc #extern/glew/include'
defs = []
-if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+if env['OURPLATFORM'] in ('win32-vc', 'win64-vc','win32-mingw'):
if env['BF_DEBUG']:
defs.append('_DEBUG')
-incs += ' ' + env['BF_PYTHON_INC']
-#incs += ' ' + env['BF_OPENGL_INC']
+if env['WITH_BF_PYTHON']:
+ incs += ' ' + env['BF_PYTHON_INC']
+else:
+ defs.append('DISABLE_PYTHON')
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
diff --git a/source/nan_compile.mk b/source/nan_compile.mk
index c62b4f2681b..8d4da1e2790 100644
--- a/source/nan_compile.mk
+++ b/source/nan_compile.mk
@@ -62,27 +62,27 @@ ifdef NAN_DEBUG
CCFLAGS += $(NAN_DEBUG)
endif
-REL_CFLAGS += -DNDEBUG
-REL_CCFLAGS += -DNDEBUG
-DBG_CFLAGS += -g
-DBG_CCFLAGS += -g
+REL_CFLAGS += -DNDEBUG
+REL_CCFLAGS += -DNDEBUG
+DBG_CFLAGS += -g
+DBG_CCFLAGS += -g
# OS dependent parts ---------------------------------------------------
ifeq ($(OS),darwin)
- CC = gcc
- CCC = g++
- ifeq ($(CPU),powerpc)
- CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- else
- CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- endif
-# REL_CFLAGS += -O
-# REL_CCFLAGS += -O2
- CPPFLAGS += -D_THREAD_SAFE
- NAN_DEPEND = true
+ CC ?= gcc
+ CCC ?= g++
+ ifeq ($(CPU),powerpc)
+ CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ else
+ CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ endif
+# REL_CFLAGS += -O
+# REL_CCFLAGS += -O2
+ CPPFLAGS += -D_THREAD_SAFE
+ NAN_DEPEND = true
OPENGL_HEADERS = /System/Library/Frameworks/OpenGL.framework
AR = ar
ARFLAGS = ruv
@@ -91,28 +91,28 @@ ifeq ($(OS),darwin)
endif
ifeq ($(OS),freebsd)
- CC = gcc
- CCC = g++
+ CC ?= gcc
+ CCC ?= g++
JAVAC = javac
JAVAH = javah
- CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- REL_CFLAGS += -O2
- REL_CCFLAGS += -O2
- CPPFLAGS += -D_THREAD_SAFE
- NAN_DEPEND = true
+ CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ REL_CFLAGS += -O2
+ REL_CCFLAGS += -O2
+ CPPFLAGS += -D_THREAD_SAFE
+ NAN_DEPEND = true
OPENGL_HEADERS = /usr/X11R6/include
JAVA_HEADERS = /usr/local/jdk1.3.1/include
JAVA_SYSTEM_HEADERS = /usr/local/jdk1.3.1/include/freebsd
- AR = ar
+ AR = ar
ARFLAGS = ruv
ARFLAGSQUIET = ru
endif
ifeq ($(OS),irix)
ifeq ($(IRIX_USE_GCC),true)
- CC = gcc
- CCC = g++
+ CC ?= gcc
+ CCC ?= g++
CFLAGS += -fPIC -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4
CCFLAGS += -fPIC -fpermissive -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4
REL_CFLAGS += -O2
@@ -121,16 +121,16 @@ ifeq ($(OS),irix)
DBG_CFLAGS += -g3 -gdwarf-2 -ggdb
DBG_CCFLAGS += -g3 -gdwarf-2 -ggdb
else
- CC = cc
- CCC = CC
- CFLAGS += -n32 -mips3 -Xcpluscomm
- CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std
+ CC ?= cc
+ CCC ?= CC
+ CFLAGS += -n32 -mips3 -Xcpluscomm
+ CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std
ifdef MIPS73_ISOHEADERS
- CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS)
+ CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS)
else
- CCFLAGS += -LANG:libc_in_namespace_std=off
+ CCFLAGS += -LANG:libc_in_namespace_std=off
endif
- REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
+ REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
REL_CCFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
endif
OPENGL_HEADERS = /usr/include
@@ -141,14 +141,14 @@ ifeq ($(OS),irix)
endif
ifeq ($(OS),linux)
- CC = gcc
- CCC = g++
-# CFLAGS += -pipe
- CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
-# CCFLAGS += -pipe
- REL_CFLAGS += -O2
- REL_CCFLAGS += -O2
+ CC ?= gcc
+ CCC ?= g++
+# CFLAGS += -pipe
+# CCFLAGS += -pipe
+ CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ REL_CFLAGS += -O2
+ REL_CCFLAGS += -O2
NAN_DEPEND = true
ifeq ($(CPU),alpha)
CFLAGS += -mieee
@@ -160,11 +160,11 @@ ifeq ($(OS),linux)
endif
ifeq ($(OS),openbsd)
- CC = gcc
- CCC = g++
- CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- REL_CFLAGS += -O2
+ CC ?= gcc
+ CCC ?= g++
+ CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ REL_CFLAGS += -O2
REL_CCFLAGS += -O2
NAN_DEPEND = true
CPPFLAGS += -D__FreeBSD__
@@ -177,30 +177,30 @@ endif
ifeq ($(OS),solaris)
# Adding gcc flag to $CC is not good, however if its not there makesdna wont build - Campbell
ifeq (x86_64, $(findstring x86_64, $(CPU)))
- CC = gcc -m64
- CCC = g++ -m64
+ CC ?= gcc -m64
+ CCC ?= g++ -m64
else
- CC = gcc
- CCC = g++
- #CC = cc
- #CCC = CC
+ CC ?= gcc
+ CCC ?= g++
+ #CC ?= cc
+ #CCC ?= CC
endif
JAVAC = javac
JAVAH = javah
- CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
- CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
-# CFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned"
-# CCFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned"
+ CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+# CFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned"
+# CCFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned"
# Note, you might still want to compile a 32 bit binary if you have a 64bit system. if so remove the following lines
# ifeq ($(findstring 64,$(CPU)), 64)
-# CFLAGS += -m64
-# CCFLAGS += -m64
+# CFLAGS += -m64
+# CCFLAGS += -m64
# endif
- REL_CFLAGS += -O2
- REL_CCFLAGS += -O2
+ REL_CFLAGS += -O2
+ REL_CCFLAGS += -O2
NAN_DEPEND = true
# ifeq ($(CPU),sparc)
@@ -211,7 +211,7 @@ ifeq ($(OS),solaris)
JAVA_SYSTEM_HEADERS = /usr/java/include/solaris
else
# OPENGL_HEADERS = /usr/X11/include/mesa
- OPENGL_HEADERS = /usr/X11/include/
+ OPENGL_HEADERS = /usr/X11/include/
endif
AR = ar
ARFLAGS = ruv
@@ -220,8 +220,8 @@ endif
ifeq ($(OS),windows)
ifeq ($(FREE_WINDOWS),true)
- CC = gcc
- CCC = g++
+ CC ?= gcc
+ CCC ?= g++
CFLAGS += -pipe -mno-cygwin -mwindows -funsigned-char -fno-strict-aliasing
CCFLAGS += -pipe -mno-cygwin -mwindows -funsigned-char -fno-strict-aliasing
CPPFLAGS += -DFREE_WINDOWS
@@ -233,16 +233,16 @@ ifeq ($(OS),windows)
AR = ar
ARFLAGS = ruv
ARFLAGSQUIET = ru
- WINRC = $(wildcard *.rc)
+ WINRC = $(wildcard *.rc)
RANLIB = ranlib
else
- CC = $(SRCHOME)/tools/cygwin/cl_wrapper.pl
- CCC = $(SRCHOME)/tools/cygwin/cl_wrapper.pl
+ CC ?= $(SRCHOME)/tools/cygwin/cl_wrapper.pl
+ CCC ?= $(SRCHOME)/tools/cygwin/cl_wrapper.pl
JAVAC = $(SRCHOME)/tools/cygwin/java_wrapper.pl -c
JAVAH = $(SRCHOME)/tools/cygwin/java_wrapper.pl -h
- REL_CFLAGS += /O2
+ REL_CFLAGS += /O2
REL_CCFLAGS += /O2 -GX
- DBG_CFLAGS += /Fd$(DIR)/debug/
+ DBG_CFLAGS += /Fd$(DIR)/debug/
DBG_CCFLAGS += /Fd$(DIR)/debug/
CFLAGS += /MT
CCFLAGS += /MT
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index f8afc7f3fa6..1aff7e1dea7 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -81,6 +81,8 @@ ifndef CONFIG_GUESS
endif
export NAN_MOTO ?= $(LCGDIR)/moto
+ export NAN_ITASC ?= $(LCGDIR)/itasc
+
export BF_PROFILE ?= false
export NAN_USE_BULLET ?= true
export NAN_BULLET2 ?= $(LCGDIR)/bullet2
@@ -138,11 +140,14 @@ ifndef CONFIG_GUESS
endif
ifeq ($(NAN_USE_FFMPEG_CONFIG), true)
- export NAN_FFMPEG ?= $(shell ffmpeg-config --prefix)
- export NAN_FFMPEGLIBS ?= $(shell ffmpeg-config --libs avformat avcodec)
- export NAN_FFMPEGCFLAGS ?= $(shell ffmpeg-config --cflags)
+ export NAN_FFMPEG = $(shell pkg-config --variable=prefix libavcodec) # Assume they are all in the same prefix
+ export NAN_FFMPEGLIBS = $(shell pkg-config --libs libavcodec libavdevice libavformat libswscale libavutil)
+ export NAN_FFMPEGCFLAGS = $(shell pkg-config --cflags libavcodec libavdevice libavformat libswscale libavutil)
endif
+ # Compare recreated .mo files with committed ones
+ export BF_VERIFY_MO_FILES ?= true
+
# Platform Dependent settings go below:
ifeq ($(OS),darwin)
@@ -309,6 +314,9 @@ ifndef CONFIG_GUESS
# enable l10n
export INTERNATIONAL ?= true
+ # Different endianess will make it fail, rely on other plataforms for checks
+ export BF_VERIFY_MO_FILES = false
+
else
ifeq ($(OS),linux)
@@ -336,12 +344,6 @@ ifndef CONFIG_GUESS
export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags)
export NAN_SAMPLERATE ?= /usr
-ifneq ($(NAN_USE_FFMPEG_CONFIG), true)
- export NAN_FFMPEG ?= /usr
- export NAN_FFMPEGLIBS ?= -L$(NAN_FFMPEG)/lib -lavformat -lavcodec -lavutil -lswscale -lavdevice -ldts -lz
- export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include
-endif
-
ifeq ($(WITH_OPENEXR), true)
export NAN_OPENEXR ?= $(shell pkg-config --variable=prefix OpenEXR )
export NAN_OPENEXR_INC ?= $(shell pkg-config --cflags OpenEXR )
diff --git a/source/nan_warn.mk b/source/nan_warn.mk
index 5841cdf5908..0dd4e0b8147 100644
--- a/source/nan_warn.mk
+++ b/source/nan_warn.mk
@@ -34,34 +34,33 @@
#
# Force the correct redefinition
-LEVEL_1_C_WARNINGS = -FIX_NAN_WARN
-LEVEL_1_CPP_WARNINGS = -FIX_NAN_WARN
-LEVEL_2_C_WARNINGS = -FIX_NAN_WARN
-LEVEL_2_CPP_WARNINGS = -FIX_NAN_WARN
-FIX_STUBS_WARNINGS = -FIX_NAN_WARN
+LEVEL_1_C_WARNINGS = -FIX_NAN_WARN1A
+LEVEL_1_CPP_WARNINGS = -FIX_NAN_WARN1B
+LEVEL_2_C_WARNINGS = -FIX_NAN_WARN2A
+LEVEL_2_CPP_WARNINGS = -FIX_NAN_WARN2B
+FIX_STUBS_WARNINGS = -FIX_NAN_WARN3
########################################################################
# Level 1: basic C warnings.
-ifeq ($(CC),gcc)
+ifeq (gcc, $(findstring gcc,$(CC)))
LEVEL_1_C_WARNINGS = -Wall
LEVEL_1_C_WARNINGS += -Wno-char-subscripts
else
- ifeq ($(CC),cc)
+ ifeq (cc, $(findstring cc,$(CC)))
ifeq ($(OS),irix)
# MIPSpro Compilers
#
# Irix warning info
#
- # 1001 # the source file does not end w/ a newline
- # 1110 # unreachable statement
- # 1201 # trailing comma in enums is nonstandard
- # 1209 # constant controlling expressions
- # 1355 # extra semicolon is ignored
- # 1424 # unreferenced template paramaters
- # 1681 # virtual function override
- # 3201 # unreferenced formal paramaters
+ # 1001 # the source file does not end w/ a newline
+ # 1110 # unreachable statement
+ # 1201 # trailing comma in enums is nonstandard
+ # 1209 # constant controlling expressions
+ # 1355 # extra semicolon is ignored
+ # 1424 # unreferenced template paramaters
+ # 1681 # virtual function override
+ # 3201 # unreferenced formal paramaters
#
-
LEVEL_1_C_WARNINGS = -fullwarn -woff 1001,1110,1201,1209,1355,1424,1681,3201
endif
endif
@@ -72,14 +71,14 @@ else
endif
# Level 1: basic CPP warnings.
-ifeq ($(CCC),g++)
+ifeq (g++, $(findstring g++,$(CCC)))
LEVEL_1_CPP_WARNINGS = -Wall
LEVEL_1_CPP_WARNINGS += -Wno-reorder
else
- ifeq ($(CCC),CC)
+ ifeq (CC, $(findstring CC,$(CCC)))
ifeq ($(OS),irix)
# MIPSpro Compilers
- # see warning descriptions above
+ # see warning descriptions above
LEVEL_1_CPP_WARNINGS = -woff 1001,1110,1201,1209,1355,1424,1681,3201
endif
endif
@@ -92,7 +91,7 @@ endif
########################################################################
# Level 2: paranoia level C warnings.
# DO NOT REUSE LEVEL_1_ DEFINES.
-ifeq ($(CC),gcc)
+ifeq (gcc, $(findstring gcc,$(CC)))
LEVEL_2_C_WARNINGS = -Wall
LEVEL_2_C_WARNINGS += -W
# deliberately enable char-subscript warnings
@@ -108,10 +107,10 @@ ifeq ($(CC),gcc)
LEVEL_2_C_WARNINGS += -Wnested-externs
LEVEL_2_C_WARNINGS += -Wredundant-decls
else
- ifeq ($(CC),cc)
+ ifeq (cc, $(findstring cc,$(CC)))
ifeq ($(OS),irix)
# MIPSpro Compilers
- # see warning descriptions above
+ # see warning descriptions above
LEVEL_2_C_WARNINGS = -fullwarn -woff 1001,1209,1424,3201
endif
ifeq ($(OS),solaris)
@@ -127,7 +126,7 @@ endif
# Level 2: paranoia level CPP warnings.
# DO NOT REUSE LEVEL_1_ DEFINES.
-ifeq ($(CCC),g++)
+ifeq (g++, $(findstring g++,$(CCC)))
LEVEL_2_CPP_WARNINGS = -Wall
LEVEL_2_CPP_WARNINGS += -W
# deliberately enable char-subscript warnings
@@ -145,10 +144,10 @@ ifeq ($(CCC),g++)
LEVEL_2_CPP_WARNINGS += -Wsign-promo
LEVEL_2_CPP_WARNINGS += -Wsynth
else
- ifeq ($(CCC),CC)
+ ifeq (CC, $(findstring CC,$(CCC)))
ifeq ($(OS),irix)
# MIPSpro Compilers
- # see warning descriptions above
+ # see warning descriptions above
LEVEL_2_CPP_WARNINGS = -fullwarn -woff 1209,1424,3201
endif
endif
@@ -160,7 +159,7 @@ endif
########################################################################
# stubs warning fix
-ifeq ($(CC),gcc)
+ifeq (gcc, $(findstring gcc,$(CC)))
FIX_STUBS_WARNINGS = -Wno-unused
else
FIX_STUBS_WARNINGS =
diff --git a/tools/Blender.py b/tools/Blender.py
index d7cbe1076e7..1b0573cfda4 100644
--- a/tools/Blender.py
+++ b/tools/Blender.py
@@ -171,7 +171,7 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_FREETYPE_LIB'])
if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
- if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
else:
syslibs.append(lenv['BF_PYTHON_LIB'])
@@ -405,8 +405,11 @@ def PyInstall(target=None, source=None, env=None):
print 'Install command:', cmd
commands.getoutput(cmd)
+ if env['WITH_BF_FHS']: dir = os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) # BLENDERPATH
+ else: dir = os.path.join(env['BF_INSTALLDIR'], '.blender')
+
py_src = env.subst( env['BF_PYTHON_LIBPATH'] + '/python'+env['BF_PYTHON_VERSION'] )
- py_target = env.subst( env['BF_INSTALLDIR'] + '/.blender/python/lib/python'+env['BF_PYTHON_VERSION'] )
+ py_target = env.subst( dir + '/python/lib/python'+env['BF_PYTHON_VERSION'] )
# Copied from source/creator/CMakeLists.txt, keep in sync.
print 'Install python from:'
diff --git a/tools/btools.py b/tools/btools.py
index 7cadab992b8..b1584ae8784 100755
--- a/tools/btools.py
+++ b/tools/btools.py
@@ -27,7 +27,7 @@ def print_arguments(args, bc):
def validate_arguments(args, bc):
opts_list = [
- 'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC',
+ 'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL',
'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
'BF_LIBSAMPLERATE', 'BF_LIBSAMPLERATE_INC', 'BF_LIBSAMPLERATE_LIB', 'BF_LIBSAMPLERATE_LIBPATH',
@@ -56,6 +56,7 @@ def validate_arguments(args, bc):
'WITH_BF_PLAYER',
'WITH_BF_NOBLENDER',
'WITH_BF_BINRELOC',
+ 'WITH_BF_LZO', 'WITH_BF_LZMA',
'LCGDIR',
'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
@@ -69,6 +70,8 @@ def validate_arguments(args, bc):
'WITH_BF_DOCS',
'BF_NUMJOBS',
'BF_MSVS',
+ 'WITH_BF_FHS',
+ 'BF_VERSION',
]
# Have options here that scons expects to be lists
@@ -91,7 +94,7 @@ def validate_arguments(args, bc):
'BF_BSC', 'BF_CONFIG',
'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
- 'BF_DOCDIR', 'BF_UNIT_TEST']
+ 'BF_UNIT_TEST']
okdict = {}
@@ -156,6 +159,7 @@ def read_opts(cfg, args):
('BF_PYTHON_INC', 'include path for Python headers', ''),
('BF_PYTHON_BINARY', 'Path to the Python interpreter', ''),
('BF_PYTHON_LIB', 'Python library', ''),
+ ('BF_PYTHON_DLL', 'Python dll - used on Windows only', ''),
('BF_PYTHON_LIB_STATIC', 'Python static libraries', ''),
('BF_PYTHON_LIBPATH', 'Library path', ''),
('BF_PYTHON_LINKFLAGS', 'Python link flags', ''),
@@ -362,7 +366,6 @@ def read_opts(cfg, args):
('BF_BUILDDIR', 'Build dir', ''),
('BF_INSTALLDIR', 'Installation dir', ''),
- ('BF_DOCDIR', 'Dir where BPy documentation will be created', ''),
('CC', 'C compiler to use', ''),
('CXX', 'C++ compiler to use', ''),
@@ -377,6 +380,9 @@ def read_opts(cfg, args):
(BoolVariable('BF_QUIET', 'Enable silent output if true', True)),
(BoolVariable('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', False)),
+ (BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)),
+ (BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)),
+
(BoolVariable('WITH_BF_LCMS', 'Enable color correction with lcms', False)),
('BF_LCMS_LIB', 'LCMSlibrary', 'lcms'),
@@ -387,6 +393,9 @@ def read_opts(cfg, args):
('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'),
('BF_NUMJOBS', 'Number of build processes to spawn', '1'),
('BF_MSVS', 'Generate MSVS project files and solution', False),
+
+ (BoolVariable('WITH_BF_FHS', 'Use the Unix "Filesystem Hierarchy Standard" rather then a redistributable directory layout', False)),
+ ('BF_VERSION', 'The root path for Unix (non-apple)', '2.5'),
(BoolVariable('BF_UNIT_TEST', 'Build with unit test support.', False))